diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 68e8fc714d6..ef1146c45d6 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -7,97 +7,75 @@ "workspaceFolder": "/workspace", "shutdownAction": "stopCompose", "postCreateCommand": "/docker-init.sh", + "postStartCommand": "/docker-start.sh", "containerEnv": { "EDITOR_VSCODE": "true" }, "features": { - "docker-in-docker": { - "version": "latest" - } }, - - // Set *default* container specific settings.json values on container create. - "settings": { - "terminal.integrated.defaultProfile.linux": "zsh", - "python.pythonPath": "/usr/local/bin/python", - "python.languageServer": "Pylance", - "python.linting.enabled": true, - "python.linting.pylintEnabled": true, - "python.formatting.autopep8Path": "/usr/local/py-utils/bin/autopep8", - "python.formatting.blackPath": "/usr/local/py-utils/bin/black", - "python.formatting.yapfPath": "/usr/local/py-utils/bin/yapf", - "python.linting.banditPath": "/usr/local/py-utils/bin/bandit", - "python.linting.flake8Path": "/usr/local/py-utils/bin/flake8", - "python.linting.mypyPath": "/usr/local/py-utils/bin/mypy", - "python.linting.pycodestylePath": "/usr/local/py-utils/bin/pycodestyle", - "python.linting.pydocstylePath": "/usr/local/py-utils/bin/pydocstyle", - "python.linting.pylintPath": "/usr/local/py-utils/bin/pylint", - "python.testing.pytestArgs": [ - "ietf" - ], - "python.testing.unittestEnabled": true, - "python.testing.pytestEnabled": false, - "python.testing.unittestArgs": [ - "-v", - "-s", - "./ietf", - "-p", - "test*.py" - ], - "sqltools.connections": [ - // Default connection to dev DB container - { - "name": "Local Dev", - "server": "db", - "port": 3306, - "database": "ietf_utf8", - "username": "django", - "password": "RkTkDPFnKpko", - "driver": "MySQL", - "askForPassword": false, - "connectionTimeout": 60 + + "customizations": { + "vscode": { + "extensions": [ + "vue.volar", + "batisteo.vscode-django", + "eamodio.gitlens", + "editorconfig.editorconfig", + "mrmlnc.vscode-duplicate", + "ms-azuretools.vscode-docker", + "ms-playwright.playwright", + "ms-python.python", + "ms-python.pylint", + "ms-python.vscode-pylance", + "mutantdino.resourcemonitor", + "oderwat.indent-rainbow", + "oxc.oxc-vscode", + "redhat.vscode-yaml", + "charliermarsh.ruff" + ], + "settings": { + "terminal.integrated.defaultProfile.linux": "zsh", + "python.pythonPath": "/usr/local/bin/python", + "python.languageServer": "Default", + "python.formatting.autopep8Path": "/usr/local/py-utils/bin/autopep8", + "python.formatting.blackPath": "/usr/local/py-utils/bin/black", + "python.formatting.yapfPath": "/usr/local/py-utils/bin/yapf", + "python.testing.pytestArgs": [ + "ietf" + ], + "python.testing.unittestEnabled": true, + "python.testing.pytestEnabled": false, + "python.testing.unittestArgs": [ + "-v", + "-s", + "./ietf", + "-p", + "test*.py" + ] } - ] - // "python.envFile": "${workspaceFolder}/.devcontainer/dev.env" + } }, - // Add the IDs of extensions you want installed when the container is created. - "extensions": [ - "arcanis.vscode-zipfs", - "batisteo.vscode-django", - "dbaeumer.vscode-eslint", - "eamodio.gitlens", - "editorconfig.editorconfig", - "vue.volar", - "mrmlnc.vscode-duplicate", - "ms-azuretools.vscode-docker", - "ms-python.python", - "ms-python.vscode-pylance", - "mtxr.sqltools-driver-mysql", - "mtxr.sqltools", - "mutantdino.resourcemonitor", - "oderwat.indent-rainbow", - "redhat.vscode-yaml", - "spmeesseman.vscode-taskexplorer", - "visualstudioexptteam.vscodeintellicode" - ], - // Use 'forwardPorts' to make a list of ports inside the container available locally. - "forwardPorts": [8000, 3306], + "forwardPorts": [3000, 5432, 8000], "portsAttributes": { "3000": { "label": "Vite", "onAutoForward": "silent" }, - "3306": { - "label": "MariaDB", + "5432": { + "label": "PostgreSQL", "onAutoForward": "silent" }, "8000": { - "label": "Datatracker", + "label": "NGINX", "onAutoForward": "notify" + }, + "8001": { + "label": "Datatracker", + "onAutoForward": "ignore" } }, diff --git a/.devcontainer/docker-compose.extend.yml b/.devcontainer/docker-compose.extend.yml index 3cab4ab8708..ce1ce259fdb 100644 --- a/.devcontainer/docker-compose.extend.yml +++ b/.devcontainer/docker-compose.extend.yml @@ -1,5 +1,3 @@ -version: '3.8' - services: app: environment: @@ -11,9 +9,13 @@ services: - /workspace/.vite - /workspace/.yarn/unplugged - app-assets:/assets - - datatracker-vscode-ext:/root/.vscode-server/extensions + # - datatracker-vscode-ext:/root/.vscode-server/extensions # Runs app on the same network as the database container, allows "forwardPorts" in devcontainer.json function. network_mode: service:db + blobstore: + ports: + - '9000:9000' + - '9001:9001' volumes: datatracker-vscode-ext: diff --git a/.editorconfig b/.editorconfig index 48e3b5f1532..7d5f138b355 100644 --- a/.editorconfig +++ b/.editorconfig @@ -6,40 +6,24 @@ root = true # Global settings for IETF datatracker # --------------------------------------------------------- -# PEP8 Style [*] -indent_size = 4 +indent_size = 2 indent_style = space charset = utf-8 -trim_trailing_whitespace = false +trim_trailing_whitespace = true insert_final_newline = true +end_of_line = lf # Specializations below *add to* the above defaults -# Settings for .github folder -# --------------------------------------------------------- -# GitHub Markdown Style - -[.github/**] -indent_size = 2 - -# Settings for client-side JS / Vue files +# Settings for Python files # --------------------------------------------------------- -# StandardJS Style - -[client/**] -indent_size = 2 - -[{package.json,.eslintrc.js,.yarnrc.yml,vite.config.js,cypress.config.js}] -indent_size = 2 - -# Settings for cypress tests -# --------------------------------------------------------- -# StandardJS Style +# PEP8 Style -[cypress/**] -indent_size = 2 +[*.{py,py.bak}] +indent_size = 4 +trim_trailing_whitespace = false # Settings for HTML templates # --------------------------------------------------------- @@ -47,3 +31,15 @@ indent_size = 2 [ietf/**.html] insert_final_newline = false + +# Settings for Markdown +# --------------------------------------------------------- +# Avoid trimming trailing whitespace +[*.md] +trim_trailing_whitespace = false + +# Unset for special / output files +# --------------------------------------------------------- +[{patch,vzic,bin}/**] +indent_style = unset +indent_size = unset diff --git a/.eslintrc.js b/.eslintrc.js deleted file mode 100644 index 498d6e77de6..00000000000 --- a/.eslintrc.js +++ /dev/null @@ -1,29 +0,0 @@ -module.exports = { - root: true, - env: { - browser: true, - es2021: true, - jquery: true, - node: true, - 'vue/setup-compiler-macros': true - }, - extends: [ - // 'plugin:vue/vue3-essential', // Priority A: Essential (Error Prevention) - 'plugin:vue/vue3-strongly-recommended', // Priority B: Strongly Recommended (Improving Readability) - 'plugin:cypress/recommended' - ], - globals: { - d3: true - }, - parserOptions: { - ecmaVersion: 'latest', - sourceType: 'module' - }, - plugins: [ - 'vue' - ], - rules: { - 'vue/script-setup-uses-vars': 'error', - 'vue/multi-word-component-names': 'off' - } -} diff --git a/.gitattributes b/.gitattributes index 937c0eb3795..62f4aae4323 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,2 +1,280 @@ -/.yarn/releases/** binary -/.yarn/plugins/** binary +# Auto detect text files and perform LF normalization +* text=auto + +# --------------------------------------------------- +# Python Projects +# --------------------------------------------------- + +# Source files +*.pxd text diff=python +*.py text diff=python +*.py3 text diff=python +*.pyw text diff=python +*.pyx text diff=python +*.pyz text diff=python +*.pyi text diff=python + +# Binary files +*.db binary +*.p binary +*.pkl binary +*.pickle binary +*.pyc binary export-ignore +*.pyo binary export-ignore +*.pyd binary + +# Jupyter notebook +*.ipynb text eol=lf + +# --------------------------------------------------- +# Web Projects +# --------------------------------------------------- + +# Source code +*.bash text eol=lf +*.bat text eol=crlf +*.cmd text eol=crlf +*.coffee text +*.css text diff=css +*.htm text diff=html +*.html text diff=html +*.inc text +*.ini text +*.js text +*.mjs text +*.cjs text +*.json text +*.jsx text +*.less text +*.ls text +*.map text -diff +*.od text +*.onlydata text +*.php text diff=php +*.pl text +*.ps1 text eol=crlf +*.py text diff=python +*.rb text diff=ruby +*.sass text +*.scm text +*.scss text diff=css +*.sh text eol=lf +.husky/* text eol=lf +*.sql text +*.styl text +*.tag text +*.ts text +*.tsx text +*.xml text +*.xhtml text diff=html + +# Docker +Dockerfile text + +# Documentation +*.ipynb text eol=lf +*.markdown text diff=markdown +*.md text diff=markdown +*.mdwn text diff=markdown +*.mdown text diff=markdown +*.mkd text diff=markdown +*.mkdn text diff=markdown +*.mdtxt text +*.mdtext text +*.txt text +AUTHORS text +CHANGELOG text +CHANGES text +CONTRIBUTING text +COPYING text +copyright text +*COPYRIGHT* text +INSTALL text +license text +LICENSE text +NEWS text +readme text +*README* text +TODO text + +# Templates +*.dot text +*.ejs text +*.erb text +*.haml text +*.handlebars text +*.hbs text +*.hbt text +*.jade text +*.latte text +*.mustache text +*.njk text +*.phtml text +*.pug text +*.svelte text +*.tmpl text +*.tpl text +*.twig text +*.vue text + +# Configs +*.cnf text +*.conf text +*.config text +.editorconfig text +.env text +.gitattributes text +.gitconfig text +.htaccess text +*.lock text -diff +package.json text eol=lf +package-lock.json text eol=lf -diff +pnpm-lock.yaml text eol=lf -diff +.prettierrc text +yarn.lock text -diff +*.toml text +*.yaml text +*.yml text +browserslist text +Makefile text +makefile text +# Fixes syntax highlighting on GitHub to allow comments +tsconfig.json linguist-language=JSON-with-Comments + +# Heroku +Procfile text + +# Graphics +*.ai binary +*.bmp binary +*.eps binary +*.gif binary +*.gifv binary +*.ico binary +*.jng binary +*.jp2 binary +*.jpg binary +*.jpeg binary +*.jpx binary +*.jxr binary +*.pdf binary +*.png binary +*.psb binary +*.psd binary +*.svg text +*.svgz binary +*.tif binary +*.tiff binary +*.wbmp binary +*.webp binary + +# Audio +*.kar binary +*.m4a binary +*.mid binary +*.midi binary +*.mp3 binary +*.ogg binary +*.ra binary + +# Video +*.3gpp binary +*.3gp binary +*.as binary +*.asf binary +*.asx binary +*.avi binary +*.fla binary +*.flv binary +*.m4v binary +*.mng binary +*.mov binary +*.mp4 binary +*.mpeg binary +*.mpg binary +*.ogv binary +*.swc binary +*.swf binary +*.webm binary + +# Archives +*.7z binary +*.gz binary +*.jar binary +*.rar binary +*.tar binary +*.zip binary + +# Fonts +*.ttf binary +*.eot binary +*.otf binary +*.woff binary +*.woff2 binary + +# Executables +*.exe binary +*.pyc binary +# Prevents massive diffs caused by vendored, minified files +**/.yarn/releases/** binary +**/.yarn/plugins/** binary + +# RC files (like .babelrc or .eslintrc) +*.*rc text + +# Ignore files (like .npmignore or .gitignore) +*.*ignore text + +# Prevents massive diffs from built files +dist/* binary + +# --------------------------------------------------- +# Common +# --------------------------------------------------- + +# Documents +*.bibtex text diff=bibtex +*.doc diff=astextplain +*.DOC diff=astextplain +*.docx diff=astextplain +*.DOCX diff=astextplain +*.dot diff=astextplain +*.DOT diff=astextplain +*.pdf diff=astextplain +*.PDF diff=astextplain +*.rtf diff=astextplain +*.RTF diff=astextplain +*.md text diff=markdown +*.mdx text diff=markdown +*.tex text diff=tex +*.adoc text +*.textile text +*.mustache text +*.csv text eol=crlf +*.tab text +*.tsv text +*.txt text +*.sql text +*.epub diff=astextplain + +# Text files where line endings should be preserved +*.patch -text + +# --------------------------------------------------- +# Vzic specific +# --------------------------------------------------- + +*.pl text diff=perl +*.pm text diff=perl + +# C/C++ +*.c text diff=cpp +*.cc text diff=cpp +*.cxx text diff=cpp +*.cpp text diff=cpp +*.cpi text diff=cpp +*.c++ text diff=cpp +*.hpp text diff=cpp +*.h text diff=cpp +*.h++ text diff=cpp +*.hh text diff=cpp \ No newline at end of file diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml index ef8822f5b67..320614b17ec 100644 --- a/.github/ISSUE_TEMPLATE/config.yml +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -1,8 +1,8 @@ -blank_issues_enabled: false -contact_links: - - name: Help / Questions - url: https://github.com/ietf-tools/datatracker/discussions/categories/help-questions - about: Need help? Have a question on setting up the project or its usage? - - name: Discuss New Ideas - url: https://github.com/ietf-tools/datatracker/discussions/categories/ideas - about: Submit ideas for new features or improvements to be discussed. +blank_issues_enabled: false +contact_links: + - name: Help and questions + url: https://github.com/ietf-tools/datatracker/discussions/categories/help-questions + about: Need help? Have a question on setting up the project or its usage? + - name: Discuss new ideas + url: https://github.com/ietf-tools/datatracker/discussions/categories/ideas + about: Submit ideas for new features or improvements to be discussed. diff --git a/.github/ISSUE_TEMPLATE/new-feature.yml b/.github/ISSUE_TEMPLATE/new-feature.yml index cf671768921..285081e1c8b 100644 --- a/.github/ISSUE_TEMPLATE/new-feature.yml +++ b/.github/ISSUE_TEMPLATE/new-feature.yml @@ -1,16 +1,17 @@ -name: New Feature / Enhancement -description: Propose a new idea to be implemented +name: Suggest new feature or enhancement +description: Propose a new idea to be implemented. labels: ["enhancement"] +type: Feature body: - type: markdown attributes: value: | - Thanks for taking the time to propose a new feature / enhancement idea. + Thanks for taking the time to propose a new feature or enhancement idea. - type: textarea id: description attributes: label: Description - description: Include as much info as possible, including mockups / screenshots if available. + description: Include as much info as possible, including mockups or screenshots if available. placeholder: Description validations: required: true diff --git a/.github/ISSUE_TEMPLATE/report-a-bug.yml b/.github/ISSUE_TEMPLATE/report-a-bug.yml index 0749f78956c..47fa1185b40 100644 --- a/.github/ISSUE_TEMPLATE/report-a-bug.yml +++ b/.github/ISSUE_TEMPLATE/report-a-bug.yml @@ -1,6 +1,7 @@ -name: Report a Bug -description: Something isn't right? File a bug report +name: Report a Datatracker bug +description: Something in the datatracker's behavior isn't right? File a bug report. Don't use this to report RFC errata or issues with the content of Internet-Drafts. labels: ["bug"] +type: Bug body: - type: markdown attributes: @@ -10,7 +11,7 @@ body: id: description attributes: label: Describe the issue - description: Include as much info as possible, including the current behavior, expected behavior, screenshots, etc. If this is a display / UX issue, make sure to list the browser(s) you're experiencing the issue on. + description: Include as much info as possible, including the current behavior, expected behavior, screenshots, etc. If this is a display or user interface issue, make sure to list the browser(s) you're experiencing the issue on. placeholder: Description validations: required: true @@ -22,3 +23,11 @@ body: options: - label: I agree to follow the [IETF's Code of Conduct](https://github.com/ietf-tools/.github/blob/main/CODE_OF_CONDUCT.md) required: true + - type: markdown + attributes: + value: | + If you are having trouble logging into the datatracker, please do not open an issue here. Instead, please send email to support@ietf.org providing your name and username. + - type: markdown + attributes: + value: | + **Please do not report issues with the content of Internet-Drafts or RFCs using this repository. Send email to the relevant group instead. Some Internet-Drafts have their own github repositories where issues can be reported. See the datatracker's page for the I-D for links and email addresses. Errata for published RFCs are submitted at https://www.rfc-editor.org/errata.php#reportnew** diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 00000000000..ffddad2c4c8 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,45 @@ +# To get started with Dependabot version updates, you'll need to specify which +# package ecosystems to update and where the package manifests are located. +# Please see the documentation for all configuration options: +# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates + +version: 2 +updates: + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "weekly" + - package-ecosystem: "docker" + directory: "/docker" + schedule: + interval: "weekly" + - package-ecosystem: "pip" + directory: "/" + schedule: + interval: "weekly" + reviewers: + - "rjsparks" + - package-ecosystem: "npm" + directory: "/" + schedule: + interval: "weekly" + groups: + npm: + patterns: + - "*" + - package-ecosystem: "npm" + directory: "/playwright" + schedule: + interval: "weekly" + groups: + npm: + patterns: + - "*" + - package-ecosystem: "npm" + directory: "/dev/diff" + schedule: + interval: "weekly" + groups: + npm: + patterns: + - "*" diff --git a/.github/semantic.yml b/.github/semantic.yml new file mode 100644 index 00000000000..be3439f6b97 --- /dev/null +++ b/.github/semantic.yml @@ -0,0 +1,3 @@ +enabled: true +titleOnly: true +targetUrl: "https://www.conventionalcommits.org/en/v1.0.0/#summary" diff --git a/.github/workflows/build-base-app.yml b/.github/workflows/build-base-app.yml index 6bc771def0d..a2abe089ce6 100644 --- a/.github/workflows/build-base-app.yml +++ b/.github/workflows/build-base-app.yml @@ -1,42 +1,67 @@ -name: Build Base App Docker Image - -on: - push: - branches: - - 'main' - paths: - - 'docker/base.Dockerfile' - - workflow_dispatch: - -jobs: - publish: - runs-on: ubuntu-latest - permissions: - contents: read - packages: write - - steps: - - uses: actions/checkout@v2 - - - name: Set up QEMU - uses: docker/setup-qemu-action@v2 - - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v2 - - - name: Login to GitHub Container Registry - uses: docker/login-action@v2 - with: - registry: ghcr.io - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - - - name: Docker Build & Push - uses: docker/build-push-action@v3 - with: - context: . - file: docker/base.Dockerfile - platforms: linux/amd64,linux/arm64 - push: true - tags: ghcr.io/ietf-tools/datatracker-app-base:latest +name: Build Base App Docker Image + +on: + push: + branches: + - 'main' + paths: + - 'docker/base.Dockerfile' + - 'requirements.txt' + + workflow_dispatch: + +jobs: + publish: + runs-on: ubuntu-latest + permissions: + contents: write + packages: write + + steps: + - uses: actions/checkout@v7 + with: + token: ${{ secrets.GH_COMMON_TOKEN }} + + - name: Set Version + run: | + printf -v CURDATE '%(%Y%m%dT%H%M)T' -1 + echo "IMGVERSION=$CURDATE" >> $GITHUB_ENV + + - name: Set up QEMU + uses: docker/setup-qemu-action@v4 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v4 + + - name: Login to GitHub Container Registry + uses: docker/login-action@v4 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Docker Build & Push + uses: docker/build-push-action@v7 + env: + DOCKER_BUILD_SUMMARY: false + with: + context: . + file: docker/base.Dockerfile + platforms: linux/amd64,linux/arm64 + push: true + tags: | + ghcr.io/ietf-tools/datatracker-app-base:${{ env.IMGVERSION }} + ghcr.io/ietf-tools/datatracker-app-base:py312 + ${{ github.ref == 'refs/heads/main' && 'ghcr.io/ietf-tools/datatracker-app-base:latest' || '' }} + + - name: Update version references + run: | + sed -i "1s/.*/FROM ghcr.io\/ietf-tools\/datatracker-app-base:${{ env.IMGVERSION }}/" dev/build/Dockerfile + echo "${{ env.IMGVERSION }}" > dev/build/TARGET_BASE + + - name: Commit CHANGELOG.md + uses: stefanzweifel/git-auto-commit-action@v7 + with: + branch: ${{ github.ref_name }} + commit_message: 'ci: update base image target version to ${{ env.IMGVERSION }}' + file_pattern: dev/build/Dockerfile dev/build/TARGET_BASE diff --git a/.github/workflows/build-devblobstore.yml b/.github/workflows/build-devblobstore.yml new file mode 100644 index 00000000000..429aa08b006 --- /dev/null +++ b/.github/workflows/build-devblobstore.yml @@ -0,0 +1,47 @@ +name: Build Dev/Test Blobstore Docker Image + +on: + push: + branches: + - 'main' + paths: + - '.github/workflows/build-devblobstore.yml' + + workflow_dispatch: + +env: + MINIO_VERSION: latest + +jobs: + publish: + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + + steps: + - uses: actions/checkout@v7 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v4 + + - name: Login to GitHub Container Registry + uses: docker/login-action@v4 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Docker Build & Push + uses: docker/build-push-action@v7 + env: + DOCKER_BUILD_SUMMARY: false + with: + context: . + file: docker/devblobstore.Dockerfile + platforms: linux/amd64,linux/arm64 + push: true + build-args: MINIO_VERSION=${{ env.MINIO_VERSION }} + tags: | + ghcr.io/ietf-tools/datatracker-devblobstore:${{ env.MINIO_VERSION }} + ghcr.io/ietf-tools/datatracker-devblobstore:latest diff --git a/.github/workflows/build-mq-broker.yml b/.github/workflows/build-mq-broker.yml new file mode 100644 index 00000000000..7832e65a3a3 --- /dev/null +++ b/.github/workflows/build-mq-broker.yml @@ -0,0 +1,63 @@ +name: Build MQ Broker Docker Image + +on: + push: + branches: + - 'main' + paths: + - 'dev/mq/**' + - '.github/workflows/build-mq-broker.yml' + + workflow_dispatch: + inputs: + rabbitmq_version: + description: 'RabbitMQ Version' + default: '3.13-alpine' + required: true + type: string + +jobs: + publish: + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + + steps: + - uses: actions/checkout@v7 + + - name: Set up QEMU + uses: docker/setup-qemu-action@v4 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v4 + + - name: Login to GitHub Container Registry + uses: docker/login-action@v4 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Set rabbitmq version + id: rabbitmq-version + run: | + if [[ "${{ inputs.rabbitmq_version }}" == "" ]]; then + echo "RABBITMQ_VERSION=3.13-alpine" >> $GITHUB_OUTPUT + else + echo "RABBITMQ_VERSION=${{ inputs.rabbitmq_version }}" >> $GITHUB_OUTPUT + fi + + - name: Docker Build & Push + uses: docker/build-push-action@v7 + env: + DOCKER_BUILD_SUMMARY: false + with: + context: . + file: dev/mq/Dockerfile + platforms: linux/amd64,linux/arm64 + push: true + build-args: RABBITMQ_VERSION=${{ steps.rabbitmq-version.outputs.RABBITMQ_VERSION }} + tags: | + ghcr.io/ietf-tools/datatracker-mq:${{ steps.rabbitmq-version.outputs.RABBITMQ_VERSION }} + ghcr.io/ietf-tools/datatracker-mq:latest diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 963bacb428a..e7f0f8abcd3 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,317 +1,244 @@ -name: Build and Release +name: Build Dev and Deploy +run-name: Dev Build ${{ github.run_number }} of branch ${{ github.ref_name }} by @${{ github.actor }} on: - push: - tags: - - '*' - workflow_dispatch: inputs: - publish: - description: 'Create Production Release' + deploy: + description: 'Deploy to K8S' + default: 'Skip' + required: true + type: choice + options: + - Skip + - Dev + - Staging + deployStrategy: + description: 'Deploy Strategy (Staging Only)' + default: 'Recreate' + required: true + type: choice + options: + - Recreate + - RollingUpdate + - Current + devNoDbRefresh: + description: 'Disable Daily DB Refresh (Dev Only)' + default: false required: true type: boolean - skiptests: + skipTests: description: 'Skip Tests' + default: false required: true type: boolean - dryrun: - description: 'Dry Run' + skipArmBuild: + description: 'Skip ARM64 Build' + default: false required: true type: boolean - summary: - description: 'Summary' - required: false - type: string - default: '' + ignoreLowerCoverage: + description: 'Ignore Lower Coverage' + default: false + required: true + type: boolean + updateCoverage: + description: 'Update Baseline Coverage' + default: false + required: true + type: boolean + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true jobs: # ----------------------------------------------------------------- # PREPARE # ----------------------------------------------------------------- prepare: - name: Prepare Release + name: Prepare runs-on: ubuntu-latest outputs: - should_deploy: ${{ steps.buildvars.outputs.should_deploy }} - pkg_version: ${{ steps.buildvars.outputs.pkg_version }} + buildVersion: ${{ steps.buildvars.outputs.buildVersion }} + previousVersion: ${{ steps.semver.outputs.current }} + baseImageVersion: ${{ steps.baseimgversion.outputs.baseImageVersion }} - steps: - - uses: actions/checkout@v2 + steps: + - uses: actions/checkout@v7 with: - fetch-depth: 0 - - - name: Dry Run Notify - if: ${{ github.event.inputs.dryrun == 'true' }} - run: | - echo "::notice::This is a DRY RUN of a production release. No release will be created." + fetch-depth: 1 + fetch-tags: false - - name: Get Next Version - if: ${{ github.event.inputs.publish == 'true' || github.event.inputs.dryrun == 'true' }} + - name: Get Dev Version id: semver uses: ietf-tools/semver-action@v1 with: token: ${{ github.token }} - branch: main - - - name: Set Next Version Env Var - if: ${{ github.event.inputs.publish == 'true' || github.event.inputs.dryrun == 'true' }} - run: | - echo "NEXT_VERSION=$nextStrict" >> $GITHUB_ENV - - - name: Create Draft Release - uses: ncipollo/release-action@v1 - if: ${{ github.event.inputs.publish == 'true' && github.event.inputs.dryrun == 'false' }} - with: - prerelease: true - draft: false - commit: ${{ github.sha }} - tag: ${{ env.NEXT_VERSION }} - name: ${{ env.NEXT_VERSION }} - body: '*pending*' - token: ${{ secrets.GITHUB_TOKEN }} + branch: release + skipInvalidTags: true + noVersionBumpBehavior: 'current' + noNewCommitBehavior: 'current' - name: Set Build Variables id: buildvars run: | - if [[ $NEXT_VERSION ]]; then - echo "Using AUTO SEMVER mode: $NEXT_VERSION" - echo "::set-output name=should_deploy::true" - echo "::set-output name=pkg_version::$NEXT_VERSION" - echo "::notice::Release $NEXT_VERSION created using branch $GITHUB_REF_NAME" - elif [[ "$GITHUB_REF" =~ ^refs/tags/* ]]; then - echo "Using TAG mode: $GITHUB_REF_NAME" - echo "::set-output name=should_deploy::true" - echo "::set-output name=pkg_version::$GITHUB_REF_NAME" - echo "::notice::Release $GITHUB_REF_NAME created using tag $GITHUB_REF_NAME" - else - echo "Using TEST mode: 8.0.0-dev.$GITHUB_RUN_NUMBER" - echo "::set-output name=should_deploy::false" - echo "::set-output name=pkg_version::8.0.0-dev.$GITHUB_RUN_NUMBER" - echo "::notice::Non-production build 8.0.0-dev.$GITHUB_RUN_NUMBER created using branch $GITHUB_REF_NAME" - fi + SHORT_SHA="${GITHUB_SHA:0:7}" + echo "Will set build version to: ${{ steps.semver.outputs.nextMajorStrict }}.0.0-dev.$SHORT_SHA" + echo "buildVersion=${{ steps.semver.outputs.nextMajorStrict }}.0.0-dev.$SHORT_SHA" >> $GITHUB_OUTPUT + echo "::notice::Non-production build ${{ steps.semver.outputs.nextMajorStrict }}.0.0-dev.$SHORT_SHA created using branch $GITHUB_REF_NAME" + + - name: Get Base Image Target Version + id: baseimgversion + run: | + echo "baseImageVersion=$(sed -n '1p' dev/build/TARGET_BASE)" >> $GITHUB_OUTPUT # ----------------------------------------------------------------- # TESTS # ----------------------------------------------------------------- - tests-python: - name: Run Tests (Python) - if: ${{ github.event.inputs.skiptests == 'false' }} + tests: + name: Run Tests + uses: ./.github/workflows/reusable-tests.yml + if: ${{ !inputs.skipTests }} needs: [prepare] - runs-on: ubuntu-latest - container: ghcr.io/ietf-tools/datatracker-app-base:latest - - services: - db: - image: ghcr.io/ietf-tools/datatracker-db:latest - volumes: - - mariadb-data:/var/lib/mysql - env: - MYSQL_ROOT_PASSWORD: ietf - MYSQL_DATABASE: ietf_utf8 - MYSQL_USER: django - MYSQL_PASSWORD: RkTkDPFnKpko - - steps: - - uses: actions/checkout@v3 - - - name: Prepare for tests - run: | - chmod +x ./dev/tests/prepare.sh - sh ./dev/tests/prepare.sh - - - name: Ensure DB is ready - run: | - /usr/local/bin/wait-for db:3306 -- echo "DB ready" - - - name: Run all tests - run: | - echo "Running checks..." - ./ietf/manage.py check - echo "Validating migrations..." - MSG=$(ietf/manage.py makemigrations 2>&1) - if ! ( echo ${MSG} | grep -q "^No changes detected$") ; then - echo "Model changes without migrations found." - echo ${MSG} - exit 1 - fi - echo "Running tests..." - ./ietf/manage.py test --settings=settings_sqlitetest - coverage xml - - - name: Upload Coverage Results to Codecov - uses: codecov/codecov-action@v2.1.0 - with: - files: coverage.xml - - - name: Convert Coverage Results - if: ${{ always() }} - run: | - mv latest-coverage.json coverage.json - - - name: Upload Coverage Results as Build Artifact - uses: actions/upload-artifact@v3.0.0 - if: ${{ always() }} - with: - name: coverage - path: coverage.json - - tests-cypress: - name: Run Tests (Cypress) - if: ${{ github.event.inputs.skiptests == 'false' }} - needs: [prepare] - runs-on: ubuntu-latest - container: ghcr.io/ietf-tools/datatracker-app-base:latest - - services: - db: - image: ghcr.io/ietf-tools/datatracker-db:latest - volumes: - - mariadb-data:/var/lib/mysql - env: - MYSQL_ROOT_PASSWORD: ietf - MYSQL_DATABASE: ietf_utf8 - MYSQL_USER: django - MYSQL_PASSWORD: RkTkDPFnKpko - - steps: - - uses: actions/checkout@v3 - - - name: Prepare for tests - run: | - chmod +x ./dev/tests/prepare.sh - sh ./dev/tests/prepare.sh - - - name: Ensure DB is ready - run: | - /usr/local/bin/wait-for db:3306 -- echo "DB ready" - - - name: Start Datatracker - run: | - echo "Running checks..." - ./ietf/manage.py check - echo "Starting datatracker..." - ./ietf/manage.py runserver 0.0.0.0:8000 --settings=settings_local & - echo "Waiting for datatracker to be ready..." - /usr/local/bin/wait-for localhost:8000 -- echo "Datatracker ready" + secrets: inherit + with: + ignoreLowerCoverage: ${{ inputs.ignoreLowerCoverage == 'true' }} + skipSelenium: true + targetBaseVersion: ${{ needs.prepare.outputs.baseImageVersion }} - - name: Run all tests - run: | - echo "Running tests..." - yarn cypress - - - name: Upload Video Recordings - uses: actions/upload-artifact@v3.0.0 - if: ${{ always() }} - with: - name: videos - path: cypress/videos/ + # ----------------------------------------------------------------- + # BUILD IMAGE + # ----------------------------------------------------------------- + build: + name: Build Image + uses: ./.github/workflows/reusable-build.yml + if: ${{ !failure() && !cancelled() }} + needs: [tests, prepare] + permissions: + contents: write + packages: write + secrets: inherit + with: + buildVersion: ${{ needs.prepare.outputs.buildVersion }} + isReleaseBuild: false + previousVersion: ${{ needs.prepare.outputs.previousVersion }} + handleCoverageResults: ${{ inputs.skipTests == 'false' }} + updateCoverageBaseline: ${{ inputs.updateCoverage }} + baseImageVersion: ${{ needs.prepare.outputs.baseImageVersion }} + skipArmBuild: ${{ inputs.skipArmBuild }} # ----------------------------------------------------------------- - # RELEASE + # NOTIFY # ----------------------------------------------------------------- - release: - name: Make Release + notify: + name: Notify if: ${{ always() }} - needs: [tests-python, tests-cypress, prepare] + needs: [prepare, tests, build] runs-on: ubuntu-latest env: - SHOULD_DEPLOY: ${{needs.prepare.outputs.should_deploy}} - PKG_VERSION: ${{needs.prepare.outputs.pkg_version}} - - steps: - - uses: actions/checkout@v2 - with: - fetch-depth: 0 + BUILD_VERSION: ${{ needs.prepare.outputs.buildVersion }} - - name: Setup Node.js - uses: actions/setup-node@v3.0.0 + steps: + - name: Notify on Slack (Success) + if: ${{ !contains(join(needs.*.result, ','), 'failure') }} + uses: slackapi/slack-github-action@v3 with: - node-version: 16.x - - - name: Setup Python - uses: actions/setup-python@v2 + token: ${{ secrets.SLACK_GH_BOT }} + method: chat.postMessage + payload: | + channel: ${{ secrets.SLACK_GH_BUILDS_CHANNEL_ID }} + text: "Datatracker Dev Build by ${{ github.triggering_actor }}" + attachments: + - color: "28a745" + fields: + - title: "Status" + short: true + value: "Completed" + - name: Notify on Slack (Failure) + if: ${{ contains(join(needs.*.result, ','), 'failure') }} + uses: slackapi/slack-github-action@v3 with: - python-version: '3.x' + token: ${{ secrets.SLACK_GH_BOT }} + method: chat.postMessage + payload: | + channel: ${{ secrets.SLACK_GH_BUILDS_CHANNEL_ID }} + text: "Datatracker Dev Build by ${{ github.triggering_actor }}" + attachments: + - color: "a82929" + fields: + - title: "Status" + short: true + value: "Failed 😱" - - name: Download a Coverage Results - if: ${{ github.event.inputs.skiptests == 'false' }} - uses: actions/download-artifact@v3.0.0 - with: - name: coverage + # ----------------------------------------------------------------- + # DEV + # ----------------------------------------------------------------- + dev: + name: Deploy to Dev + if: ${{ !failure() && !cancelled() && inputs.deploy == 'Dev' }} + needs: [prepare, build] + runs-on: ubuntu-latest + environment: + name: dev + env: + BUILD_VERSION: ${{ needs.prepare.outputs.buildVersion }} + + steps: + - uses: actions/checkout@v7 + with: + ref: main + + - name: Get Deploy Name + env: + DEBIAN_FRONTEND: noninteractive + run: | + echo "Install Get Deploy Name CLI dependencies..." + cd dev/k8s-get-deploy-name + npm ci + echo "Get Deploy Name..." + echo "DEPLOY_NAMESPACE=$(node cli.js --branch ${{ github.ref_name }})" >> "$GITHUB_ENV" - - name: Make Release Build - env: - DEBIAN_FRONTEND: noninteractive - run: | - echo "PKG_VERSION: $PKG_VERSION" - echo "GITHUB_SHA: $GITHUB_SHA" - echo "GITHUB_REF_NAME: $GITHUB_REF_NAME" - echo "Running build script..." - chmod +x ./dev/deploy/build.sh - sh ./dev/deploy/build.sh - echo "Setting version $PKG_VERSION..." - sed -i -r -e "s|^__version__ += '.*'$|__version__ = '$PKG_VERSION'|" ietf/__init__.py - sed -i -r -e "s|^__release_hash__ += '.*'$|__release_hash__ = '$GITHUB_SHA'|" ietf/__init__.py - sed -i -r -e "s|^__release_branch__ += '.*'$|__release_branch__ = '$GITHUB_REF_NAME'|" ietf/__init__.py + - name: Deploy to dev + uses: ietf-tools/workflow-dispatch-action@v1 + with: + workflow: deploy-dev.yml + repo: ietf-tools/infra-k8s + ref: main + token: ${{ secrets.GH_INFRA_K8S_TOKEN }} + inputs: '{ "app":"datatracker", "appVersion":"${{ env.BUILD_VERSION }}", "remoteRef":"${{ github.sha }}", "namespace":"${{ env.DEPLOY_NAMESPACE }}", "disableDailyDbRefresh":${{ inputs.devNoDbRefresh }} }' + waitForCompletionTimeout: 60m - - name: Set Production Flags - if: ${{ env.SHOULD_DEPLOY == 'true' }} - run: | - echo "Setting production flags in settings.py..." - sed -i -r -e 's/^DEBUG *= *.*$/DEBUG = False/' -e "s/^SERVER_MODE *= *.*\$/SERVER_MODE = 'production'/" ietf/settings.py - - - name: Make Release Tarball - env: - DEBIAN_FRONTEND: noninteractive - run: | - echo "Build release tarball..." - mkdir -p /home/runner/work/release - tar -czf /home/runner/work/release/release.tar.gz -X dev/deploy/exclude-patterns.txt . - - - name: Update CHANGELOG - id: changelog - uses: Requarks/changelog-action@v1 - if: ${{ env.SHOULD_DEPLOY == 'true' && github.event.inputs.dryrun == 'false' }} - with: - token: ${{ github.token }} - tag: ${{ env.PKG_VERSION }} - writeToFile: false + # ----------------------------------------------------------------- + # STAGING + # ----------------------------------------------------------------- + staging: + name: Deploy to Staging + if: ${{ !failure() && !cancelled() && inputs.deploy == 'Staging' }} + needs: [prepare, build] + runs-on: ubuntu-latest + environment: + name: staging + env: + BUILD_VERSION: ${{ needs.prepare.outputs.buildVersion }} + + steps: + - name: Refresh Staging DB + uses: ietf-tools/workflow-dispatch-action@v1 + with: + workflow: deploy-db.yml + repo: ietf-tools/infra-k8s + ref: main + token: ${{ secrets.GH_INFRA_K8S_TOKEN }} + inputs: '{ "environment":"${{ secrets.GHA_K8S_CLUSTER }}", "app":"datatracker", "manifest":"postgres", "forceRecreate":true, "restoreToLastFullSnapshot":true, "waitClusterReady":true }' + waitForCompletionTimeout: 120m - - name: Prepare Coverage Action - if: ${{ github.event.inputs.skiptests == 'false' }} - working-directory: ./dev/coverage-action - run: npm install - - - name: Process Coverage Stats + Chart - id: covprocess - uses: ./dev/coverage-action/ - if: ${{ github.event.inputs.skiptests == 'false' }} - with: - token: ${{ github.token }} - tokenCommon: ${{ secrets.GH_COMMON_TOKEN }} - repoCommon: common - version: ${{needs.prepare.outputs.pkg_version}} - changelog: ${{ steps.changelog.outputs.changes }} - summary: ${{ github.event.inputs.summary }} - coverageResultsPath: coverage.json - histCoveragePath: historical-coverage.json - - - name: Create Release - uses: ncipollo/release-action@v1 - if: ${{ env.SHOULD_DEPLOY == 'true' && github.event.inputs.dryrun == 'false' }} - with: - allowUpdates: true - draft: false - tag: ${{ env.PKG_VERSION }} - name: ${{ env.PKG_VERSION }} - body: ${{ steps.covprocess.outputs.changelog }} - artifacts: "/home/runner/work/release/release.tar.gz,coverage.json,historical-coverage.json" - token: ${{ secrets.GITHUB_TOKEN }} - - - name: Upload Build Artifacts - uses: actions/upload-artifact@v2.3.1 - if: ${{ env.SHOULD_DEPLOY == 'false' || github.event.inputs.dryrun == 'true' }} - with: - name: release-${{ env.PKG_VERSION }} - path: /home/runner/work/release/release.tar.gz + - name: Deploy to staging + uses: ietf-tools/workflow-dispatch-action@v1 + with: + workflow: deploy.yml + repo: ietf-tools/infra-k8s + ref: main + token: ${{ secrets.GH_INFRA_K8S_TOKEN }} + inputs: '{ "environment":"${{ secrets.GHA_K8S_CLUSTER }}", "app":"datatracker", "appVersion":"${{ env.BUILD_VERSION }}", "remoteRef":"${{ github.sha }}", "deployStrategy":"${{ inputs.deployStrategy }}" }' + waitForCompletionTimeout: 30m diff --git a/.github/workflows/ci-run-tests.yml b/.github/workflows/ci-run-tests.yml index fa96563ff1e..50ec4c1943b 100644 --- a/.github/workflows/ci-run-tests.yml +++ b/.github/workflows/ci-run-tests.yml @@ -1,72 +1,46 @@ -name: Run All Tests +name: PR - Run All Tests on: pull_request: branches: - 'main' + - 'feat/rfc' paths: + - 'client/**' - 'ietf/**' + - 'playwright/**' - 'requirements.txt' - 'package.json' jobs: - tests: - name: Run Tests + # ----------------------------------------------------------------- + # PREPARE + # ----------------------------------------------------------------- + prepare: + name: Prepare runs-on: ubuntu-latest - container: ghcr.io/ietf-tools/datatracker-app-base:latest - - services: - db: - image: ghcr.io/ietf-tools/datatracker-db:latest - volumes: - - mariadb-data:/var/lib/mysql - env: - MYSQL_ROOT_PASSWORD: ietf - MYSQL_DATABASE: ietf_utf8 - MYSQL_USER: django - MYSQL_PASSWORD: RkTkDPFnKpko - - steps: - - uses: actions/checkout@v3 - - - name: Prepare for tests - run: | - chmod +x ./dev/tests/prepare.sh - sh ./dev/tests/prepare.sh - - - name: Ensure DB is ready - run: | - /usr/local/bin/wait-for db:3306 -- echo "DB ready" - - - name: Run all tests - run: | - echo "Running checks..." - ./ietf/manage.py check - ./ietf/manage.py migrate - echo "Validating migrations..." - MSG=$(ietf/manage.py makemigrations 2>&1) - if ! ( echo ${MSG} | grep -q "^No changes detected$") ; then - echo "Model changes without migrations found." - echo ${MSG} - exit 1 - fi - echo "Running tests..." - ./ietf/manage.py test --settings=settings_sqlitetest - coverage xml + outputs: + base_image_version: ${{ steps.baseimgversion.outputs.base_image_version }} - - name: Upload Coverage Results to Codecov - uses: codecov/codecov-action@v2.1.0 + steps: + - uses: actions/checkout@v7 with: - files: coverage.xml - - - name: Convert Coverage Results - if: ${{ always() }} + fetch-depth: 1 + fetch-tags: false + + - name: Get Base Image Target Version + id: baseimgversion run: | - mv latest-coverage.json coverage.json - - - name: Upload Coverage Results as Build Artifact - uses: actions/upload-artifact@v3.0.0 - if: ${{ always() }} - with: - name: coverage - path: coverage.json + echo "base_image_version=$(sed -n '1p' dev/build/TARGET_BASE)" >> $GITHUB_OUTPUT + + # ----------------------------------------------------------------- + # TESTS + # ----------------------------------------------------------------- + tests: + name: Run Tests + uses: ./.github/workflows/reusable-tests.yml + needs: [prepare] + with: + ignoreLowerCoverage: false + skipSelenium: true + targetBaseVersion: ${{ needs.prepare.outputs.base_image_version }} diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 2ed7034d6ca..15b2231ce39 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -26,12 +26,12 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v2 + uses: actions/checkout@v7 - name: Initialize CodeQL - uses: github/codeql-action/init@v1 + uses: github/codeql-action/init@v4 with: languages: ${{ matrix.language }} - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v1 + uses: github/codeql-action/analyze@v4 diff --git a/.github/workflows/dependency-review.yml b/.github/workflows/dependency-review.yml new file mode 100644 index 00000000000..5bb26e4f6fa --- /dev/null +++ b/.github/workflows/dependency-review.yml @@ -0,0 +1,22 @@ +# Dependency Review Action +# +# This Action will scan dependency manifest files that change as part of a Pull Request, surfacing known-vulnerable versions of the packages declared or updated in the PR. Once installed, if the workflow run is marked as required, PRs introducing known-vulnerable packages will be blocked from merging. +# +# Source repository: https://github.com/actions/dependency-review-action +# Public documentation: https://docs.github.com/en/code-security/supply-chain-security/understanding-your-software-supply-chain/about-dependency-review#dependency-review-enforcement +name: 'Dependency Review' +on: [pull_request] + +permissions: + contents: read + +jobs: + dependency-review: + runs-on: ubuntu-latest + steps: + - name: 'Checkout Repository' + uses: actions/checkout@v7 + - name: 'Dependency Review' + uses: actions/dependency-review-action@v5 + with: + vulnerability-check: false diff --git a/.github/workflows/dev-assets-sync-nightly.yml b/.github/workflows/dev-assets-sync-nightly.yml new file mode 100644 index 00000000000..83121354e64 --- /dev/null +++ b/.github/workflows/dev-assets-sync-nightly.yml @@ -0,0 +1,49 @@ +# GITHUB ACTIONS - WORKFLOW + +# RSync the assets in the shared assets volume + +name: Nightly Dev Shared Assets Sync + +# Controls when the workflow will run +on: + # Run every night + schedule: + - cron: '0 1 * * *' + + # Run on app-rsync-extras.sh changes + push: + branches: + - main + paths: + - 'docker/scripts/app-rsync-extras.sh' + + # Allows you to run this workflow manually from the Actions tab + workflow_dispatch: + +jobs: + build: + name: Build Docker Image + runs-on: ubuntu-latest + if: ${{ github.event_name != 'schedule' }} + permissions: + contents: read + packages: write + steps: + - uses: actions/checkout@v7 + + - name: Login to GitHub Container Registry + uses: docker/login-action@v4 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Docker Build & Push + uses: docker/build-push-action@v7 + env: + DOCKER_BUILD_SUMMARY: false + with: + context: . + file: dev/shared-assets-sync/Dockerfile + push: true + tags: ghcr.io/ietf-tools/datatracker-rsync-assets:latest diff --git a/.github/workflows/dev-db-nightly.yml b/.github/workflows/dev-db-nightly.yml deleted file mode 100644 index 33e41633852..00000000000 --- a/.github/workflows/dev-db-nightly.yml +++ /dev/null @@ -1,94 +0,0 @@ -# GITHUB ACTIONS - WORKFLOW - -# Build the database dev docker image with the latest database dump every night -# so that developers don't have to manually build it themselves. - -# DB dump becomes available at around 0700 UTC, so schedule is set to 0800 UTC -# to account for variations. - -name: Nightly Dev DB Image - -# Controls when the workflow will run -on: - # Run every night - schedule: - - cron: '0 8 * * *' - - # Run on db.Dockerfile changes - push: - branches: - - main - paths: - - 'docker/db.Dockerfile' - - # Allows you to run this workflow manually from the Actions tab - workflow_dispatch: - -jobs: - build: - name: Build Docker Images - runs-on: ubuntu-latest - if: ${{ github.ref == 'refs/heads/main' }} - permissions: - contents: read - packages: write - strategy: - matrix: - include: - - platform: "linux/arm64" - docker: "arm64" - - platform: "linux/amd64" - docker: "x64" - steps: - - uses: actions/checkout@v2 - - - name: Set up QEMU - uses: docker/setup-qemu-action@v2 - - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v2 - - - name: Login to GitHub Container Registry - uses: docker/login-action@v2 - with: - registry: ghcr.io - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - - - name: Docker Build & Push - uses: docker/build-push-action@v3 - with: - context: . - file: docker/db.Dockerfile - platforms: ${{ matrix.platform }} - push: true - tags: ghcr.io/ietf-tools/datatracker-db:latest-${{ matrix.docker }} - - combine: - name: Create Docker Manifests - runs-on: ubuntu-latest - needs: [build] - permissions: - packages: write - steps: - - uses: actions/checkout@v2 - - - name: Get Current Date as Tag - id: date - run: echo "::set-output name=date::$(date +'%Y%m%d')" - - - name: Login to GitHub Container Registry - uses: docker/login-action@v2 - with: - registry: ghcr.io - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - - - name: Create and Push Manifests - run: | - echo "Creating the manifests..." - docker manifest create ghcr.io/ietf-tools/datatracker-db:nightly-${{ steps.date.outputs.date }} ghcr.io/ietf-tools/datatracker-db:latest-x64 ghcr.io/ietf-tools/datatracker-db:latest-arm64 - docker manifest create ghcr.io/ietf-tools/datatracker-db:latest ghcr.io/ietf-tools/datatracker-db:latest-x64 ghcr.io/ietf-tools/datatracker-db:latest-arm64 - echo "Pushing the manifests..." - docker manifest push -p ghcr.io/ietf-tools/datatracker-db:nightly-${{ steps.date.outputs.date }} - docker manifest push -p ghcr.io/ietf-tools/datatracker-db:latest diff --git a/.github/workflows/lock-threads.yml b/.github/workflows/lock-threads.yml index 7ce1f411e14..b90300c09b2 100644 --- a/.github/workflows/lock-threads.yml +++ b/.github/workflows/lock-threads.yml @@ -16,9 +16,10 @@ jobs: action: runs-on: ubuntu-latest steps: - - uses: dessant/lock-threads@v3 + - uses: dessant/lock-threads@v6 with: github-token: ${{ github.token }} + process-only: 'issues, prs' issue-inactive-days: 7 pr-inactive-days: 3 log-output: true diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 00000000000..2de02eb2852 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,209 @@ +name: Make Release and Deploy +run-name: RELEASE ${{ github.run_number }} by @${{ github.actor }} + +on: + workflow_dispatch: + inputs: + deployStrategy: + description: 'Deploy Strategy' + default: 'Recreate' + required: true + type: choice + options: + - Recreate + - RollingUpdate + - Current + +concurrency: + group: ${{ github.workflow }} + cancel-in-progress: true + +jobs: + # ----------------------------------------------------------------- + # PREPARE + # ----------------------------------------------------------------- + prepare: + name: Prepare Release + runs-on: ubuntu-latest + outputs: + buildVersion: ${{ steps.buildvars.outputs.buildVersion }} + previousVersion: ${{ steps.semver.outputs.current }} + baseImageVersion: ${{ steps.baseimgversion.outputs.baseImageVersion }} + + steps: + - name: Ensure release branch + if: github.ref != 'refs/heads/release' + run: | + echo "This workflow can only run on the 'release' branch (current: ${{ github.ref_name }})" + exit 1 + + - uses: actions/checkout@v7 + with: + fetch-depth: 1 + fetch-tags: false + + - name: Get Next Version + id: semver + uses: ietf-tools/semver-action@v1 + with: + token: ${{ github.token }} + branch: release + skipInvalidTags: true + patchList: fix, bugfix, perf, refactor, test, tests, chore + + - name: Create Draft Release + uses: ncipollo/release-action@v1.21.0 + with: + prerelease: true + draft: false + commit: ${{ github.sha }} + tag: ${{ steps.semver.outputs.nextStrict }} + name: ${{ steps.semver.outputs.nextStrict }} + body: '*pending*' + token: ${{ secrets.GITHUB_TOKEN }} + + - name: Set Build Variables + id: buildvars + run: | + echo "Will set build version to: ${{ steps.semver.outputs.nextStrict }}" + echo "buildVersion=${{ steps.semver.outputs.nextStrict }}" >> $GITHUB_OUTPUT + echo "::notice::Release ${{ steps.semver.outputs.nextStrict }} created using branch $GITHUB_REF_NAME" + + - name: Get Base Image Target Version + id: baseimgversion + run: | + echo "baseImageVersion=$(sed -n '1p' dev/build/TARGET_BASE)" >> $GITHUB_OUTPUT + + # ----------------------------------------------------------------- + # TESTS + # ----------------------------------------------------------------- + tests: + name: Run Tests + uses: ./.github/workflows/reusable-tests.yml + needs: [prepare] + secrets: inherit + with: + ignoreLowerCoverage: false + skipSelenium: true + targetBaseVersion: ${{ needs.prepare.outputs.baseImageVersion }} + + # ----------------------------------------------------------------- + # BUILD RELEASE + # ----------------------------------------------------------------- + build: + name: Build Release Image + uses: ./.github/workflows/reusable-build.yml + if: ${{ !failure() && !cancelled() }} + needs: [tests, prepare] + permissions: + contents: write + packages: write + secrets: inherit + with: + buildVersion: ${{needs.prepare.outputs.buildVersion}} + isReleaseBuild: true + previousVersion: ${{needs.prepare.outputs.previousVersion}} + handleCoverageResults: true + updateCoverageBaseline: true + baseImageVersion: ${{ needs.prepare.outputs.baseImageVersion }} + + # ----------------------------------------------------------------- + # NOTIFY + # ----------------------------------------------------------------- + notify: + name: Notify + if: ${{ always() }} + needs: [prepare, tests, build] + runs-on: ubuntu-latest + env: + BUILD_VERSION: ${{needs.prepare.outputs.buildVersion}} + + steps: + - name: Notify on Slack (Success) + if: ${{ !contains(join(needs.*.result, ','), 'failure') }} + uses: slackapi/slack-github-action@v3 + with: + token: ${{ secrets.SLACK_GH_BOT }} + method: chat.postMessage + payload: | + channel: ${{ secrets.SLACK_GH_BUILDS_CHANNEL_ID }} + text: "Datatracker Release Build by ${{ github.triggering_actor }}" + attachments: + - color: "28a745" + fields: + - title: "Status" + short: true + value: "Completed" + - name: Notify on Slack (Failure) + if: ${{ contains(join(needs.*.result, ','), 'failure') }} + uses: slackapi/slack-github-action@v3 + with: + token: ${{ secrets.SLACK_GH_BOT }} + method: chat.postMessage + payload: | + channel: ${{ secrets.SLACK_GH_BUILDS_CHANNEL_ID }} + text: "Datatracker Release Build by ${{ github.triggering_actor }}" + attachments: + - color: "a82929" + fields: + - title: "Status" + short: true + value: "Failed 😱" + + # ----------------------------------------------------------------- + # STAGING + # ----------------------------------------------------------------- + staging: + name: Deploy to Staging + if: ${{ !failure() && !cancelled() }} + needs: [prepare, build] + runs-on: ubuntu-latest + environment: + name: staging + env: + BUILD_VERSION: ${{needs.prepare.outputs.buildVersion}} + + steps: + - name: Refresh Staging DB + uses: ietf-tools/workflow-dispatch-action@v1 + with: + workflow: deploy-db.yml + repo: ietf-tools/infra-k8s + ref: main + token: ${{ secrets.GH_INFRA_K8S_TOKEN }} + inputs: '{ "environment":"${{ secrets.GHA_K8S_CLUSTER }}", "app":"datatracker", "manifest":"postgres", "forceRecreate":true, "restoreToLastFullSnapshot":true, "waitClusterReady":true }' + waitForCompletionTimeout: 120m + + - name: Deploy to staging + uses: ietf-tools/workflow-dispatch-action@v1 + with: + workflow: deploy.yml + repo: ietf-tools/infra-k8s + ref: main + token: ${{ secrets.GH_INFRA_K8S_TOKEN }} + inputs: '{ "environment":"${{ secrets.GHA_K8S_CLUSTER }}", "app":"datatracker", "appVersion":"${{ env.BUILD_VERSION }}", "remoteRef":"${{ github.sha }}", "deployStrategy":"${{ inputs.deployStrategy }}" }' + waitForCompletionTimeout: 30m + + # ----------------------------------------------------------------- + # PROD + # ----------------------------------------------------------------- + prod: + name: Deploy to Production + if: ${{ !failure() && !cancelled() }} + needs: [prepare, staging] + runs-on: ubuntu-latest + environment: + name: production + env: + BUILD_VERSION: ${{needs.prepare.outputs.buildVersion}} + + steps: + - name: Deploy to production + uses: ietf-tools/workflow-dispatch-action@v1 + with: + workflow: deploy.yml + repo: ietf-tools/infra-k8s + ref: main + token: ${{ secrets.GH_INFRA_K8S_TOKEN }} + inputs: '{ "environment":"${{ secrets.GHA_K8S_CLUSTER }}", "app":"datatracker", "appVersion":"${{ env.BUILD_VERSION }}", "remoteRef":"${{ github.sha }}", "deployStrategy":"${{ inputs.deployStrategy }}" }' + waitForCompletionTimeout: 30m diff --git a/.github/workflows/reusable-build.yml b/.github/workflows/reusable-build.yml new file mode 100644 index 00000000000..ca38345beee --- /dev/null +++ b/.github/workflows/reusable-build.yml @@ -0,0 +1,207 @@ +name: Reusable Build Workflow + +on: + workflow_call: + inputs: + buildVersion: + required: true + type: string + isReleaseBuild: + default: false + required: false + type: boolean + previousVersion: + required: false + type: string + handleCoverageResults: + default: true + required: false + type: boolean + updateCoverageBaseline: + default: false + required: false + type: boolean + baseImageVersion: + default: latest + required: false + type: string + skipArmBuild: + default: false + required: false + type: boolean + +jobs: + # ----------------------------------------------------------------- + # BUILD IMAGE + # ----------------------------------------------------------------- + build: + name: Build Image + runs-on: + group: hperf-8c32r + permissions: + contents: write + packages: write + + steps: + - uses: actions/checkout@v7 + with: + fetch-depth: 1 + fetch-tags: false + + - name: Setup Node.js environment + uses: actions/setup-node@v7 + with: + node-version: 18.x + + - name: Setup Python + uses: actions/setup-python@v6 + with: + python-version: "3.x" + + - name: Setup AWS CLI + uses: unfor19/install-aws-cli-action@v1 + with: + version: 2.22.35 + + - name: Download a Coverage Results + if: ${{ inputs.handleCoverageResults }} + uses: actions/download-artifact@v8.0.1 + with: + name: coverage + + - name: Make Build + env: + DEBIAN_FRONTEND: noninteractive + BROWSERSLIST_IGNORE_OLD_DATA: 1 + run: | + echo "BUILD_VERSION: ${{ inputs.buildVersion }}" + echo "GITHUB_SHA: $GITHUB_SHA" + echo "GITHUB_REF_NAME: $GITHUB_REF_NAME" + echo "Running frontend build script..." + echo "Installing node packages..." + npm ci + echo "Packaging static assets..." + npm run build -- --base=https://static.ietf.org/dt/${{ inputs.buildVersion }}/ + npm run legacy:build + echo "Setting version ${{ inputs.buildVersion }}..." + sed -i -r -e "s|^__version__ += '.*'$|__version__ = '${{ inputs.buildVersion }}'|" ietf/__init__.py + sed -i -r -e "s|^__release_hash__ += '.*'$|__release_hash__ = '$GITHUB_SHA'|" ietf/__init__.py + sed -i -r -e "s|^__release_branch__ += '.*'$|__release_branch__ = '$GITHUB_REF_NAME'|" ietf/__init__.py + + - name: Set Production Flags + if: ${{ inputs.isReleaseBuild }} + run: | + echo "Setting production flags in settings.py..." + sed -i -r -e 's/^DEBUG *= *.*$/DEBUG = False/' -e "s/^SERVER_MODE *= *.*\$/SERVER_MODE = 'production'/" ietf/settings.py + + - name: Make Tarball + env: + DEBIAN_FRONTEND: noninteractive + run: | + echo "Build release tarball..." + mkdir -p /home/runner/work/release + tar -czf /home/runner/work/release/release.tar.gz -X dev/build/exclude-patterns.txt . + + - name: Collect + Push Statics + env: + DEBIAN_FRONTEND: noninteractive + AWS_ACCESS_KEY_ID: ${{ secrets.CF_R2_STATIC_KEY_ID }} + AWS_SECRET_ACCESS_KEY: ${{ secrets.CF_R2_STATIC_KEY_SECRET }} + AWS_DEFAULT_REGION: auto + AWS_ENDPOINT_URL: ${{ secrets.CF_R2_ENDPOINT }} + run: | + echo "Collecting statics..." + echo "Using ghcr.io/ietf-tools/datatracker-app-base:${{ inputs.baseImageVersion }}" + docker run --rm --name collectstatics -v $(pwd):/workspace ghcr.io/ietf-tools/datatracker-app-base:${{ inputs.baseImageVersion }} sh dev/build/collectstatics.sh + echo "Pushing statics..." + cd static + aws s3 sync . s3://static/dt/${{ inputs.buildVersion }} --only-show-errors + + - name: Augment dockerignore for docker image build + env: + DEBIAN_FRONTEND: noninteractive + run: | + cat >> .dockerignore <> $GITHUB_ENV + + - name: Build Images + uses: docker/build-push-action@v7 + env: + DOCKER_BUILD_SUMMARY: false + with: + context: . + file: dev/build/Dockerfile + platforms: ${{ inputs.skipArmBuild && 'linux/amd64' || 'linux/amd64,linux/arm64' }} + push: true + tags: | + ghcr.io/ietf-tools/datatracker:${{ inputs.buildVersion }} + ${{ env.FEATURE_LATEST_TAG && format('ghcr.io/ietf-tools/datatracker:{0}-latest', env.FEATURE_LATEST_TAG) || null }} + + - name: Generate CHANGELOG + id: changelog + uses: Requarks/changelog-action@v1 + if: ${{ inputs.isReleaseBuild }} + with: + token: ${{ github.token }} + fromTag: ${{ inputs.buildVersion }} + toTag: ${{ inputs.previousVersion }} + writeToFile: false + + - name: Download Coverage Results + if: ${{ inputs.handleCoverageResults }} + uses: actions/download-artifact@v8 + with: + name: coverage + + - name: Create Release + uses: ncipollo/release-action@v1.21.0 + if: ${{ inputs.isReleaseBuild }} + with: + allowUpdates: true + makeLatest: true + draft: false + tag: ${{ inputs.buildVersion }} + name: ${{ inputs.buildVersion }} + body: ${{ steps.changelog.outputs.changes }} + artifacts: "/home/runner/work/release/release.tar.gz,coverage.json" + token: ${{ secrets.GITHUB_TOKEN }} + + - name: Update Baseline Coverage + uses: ncipollo/release-action@v1.21.0 + if: ${{ inputs.updateCoverageBaseline }} + with: + allowUpdates: true + tag: baseline + omitBodyDuringUpdate: true + omitNameDuringUpdate: true + omitPrereleaseDuringUpdate: true + replacesArtifacts: true + artifacts: "coverage.json" + token: ${{ secrets.GITHUB_TOKEN }} + + - name: Upload Build Artifacts + uses: actions/upload-artifact@v7 + with: + name: release-${{ inputs.buildVersion }} + path: /home/runner/work/release/release.tar.gz diff --git a/.github/workflows/reusable-tests.yml b/.github/workflows/reusable-tests.yml new file mode 100644 index 00000000000..90d09970acb --- /dev/null +++ b/.github/workflows/reusable-tests.yml @@ -0,0 +1,190 @@ +name: Reusable Tests Workflow + +on: + workflow_call: + inputs: + ignoreLowerCoverage: + description: 'Ignore Lower Coverage' + default: false + required: true + type: boolean + skipSelenium: + description: 'Skip Selenium Tests' + default: false + required: false + type: boolean + targetBaseVersion: + description: 'Target Base Image Version' + default: latest + required: false + type: string + +jobs: + tests-python: + name: Python Tests + runs-on: ubuntu-latest + container: ghcr.io/ietf-tools/datatracker-app-base:${{ inputs.targetBaseVersion }} + + services: + db: + image: ghcr.io/ietf-tools/datatracker-db:latest + blobstore: + image: ghcr.io/ietf-tools/datatracker-devblobstore:latest + + steps: + - uses: actions/checkout@v7 + + - name: Prepare for tests + run: | + chmod +x ./dev/tests/prepare.sh + sh ./dev/tests/prepare.sh + + - name: Ensure DB is ready + run: | + /usr/local/bin/wait-for db:5432 -- echo "DB ready" + + - name: Run all tests + shell: bash + run: | + echo "Running checks..." + ./ietf/manage.py check + ./ietf/manage.py migrate --fake-initial + echo "Validating migrations..." + if ! ( ietf/manage.py makemigrations --dry-run --check --verbosity 3 ) ; then + echo "Model changes without migrations found." + exit 1 + fi + if [[ "x${{ inputs.skipSelenium }}" == "xtrue" ]]; then + echo "Disable selenium tests..." + rm /usr/bin/geckodriver + fi + echo "Running tests..." + if [[ "x${{ inputs.ignoreLowerCoverage }}" == "xtrue" ]]; then + echo "Lower coverage failures will be ignored." + HOME=/root ./ietf/manage.py test -v2 --validate-html-harder --settings=settings_test --ignore-lower-coverage + else + HOME=/root ./ietf/manage.py test -v2 --validate-html-harder --settings=settings_test + fi + coverage xml + + - name: Upload geckodriver.log + uses: actions/upload-artifact@v7 + if: ${{ failure() }} + with: + name: geckodriverlog + path: geckodriver.log + + - name: Upload Coverage Results to Codecov + uses: codecov/codecov-action@v7 + with: + disable_search: true + files: coverage.xml + token: ${{ secrets.CODECOV_TOKEN }} + + - name: Convert Coverage Results + if: ${{ always() }} + run: | + mv latest-coverage.json coverage.json + + - name: Upload Coverage Results as Build Artifact + uses: actions/upload-artifact@v7 + if: ${{ always() }} + with: + name: coverage + path: coverage.json + + tests-playwright: + name: Playwright Tests + runs-on: macos-latest + strategy: + fail-fast: false + matrix: + project: [chromium, firefox] + + steps: + - uses: actions/checkout@v7 + + - uses: actions/setup-node@v7 + with: + node-version: '26' + + - name: Run all tests + run: | + echo "Installing dependencies..." + npm ci + echo "Installing Playwright..." + cd playwright + mkdir test-results + npm ci + npx playwright install --with-deps ${{ matrix.project }} + echo "Running tests..." + npx playwright test --project=${{ matrix.project }} + + - name: Upload Report + uses: actions/upload-artifact@v7 + if: ${{ always() }} + continue-on-error: true + with: + name: playwright-results-${{ matrix.project }} + path: playwright/test-results/ + if-no-files-found: ignore + + tests-playwright-legacy: + if: ${{ false }} # disable until we sort out suspected test runner issue + name: Playwright Legacy Tests + runs-on: ubuntu-latest + container: ghcr.io/ietf-tools/datatracker-app-base:${{ inputs.targetBaseVersion }} + strategy: + fail-fast: false + matrix: + project: [chromium, firefox] + + services: + db: + image: ghcr.io/ietf-tools/datatracker-db:latest + + steps: + - uses: actions/checkout@v7 + + - name: Prepare for tests + run: | + chmod +x ./dev/tests/prepare.sh + sh ./dev/tests/prepare.sh + + - name: Ensure DB is ready + run: | + /usr/local/bin/wait-for db:5432 -- echo "DB ready" + + - name: Start Datatracker + run: | + echo "Running checks..." + ./ietf/manage.py check + ./ietf/manage.py migrate --fake-initial + echo "Starting datatracker..." + ./ietf/manage.py runserver 0.0.0.0:8000 --settings=settings_local & + echo "Waiting for datatracker to be ready..." + /usr/local/bin/wait-for localhost:8000 -- echo "Datatracker ready" + + - name: Run all tests + env: + # Required to get firefox to run as root: + HOME: "" + run: | + echo "Installing dependencies..." + npm ci + echo "Installing Playwright..." + cd playwright + mkdir test-results + npm ci + npx playwright install --with-deps ${{ matrix.project }} + echo "Running tests..." + npx playwright test --project=${{ matrix.project }} -c playwright-legacy.config.js + + - name: Upload Report + uses: actions/upload-artifact@v7 + if: ${{ always() }} + continue-on-error: true + with: + name: playwright-legacy-results-${{ matrix.project }} + path: playwright/test-results/ + if-no-files-found: ignore diff --git a/.gitignore b/.gitignore index a515bae8a2c..ccc7a46b08d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ .DS_store datatracker.sublime-project datatracker.sublime-workspace +/.claude /.coverage /.factoryboy_random_state /.mypy_cache @@ -11,19 +12,23 @@ datatracker.sublime-workspace /.settings /.tmp /.vite +/client/dist /data /dist /docker/docker-compose.extend-custom.yml /env /ghostdriver.log +/geckodriver.log /htmlcov /ietf/static/dist-neue /latest-coverage.json /media /node_modules /release-coverage.json +/static /tmp-* /.testresult +*.swp *.pyc __pycache__ .yarn/* diff --git a/.npmrc b/.npmrc new file mode 100644 index 00000000000..fcbbb678280 --- /dev/null +++ b/.npmrc @@ -0,0 +1,5 @@ +audit = false +fund = false +save-exact = true +save-prefix = "" +update-notifier = false diff --git a/.oxfmtrc.json b/.oxfmtrc.json new file mode 100644 index 00000000000..518e8c95e1d --- /dev/null +++ b/.oxfmtrc.json @@ -0,0 +1,9 @@ +{ + "$schema": "./node_modules/oxfmt/configuration_schema.json", + "semi": false, + "singleQuote": true, + "trailingComma": "none", + "bracketSameLine": true, + "endOfLine": "lf", + "insertFinalNewline": true +} diff --git a/.oxlintrc.json b/.oxlintrc.json new file mode 100644 index 00000000000..d5648b966b8 --- /dev/null +++ b/.oxlintrc.json @@ -0,0 +1,10 @@ +{ + "$schema": "./node_modules/oxlint/configuration_schema.json", + "plugins": ["eslint", "typescript", "unicorn", "oxc", "vue"], + "env": { + "browser": true + }, + "categories": { + "correctness": "error" + } +} diff --git a/.pnp.cjs b/.pnp.cjs deleted file mode 100644 index 2ea8bb24303..00000000000 --- a/.pnp.cjs +++ /dev/null @@ -1,19115 +0,0 @@ -#!/usr/bin/env node -/* 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.`); -} - -function $$SETUP_STATE(hydrateRuntimeState, basePath) { - return hydrateRuntimeState(JSON.parse('{\ - "__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": [\ - {\ - "name": "root-workspace-0b6124",\ - "reference": "workspace:."\ - }\ - ],\ - "enableTopLevelFallback": true,\ - "ignorePatternData": "(^(?:\\\\.yarn\\\\/sdks(?:\\\\/(?!\\\\.{1,2}(?:\\\\/|$))(?:(?:(?!(?:^|\\\\/)\\\\.{1,2}(?:\\\\/|$)).)*?)|$))$)",\ - "fallbackExclusionList": [\ - ["root-workspace-0b6124", ["workspace:."]]\ - ],\ - "fallbackPool": [\ - ],\ - "packageRegistryData": [\ - [null, [\ - [null, {\ - "packageLocation": "./",\ - "packageDependencies": [\ - ["@fullcalendar/bootstrap5", "npm:5.11.0"],\ - ["@fullcalendar/core", "npm:5.11.0"],\ - ["@fullcalendar/daygrid", "npm:5.11.0"],\ - ["@fullcalendar/interaction", "npm:5.11.0"],\ - ["@fullcalendar/list", "npm:5.11.0"],\ - ["@fullcalendar/luxon2", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:5.11.0"],\ - ["@fullcalendar/timegrid", "npm:5.11.0"],\ - ["@fullcalendar/vue3", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:5.11.1"],\ - ["@parcel/transformer-sass", "npm:2.6.2"],\ - ["@popperjs/core", "npm:2.11.5"],\ - ["@vitejs/plugin-vue", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:2.3.3"],\ - ["@vue/test-utils", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:2.0.2"],\ - ["bootstrap", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:5.2.0"],\ - ["bootstrap-icons", "npm:1.9.1"],\ - ["browser-fs-access", "npm:0.31.0"],\ - ["browserlist", "npm:1.0.1"],\ - ["c8", "npm:7.12.0"],\ - ["caniuse-lite", "npm:1.0.30001368"],\ - ["cypress", "npm:10.3.1"],\ - ["cypress-real-events", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:1.7.1"],\ - ["d3", "npm:7.6.1"],\ - ["eslint", "npm:8.20.0"],\ - ["eslint-config-standard", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:17.0.0"],\ - ["eslint-plugin-cypress", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:2.12.1"],\ - ["eslint-plugin-import", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:2.26.0"],\ - ["eslint-plugin-node", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:11.1.0"],\ - ["eslint-plugin-promise", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:6.0.0"],\ - ["eslint-plugin-vue", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:9.2.0"],\ - ["file-saver", "npm:2.0.5"],\ - ["highcharts", "npm:10.2.0"],\ - ["html-validate", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:7.1.2"],\ - ["jquery", "npm:3.6.0"],\ - ["jquery-migrate", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:3.4.0"],\ - ["jquery-ui-dist", "npm:1.13.1"],\ - ["js-cookie", "npm:3.0.1"],\ - ["list.js", "npm:2.3.1"],\ - ["lodash", "npm:4.17.21"],\ - ["luxon", "npm:3.0.1"],\ - ["moment", "npm:2.29.4"],\ - ["moment-timezone", "npm:0.5.34"],\ - ["murmurhash-js", "npm:1.0.0"],\ - ["naive-ui", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:2.31.0"],\ - ["parcel", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:2.6.2"],\ - ["pinia", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:2.0.16"],\ - ["pinia-plugin-persist", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:1.0.0"],\ - ["pug", "npm:3.0.2"],\ - ["sass", "npm:1.53.0"],\ - ["select2", "npm:4.1.0-rc.0"],\ - ["select2-bootstrap-5-theme", "npm:1.3.0"],\ - ["slugify", "npm:1.6.5"],\ - ["sortablejs", "npm:1.15.0"],\ - ["vite", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:2.9.14"],\ - ["vitest", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:0.18.1"],\ - ["vue", "npm:3.2.37"],\ - ["vue-router", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:4.1.2"],\ - ["zxcvbn", "npm:4.4.2"]\ - ],\ - "linkType": "SOFT"\ - }]\ - ]],\ - ["@babel/code-frame", [\ - ["npm:7.16.7", {\ - "packageLocation": "./.yarn/cache/@babel-code-frame-npm-7.16.7-093eb9e124-db2f7faa31.zip/node_modules/@babel/code-frame/",\ - "packageDependencies": [\ - ["@babel/code-frame", "npm:7.16.7"],\ - ["@babel/highlight", "npm:7.17.12"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["@babel/helper-validator-identifier", [\ - ["npm:7.16.7", {\ - "packageLocation": "./.yarn/cache/@babel-helper-validator-identifier-npm-7.16.7-8599fb00fc-dbb3db9d18.zip/node_modules/@babel/helper-validator-identifier/",\ - "packageDependencies": [\ - ["@babel/helper-validator-identifier", "npm:7.16.7"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["@babel/highlight", [\ - ["npm:7.17.12", {\ - "packageLocation": "./.yarn/cache/@babel-highlight-npm-7.17.12-73223b881e-841a11aa35.zip/node_modules/@babel/highlight/",\ - "packageDependencies": [\ - ["@babel/highlight", "npm:7.17.12"],\ - ["@babel/helper-validator-identifier", "npm:7.16.7"],\ - ["chalk", "npm:2.4.2"],\ - ["js-tokens", "npm:4.0.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["@babel/parser", [\ - ["npm:7.18.4", {\ - "packageLocation": "./.yarn/cache/@babel-parser-npm-7.18.4-63fd355e07-e05b2dc720.zip/node_modules/@babel/parser/",\ - "packageDependencies": [\ - ["@babel/parser", "npm:7.18.4"],\ - ["@babel/types", "npm:7.18.4"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["@babel/types", [\ - ["npm:7.18.4", {\ - "packageLocation": "./.yarn/cache/@babel-types-npm-7.18.4-758c2695f8-85df59beb9.zip/node_modules/@babel/types/",\ - "packageDependencies": [\ - ["@babel/types", "npm:7.18.4"],\ - ["@babel/helper-validator-identifier", "npm:7.16.7"],\ - ["to-fast-properties", "npm:2.0.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["@bcoe/v8-coverage", [\ - ["npm:0.2.3", {\ - "packageLocation": "./.yarn/cache/@bcoe-v8-coverage-npm-0.2.3-9e27b3c57e-850f930553.zip/node_modules/@bcoe/v8-coverage/",\ - "packageDependencies": [\ - ["@bcoe/v8-coverage", "npm:0.2.3"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["@colors/colors", [\ - ["npm:1.5.0", {\ - "packageLocation": "./.yarn/cache/@colors-colors-npm-1.5.0-875af3a8b4-d64d5260be.zip/node_modules/@colors/colors/",\ - "packageDependencies": [\ - ["@colors/colors", "npm:1.5.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["@css-render/plugin-bem", [\ - ["npm:0.15.10", {\ - "packageLocation": "./.yarn/cache/@css-render-plugin-bem-npm-0.15.10-41ccecaa2f-cbab72a7b5.zip/node_modules/@css-render/plugin-bem/",\ - "packageDependencies": [\ - ["@css-render/plugin-bem", "npm:0.15.10"]\ - ],\ - "linkType": "SOFT"\ - }],\ - ["virtual:9f096c233074b200486016c951159c23194337e7c7d59a71ca2c42d04bf345037b52ab329d71315b0e0d2a9be58321dfafc718b2bc37ea4bde4e8e682754a169#npm:0.15.10", {\ - "packageLocation": "./.yarn/__virtual__/@css-render-plugin-bem-virtual-3b11288293/0/cache/@css-render-plugin-bem-npm-0.15.10-41ccecaa2f-cbab72a7b5.zip/node_modules/@css-render/plugin-bem/",\ - "packageDependencies": [\ - ["@css-render/plugin-bem", "virtual:9f096c233074b200486016c951159c23194337e7c7d59a71ca2c42d04bf345037b52ab329d71315b0e0d2a9be58321dfafc718b2bc37ea4bde4e8e682754a169#npm:0.15.10"],\ - ["@types/css-render", null],\ - ["css-render", "npm:0.15.10"]\ - ],\ - "packagePeers": [\ - "@types/css-render",\ - "css-render"\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["@css-render/vue3-ssr", [\ - ["npm:0.15.10", {\ - "packageLocation": "./.yarn/cache/@css-render-vue3-ssr-npm-0.15.10-b8526cc313-7977e0c440.zip/node_modules/@css-render/vue3-ssr/",\ - "packageDependencies": [\ - ["@css-render/vue3-ssr", "npm:0.15.10"]\ - ],\ - "linkType": "SOFT"\ - }],\ - ["virtual:9f096c233074b200486016c951159c23194337e7c7d59a71ca2c42d04bf345037b52ab329d71315b0e0d2a9be58321dfafc718b2bc37ea4bde4e8e682754a169#npm:0.15.10", {\ - "packageLocation": "./.yarn/__virtual__/@css-render-vue3-ssr-virtual-3e6ca7360a/0/cache/@css-render-vue3-ssr-npm-0.15.10-b8526cc313-7977e0c440.zip/node_modules/@css-render/vue3-ssr/",\ - "packageDependencies": [\ - ["@css-render/vue3-ssr", "virtual:9f096c233074b200486016c951159c23194337e7c7d59a71ca2c42d04bf345037b52ab329d71315b0e0d2a9be58321dfafc718b2bc37ea4bde4e8e682754a169#npm:0.15.10"],\ - ["@types/vue", null],\ - ["vue", "npm:3.2.37"]\ - ],\ - "packagePeers": [\ - "@types/vue",\ - "vue"\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["@cypress/request", [\ - ["npm:2.88.10", {\ - "packageLocation": "./.yarn/cache/@cypress-request-npm-2.88.10-44c588c8fc-69c3e3b332.zip/node_modules/@cypress/request/",\ - "packageDependencies": [\ - ["@cypress/request", "npm:2.88.10"],\ - ["aws-sign2", "npm:0.7.0"],\ - ["aws4", "npm:1.11.0"],\ - ["caseless", "npm:0.12.0"],\ - ["combined-stream", "npm:1.0.8"],\ - ["extend", "npm:3.0.2"],\ - ["forever-agent", "npm:0.6.1"],\ - ["form-data", "npm:2.3.3"],\ - ["http-signature", "npm:1.3.6"],\ - ["is-typedarray", "npm:1.0.0"],\ - ["isstream", "npm:0.1.2"],\ - ["json-stringify-safe", "npm:5.0.1"],\ - ["mime-types", "npm:2.1.35"],\ - ["performance-now", "npm:2.1.0"],\ - ["qs", "npm:6.5.3"],\ - ["safe-buffer", "npm:5.2.1"],\ - ["tough-cookie", "npm:2.5.0"],\ - ["tunnel-agent", "npm:0.6.0"],\ - ["uuid", "npm:8.3.2"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["@cypress/xvfb", [\ - ["npm:1.2.4", {\ - "packageLocation": "./.yarn/cache/@cypress-xvfb-npm-1.2.4-396a3691f7-7bdcdaeb1b.zip/node_modules/@cypress/xvfb/",\ - "packageDependencies": [\ - ["@cypress/xvfb", "npm:1.2.4"],\ - ["debug", "virtual:396a3691f7b25accf085fe2fff1f56eb7540eff3f2e928a7572ca1de9b831ff8f22136404f236aaed35d90369918dfc34392844d0f822a310563f34746dfb015#npm:3.2.7"],\ - ["lodash.once", "npm:4.1.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["@emotion/hash", [\ - ["npm:0.8.0", {\ - "packageLocation": "./.yarn/cache/@emotion-hash-npm-0.8.0-0104f4bbf3-4b35d88a97.zip/node_modules/@emotion/hash/",\ - "packageDependencies": [\ - ["@emotion/hash", "npm:0.8.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["@eslint/eslintrc", [\ - ["npm:1.3.0", {\ - "packageLocation": "./.yarn/cache/@eslint-eslintrc-npm-1.3.0-1f3c51be25-a1e734ad31.zip/node_modules/@eslint/eslintrc/",\ - "packageDependencies": [\ - ["@eslint/eslintrc", "npm:1.3.0"],\ - ["ajv", "npm:6.12.6"],\ - ["debug", "virtual:b86a9fb34323a98c6519528ed55faa0d9b44ca8879307c0b29aa384bde47ff59a7d0c9051b31246f14521dfb71ba3c5d6d0b35c29fffc17bf875aa6ad977d9e8#npm:4.3.4"],\ - ["espree", "npm:9.3.2"],\ - ["globals", "npm:13.15.0"],\ - ["ignore", "npm:5.2.0"],\ - ["import-fresh", "npm:3.3.0"],\ - ["js-yaml", "npm:4.1.0"],\ - ["minimatch", "npm:3.1.2"],\ - ["strip-json-comments", "npm:3.1.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["@fullcalendar/bootstrap5", [\ - ["npm:5.11.0", {\ - "packageLocation": "./.yarn/cache/@fullcalendar-bootstrap5-npm-5.11.0-2c476fdabc-164120b931.zip/node_modules/@fullcalendar/bootstrap5/",\ - "packageDependencies": [\ - ["@fullcalendar/bootstrap5", "npm:5.11.0"],\ - ["@fullcalendar/common", "npm:5.11.0"],\ - ["tslib", "npm:2.4.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["@fullcalendar/common", [\ - ["npm:5.11.0", {\ - "packageLocation": "./.yarn/cache/@fullcalendar-common-npm-5.11.0-5c975d3481-1bda749a43.zip/node_modules/@fullcalendar/common/",\ - "packageDependencies": [\ - ["@fullcalendar/common", "npm:5.11.0"],\ - ["tslib", "npm:2.4.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["@fullcalendar/core", [\ - ["npm:5.11.0", {\ - "packageLocation": "./.yarn/cache/@fullcalendar-core-npm-5.11.0-a3d247e75a-20e60c65af.zip/node_modules/@fullcalendar/core/",\ - "packageDependencies": [\ - ["@fullcalendar/core", "npm:5.11.0"],\ - ["@fullcalendar/common", "npm:5.11.0"],\ - ["preact", "npm:10.7.2"],\ - ["tslib", "npm:2.4.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["@fullcalendar/daygrid", [\ - ["npm:5.11.0", {\ - "packageLocation": "./.yarn/cache/@fullcalendar-daygrid-npm-5.11.0-4beb665944-d30105222f.zip/node_modules/@fullcalendar/daygrid/",\ - "packageDependencies": [\ - ["@fullcalendar/daygrid", "npm:5.11.0"],\ - ["@fullcalendar/common", "npm:5.11.0"],\ - ["tslib", "npm:2.4.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["@fullcalendar/interaction", [\ - ["npm:5.11.0", {\ - "packageLocation": "./.yarn/cache/@fullcalendar-interaction-npm-5.11.0-bdf2352cc1-625eb7ea33.zip/node_modules/@fullcalendar/interaction/",\ - "packageDependencies": [\ - ["@fullcalendar/interaction", "npm:5.11.0"],\ - ["@fullcalendar/common", "npm:5.11.0"],\ - ["tslib", "npm:2.4.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["@fullcalendar/list", [\ - ["npm:5.11.0", {\ - "packageLocation": "./.yarn/cache/@fullcalendar-list-npm-5.11.0-f90ee50a26-08be90dbdf.zip/node_modules/@fullcalendar/list/",\ - "packageDependencies": [\ - ["@fullcalendar/list", "npm:5.11.0"],\ - ["@fullcalendar/common", "npm:5.11.0"],\ - ["tslib", "npm:2.4.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["@fullcalendar/luxon2", [\ - ["npm:5.11.0", {\ - "packageLocation": "./.yarn/cache/@fullcalendar-luxon2-npm-5.11.0-c598bea26b-7be523ce12.zip/node_modules/@fullcalendar/luxon2/",\ - "packageDependencies": [\ - ["@fullcalendar/luxon2", "npm:5.11.0"]\ - ],\ - "linkType": "SOFT"\ - }],\ - ["virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:5.11.0", {\ - "packageLocation": "./.yarn/__virtual__/@fullcalendar-luxon2-virtual-651b5b1f0e/0/cache/@fullcalendar-luxon2-npm-5.11.0-c598bea26b-7be523ce12.zip/node_modules/@fullcalendar/luxon2/",\ - "packageDependencies": [\ - ["@fullcalendar/luxon2", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:5.11.0"],\ - ["@fullcalendar/common", "npm:5.11.0"],\ - ["@types/luxon", null],\ - ["luxon", "npm:3.0.1"],\ - ["tslib", "npm:2.4.0"]\ - ],\ - "packagePeers": [\ - "@types/luxon",\ - "luxon"\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["@fullcalendar/timegrid", [\ - ["npm:5.11.0", {\ - "packageLocation": "./.yarn/cache/@fullcalendar-timegrid-npm-5.11.0-13dce02247-4a7fb7fe3e.zip/node_modules/@fullcalendar/timegrid/",\ - "packageDependencies": [\ - ["@fullcalendar/timegrid", "npm:5.11.0"],\ - ["@fullcalendar/common", "npm:5.11.0"],\ - ["@fullcalendar/daygrid", "npm:5.11.0"],\ - ["tslib", "npm:2.4.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["@fullcalendar/vue3", [\ - ["npm:5.11.1", {\ - "packageLocation": "./.yarn/cache/@fullcalendar-vue3-npm-5.11.1-ec3de404fa-83ca9fecf5.zip/node_modules/@fullcalendar/vue3/",\ - "packageDependencies": [\ - ["@fullcalendar/vue3", "npm:5.11.1"]\ - ],\ - "linkType": "SOFT"\ - }],\ - ["virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:5.11.1", {\ - "packageLocation": "./.yarn/__virtual__/@fullcalendar-vue3-virtual-537468a83f/0/cache/@fullcalendar-vue3-npm-5.11.1-ec3de404fa-83ca9fecf5.zip/node_modules/@fullcalendar/vue3/",\ - "packageDependencies": [\ - ["@fullcalendar/vue3", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:5.11.1"],\ - ["@fullcalendar/core", "npm:5.11.0"],\ - ["@types/vue", null],\ - ["tslib", "npm:2.4.0"],\ - ["vue", "npm:3.2.37"]\ - ],\ - "packagePeers": [\ - "@types/vue",\ - "vue"\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["@gar/promisify", [\ - ["npm:1.1.3", {\ - "packageLocation": "./.yarn/cache/@gar-promisify-npm-1.1.3-ac1a325862-4059f790e2.zip/node_modules/@gar/promisify/",\ - "packageDependencies": [\ - ["@gar/promisify", "npm:1.1.3"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["@html-validate/stylish", [\ - ["npm:3.0.0", {\ - "packageLocation": "./.yarn/cache/@html-validate-stylish-npm-3.0.0-6d9dccafda-818efd25ac.zip/node_modules/@html-validate/stylish/",\ - "packageDependencies": [\ - ["@html-validate/stylish", "npm:3.0.0"],\ - ["kleur", "npm:4.1.4"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["@humanwhocodes/config-array", [\ - ["npm:0.9.5", {\ - "packageLocation": "./.yarn/cache/@humanwhocodes-config-array-npm-0.9.5-030a025eae-8ba6281bc0.zip/node_modules/@humanwhocodes/config-array/",\ - "packageDependencies": [\ - ["@humanwhocodes/config-array", "npm:0.9.5"],\ - ["@humanwhocodes/object-schema", "npm:1.2.1"],\ - ["debug", "virtual:b86a9fb34323a98c6519528ed55faa0d9b44ca8879307c0b29aa384bde47ff59a7d0c9051b31246f14521dfb71ba3c5d6d0b35c29fffc17bf875aa6ad977d9e8#npm:4.3.4"],\ - ["minimatch", "npm:3.1.2"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["@humanwhocodes/object-schema", [\ - ["npm:1.2.1", {\ - "packageLocation": "./.yarn/cache/@humanwhocodes-object-schema-npm-1.2.1-eb622b5d0e-a824a1ec31.zip/node_modules/@humanwhocodes/object-schema/",\ - "packageDependencies": [\ - ["@humanwhocodes/object-schema", "npm:1.2.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["@istanbuljs/schema", [\ - ["npm:0.1.3", {\ - "packageLocation": "./.yarn/cache/@istanbuljs-schema-npm-0.1.3-466bd3eaaa-5282759d96.zip/node_modules/@istanbuljs/schema/",\ - "packageDependencies": [\ - ["@istanbuljs/schema", "npm:0.1.3"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["@jridgewell/resolve-uri", [\ - ["npm:3.1.0", {\ - "packageLocation": "./.yarn/cache/@jridgewell-resolve-uri-npm-3.1.0-6ff2351e61-b5ceaaf9a1.zip/node_modules/@jridgewell/resolve-uri/",\ - "packageDependencies": [\ - ["@jridgewell/resolve-uri", "npm:3.1.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["@jridgewell/sourcemap-codec", [\ - ["npm:1.4.14", {\ - "packageLocation": "./.yarn/cache/@jridgewell-sourcemap-codec-npm-1.4.14-f5f0630788-61100637b6.zip/node_modules/@jridgewell/sourcemap-codec/",\ - "packageDependencies": [\ - ["@jridgewell/sourcemap-codec", "npm:1.4.14"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["@jridgewell/trace-mapping", [\ - ["npm:0.3.14", {\ - "packageLocation": "./.yarn/cache/@jridgewell-trace-mapping-npm-0.3.14-c78fcccfdf-b9537b9630.zip/node_modules/@jridgewell/trace-mapping/",\ - "packageDependencies": [\ - ["@jridgewell/trace-mapping", "npm:0.3.14"],\ - ["@jridgewell/resolve-uri", "npm:3.1.0"],\ - ["@jridgewell/sourcemap-codec", "npm:1.4.14"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["@juggle/resize-observer", [\ - ["npm:3.3.1", {\ - "packageLocation": "./.yarn/cache/@juggle-resize-observer-npm-3.3.1-f36d80a4f0-ddabc40442.zip/node_modules/@juggle/resize-observer/",\ - "packageDependencies": [\ - ["@juggle/resize-observer", "npm:3.3.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["@lezer/common", [\ - ["npm:0.15.12", {\ - "packageLocation": "./.yarn/cache/@lezer-common-npm-0.15.12-62017272b0-dae6581618.zip/node_modules/@lezer/common/",\ - "packageDependencies": [\ - ["@lezer/common", "npm:0.15.12"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["@lezer/lr", [\ - ["npm:0.15.8", {\ - "packageLocation": "./.yarn/cache/@lezer-lr-npm-0.15.8-8c481c39cd-e741225d6a.zip/node_modules/@lezer/lr/",\ - "packageDependencies": [\ - ["@lezer/lr", "npm:0.15.8"],\ - ["@lezer/common", "npm:0.15.12"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["@lmdb/lmdb-darwin-arm64", [\ - ["npm:2.5.2", {\ - "packageLocation": "./.yarn/unplugged/@lmdb-lmdb-darwin-arm64-npm-2.5.2-ba0aa88b93/node_modules/@lmdb/lmdb-darwin-arm64/",\ - "packageDependencies": [\ - ["@lmdb/lmdb-darwin-arm64", "npm:2.5.2"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["@lmdb/lmdb-darwin-x64", [\ - ["npm:2.5.2", {\ - "packageLocation": "./.yarn/unplugged/@lmdb-lmdb-darwin-x64-npm-2.5.2-237e0d1098/node_modules/@lmdb/lmdb-darwin-x64/",\ - "packageDependencies": [\ - ["@lmdb/lmdb-darwin-x64", "npm:2.5.2"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["@lmdb/lmdb-linux-arm", [\ - ["npm:2.5.2", {\ - "packageLocation": "./.yarn/unplugged/@lmdb-lmdb-linux-arm-npm-2.5.2-173e06820e/node_modules/@lmdb/lmdb-linux-arm/",\ - "packageDependencies": [\ - ["@lmdb/lmdb-linux-arm", "npm:2.5.2"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["@lmdb/lmdb-linux-arm64", [\ - ["npm:2.5.2", {\ - "packageLocation": "./.yarn/unplugged/@lmdb-lmdb-linux-arm64-npm-2.5.2-29a971842e/node_modules/@lmdb/lmdb-linux-arm64/",\ - "packageDependencies": [\ - ["@lmdb/lmdb-linux-arm64", "npm:2.5.2"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["@lmdb/lmdb-linux-x64", [\ - ["npm:2.5.2", {\ - "packageLocation": "./.yarn/unplugged/@lmdb-lmdb-linux-x64-npm-2.5.2-ca846c82b3/node_modules/@lmdb/lmdb-linux-x64/",\ - "packageDependencies": [\ - ["@lmdb/lmdb-linux-x64", "npm:2.5.2"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["@lmdb/lmdb-win32-x64", [\ - ["npm:2.5.2", {\ - "packageLocation": "./.yarn/unplugged/@lmdb-lmdb-win32-x64-npm-2.5.2-b6c28f5123/node_modules/@lmdb/lmdb-win32-x64/",\ - "packageDependencies": [\ - ["@lmdb/lmdb-win32-x64", "npm:2.5.2"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["@mischnic/json-sourcemap", [\ - ["npm:0.1.0", {\ - "packageLocation": "./.yarn/cache/@mischnic-json-sourcemap-npm-0.1.0-4b4af227b1-a30eda9eb0.zip/node_modules/@mischnic/json-sourcemap/",\ - "packageDependencies": [\ - ["@mischnic/json-sourcemap", "npm:0.1.0"],\ - ["@lezer/common", "npm:0.15.12"],\ - ["@lezer/lr", "npm:0.15.8"],\ - ["json5", "npm:2.2.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["@msgpackr-extract/msgpackr-extract-darwin-arm64", [\ - ["npm:2.0.2", {\ - "packageLocation": "./.yarn/unplugged/@msgpackr-extract-msgpackr-extract-darwin-arm64-npm-2.0.2-be5249cbca/node_modules/@msgpackr-extract/msgpackr-extract-darwin-arm64/",\ - "packageDependencies": [\ - ["@msgpackr-extract/msgpackr-extract-darwin-arm64", "npm:2.0.2"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["@msgpackr-extract/msgpackr-extract-darwin-x64", [\ - ["npm:2.0.2", {\ - "packageLocation": "./.yarn/unplugged/@msgpackr-extract-msgpackr-extract-darwin-x64-npm-2.0.2-aaad2bbcdd/node_modules/@msgpackr-extract/msgpackr-extract-darwin-x64/",\ - "packageDependencies": [\ - ["@msgpackr-extract/msgpackr-extract-darwin-x64", "npm:2.0.2"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["@msgpackr-extract/msgpackr-extract-linux-arm", [\ - ["npm:2.0.2", {\ - "packageLocation": "./.yarn/unplugged/@msgpackr-extract-msgpackr-extract-linux-arm-npm-2.0.2-bfe5ad30af/node_modules/@msgpackr-extract/msgpackr-extract-linux-arm/",\ - "packageDependencies": [\ - ["@msgpackr-extract/msgpackr-extract-linux-arm", "npm:2.0.2"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["@msgpackr-extract/msgpackr-extract-linux-arm64", [\ - ["npm:2.0.2", {\ - "packageLocation": "./.yarn/unplugged/@msgpackr-extract-msgpackr-extract-linux-arm64-npm-2.0.2-73fc5b0175/node_modules/@msgpackr-extract/msgpackr-extract-linux-arm64/",\ - "packageDependencies": [\ - ["@msgpackr-extract/msgpackr-extract-linux-arm64", "npm:2.0.2"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["@msgpackr-extract/msgpackr-extract-linux-x64", [\ - ["npm:2.0.2", {\ - "packageLocation": "./.yarn/unplugged/@msgpackr-extract-msgpackr-extract-linux-x64-npm-2.0.2-028869dc6b/node_modules/@msgpackr-extract/msgpackr-extract-linux-x64/",\ - "packageDependencies": [\ - ["@msgpackr-extract/msgpackr-extract-linux-x64", "npm:2.0.2"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["@msgpackr-extract/msgpackr-extract-win32-x64", [\ - ["npm:2.0.2", {\ - "packageLocation": "./.yarn/unplugged/@msgpackr-extract-msgpackr-extract-win32-x64-npm-2.0.2-c54981be26/node_modules/@msgpackr-extract/msgpackr-extract-win32-x64/",\ - "packageDependencies": [\ - ["@msgpackr-extract/msgpackr-extract-win32-x64", "npm:2.0.2"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["@npmcli/fs", [\ - ["npm:2.1.0", {\ - "packageLocation": "./.yarn/cache/@npmcli-fs-npm-2.1.0-3b106d08bc-6ec6d678af.zip/node_modules/@npmcli/fs/",\ - "packageDependencies": [\ - ["@npmcli/fs", "npm:2.1.0"],\ - ["@gar/promisify", "npm:1.1.3"],\ - ["semver", "npm:7.3.7"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["@npmcli/move-file", [\ - ["npm:2.0.0", {\ - "packageLocation": "./.yarn/cache/@npmcli-move-file-npm-2.0.0-d8bd1d35d2-1388777b50.zip/node_modules/@npmcli/move-file/",\ - "packageDependencies": [\ - ["@npmcli/move-file", "npm:2.0.0"],\ - ["mkdirp", "npm:1.0.4"],\ - ["rimraf", "npm:3.0.2"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["@parcel/bundler-default", [\ - ["npm:2.6.2", {\ - "packageLocation": "./.yarn/cache/@parcel-bundler-default-npm-2.6.2-99c549a93d-f99c2b673b.zip/node_modules/@parcel/bundler-default/",\ - "packageDependencies": [\ - ["@parcel/bundler-default", "npm:2.6.2"],\ - ["@parcel/diagnostic", "npm:2.6.2"],\ - ["@parcel/hash", "npm:2.6.2"],\ - ["@parcel/plugin", "npm:2.6.2"],\ - ["@parcel/utils", "npm:2.6.2"],\ - ["nullthrows", "npm:1.1.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["@parcel/cache", [\ - ["npm:2.6.2", {\ - "packageLocation": "./.yarn/cache/@parcel-cache-npm-2.6.2-7c97030a45-e7b540fe10.zip/node_modules/@parcel/cache/",\ - "packageDependencies": [\ - ["@parcel/cache", "npm:2.6.2"]\ - ],\ - "linkType": "SOFT"\ - }],\ - ["virtual:aa1797faca4a934b86d07dfa52e0db4db288b85fed415e745782ef9bd4bd39771970f9017a79cb7ed092d23d2539cea12a1cec949dfa0bb86e0fda2290caa70e#npm:2.6.2", {\ - "packageLocation": "./.yarn/__virtual__/@parcel-cache-virtual-f3b3d44508/0/cache/@parcel-cache-npm-2.6.2-7c97030a45-e7b540fe10.zip/node_modules/@parcel/cache/",\ - "packageDependencies": [\ - ["@parcel/cache", "virtual:aa1797faca4a934b86d07dfa52e0db4db288b85fed415e745782ef9bd4bd39771970f9017a79cb7ed092d23d2539cea12a1cec949dfa0bb86e0fda2290caa70e#npm:2.6.2"],\ - ["@parcel/core", "npm:2.6.2"],\ - ["@parcel/fs", "virtual:aa1797faca4a934b86d07dfa52e0db4db288b85fed415e745782ef9bd4bd39771970f9017a79cb7ed092d23d2539cea12a1cec949dfa0bb86e0fda2290caa70e#npm:2.6.2"],\ - ["@parcel/logger", "npm:2.6.2"],\ - ["@parcel/utils", "npm:2.6.2"],\ - ["@types/parcel__core", null],\ - ["lmdb", "npm:2.5.2"]\ - ],\ - "packagePeers": [\ - "@types/parcel__core"\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["@parcel/codeframe", [\ - ["npm:2.6.2", {\ - "packageLocation": "./.yarn/cache/@parcel-codeframe-npm-2.6.2-39f0ef1504-3253f42b90.zip/node_modules/@parcel/codeframe/",\ - "packageDependencies": [\ - ["@parcel/codeframe", "npm:2.6.2"],\ - ["chalk", "npm:4.1.2"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["@parcel/compressor-raw", [\ - ["npm:2.6.2", {\ - "packageLocation": "./.yarn/cache/@parcel-compressor-raw-npm-2.6.2-32d58189e9-fb147eb189.zip/node_modules/@parcel/compressor-raw/",\ - "packageDependencies": [\ - ["@parcel/compressor-raw", "npm:2.6.2"],\ - ["@parcel/plugin", "npm:2.6.2"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["@parcel/config-default", [\ - ["npm:2.6.2", {\ - "packageLocation": "./.yarn/cache/@parcel-config-default-npm-2.6.2-fd9b2d7d94-08cf9d08bb.zip/node_modules/@parcel/config-default/",\ - "packageDependencies": [\ - ["@parcel/config-default", "npm:2.6.2"]\ - ],\ - "linkType": "SOFT"\ - }],\ - ["virtual:84b0bbf7cdbd64ba6288b0a2db70a23b27d744d0bbf8200bb4b5364e102414e474ed93cd3bc30c30f0b0610197107cf6b488ea300fecc519f56b3d8403250c31#npm:2.6.2", {\ - "packageLocation": "./.yarn/__virtual__/@parcel-config-default-virtual-2d370753d9/0/cache/@parcel-config-default-npm-2.6.2-fd9b2d7d94-08cf9d08bb.zip/node_modules/@parcel/config-default/",\ - "packageDependencies": [\ - ["@parcel/config-default", "virtual:84b0bbf7cdbd64ba6288b0a2db70a23b27d744d0bbf8200bb4b5364e102414e474ed93cd3bc30c30f0b0610197107cf6b488ea300fecc519f56b3d8403250c31#npm:2.6.2"],\ - ["@parcel/bundler-default", "npm:2.6.2"],\ - ["@parcel/compressor-raw", "npm:2.6.2"],\ - ["@parcel/core", "npm:2.6.2"],\ - ["@parcel/namer-default", "npm:2.6.2"],\ - ["@parcel/optimizer-css", "npm:2.6.2"],\ - ["@parcel/optimizer-htmlnano", "npm:2.6.2"],\ - ["@parcel/optimizer-image", "npm:2.6.2"],\ - ["@parcel/optimizer-svgo", "npm:2.6.2"],\ - ["@parcel/optimizer-terser", "npm:2.6.2"],\ - ["@parcel/packager-css", "npm:2.6.2"],\ - ["@parcel/packager-html", "npm:2.6.2"],\ - ["@parcel/packager-js", "npm:2.6.2"],\ - ["@parcel/packager-raw", "npm:2.6.2"],\ - ["@parcel/packager-svg", "npm:2.6.2"],\ - ["@parcel/reporter-dev-server", "npm:2.6.2"],\ - ["@parcel/resolver-default", "npm:2.6.2"],\ - ["@parcel/runtime-browser-hmr", "npm:2.6.2"],\ - ["@parcel/runtime-js", "npm:2.6.2"],\ - ["@parcel/runtime-react-refresh", "npm:2.6.2"],\ - ["@parcel/runtime-service-worker", "npm:2.6.2"],\ - ["@parcel/transformer-babel", "npm:2.6.2"],\ - ["@parcel/transformer-css", "npm:2.6.2"],\ - ["@parcel/transformer-html", "npm:2.6.2"],\ - ["@parcel/transformer-image", "virtual:2d370753d95a3d52f78f3ca64747a2e25bcd4f0e5efd31562ad6d588b2ccc11b94c6454009cfedbb3ba5deb7d012ce632bc48fe055f74a2703cfedd634c0b462#npm:2.6.2"],\ - ["@parcel/transformer-js", "virtual:2d370753d95a3d52f78f3ca64747a2e25bcd4f0e5efd31562ad6d588b2ccc11b94c6454009cfedbb3ba5deb7d012ce632bc48fe055f74a2703cfedd634c0b462#npm:2.6.2"],\ - ["@parcel/transformer-json", "npm:2.6.2"],\ - ["@parcel/transformer-postcss", "npm:2.6.2"],\ - ["@parcel/transformer-posthtml", "npm:2.6.2"],\ - ["@parcel/transformer-raw", "npm:2.6.2"],\ - ["@parcel/transformer-react-refresh-wrap", "npm:2.6.2"],\ - ["@parcel/transformer-svg", "npm:2.6.2"],\ - ["@types/parcel__core", null]\ - ],\ - "packagePeers": [\ - "@parcel/core",\ - "@types/parcel__core"\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["@parcel/core", [\ - ["npm:2.6.2", {\ - "packageLocation": "./.yarn/cache/@parcel-core-npm-2.6.2-f04091cfa7-f550cbbd5e.zip/node_modules/@parcel/core/",\ - "packageDependencies": [\ - ["@parcel/core", "npm:2.6.2"],\ - ["@mischnic/json-sourcemap", "npm:0.1.0"],\ - ["@parcel/cache", "virtual:aa1797faca4a934b86d07dfa52e0db4db288b85fed415e745782ef9bd4bd39771970f9017a79cb7ed092d23d2539cea12a1cec949dfa0bb86e0fda2290caa70e#npm:2.6.2"],\ - ["@parcel/diagnostic", "npm:2.6.2"],\ - ["@parcel/events", "npm:2.6.2"],\ - ["@parcel/fs", "virtual:aa1797faca4a934b86d07dfa52e0db4db288b85fed415e745782ef9bd4bd39771970f9017a79cb7ed092d23d2539cea12a1cec949dfa0bb86e0fda2290caa70e#npm:2.6.2"],\ - ["@parcel/graph", "npm:2.6.2"],\ - ["@parcel/hash", "npm:2.6.2"],\ - ["@parcel/logger", "npm:2.6.2"],\ - ["@parcel/package-manager", "virtual:aa1797faca4a934b86d07dfa52e0db4db288b85fed415e745782ef9bd4bd39771970f9017a79cb7ed092d23d2539cea12a1cec949dfa0bb86e0fda2290caa70e#npm:2.6.2"],\ - ["@parcel/plugin", "npm:2.6.2"],\ - ["@parcel/source-map", "npm:2.0.5"],\ - ["@parcel/types", "npm:2.6.2"],\ - ["@parcel/utils", "npm:2.6.2"],\ - ["@parcel/workers", "virtual:aa1797faca4a934b86d07dfa52e0db4db288b85fed415e745782ef9bd4bd39771970f9017a79cb7ed092d23d2539cea12a1cec949dfa0bb86e0fda2290caa70e#npm:2.6.2"],\ - ["abortcontroller-polyfill", "npm:1.7.3"],\ - ["base-x", "npm:3.0.9"],\ - ["browserslist", "npm:4.20.3"],\ - ["clone", "npm:2.1.2"],\ - ["dotenv", "npm:7.0.0"],\ - ["dotenv-expand", "npm:5.1.0"],\ - ["json5", "npm:2.2.1"],\ - ["msgpackr", "npm:1.6.0"],\ - ["nullthrows", "npm:1.1.1"],\ - ["semver", "npm:5.7.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["@parcel/css", [\ - ["npm:1.10.1", {\ - "packageLocation": "./.yarn/cache/@parcel-css-npm-1.10.1-708147cb8f-699752d6ec.zip/node_modules/@parcel/css/",\ - "packageDependencies": [\ - ["@parcel/css", "npm:1.10.1"],\ - ["@parcel/css-darwin-arm64", "npm:1.10.1"],\ - ["@parcel/css-darwin-x64", "npm:1.10.1"],\ - ["@parcel/css-linux-arm-gnueabihf", "npm:1.10.1"],\ - ["@parcel/css-linux-arm64-gnu", "npm:1.10.1"],\ - ["@parcel/css-linux-arm64-musl", "npm:1.10.1"],\ - ["@parcel/css-linux-x64-gnu", "npm:1.10.1"],\ - ["@parcel/css-linux-x64-musl", "npm:1.10.1"],\ - ["@parcel/css-win32-x64-msvc", "npm:1.10.1"],\ - ["detect-libc", "npm:1.0.3"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["@parcel/css-darwin-arm64", [\ - ["npm:1.10.1", {\ - "packageLocation": "./.yarn/unplugged/@parcel-css-darwin-arm64-npm-1.10.1-03e9bc5743/node_modules/@parcel/css-darwin-arm64/",\ - "packageDependencies": [\ - ["@parcel/css-darwin-arm64", "npm:1.10.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["@parcel/css-darwin-x64", [\ - ["npm:1.10.1", {\ - "packageLocation": "./.yarn/unplugged/@parcel-css-darwin-x64-npm-1.10.1-9fe704042c/node_modules/@parcel/css-darwin-x64/",\ - "packageDependencies": [\ - ["@parcel/css-darwin-x64", "npm:1.10.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["@parcel/css-linux-arm-gnueabihf", [\ - ["npm:1.10.1", {\ - "packageLocation": "./.yarn/unplugged/@parcel-css-linux-arm-gnueabihf-npm-1.10.1-a264cbd3ab/node_modules/@parcel/css-linux-arm-gnueabihf/",\ - "packageDependencies": [\ - ["@parcel/css-linux-arm-gnueabihf", "npm:1.10.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["@parcel/css-linux-arm64-gnu", [\ - ["npm:1.10.1", {\ - "packageLocation": "./.yarn/unplugged/@parcel-css-linux-arm64-gnu-npm-1.10.1-f794ca00bb/node_modules/@parcel/css-linux-arm64-gnu/",\ - "packageDependencies": [\ - ["@parcel/css-linux-arm64-gnu", "npm:1.10.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["@parcel/css-linux-arm64-musl", [\ - ["npm:1.10.1", {\ - "packageLocation": "./.yarn/unplugged/@parcel-css-linux-arm64-musl-npm-1.10.1-44ec075319/node_modules/@parcel/css-linux-arm64-musl/",\ - "packageDependencies": [\ - ["@parcel/css-linux-arm64-musl", "npm:1.10.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["@parcel/css-linux-x64-gnu", [\ - ["npm:1.10.1", {\ - "packageLocation": "./.yarn/unplugged/@parcel-css-linux-x64-gnu-npm-1.10.1-a1033caa61/node_modules/@parcel/css-linux-x64-gnu/",\ - "packageDependencies": [\ - ["@parcel/css-linux-x64-gnu", "npm:1.10.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["@parcel/css-linux-x64-musl", [\ - ["npm:1.10.1", {\ - "packageLocation": "./.yarn/unplugged/@parcel-css-linux-x64-musl-npm-1.10.1-f741e7460b/node_modules/@parcel/css-linux-x64-musl/",\ - "packageDependencies": [\ - ["@parcel/css-linux-x64-musl", "npm:1.10.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["@parcel/css-win32-x64-msvc", [\ - ["npm:1.10.1", {\ - "packageLocation": "./.yarn/unplugged/@parcel-css-win32-x64-msvc-npm-1.10.1-38319dc193/node_modules/@parcel/css-win32-x64-msvc/",\ - "packageDependencies": [\ - ["@parcel/css-win32-x64-msvc", "npm:1.10.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["@parcel/diagnostic", [\ - ["npm:2.6.2", {\ - "packageLocation": "./.yarn/cache/@parcel-diagnostic-npm-2.6.2-ad66c9d460-c20c7b12c4.zip/node_modules/@parcel/diagnostic/",\ - "packageDependencies": [\ - ["@parcel/diagnostic", "npm:2.6.2"],\ - ["@mischnic/json-sourcemap", "npm:0.1.0"],\ - ["nullthrows", "npm:1.1.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["@parcel/events", [\ - ["npm:2.6.2", {\ - "packageLocation": "./.yarn/cache/@parcel-events-npm-2.6.2-c1dc15633e-272898db0c.zip/node_modules/@parcel/events/",\ - "packageDependencies": [\ - ["@parcel/events", "npm:2.6.2"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["@parcel/fs", [\ - ["npm:2.6.2", {\ - "packageLocation": "./.yarn/cache/@parcel-fs-npm-2.6.2-1670f601e3-b5e324d93b.zip/node_modules/@parcel/fs/",\ - "packageDependencies": [\ - ["@parcel/fs", "npm:2.6.2"]\ - ],\ - "linkType": "SOFT"\ - }],\ - ["virtual:aa1797faca4a934b86d07dfa52e0db4db288b85fed415e745782ef9bd4bd39771970f9017a79cb7ed092d23d2539cea12a1cec949dfa0bb86e0fda2290caa70e#npm:2.6.2", {\ - "packageLocation": "./.yarn/__virtual__/@parcel-fs-virtual-cfea854226/0/cache/@parcel-fs-npm-2.6.2-1670f601e3-b5e324d93b.zip/node_modules/@parcel/fs/",\ - "packageDependencies": [\ - ["@parcel/fs", "virtual:aa1797faca4a934b86d07dfa52e0db4db288b85fed415e745782ef9bd4bd39771970f9017a79cb7ed092d23d2539cea12a1cec949dfa0bb86e0fda2290caa70e#npm:2.6.2"],\ - ["@parcel/core", "npm:2.6.2"],\ - ["@parcel/fs-search", "npm:2.6.2"],\ - ["@parcel/types", "npm:2.6.2"],\ - ["@parcel/utils", "npm:2.6.2"],\ - ["@parcel/watcher", "npm:2.0.5"],\ - ["@parcel/workers", "virtual:aa1797faca4a934b86d07dfa52e0db4db288b85fed415e745782ef9bd4bd39771970f9017a79cb7ed092d23d2539cea12a1cec949dfa0bb86e0fda2290caa70e#npm:2.6.2"],\ - ["@types/parcel__core", null]\ - ],\ - "packagePeers": [\ - "@types/parcel__core"\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["@parcel/fs-search", [\ - ["npm:2.6.2", {\ - "packageLocation": "./.yarn/unplugged/@parcel-fs-search-npm-2.6.2-babb086a28/node_modules/@parcel/fs-search/",\ - "packageDependencies": [\ - ["@parcel/fs-search", "npm:2.6.2"],\ - ["detect-libc", "npm:1.0.3"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["@parcel/graph", [\ - ["npm:2.6.2", {\ - "packageLocation": "./.yarn/cache/@parcel-graph-npm-2.6.2-21a1647d01-74490009e8.zip/node_modules/@parcel/graph/",\ - "packageDependencies": [\ - ["@parcel/graph", "npm:2.6.2"],\ - ["@parcel/utils", "npm:2.6.2"],\ - ["nullthrows", "npm:1.1.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["@parcel/hash", [\ - ["npm:2.6.2", {\ - "packageLocation": "./.yarn/unplugged/@parcel-hash-npm-2.6.2-b2130ce130/node_modules/@parcel/hash/",\ - "packageDependencies": [\ - ["@parcel/hash", "npm:2.6.2"],\ - ["detect-libc", "npm:1.0.3"],\ - ["xxhash-wasm", "npm:0.4.2"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["@parcel/logger", [\ - ["npm:2.6.2", {\ - "packageLocation": "./.yarn/cache/@parcel-logger-npm-2.6.2-d7fe563ebb-d3536408da.zip/node_modules/@parcel/logger/",\ - "packageDependencies": [\ - ["@parcel/logger", "npm:2.6.2"],\ - ["@parcel/diagnostic", "npm:2.6.2"],\ - ["@parcel/events", "npm:2.6.2"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["@parcel/markdown-ansi", [\ - ["npm:2.6.2", {\ - "packageLocation": "./.yarn/cache/@parcel-markdown-ansi-npm-2.6.2-16ce118d53-742c64c5db.zip/node_modules/@parcel/markdown-ansi/",\ - "packageDependencies": [\ - ["@parcel/markdown-ansi", "npm:2.6.2"],\ - ["chalk", "npm:4.1.2"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["@parcel/namer-default", [\ - ["npm:2.6.2", {\ - "packageLocation": "./.yarn/cache/@parcel-namer-default-npm-2.6.2-a284c84566-259053a59f.zip/node_modules/@parcel/namer-default/",\ - "packageDependencies": [\ - ["@parcel/namer-default", "npm:2.6.2"],\ - ["@parcel/diagnostic", "npm:2.6.2"],\ - ["@parcel/plugin", "npm:2.6.2"],\ - ["nullthrows", "npm:1.1.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["@parcel/node-resolver-core", [\ - ["npm:2.6.2", {\ - "packageLocation": "./.yarn/cache/@parcel-node-resolver-core-npm-2.6.2-ddf86db312-7746b309fa.zip/node_modules/@parcel/node-resolver-core/",\ - "packageDependencies": [\ - ["@parcel/node-resolver-core", "npm:2.6.2"],\ - ["@parcel/diagnostic", "npm:2.6.2"],\ - ["@parcel/utils", "npm:2.6.2"],\ - ["nullthrows", "npm:1.1.1"],\ - ["semver", "npm:5.7.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["@parcel/optimizer-css", [\ - ["npm:2.6.2", {\ - "packageLocation": "./.yarn/cache/@parcel-optimizer-css-npm-2.6.2-8806a46a86-d1179276f4.zip/node_modules/@parcel/optimizer-css/",\ - "packageDependencies": [\ - ["@parcel/optimizer-css", "npm:2.6.2"],\ - ["@parcel/css", "npm:1.10.1"],\ - ["@parcel/diagnostic", "npm:2.6.2"],\ - ["@parcel/plugin", "npm:2.6.2"],\ - ["@parcel/source-map", "npm:2.0.5"],\ - ["@parcel/utils", "npm:2.6.2"],\ - ["browserslist", "npm:4.20.3"],\ - ["nullthrows", "npm:1.1.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["@parcel/optimizer-htmlnano", [\ - ["npm:2.6.2", {\ - "packageLocation": "./.yarn/cache/@parcel-optimizer-htmlnano-npm-2.6.2-3a6cbfa587-3b86fb1b17.zip/node_modules/@parcel/optimizer-htmlnano/",\ - "packageDependencies": [\ - ["@parcel/optimizer-htmlnano", "npm:2.6.2"],\ - ["@parcel/plugin", "npm:2.6.2"],\ - ["htmlnano", "virtual:3a6cbfa587d4870ab3a0c1483e53d38c90b75222449e94f708edd9df02a7aeb0eada20885838b455e0694092bf130d1a617be06492c01a37600b15ec855f7ed0#npm:2.0.2"],\ - ["nullthrows", "npm:1.1.1"],\ - ["posthtml", "npm:0.16.6"],\ - ["svgo", "npm:2.8.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["@parcel/optimizer-image", [\ - ["npm:2.6.2", {\ - "packageLocation": "./.yarn/unplugged/@parcel-optimizer-image-npm-2.6.2-da334eea79/node_modules/@parcel/optimizer-image/",\ - "packageDependencies": [\ - ["@parcel/optimizer-image", "npm:2.6.2"],\ - ["@parcel/core", "npm:2.6.2"],\ - ["@parcel/diagnostic", "npm:2.6.2"],\ - ["@parcel/plugin", "npm:2.6.2"],\ - ["@parcel/utils", "npm:2.6.2"],\ - ["@parcel/workers", "virtual:aa1797faca4a934b86d07dfa52e0db4db288b85fed415e745782ef9bd4bd39771970f9017a79cb7ed092d23d2539cea12a1cec949dfa0bb86e0fda2290caa70e#npm:2.6.2"],\ - ["detect-libc", "npm:1.0.3"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["@parcel/optimizer-svgo", [\ - ["npm:2.6.2", {\ - "packageLocation": "./.yarn/cache/@parcel-optimizer-svgo-npm-2.6.2-48d274d3c4-00b6737805.zip/node_modules/@parcel/optimizer-svgo/",\ - "packageDependencies": [\ - ["@parcel/optimizer-svgo", "npm:2.6.2"],\ - ["@parcel/diagnostic", "npm:2.6.2"],\ - ["@parcel/plugin", "npm:2.6.2"],\ - ["@parcel/utils", "npm:2.6.2"],\ - ["svgo", "npm:2.8.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["@parcel/optimizer-terser", [\ - ["npm:2.6.2", {\ - "packageLocation": "./.yarn/cache/@parcel-optimizer-terser-npm-2.6.2-a5c22918d5-1b9cdee197.zip/node_modules/@parcel/optimizer-terser/",\ - "packageDependencies": [\ - ["@parcel/optimizer-terser", "npm:2.6.2"],\ - ["@parcel/diagnostic", "npm:2.6.2"],\ - ["@parcel/plugin", "npm:2.6.2"],\ - ["@parcel/source-map", "npm:2.0.5"],\ - ["@parcel/utils", "npm:2.6.2"],\ - ["nullthrows", "npm:1.1.1"],\ - ["terser", "npm:5.13.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["@parcel/package-manager", [\ - ["npm:2.6.2", {\ - "packageLocation": "./.yarn/cache/@parcel-package-manager-npm-2.6.2-41edbfb7da-0c7dfce953.zip/node_modules/@parcel/package-manager/",\ - "packageDependencies": [\ - ["@parcel/package-manager", "npm:2.6.2"]\ - ],\ - "linkType": "SOFT"\ - }],\ - ["virtual:aa1797faca4a934b86d07dfa52e0db4db288b85fed415e745782ef9bd4bd39771970f9017a79cb7ed092d23d2539cea12a1cec949dfa0bb86e0fda2290caa70e#npm:2.6.2", {\ - "packageLocation": "./.yarn/__virtual__/@parcel-package-manager-virtual-423c759aca/0/cache/@parcel-package-manager-npm-2.6.2-41edbfb7da-0c7dfce953.zip/node_modules/@parcel/package-manager/",\ - "packageDependencies": [\ - ["@parcel/package-manager", "virtual:aa1797faca4a934b86d07dfa52e0db4db288b85fed415e745782ef9bd4bd39771970f9017a79cb7ed092d23d2539cea12a1cec949dfa0bb86e0fda2290caa70e#npm:2.6.2"],\ - ["@parcel/core", "npm:2.6.2"],\ - ["@parcel/diagnostic", "npm:2.6.2"],\ - ["@parcel/fs", "virtual:aa1797faca4a934b86d07dfa52e0db4db288b85fed415e745782ef9bd4bd39771970f9017a79cb7ed092d23d2539cea12a1cec949dfa0bb86e0fda2290caa70e#npm:2.6.2"],\ - ["@parcel/logger", "npm:2.6.2"],\ - ["@parcel/types", "npm:2.6.2"],\ - ["@parcel/utils", "npm:2.6.2"],\ - ["@parcel/workers", "virtual:aa1797faca4a934b86d07dfa52e0db4db288b85fed415e745782ef9bd4bd39771970f9017a79cb7ed092d23d2539cea12a1cec949dfa0bb86e0fda2290caa70e#npm:2.6.2"],\ - ["@types/parcel__core", null],\ - ["semver", "npm:5.7.1"]\ - ],\ - "packagePeers": [\ - "@types/parcel__core"\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["@parcel/packager-css", [\ - ["npm:2.6.2", {\ - "packageLocation": "./.yarn/cache/@parcel-packager-css-npm-2.6.2-4c2ce40a16-70d0c5195f.zip/node_modules/@parcel/packager-css/",\ - "packageDependencies": [\ - ["@parcel/packager-css", "npm:2.6.2"],\ - ["@parcel/plugin", "npm:2.6.2"],\ - ["@parcel/source-map", "npm:2.0.5"],\ - ["@parcel/utils", "npm:2.6.2"],\ - ["nullthrows", "npm:1.1.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["@parcel/packager-html", [\ - ["npm:2.6.2", {\ - "packageLocation": "./.yarn/cache/@parcel-packager-html-npm-2.6.2-44f9c9a0af-5f0095111d.zip/node_modules/@parcel/packager-html/",\ - "packageDependencies": [\ - ["@parcel/packager-html", "npm:2.6.2"],\ - ["@parcel/plugin", "npm:2.6.2"],\ - ["@parcel/types", "npm:2.6.2"],\ - ["@parcel/utils", "npm:2.6.2"],\ - ["nullthrows", "npm:1.1.1"],\ - ["posthtml", "npm:0.16.6"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["@parcel/packager-js", [\ - ["npm:2.6.2", {\ - "packageLocation": "./.yarn/cache/@parcel-packager-js-npm-2.6.2-fc8a4a80e6-b441a709c6.zip/node_modules/@parcel/packager-js/",\ - "packageDependencies": [\ - ["@parcel/packager-js", "npm:2.6.2"],\ - ["@parcel/diagnostic", "npm:2.6.2"],\ - ["@parcel/hash", "npm:2.6.2"],\ - ["@parcel/plugin", "npm:2.6.2"],\ - ["@parcel/source-map", "npm:2.0.5"],\ - ["@parcel/utils", "npm:2.6.2"],\ - ["globals", "npm:13.15.0"],\ - ["nullthrows", "npm:1.1.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["@parcel/packager-raw", [\ - ["npm:2.6.2", {\ - "packageLocation": "./.yarn/cache/@parcel-packager-raw-npm-2.6.2-c2c82c87c4-c067a612c0.zip/node_modules/@parcel/packager-raw/",\ - "packageDependencies": [\ - ["@parcel/packager-raw", "npm:2.6.2"],\ - ["@parcel/plugin", "npm:2.6.2"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["@parcel/packager-svg", [\ - ["npm:2.6.2", {\ - "packageLocation": "./.yarn/cache/@parcel-packager-svg-npm-2.6.2-91ca24db32-50468d382f.zip/node_modules/@parcel/packager-svg/",\ - "packageDependencies": [\ - ["@parcel/packager-svg", "npm:2.6.2"],\ - ["@parcel/plugin", "npm:2.6.2"],\ - ["@parcel/types", "npm:2.6.2"],\ - ["@parcel/utils", "npm:2.6.2"],\ - ["posthtml", "npm:0.16.6"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["@parcel/plugin", [\ - ["npm:2.6.2", {\ - "packageLocation": "./.yarn/cache/@parcel-plugin-npm-2.6.2-d1ea2dda44-23da0fa372.zip/node_modules/@parcel/plugin/",\ - "packageDependencies": [\ - ["@parcel/plugin", "npm:2.6.2"],\ - ["@parcel/types", "npm:2.6.2"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["@parcel/reporter-cli", [\ - ["npm:2.6.2", {\ - "packageLocation": "./.yarn/cache/@parcel-reporter-cli-npm-2.6.2-04e1d13b83-27486b9c5c.zip/node_modules/@parcel/reporter-cli/",\ - "packageDependencies": [\ - ["@parcel/reporter-cli", "npm:2.6.2"],\ - ["@parcel/plugin", "npm:2.6.2"],\ - ["@parcel/types", "npm:2.6.2"],\ - ["@parcel/utils", "npm:2.6.2"],\ - ["chalk", "npm:4.1.2"],\ - ["term-size", "npm:2.2.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["@parcel/reporter-dev-server", [\ - ["npm:2.6.2", {\ - "packageLocation": "./.yarn/cache/@parcel-reporter-dev-server-npm-2.6.2-22ced32479-44007a3bce.zip/node_modules/@parcel/reporter-dev-server/",\ - "packageDependencies": [\ - ["@parcel/reporter-dev-server", "npm:2.6.2"],\ - ["@parcel/plugin", "npm:2.6.2"],\ - ["@parcel/utils", "npm:2.6.2"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["@parcel/resolver-default", [\ - ["npm:2.6.2", {\ - "packageLocation": "./.yarn/cache/@parcel-resolver-default-npm-2.6.2-0584e152a0-e0dfff6e62.zip/node_modules/@parcel/resolver-default/",\ - "packageDependencies": [\ - ["@parcel/resolver-default", "npm:2.6.2"],\ - ["@parcel/node-resolver-core", "npm:2.6.2"],\ - ["@parcel/plugin", "npm:2.6.2"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["@parcel/runtime-browser-hmr", [\ - ["npm:2.6.2", {\ - "packageLocation": "./.yarn/cache/@parcel-runtime-browser-hmr-npm-2.6.2-abf052bd22-39a324c4ef.zip/node_modules/@parcel/runtime-browser-hmr/",\ - "packageDependencies": [\ - ["@parcel/runtime-browser-hmr", "npm:2.6.2"],\ - ["@parcel/plugin", "npm:2.6.2"],\ - ["@parcel/utils", "npm:2.6.2"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["@parcel/runtime-js", [\ - ["npm:2.6.2", {\ - "packageLocation": "./.yarn/cache/@parcel-runtime-js-npm-2.6.2-64b723c929-861e89c536.zip/node_modules/@parcel/runtime-js/",\ - "packageDependencies": [\ - ["@parcel/runtime-js", "npm:2.6.2"],\ - ["@parcel/plugin", "npm:2.6.2"],\ - ["@parcel/utils", "npm:2.6.2"],\ - ["nullthrows", "npm:1.1.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["@parcel/runtime-react-refresh", [\ - ["npm:2.6.2", {\ - "packageLocation": "./.yarn/cache/@parcel-runtime-react-refresh-npm-2.6.2-0e47dcf17b-0c33a13dd4.zip/node_modules/@parcel/runtime-react-refresh/",\ - "packageDependencies": [\ - ["@parcel/runtime-react-refresh", "npm:2.6.2"],\ - ["@parcel/plugin", "npm:2.6.2"],\ - ["@parcel/utils", "npm:2.6.2"],\ - ["react-error-overlay", "npm:6.0.9"],\ - ["react-refresh", "npm:0.9.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["@parcel/runtime-service-worker", [\ - ["npm:2.6.2", {\ - "packageLocation": "./.yarn/cache/@parcel-runtime-service-worker-npm-2.6.2-b2e2082392-2a9790ad27.zip/node_modules/@parcel/runtime-service-worker/",\ - "packageDependencies": [\ - ["@parcel/runtime-service-worker", "npm:2.6.2"],\ - ["@parcel/plugin", "npm:2.6.2"],\ - ["@parcel/utils", "npm:2.6.2"],\ - ["nullthrows", "npm:1.1.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["@parcel/source-map", [\ - ["npm:2.0.5", {\ - "packageLocation": "./.yarn/unplugged/@parcel-source-map-npm-2.0.5-2444d2c092/node_modules/@parcel/source-map/",\ - "packageDependencies": [\ - ["@parcel/source-map", "npm:2.0.5"],\ - ["detect-libc", "npm:1.0.3"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["@parcel/transformer-babel", [\ - ["npm:2.6.2", {\ - "packageLocation": "./.yarn/cache/@parcel-transformer-babel-npm-2.6.2-c5c9478ebe-c7f14b76bf.zip/node_modules/@parcel/transformer-babel/",\ - "packageDependencies": [\ - ["@parcel/transformer-babel", "npm:2.6.2"],\ - ["@parcel/diagnostic", "npm:2.6.2"],\ - ["@parcel/plugin", "npm:2.6.2"],\ - ["@parcel/source-map", "npm:2.0.5"],\ - ["@parcel/utils", "npm:2.6.2"],\ - ["browserslist", "npm:4.20.3"],\ - ["json5", "npm:2.2.1"],\ - ["nullthrows", "npm:1.1.1"],\ - ["semver", "npm:5.7.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["@parcel/transformer-css", [\ - ["npm:2.6.2", {\ - "packageLocation": "./.yarn/cache/@parcel-transformer-css-npm-2.6.2-ab5a4c9465-2a8ac50457.zip/node_modules/@parcel/transformer-css/",\ - "packageDependencies": [\ - ["@parcel/transformer-css", "npm:2.6.2"],\ - ["@parcel/css", "npm:1.10.1"],\ - ["@parcel/diagnostic", "npm:2.6.2"],\ - ["@parcel/plugin", "npm:2.6.2"],\ - ["@parcel/source-map", "npm:2.0.5"],\ - ["@parcel/utils", "npm:2.6.2"],\ - ["browserslist", "npm:4.20.3"],\ - ["nullthrows", "npm:1.1.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["@parcel/transformer-html", [\ - ["npm:2.6.2", {\ - "packageLocation": "./.yarn/cache/@parcel-transformer-html-npm-2.6.2-bf84827f26-6d37d556aa.zip/node_modules/@parcel/transformer-html/",\ - "packageDependencies": [\ - ["@parcel/transformer-html", "npm:2.6.2"],\ - ["@parcel/diagnostic", "npm:2.6.2"],\ - ["@parcel/hash", "npm:2.6.2"],\ - ["@parcel/plugin", "npm:2.6.2"],\ - ["nullthrows", "npm:1.1.1"],\ - ["posthtml", "npm:0.16.6"],\ - ["posthtml-parser", "npm:0.10.2"],\ - ["posthtml-render", "npm:3.0.0"],\ - ["semver", "npm:5.7.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["@parcel/transformer-image", [\ - ["npm:2.6.2", {\ - "packageLocation": "./.yarn/cache/@parcel-transformer-image-npm-2.6.2-28b8a807bd-2627a162b9.zip/node_modules/@parcel/transformer-image/",\ - "packageDependencies": [\ - ["@parcel/transformer-image", "npm:2.6.2"]\ - ],\ - "linkType": "SOFT"\ - }],\ - ["virtual:2d370753d95a3d52f78f3ca64747a2e25bcd4f0e5efd31562ad6d588b2ccc11b94c6454009cfedbb3ba5deb7d012ce632bc48fe055f74a2703cfedd634c0b462#npm:2.6.2", {\ - "packageLocation": "./.yarn/__virtual__/@parcel-transformer-image-virtual-4627502781/0/cache/@parcel-transformer-image-npm-2.6.2-28b8a807bd-2627a162b9.zip/node_modules/@parcel/transformer-image/",\ - "packageDependencies": [\ - ["@parcel/transformer-image", "virtual:2d370753d95a3d52f78f3ca64747a2e25bcd4f0e5efd31562ad6d588b2ccc11b94c6454009cfedbb3ba5deb7d012ce632bc48fe055f74a2703cfedd634c0b462#npm:2.6.2"],\ - ["@parcel/core", "npm:2.6.2"],\ - ["@parcel/plugin", "npm:2.6.2"],\ - ["@parcel/workers", "virtual:aa1797faca4a934b86d07dfa52e0db4db288b85fed415e745782ef9bd4bd39771970f9017a79cb7ed092d23d2539cea12a1cec949dfa0bb86e0fda2290caa70e#npm:2.6.2"],\ - ["@types/parcel__core", null],\ - ["nullthrows", "npm:1.1.1"]\ - ],\ - "packagePeers": [\ - "@parcel/core",\ - "@types/parcel__core"\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["@parcel/transformer-js", [\ - ["npm:2.6.2", {\ - "packageLocation": "./.yarn/unplugged/@parcel-transformer-js-virtual-ff1bab70e7/node_modules/@parcel/transformer-js/",\ - "packageDependencies": [\ - ["@parcel/transformer-js", "npm:2.6.2"]\ - ],\ - "linkType": "SOFT"\ - }],\ - ["virtual:2d370753d95a3d52f78f3ca64747a2e25bcd4f0e5efd31562ad6d588b2ccc11b94c6454009cfedbb3ba5deb7d012ce632bc48fe055f74a2703cfedd634c0b462#npm:2.6.2", {\ - "packageLocation": "./.yarn/unplugged/@parcel-transformer-js-virtual-ff1bab70e7/node_modules/@parcel/transformer-js/",\ - "packageDependencies": [\ - ["@parcel/transformer-js", "virtual:2d370753d95a3d52f78f3ca64747a2e25bcd4f0e5efd31562ad6d588b2ccc11b94c6454009cfedbb3ba5deb7d012ce632bc48fe055f74a2703cfedd634c0b462#npm:2.6.2"],\ - ["@parcel/core", "npm:2.6.2"],\ - ["@parcel/diagnostic", "npm:2.6.2"],\ - ["@parcel/plugin", "npm:2.6.2"],\ - ["@parcel/source-map", "npm:2.0.5"],\ - ["@parcel/utils", "npm:2.6.2"],\ - ["@parcel/workers", "virtual:aa1797faca4a934b86d07dfa52e0db4db288b85fed415e745782ef9bd4bd39771970f9017a79cb7ed092d23d2539cea12a1cec949dfa0bb86e0fda2290caa70e#npm:2.6.2"],\ - ["@swc/helpers", "npm:0.4.3"],\ - ["@types/parcel__core", null],\ - ["browserslist", "npm:4.20.3"],\ - ["detect-libc", "npm:1.0.3"],\ - ["nullthrows", "npm:1.1.1"],\ - ["regenerator-runtime", "npm:0.13.9"],\ - ["semver", "npm:5.7.1"]\ - ],\ - "packagePeers": [\ - "@parcel/core",\ - "@types/parcel__core"\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["@parcel/transformer-json", [\ - ["npm:2.6.2", {\ - "packageLocation": "./.yarn/cache/@parcel-transformer-json-npm-2.6.2-e55c433bcb-0b4162ba93.zip/node_modules/@parcel/transformer-json/",\ - "packageDependencies": [\ - ["@parcel/transformer-json", "npm:2.6.2"],\ - ["@parcel/plugin", "npm:2.6.2"],\ - ["json5", "npm:2.2.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["@parcel/transformer-postcss", [\ - ["npm:2.6.2", {\ - "packageLocation": "./.yarn/cache/@parcel-transformer-postcss-npm-2.6.2-3da3a44a17-473d1e96f9.zip/node_modules/@parcel/transformer-postcss/",\ - "packageDependencies": [\ - ["@parcel/transformer-postcss", "npm:2.6.2"],\ - ["@parcel/diagnostic", "npm:2.6.2"],\ - ["@parcel/hash", "npm:2.6.2"],\ - ["@parcel/plugin", "npm:2.6.2"],\ - ["@parcel/utils", "npm:2.6.2"],\ - ["clone", "npm:2.1.2"],\ - ["nullthrows", "npm:1.1.1"],\ - ["postcss-value-parser", "npm:4.2.0"],\ - ["semver", "npm:5.7.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["@parcel/transformer-posthtml", [\ - ["npm:2.6.2", {\ - "packageLocation": "./.yarn/cache/@parcel-transformer-posthtml-npm-2.6.2-7d4694cfa8-3ddb727aa2.zip/node_modules/@parcel/transformer-posthtml/",\ - "packageDependencies": [\ - ["@parcel/transformer-posthtml", "npm:2.6.2"],\ - ["@parcel/plugin", "npm:2.6.2"],\ - ["@parcel/utils", "npm:2.6.2"],\ - ["nullthrows", "npm:1.1.1"],\ - ["posthtml", "npm:0.16.6"],\ - ["posthtml-parser", "npm:0.10.2"],\ - ["posthtml-render", "npm:3.0.0"],\ - ["semver", "npm:5.7.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["@parcel/transformer-raw", [\ - ["npm:2.6.2", {\ - "packageLocation": "./.yarn/cache/@parcel-transformer-raw-npm-2.6.2-0f247428f1-aa8543194f.zip/node_modules/@parcel/transformer-raw/",\ - "packageDependencies": [\ - ["@parcel/transformer-raw", "npm:2.6.2"],\ - ["@parcel/plugin", "npm:2.6.2"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["@parcel/transformer-react-refresh-wrap", [\ - ["npm:2.6.2", {\ - "packageLocation": "./.yarn/cache/@parcel-transformer-react-refresh-wrap-npm-2.6.2-62385046b0-6655b93d5e.zip/node_modules/@parcel/transformer-react-refresh-wrap/",\ - "packageDependencies": [\ - ["@parcel/transformer-react-refresh-wrap", "npm:2.6.2"],\ - ["@parcel/plugin", "npm:2.6.2"],\ - ["@parcel/utils", "npm:2.6.2"],\ - ["react-refresh", "npm:0.9.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["@parcel/transformer-sass", [\ - ["npm:2.6.2", {\ - "packageLocation": "./.yarn/cache/@parcel-transformer-sass-npm-2.6.2-b485ae126e-b35e8d272f.zip/node_modules/@parcel/transformer-sass/",\ - "packageDependencies": [\ - ["@parcel/transformer-sass", "npm:2.6.2"],\ - ["@parcel/plugin", "npm:2.6.2"],\ - ["@parcel/source-map", "npm:2.0.5"],\ - ["sass", "npm:1.52.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["@parcel/transformer-svg", [\ - ["npm:2.6.2", {\ - "packageLocation": "./.yarn/cache/@parcel-transformer-svg-npm-2.6.2-11420db70b-b768ecc0c6.zip/node_modules/@parcel/transformer-svg/",\ - "packageDependencies": [\ - ["@parcel/transformer-svg", "npm:2.6.2"],\ - ["@parcel/diagnostic", "npm:2.6.2"],\ - ["@parcel/hash", "npm:2.6.2"],\ - ["@parcel/plugin", "npm:2.6.2"],\ - ["nullthrows", "npm:1.1.1"],\ - ["posthtml", "npm:0.16.6"],\ - ["posthtml-parser", "npm:0.10.2"],\ - ["posthtml-render", "npm:3.0.0"],\ - ["semver", "npm:5.7.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["@parcel/types", [\ - ["npm:2.6.2", {\ - "packageLocation": "./.yarn/cache/@parcel-types-npm-2.6.2-aa1797faca-16f3c3ac36.zip/node_modules/@parcel/types/",\ - "packageDependencies": [\ - ["@parcel/types", "npm:2.6.2"],\ - ["@parcel/cache", "virtual:aa1797faca4a934b86d07dfa52e0db4db288b85fed415e745782ef9bd4bd39771970f9017a79cb7ed092d23d2539cea12a1cec949dfa0bb86e0fda2290caa70e#npm:2.6.2"],\ - ["@parcel/diagnostic", "npm:2.6.2"],\ - ["@parcel/fs", "virtual:aa1797faca4a934b86d07dfa52e0db4db288b85fed415e745782ef9bd4bd39771970f9017a79cb7ed092d23d2539cea12a1cec949dfa0bb86e0fda2290caa70e#npm:2.6.2"],\ - ["@parcel/package-manager", "virtual:aa1797faca4a934b86d07dfa52e0db4db288b85fed415e745782ef9bd4bd39771970f9017a79cb7ed092d23d2539cea12a1cec949dfa0bb86e0fda2290caa70e#npm:2.6.2"],\ - ["@parcel/source-map", "npm:2.0.5"],\ - ["@parcel/workers", "virtual:aa1797faca4a934b86d07dfa52e0db4db288b85fed415e745782ef9bd4bd39771970f9017a79cb7ed092d23d2539cea12a1cec949dfa0bb86e0fda2290caa70e#npm:2.6.2"],\ - ["utility-types", "npm:3.10.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["@parcel/utils", [\ - ["npm:2.6.2", {\ - "packageLocation": "./.yarn/cache/@parcel-utils-npm-2.6.2-cab87aed21-a74fdca966.zip/node_modules/@parcel/utils/",\ - "packageDependencies": [\ - ["@parcel/utils", "npm:2.6.2"],\ - ["@parcel/codeframe", "npm:2.6.2"],\ - ["@parcel/diagnostic", "npm:2.6.2"],\ - ["@parcel/hash", "npm:2.6.2"],\ - ["@parcel/logger", "npm:2.6.2"],\ - ["@parcel/markdown-ansi", "npm:2.6.2"],\ - ["@parcel/source-map", "npm:2.0.5"],\ - ["chalk", "npm:4.1.2"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["@parcel/watcher", [\ - ["npm:2.0.5", {\ - "packageLocation": "./.yarn/unplugged/@parcel-watcher-npm-2.0.5-bda35fb0f8/node_modules/@parcel/watcher/",\ - "packageDependencies": [\ - ["@parcel/watcher", "npm:2.0.5"],\ - ["node-addon-api", "npm:3.2.1"],\ - ["node-gyp", "npm:9.0.0"],\ - ["node-gyp-build", "npm:4.4.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["@parcel/workers", [\ - ["npm:2.6.2", {\ - "packageLocation": "./.yarn/cache/@parcel-workers-npm-2.6.2-a30e38db52-92b65cd3fd.zip/node_modules/@parcel/workers/",\ - "packageDependencies": [\ - ["@parcel/workers", "npm:2.6.2"]\ - ],\ - "linkType": "SOFT"\ - }],\ - ["virtual:aa1797faca4a934b86d07dfa52e0db4db288b85fed415e745782ef9bd4bd39771970f9017a79cb7ed092d23d2539cea12a1cec949dfa0bb86e0fda2290caa70e#npm:2.6.2", {\ - "packageLocation": "./.yarn/__virtual__/@parcel-workers-virtual-fa9718ade0/0/cache/@parcel-workers-npm-2.6.2-a30e38db52-92b65cd3fd.zip/node_modules/@parcel/workers/",\ - "packageDependencies": [\ - ["@parcel/workers", "virtual:aa1797faca4a934b86d07dfa52e0db4db288b85fed415e745782ef9bd4bd39771970f9017a79cb7ed092d23d2539cea12a1cec949dfa0bb86e0fda2290caa70e#npm:2.6.2"],\ - ["@parcel/core", "npm:2.6.2"],\ - ["@parcel/diagnostic", "npm:2.6.2"],\ - ["@parcel/logger", "npm:2.6.2"],\ - ["@parcel/types", "npm:2.6.2"],\ - ["@parcel/utils", "npm:2.6.2"],\ - ["@types/parcel__core", null],\ - ["chrome-trace-event", "npm:1.0.3"],\ - ["nullthrows", "npm:1.1.1"]\ - ],\ - "packagePeers": [\ - "@types/parcel__core"\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["@popperjs/core", [\ - ["npm:2.11.5", {\ - "packageLocation": "./.yarn/cache/@popperjs-core-npm-2.11.5-a338f16bd4-fd7f9dca3f.zip/node_modules/@popperjs/core/",\ - "packageDependencies": [\ - ["@popperjs/core", "npm:2.11.5"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["@sidvind/better-ajv-errors", [\ - ["npm:2.0.0", {\ - "packageLocation": "./.yarn/cache/@sidvind-better-ajv-errors-npm-2.0.0-3531bddef9-12b0d87855.zip/node_modules/@sidvind/better-ajv-errors/",\ - "packageDependencies": [\ - ["@sidvind/better-ajv-errors", "npm:2.0.0"]\ - ],\ - "linkType": "SOFT"\ - }],\ - ["virtual:9e7a4831943ff00ebf8ab9b738a379a7f31c6e004493e5987b05deb16a73f71a896a690e256d8f5e72f136a61b8533b4ef2cde3717790ed10cb7b6ca84d6613b#npm:2.0.0", {\ - "packageLocation": "./.yarn/__virtual__/@sidvind-better-ajv-errors-virtual-037fa3e9b1/0/cache/@sidvind-better-ajv-errors-npm-2.0.0-3531bddef9-12b0d87855.zip/node_modules/@sidvind/better-ajv-errors/",\ - "packageDependencies": [\ - ["@sidvind/better-ajv-errors", "virtual:9e7a4831943ff00ebf8ab9b738a379a7f31c6e004493e5987b05deb16a73f71a896a690e256d8f5e72f136a61b8533b4ef2cde3717790ed10cb7b6ca84d6613b#npm:2.0.0"],\ - ["@babel/code-frame", "npm:7.16.7"],\ - ["@types/ajv", null],\ - ["ajv", "npm:8.11.0"],\ - ["chalk", "npm:4.1.2"]\ - ],\ - "packagePeers": [\ - "@types/ajv",\ - "ajv"\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["@swc/helpers", [\ - ["npm:0.4.3", {\ - "packageLocation": "./.yarn/cache/@swc-helpers-npm-0.4.3-5d4bea11d2-5c2f173e95.zip/node_modules/@swc/helpers/",\ - "packageDependencies": [\ - ["@swc/helpers", "npm:0.4.3"],\ - ["tslib", "npm:2.4.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["@tootallnate/once", [\ - ["npm:2.0.0", {\ - "packageLocation": "./.yarn/cache/@tootallnate-once-npm-2.0.0-e36cf4f140-ad87447820.zip/node_modules/@tootallnate/once/",\ - "packageDependencies": [\ - ["@tootallnate/once", "npm:2.0.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["@trysound/sax", [\ - ["npm:0.2.0", {\ - "packageLocation": "./.yarn/cache/@trysound-sax-npm-0.2.0-9f763d0295-11226c39b5.zip/node_modules/@trysound/sax/",\ - "packageDependencies": [\ - ["@trysound/sax", "npm:0.2.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["@types/chai", [\ - ["npm:4.3.1", {\ - "packageLocation": "./.yarn/cache/@types-chai-npm-4.3.1-dab3901c30-2ee246b76c.zip/node_modules/@types/chai/",\ - "packageDependencies": [\ - ["@types/chai", "npm:4.3.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["@types/chai-subset", [\ - ["npm:1.3.3", {\ - "packageLocation": "./.yarn/cache/@types-chai-subset-npm-1.3.3-acf55b3b37-4481da7345.zip/node_modules/@types/chai-subset/",\ - "packageDependencies": [\ - ["@types/chai-subset", "npm:1.3.3"],\ - ["@types/chai", "npm:4.3.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["@types/istanbul-lib-coverage", [\ - ["npm:2.0.4", {\ - "packageLocation": "./.yarn/cache/@types-istanbul-lib-coverage-npm-2.0.4-734954bb56-a25d7589ee.zip/node_modules/@types/istanbul-lib-coverage/",\ - "packageDependencies": [\ - ["@types/istanbul-lib-coverage", "npm:2.0.4"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["@types/jest", [\ - ["npm:27.4.1", {\ - "packageLocation": "./.yarn/cache/@types-jest-npm-27.4.1-31d07cd0d8-5184f3eef4.zip/node_modules/@types/jest/",\ - "packageDependencies": [\ - ["@types/jest", "npm:27.4.1"],\ - ["jest-matcher-utils", "npm:27.5.1"],\ - ["pretty-format", "npm:27.5.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["@types/json5", [\ - ["npm:0.0.29", {\ - "packageLocation": "./.yarn/cache/@types-json5-npm-0.0.29-f63a7916bd-e60b153664.zip/node_modules/@types/json5/",\ - "packageDependencies": [\ - ["@types/json5", "npm:0.0.29"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["@types/lodash", [\ - ["npm:4.14.182", {\ - "packageLocation": "./.yarn/cache/@types-lodash-npm-4.14.182-1073aac722-7dd137aa9d.zip/node_modules/@types/lodash/",\ - "packageDependencies": [\ - ["@types/lodash", "npm:4.14.182"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["@types/lodash-es", [\ - ["npm:4.17.6", {\ - "packageLocation": "./.yarn/cache/@types-lodash-es-npm-4.17.6-fd5abbdc74-9bd239dd52.zip/node_modules/@types/lodash-es/",\ - "packageDependencies": [\ - ["@types/lodash-es", "npm:4.17.6"],\ - ["@types/lodash", "npm:4.14.182"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["@types/node", [\ - ["npm:14.18.18", {\ - "packageLocation": "./.yarn/cache/@types-node-npm-14.18.18-2f8f733938-a165225cd2.zip/node_modules/@types/node/",\ - "packageDependencies": [\ - ["@types/node", "npm:14.18.18"]\ - ],\ - "linkType": "HARD"\ - }],\ - ["npm:17.0.29", {\ - "packageLocation": "./.yarn/cache/@types-node-npm-17.0.29-0de8e6d3d0-bb9d7bce9d.zip/node_modules/@types/node/",\ - "packageDependencies": [\ - ["@types/node", "npm:17.0.29"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["@types/parse-json", [\ - ["npm:4.0.0", {\ - "packageLocation": "./.yarn/cache/@types-parse-json-npm-4.0.0-298522afa6-fd6bce2b67.zip/node_modules/@types/parse-json/",\ - "packageDependencies": [\ - ["@types/parse-json", "npm:4.0.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["@types/sinonjs__fake-timers", [\ - ["npm:8.1.1", {\ - "packageLocation": "./.yarn/cache/@types-sinonjs__fake-timers-npm-8.1.1-95ac9b59b5-ca09d54d47.zip/node_modules/@types/sinonjs__fake-timers/",\ - "packageDependencies": [\ - ["@types/sinonjs__fake-timers", "npm:8.1.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["@types/sizzle", [\ - ["npm:2.3.3", {\ - "packageLocation": "./.yarn/cache/@types-sizzle-npm-2.3.3-9403924950-586a9fb1f6.zip/node_modules/@types/sizzle/",\ - "packageDependencies": [\ - ["@types/sizzle", "npm:2.3.3"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["@types/yauzl", [\ - ["npm:2.10.0", {\ - "packageLocation": "./.yarn/cache/@types-yauzl-npm-2.10.0-7b242343cb-55d27ae5d3.zip/node_modules/@types/yauzl/",\ - "packageDependencies": [\ - ["@types/yauzl", "npm:2.10.0"],\ - ["@types/node", "npm:14.18.18"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["@vitejs/plugin-vue", [\ - ["npm:2.3.3", {\ - "packageLocation": "./.yarn/cache/@vitejs-plugin-vue-npm-2.3.3-89ac1da9f4-9303dcb9c8.zip/node_modules/@vitejs/plugin-vue/",\ - "packageDependencies": [\ - ["@vitejs/plugin-vue", "npm:2.3.3"]\ - ],\ - "linkType": "SOFT"\ - }],\ - ["virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:2.3.3", {\ - "packageLocation": "./.yarn/__virtual__/@vitejs-plugin-vue-virtual-e1274aae2d/0/cache/@vitejs-plugin-vue-npm-2.3.3-89ac1da9f4-9303dcb9c8.zip/node_modules/@vitejs/plugin-vue/",\ - "packageDependencies": [\ - ["@vitejs/plugin-vue", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:2.3.3"],\ - ["@types/vite", null],\ - ["@types/vue", null],\ - ["vite", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:2.9.14"],\ - ["vue", "npm:3.2.37"]\ - ],\ - "packagePeers": [\ - "@types/vite",\ - "@types/vue",\ - "vite",\ - "vue"\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["@vue/compiler-core", [\ - ["npm:3.2.37", {\ - "packageLocation": "./.yarn/cache/@vue-compiler-core-npm-3.2.37-1ed1423427-5642e20813.zip/node_modules/@vue/compiler-core/",\ - "packageDependencies": [\ - ["@vue/compiler-core", "npm:3.2.37"],\ - ["@babel/parser", "npm:7.18.4"],\ - ["@vue/shared", "npm:3.2.37"],\ - ["estree-walker", "npm:2.0.2"],\ - ["source-map", "npm:0.6.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["@vue/compiler-dom", [\ - ["npm:3.2.37", {\ - "packageLocation": "./.yarn/cache/@vue-compiler-dom-npm-3.2.37-b8cfefaa49-6cfa9d2ee1.zip/node_modules/@vue/compiler-dom/",\ - "packageDependencies": [\ - ["@vue/compiler-dom", "npm:3.2.37"],\ - ["@vue/compiler-core", "npm:3.2.37"],\ - ["@vue/shared", "npm:3.2.37"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["@vue/compiler-sfc", [\ - ["npm:3.2.37", {\ - "packageLocation": "./.yarn/cache/@vue-compiler-sfc-npm-3.2.37-a6956912bb-9f9067d79f.zip/node_modules/@vue/compiler-sfc/",\ - "packageDependencies": [\ - ["@vue/compiler-sfc", "npm:3.2.37"],\ - ["@babel/parser", "npm:7.18.4"],\ - ["@vue/compiler-core", "npm:3.2.37"],\ - ["@vue/compiler-dom", "npm:3.2.37"],\ - ["@vue/compiler-ssr", "npm:3.2.37"],\ - ["@vue/reactivity-transform", "npm:3.2.37"],\ - ["@vue/shared", "npm:3.2.37"],\ - ["estree-walker", "npm:2.0.2"],\ - ["magic-string", "npm:0.25.9"],\ - ["postcss", "npm:8.4.12"],\ - ["source-map", "npm:0.6.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["@vue/compiler-ssr", [\ - ["npm:3.2.37", {\ - "packageLocation": "./.yarn/cache/@vue-compiler-ssr-npm-3.2.37-30882c5f14-e137462340.zip/node_modules/@vue/compiler-ssr/",\ - "packageDependencies": [\ - ["@vue/compiler-ssr", "npm:3.2.37"],\ - ["@vue/compiler-dom", "npm:3.2.37"],\ - ["@vue/shared", "npm:3.2.37"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["@vue/devtools-api", [\ - ["npm:6.1.4", {\ - "packageLocation": "./.yarn/cache/@vue-devtools-api-npm-6.1.4-4ee2c9cc71-027bb138b0.zip/node_modules/@vue/devtools-api/",\ - "packageDependencies": [\ - ["@vue/devtools-api", "npm:6.1.4"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["@vue/reactivity", [\ - ["npm:3.2.37", {\ - "packageLocation": "./.yarn/cache/@vue-reactivity-npm-3.2.37-b6bb8fbcbd-94e353f8b8.zip/node_modules/@vue/reactivity/",\ - "packageDependencies": [\ - ["@vue/reactivity", "npm:3.2.37"],\ - ["@vue/shared", "npm:3.2.37"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["@vue/reactivity-transform", [\ - ["npm:3.2.37", {\ - "packageLocation": "./.yarn/cache/@vue-reactivity-transform-npm-3.2.37-96d5a7d46e-d9e7c353e2.zip/node_modules/@vue/reactivity-transform/",\ - "packageDependencies": [\ - ["@vue/reactivity-transform", "npm:3.2.37"],\ - ["@babel/parser", "npm:7.18.4"],\ - ["@vue/compiler-core", "npm:3.2.37"],\ - ["@vue/shared", "npm:3.2.37"],\ - ["estree-walker", "npm:2.0.2"],\ - ["magic-string", "npm:0.25.9"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["@vue/runtime-core", [\ - ["npm:3.2.37", {\ - "packageLocation": "./.yarn/cache/@vue-runtime-core-npm-3.2.37-4babb388df-8dbf4e1f97.zip/node_modules/@vue/runtime-core/",\ - "packageDependencies": [\ - ["@vue/runtime-core", "npm:3.2.37"],\ - ["@vue/reactivity", "npm:3.2.37"],\ - ["@vue/shared", "npm:3.2.37"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["@vue/runtime-dom", [\ - ["npm:3.2.37", {\ - "packageLocation": "./.yarn/cache/@vue-runtime-dom-npm-3.2.37-6bd25ee477-36dddfd561.zip/node_modules/@vue/runtime-dom/",\ - "packageDependencies": [\ - ["@vue/runtime-dom", "npm:3.2.37"],\ - ["@vue/runtime-core", "npm:3.2.37"],\ - ["@vue/shared", "npm:3.2.37"],\ - ["csstype", "npm:2.6.20"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["@vue/server-renderer", [\ - ["npm:3.2.37", {\ - "packageLocation": "./.yarn/cache/@vue-server-renderer-npm-3.2.37-93c5150576-634d43cd21.zip/node_modules/@vue/server-renderer/",\ - "packageDependencies": [\ - ["@vue/server-renderer", "npm:3.2.37"]\ - ],\ - "linkType": "SOFT"\ - }],\ - ["virtual:c15242c7af88e957688e92d9c054d0c6533fd55fdb771c3854473b923e00751099a2c292023fc5bcf1d904adde806541a7f6b2b8e48d11e76ccb2ee0856b45bd#npm:3.2.37", {\ - "packageLocation": "./.yarn/__virtual__/@vue-server-renderer-virtual-947c838fbc/0/cache/@vue-server-renderer-npm-3.2.37-93c5150576-634d43cd21.zip/node_modules/@vue/server-renderer/",\ - "packageDependencies": [\ - ["@vue/server-renderer", "virtual:c15242c7af88e957688e92d9c054d0c6533fd55fdb771c3854473b923e00751099a2c292023fc5bcf1d904adde806541a7f6b2b8e48d11e76ccb2ee0856b45bd#npm:3.2.37"],\ - ["@types/vue", null],\ - ["@vue/compiler-ssr", "npm:3.2.37"],\ - ["@vue/shared", "npm:3.2.37"],\ - ["vue", "npm:3.2.37"]\ - ],\ - "packagePeers": [\ - "@types/vue",\ - "vue"\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["@vue/shared", [\ - ["npm:3.2.37", {\ - "packageLocation": "./.yarn/cache/@vue-shared-npm-3.2.37-60a8943fc6-999ab8baeb.zip/node_modules/@vue/shared/",\ - "packageDependencies": [\ - ["@vue/shared", "npm:3.2.37"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["@vue/test-utils", [\ - ["npm:2.0.2", {\ - "packageLocation": "./.yarn/cache/@vue-test-utils-npm-2.0.2-8fecfc05d1-384bdd4231.zip/node_modules/@vue/test-utils/",\ - "packageDependencies": [\ - ["@vue/test-utils", "npm:2.0.2"]\ - ],\ - "linkType": "SOFT"\ - }],\ - ["virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:2.0.2", {\ - "packageLocation": "./.yarn/__virtual__/@vue-test-utils-virtual-7d914f583a/0/cache/@vue-test-utils-npm-2.0.2-8fecfc05d1-384bdd4231.zip/node_modules/@vue/test-utils/",\ - "packageDependencies": [\ - ["@vue/test-utils", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:2.0.2"],\ - ["@types/vue", null],\ - ["vue", "npm:3.2.37"]\ - ],\ - "packagePeers": [\ - "@types/vue",\ - "vue"\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["abbrev", [\ - ["npm:1.1.1", {\ - "packageLocation": "./.yarn/cache/abbrev-npm-1.1.1-3659247eab-a4a97ec07d.zip/node_modules/abbrev/",\ - "packageDependencies": [\ - ["abbrev", "npm:1.1.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["abortcontroller-polyfill", [\ - ["npm:1.7.3", {\ - "packageLocation": "./.yarn/cache/abortcontroller-polyfill-npm-1.7.3-3b01198b7a-55739d7f0c.zip/node_modules/abortcontroller-polyfill/",\ - "packageDependencies": [\ - ["abortcontroller-polyfill", "npm:1.7.3"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["acorn", [\ - ["npm:7.4.1", {\ - "packageLocation": "./.yarn/cache/acorn-npm-7.4.1-f450b4646c-1860f23c21.zip/node_modules/acorn/",\ - "packageDependencies": [\ - ["acorn", "npm:7.4.1"]\ - ],\ - "linkType": "HARD"\ - }],\ - ["npm:8.7.1", {\ - "packageLocation": "./.yarn/cache/acorn-npm-8.7.1-7c7a019990-aca0aabf98.zip/node_modules/acorn/",\ - "packageDependencies": [\ - ["acorn", "npm:8.7.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["acorn-jsx", [\ - ["npm:5.3.2", {\ - "packageLocation": "./.yarn/cache/acorn-jsx-npm-5.3.2-d7594599ea-c3d3b2a89c.zip/node_modules/acorn-jsx/",\ - "packageDependencies": [\ - ["acorn-jsx", "npm:5.3.2"]\ - ],\ - "linkType": "SOFT"\ - }],\ - ["virtual:c70fa2a91dcbd99b022aeff42b1b7671b1079fb9945248dc00dedd7520f879dc07058703f4626782de94f97692f30d5b18138d744c1e1ed1913a7610755d40e3#npm:5.3.2", {\ - "packageLocation": "./.yarn/__virtual__/acorn-jsx-virtual-068582d542/0/cache/acorn-jsx-npm-5.3.2-d7594599ea-c3d3b2a89c.zip/node_modules/acorn-jsx/",\ - "packageDependencies": [\ - ["acorn-jsx", "virtual:c70fa2a91dcbd99b022aeff42b1b7671b1079fb9945248dc00dedd7520f879dc07058703f4626782de94f97692f30d5b18138d744c1e1ed1913a7610755d40e3#npm:5.3.2"],\ - ["@types/acorn", null],\ - ["acorn", "npm:8.7.1"]\ - ],\ - "packagePeers": [\ - "@types/acorn",\ - "acorn"\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["acorn-walk", [\ - ["npm:8.2.0", {\ - "packageLocation": "./.yarn/cache/acorn-walk-npm-8.2.0-2f2cac3177-1715e76c01.zip/node_modules/acorn-walk/",\ - "packageDependencies": [\ - ["acorn-walk", "npm:8.2.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["agent-base", [\ - ["npm:6.0.2", {\ - "packageLocation": "./.yarn/cache/agent-base-npm-6.0.2-428f325a93-f52b6872cc.zip/node_modules/agent-base/",\ - "packageDependencies": [\ - ["agent-base", "npm:6.0.2"],\ - ["debug", "virtual:b86a9fb34323a98c6519528ed55faa0d9b44ca8879307c0b29aa384bde47ff59a7d0c9051b31246f14521dfb71ba3c5d6d0b35c29fffc17bf875aa6ad977d9e8#npm:4.3.4"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["agentkeepalive", [\ - ["npm:4.2.1", {\ - "packageLocation": "./.yarn/cache/agentkeepalive-npm-4.2.1-b86a9fb343-39cb49ed8c.zip/node_modules/agentkeepalive/",\ - "packageDependencies": [\ - ["agentkeepalive", "npm:4.2.1"],\ - ["debug", "virtual:b86a9fb34323a98c6519528ed55faa0d9b44ca8879307c0b29aa384bde47ff59a7d0c9051b31246f14521dfb71ba3c5d6d0b35c29fffc17bf875aa6ad977d9e8#npm:4.3.4"],\ - ["depd", "npm:1.1.2"],\ - ["humanize-ms", "npm:1.2.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["aggregate-error", [\ - ["npm:3.1.0", {\ - "packageLocation": "./.yarn/cache/aggregate-error-npm-3.1.0-415a406f4e-1101a33f21.zip/node_modules/aggregate-error/",\ - "packageDependencies": [\ - ["aggregate-error", "npm:3.1.0"],\ - ["clean-stack", "npm:2.2.0"],\ - ["indent-string", "npm:4.0.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["ajv", [\ - ["npm:6.12.6", {\ - "packageLocation": "./.yarn/cache/ajv-npm-6.12.6-4b5105e2b2-874972efe5.zip/node_modules/ajv/",\ - "packageDependencies": [\ - ["ajv", "npm:6.12.6"],\ - ["fast-deep-equal", "npm:3.1.3"],\ - ["fast-json-stable-stringify", "npm:2.1.0"],\ - ["json-schema-traverse", "npm:0.4.1"],\ - ["uri-js", "npm:4.4.1"]\ - ],\ - "linkType": "HARD"\ - }],\ - ["npm:8.11.0", {\ - "packageLocation": "./.yarn/cache/ajv-npm-8.11.0-83d029789c-5e0ff22680.zip/node_modules/ajv/",\ - "packageDependencies": [\ - ["ajv", "npm:8.11.0"],\ - ["fast-deep-equal", "npm:3.1.3"],\ - ["json-schema-traverse", "npm:1.0.0"],\ - ["require-from-string", "npm:2.0.2"],\ - ["uri-js", "npm:4.4.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["ansi-colors", [\ - ["npm:4.1.3", {\ - "packageLocation": "./.yarn/cache/ansi-colors-npm-4.1.3-8ffd0ae6c7-a9c2ec8420.zip/node_modules/ansi-colors/",\ - "packageDependencies": [\ - ["ansi-colors", "npm:4.1.3"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["ansi-escapes", [\ - ["npm:4.3.2", {\ - "packageLocation": "./.yarn/cache/ansi-escapes-npm-4.3.2-3ad173702f-93111c4218.zip/node_modules/ansi-escapes/",\ - "packageDependencies": [\ - ["ansi-escapes", "npm:4.3.2"],\ - ["type-fest", "npm:0.21.3"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["ansi-regex", [\ - ["npm:5.0.1", {\ - "packageLocation": "./.yarn/cache/ansi-regex-npm-5.0.1-c963a48615-2aa4bb54ca.zip/node_modules/ansi-regex/",\ - "packageDependencies": [\ - ["ansi-regex", "npm:5.0.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["ansi-styles", [\ - ["npm:3.2.1", {\ - "packageLocation": "./.yarn/cache/ansi-styles-npm-3.2.1-8cb8107983-d85ade01c1.zip/node_modules/ansi-styles/",\ - "packageDependencies": [\ - ["ansi-styles", "npm:3.2.1"],\ - ["color-convert", "npm:1.9.3"]\ - ],\ - "linkType": "HARD"\ - }],\ - ["npm:4.3.0", {\ - "packageLocation": "./.yarn/cache/ansi-styles-npm-4.3.0-245c7d42c7-513b44c3b2.zip/node_modules/ansi-styles/",\ - "packageDependencies": [\ - ["ansi-styles", "npm:4.3.0"],\ - ["color-convert", "npm:2.0.1"]\ - ],\ - "linkType": "HARD"\ - }],\ - ["npm:5.2.0", {\ - "packageLocation": "./.yarn/cache/ansi-styles-npm-5.2.0-72fc7003e3-d7f4e97ce0.zip/node_modules/ansi-styles/",\ - "packageDependencies": [\ - ["ansi-styles", "npm:5.2.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["anymatch", [\ - ["npm:3.1.2", {\ - "packageLocation": "./.yarn/cache/anymatch-npm-3.1.2-1d5471acfa-985163db22.zip/node_modules/anymatch/",\ - "packageDependencies": [\ - ["anymatch", "npm:3.1.2"],\ - ["normalize-path", "npm:3.0.0"],\ - ["picomatch", "npm:2.3.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["aproba", [\ - ["npm:2.0.0", {\ - "packageLocation": "./.yarn/cache/aproba-npm-2.0.0-8716bcfde6-5615cadcfb.zip/node_modules/aproba/",\ - "packageDependencies": [\ - ["aproba", "npm:2.0.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["arch", [\ - ["npm:2.2.0", {\ - "packageLocation": "./.yarn/cache/arch-npm-2.2.0-34797684d8-e21b763502.zip/node_modules/arch/",\ - "packageDependencies": [\ - ["arch", "npm:2.2.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["are-we-there-yet", [\ - ["npm:3.0.0", {\ - "packageLocation": "./.yarn/cache/are-we-there-yet-npm-3.0.0-1391430190-348edfdd93.zip/node_modules/are-we-there-yet/",\ - "packageDependencies": [\ - ["are-we-there-yet", "npm:3.0.0"],\ - ["delegates", "npm:1.0.0"],\ - ["readable-stream", "npm:3.6.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["argparse", [\ - ["npm:2.0.1", {\ - "packageLocation": "./.yarn/cache/argparse-npm-2.0.1-faff7999e6-83644b5649.zip/node_modules/argparse/",\ - "packageDependencies": [\ - ["argparse", "npm:2.0.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["array-includes", [\ - ["npm:3.1.4", {\ - "packageLocation": "./.yarn/cache/array-includes-npm-3.1.4-79bb883109-69967c38c5.zip/node_modules/array-includes/",\ - "packageDependencies": [\ - ["array-includes", "npm:3.1.4"],\ - ["call-bind", "npm:1.0.2"],\ - ["define-properties", "npm:1.1.4"],\ - ["es-abstract", "npm:1.19.5"],\ - ["get-intrinsic", "npm:1.1.1"],\ - ["is-string", "npm:1.0.7"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["array.prototype.flat", [\ - ["npm:1.3.0", {\ - "packageLocation": "./.yarn/cache/array.prototype.flat-npm-1.3.0-6c5c4292bd-2a652b3e8d.zip/node_modules/array.prototype.flat/",\ - "packageDependencies": [\ - ["array.prototype.flat", "npm:1.3.0"],\ - ["call-bind", "npm:1.0.2"],\ - ["define-properties", "npm:1.1.4"],\ - ["es-abstract", "npm:1.19.5"],\ - ["es-shim-unscopables", "npm:1.0.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["asap", [\ - ["npm:2.0.6", {\ - "packageLocation": "./.yarn/cache/asap-npm-2.0.6-36714d439d-b296c92c4b.zip/node_modules/asap/",\ - "packageDependencies": [\ - ["asap", "npm:2.0.6"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["asn1", [\ - ["npm:0.2.6", {\ - "packageLocation": "./.yarn/cache/asn1-npm-0.2.6-bdd07356c4-39f2ae343b.zip/node_modules/asn1/",\ - "packageDependencies": [\ - ["asn1", "npm:0.2.6"],\ - ["safer-buffer", "npm:2.1.2"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["assert-never", [\ - ["npm:1.2.1", {\ - "packageLocation": "./.yarn/cache/assert-never-npm-1.2.1-d423b480cd-ea4f1756d9.zip/node_modules/assert-never/",\ - "packageDependencies": [\ - ["assert-never", "npm:1.2.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["assert-plus", [\ - ["npm:1.0.0", {\ - "packageLocation": "./.yarn/cache/assert-plus-npm-1.0.0-cac95ef098-19b4340cb8.zip/node_modules/assert-plus/",\ - "packageDependencies": [\ - ["assert-plus", "npm:1.0.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["assertion-error", [\ - ["npm:1.1.0", {\ - "packageLocation": "./.yarn/cache/assertion-error-npm-1.1.0-66b893015e-fd9429d3a3.zip/node_modules/assertion-error/",\ - "packageDependencies": [\ - ["assertion-error", "npm:1.1.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["astral-regex", [\ - ["npm:2.0.0", {\ - "packageLocation": "./.yarn/cache/astral-regex-npm-2.0.0-f30d866aab-876231688c.zip/node_modules/astral-regex/",\ - "packageDependencies": [\ - ["astral-regex", "npm:2.0.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["async", [\ - ["npm:3.2.3", {\ - "packageLocation": "./.yarn/cache/async-npm-3.2.3-e9d6b79c88-c4bee57ab2.zip/node_modules/async/",\ - "packageDependencies": [\ - ["async", "npm:3.2.3"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["async-validator", [\ - ["npm:4.1.1", {\ - "packageLocation": "./.yarn/cache/async-validator-npm-4.1.1-470b8d5b59-88590ab8ad.zip/node_modules/async-validator/",\ - "packageDependencies": [\ - ["async-validator", "npm:4.1.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["asynckit", [\ - ["npm:0.4.0", {\ - "packageLocation": "./.yarn/cache/asynckit-npm-0.4.0-c718858525-7b78c451df.zip/node_modules/asynckit/",\ - "packageDependencies": [\ - ["asynckit", "npm:0.4.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["at-least-node", [\ - ["npm:1.0.0", {\ - "packageLocation": "./.yarn/cache/at-least-node-npm-1.0.0-2b36e661fa-463e2f8e43.zip/node_modules/at-least-node/",\ - "packageDependencies": [\ - ["at-least-node", "npm:1.0.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["aws-sign2", [\ - ["npm:0.7.0", {\ - "packageLocation": "./.yarn/cache/aws-sign2-npm-0.7.0-656c6cb84d-b148b0bb07.zip/node_modules/aws-sign2/",\ - "packageDependencies": [\ - ["aws-sign2", "npm:0.7.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["aws4", [\ - ["npm:1.11.0", {\ - "packageLocation": "./.yarn/cache/aws4-npm-1.11.0-283476ad94-5a00d045fd.zip/node_modules/aws4/",\ - "packageDependencies": [\ - ["aws4", "npm:1.11.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["babel-walk", [\ - ["npm:3.0.0-canary-5", {\ - "packageLocation": "./.yarn/cache/babel-walk-npm-3.0.0-canary-5-61b07ed745-6fe7ee3889.zip/node_modules/babel-walk/",\ - "packageDependencies": [\ - ["babel-walk", "npm:3.0.0-canary-5"],\ - ["@babel/types", "npm:7.18.4"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["balanced-match", [\ - ["npm:1.0.2", {\ - "packageLocation": "./.yarn/cache/balanced-match-npm-1.0.2-a53c126459-9706c088a2.zip/node_modules/balanced-match/",\ - "packageDependencies": [\ - ["balanced-match", "npm:1.0.2"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["base-x", [\ - ["npm:3.0.9", {\ - "packageLocation": "./.yarn/cache/base-x-npm-3.0.9-7b2588e106-957101d6fd.zip/node_modules/base-x/",\ - "packageDependencies": [\ - ["base-x", "npm:3.0.9"],\ - ["safe-buffer", "npm:5.2.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["base64-js", [\ - ["npm:1.5.1", {\ - "packageLocation": "./.yarn/cache/base64-js-npm-1.5.1-b2f7275641-669632eb37.zip/node_modules/base64-js/",\ - "packageDependencies": [\ - ["base64-js", "npm:1.5.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["bcrypt-pbkdf", [\ - ["npm:1.0.2", {\ - "packageLocation": "./.yarn/cache/bcrypt-pbkdf-npm-1.0.2-80db8b16ed-4edfc9fe7d.zip/node_modules/bcrypt-pbkdf/",\ - "packageDependencies": [\ - ["bcrypt-pbkdf", "npm:1.0.2"],\ - ["tweetnacl", "npm:0.14.5"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["binary-extensions", [\ - ["npm:2.2.0", {\ - "packageLocation": "./.yarn/cache/binary-extensions-npm-2.2.0-180c33fec7-ccd267956c.zip/node_modules/binary-extensions/",\ - "packageDependencies": [\ - ["binary-extensions", "npm:2.2.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["blob-util", [\ - ["npm:2.0.2", {\ - "packageLocation": "./.yarn/cache/blob-util-npm-2.0.2-8026c830fe-d543e6b92e.zip/node_modules/blob-util/",\ - "packageDependencies": [\ - ["blob-util", "npm:2.0.2"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["bluebird", [\ - ["npm:3.7.2", {\ - "packageLocation": "./.yarn/cache/bluebird-npm-3.7.2-6a54136ee3-869417503c.zip/node_modules/bluebird/",\ - "packageDependencies": [\ - ["bluebird", "npm:3.7.2"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["boolbase", [\ - ["npm:1.0.0", {\ - "packageLocation": "./.yarn/cache/boolbase-npm-1.0.0-965fe9af6d-3e25c80ef6.zip/node_modules/boolbase/",\ - "packageDependencies": [\ - ["boolbase", "npm:1.0.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["bootstrap", [\ - ["npm:5.1.3", {\ - "packageLocation": "./.yarn/cache/bootstrap-npm-5.1.3-691fdc19a6-301b5ed872.zip/node_modules/bootstrap/",\ - "packageDependencies": [\ - ["bootstrap", "npm:5.1.3"]\ - ],\ - "linkType": "SOFT"\ - }],\ - ["npm:5.2.0", {\ - "packageLocation": "./.yarn/cache/bootstrap-npm-5.2.0-e6c71ad969-9dbfb5d26b.zip/node_modules/bootstrap/",\ - "packageDependencies": [\ - ["bootstrap", "npm:5.2.0"]\ - ],\ - "linkType": "SOFT"\ - }],\ - ["virtual:10122bfbcba1a448fa8cd209500287123cf7dd2abe325c6afac0050500c2a7843d4fa38428d3ef45d200d480f092839e6533b4c96c028b4d6e4e1d970111b151#npm:5.1.3", {\ - "packageLocation": "./.yarn/__virtual__/bootstrap-virtual-60f254b806/0/cache/bootstrap-npm-5.1.3-691fdc19a6-301b5ed872.zip/node_modules/bootstrap/",\ - "packageDependencies": [\ - ["bootstrap", "virtual:10122bfbcba1a448fa8cd209500287123cf7dd2abe325c6afac0050500c2a7843d4fa38428d3ef45d200d480f092839e6533b4c96c028b4d6e4e1d970111b151#npm:5.1.3"],\ - ["@popperjs/core", "npm:2.11.5"],\ - ["@types/popperjs__core", null]\ - ],\ - "packagePeers": [\ - "@popperjs/core",\ - "@types/popperjs__core"\ - ],\ - "linkType": "HARD"\ - }],\ - ["virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:5.2.0", {\ - "packageLocation": "./.yarn/__virtual__/bootstrap-virtual-3ea260682f/0/cache/bootstrap-npm-5.2.0-e6c71ad969-9dbfb5d26b.zip/node_modules/bootstrap/",\ - "packageDependencies": [\ - ["bootstrap", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:5.2.0"],\ - ["@popperjs/core", "npm:2.11.5"],\ - ["@types/popperjs__core", null]\ - ],\ - "packagePeers": [\ - "@popperjs/core",\ - "@types/popperjs__core"\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["bootstrap-icons", [\ - ["npm:1.9.1", {\ - "packageLocation": "./.yarn/cache/bootstrap-icons-npm-1.9.1-69d14bd4a0-b388264719.zip/node_modules/bootstrap-icons/",\ - "packageDependencies": [\ - ["bootstrap-icons", "npm:1.9.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["brace-expansion", [\ - ["npm:1.1.11", {\ - "packageLocation": "./.yarn/cache/brace-expansion-npm-1.1.11-fb95eb05ad-faf34a7bb0.zip/node_modules/brace-expansion/",\ - "packageDependencies": [\ - ["brace-expansion", "npm:1.1.11"],\ - ["balanced-match", "npm:1.0.2"],\ - ["concat-map", "npm:0.0.1"]\ - ],\ - "linkType": "HARD"\ - }],\ - ["npm:2.0.1", {\ - "packageLocation": "./.yarn/cache/brace-expansion-npm-2.0.1-17aa2616f9-a61e7cd2e8.zip/node_modules/brace-expansion/",\ - "packageDependencies": [\ - ["brace-expansion", "npm:2.0.1"],\ - ["balanced-match", "npm:1.0.2"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["braces", [\ - ["npm:3.0.2", {\ - "packageLocation": "./.yarn/cache/braces-npm-3.0.2-782240b28a-e2a8e769a8.zip/node_modules/braces/",\ - "packageDependencies": [\ - ["braces", "npm:3.0.2"],\ - ["fill-range", "npm:7.0.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["browser-fs-access", [\ - ["npm:0.31.0", {\ - "packageLocation": "./.yarn/cache/browser-fs-access-npm-0.31.0-0e9a01c010-d1b6682415.zip/node_modules/browser-fs-access/",\ - "packageDependencies": [\ - ["browser-fs-access", "npm:0.31.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["browserlist", [\ - ["npm:1.0.1", {\ - "packageLocation": "./.yarn/cache/browserlist-npm-1.0.1-5c12c77f80-db4dc273b5.zip/node_modules/browserlist/",\ - "packageDependencies": [\ - ["browserlist", "npm:1.0.1"],\ - ["chalk", "npm:2.4.2"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["browserslist", [\ - ["npm:4.20.3", {\ - "packageLocation": "./.yarn/cache/browserslist-npm-4.20.3-d7ff9d00b4-1e4b719ac2.zip/node_modules/browserslist/",\ - "packageDependencies": [\ - ["browserslist", "npm:4.20.3"],\ - ["caniuse-lite", "npm:1.0.30001340"],\ - ["electron-to-chromium", "npm:1.4.137"],\ - ["escalade", "npm:3.1.1"],\ - ["node-releases", "npm:2.0.4"],\ - ["picocolors", "npm:1.0.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["buffer", [\ - ["npm:5.7.1", {\ - "packageLocation": "./.yarn/cache/buffer-npm-5.7.1-513ef8259e-e2cf8429e1.zip/node_modules/buffer/",\ - "packageDependencies": [\ - ["buffer", "npm:5.7.1"],\ - ["base64-js", "npm:1.5.1"],\ - ["ieee754", "npm:1.2.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["buffer-crc32", [\ - ["npm:0.2.13", {\ - "packageLocation": "./.yarn/cache/buffer-crc32-npm-0.2.13-c4b6fceac1-06252347ae.zip/node_modules/buffer-crc32/",\ - "packageDependencies": [\ - ["buffer-crc32", "npm:0.2.13"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["buffer-from", [\ - ["npm:1.1.2", {\ - "packageLocation": "./.yarn/cache/buffer-from-npm-1.1.2-03d2f20d7e-0448524a56.zip/node_modules/buffer-from/",\ - "packageDependencies": [\ - ["buffer-from", "npm:1.1.2"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["builtins", [\ - ["npm:4.1.0", {\ - "packageLocation": "./.yarn/cache/builtins-npm-4.1.0-b8969ccdfe-3524f5a589.zip/node_modules/builtins/",\ - "packageDependencies": [\ - ["builtins", "npm:4.1.0"],\ - ["semver", "npm:7.3.7"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["c8", [\ - ["npm:7.12.0", {\ - "packageLocation": "./.yarn/cache/c8-npm-7.12.0-c808cac509-3b7fa9ad7c.zip/node_modules/c8/",\ - "packageDependencies": [\ - ["c8", "npm:7.12.0"],\ - ["@bcoe/v8-coverage", "npm:0.2.3"],\ - ["@istanbuljs/schema", "npm:0.1.3"],\ - ["find-up", "npm:5.0.0"],\ - ["foreground-child", "npm:2.0.0"],\ - ["istanbul-lib-coverage", "npm:3.2.0"],\ - ["istanbul-lib-report", "npm:3.0.0"],\ - ["istanbul-reports", "npm:3.1.4"],\ - ["rimraf", "npm:3.0.2"],\ - ["test-exclude", "npm:6.0.0"],\ - ["v8-to-istanbul", "npm:9.0.1"],\ - ["yargs", "npm:16.2.0"],\ - ["yargs-parser", "npm:20.2.9"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["cacache", [\ - ["npm:16.1.0", {\ - "packageLocation": "./.yarn/cache/cacache-npm-16.1.0-e24d9a7d5b-ddfcf92f07.zip/node_modules/cacache/",\ - "packageDependencies": [\ - ["cacache", "npm:16.1.0"],\ - ["@npmcli/fs", "npm:2.1.0"],\ - ["@npmcli/move-file", "npm:2.0.0"],\ - ["chownr", "npm:2.0.0"],\ - ["fs-minipass", "npm:2.1.0"],\ - ["glob", "npm:8.0.3"],\ - ["infer-owner", "npm:1.0.4"],\ - ["lru-cache", "npm:7.10.1"],\ - ["minipass", "npm:3.1.6"],\ - ["minipass-collect", "npm:1.0.2"],\ - ["minipass-flush", "npm:1.0.5"],\ - ["minipass-pipeline", "npm:1.2.4"],\ - ["mkdirp", "npm:1.0.4"],\ - ["p-map", "npm:4.0.0"],\ - ["promise-inflight", "virtual:e24d9a7d5bfafeb0e9feff2818e85407e1cf44a276d18b9ca6dfb49cddb2524392de2fcf443eda17f1ea0d182e400e896df3142d004a89f718873309f2bace8e#npm:1.0.1"],\ - ["rimraf", "npm:3.0.2"],\ - ["ssri", "npm:9.0.1"],\ - ["tar", "npm:6.1.11"],\ - ["unique-filename", "npm:1.1.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["cachedir", [\ - ["npm:2.3.0", {\ - "packageLocation": "./.yarn/cache/cachedir-npm-2.3.0-640dc16bbb-ec90cb0f2e.zip/node_modules/cachedir/",\ - "packageDependencies": [\ - ["cachedir", "npm:2.3.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["call-bind", [\ - ["npm:1.0.2", {\ - "packageLocation": "./.yarn/cache/call-bind-npm-1.0.2-c957124861-f8e31de9d1.zip/node_modules/call-bind/",\ - "packageDependencies": [\ - ["call-bind", "npm:1.0.2"],\ - ["function-bind", "npm:1.1.1"],\ - ["get-intrinsic", "npm:1.1.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["callsites", [\ - ["npm:3.1.0", {\ - "packageLocation": "./.yarn/cache/callsites-npm-3.1.0-268f989910-072d17b6ab.zip/node_modules/callsites/",\ - "packageDependencies": [\ - ["callsites", "npm:3.1.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["caniuse-lite", [\ - ["npm:1.0.30001340", {\ - "packageLocation": "./.yarn/cache/caniuse-lite-npm-1.0.30001340-5ba8569de6-5b419c93cb.zip/node_modules/caniuse-lite/",\ - "packageDependencies": [\ - ["caniuse-lite", "npm:1.0.30001340"]\ - ],\ - "linkType": "HARD"\ - }],\ - ["npm:1.0.30001368", {\ - "packageLocation": "./.yarn/cache/caniuse-lite-npm-1.0.30001368-82766437b8-e2a763e7bc.zip/node_modules/caniuse-lite/",\ - "packageDependencies": [\ - ["caniuse-lite", "npm:1.0.30001368"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["caseless", [\ - ["npm:0.12.0", {\ - "packageLocation": "./.yarn/cache/caseless-npm-0.12.0-e83bc5df83-b43bd4c440.zip/node_modules/caseless/",\ - "packageDependencies": [\ - ["caseless", "npm:0.12.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["chai", [\ - ["npm:4.3.6", {\ - "packageLocation": "./.yarn/cache/chai-npm-4.3.6-dba90e4b0b-acff93fd53.zip/node_modules/chai/",\ - "packageDependencies": [\ - ["chai", "npm:4.3.6"],\ - ["assertion-error", "npm:1.1.0"],\ - ["check-error", "npm:1.0.2"],\ - ["deep-eql", "npm:3.0.1"],\ - ["get-func-name", "npm:2.0.0"],\ - ["loupe", "npm:2.3.4"],\ - ["pathval", "npm:1.1.1"],\ - ["type-detect", "npm:4.0.8"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["chalk", [\ - ["npm:2.4.2", {\ - "packageLocation": "./.yarn/cache/chalk-npm-2.4.2-3ea16dd91e-ec3661d38f.zip/node_modules/chalk/",\ - "packageDependencies": [\ - ["chalk", "npm:2.4.2"],\ - ["ansi-styles", "npm:3.2.1"],\ - ["escape-string-regexp", "npm:1.0.5"],\ - ["supports-color", "npm:5.5.0"]\ - ],\ - "linkType": "HARD"\ - }],\ - ["npm:4.1.2", {\ - "packageLocation": "./.yarn/cache/chalk-npm-4.1.2-ba8b67ab80-fe75c9d5c7.zip/node_modules/chalk/",\ - "packageDependencies": [\ - ["chalk", "npm:4.1.2"],\ - ["ansi-styles", "npm:4.3.0"],\ - ["supports-color", "npm:7.2.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["character-parser", [\ - ["npm:2.2.0", {\ - "packageLocation": "./.yarn/cache/character-parser-npm-2.2.0-a5df9fb883-71826fae50.zip/node_modules/character-parser/",\ - "packageDependencies": [\ - ["character-parser", "npm:2.2.0"],\ - ["is-regex", "npm:1.1.4"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["check-error", [\ - ["npm:1.0.2", {\ - "packageLocation": "./.yarn/cache/check-error-npm-1.0.2-00c540c6e9-d9d1065044.zip/node_modules/check-error/",\ - "packageDependencies": [\ - ["check-error", "npm:1.0.2"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["check-more-types", [\ - ["npm:2.24.0", {\ - "packageLocation": "./.yarn/cache/check-more-types-npm-2.24.0-fa2e491b27-b09080ec34.zip/node_modules/check-more-types/",\ - "packageDependencies": [\ - ["check-more-types", "npm:2.24.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["chokidar", [\ - ["npm:3.5.3", {\ - "packageLocation": "./.yarn/cache/chokidar-npm-3.5.3-c5f9b0a56a-b49fcde401.zip/node_modules/chokidar/",\ - "packageDependencies": [\ - ["chokidar", "npm:3.5.3"],\ - ["anymatch", "npm:3.1.2"],\ - ["braces", "npm:3.0.2"],\ - ["fsevents", "patch:fsevents@npm%3A2.3.2#~builtin::version=2.3.2&hash=18f3a7"],\ - ["glob-parent", "npm:5.1.2"],\ - ["is-binary-path", "npm:2.1.0"],\ - ["is-glob", "npm:4.0.3"],\ - ["normalize-path", "npm:3.0.0"],\ - ["readdirp", "npm:3.6.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["chownr", [\ - ["npm:2.0.0", {\ - "packageLocation": "./.yarn/cache/chownr-npm-2.0.0-638f1c9c61-c57cf9dd07.zip/node_modules/chownr/",\ - "packageDependencies": [\ - ["chownr", "npm:2.0.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["chrome-trace-event", [\ - ["npm:1.0.3", {\ - "packageLocation": "./.yarn/cache/chrome-trace-event-npm-1.0.3-e0ae3dcd60-cb8b1fc7e8.zip/node_modules/chrome-trace-event/",\ - "packageDependencies": [\ - ["chrome-trace-event", "npm:1.0.3"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["ci-info", [\ - ["npm:3.3.1", {\ - "packageLocation": "./.yarn/cache/ci-info-npm-3.3.1-c80845db6d-244546317c.zip/node_modules/ci-info/",\ - "packageDependencies": [\ - ["ci-info", "npm:3.3.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["clean-stack", [\ - ["npm:2.2.0", {\ - "packageLocation": "./.yarn/cache/clean-stack-npm-2.2.0-a8ce435a5c-2ac8cd2b2f.zip/node_modules/clean-stack/",\ - "packageDependencies": [\ - ["clean-stack", "npm:2.2.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["cli-cursor", [\ - ["npm:3.1.0", {\ - "packageLocation": "./.yarn/cache/cli-cursor-npm-3.1.0-fee1e46b5e-2692784c6c.zip/node_modules/cli-cursor/",\ - "packageDependencies": [\ - ["cli-cursor", "npm:3.1.0"],\ - ["restore-cursor", "npm:3.1.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["cli-table3", [\ - ["npm:0.6.2", {\ - "packageLocation": "./.yarn/cache/cli-table3-npm-0.6.2-dff919b99d-2f82391698.zip/node_modules/cli-table3/",\ - "packageDependencies": [\ - ["cli-table3", "npm:0.6.2"],\ - ["@colors/colors", "npm:1.5.0"],\ - ["string-width", "npm:4.2.3"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["cli-truncate", [\ - ["npm:2.1.0", {\ - "packageLocation": "./.yarn/cache/cli-truncate-npm-2.1.0-72184d3467-bf1e4e6195.zip/node_modules/cli-truncate/",\ - "packageDependencies": [\ - ["cli-truncate", "npm:2.1.0"],\ - ["slice-ansi", "npm:3.0.0"],\ - ["string-width", "npm:4.2.3"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["cliui", [\ - ["npm:7.0.4", {\ - "packageLocation": "./.yarn/cache/cliui-npm-7.0.4-d6b8a9edb6-ce2e8f578a.zip/node_modules/cliui/",\ - "packageDependencies": [\ - ["cliui", "npm:7.0.4"],\ - ["string-width", "npm:4.2.3"],\ - ["strip-ansi", "npm:6.0.1"],\ - ["wrap-ansi", "npm:7.0.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["clone", [\ - ["npm:2.1.2", {\ - "packageLocation": "./.yarn/cache/clone-npm-2.1.2-1d491c6629-aaf106e9bc.zip/node_modules/clone/",\ - "packageDependencies": [\ - ["clone", "npm:2.1.2"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["color-convert", [\ - ["npm:1.9.3", {\ - "packageLocation": "./.yarn/cache/color-convert-npm-1.9.3-1fe690075e-fd7a64a17c.zip/node_modules/color-convert/",\ - "packageDependencies": [\ - ["color-convert", "npm:1.9.3"],\ - ["color-name", "npm:1.1.3"]\ - ],\ - "linkType": "HARD"\ - }],\ - ["npm:2.0.1", {\ - "packageLocation": "./.yarn/cache/color-convert-npm-2.0.1-79730e935b-79e6bdb9fd.zip/node_modules/color-convert/",\ - "packageDependencies": [\ - ["color-convert", "npm:2.0.1"],\ - ["color-name", "npm:1.1.4"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["color-name", [\ - ["npm:1.1.3", {\ - "packageLocation": "./.yarn/cache/color-name-npm-1.1.3-728b7b5d39-09c5d3e33d.zip/node_modules/color-name/",\ - "packageDependencies": [\ - ["color-name", "npm:1.1.3"]\ - ],\ - "linkType": "HARD"\ - }],\ - ["npm:1.1.4", {\ - "packageLocation": "./.yarn/cache/color-name-npm-1.1.4-025792b0ea-b044585952.zip/node_modules/color-name/",\ - "packageDependencies": [\ - ["color-name", "npm:1.1.4"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["color-support", [\ - ["npm:1.1.3", {\ - "packageLocation": "./.yarn/cache/color-support-npm-1.1.3-3be5c53455-9b73568176.zip/node_modules/color-support/",\ - "packageDependencies": [\ - ["color-support", "npm:1.1.3"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["colorette", [\ - ["npm:2.0.16", {\ - "packageLocation": "./.yarn/cache/colorette-npm-2.0.16-7b996485d7-cd55596a3a.zip/node_modules/colorette/",\ - "packageDependencies": [\ - ["colorette", "npm:2.0.16"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["combined-stream", [\ - ["npm:1.0.8", {\ - "packageLocation": "./.yarn/cache/combined-stream-npm-1.0.8-dc14d4a63a-49fa4aeb49.zip/node_modules/combined-stream/",\ - "packageDependencies": [\ - ["combined-stream", "npm:1.0.8"],\ - ["delayed-stream", "npm:1.0.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["commander", [\ - ["npm:2.20.3", {\ - "packageLocation": "./.yarn/cache/commander-npm-2.20.3-d8dcbaa39b-ab8c07884e.zip/node_modules/commander/",\ - "packageDependencies": [\ - ["commander", "npm:2.20.3"]\ - ],\ - "linkType": "HARD"\ - }],\ - ["npm:5.1.0", {\ - "packageLocation": "./.yarn/cache/commander-npm-5.1.0-7e939e7832-0b7fec1712.zip/node_modules/commander/",\ - "packageDependencies": [\ - ["commander", "npm:5.1.0"]\ - ],\ - "linkType": "HARD"\ - }],\ - ["npm:7.2.0", {\ - "packageLocation": "./.yarn/cache/commander-npm-7.2.0-19178180f8-53501cbeee.zip/node_modules/commander/",\ - "packageDependencies": [\ - ["commander", "npm:7.2.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["common-tags", [\ - ["npm:1.8.2", {\ - "packageLocation": "./.yarn/cache/common-tags-npm-1.8.2-2c30ba69b3-767a6255a8.zip/node_modules/common-tags/",\ - "packageDependencies": [\ - ["common-tags", "npm:1.8.2"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["concat-map", [\ - ["npm:0.0.1", {\ - "packageLocation": "./.yarn/cache/concat-map-npm-0.0.1-85a921b7ee-902a9f5d89.zip/node_modules/concat-map/",\ - "packageDependencies": [\ - ["concat-map", "npm:0.0.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["console-control-strings", [\ - ["npm:1.1.0", {\ - "packageLocation": "./.yarn/cache/console-control-strings-npm-1.1.0-e3160e5275-8755d76787.zip/node_modules/console-control-strings/",\ - "packageDependencies": [\ - ["console-control-strings", "npm:1.1.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["constantinople", [\ - ["npm:4.0.1", {\ - "packageLocation": "./.yarn/cache/constantinople-npm-4.0.1-925d9c26ce-8f70f16ddf.zip/node_modules/constantinople/",\ - "packageDependencies": [\ - ["constantinople", "npm:4.0.1"],\ - ["@babel/parser", "npm:7.18.4"],\ - ["@babel/types", "npm:7.18.4"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["convert-source-map", [\ - ["npm:1.8.0", {\ - "packageLocation": "./.yarn/cache/convert-source-map-npm-1.8.0-037f671dde-985d974a2d.zip/node_modules/convert-source-map/",\ - "packageDependencies": [\ - ["convert-source-map", "npm:1.8.0"],\ - ["safe-buffer", "npm:5.1.2"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["core-util-is", [\ - ["npm:1.0.2", {\ - "packageLocation": "./.yarn/cache/core-util-is-npm-1.0.2-9fc2b94dc3-7a4c925b49.zip/node_modules/core-util-is/",\ - "packageDependencies": [\ - ["core-util-is", "npm:1.0.2"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["cosmiconfig", [\ - ["npm:7.0.1", {\ - "packageLocation": "./.yarn/cache/cosmiconfig-npm-7.0.1-dd19ae2403-4be63e7117.zip/node_modules/cosmiconfig/",\ - "packageDependencies": [\ - ["cosmiconfig", "npm:7.0.1"],\ - ["@types/parse-json", "npm:4.0.0"],\ - ["import-fresh", "npm:3.3.0"],\ - ["parse-json", "npm:5.2.0"],\ - ["path-type", "npm:4.0.0"],\ - ["yaml", "npm:1.10.2"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["cross-spawn", [\ - ["npm:7.0.3", {\ - "packageLocation": "./.yarn/cache/cross-spawn-npm-7.0.3-e4ff3e65b3-671cc7c728.zip/node_modules/cross-spawn/",\ - "packageDependencies": [\ - ["cross-spawn", "npm:7.0.3"],\ - ["path-key", "npm:3.1.1"],\ - ["shebang-command", "npm:2.0.0"],\ - ["which", "npm:2.0.2"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["css-render", [\ - ["npm:0.15.10", {\ - "packageLocation": "./.yarn/cache/css-render-npm-0.15.10-57cf7c0959-051ebb6a56.zip/node_modules/css-render/",\ - "packageDependencies": [\ - ["css-render", "npm:0.15.10"],\ - ["@emotion/hash", "npm:0.8.0"],\ - ["@types/node", "npm:17.0.29"],\ - ["csstype", "npm:3.0.11"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["css-select", [\ - ["npm:4.3.0", {\ - "packageLocation": "./.yarn/cache/css-select-npm-4.3.0-72f53028ec-d620273683.zip/node_modules/css-select/",\ - "packageDependencies": [\ - ["css-select", "npm:4.3.0"],\ - ["boolbase", "npm:1.0.0"],\ - ["css-what", "npm:6.1.0"],\ - ["domhandler", "npm:4.3.1"],\ - ["domutils", "npm:2.8.0"],\ - ["nth-check", "npm:2.1.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["css-tree", [\ - ["npm:1.1.3", {\ - "packageLocation": "./.yarn/cache/css-tree-npm-1.1.3-9c46f35513-79f9b81803.zip/node_modules/css-tree/",\ - "packageDependencies": [\ - ["css-tree", "npm:1.1.3"],\ - ["mdn-data", "npm:2.0.14"],\ - ["source-map", "npm:0.6.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["css-what", [\ - ["npm:6.1.0", {\ - "packageLocation": "./.yarn/cache/css-what-npm-6.1.0-57f751efbb-b975e547e1.zip/node_modules/css-what/",\ - "packageDependencies": [\ - ["css-what", "npm:6.1.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["cssesc", [\ - ["npm:3.0.0", {\ - "packageLocation": "./.yarn/cache/cssesc-npm-3.0.0-15ec56f86f-f8c4ababff.zip/node_modules/cssesc/",\ - "packageDependencies": [\ - ["cssesc", "npm:3.0.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["csso", [\ - ["npm:4.2.0", {\ - "packageLocation": "./.yarn/cache/csso-npm-4.2.0-b277db8d71-380ba9663d.zip/node_modules/csso/",\ - "packageDependencies": [\ - ["csso", "npm:4.2.0"],\ - ["css-tree", "npm:1.1.3"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["csstype", [\ - ["npm:2.6.20", {\ - "packageLocation": "./.yarn/cache/csstype-npm-2.6.20-7c929732a1-cb5d5ded49.zip/node_modules/csstype/",\ - "packageDependencies": [\ - ["csstype", "npm:2.6.20"]\ - ],\ - "linkType": "HARD"\ - }],\ - ["npm:3.0.11", {\ - "packageLocation": "./.yarn/cache/csstype-npm-3.0.11-b49897178d-95e56abfe9.zip/node_modules/csstype/",\ - "packageDependencies": [\ - ["csstype", "npm:3.0.11"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["cypress", [\ - ["npm:10.3.1", {\ - "packageLocation": "./.yarn/unplugged/cypress-npm-10.3.1-b9950af2d1/node_modules/cypress/",\ - "packageDependencies": [\ - ["cypress", "npm:10.3.1"],\ - ["@cypress/request", "npm:2.88.10"],\ - ["@cypress/xvfb", "npm:1.2.4"],\ - ["@types/node", "npm:14.18.18"],\ - ["@types/sinonjs__fake-timers", "npm:8.1.1"],\ - ["@types/sizzle", "npm:2.3.3"],\ - ["arch", "npm:2.2.0"],\ - ["blob-util", "npm:2.0.2"],\ - ["bluebird", "npm:3.7.2"],\ - ["buffer", "npm:5.7.1"],\ - ["cachedir", "npm:2.3.0"],\ - ["chalk", "npm:4.1.2"],\ - ["check-more-types", "npm:2.24.0"],\ - ["cli-cursor", "npm:3.1.0"],\ - ["cli-table3", "npm:0.6.2"],\ - ["commander", "npm:5.1.0"],\ - ["common-tags", "npm:1.8.2"],\ - ["dayjs", "npm:1.11.2"],\ - ["debug", "virtual:b9950af2d111388934806057a586eabc99a9a1279d1f7d5a87654ac6209cdd318e086140e128e4a5adc819e925bea187073b27a79d28a166d5dffe758bcd5335#npm:4.3.4"],\ - ["enquirer", "npm:2.3.6"],\ - ["eventemitter2", "npm:6.4.5"],\ - ["execa", "npm:4.1.0"],\ - ["executable", "npm:4.1.1"],\ - ["extract-zip", "npm:2.0.1"],\ - ["figures", "npm:3.2.0"],\ - ["fs-extra", "npm:9.1.0"],\ - ["getos", "npm:3.2.1"],\ - ["is-ci", "npm:3.0.1"],\ - ["is-installed-globally", "npm:0.4.0"],\ - ["lazy-ass", "npm:1.6.0"],\ - ["listr2", "virtual:b9950af2d111388934806057a586eabc99a9a1279d1f7d5a87654ac6209cdd318e086140e128e4a5adc819e925bea187073b27a79d28a166d5dffe758bcd5335#npm:3.14.0"],\ - ["lodash", "npm:4.17.21"],\ - ["log-symbols", "npm:4.1.0"],\ - ["minimist", "npm:1.2.6"],\ - ["ospath", "npm:1.2.2"],\ - ["pretty-bytes", "npm:5.6.0"],\ - ["proxy-from-env", "npm:1.0.0"],\ - ["request-progress", "npm:3.0.0"],\ - ["semver", "npm:7.3.7"],\ - ["supports-color", "npm:8.1.1"],\ - ["tmp", "npm:0.2.1"],\ - ["untildify", "npm:4.0.0"],\ - ["yauzl", "npm:2.10.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["cypress-real-events", [\ - ["npm:1.7.1", {\ - "packageLocation": "./.yarn/cache/cypress-real-events-npm-1.7.1-6d5a866c0e-b31c2facfa.zip/node_modules/cypress-real-events/",\ - "packageDependencies": [\ - ["cypress-real-events", "npm:1.7.1"]\ - ],\ - "linkType": "SOFT"\ - }],\ - ["virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:1.7.1", {\ - "packageLocation": "./.yarn/__virtual__/cypress-real-events-virtual-b344eb5fcd/0/cache/cypress-real-events-npm-1.7.1-6d5a866c0e-b31c2facfa.zip/node_modules/cypress-real-events/",\ - "packageDependencies": [\ - ["cypress-real-events", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:1.7.1"],\ - ["@types/cypress", null],\ - ["cypress", "npm:10.3.1"]\ - ],\ - "packagePeers": [\ - "@types/cypress",\ - "cypress"\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["d3", [\ - ["npm:7.6.1", {\ - "packageLocation": "./.yarn/cache/d3-npm-7.6.1-9545deaa85-af883cfeaf.zip/node_modules/d3/",\ - "packageDependencies": [\ - ["d3", "npm:7.6.1"],\ - ["d3-array", "npm:3.1.6"],\ - ["d3-axis", "npm:3.0.0"],\ - ["d3-brush", "npm:3.0.0"],\ - ["d3-chord", "npm:3.0.1"],\ - ["d3-color", "npm:3.1.0"],\ - ["d3-contour", "npm:4.0.0"],\ - ["d3-delaunay", "npm:6.0.2"],\ - ["d3-dispatch", "npm:3.0.1"],\ - ["d3-drag", "npm:3.0.0"],\ - ["d3-dsv", "npm:3.0.1"],\ - ["d3-ease", "npm:3.0.1"],\ - ["d3-fetch", "npm:3.0.1"],\ - ["d3-force", "npm:3.0.0"],\ - ["d3-format", "npm:3.1.0"],\ - ["d3-geo", "npm:3.0.1"],\ - ["d3-hierarchy", "npm:3.1.2"],\ - ["d3-interpolate", "npm:3.0.1"],\ - ["d3-path", "npm:3.0.1"],\ - ["d3-polygon", "npm:3.0.1"],\ - ["d3-quadtree", "npm:3.0.1"],\ - ["d3-random", "npm:3.0.1"],\ - ["d3-scale", "npm:4.0.2"],\ - ["d3-scale-chromatic", "npm:3.0.0"],\ - ["d3-selection", "npm:3.0.0"],\ - ["d3-shape", "npm:3.1.0"],\ - ["d3-time", "npm:3.0.0"],\ - ["d3-time-format", "npm:4.1.0"],\ - ["d3-timer", "npm:3.0.1"],\ - ["d3-transition", "virtual:0f86c8ad35ed5e8074d92c2c7b108ccb80697d12d1f8d7d6652d16c1efa6c4d26d8de3689bc5728bc948bba913da0e22877ef20338493e863732102d95b6678d#npm:3.0.1"],\ - ["d3-zoom", "npm:3.0.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["d3-array", [\ - ["npm:3.1.6", {\ - "packageLocation": "./.yarn/cache/d3-array-npm-3.1.6-fa4f0bcb75-32f515bd25.zip/node_modules/d3-array/",\ - "packageDependencies": [\ - ["d3-array", "npm:3.1.6"],\ - ["internmap", "npm:2.0.3"]\ - ],\ - "linkType": "HARD"\ - }],\ - ["npm:3.2.0", {\ - "packageLocation": "./.yarn/cache/d3-array-npm-3.2.0-c3a38fe288-e236f6670b.zip/node_modules/d3-array/",\ - "packageDependencies": [\ - ["d3-array", "npm:3.2.0"],\ - ["internmap", "npm:2.0.3"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["d3-axis", [\ - ["npm:3.0.0", {\ - "packageLocation": "./.yarn/cache/d3-axis-npm-3.0.0-81ef16a9a5-227ddaa6d4.zip/node_modules/d3-axis/",\ - "packageDependencies": [\ - ["d3-axis", "npm:3.0.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["d3-brush", [\ - ["npm:3.0.0", {\ - "packageLocation": "./.yarn/cache/d3-brush-npm-3.0.0-0f86c8ad35-1d04216776.zip/node_modules/d3-brush/",\ - "packageDependencies": [\ - ["d3-brush", "npm:3.0.0"],\ - ["d3-dispatch", "npm:3.0.1"],\ - ["d3-drag", "npm:3.0.0"],\ - ["d3-interpolate", "npm:3.0.1"],\ - ["d3-selection", "npm:3.0.0"],\ - ["d3-transition", "virtual:0f86c8ad35ed5e8074d92c2c7b108ccb80697d12d1f8d7d6652d16c1efa6c4d26d8de3689bc5728bc948bba913da0e22877ef20338493e863732102d95b6678d#npm:3.0.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["d3-chord", [\ - ["npm:3.0.1", {\ - "packageLocation": "./.yarn/cache/d3-chord-npm-3.0.1-3fcb345658-ddf35d4167.zip/node_modules/d3-chord/",\ - "packageDependencies": [\ - ["d3-chord", "npm:3.0.1"],\ - ["d3-path", "npm:3.0.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["d3-color", [\ - ["npm:3.1.0", {\ - "packageLocation": "./.yarn/cache/d3-color-npm-3.1.0-fc73fe3b15-4931fbfda5.zip/node_modules/d3-color/",\ - "packageDependencies": [\ - ["d3-color", "npm:3.1.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["d3-contour", [\ - ["npm:4.0.0", {\ - "packageLocation": "./.yarn/cache/d3-contour-npm-4.0.0-9b98ab4af2-1f9b9e56d0.zip/node_modules/d3-contour/",\ - "packageDependencies": [\ - ["d3-contour", "npm:4.0.0"],\ - ["d3-array", "npm:3.2.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["d3-delaunay", [\ - ["npm:6.0.2", {\ - "packageLocation": "./.yarn/cache/d3-delaunay-npm-6.0.2-23823819ce-80b18686dd.zip/node_modules/d3-delaunay/",\ - "packageDependencies": [\ - ["d3-delaunay", "npm:6.0.2"],\ - ["delaunator", "npm:5.0.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["d3-dispatch", [\ - ["npm:3.0.1", {\ - "packageLocation": "./.yarn/cache/d3-dispatch-npm-3.0.1-5f44c3166f-fdfd4a230f.zip/node_modules/d3-dispatch/",\ - "packageDependencies": [\ - ["d3-dispatch", "npm:3.0.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["d3-drag", [\ - ["npm:3.0.0", {\ - "packageLocation": "./.yarn/cache/d3-drag-npm-3.0.0-cf7b48417f-d297231e60.zip/node_modules/d3-drag/",\ - "packageDependencies": [\ - ["d3-drag", "npm:3.0.0"],\ - ["d3-dispatch", "npm:3.0.1"],\ - ["d3-selection", "npm:3.0.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["d3-dsv", [\ - ["npm:3.0.1", {\ - "packageLocation": "./.yarn/cache/d3-dsv-npm-3.0.1-5d88fb8a85-5fc0723647.zip/node_modules/d3-dsv/",\ - "packageDependencies": [\ - ["d3-dsv", "npm:3.0.1"],\ - ["commander", "npm:7.2.0"],\ - ["iconv-lite", "npm:0.6.3"],\ - ["rw", "npm:1.3.3"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["d3-ease", [\ - ["npm:3.0.1", {\ - "packageLocation": "./.yarn/cache/d3-ease-npm-3.0.1-f8f3709dc7-06e2ee5326.zip/node_modules/d3-ease/",\ - "packageDependencies": [\ - ["d3-ease", "npm:3.0.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["d3-fetch", [\ - ["npm:3.0.1", {\ - "packageLocation": "./.yarn/cache/d3-fetch-npm-3.0.1-ad9ce3dc3e-382dcea065.zip/node_modules/d3-fetch/",\ - "packageDependencies": [\ - ["d3-fetch", "npm:3.0.1"],\ - ["d3-dsv", "npm:3.0.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["d3-force", [\ - ["npm:3.0.0", {\ - "packageLocation": "./.yarn/cache/d3-force-npm-3.0.0-462e87e63b-6c7e96438c.zip/node_modules/d3-force/",\ - "packageDependencies": [\ - ["d3-force", "npm:3.0.0"],\ - ["d3-dispatch", "npm:3.0.1"],\ - ["d3-quadtree", "npm:3.0.1"],\ - ["d3-timer", "npm:3.0.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["d3-format", [\ - ["npm:3.1.0", {\ - "packageLocation": "./.yarn/cache/d3-format-npm-3.1.0-dfc19924ca-f345ec3b8a.zip/node_modules/d3-format/",\ - "packageDependencies": [\ - ["d3-format", "npm:3.1.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["d3-geo", [\ - ["npm:3.0.1", {\ - "packageLocation": "./.yarn/cache/d3-geo-npm-3.0.1-2aabdbb750-e0f7e6a2f0.zip/node_modules/d3-geo/",\ - "packageDependencies": [\ - ["d3-geo", "npm:3.0.1"],\ - ["d3-array", "npm:3.1.6"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["d3-hierarchy", [\ - ["npm:3.1.2", {\ - "packageLocation": "./.yarn/cache/d3-hierarchy-npm-3.1.2-1ac1bae7e3-0fd946a8c5.zip/node_modules/d3-hierarchy/",\ - "packageDependencies": [\ - ["d3-hierarchy", "npm:3.1.2"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["d3-interpolate", [\ - ["npm:3.0.1", {\ - "packageLocation": "./.yarn/cache/d3-interpolate-npm-3.0.1-77ddca7977-a42ba314e2.zip/node_modules/d3-interpolate/",\ - "packageDependencies": [\ - ["d3-interpolate", "npm:3.0.1"],\ - ["d3-color", "npm:3.1.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["d3-path", [\ - ["npm:3.0.1", {\ - "packageLocation": "./.yarn/cache/d3-path-npm-3.0.1-c8a313bdd3-6347c7055e.zip/node_modules/d3-path/",\ - "packageDependencies": [\ - ["d3-path", "npm:3.0.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["d3-polygon", [\ - ["npm:3.0.1", {\ - "packageLocation": "./.yarn/cache/d3-polygon-npm-3.0.1-ccec77a8d4-0b85c53251.zip/node_modules/d3-polygon/",\ - "packageDependencies": [\ - ["d3-polygon", "npm:3.0.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["d3-quadtree", [\ - ["npm:3.0.1", {\ - "packageLocation": "./.yarn/cache/d3-quadtree-npm-3.0.1-6f0eae8c83-5469d46276.zip/node_modules/d3-quadtree/",\ - "packageDependencies": [\ - ["d3-quadtree", "npm:3.0.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["d3-random", [\ - ["npm:3.0.1", {\ - "packageLocation": "./.yarn/cache/d3-random-npm-3.0.1-4fabe65eda-a70ad8d1ca.zip/node_modules/d3-random/",\ - "packageDependencies": [\ - ["d3-random", "npm:3.0.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["d3-scale", [\ - ["npm:4.0.2", {\ - "packageLocation": "./.yarn/cache/d3-scale-npm-4.0.2-d17a53447b-a9c770d283.zip/node_modules/d3-scale/",\ - "packageDependencies": [\ - ["d3-scale", "npm:4.0.2"],\ - ["d3-array", "npm:3.1.6"],\ - ["d3-format", "npm:3.1.0"],\ - ["d3-interpolate", "npm:3.0.1"],\ - ["d3-time", "npm:3.0.0"],\ - ["d3-time-format", "npm:4.1.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["d3-scale-chromatic", [\ - ["npm:3.0.0", {\ - "packageLocation": "./.yarn/cache/d3-scale-chromatic-npm-3.0.0-ca3b48a3cb-a8ce4cb026.zip/node_modules/d3-scale-chromatic/",\ - "packageDependencies": [\ - ["d3-scale-chromatic", "npm:3.0.0"],\ - ["d3-color", "npm:3.1.0"],\ - ["d3-interpolate", "npm:3.0.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["d3-selection", [\ - ["npm:3.0.0", {\ - "packageLocation": "./.yarn/cache/d3-selection-npm-3.0.0-39a42b4ca9-f4e60e1333.zip/node_modules/d3-selection/",\ - "packageDependencies": [\ - ["d3-selection", "npm:3.0.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["d3-shape", [\ - ["npm:3.1.0", {\ - "packageLocation": "./.yarn/cache/d3-shape-npm-3.1.0-a298c27eca-3dffe31b56.zip/node_modules/d3-shape/",\ - "packageDependencies": [\ - ["d3-shape", "npm:3.1.0"],\ - ["d3-path", "npm:3.0.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["d3-time", [\ - ["npm:3.0.0", {\ - "packageLocation": "./.yarn/cache/d3-time-npm-3.0.0-a4963e64c8-01646568ef.zip/node_modules/d3-time/",\ - "packageDependencies": [\ - ["d3-time", "npm:3.0.0"],\ - ["d3-array", "npm:3.1.6"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["d3-time-format", [\ - ["npm:4.1.0", {\ - "packageLocation": "./.yarn/cache/d3-time-format-npm-4.1.0-7f352c4634-7342bce283.zip/node_modules/d3-time-format/",\ - "packageDependencies": [\ - ["d3-time-format", "npm:4.1.0"],\ - ["d3-time", "npm:3.0.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["d3-timer", [\ - ["npm:3.0.1", {\ - "packageLocation": "./.yarn/cache/d3-timer-npm-3.0.1-45083f465d-1cfddf86d7.zip/node_modules/d3-timer/",\ - "packageDependencies": [\ - ["d3-timer", "npm:3.0.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["d3-transition", [\ - ["npm:3.0.1", {\ - "packageLocation": "./.yarn/cache/d3-transition-npm-3.0.1-9191e0faaa-cb1e6e018c.zip/node_modules/d3-transition/",\ - "packageDependencies": [\ - ["d3-transition", "npm:3.0.1"]\ - ],\ - "linkType": "SOFT"\ - }],\ - ["virtual:0f86c8ad35ed5e8074d92c2c7b108ccb80697d12d1f8d7d6652d16c1efa6c4d26d8de3689bc5728bc948bba913da0e22877ef20338493e863732102d95b6678d#npm:3.0.1", {\ - "packageLocation": "./.yarn/__virtual__/d3-transition-virtual-19b5c5972e/0/cache/d3-transition-npm-3.0.1-9191e0faaa-cb1e6e018c.zip/node_modules/d3-transition/",\ - "packageDependencies": [\ - ["d3-transition", "virtual:0f86c8ad35ed5e8074d92c2c7b108ccb80697d12d1f8d7d6652d16c1efa6c4d26d8de3689bc5728bc948bba913da0e22877ef20338493e863732102d95b6678d#npm:3.0.1"],\ - ["@types/d3-selection", null],\ - ["d3-color", "npm:3.1.0"],\ - ["d3-dispatch", "npm:3.0.1"],\ - ["d3-ease", "npm:3.0.1"],\ - ["d3-interpolate", "npm:3.0.1"],\ - ["d3-selection", "npm:3.0.0"],\ - ["d3-timer", "npm:3.0.1"]\ - ],\ - "packagePeers": [\ - "@types/d3-selection",\ - "d3-selection"\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["d3-zoom", [\ - ["npm:3.0.0", {\ - "packageLocation": "./.yarn/cache/d3-zoom-npm-3.0.0-18f706a421-8056e35272.zip/node_modules/d3-zoom/",\ - "packageDependencies": [\ - ["d3-zoom", "npm:3.0.0"],\ - ["d3-dispatch", "npm:3.0.1"],\ - ["d3-drag", "npm:3.0.0"],\ - ["d3-interpolate", "npm:3.0.1"],\ - ["d3-selection", "npm:3.0.0"],\ - ["d3-transition", "virtual:0f86c8ad35ed5e8074d92c2c7b108ccb80697d12d1f8d7d6652d16c1efa6c4d26d8de3689bc5728bc948bba913da0e22877ef20338493e863732102d95b6678d#npm:3.0.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["dashdash", [\ - ["npm:1.14.1", {\ - "packageLocation": "./.yarn/cache/dashdash-npm-1.14.1-be8f10a286-3634c24957.zip/node_modules/dashdash/",\ - "packageDependencies": [\ - ["dashdash", "npm:1.14.1"],\ - ["assert-plus", "npm:1.0.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["date-fns", [\ - ["npm:2.28.0", {\ - "packageLocation": "./.yarn/cache/date-fns-npm-2.28.0-c19c5add1b-a0516b2e4f.zip/node_modules/date-fns/",\ - "packageDependencies": [\ - ["date-fns", "npm:2.28.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["date-fns-tz", [\ - ["npm:1.3.3", {\ - "packageLocation": "./.yarn/cache/date-fns-tz-npm-1.3.3-4b42de3dcf-52111dffb4.zip/node_modules/date-fns-tz/",\ - "packageDependencies": [\ - ["date-fns-tz", "npm:1.3.3"]\ - ],\ - "linkType": "SOFT"\ - }],\ - ["virtual:9f096c233074b200486016c951159c23194337e7c7d59a71ca2c42d04bf345037b52ab329d71315b0e0d2a9be58321dfafc718b2bc37ea4bde4e8e682754a169#npm:1.3.3", {\ - "packageLocation": "./.yarn/__virtual__/date-fns-tz-virtual-157457fef7/0/cache/date-fns-tz-npm-1.3.3-4b42de3dcf-52111dffb4.zip/node_modules/date-fns-tz/",\ - "packageDependencies": [\ - ["date-fns-tz", "virtual:9f096c233074b200486016c951159c23194337e7c7d59a71ca2c42d04bf345037b52ab329d71315b0e0d2a9be58321dfafc718b2bc37ea4bde4e8e682754a169#npm:1.3.3"],\ - ["@types/date-fns", null],\ - ["date-fns", "npm:2.28.0"]\ - ],\ - "packagePeers": [\ - "@types/date-fns",\ - "date-fns"\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["dayjs", [\ - ["npm:1.11.2", {\ - "packageLocation": "./.yarn/cache/dayjs-npm-1.11.2-644b12fe04-78f8bd04a9.zip/node_modules/dayjs/",\ - "packageDependencies": [\ - ["dayjs", "npm:1.11.2"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["debug", [\ - ["npm:2.6.9", {\ - "packageLocation": "./.yarn/cache/debug-npm-2.6.9-7d4cb597dc-d2f51589ca.zip/node_modules/debug/",\ - "packageDependencies": [\ - ["debug", "npm:2.6.9"]\ - ],\ - "linkType": "SOFT"\ - }],\ - ["npm:3.2.7", {\ - "packageLocation": "./.yarn/cache/debug-npm-3.2.7-754e818c7a-b3d8c59407.zip/node_modules/debug/",\ - "packageDependencies": [\ - ["debug", "npm:3.2.7"]\ - ],\ - "linkType": "SOFT"\ - }],\ - ["npm:4.3.4", {\ - "packageLocation": "./.yarn/cache/debug-npm-4.3.4-4513954577-3dbad3f94e.zip/node_modules/debug/",\ - "packageDependencies": [\ - ["debug", "npm:4.3.4"]\ - ],\ - "linkType": "SOFT"\ - }],\ - ["virtual:396a3691f7b25accf085fe2fff1f56eb7540eff3f2e928a7572ca1de9b831ff8f22136404f236aaed35d90369918dfc34392844d0f822a310563f34746dfb015#npm:3.2.7", {\ - "packageLocation": "./.yarn/__virtual__/debug-virtual-507f12afb6/0/cache/debug-npm-3.2.7-754e818c7a-b3d8c59407.zip/node_modules/debug/",\ - "packageDependencies": [\ - ["debug", "virtual:396a3691f7b25accf085fe2fff1f56eb7540eff3f2e928a7572ca1de9b831ff8f22136404f236aaed35d90369918dfc34392844d0f822a310563f34746dfb015#npm:3.2.7"],\ - ["@types/supports-color", null],\ - ["ms", "npm:2.1.2"],\ - ["supports-color", null]\ - ],\ - "packagePeers": [\ - "@types/supports-color",\ - "supports-color"\ - ],\ - "linkType": "HARD"\ - }],\ - ["virtual:b86a9fb34323a98c6519528ed55faa0d9b44ca8879307c0b29aa384bde47ff59a7d0c9051b31246f14521dfb71ba3c5d6d0b35c29fffc17bf875aa6ad977d9e8#npm:4.3.4", {\ - "packageLocation": "./.yarn/__virtual__/debug-virtual-4488998e89/0/cache/debug-npm-4.3.4-4513954577-3dbad3f94e.zip/node_modules/debug/",\ - "packageDependencies": [\ - ["debug", "virtual:b86a9fb34323a98c6519528ed55faa0d9b44ca8879307c0b29aa384bde47ff59a7d0c9051b31246f14521dfb71ba3c5d6d0b35c29fffc17bf875aa6ad977d9e8#npm:4.3.4"],\ - ["@types/supports-color", null],\ - ["ms", "npm:2.1.2"],\ - ["supports-color", null]\ - ],\ - "packagePeers": [\ - "@types/supports-color",\ - "supports-color"\ - ],\ - "linkType": "HARD"\ - }],\ - ["virtual:b9950af2d111388934806057a586eabc99a9a1279d1f7d5a87654ac6209cdd318e086140e128e4a5adc819e925bea187073b27a79d28a166d5dffe758bcd5335#npm:4.3.4", {\ - "packageLocation": "./.yarn/__virtual__/debug-virtual-eda81ef27b/0/cache/debug-npm-4.3.4-4513954577-3dbad3f94e.zip/node_modules/debug/",\ - "packageDependencies": [\ - ["debug", "virtual:b9950af2d111388934806057a586eabc99a9a1279d1f7d5a87654ac6209cdd318e086140e128e4a5adc819e925bea187073b27a79d28a166d5dffe758bcd5335#npm:4.3.4"],\ - ["@types/supports-color", null],\ - ["ms", "npm:2.1.2"],\ - ["supports-color", "npm:8.1.1"]\ - ],\ - "packagePeers": [\ - "@types/supports-color",\ - "supports-color"\ - ],\ - "linkType": "HARD"\ - }],\ - ["virtual:c0858ad0a599e687a7d876de5591e3b098ca550f5c1ad46e7d0e2b6f5720a919cb228a47405daf7d626be1747e41a5b93e4b4d748f16d5e7c36c433aed618452#npm:2.6.9", {\ - "packageLocation": "./.yarn/__virtual__/debug-virtual-398581acf1/0/cache/debug-npm-2.6.9-7d4cb597dc-d2f51589ca.zip/node_modules/debug/",\ - "packageDependencies": [\ - ["debug", "virtual:c0858ad0a599e687a7d876de5591e3b098ca550f5c1ad46e7d0e2b6f5720a919cb228a47405daf7d626be1747e41a5b93e4b4d748f16d5e7c36c433aed618452#npm:2.6.9"],\ - ["@types/supports-color", null],\ - ["ms", "npm:2.0.0"],\ - ["supports-color", null]\ - ],\ - "packagePeers": [\ - "@types/supports-color",\ - "supports-color"\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["deep-eql", [\ - ["npm:3.0.1", {\ - "packageLocation": "./.yarn/cache/deep-eql-npm-3.0.1-9a66c09c65-4f4c9fb79e.zip/node_modules/deep-eql/",\ - "packageDependencies": [\ - ["deep-eql", "npm:3.0.1"],\ - ["type-detect", "npm:4.0.8"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["deep-is", [\ - ["npm:0.1.4", {\ - "packageLocation": "./.yarn/cache/deep-is-npm-0.1.4-88938b5a67-edb65dd0d7.zip/node_modules/deep-is/",\ - "packageDependencies": [\ - ["deep-is", "npm:0.1.4"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["deepmerge", [\ - ["npm:4.2.2", {\ - "packageLocation": "./.yarn/cache/deepmerge-npm-4.2.2-112165ced2-a8c43a1ed8.zip/node_modules/deepmerge/",\ - "packageDependencies": [\ - ["deepmerge", "npm:4.2.2"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["define-properties", [\ - ["npm:1.1.4", {\ - "packageLocation": "./.yarn/cache/define-properties-npm-1.1.4-85ee575655-ce0aef3f9e.zip/node_modules/define-properties/",\ - "packageDependencies": [\ - ["define-properties", "npm:1.1.4"],\ - ["has-property-descriptors", "npm:1.0.0"],\ - ["object-keys", "npm:1.1.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["delaunator", [\ - ["npm:5.0.0", {\ - "packageLocation": "./.yarn/cache/delaunator-npm-5.0.0-9540390d61-d676418844.zip/node_modules/delaunator/",\ - "packageDependencies": [\ - ["delaunator", "npm:5.0.0"],\ - ["robust-predicates", "npm:3.0.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["delayed-stream", [\ - ["npm:1.0.0", {\ - "packageLocation": "./.yarn/cache/delayed-stream-npm-1.0.0-c5a4c4cc02-46fe6e83e2.zip/node_modules/delayed-stream/",\ - "packageDependencies": [\ - ["delayed-stream", "npm:1.0.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["delegates", [\ - ["npm:1.0.0", {\ - "packageLocation": "./.yarn/cache/delegates-npm-1.0.0-9b1942d75f-a51744d9b5.zip/node_modules/delegates/",\ - "packageDependencies": [\ - ["delegates", "npm:1.0.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["depd", [\ - ["npm:1.1.2", {\ - "packageLocation": "./.yarn/cache/depd-npm-1.1.2-b0c8414da7-6b406620d2.zip/node_modules/depd/",\ - "packageDependencies": [\ - ["depd", "npm:1.1.2"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["detect-libc", [\ - ["npm:1.0.3", {\ - "packageLocation": "./.yarn/cache/detect-libc-npm-1.0.3-c30ac344d4-daaaed925f.zip/node_modules/detect-libc/",\ - "packageDependencies": [\ - ["detect-libc", "npm:1.0.3"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["diff-sequences", [\ - ["npm:27.5.1", {\ - "packageLocation": "./.yarn/cache/diff-sequences-npm-27.5.1-29338362fa-a00db5554c.zip/node_modules/diff-sequences/",\ - "packageDependencies": [\ - ["diff-sequences", "npm:27.5.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["doctrine", [\ - ["npm:2.1.0", {\ - "packageLocation": "./.yarn/cache/doctrine-npm-2.1.0-ac15d049b7-a45e277f7f.zip/node_modules/doctrine/",\ - "packageDependencies": [\ - ["doctrine", "npm:2.1.0"],\ - ["esutils", "npm:2.0.3"]\ - ],\ - "linkType": "HARD"\ - }],\ - ["npm:3.0.0", {\ - "packageLocation": "./.yarn/cache/doctrine-npm-3.0.0-c6f1615f04-fd7673ca77.zip/node_modules/doctrine/",\ - "packageDependencies": [\ - ["doctrine", "npm:3.0.0"],\ - ["esutils", "npm:2.0.3"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["doctypes", [\ - ["npm:1.1.0", {\ - "packageLocation": "./.yarn/cache/doctypes-npm-1.1.0-cb4fdda595-6e6c2d1a80.zip/node_modules/doctypes/",\ - "packageDependencies": [\ - ["doctypes", "npm:1.1.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["dom-serializer", [\ - ["npm:1.4.1", {\ - "packageLocation": "./.yarn/cache/dom-serializer-npm-1.4.1-ebb24349c1-fbb0b01f87.zip/node_modules/dom-serializer/",\ - "packageDependencies": [\ - ["dom-serializer", "npm:1.4.1"],\ - ["domelementtype", "npm:2.3.0"],\ - ["domhandler", "npm:4.3.1"],\ - ["entities", "npm:2.2.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["domelementtype", [\ - ["npm:2.3.0", {\ - "packageLocation": "./.yarn/cache/domelementtype-npm-2.3.0-02de7cbfba-ee837a318f.zip/node_modules/domelementtype/",\ - "packageDependencies": [\ - ["domelementtype", "npm:2.3.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["domhandler", [\ - ["npm:4.3.1", {\ - "packageLocation": "./.yarn/cache/domhandler-npm-4.3.1-493539c1ca-4c665ceed0.zip/node_modules/domhandler/",\ - "packageDependencies": [\ - ["domhandler", "npm:4.3.1"],\ - ["domelementtype", "npm:2.3.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["domutils", [\ - ["npm:2.8.0", {\ - "packageLocation": "./.yarn/cache/domutils-npm-2.8.0-0325139e5c-abf7434315.zip/node_modules/domutils/",\ - "packageDependencies": [\ - ["domutils", "npm:2.8.0"],\ - ["dom-serializer", "npm:1.4.1"],\ - ["domelementtype", "npm:2.3.0"],\ - ["domhandler", "npm:4.3.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["dotenv", [\ - ["npm:7.0.0", {\ - "packageLocation": "./.yarn/cache/dotenv-npm-7.0.0-9fbf3b4fd8-18a7b3ef0e.zip/node_modules/dotenv/",\ - "packageDependencies": [\ - ["dotenv", "npm:7.0.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["dotenv-expand", [\ - ["npm:5.1.0", {\ - "packageLocation": "./.yarn/cache/dotenv-expand-npm-5.1.0-c3fff50eb5-8017675b7f.zip/node_modules/dotenv-expand/",\ - "packageDependencies": [\ - ["dotenv-expand", "npm:5.1.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["ecc-jsbn", [\ - ["npm:0.1.2", {\ - "packageLocation": "./.yarn/cache/ecc-jsbn-npm-0.1.2-85b7a7be89-22fef4b620.zip/node_modules/ecc-jsbn/",\ - "packageDependencies": [\ - ["ecc-jsbn", "npm:0.1.2"],\ - ["jsbn", "npm:0.1.1"],\ - ["safer-buffer", "npm:2.1.2"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["electron-to-chromium", [\ - ["npm:1.4.137", {\ - "packageLocation": "./.yarn/cache/electron-to-chromium-npm-1.4.137-35182e6efc-639d7b9490.zip/node_modules/electron-to-chromium/",\ - "packageDependencies": [\ - ["electron-to-chromium", "npm:1.4.137"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["emoji-regex", [\ - ["npm:8.0.0", {\ - "packageLocation": "./.yarn/cache/emoji-regex-npm-8.0.0-213764015c-d4c5c39d5a.zip/node_modules/emoji-regex/",\ - "packageDependencies": [\ - ["emoji-regex", "npm:8.0.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["encoding", [\ - ["npm:0.1.13", {\ - "packageLocation": "./.yarn/cache/encoding-npm-0.1.13-82a1837d30-bb98632f8f.zip/node_modules/encoding/",\ - "packageDependencies": [\ - ["encoding", "npm:0.1.13"],\ - ["iconv-lite", "npm:0.6.3"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["end-of-stream", [\ - ["npm:1.4.4", {\ - "packageLocation": "./.yarn/cache/end-of-stream-npm-1.4.4-497fc6dee1-530a5a5a1e.zip/node_modules/end-of-stream/",\ - "packageDependencies": [\ - ["end-of-stream", "npm:1.4.4"],\ - ["once", "npm:1.4.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["enquirer", [\ - ["npm:2.3.6", {\ - "packageLocation": "./.yarn/cache/enquirer-npm-2.3.6-7899175762-1c0911e14a.zip/node_modules/enquirer/",\ - "packageDependencies": [\ - ["enquirer", "npm:2.3.6"],\ - ["ansi-colors", "npm:4.1.3"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["entities", [\ - ["npm:2.2.0", {\ - "packageLocation": "./.yarn/cache/entities-npm-2.2.0-0fc8d5b2f7-19010dacaf.zip/node_modules/entities/",\ - "packageDependencies": [\ - ["entities", "npm:2.2.0"]\ - ],\ - "linkType": "HARD"\ - }],\ - ["npm:3.0.1", {\ - "packageLocation": "./.yarn/cache/entities-npm-3.0.1-21eeb201ba-aaf7f12033.zip/node_modules/entities/",\ - "packageDependencies": [\ - ["entities", "npm:3.0.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["env-paths", [\ - ["npm:2.2.1", {\ - "packageLocation": "./.yarn/cache/env-paths-npm-2.2.1-7c7577428c-65b5df55a8.zip/node_modules/env-paths/",\ - "packageDependencies": [\ - ["env-paths", "npm:2.2.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["err-code", [\ - ["npm:2.0.3", {\ - "packageLocation": "./.yarn/cache/err-code-npm-2.0.3-082e0ff9a7-8b7b1be20d.zip/node_modules/err-code/",\ - "packageDependencies": [\ - ["err-code", "npm:2.0.3"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["error-ex", [\ - ["npm:1.3.2", {\ - "packageLocation": "./.yarn/cache/error-ex-npm-1.3.2-5654f80c0f-c1c2b8b65f.zip/node_modules/error-ex/",\ - "packageDependencies": [\ - ["error-ex", "npm:1.3.2"],\ - ["is-arrayish", "npm:0.2.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["es-abstract", [\ - ["npm:1.19.5", {\ - "packageLocation": "./.yarn/cache/es-abstract-npm-1.19.5-524a87d262-55199b0f17.zip/node_modules/es-abstract/",\ - "packageDependencies": [\ - ["es-abstract", "npm:1.19.5"],\ - ["call-bind", "npm:1.0.2"],\ - ["es-to-primitive", "npm:1.2.1"],\ - ["function-bind", "npm:1.1.1"],\ - ["get-intrinsic", "npm:1.1.1"],\ - ["get-symbol-description", "npm:1.0.0"],\ - ["has", "npm:1.0.3"],\ - ["has-symbols", "npm:1.0.3"],\ - ["internal-slot", "npm:1.0.3"],\ - ["is-callable", "npm:1.2.4"],\ - ["is-negative-zero", "npm:2.0.2"],\ - ["is-regex", "npm:1.1.4"],\ - ["is-shared-array-buffer", "npm:1.0.2"],\ - ["is-string", "npm:1.0.7"],\ - ["is-weakref", "npm:1.0.2"],\ - ["object-inspect", "npm:1.12.0"],\ - ["object-keys", "npm:1.1.1"],\ - ["object.assign", "npm:4.1.2"],\ - ["string.prototype.trimend", "npm:1.0.4"],\ - ["string.prototype.trimstart", "npm:1.0.4"],\ - ["unbox-primitive", "npm:1.0.2"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["es-shim-unscopables", [\ - ["npm:1.0.0", {\ - "packageLocation": "./.yarn/cache/es-shim-unscopables-npm-1.0.0-06186593f1-83e95cadbb.zip/node_modules/es-shim-unscopables/",\ - "packageDependencies": [\ - ["es-shim-unscopables", "npm:1.0.0"],\ - ["has", "npm:1.0.3"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["es-to-primitive", [\ - ["npm:1.2.1", {\ - "packageLocation": "./.yarn/cache/es-to-primitive-npm-1.2.1-b7a7eac6c5-4ead6671a2.zip/node_modules/es-to-primitive/",\ - "packageDependencies": [\ - ["es-to-primitive", "npm:1.2.1"],\ - ["is-callable", "npm:1.2.4"],\ - ["is-date-object", "npm:1.0.5"],\ - ["is-symbol", "npm:1.0.4"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["esbuild", [\ - ["npm:0.14.38", {\ - "packageLocation": "./.yarn/unplugged/esbuild-npm-0.14.38-04b78ffe2b/node_modules/esbuild/",\ - "packageDependencies": [\ - ["esbuild", "npm:0.14.38"],\ - ["esbuild-android-64", "npm:0.14.38"],\ - ["esbuild-android-arm64", "npm:0.14.38"],\ - ["esbuild-darwin-64", "npm:0.14.38"],\ - ["esbuild-darwin-arm64", "npm:0.14.38"],\ - ["esbuild-freebsd-64", "npm:0.14.38"],\ - ["esbuild-freebsd-arm64", "npm:0.14.38"],\ - ["esbuild-linux-32", "npm:0.14.38"],\ - ["esbuild-linux-64", "npm:0.14.38"],\ - ["esbuild-linux-arm", "npm:0.14.38"],\ - ["esbuild-linux-arm64", "npm:0.14.38"],\ - ["esbuild-linux-mips64le", "npm:0.14.38"],\ - ["esbuild-linux-ppc64le", "npm:0.14.38"],\ - ["esbuild-linux-riscv64", "npm:0.14.38"],\ - ["esbuild-linux-s390x", "npm:0.14.38"],\ - ["esbuild-netbsd-64", "npm:0.14.38"],\ - ["esbuild-openbsd-64", "npm:0.14.38"],\ - ["esbuild-sunos-64", "npm:0.14.38"],\ - ["esbuild-windows-32", "npm:0.14.38"],\ - ["esbuild-windows-64", "npm:0.14.38"],\ - ["esbuild-windows-arm64", "npm:0.14.38"]\ - ],\ - "linkType": "HARD"\ - }],\ - ["npm:0.14.49", {\ - "packageLocation": "./.yarn/unplugged/esbuild-npm-0.14.49-8ea32c7f59/node_modules/esbuild/",\ - "packageDependencies": [\ - ["esbuild", "npm:0.14.49"],\ - ["esbuild-android-64", "npm:0.14.49"],\ - ["esbuild-android-arm64", "npm:0.14.49"],\ - ["esbuild-darwin-64", "npm:0.14.49"],\ - ["esbuild-darwin-arm64", "npm:0.14.49"],\ - ["esbuild-freebsd-64", "npm:0.14.49"],\ - ["esbuild-freebsd-arm64", "npm:0.14.49"],\ - ["esbuild-linux-32", "npm:0.14.49"],\ - ["esbuild-linux-64", "npm:0.14.49"],\ - ["esbuild-linux-arm", "npm:0.14.49"],\ - ["esbuild-linux-arm64", "npm:0.14.49"],\ - ["esbuild-linux-mips64le", "npm:0.14.49"],\ - ["esbuild-linux-ppc64le", "npm:0.14.49"],\ - ["esbuild-linux-riscv64", "npm:0.14.49"],\ - ["esbuild-linux-s390x", "npm:0.14.49"],\ - ["esbuild-netbsd-64", "npm:0.14.49"],\ - ["esbuild-openbsd-64", "npm:0.14.49"],\ - ["esbuild-sunos-64", "npm:0.14.49"],\ - ["esbuild-windows-32", "npm:0.14.49"],\ - ["esbuild-windows-64", "npm:0.14.49"],\ - ["esbuild-windows-arm64", "npm:0.14.49"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["esbuild-android-64", [\ - ["npm:0.14.38", {\ - "packageLocation": "./.yarn/unplugged/esbuild-android-64-npm-0.14.38-6b82ed658f/node_modules/esbuild-android-64/",\ - "packageDependencies": [\ - ["esbuild-android-64", "npm:0.14.38"]\ - ],\ - "linkType": "HARD"\ - }],\ - ["npm:0.14.49", {\ - "packageLocation": "./.yarn/unplugged/esbuild-android-64-npm-0.14.49-8ab6d0c211/node_modules/esbuild-android-64/",\ - "packageDependencies": [\ - ["esbuild-android-64", "npm:0.14.49"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["esbuild-android-arm64", [\ - ["npm:0.14.38", {\ - "packageLocation": "./.yarn/unplugged/esbuild-android-arm64-npm-0.14.38-64ce8c8c5a/node_modules/esbuild-android-arm64/",\ - "packageDependencies": [\ - ["esbuild-android-arm64", "npm:0.14.38"]\ - ],\ - "linkType": "HARD"\ - }],\ - ["npm:0.14.49", {\ - "packageLocation": "./.yarn/unplugged/esbuild-android-arm64-npm-0.14.49-286ab74f81/node_modules/esbuild-android-arm64/",\ - "packageDependencies": [\ - ["esbuild-android-arm64", "npm:0.14.49"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["esbuild-darwin-64", [\ - ["npm:0.14.38", {\ - "packageLocation": "./.yarn/unplugged/esbuild-darwin-64-npm-0.14.38-fee9a60d9b/node_modules/esbuild-darwin-64/",\ - "packageDependencies": [\ - ["esbuild-darwin-64", "npm:0.14.38"]\ - ],\ - "linkType": "HARD"\ - }],\ - ["npm:0.14.49", {\ - "packageLocation": "./.yarn/unplugged/esbuild-darwin-64-npm-0.14.49-55333913ef/node_modules/esbuild-darwin-64/",\ - "packageDependencies": [\ - ["esbuild-darwin-64", "npm:0.14.49"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["esbuild-darwin-arm64", [\ - ["npm:0.14.38", {\ - "packageLocation": "./.yarn/unplugged/esbuild-darwin-arm64-npm-0.14.38-b37de966bb/node_modules/esbuild-darwin-arm64/",\ - "packageDependencies": [\ - ["esbuild-darwin-arm64", "npm:0.14.38"]\ - ],\ - "linkType": "HARD"\ - }],\ - ["npm:0.14.49", {\ - "packageLocation": "./.yarn/unplugged/esbuild-darwin-arm64-npm-0.14.49-3434761197/node_modules/esbuild-darwin-arm64/",\ - "packageDependencies": [\ - ["esbuild-darwin-arm64", "npm:0.14.49"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["esbuild-freebsd-64", [\ - ["npm:0.14.38", {\ - "packageLocation": "./.yarn/unplugged/esbuild-freebsd-64-npm-0.14.38-aca18c247d/node_modules/esbuild-freebsd-64/",\ - "packageDependencies": [\ - ["esbuild-freebsd-64", "npm:0.14.38"]\ - ],\ - "linkType": "HARD"\ - }],\ - ["npm:0.14.49", {\ - "packageLocation": "./.yarn/unplugged/esbuild-freebsd-64-npm-0.14.49-b763ba7ebe/node_modules/esbuild-freebsd-64/",\ - "packageDependencies": [\ - ["esbuild-freebsd-64", "npm:0.14.49"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["esbuild-freebsd-arm64", [\ - ["npm:0.14.38", {\ - "packageLocation": "./.yarn/unplugged/esbuild-freebsd-arm64-npm-0.14.38-7d463e95c8/node_modules/esbuild-freebsd-arm64/",\ - "packageDependencies": [\ - ["esbuild-freebsd-arm64", "npm:0.14.38"]\ - ],\ - "linkType": "HARD"\ - }],\ - ["npm:0.14.49", {\ - "packageLocation": "./.yarn/unplugged/esbuild-freebsd-arm64-npm-0.14.49-c11fd04f0b/node_modules/esbuild-freebsd-arm64/",\ - "packageDependencies": [\ - ["esbuild-freebsd-arm64", "npm:0.14.49"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["esbuild-linux-32", [\ - ["npm:0.14.38", {\ - "packageLocation": "./.yarn/unplugged/esbuild-linux-32-npm-0.14.38-5412bd9f4a/node_modules/esbuild-linux-32/",\ - "packageDependencies": [\ - ["esbuild-linux-32", "npm:0.14.38"]\ - ],\ - "linkType": "HARD"\ - }],\ - ["npm:0.14.49", {\ - "packageLocation": "./.yarn/unplugged/esbuild-linux-32-npm-0.14.49-1634254ec4/node_modules/esbuild-linux-32/",\ - "packageDependencies": [\ - ["esbuild-linux-32", "npm:0.14.49"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["esbuild-linux-64", [\ - ["npm:0.14.38", {\ - "packageLocation": "./.yarn/unplugged/esbuild-linux-64-npm-0.14.38-c39b94428f/node_modules/esbuild-linux-64/",\ - "packageDependencies": [\ - ["esbuild-linux-64", "npm:0.14.38"]\ - ],\ - "linkType": "HARD"\ - }],\ - ["npm:0.14.49", {\ - "packageLocation": "./.yarn/unplugged/esbuild-linux-64-npm-0.14.49-96241737d6/node_modules/esbuild-linux-64/",\ - "packageDependencies": [\ - ["esbuild-linux-64", "npm:0.14.49"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["esbuild-linux-arm", [\ - ["npm:0.14.38", {\ - "packageLocation": "./.yarn/unplugged/esbuild-linux-arm-npm-0.14.38-d3961a7850/node_modules/esbuild-linux-arm/",\ - "packageDependencies": [\ - ["esbuild-linux-arm", "npm:0.14.38"]\ - ],\ - "linkType": "HARD"\ - }],\ - ["npm:0.14.49", {\ - "packageLocation": "./.yarn/unplugged/esbuild-linux-arm-npm-0.14.49-a8abc07f42/node_modules/esbuild-linux-arm/",\ - "packageDependencies": [\ - ["esbuild-linux-arm", "npm:0.14.49"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["esbuild-linux-arm64", [\ - ["npm:0.14.38", {\ - "packageLocation": "./.yarn/unplugged/esbuild-linux-arm64-npm-0.14.38-cef31fba53/node_modules/esbuild-linux-arm64/",\ - "packageDependencies": [\ - ["esbuild-linux-arm64", "npm:0.14.38"]\ - ],\ - "linkType": "HARD"\ - }],\ - ["npm:0.14.49", {\ - "packageLocation": "./.yarn/unplugged/esbuild-linux-arm64-npm-0.14.49-54281525ae/node_modules/esbuild-linux-arm64/",\ - "packageDependencies": [\ - ["esbuild-linux-arm64", "npm:0.14.49"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["esbuild-linux-mips64le", [\ - ["npm:0.14.38", {\ - "packageLocation": "./.yarn/unplugged/esbuild-linux-mips64le-npm-0.14.38-892bc61b4a/node_modules/esbuild-linux-mips64le/",\ - "packageDependencies": [\ - ["esbuild-linux-mips64le", "npm:0.14.38"]\ - ],\ - "linkType": "HARD"\ - }],\ - ["npm:0.14.49", {\ - "packageLocation": "./.yarn/unplugged/esbuild-linux-mips64le-npm-0.14.49-bbf71f749a/node_modules/esbuild-linux-mips64le/",\ - "packageDependencies": [\ - ["esbuild-linux-mips64le", "npm:0.14.49"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["esbuild-linux-ppc64le", [\ - ["npm:0.14.38", {\ - "packageLocation": "./.yarn/unplugged/esbuild-linux-ppc64le-npm-0.14.38-2a6c85c3a6/node_modules/esbuild-linux-ppc64le/",\ - "packageDependencies": [\ - ["esbuild-linux-ppc64le", "npm:0.14.38"]\ - ],\ - "linkType": "HARD"\ - }],\ - ["npm:0.14.49", {\ - "packageLocation": "./.yarn/unplugged/esbuild-linux-ppc64le-npm-0.14.49-01e0f34004/node_modules/esbuild-linux-ppc64le/",\ - "packageDependencies": [\ - ["esbuild-linux-ppc64le", "npm:0.14.49"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["esbuild-linux-riscv64", [\ - ["npm:0.14.38", {\ - "packageLocation": "./.yarn/unplugged/esbuild-linux-riscv64-npm-0.14.38-914b778d99/node_modules/esbuild-linux-riscv64/",\ - "packageDependencies": [\ - ["esbuild-linux-riscv64", "npm:0.14.38"]\ - ],\ - "linkType": "HARD"\ - }],\ - ["npm:0.14.49", {\ - "packageLocation": "./.yarn/unplugged/esbuild-linux-riscv64-npm-0.14.49-26ace1600d/node_modules/esbuild-linux-riscv64/",\ - "packageDependencies": [\ - ["esbuild-linux-riscv64", "npm:0.14.49"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["esbuild-linux-s390x", [\ - ["npm:0.14.38", {\ - "packageLocation": "./.yarn/unplugged/esbuild-linux-s390x-npm-0.14.38-849986d7ae/node_modules/esbuild-linux-s390x/",\ - "packageDependencies": [\ - ["esbuild-linux-s390x", "npm:0.14.38"]\ - ],\ - "linkType": "HARD"\ - }],\ - ["npm:0.14.49", {\ - "packageLocation": "./.yarn/unplugged/esbuild-linux-s390x-npm-0.14.49-a45311815a/node_modules/esbuild-linux-s390x/",\ - "packageDependencies": [\ - ["esbuild-linux-s390x", "npm:0.14.49"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["esbuild-netbsd-64", [\ - ["npm:0.14.38", {\ - "packageLocation": "./.yarn/unplugged/esbuild-netbsd-64-npm-0.14.38-dbbf2ab36f/node_modules/esbuild-netbsd-64/",\ - "packageDependencies": [\ - ["esbuild-netbsd-64", "npm:0.14.38"]\ - ],\ - "linkType": "HARD"\ - }],\ - ["npm:0.14.49", {\ - "packageLocation": "./.yarn/unplugged/esbuild-netbsd-64-npm-0.14.49-3c4da1e04e/node_modules/esbuild-netbsd-64/",\ - "packageDependencies": [\ - ["esbuild-netbsd-64", "npm:0.14.49"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["esbuild-openbsd-64", [\ - ["npm:0.14.38", {\ - "packageLocation": "./.yarn/unplugged/esbuild-openbsd-64-npm-0.14.38-017edcbe34/node_modules/esbuild-openbsd-64/",\ - "packageDependencies": [\ - ["esbuild-openbsd-64", "npm:0.14.38"]\ - ],\ - "linkType": "HARD"\ - }],\ - ["npm:0.14.49", {\ - "packageLocation": "./.yarn/unplugged/esbuild-openbsd-64-npm-0.14.49-759332d439/node_modules/esbuild-openbsd-64/",\ - "packageDependencies": [\ - ["esbuild-openbsd-64", "npm:0.14.49"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["esbuild-sunos-64", [\ - ["npm:0.14.38", {\ - "packageLocation": "./.yarn/unplugged/esbuild-sunos-64-npm-0.14.38-904aa7cde2/node_modules/esbuild-sunos-64/",\ - "packageDependencies": [\ - ["esbuild-sunos-64", "npm:0.14.38"]\ - ],\ - "linkType": "HARD"\ - }],\ - ["npm:0.14.49", {\ - "packageLocation": "./.yarn/unplugged/esbuild-sunos-64-npm-0.14.49-5b833f4bb9/node_modules/esbuild-sunos-64/",\ - "packageDependencies": [\ - ["esbuild-sunos-64", "npm:0.14.49"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["esbuild-windows-32", [\ - ["npm:0.14.38", {\ - "packageLocation": "./.yarn/unplugged/esbuild-windows-32-npm-0.14.38-21ba7ca13b/node_modules/esbuild-windows-32/",\ - "packageDependencies": [\ - ["esbuild-windows-32", "npm:0.14.38"]\ - ],\ - "linkType": "HARD"\ - }],\ - ["npm:0.14.49", {\ - "packageLocation": "./.yarn/unplugged/esbuild-windows-32-npm-0.14.49-ec5266d8cc/node_modules/esbuild-windows-32/",\ - "packageDependencies": [\ - ["esbuild-windows-32", "npm:0.14.49"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["esbuild-windows-64", [\ - ["npm:0.14.38", {\ - "packageLocation": "./.yarn/unplugged/esbuild-windows-64-npm-0.14.38-67094dd963/node_modules/esbuild-windows-64/",\ - "packageDependencies": [\ - ["esbuild-windows-64", "npm:0.14.38"]\ - ],\ - "linkType": "HARD"\ - }],\ - ["npm:0.14.49", {\ - "packageLocation": "./.yarn/unplugged/esbuild-windows-64-npm-0.14.49-72426d3535/node_modules/esbuild-windows-64/",\ - "packageDependencies": [\ - ["esbuild-windows-64", "npm:0.14.49"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["esbuild-windows-arm64", [\ - ["npm:0.14.38", {\ - "packageLocation": "./.yarn/unplugged/esbuild-windows-arm64-npm-0.14.38-9693d16298/node_modules/esbuild-windows-arm64/",\ - "packageDependencies": [\ - ["esbuild-windows-arm64", "npm:0.14.38"]\ - ],\ - "linkType": "HARD"\ - }],\ - ["npm:0.14.49", {\ - "packageLocation": "./.yarn/unplugged/esbuild-windows-arm64-npm-0.14.49-88d3b995f3/node_modules/esbuild-windows-arm64/",\ - "packageDependencies": [\ - ["esbuild-windows-arm64", "npm:0.14.49"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["escalade", [\ - ["npm:3.1.1", {\ - "packageLocation": "./.yarn/cache/escalade-npm-3.1.1-e02da076aa-a3e2a99f07.zip/node_modules/escalade/",\ - "packageDependencies": [\ - ["escalade", "npm:3.1.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["escape-string-regexp", [\ - ["npm:1.0.5", {\ - "packageLocation": "./.yarn/cache/escape-string-regexp-npm-1.0.5-3284de402f-6092fda75c.zip/node_modules/escape-string-regexp/",\ - "packageDependencies": [\ - ["escape-string-regexp", "npm:1.0.5"]\ - ],\ - "linkType": "HARD"\ - }],\ - ["npm:4.0.0", {\ - "packageLocation": "./.yarn/cache/escape-string-regexp-npm-4.0.0-4b531d8d59-98b48897d9.zip/node_modules/escape-string-regexp/",\ - "packageDependencies": [\ - ["escape-string-regexp", "npm:4.0.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["eslint", [\ - ["npm:8.20.0", {\ - "packageLocation": "./.yarn/cache/eslint-npm-8.20.0-6bbc377ff7-a31adf390d.zip/node_modules/eslint/",\ - "packageDependencies": [\ - ["eslint", "npm:8.20.0"],\ - ["@eslint/eslintrc", "npm:1.3.0"],\ - ["@humanwhocodes/config-array", "npm:0.9.5"],\ - ["ajv", "npm:6.12.6"],\ - ["chalk", "npm:4.1.2"],\ - ["cross-spawn", "npm:7.0.3"],\ - ["debug", "virtual:b86a9fb34323a98c6519528ed55faa0d9b44ca8879307c0b29aa384bde47ff59a7d0c9051b31246f14521dfb71ba3c5d6d0b35c29fffc17bf875aa6ad977d9e8#npm:4.3.4"],\ - ["doctrine", "npm:3.0.0"],\ - ["escape-string-regexp", "npm:4.0.0"],\ - ["eslint-scope", "npm:7.1.1"],\ - ["eslint-utils", "virtual:6bbc377ff7d43f22ea2360c3aee97bcf0f6339e192d2c386c426ceea292a9ce5661e69e9612ae08b90169c7cfa809c9325a1ee72fdf18fe82fe1502ee91ceb77#npm:3.0.0"],\ - ["eslint-visitor-keys", "npm:3.3.0"],\ - ["espree", "npm:9.3.2"],\ - ["esquery", "npm:1.4.0"],\ - ["esutils", "npm:2.0.3"],\ - ["fast-deep-equal", "npm:3.1.3"],\ - ["file-entry-cache", "npm:6.0.1"],\ - ["functional-red-black-tree", "npm:1.0.1"],\ - ["glob-parent", "npm:6.0.2"],\ - ["globals", "npm:13.15.0"],\ - ["ignore", "npm:5.2.0"],\ - ["import-fresh", "npm:3.3.0"],\ - ["imurmurhash", "npm:0.1.4"],\ - ["is-glob", "npm:4.0.3"],\ - ["js-yaml", "npm:4.1.0"],\ - ["json-stable-stringify-without-jsonify", "npm:1.0.1"],\ - ["levn", "npm:0.4.1"],\ - ["lodash.merge", "npm:4.6.2"],\ - ["minimatch", "npm:3.1.2"],\ - ["natural-compare", "npm:1.4.0"],\ - ["optionator", "npm:0.9.1"],\ - ["regexpp", "npm:3.2.0"],\ - ["strip-ansi", "npm:6.0.1"],\ - ["strip-json-comments", "npm:3.1.1"],\ - ["text-table", "npm:0.2.0"],\ - ["v8-compile-cache", "npm:2.3.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["eslint-config-standard", [\ - ["npm:17.0.0", {\ - "packageLocation": "./.yarn/cache/eslint-config-standard-npm-17.0.0-2803f6a79a-dc0ed51e18.zip/node_modules/eslint-config-standard/",\ - "packageDependencies": [\ - ["eslint-config-standard", "npm:17.0.0"]\ - ],\ - "linkType": "SOFT"\ - }],\ - ["virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:17.0.0", {\ - "packageLocation": "./.yarn/__virtual__/eslint-config-standard-virtual-5de208ba69/0/cache/eslint-config-standard-npm-17.0.0-2803f6a79a-dc0ed51e18.zip/node_modules/eslint-config-standard/",\ - "packageDependencies": [\ - ["eslint-config-standard", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:17.0.0"],\ - ["@types/eslint", null],\ - ["@types/eslint-plugin-import", null],\ - ["@types/eslint-plugin-n", null],\ - ["@types/eslint-plugin-promise", null],\ - ["eslint", "npm:8.20.0"],\ - ["eslint-plugin-import", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:2.26.0"],\ - ["eslint-plugin-n", "virtual:5de208ba69f1abc06b9e76e02d4ce4fc49fcab4f9a21e07e70644bde43652129abc0a8d2e76e362701d48e3019da8bcf1b9d697031ba71659718edb10a775408#npm:15.2.0"],\ - ["eslint-plugin-promise", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:6.0.0"]\ - ],\ - "packagePeers": [\ - "@types/eslint-plugin-import",\ - "@types/eslint-plugin-n",\ - "@types/eslint-plugin-promise",\ - "@types/eslint",\ - "eslint-plugin-import",\ - "eslint-plugin-promise",\ - "eslint"\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["eslint-import-resolver-node", [\ - ["npm:0.3.6", {\ - "packageLocation": "./.yarn/cache/eslint-import-resolver-node-npm-0.3.6-d9426786c6-6266733af1.zip/node_modules/eslint-import-resolver-node/",\ - "packageDependencies": [\ - ["eslint-import-resolver-node", "npm:0.3.6"],\ - ["debug", "virtual:396a3691f7b25accf085fe2fff1f56eb7540eff3f2e928a7572ca1de9b831ff8f22136404f236aaed35d90369918dfc34392844d0f822a310563f34746dfb015#npm:3.2.7"],\ - ["resolve", "patch:resolve@npm%3A1.22.0#~builtin::version=1.22.0&hash=07638b"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["eslint-module-utils", [\ - ["npm:2.7.3", {\ - "packageLocation": "./.yarn/cache/eslint-module-utils-npm-2.7.3-ccd32fe6fd-77048263f3.zip/node_modules/eslint-module-utils/",\ - "packageDependencies": [\ - ["eslint-module-utils", "npm:2.7.3"]\ - ],\ - "linkType": "SOFT"\ - }],\ - ["virtual:c0858ad0a599e687a7d876de5591e3b098ca550f5c1ad46e7d0e2b6f5720a919cb228a47405daf7d626be1747e41a5b93e4b4d748f16d5e7c36c433aed618452#npm:2.7.3", {\ - "packageLocation": "./.yarn/__virtual__/eslint-module-utils-virtual-e944405700/0/cache/eslint-module-utils-npm-2.7.3-ccd32fe6fd-77048263f3.zip/node_modules/eslint-module-utils/",\ - "packageDependencies": [\ - ["eslint-module-utils", "virtual:c0858ad0a599e687a7d876de5591e3b098ca550f5c1ad46e7d0e2b6f5720a919cb228a47405daf7d626be1747e41a5b93e4b4d748f16d5e7c36c433aed618452#npm:2.7.3"],\ - ["@types/eslint-import-resolver-node", null],\ - ["@types/eslint-import-resolver-typescript", null],\ - ["@types/eslint-import-resolver-webpack", null],\ - ["@types/typescript-eslint__parser", null],\ - ["@typescript-eslint/parser", null],\ - ["debug", "virtual:396a3691f7b25accf085fe2fff1f56eb7540eff3f2e928a7572ca1de9b831ff8f22136404f236aaed35d90369918dfc34392844d0f822a310563f34746dfb015#npm:3.2.7"],\ - ["eslint-import-resolver-node", "npm:0.3.6"],\ - ["eslint-import-resolver-typescript", null],\ - ["eslint-import-resolver-webpack", null],\ - ["find-up", "npm:2.1.0"]\ - ],\ - "packagePeers": [\ - "@types/eslint-import-resolver-node",\ - "@types/eslint-import-resolver-typescript",\ - "@types/eslint-import-resolver-webpack",\ - "@types/typescript-eslint__parser",\ - "@typescript-eslint/parser",\ - "eslint-import-resolver-node",\ - "eslint-import-resolver-typescript",\ - "eslint-import-resolver-webpack"\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["eslint-plugin-cypress", [\ - ["npm:2.12.1", {\ - "packageLocation": "./.yarn/cache/eslint-plugin-cypress-npm-2.12.1-6681f582fa-1f1c36e149.zip/node_modules/eslint-plugin-cypress/",\ - "packageDependencies": [\ - ["eslint-plugin-cypress", "npm:2.12.1"]\ - ],\ - "linkType": "SOFT"\ - }],\ - ["virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:2.12.1", {\ - "packageLocation": "./.yarn/__virtual__/eslint-plugin-cypress-virtual-3210db2eaa/0/cache/eslint-plugin-cypress-npm-2.12.1-6681f582fa-1f1c36e149.zip/node_modules/eslint-plugin-cypress/",\ - "packageDependencies": [\ - ["eslint-plugin-cypress", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:2.12.1"],\ - ["@types/eslint", null],\ - ["eslint", "npm:8.20.0"],\ - ["globals", "npm:11.12.0"]\ - ],\ - "packagePeers": [\ - "@types/eslint",\ - "eslint"\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["eslint-plugin-es", [\ - ["npm:3.0.1", {\ - "packageLocation": "./.yarn/cache/eslint-plugin-es-npm-3.0.1-95e8015220-e57592c523.zip/node_modules/eslint-plugin-es/",\ - "packageDependencies": [\ - ["eslint-plugin-es", "npm:3.0.1"]\ - ],\ - "linkType": "SOFT"\ - }],\ - ["npm:4.1.0", {\ - "packageLocation": "./.yarn/cache/eslint-plugin-es-npm-4.1.0-a4cf26d3cd-26b87a216d.zip/node_modules/eslint-plugin-es/",\ - "packageDependencies": [\ - ["eslint-plugin-es", "npm:4.1.0"]\ - ],\ - "linkType": "SOFT"\ - }],\ - ["virtual:5cccaf00e87dfff96dbbb5eaf7a3055373358b8114d6a1adfb32f54ed6b40ba06068d3aa1fdd8062899a0cad040f68c17cc6b72bac2cdbe9700f3d6330d112f3#npm:3.0.1", {\ - "packageLocation": "./.yarn/__virtual__/eslint-plugin-es-virtual-9a126af2f5/0/cache/eslint-plugin-es-npm-3.0.1-95e8015220-e57592c523.zip/node_modules/eslint-plugin-es/",\ - "packageDependencies": [\ - ["eslint-plugin-es", "virtual:5cccaf00e87dfff96dbbb5eaf7a3055373358b8114d6a1adfb32f54ed6b40ba06068d3aa1fdd8062899a0cad040f68c17cc6b72bac2cdbe9700f3d6330d112f3#npm:3.0.1"],\ - ["@types/eslint", null],\ - ["eslint", "npm:8.20.0"],\ - ["eslint-utils", "npm:2.1.0"],\ - ["regexpp", "npm:3.2.0"]\ - ],\ - "packagePeers": [\ - "@types/eslint",\ - "eslint"\ - ],\ - "linkType": "HARD"\ - }],\ - ["virtual:c8e07c2a6b56869a5a6a64a5a2bbfafd2756fdfec2e39799aafeb55edf967e3394125f03e2dbe23e573456f9dc23ed0ee125b7a467ac99d6b6dc124c1fb861dd#npm:4.1.0", {\ - "packageLocation": "./.yarn/__virtual__/eslint-plugin-es-virtual-2fffa83c77/0/cache/eslint-plugin-es-npm-4.1.0-a4cf26d3cd-26b87a216d.zip/node_modules/eslint-plugin-es/",\ - "packageDependencies": [\ - ["eslint-plugin-es", "virtual:c8e07c2a6b56869a5a6a64a5a2bbfafd2756fdfec2e39799aafeb55edf967e3394125f03e2dbe23e573456f9dc23ed0ee125b7a467ac99d6b6dc124c1fb861dd#npm:4.1.0"],\ - ["@types/eslint", null],\ - ["eslint", "npm:8.20.0"],\ - ["eslint-utils", "npm:2.1.0"],\ - ["regexpp", "npm:3.2.0"]\ - ],\ - "packagePeers": [\ - "@types/eslint",\ - "eslint"\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["eslint-plugin-import", [\ - ["npm:2.26.0", {\ - "packageLocation": "./.yarn/cache/eslint-plugin-import-npm-2.26.0-959fe14a01-0bf77ad803.zip/node_modules/eslint-plugin-import/",\ - "packageDependencies": [\ - ["eslint-plugin-import", "npm:2.26.0"]\ - ],\ - "linkType": "SOFT"\ - }],\ - ["virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:2.26.0", {\ - "packageLocation": "./.yarn/__virtual__/eslint-plugin-import-virtual-c0858ad0a5/0/cache/eslint-plugin-import-npm-2.26.0-959fe14a01-0bf77ad803.zip/node_modules/eslint-plugin-import/",\ - "packageDependencies": [\ - ["eslint-plugin-import", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:2.26.0"],\ - ["@types/eslint", null],\ - ["@types/typescript-eslint__parser", null],\ - ["@typescript-eslint/parser", null],\ - ["array-includes", "npm:3.1.4"],\ - ["array.prototype.flat", "npm:1.3.0"],\ - ["debug", "virtual:c0858ad0a599e687a7d876de5591e3b098ca550f5c1ad46e7d0e2b6f5720a919cb228a47405daf7d626be1747e41a5b93e4b4d748f16d5e7c36c433aed618452#npm:2.6.9"],\ - ["doctrine", "npm:2.1.0"],\ - ["eslint", "npm:8.20.0"],\ - ["eslint-import-resolver-node", "npm:0.3.6"],\ - ["eslint-module-utils", "virtual:c0858ad0a599e687a7d876de5591e3b098ca550f5c1ad46e7d0e2b6f5720a919cb228a47405daf7d626be1747e41a5b93e4b4d748f16d5e7c36c433aed618452#npm:2.7.3"],\ - ["has", "npm:1.0.3"],\ - ["is-core-module", "npm:2.9.0"],\ - ["is-glob", "npm:4.0.3"],\ - ["minimatch", "npm:3.1.2"],\ - ["object.values", "npm:1.1.5"],\ - ["resolve", "patch:resolve@npm%3A1.22.0#~builtin::version=1.22.0&hash=07638b"],\ - ["tsconfig-paths", "npm:3.14.1"]\ - ],\ - "packagePeers": [\ - "@types/eslint",\ - "@types/typescript-eslint__parser",\ - "@typescript-eslint/parser",\ - "eslint"\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["eslint-plugin-n", [\ - ["npm:15.2.0", {\ - "packageLocation": "./.yarn/cache/eslint-plugin-n-npm-15.2.0-669e8b723e-4303dea35a.zip/node_modules/eslint-plugin-n/",\ - "packageDependencies": [\ - ["eslint-plugin-n", "npm:15.2.0"]\ - ],\ - "linkType": "SOFT"\ - }],\ - ["virtual:5de208ba69f1abc06b9e76e02d4ce4fc49fcab4f9a21e07e70644bde43652129abc0a8d2e76e362701d48e3019da8bcf1b9d697031ba71659718edb10a775408#npm:15.2.0", {\ - "packageLocation": "./.yarn/__virtual__/eslint-plugin-n-virtual-c8e07c2a6b/0/cache/eslint-plugin-n-npm-15.2.0-669e8b723e-4303dea35a.zip/node_modules/eslint-plugin-n/",\ - "packageDependencies": [\ - ["eslint-plugin-n", "virtual:5de208ba69f1abc06b9e76e02d4ce4fc49fcab4f9a21e07e70644bde43652129abc0a8d2e76e362701d48e3019da8bcf1b9d697031ba71659718edb10a775408#npm:15.2.0"],\ - ["@types/eslint", null],\ - ["builtins", "npm:4.1.0"],\ - ["eslint", "npm:8.20.0"],\ - ["eslint-plugin-es", "virtual:c8e07c2a6b56869a5a6a64a5a2bbfafd2756fdfec2e39799aafeb55edf967e3394125f03e2dbe23e573456f9dc23ed0ee125b7a467ac99d6b6dc124c1fb861dd#npm:4.1.0"],\ - ["eslint-utils", "virtual:6bbc377ff7d43f22ea2360c3aee97bcf0f6339e192d2c386c426ceea292a9ce5661e69e9612ae08b90169c7cfa809c9325a1ee72fdf18fe82fe1502ee91ceb77#npm:3.0.0"],\ - ["ignore", "npm:5.2.0"],\ - ["is-core-module", "npm:2.9.0"],\ - ["minimatch", "npm:3.1.2"],\ - ["resolve", "patch:resolve@npm%3A1.22.0#~builtin::version=1.22.0&hash=07638b"],\ - ["semver", "npm:6.3.0"]\ - ],\ - "packagePeers": [\ - "@types/eslint",\ - "eslint"\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["eslint-plugin-node", [\ - ["npm:11.1.0", {\ - "packageLocation": "./.yarn/cache/eslint-plugin-node-npm-11.1.0-913abe06f4-5804c4f8a6.zip/node_modules/eslint-plugin-node/",\ - "packageDependencies": [\ - ["eslint-plugin-node", "npm:11.1.0"]\ - ],\ - "linkType": "SOFT"\ - }],\ - ["virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:11.1.0", {\ - "packageLocation": "./.yarn/__virtual__/eslint-plugin-node-virtual-5cccaf00e8/0/cache/eslint-plugin-node-npm-11.1.0-913abe06f4-5804c4f8a6.zip/node_modules/eslint-plugin-node/",\ - "packageDependencies": [\ - ["eslint-plugin-node", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:11.1.0"],\ - ["@types/eslint", null],\ - ["eslint", "npm:8.20.0"],\ - ["eslint-plugin-es", "virtual:5cccaf00e87dfff96dbbb5eaf7a3055373358b8114d6a1adfb32f54ed6b40ba06068d3aa1fdd8062899a0cad040f68c17cc6b72bac2cdbe9700f3d6330d112f3#npm:3.0.1"],\ - ["eslint-utils", "npm:2.1.0"],\ - ["ignore", "npm:5.2.0"],\ - ["minimatch", "npm:3.1.2"],\ - ["resolve", "patch:resolve@npm%3A1.22.0#~builtin::version=1.22.0&hash=07638b"],\ - ["semver", "npm:6.3.0"]\ - ],\ - "packagePeers": [\ - "@types/eslint",\ - "eslint"\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["eslint-plugin-promise", [\ - ["npm:6.0.0", {\ - "packageLocation": "./.yarn/cache/eslint-plugin-promise-npm-6.0.0-5a0de876d5-7e761507c5.zip/node_modules/eslint-plugin-promise/",\ - "packageDependencies": [\ - ["eslint-plugin-promise", "npm:6.0.0"]\ - ],\ - "linkType": "SOFT"\ - }],\ - ["virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:6.0.0", {\ - "packageLocation": "./.yarn/__virtual__/eslint-plugin-promise-virtual-18fcc16105/0/cache/eslint-plugin-promise-npm-6.0.0-5a0de876d5-7e761507c5.zip/node_modules/eslint-plugin-promise/",\ - "packageDependencies": [\ - ["eslint-plugin-promise", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:6.0.0"],\ - ["@types/eslint", null],\ - ["eslint", "npm:8.20.0"]\ - ],\ - "packagePeers": [\ - "@types/eslint",\ - "eslint"\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["eslint-plugin-vue", [\ - ["npm:9.2.0", {\ - "packageLocation": "./.yarn/cache/eslint-plugin-vue-npm-9.2.0-eb1ca66b56-008819b12a.zip/node_modules/eslint-plugin-vue/",\ - "packageDependencies": [\ - ["eslint-plugin-vue", "npm:9.2.0"]\ - ],\ - "linkType": "SOFT"\ - }],\ - ["virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:9.2.0", {\ - "packageLocation": "./.yarn/__virtual__/eslint-plugin-vue-virtual-9414c87416/0/cache/eslint-plugin-vue-npm-9.2.0-eb1ca66b56-008819b12a.zip/node_modules/eslint-plugin-vue/",\ - "packageDependencies": [\ - ["eslint-plugin-vue", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:9.2.0"],\ - ["@types/eslint", null],\ - ["eslint", "npm:8.20.0"],\ - ["eslint-utils", "virtual:6bbc377ff7d43f22ea2360c3aee97bcf0f6339e192d2c386c426ceea292a9ce5661e69e9612ae08b90169c7cfa809c9325a1ee72fdf18fe82fe1502ee91ceb77#npm:3.0.0"],\ - ["natural-compare", "npm:1.4.0"],\ - ["nth-check", "npm:2.1.1"],\ - ["postcss-selector-parser", "npm:6.0.10"],\ - ["semver", "npm:7.3.7"],\ - ["vue-eslint-parser", "virtual:9414c87416def0a63dceb2f6f5fb7f6686d5c8cb4f316560809cc3f0b442b2490e362606443411ef0a3ef5d60343598226e3c932fec0ce0ca7dcbb584729a7b1#npm:9.0.3"],\ - ["xml-name-validator", "npm:4.0.0"]\ - ],\ - "packagePeers": [\ - "@types/eslint",\ - "eslint"\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["eslint-scope", [\ - ["npm:7.1.1", {\ - "packageLocation": "./.yarn/cache/eslint-scope-npm-7.1.1-23935eb377-9f6e974ab2.zip/node_modules/eslint-scope/",\ - "packageDependencies": [\ - ["eslint-scope", "npm:7.1.1"],\ - ["esrecurse", "npm:4.3.0"],\ - ["estraverse", "npm:5.3.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["eslint-utils", [\ - ["npm:2.1.0", {\ - "packageLocation": "./.yarn/cache/eslint-utils-npm-2.1.0-a3a7ebf4fa-27500938f3.zip/node_modules/eslint-utils/",\ - "packageDependencies": [\ - ["eslint-utils", "npm:2.1.0"],\ - ["eslint-visitor-keys", "npm:1.3.0"]\ - ],\ - "linkType": "HARD"\ - }],\ - ["npm:3.0.0", {\ - "packageLocation": "./.yarn/cache/eslint-utils-npm-3.0.0-630b3a4013-0668fe02f5.zip/node_modules/eslint-utils/",\ - "packageDependencies": [\ - ["eslint-utils", "npm:3.0.0"]\ - ],\ - "linkType": "SOFT"\ - }],\ - ["virtual:6bbc377ff7d43f22ea2360c3aee97bcf0f6339e192d2c386c426ceea292a9ce5661e69e9612ae08b90169c7cfa809c9325a1ee72fdf18fe82fe1502ee91ceb77#npm:3.0.0", {\ - "packageLocation": "./.yarn/__virtual__/eslint-utils-virtual-ce0e5542f2/0/cache/eslint-utils-npm-3.0.0-630b3a4013-0668fe02f5.zip/node_modules/eslint-utils/",\ - "packageDependencies": [\ - ["eslint-utils", "virtual:6bbc377ff7d43f22ea2360c3aee97bcf0f6339e192d2c386c426ceea292a9ce5661e69e9612ae08b90169c7cfa809c9325a1ee72fdf18fe82fe1502ee91ceb77#npm:3.0.0"],\ - ["@types/eslint", null],\ - ["eslint", "npm:8.20.0"],\ - ["eslint-visitor-keys", "npm:2.1.0"]\ - ],\ - "packagePeers": [\ - "@types/eslint",\ - "eslint"\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["eslint-visitor-keys", [\ - ["npm:1.3.0", {\ - "packageLocation": "./.yarn/cache/eslint-visitor-keys-npm-1.3.0-c07780a0fb-37a19b712f.zip/node_modules/eslint-visitor-keys/",\ - "packageDependencies": [\ - ["eslint-visitor-keys", "npm:1.3.0"]\ - ],\ - "linkType": "HARD"\ - }],\ - ["npm:2.1.0", {\ - "packageLocation": "./.yarn/cache/eslint-visitor-keys-npm-2.1.0-c31806b6b9-e3081d7dd2.zip/node_modules/eslint-visitor-keys/",\ - "packageDependencies": [\ - ["eslint-visitor-keys", "npm:2.1.0"]\ - ],\ - "linkType": "HARD"\ - }],\ - ["npm:3.3.0", {\ - "packageLocation": "./.yarn/cache/eslint-visitor-keys-npm-3.3.0-d329af7c8c-d59e68a7c5.zip/node_modules/eslint-visitor-keys/",\ - "packageDependencies": [\ - ["eslint-visitor-keys", "npm:3.3.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["espree", [\ - ["npm:9.3.2", {\ - "packageLocation": "./.yarn/cache/espree-npm-9.3.2-c70fa2a91d-9a790d6779.zip/node_modules/espree/",\ - "packageDependencies": [\ - ["espree", "npm:9.3.2"],\ - ["acorn", "npm:8.7.1"],\ - ["acorn-jsx", "virtual:c70fa2a91dcbd99b022aeff42b1b7671b1079fb9945248dc00dedd7520f879dc07058703f4626782de94f97692f30d5b18138d744c1e1ed1913a7610755d40e3#npm:5.3.2"],\ - ["eslint-visitor-keys", "npm:3.3.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["esquery", [\ - ["npm:1.4.0", {\ - "packageLocation": "./.yarn/cache/esquery-npm-1.4.0-f39408b1a7-a0807e17ab.zip/node_modules/esquery/",\ - "packageDependencies": [\ - ["esquery", "npm:1.4.0"],\ - ["estraverse", "npm:5.3.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["esrecurse", [\ - ["npm:4.3.0", {\ - "packageLocation": "./.yarn/cache/esrecurse-npm-4.3.0-10b86a887a-ebc17b1a33.zip/node_modules/esrecurse/",\ - "packageDependencies": [\ - ["esrecurse", "npm:4.3.0"],\ - ["estraverse", "npm:5.3.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["estraverse", [\ - ["npm:5.3.0", {\ - "packageLocation": "./.yarn/cache/estraverse-npm-5.3.0-03284f8f63-072780882d.zip/node_modules/estraverse/",\ - "packageDependencies": [\ - ["estraverse", "npm:5.3.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["estree-walker", [\ - ["npm:2.0.2", {\ - "packageLocation": "./.yarn/cache/estree-walker-npm-2.0.2-dfab42f65c-6151e6f982.zip/node_modules/estree-walker/",\ - "packageDependencies": [\ - ["estree-walker", "npm:2.0.2"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["esutils", [\ - ["npm:2.0.3", {\ - "packageLocation": "./.yarn/cache/esutils-npm-2.0.3-f865beafd5-22b5b08f74.zip/node_modules/esutils/",\ - "packageDependencies": [\ - ["esutils", "npm:2.0.3"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["eventemitter2", [\ - ["npm:6.4.5", {\ - "packageLocation": "./.yarn/cache/eventemitter2-npm-6.4.5-6862f231f1-84504f9cf0.zip/node_modules/eventemitter2/",\ - "packageDependencies": [\ - ["eventemitter2", "npm:6.4.5"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["evtd", [\ - ["npm:0.2.3", {\ - "packageLocation": "./.yarn/cache/evtd-npm-0.2.3-51a4edcda1-5ddded6263.zip/node_modules/evtd/",\ - "packageDependencies": [\ - ["evtd", "npm:0.2.3"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["execa", [\ - ["npm:4.1.0", {\ - "packageLocation": "./.yarn/cache/execa-npm-4.1.0-cc675b4189-e30d298934.zip/node_modules/execa/",\ - "packageDependencies": [\ - ["execa", "npm:4.1.0"],\ - ["cross-spawn", "npm:7.0.3"],\ - ["get-stream", "npm:5.2.0"],\ - ["human-signals", "npm:1.1.1"],\ - ["is-stream", "npm:2.0.1"],\ - ["merge-stream", "npm:2.0.0"],\ - ["npm-run-path", "npm:4.0.1"],\ - ["onetime", "npm:5.1.2"],\ - ["signal-exit", "npm:3.0.7"],\ - ["strip-final-newline", "npm:2.0.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["executable", [\ - ["npm:4.1.1", {\ - "packageLocation": "./.yarn/cache/executable-npm-4.1.1-c06d32cd1b-f01927ce59.zip/node_modules/executable/",\ - "packageDependencies": [\ - ["executable", "npm:4.1.1"],\ - ["pify", "npm:2.3.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["extend", [\ - ["npm:3.0.2", {\ - "packageLocation": "./.yarn/cache/extend-npm-3.0.2-e1ca07ac54-a50a8309ca.zip/node_modules/extend/",\ - "packageDependencies": [\ - ["extend", "npm:3.0.2"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["extract-zip", [\ - ["npm:2.0.1", {\ - "packageLocation": "./.yarn/cache/extract-zip-npm-2.0.1-92a28e392b-8cbda9debd.zip/node_modules/extract-zip/",\ - "packageDependencies": [\ - ["extract-zip", "npm:2.0.1"],\ - ["@types/yauzl", "npm:2.10.0"],\ - ["debug", "virtual:b86a9fb34323a98c6519528ed55faa0d9b44ca8879307c0b29aa384bde47ff59a7d0c9051b31246f14521dfb71ba3c5d6d0b35c29fffc17bf875aa6ad977d9e8#npm:4.3.4"],\ - ["get-stream", "npm:5.2.0"],\ - ["yauzl", "npm:2.10.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["extsprintf", [\ - ["npm:1.3.0", {\ - "packageLocation": "./.yarn/cache/extsprintf-npm-1.3.0-61a92b324c-cee7a4a1e3.zip/node_modules/extsprintf/",\ - "packageDependencies": [\ - ["extsprintf", "npm:1.3.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["fast-deep-equal", [\ - ["npm:3.1.3", {\ - "packageLocation": "./.yarn/cache/fast-deep-equal-npm-3.1.3-790edcfcf5-e21a9d8d84.zip/node_modules/fast-deep-equal/",\ - "packageDependencies": [\ - ["fast-deep-equal", "npm:3.1.3"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["fast-json-stable-stringify", [\ - ["npm:2.1.0", {\ - "packageLocation": "./.yarn/cache/fast-json-stable-stringify-npm-2.1.0-02e8905fda-b191531e36.zip/node_modules/fast-json-stable-stringify/",\ - "packageDependencies": [\ - ["fast-json-stable-stringify", "npm:2.1.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["fast-levenshtein", [\ - ["npm:2.0.6", {\ - "packageLocation": "./.yarn/cache/fast-levenshtein-npm-2.0.6-fcd74b8df5-92cfec0a8d.zip/node_modules/fast-levenshtein/",\ - "packageDependencies": [\ - ["fast-levenshtein", "npm:2.0.6"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["fd-slicer", [\ - ["npm:1.1.0", {\ - "packageLocation": "./.yarn/cache/fd-slicer-npm-1.1.0-3cade0050a-c8585fd571.zip/node_modules/fd-slicer/",\ - "packageDependencies": [\ - ["fd-slicer", "npm:1.1.0"],\ - ["pend", "npm:1.2.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["figures", [\ - ["npm:3.2.0", {\ - "packageLocation": "./.yarn/cache/figures-npm-3.2.0-85d357e955-85a6ad29e9.zip/node_modules/figures/",\ - "packageDependencies": [\ - ["figures", "npm:3.2.0"],\ - ["escape-string-regexp", "npm:1.0.5"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["file-entry-cache", [\ - ["npm:6.0.1", {\ - "packageLocation": "./.yarn/cache/file-entry-cache-npm-6.0.1-31965cf0af-f49701feaa.zip/node_modules/file-entry-cache/",\ - "packageDependencies": [\ - ["file-entry-cache", "npm:6.0.1"],\ - ["flat-cache", "npm:3.0.4"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["file-saver", [\ - ["npm:2.0.5", {\ - "packageLocation": "./.yarn/cache/file-saver-npm-2.0.5-2c3bc40d53-c62d96e5ce.zip/node_modules/file-saver/",\ - "packageDependencies": [\ - ["file-saver", "npm:2.0.5"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["fill-range", [\ - ["npm:7.0.1", {\ - "packageLocation": "./.yarn/cache/fill-range-npm-7.0.1-b8b1817caa-cc283f4e65.zip/node_modules/fill-range/",\ - "packageDependencies": [\ - ["fill-range", "npm:7.0.1"],\ - ["to-regex-range", "npm:5.0.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["find-up", [\ - ["npm:2.1.0", {\ - "packageLocation": "./.yarn/cache/find-up-npm-2.1.0-9f6cb1765c-43284fe4da.zip/node_modules/find-up/",\ - "packageDependencies": [\ - ["find-up", "npm:2.1.0"],\ - ["locate-path", "npm:2.0.0"]\ - ],\ - "linkType": "HARD"\ - }],\ - ["npm:5.0.0", {\ - "packageLocation": "./.yarn/cache/find-up-npm-5.0.0-e03e9b796d-07955e3573.zip/node_modules/find-up/",\ - "packageDependencies": [\ - ["find-up", "npm:5.0.0"],\ - ["locate-path", "npm:6.0.0"],\ - ["path-exists", "npm:4.0.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["flat-cache", [\ - ["npm:3.0.4", {\ - "packageLocation": "./.yarn/cache/flat-cache-npm-3.0.4-ee77e5911e-4fdd10ecbc.zip/node_modules/flat-cache/",\ - "packageDependencies": [\ - ["flat-cache", "npm:3.0.4"],\ - ["flatted", "npm:3.2.5"],\ - ["rimraf", "npm:3.0.2"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["flatted", [\ - ["npm:3.2.5", {\ - "packageLocation": "./.yarn/cache/flatted-npm-3.2.5-0ee5a8875f-3c436e9695.zip/node_modules/flatted/",\ - "packageDependencies": [\ - ["flatted", "npm:3.2.5"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["foreground-child", [\ - ["npm:2.0.0", {\ - "packageLocation": "./.yarn/cache/foreground-child-npm-2.0.0-80c976b61e-f77ec9aff6.zip/node_modules/foreground-child/",\ - "packageDependencies": [\ - ["foreground-child", "npm:2.0.0"],\ - ["cross-spawn", "npm:7.0.3"],\ - ["signal-exit", "npm:3.0.7"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["forever-agent", [\ - ["npm:0.6.1", {\ - "packageLocation": "./.yarn/cache/forever-agent-npm-0.6.1-01dae53bf9-766ae6e220.zip/node_modules/forever-agent/",\ - "packageDependencies": [\ - ["forever-agent", "npm:0.6.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["form-data", [\ - ["npm:2.3.3", {\ - "packageLocation": "./.yarn/cache/form-data-npm-2.3.3-c016cc11c0-10c1780fa1.zip/node_modules/form-data/",\ - "packageDependencies": [\ - ["form-data", "npm:2.3.3"],\ - ["asynckit", "npm:0.4.0"],\ - ["combined-stream", "npm:1.0.8"],\ - ["mime-types", "npm:2.1.35"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["fs-extra", [\ - ["npm:9.1.0", {\ - "packageLocation": "./.yarn/cache/fs-extra-npm-9.1.0-983c2ddb4c-ba71ba32e0.zip/node_modules/fs-extra/",\ - "packageDependencies": [\ - ["fs-extra", "npm:9.1.0"],\ - ["at-least-node", "npm:1.0.0"],\ - ["graceful-fs", "npm:4.2.10"],\ - ["jsonfile", "npm:6.1.0"],\ - ["universalify", "npm:2.0.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["fs-minipass", [\ - ["npm:2.1.0", {\ - "packageLocation": "./.yarn/cache/fs-minipass-npm-2.1.0-501ef87306-1b8d128dae.zip/node_modules/fs-minipass/",\ - "packageDependencies": [\ - ["fs-minipass", "npm:2.1.0"],\ - ["minipass", "npm:3.1.6"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["fs.realpath", [\ - ["npm:1.0.0", {\ - "packageLocation": "./.yarn/cache/fs.realpath-npm-1.0.0-c8f05d8126-99ddea01a7.zip/node_modules/fs.realpath/",\ - "packageDependencies": [\ - ["fs.realpath", "npm:1.0.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["fsevents", [\ - ["patch:fsevents@npm%3A2.3.2#~builtin::version=2.3.2&hash=18f3a7", {\ - "packageLocation": "./.yarn/unplugged/fsevents-patch-3340e2eb10/node_modules/fsevents/",\ - "packageDependencies": [\ - ["fsevents", "patch:fsevents@npm%3A2.3.2#~builtin::version=2.3.2&hash=18f3a7"],\ - ["node-gyp", "npm:9.0.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["function-bind", [\ - ["npm:1.1.1", {\ - "packageLocation": "./.yarn/cache/function-bind-npm-1.1.1-b56b322ae9-b32fbaebb3.zip/node_modules/function-bind/",\ - "packageDependencies": [\ - ["function-bind", "npm:1.1.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["functional-red-black-tree", [\ - ["npm:1.0.1", {\ - "packageLocation": "./.yarn/cache/functional-red-black-tree-npm-1.0.1-ccfe924dcd-ca6c170f37.zip/node_modules/functional-red-black-tree/",\ - "packageDependencies": [\ - ["functional-red-black-tree", "npm:1.0.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["gauge", [\ - ["npm:4.0.4", {\ - "packageLocation": "./.yarn/cache/gauge-npm-4.0.4-8f878385e9-788b6bfe52.zip/node_modules/gauge/",\ - "packageDependencies": [\ - ["gauge", "npm:4.0.4"],\ - ["aproba", "npm:2.0.0"],\ - ["color-support", "npm:1.1.3"],\ - ["console-control-strings", "npm:1.1.0"],\ - ["has-unicode", "npm:2.0.1"],\ - ["signal-exit", "npm:3.0.7"],\ - ["string-width", "npm:4.2.3"],\ - ["strip-ansi", "npm:6.0.1"],\ - ["wide-align", "npm:1.1.5"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["get-caller-file", [\ - ["npm:2.0.5", {\ - "packageLocation": "./.yarn/cache/get-caller-file-npm-2.0.5-80e8a86305-b9769a836d.zip/node_modules/get-caller-file/",\ - "packageDependencies": [\ - ["get-caller-file", "npm:2.0.5"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["get-func-name", [\ - ["npm:2.0.0", {\ - "packageLocation": "./.yarn/cache/get-func-name-npm-2.0.0-afbf363765-8d82e69f3e.zip/node_modules/get-func-name/",\ - "packageDependencies": [\ - ["get-func-name", "npm:2.0.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["get-intrinsic", [\ - ["npm:1.1.1", {\ - "packageLocation": "./.yarn/cache/get-intrinsic-npm-1.1.1-7e868745da-a9fe2ca8fa.zip/node_modules/get-intrinsic/",\ - "packageDependencies": [\ - ["get-intrinsic", "npm:1.1.1"],\ - ["function-bind", "npm:1.1.1"],\ - ["has", "npm:1.0.3"],\ - ["has-symbols", "npm:1.0.3"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["get-port", [\ - ["npm:4.2.0", {\ - "packageLocation": "./.yarn/cache/get-port-npm-4.2.0-07a1c5d34e-6c9a452b2d.zip/node_modules/get-port/",\ - "packageDependencies": [\ - ["get-port", "npm:4.2.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["get-stream", [\ - ["npm:5.2.0", {\ - "packageLocation": "./.yarn/cache/get-stream-npm-5.2.0-2cfd3b452b-8bc1a23174.zip/node_modules/get-stream/",\ - "packageDependencies": [\ - ["get-stream", "npm:5.2.0"],\ - ["pump", "npm:3.0.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["get-symbol-description", [\ - ["npm:1.0.0", {\ - "packageLocation": "./.yarn/cache/get-symbol-description-npm-1.0.0-9c95a4bc1f-9ceff8fe96.zip/node_modules/get-symbol-description/",\ - "packageDependencies": [\ - ["get-symbol-description", "npm:1.0.0"],\ - ["call-bind", "npm:1.0.2"],\ - ["get-intrinsic", "npm:1.1.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["getos", [\ - ["npm:3.2.1", {\ - "packageLocation": "./.yarn/cache/getos-npm-3.2.1-620c03aa34-42fd78a66d.zip/node_modules/getos/",\ - "packageDependencies": [\ - ["getos", "npm:3.2.1"],\ - ["async", "npm:3.2.3"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["getpass", [\ - ["npm:0.1.7", {\ - "packageLocation": "./.yarn/cache/getpass-npm-0.1.7-519164a3be-ab18d55661.zip/node_modules/getpass/",\ - "packageDependencies": [\ - ["getpass", "npm:0.1.7"],\ - ["assert-plus", "npm:1.0.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["glob", [\ - ["npm:7.2.3", {\ - "packageLocation": "./.yarn/cache/glob-npm-7.2.3-2d866d17a5-29452e97b3.zip/node_modules/glob/",\ - "packageDependencies": [\ - ["glob", "npm:7.2.3"],\ - ["fs.realpath", "npm:1.0.0"],\ - ["inflight", "npm:1.0.6"],\ - ["inherits", "npm:2.0.4"],\ - ["minimatch", "npm:3.1.2"],\ - ["once", "npm:1.4.0"],\ - ["path-is-absolute", "npm:1.0.1"]\ - ],\ - "linkType": "HARD"\ - }],\ - ["npm:8.0.3", {\ - "packageLocation": "./.yarn/cache/glob-npm-8.0.3-750f909025-50bcdea19d.zip/node_modules/glob/",\ - "packageDependencies": [\ - ["glob", "npm:8.0.3"],\ - ["fs.realpath", "npm:1.0.0"],\ - ["inflight", "npm:1.0.6"],\ - ["inherits", "npm:2.0.4"],\ - ["minimatch", "npm:5.1.0"],\ - ["once", "npm:1.4.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["glob-parent", [\ - ["npm:5.1.2", {\ - "packageLocation": "./.yarn/cache/glob-parent-npm-5.1.2-021ab32634-f4f2bfe242.zip/node_modules/glob-parent/",\ - "packageDependencies": [\ - ["glob-parent", "npm:5.1.2"],\ - ["is-glob", "npm:4.0.3"]\ - ],\ - "linkType": "HARD"\ - }],\ - ["npm:6.0.2", {\ - "packageLocation": "./.yarn/cache/glob-parent-npm-6.0.2-2cbef12738-c13ee97978.zip/node_modules/glob-parent/",\ - "packageDependencies": [\ - ["glob-parent", "npm:6.0.2"],\ - ["is-glob", "npm:4.0.3"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["global-dirs", [\ - ["npm:3.0.0", {\ - "packageLocation": "./.yarn/cache/global-dirs-npm-3.0.0-45faebeb68-953c17cf14.zip/node_modules/global-dirs/",\ - "packageDependencies": [\ - ["global-dirs", "npm:3.0.0"],\ - ["ini", "npm:2.0.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["globals", [\ - ["npm:11.12.0", {\ - "packageLocation": "./.yarn/cache/globals-npm-11.12.0-1fa7f41a6c-67051a45ec.zip/node_modules/globals/",\ - "packageDependencies": [\ - ["globals", "npm:11.12.0"]\ - ],\ - "linkType": "HARD"\ - }],\ - ["npm:13.15.0", {\ - "packageLocation": "./.yarn/cache/globals-npm-13.15.0-c0b0c83a7a-383ade0873.zip/node_modules/globals/",\ - "packageDependencies": [\ - ["globals", "npm:13.15.0"],\ - ["type-fest", "npm:0.20.2"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["graceful-fs", [\ - ["npm:4.2.10", {\ - "packageLocation": "./.yarn/cache/graceful-fs-npm-4.2.10-79c70989ca-3f109d70ae.zip/node_modules/graceful-fs/",\ - "packageDependencies": [\ - ["graceful-fs", "npm:4.2.10"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["has", [\ - ["npm:1.0.3", {\ - "packageLocation": "./.yarn/cache/has-npm-1.0.3-b7f00631c1-b9ad53d53b.zip/node_modules/has/",\ - "packageDependencies": [\ - ["has", "npm:1.0.3"],\ - ["function-bind", "npm:1.1.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["has-bigints", [\ - ["npm:1.0.2", {\ - "packageLocation": "./.yarn/cache/has-bigints-npm-1.0.2-52732e614d-390e31e7be.zip/node_modules/has-bigints/",\ - "packageDependencies": [\ - ["has-bigints", "npm:1.0.2"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["has-flag", [\ - ["npm:3.0.0", {\ - "packageLocation": "./.yarn/cache/has-flag-npm-3.0.0-16ac11fe05-4a15638b45.zip/node_modules/has-flag/",\ - "packageDependencies": [\ - ["has-flag", "npm:3.0.0"]\ - ],\ - "linkType": "HARD"\ - }],\ - ["npm:4.0.0", {\ - "packageLocation": "./.yarn/cache/has-flag-npm-4.0.0-32af9f0536-261a135703.zip/node_modules/has-flag/",\ - "packageDependencies": [\ - ["has-flag", "npm:4.0.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["has-property-descriptors", [\ - ["npm:1.0.0", {\ - "packageLocation": "./.yarn/cache/has-property-descriptors-npm-1.0.0-56289b918d-a6d3f0a266.zip/node_modules/has-property-descriptors/",\ - "packageDependencies": [\ - ["has-property-descriptors", "npm:1.0.0"],\ - ["get-intrinsic", "npm:1.1.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["has-symbols", [\ - ["npm:1.0.3", {\ - "packageLocation": "./.yarn/cache/has-symbols-npm-1.0.3-1986bff2c4-a054c40c63.zip/node_modules/has-symbols/",\ - "packageDependencies": [\ - ["has-symbols", "npm:1.0.3"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["has-tostringtag", [\ - ["npm:1.0.0", {\ - "packageLocation": "./.yarn/cache/has-tostringtag-npm-1.0.0-b1fcf3ab55-cc12eb28cb.zip/node_modules/has-tostringtag/",\ - "packageDependencies": [\ - ["has-tostringtag", "npm:1.0.0"],\ - ["has-symbols", "npm:1.0.3"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["has-unicode", [\ - ["npm:2.0.1", {\ - "packageLocation": "./.yarn/cache/has-unicode-npm-2.0.1-893adb4747-1eab07a743.zip/node_modules/has-unicode/",\ - "packageDependencies": [\ - ["has-unicode", "npm:2.0.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["highcharts", [\ - ["npm:10.2.0", {\ - "packageLocation": "./.yarn/cache/highcharts-npm-10.2.0-5422304a58-b9e16b9fc4.zip/node_modules/highcharts/",\ - "packageDependencies": [\ - ["highcharts", "npm:10.2.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["highlight.js", [\ - ["npm:11.5.1", {\ - "packageLocation": "./.yarn/cache/highlight.js-npm-11.5.1-0fb1167640-bff556101d.zip/node_modules/highlight.js/",\ - "packageDependencies": [\ - ["highlight.js", "npm:11.5.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["html-escaper", [\ - ["npm:2.0.2", {\ - "packageLocation": "./.yarn/cache/html-escaper-npm-2.0.2-38e51ef294-d2df2da3ad.zip/node_modules/html-escaper/",\ - "packageDependencies": [\ - ["html-escaper", "npm:2.0.2"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["html-validate", [\ - ["npm:7.1.2", {\ - "packageLocation": "./.yarn/cache/html-validate-npm-7.1.2-66108a0686-616c859647.zip/node_modules/html-validate/",\ - "packageDependencies": [\ - ["html-validate", "npm:7.1.2"]\ - ],\ - "linkType": "SOFT"\ - }],\ - ["virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:7.1.2", {\ - "packageLocation": "./.yarn/__virtual__/html-validate-virtual-9e7a483194/0/cache/html-validate-npm-7.1.2-66108a0686-616c859647.zip/node_modules/html-validate/",\ - "packageDependencies": [\ - ["html-validate", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:7.1.2"],\ - ["@babel/code-frame", "npm:7.16.7"],\ - ["@html-validate/stylish", "npm:3.0.0"],\ - ["@sidvind/better-ajv-errors", "virtual:9e7a4831943ff00ebf8ab9b738a379a7f31c6e004493e5987b05deb16a73f71a896a690e256d8f5e72f136a61b8533b4ef2cde3717790ed10cb7b6ca84d6613b#npm:2.0.0"],\ - ["@types/jest", null],\ - ["@types/jest-diff", null],\ - ["@types/jest-snapshot", null],\ - ["acorn-walk", "npm:8.2.0"],\ - ["ajv", "npm:8.11.0"],\ - ["deepmerge", "npm:4.2.2"],\ - ["espree", "npm:9.3.2"],\ - ["glob", "npm:8.0.3"],\ - ["ignore", "npm:5.2.0"],\ - ["jest", null],\ - ["jest-diff", null],\ - ["jest-snapshot", null],\ - ["kleur", "npm:4.1.4"],\ - ["minimist", "npm:1.2.6"],\ - ["prompts", "npm:2.4.2"],\ - ["semver", "npm:7.3.7"]\ - ],\ - "packagePeers": [\ - "@types/jest-diff",\ - "@types/jest-snapshot",\ - "@types/jest",\ - "jest-diff",\ - "jest-snapshot",\ - "jest"\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["htmlnano", [\ - ["npm:2.0.2", {\ - "packageLocation": "./.yarn/cache/htmlnano-npm-2.0.2-a89803bfeb-41f9e0c0e5.zip/node_modules/htmlnano/",\ - "packageDependencies": [\ - ["htmlnano", "npm:2.0.2"]\ - ],\ - "linkType": "SOFT"\ - }],\ - ["virtual:3a6cbfa587d4870ab3a0c1483e53d38c90b75222449e94f708edd9df02a7aeb0eada20885838b455e0694092bf130d1a617be06492c01a37600b15ec855f7ed0#npm:2.0.2", {\ - "packageLocation": "./.yarn/__virtual__/htmlnano-virtual-09fedf811d/0/cache/htmlnano-npm-2.0.2-a89803bfeb-41f9e0c0e5.zip/node_modules/htmlnano/",\ - "packageDependencies": [\ - ["htmlnano", "virtual:3a6cbfa587d4870ab3a0c1483e53d38c90b75222449e94f708edd9df02a7aeb0eada20885838b455e0694092bf130d1a617be06492c01a37600b15ec855f7ed0#npm:2.0.2"],\ - ["@types/cssnano", null],\ - ["@types/postcss", null],\ - ["@types/purgecss", null],\ - ["@types/relateurl", null],\ - ["@types/srcset", null],\ - ["@types/svgo", null],\ - ["@types/terser", null],\ - ["@types/uncss", null],\ - ["cosmiconfig", "npm:7.0.1"],\ - ["cssnano", null],\ - ["postcss", null],\ - ["posthtml", "npm:0.16.6"],\ - ["purgecss", null],\ - ["relateurl", null],\ - ["srcset", null],\ - ["svgo", "npm:2.8.0"],\ - ["terser", null],\ - ["timsort", "npm:0.3.0"],\ - ["uncss", null]\ - ],\ - "packagePeers": [\ - "@types/cssnano",\ - "@types/postcss",\ - "@types/purgecss",\ - "@types/relateurl",\ - "@types/srcset",\ - "@types/svgo",\ - "@types/terser",\ - "@types/uncss",\ - "cssnano",\ - "postcss",\ - "purgecss",\ - "relateurl",\ - "srcset",\ - "svgo",\ - "terser",\ - "uncss"\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["htmlparser2", [\ - ["npm:7.2.0", {\ - "packageLocation": "./.yarn/cache/htmlparser2-npm-7.2.0-ec7c96986f-96563d9965.zip/node_modules/htmlparser2/",\ - "packageDependencies": [\ - ["htmlparser2", "npm:7.2.0"],\ - ["domelementtype", "npm:2.3.0"],\ - ["domhandler", "npm:4.3.1"],\ - ["domutils", "npm:2.8.0"],\ - ["entities", "npm:3.0.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["http-cache-semantics", [\ - ["npm:4.1.0", {\ - "packageLocation": "./.yarn/cache/http-cache-semantics-npm-4.1.0-860520a31f-974de94a81.zip/node_modules/http-cache-semantics/",\ - "packageDependencies": [\ - ["http-cache-semantics", "npm:4.1.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["http-proxy-agent", [\ - ["npm:5.0.0", {\ - "packageLocation": "./.yarn/cache/http-proxy-agent-npm-5.0.0-7f1f121b83-e2ee1ff165.zip/node_modules/http-proxy-agent/",\ - "packageDependencies": [\ - ["http-proxy-agent", "npm:5.0.0"],\ - ["@tootallnate/once", "npm:2.0.0"],\ - ["agent-base", "npm:6.0.2"],\ - ["debug", "virtual:b86a9fb34323a98c6519528ed55faa0d9b44ca8879307c0b29aa384bde47ff59a7d0c9051b31246f14521dfb71ba3c5d6d0b35c29fffc17bf875aa6ad977d9e8#npm:4.3.4"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["http-signature", [\ - ["npm:1.3.6", {\ - "packageLocation": "./.yarn/cache/http-signature-npm-1.3.6-5b2eff4373-10be2af476.zip/node_modules/http-signature/",\ - "packageDependencies": [\ - ["http-signature", "npm:1.3.6"],\ - ["assert-plus", "npm:1.0.0"],\ - ["jsprim", "npm:2.0.2"],\ - ["sshpk", "npm:1.17.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["https-proxy-agent", [\ - ["npm:5.0.1", {\ - "packageLocation": "./.yarn/cache/https-proxy-agent-npm-5.0.1-42d65f358e-571fccdf38.zip/node_modules/https-proxy-agent/",\ - "packageDependencies": [\ - ["https-proxy-agent", "npm:5.0.1"],\ - ["agent-base", "npm:6.0.2"],\ - ["debug", "virtual:b86a9fb34323a98c6519528ed55faa0d9b44ca8879307c0b29aa384bde47ff59a7d0c9051b31246f14521dfb71ba3c5d6d0b35c29fffc17bf875aa6ad977d9e8#npm:4.3.4"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["human-signals", [\ - ["npm:1.1.1", {\ - "packageLocation": "./.yarn/cache/human-signals-npm-1.1.1-616b2586c2-d587647c9e.zip/node_modules/human-signals/",\ - "packageDependencies": [\ - ["human-signals", "npm:1.1.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["humanize-ms", [\ - ["npm:1.2.1", {\ - "packageLocation": "./.yarn/cache/humanize-ms-npm-1.2.1-e942bd7329-9c7a74a282.zip/node_modules/humanize-ms/",\ - "packageDependencies": [\ - ["humanize-ms", "npm:1.2.1"],\ - ["ms", "npm:2.1.3"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["iconv-lite", [\ - ["npm:0.6.3", {\ - "packageLocation": "./.yarn/cache/iconv-lite-npm-0.6.3-24b8aae27e-3f60d47a5c.zip/node_modules/iconv-lite/",\ - "packageDependencies": [\ - ["iconv-lite", "npm:0.6.3"],\ - ["safer-buffer", "npm:2.1.2"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["ieee754", [\ - ["npm:1.2.1", {\ - "packageLocation": "./.yarn/cache/ieee754-npm-1.2.1-fb63b3caeb-5144c0c981.zip/node_modules/ieee754/",\ - "packageDependencies": [\ - ["ieee754", "npm:1.2.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["ignore", [\ - ["npm:5.2.0", {\ - "packageLocation": "./.yarn/cache/ignore-npm-5.2.0-fc4b58a4f3-6b1f926792.zip/node_modules/ignore/",\ - "packageDependencies": [\ - ["ignore", "npm:5.2.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["immutable", [\ - ["npm:4.0.0", {\ - "packageLocation": "./.yarn/cache/immutable-npm-4.0.0-74b844f82e-4b5e9181e4.zip/node_modules/immutable/",\ - "packageDependencies": [\ - ["immutable", "npm:4.0.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["import-fresh", [\ - ["npm:3.3.0", {\ - "packageLocation": "./.yarn/cache/import-fresh-npm-3.3.0-3e34265ca9-2cacfad06e.zip/node_modules/import-fresh/",\ - "packageDependencies": [\ - ["import-fresh", "npm:3.3.0"],\ - ["parent-module", "npm:1.0.1"],\ - ["resolve-from", "npm:4.0.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["imurmurhash", [\ - ["npm:0.1.4", {\ - "packageLocation": "./.yarn/cache/imurmurhash-npm-0.1.4-610c5068a0-7cae75c8cd.zip/node_modules/imurmurhash/",\ - "packageDependencies": [\ - ["imurmurhash", "npm:0.1.4"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["indent-string", [\ - ["npm:4.0.0", {\ - "packageLocation": "./.yarn/cache/indent-string-npm-4.0.0-7b717435b2-824cfb9929.zip/node_modules/indent-string/",\ - "packageDependencies": [\ - ["indent-string", "npm:4.0.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["infer-owner", [\ - ["npm:1.0.4", {\ - "packageLocation": "./.yarn/cache/infer-owner-npm-1.0.4-685ac3d2af-181e732764.zip/node_modules/infer-owner/",\ - "packageDependencies": [\ - ["infer-owner", "npm:1.0.4"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["inflight", [\ - ["npm:1.0.6", {\ - "packageLocation": "./.yarn/cache/inflight-npm-1.0.6-ccedb4b908-f4f76aa072.zip/node_modules/inflight/",\ - "packageDependencies": [\ - ["inflight", "npm:1.0.6"],\ - ["once", "npm:1.4.0"],\ - ["wrappy", "npm:1.0.2"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["inherits", [\ - ["npm:2.0.4", {\ - "packageLocation": "./.yarn/cache/inherits-npm-2.0.4-c66b3957a0-4a48a73384.zip/node_modules/inherits/",\ - "packageDependencies": [\ - ["inherits", "npm:2.0.4"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["ini", [\ - ["npm:2.0.0", {\ - "packageLocation": "./.yarn/cache/ini-npm-2.0.0-28f7426761-e7aadc5fb2.zip/node_modules/ini/",\ - "packageDependencies": [\ - ["ini", "npm:2.0.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["internal-slot", [\ - ["npm:1.0.3", {\ - "packageLocation": "./.yarn/cache/internal-slot-npm-1.0.3-9e05eea002-1944f92e98.zip/node_modules/internal-slot/",\ - "packageDependencies": [\ - ["internal-slot", "npm:1.0.3"],\ - ["get-intrinsic", "npm:1.1.1"],\ - ["has", "npm:1.0.3"],\ - ["side-channel", "npm:1.0.4"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["internmap", [\ - ["npm:2.0.3", {\ - "packageLocation": "./.yarn/cache/internmap-npm-2.0.3-d74f5c9998-7ca41ec6ab.zip/node_modules/internmap/",\ - "packageDependencies": [\ - ["internmap", "npm:2.0.3"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["ip", [\ - ["npm:1.1.8", {\ - "packageLocation": "./.yarn/cache/ip-npm-1.1.8-abea558b72-a2ade53eb3.zip/node_modules/ip/",\ - "packageDependencies": [\ - ["ip", "npm:1.1.8"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["is-arrayish", [\ - ["npm:0.2.1", {\ - "packageLocation": "./.yarn/cache/is-arrayish-npm-0.2.1-23927dfb15-eef4417e3c.zip/node_modules/is-arrayish/",\ - "packageDependencies": [\ - ["is-arrayish", "npm:0.2.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["is-bigint", [\ - ["npm:1.0.4", {\ - "packageLocation": "./.yarn/cache/is-bigint-npm-1.0.4-31c2eecbc9-c56edfe09b.zip/node_modules/is-bigint/",\ - "packageDependencies": [\ - ["is-bigint", "npm:1.0.4"],\ - ["has-bigints", "npm:1.0.2"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["is-binary-path", [\ - ["npm:2.1.0", {\ - "packageLocation": "./.yarn/cache/is-binary-path-npm-2.1.0-e61d46f557-84192eb88c.zip/node_modules/is-binary-path/",\ - "packageDependencies": [\ - ["is-binary-path", "npm:2.1.0"],\ - ["binary-extensions", "npm:2.2.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["is-boolean-object", [\ - ["npm:1.1.2", {\ - "packageLocation": "./.yarn/cache/is-boolean-object-npm-1.1.2-ecbd575e6a-c03b23dbaa.zip/node_modules/is-boolean-object/",\ - "packageDependencies": [\ - ["is-boolean-object", "npm:1.1.2"],\ - ["call-bind", "npm:1.0.2"],\ - ["has-tostringtag", "npm:1.0.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["is-callable", [\ - ["npm:1.2.4", {\ - "packageLocation": "./.yarn/cache/is-callable-npm-1.2.4-03fc17459c-1a28d57dc4.zip/node_modules/is-callable/",\ - "packageDependencies": [\ - ["is-callable", "npm:1.2.4"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["is-ci", [\ - ["npm:3.0.1", {\ - "packageLocation": "./.yarn/cache/is-ci-npm-3.0.1-d9aea361e1-192c66dc78.zip/node_modules/is-ci/",\ - "packageDependencies": [\ - ["is-ci", "npm:3.0.1"],\ - ["ci-info", "npm:3.3.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["is-core-module", [\ - ["npm:2.9.0", {\ - "packageLocation": "./.yarn/cache/is-core-module-npm-2.9.0-5ba77c35ae-b27034318b.zip/node_modules/is-core-module/",\ - "packageDependencies": [\ - ["is-core-module", "npm:2.9.0"],\ - ["has", "npm:1.0.3"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["is-date-object", [\ - ["npm:1.0.5", {\ - "packageLocation": "./.yarn/cache/is-date-object-npm-1.0.5-88f3d08b5e-baa9077cdf.zip/node_modules/is-date-object/",\ - "packageDependencies": [\ - ["is-date-object", "npm:1.0.5"],\ - ["has-tostringtag", "npm:1.0.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["is-expression", [\ - ["npm:4.0.0", {\ - "packageLocation": "./.yarn/cache/is-expression-npm-4.0.0-44cc07c8aa-0f01d0ff53.zip/node_modules/is-expression/",\ - "packageDependencies": [\ - ["is-expression", "npm:4.0.0"],\ - ["acorn", "npm:7.4.1"],\ - ["object-assign", "npm:4.1.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["is-extglob", [\ - ["npm:2.1.1", {\ - "packageLocation": "./.yarn/cache/is-extglob-npm-2.1.1-0870ea68b5-df033653d0.zip/node_modules/is-extglob/",\ - "packageDependencies": [\ - ["is-extglob", "npm:2.1.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["is-fullwidth-code-point", [\ - ["npm:3.0.0", {\ - "packageLocation": "./.yarn/cache/is-fullwidth-code-point-npm-3.0.0-1ecf4ebee5-44a30c2945.zip/node_modules/is-fullwidth-code-point/",\ - "packageDependencies": [\ - ["is-fullwidth-code-point", "npm:3.0.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["is-glob", [\ - ["npm:4.0.3", {\ - "packageLocation": "./.yarn/cache/is-glob-npm-4.0.3-cb87bf1bdb-d381c1319f.zip/node_modules/is-glob/",\ - "packageDependencies": [\ - ["is-glob", "npm:4.0.3"],\ - ["is-extglob", "npm:2.1.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["is-installed-globally", [\ - ["npm:0.4.0", {\ - "packageLocation": "./.yarn/cache/is-installed-globally-npm-0.4.0-a30dd056c7-3359840d59.zip/node_modules/is-installed-globally/",\ - "packageDependencies": [\ - ["is-installed-globally", "npm:0.4.0"],\ - ["global-dirs", "npm:3.0.0"],\ - ["is-path-inside", "npm:3.0.3"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["is-json", [\ - ["npm:2.0.1", {\ - "packageLocation": "./.yarn/cache/is-json-npm-2.0.1-a385cacc72-29efc4f82e.zip/node_modules/is-json/",\ - "packageDependencies": [\ - ["is-json", "npm:2.0.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["is-lambda", [\ - ["npm:1.0.1", {\ - "packageLocation": "./.yarn/cache/is-lambda-npm-1.0.1-7ab55bc8a8-93a32f0194.zip/node_modules/is-lambda/",\ - "packageDependencies": [\ - ["is-lambda", "npm:1.0.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["is-negative-zero", [\ - ["npm:2.0.2", {\ - "packageLocation": "./.yarn/cache/is-negative-zero-npm-2.0.2-0adac91f15-f3232194c4.zip/node_modules/is-negative-zero/",\ - "packageDependencies": [\ - ["is-negative-zero", "npm:2.0.2"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["is-number", [\ - ["npm:7.0.0", {\ - "packageLocation": "./.yarn/cache/is-number-npm-7.0.0-060086935c-456ac6f8e0.zip/node_modules/is-number/",\ - "packageDependencies": [\ - ["is-number", "npm:7.0.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["is-number-object", [\ - ["npm:1.0.7", {\ - "packageLocation": "./.yarn/cache/is-number-object-npm-1.0.7-539d0e274d-d1e8d01bb0.zip/node_modules/is-number-object/",\ - "packageDependencies": [\ - ["is-number-object", "npm:1.0.7"],\ - ["has-tostringtag", "npm:1.0.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["is-path-inside", [\ - ["npm:3.0.3", {\ - "packageLocation": "./.yarn/cache/is-path-inside-npm-3.0.3-2ea0ef44fd-abd50f0618.zip/node_modules/is-path-inside/",\ - "packageDependencies": [\ - ["is-path-inside", "npm:3.0.3"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["is-promise", [\ - ["npm:2.2.2", {\ - "packageLocation": "./.yarn/cache/is-promise-npm-2.2.2-afbf94db67-18bf7d1c59.zip/node_modules/is-promise/",\ - "packageDependencies": [\ - ["is-promise", "npm:2.2.2"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["is-regex", [\ - ["npm:1.1.4", {\ - "packageLocation": "./.yarn/cache/is-regex-npm-1.1.4-cca193ef11-362399b335.zip/node_modules/is-regex/",\ - "packageDependencies": [\ - ["is-regex", "npm:1.1.4"],\ - ["call-bind", "npm:1.0.2"],\ - ["has-tostringtag", "npm:1.0.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["is-shared-array-buffer", [\ - ["npm:1.0.2", {\ - "packageLocation": "./.yarn/cache/is-shared-array-buffer-npm-1.0.2-32e4181fcd-9508929cf1.zip/node_modules/is-shared-array-buffer/",\ - "packageDependencies": [\ - ["is-shared-array-buffer", "npm:1.0.2"],\ - ["call-bind", "npm:1.0.2"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["is-stream", [\ - ["npm:2.0.1", {\ - "packageLocation": "./.yarn/cache/is-stream-npm-2.0.1-c802db55e7-b8e05ccdf9.zip/node_modules/is-stream/",\ - "packageDependencies": [\ - ["is-stream", "npm:2.0.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["is-string", [\ - ["npm:1.0.7", {\ - "packageLocation": "./.yarn/cache/is-string-npm-1.0.7-9f7066daed-323b3d0462.zip/node_modules/is-string/",\ - "packageDependencies": [\ - ["is-string", "npm:1.0.7"],\ - ["has-tostringtag", "npm:1.0.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["is-symbol", [\ - ["npm:1.0.4", {\ - "packageLocation": "./.yarn/cache/is-symbol-npm-1.0.4-eb9baac703-92805812ef.zip/node_modules/is-symbol/",\ - "packageDependencies": [\ - ["is-symbol", "npm:1.0.4"],\ - ["has-symbols", "npm:1.0.3"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["is-typedarray", [\ - ["npm:1.0.0", {\ - "packageLocation": "./.yarn/cache/is-typedarray-npm-1.0.0-bbd99de5b6-3508c6cd0a.zip/node_modules/is-typedarray/",\ - "packageDependencies": [\ - ["is-typedarray", "npm:1.0.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["is-unicode-supported", [\ - ["npm:0.1.0", {\ - "packageLocation": "./.yarn/cache/is-unicode-supported-npm-0.1.0-0833e1bbfb-a2aab86ee7.zip/node_modules/is-unicode-supported/",\ - "packageDependencies": [\ - ["is-unicode-supported", "npm:0.1.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["is-weakref", [\ - ["npm:1.0.2", {\ - "packageLocation": "./.yarn/cache/is-weakref-npm-1.0.2-ff80e8c314-95bd9a57cd.zip/node_modules/is-weakref/",\ - "packageDependencies": [\ - ["is-weakref", "npm:1.0.2"],\ - ["call-bind", "npm:1.0.2"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["isexe", [\ - ["npm:2.0.0", {\ - "packageLocation": "./.yarn/cache/isexe-npm-2.0.0-b58870bd2e-26bf6c5480.zip/node_modules/isexe/",\ - "packageDependencies": [\ - ["isexe", "npm:2.0.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["isstream", [\ - ["npm:0.1.2", {\ - "packageLocation": "./.yarn/cache/isstream-npm-0.1.2-8581c75385-1eb2fe63a7.zip/node_modules/isstream/",\ - "packageDependencies": [\ - ["isstream", "npm:0.1.2"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["istanbul-lib-coverage", [\ - ["npm:3.2.0", {\ - "packageLocation": "./.yarn/cache/istanbul-lib-coverage-npm-3.2.0-93f84b2c8c-a2a545033b.zip/node_modules/istanbul-lib-coverage/",\ - "packageDependencies": [\ - ["istanbul-lib-coverage", "npm:3.2.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["istanbul-lib-report", [\ - ["npm:3.0.0", {\ - "packageLocation": "./.yarn/cache/istanbul-lib-report-npm-3.0.0-660f97340a-3f29eb3f53.zip/node_modules/istanbul-lib-report/",\ - "packageDependencies": [\ - ["istanbul-lib-report", "npm:3.0.0"],\ - ["istanbul-lib-coverage", "npm:3.2.0"],\ - ["make-dir", "npm:3.1.0"],\ - ["supports-color", "npm:7.2.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["istanbul-reports", [\ - ["npm:3.1.4", {\ - "packageLocation": "./.yarn/cache/istanbul-reports-npm-3.1.4-5faaa9636c-2132983355.zip/node_modules/istanbul-reports/",\ - "packageDependencies": [\ - ["istanbul-reports", "npm:3.1.4"],\ - ["html-escaper", "npm:2.0.2"],\ - ["istanbul-lib-report", "npm:3.0.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["jest-diff", [\ - ["npm:27.5.1", {\ - "packageLocation": "./.yarn/cache/jest-diff-npm-27.5.1-818e549196-8be27c1e1e.zip/node_modules/jest-diff/",\ - "packageDependencies": [\ - ["jest-diff", "npm:27.5.1"],\ - ["chalk", "npm:4.1.2"],\ - ["diff-sequences", "npm:27.5.1"],\ - ["jest-get-type", "npm:27.5.1"],\ - ["pretty-format", "npm:27.5.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["jest-get-type", [\ - ["npm:27.5.1", {\ - "packageLocation": "./.yarn/cache/jest-get-type-npm-27.5.1-980fbf7a43-63064ab701.zip/node_modules/jest-get-type/",\ - "packageDependencies": [\ - ["jest-get-type", "npm:27.5.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["jest-matcher-utils", [\ - ["npm:27.5.1", {\ - "packageLocation": "./.yarn/cache/jest-matcher-utils-npm-27.5.1-0c47b071fb-bb2135fc48.zip/node_modules/jest-matcher-utils/",\ - "packageDependencies": [\ - ["jest-matcher-utils", "npm:27.5.1"],\ - ["chalk", "npm:4.1.2"],\ - ["jest-diff", "npm:27.5.1"],\ - ["jest-get-type", "npm:27.5.1"],\ - ["pretty-format", "npm:27.5.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["jquery", [\ - ["npm:3.6.0", {\ - "packageLocation": "./.yarn/cache/jquery-npm-3.6.0-ca7872bdbb-8fd5fef4aa.zip/node_modules/jquery/",\ - "packageDependencies": [\ - ["jquery", "npm:3.6.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["jquery-migrate", [\ - ["npm:3.4.0", {\ - "packageLocation": "./.yarn/cache/jquery-migrate-npm-3.4.0-88c209e61f-7431685c56.zip/node_modules/jquery-migrate/",\ - "packageDependencies": [\ - ["jquery-migrate", "npm:3.4.0"]\ - ],\ - "linkType": "SOFT"\ - }],\ - ["virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:3.4.0", {\ - "packageLocation": "./.yarn/__virtual__/jquery-migrate-virtual-68c5ec0b7a/0/cache/jquery-migrate-npm-3.4.0-88c209e61f-7431685c56.zip/node_modules/jquery-migrate/",\ - "packageDependencies": [\ - ["jquery-migrate", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:3.4.0"],\ - ["@types/jquery", null],\ - ["jquery", "npm:3.6.0"]\ - ],\ - "packagePeers": [\ - "@types/jquery",\ - "jquery"\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["jquery-ui-dist", [\ - ["npm:1.13.1", {\ - "packageLocation": "./.yarn/cache/jquery-ui-dist-npm-1.13.1-fe4cdb19d6-9a19f520b8.zip/node_modules/jquery-ui-dist/",\ - "packageDependencies": [\ - ["jquery-ui-dist", "npm:1.13.1"],\ - ["jquery", "npm:3.6.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["js-cookie", [\ - ["npm:3.0.1", {\ - "packageLocation": "./.yarn/cache/js-cookie-npm-3.0.1-04c7177de1-bb48de67e2.zip/node_modules/js-cookie/",\ - "packageDependencies": [\ - ["js-cookie", "npm:3.0.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["js-stringify", [\ - ["npm:1.0.2", {\ - "packageLocation": "./.yarn/cache/js-stringify-npm-1.0.2-898ffeac57-f9701d9e53.zip/node_modules/js-stringify/",\ - "packageDependencies": [\ - ["js-stringify", "npm:1.0.2"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["js-tokens", [\ - ["npm:4.0.0", {\ - "packageLocation": "./.yarn/cache/js-tokens-npm-4.0.0-0ac852e9e2-8a95213a5a.zip/node_modules/js-tokens/",\ - "packageDependencies": [\ - ["js-tokens", "npm:4.0.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["js-yaml", [\ - ["npm:4.1.0", {\ - "packageLocation": "./.yarn/cache/js-yaml-npm-4.1.0-3606f32312-c7830dfd45.zip/node_modules/js-yaml/",\ - "packageDependencies": [\ - ["js-yaml", "npm:4.1.0"],\ - ["argparse", "npm:2.0.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["jsbn", [\ - ["npm:0.1.1", {\ - "packageLocation": "./.yarn/cache/jsbn-npm-0.1.1-0eb7132404-e5ff29c1b8.zip/node_modules/jsbn/",\ - "packageDependencies": [\ - ["jsbn", "npm:0.1.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["json-parse-even-better-errors", [\ - ["npm:2.3.1", {\ - "packageLocation": "./.yarn/cache/json-parse-even-better-errors-npm-2.3.1-144d62256e-798ed4cf33.zip/node_modules/json-parse-even-better-errors/",\ - "packageDependencies": [\ - ["json-parse-even-better-errors", "npm:2.3.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["json-schema", [\ - ["npm:0.4.0", {\ - "packageLocation": "./.yarn/cache/json-schema-npm-0.4.0-e776313070-66389434c3.zip/node_modules/json-schema/",\ - "packageDependencies": [\ - ["json-schema", "npm:0.4.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["json-schema-traverse", [\ - ["npm:0.4.1", {\ - "packageLocation": "./.yarn/cache/json-schema-traverse-npm-0.4.1-4759091693-7486074d3b.zip/node_modules/json-schema-traverse/",\ - "packageDependencies": [\ - ["json-schema-traverse", "npm:0.4.1"]\ - ],\ - "linkType": "HARD"\ - }],\ - ["npm:1.0.0", {\ - "packageLocation": "./.yarn/cache/json-schema-traverse-npm-1.0.0-fb3684f4f0-02f2f466cd.zip/node_modules/json-schema-traverse/",\ - "packageDependencies": [\ - ["json-schema-traverse", "npm:1.0.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["json-stable-stringify-without-jsonify", [\ - ["npm:1.0.1", {\ - "packageLocation": "./.yarn/cache/json-stable-stringify-without-jsonify-npm-1.0.1-b65772b28b-cff44156dd.zip/node_modules/json-stable-stringify-without-jsonify/",\ - "packageDependencies": [\ - ["json-stable-stringify-without-jsonify", "npm:1.0.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["json-stringify-safe", [\ - ["npm:5.0.1", {\ - "packageLocation": "./.yarn/cache/json-stringify-safe-npm-5.0.1-064ddd6ab4-48ec0adad5.zip/node_modules/json-stringify-safe/",\ - "packageDependencies": [\ - ["json-stringify-safe", "npm:5.0.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["json5", [\ - ["npm:1.0.1", {\ - "packageLocation": "./.yarn/cache/json5-npm-1.0.1-647fc8794b-e76ea23dbb.zip/node_modules/json5/",\ - "packageDependencies": [\ - ["json5", "npm:1.0.1"],\ - ["minimist", "npm:1.2.6"]\ - ],\ - "linkType": "HARD"\ - }],\ - ["npm:2.2.1", {\ - "packageLocation": "./.yarn/cache/json5-npm-2.2.1-44675c859c-74b8a23b10.zip/node_modules/json5/",\ - "packageDependencies": [\ - ["json5", "npm:2.2.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["jsonfile", [\ - ["npm:6.1.0", {\ - "packageLocation": "./.yarn/cache/jsonfile-npm-6.1.0-20a4796cee-7af3b8e1ac.zip/node_modules/jsonfile/",\ - "packageDependencies": [\ - ["jsonfile", "npm:6.1.0"],\ - ["graceful-fs", "npm:4.2.10"],\ - ["universalify", "npm:2.0.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["jsprim", [\ - ["npm:2.0.2", {\ - "packageLocation": "./.yarn/cache/jsprim-npm-2.0.2-8c40f3719c-d175f6b199.zip/node_modules/jsprim/",\ - "packageDependencies": [\ - ["jsprim", "npm:2.0.2"],\ - ["assert-plus", "npm:1.0.0"],\ - ["extsprintf", "npm:1.3.0"],\ - ["json-schema", "npm:0.4.0"],\ - ["verror", "npm:1.10.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["jstransformer", [\ - ["npm:1.0.0", {\ - "packageLocation": "./.yarn/cache/jstransformer-npm-1.0.0-41a47d180a-1e019fde17.zip/node_modules/jstransformer/",\ - "packageDependencies": [\ - ["jstransformer", "npm:1.0.0"],\ - ["is-promise", "npm:2.2.2"],\ - ["promise", "npm:7.3.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["kleur", [\ - ["npm:3.0.3", {\ - "packageLocation": "./.yarn/cache/kleur-npm-3.0.3-f6f53649a4-df82cd1e17.zip/node_modules/kleur/",\ - "packageDependencies": [\ - ["kleur", "npm:3.0.3"]\ - ],\ - "linkType": "HARD"\ - }],\ - ["npm:4.1.4", {\ - "packageLocation": "./.yarn/cache/kleur-npm-4.1.4-7a73ff57c6-7f6db36e37.zip/node_modules/kleur/",\ - "packageDependencies": [\ - ["kleur", "npm:4.1.4"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["lazy-ass", [\ - ["npm:1.6.0", {\ - "packageLocation": "./.yarn/cache/lazy-ass-npm-1.6.0-5cda93b8cb-5a3ebb1791.zip/node_modules/lazy-ass/",\ - "packageDependencies": [\ - ["lazy-ass", "npm:1.6.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["levn", [\ - ["npm:0.4.1", {\ - "packageLocation": "./.yarn/cache/levn-npm-0.4.1-d183b2d7bb-12c5021c85.zip/node_modules/levn/",\ - "packageDependencies": [\ - ["levn", "npm:0.4.1"],\ - ["prelude-ls", "npm:1.2.1"],\ - ["type-check", "npm:0.4.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["lines-and-columns", [\ - ["npm:1.2.4", {\ - "packageLocation": "./.yarn/cache/lines-and-columns-npm-1.2.4-d6c7cc5799-0c37f9f7fa.zip/node_modules/lines-and-columns/",\ - "packageDependencies": [\ - ["lines-and-columns", "npm:1.2.4"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["list.js", [\ - ["npm:2.3.1", {\ - "packageLocation": "./.yarn/cache/list.js-npm-2.3.1-31415fcbbd-3bb4e9035b.zip/node_modules/list.js/",\ - "packageDependencies": [\ - ["list.js", "npm:2.3.1"],\ - ["string-natural-compare", "npm:2.0.3"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["listr2", [\ - ["npm:3.14.0", {\ - "packageLocation": "./.yarn/cache/listr2-npm-3.14.0-446f504112-fdb8b2d6bd.zip/node_modules/listr2/",\ - "packageDependencies": [\ - ["listr2", "npm:3.14.0"]\ - ],\ - "linkType": "SOFT"\ - }],\ - ["virtual:b9950af2d111388934806057a586eabc99a9a1279d1f7d5a87654ac6209cdd318e086140e128e4a5adc819e925bea187073b27a79d28a166d5dffe758bcd5335#npm:3.14.0", {\ - "packageLocation": "./.yarn/__virtual__/listr2-virtual-846882e0be/0/cache/listr2-npm-3.14.0-446f504112-fdb8b2d6bd.zip/node_modules/listr2/",\ - "packageDependencies": [\ - ["listr2", "virtual:b9950af2d111388934806057a586eabc99a9a1279d1f7d5a87654ac6209cdd318e086140e128e4a5adc819e925bea187073b27a79d28a166d5dffe758bcd5335#npm:3.14.0"],\ - ["@types/enquirer", null],\ - ["cli-truncate", "npm:2.1.0"],\ - ["colorette", "npm:2.0.16"],\ - ["enquirer", "npm:2.3.6"],\ - ["log-update", "npm:4.0.0"],\ - ["p-map", "npm:4.0.0"],\ - ["rfdc", "npm:1.3.0"],\ - ["rxjs", "npm:7.5.5"],\ - ["through", "npm:2.3.8"],\ - ["wrap-ansi", "npm:7.0.0"]\ - ],\ - "packagePeers": [\ - "@types/enquirer",\ - "enquirer"\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["lmdb", [\ - ["npm:2.5.2", {\ - "packageLocation": "./.yarn/unplugged/lmdb-npm-2.5.2-76ec56235a/node_modules/lmdb/",\ - "packageDependencies": [\ - ["lmdb", "npm:2.5.2"],\ - ["@lmdb/lmdb-darwin-arm64", "npm:2.5.2"],\ - ["@lmdb/lmdb-darwin-x64", "npm:2.5.2"],\ - ["@lmdb/lmdb-linux-arm", "npm:2.5.2"],\ - ["@lmdb/lmdb-linux-arm64", "npm:2.5.2"],\ - ["@lmdb/lmdb-linux-x64", "npm:2.5.2"],\ - ["@lmdb/lmdb-win32-x64", "npm:2.5.2"],\ - ["msgpackr", "npm:1.6.0"],\ - ["node-addon-api", "npm:4.3.0"],\ - ["node-gyp", "npm:9.0.0"],\ - ["node-gyp-build-optional-packages", "npm:5.0.3"],\ - ["ordered-binary", "npm:1.2.5"],\ - ["weak-lru-cache", "npm:1.2.2"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["local-pkg", [\ - ["npm:0.4.2", {\ - "packageLocation": "./.yarn/cache/local-pkg-npm-0.4.2-534016519b-22be451353.zip/node_modules/local-pkg/",\ - "packageDependencies": [\ - ["local-pkg", "npm:0.4.2"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["locate-path", [\ - ["npm:2.0.0", {\ - "packageLocation": "./.yarn/cache/locate-path-npm-2.0.0-673d28b0ea-02d581edbb.zip/node_modules/locate-path/",\ - "packageDependencies": [\ - ["locate-path", "npm:2.0.0"],\ - ["p-locate", "npm:2.0.0"],\ - ["path-exists", "npm:3.0.0"]\ - ],\ - "linkType": "HARD"\ - }],\ - ["npm:6.0.0", {\ - "packageLocation": "./.yarn/cache/locate-path-npm-6.0.0-06a1e4c528-72eb661788.zip/node_modules/locate-path/",\ - "packageDependencies": [\ - ["locate-path", "npm:6.0.0"],\ - ["p-locate", "npm:5.0.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["lodash", [\ - ["npm:4.17.21", {\ - "packageLocation": "./.yarn/cache/lodash-npm-4.17.21-6382451519-eb835a2e51.zip/node_modules/lodash/",\ - "packageDependencies": [\ - ["lodash", "npm:4.17.21"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["lodash-es", [\ - ["npm:4.17.21", {\ - "packageLocation": "./.yarn/cache/lodash-es-npm-4.17.21-b45832dfce-05cbffad6e.zip/node_modules/lodash-es/",\ - "packageDependencies": [\ - ["lodash-es", "npm:4.17.21"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["lodash.merge", [\ - ["npm:4.6.2", {\ - "packageLocation": "./.yarn/cache/lodash.merge-npm-4.6.2-77cb4416bf-ad580b4bdb.zip/node_modules/lodash.merge/",\ - "packageDependencies": [\ - ["lodash.merge", "npm:4.6.2"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["lodash.once", [\ - ["npm:4.1.1", {\ - "packageLocation": "./.yarn/cache/lodash.once-npm-4.1.1-d8ba329ead-d768fa9f9b.zip/node_modules/lodash.once/",\ - "packageDependencies": [\ - ["lodash.once", "npm:4.1.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["lodash.sortby", [\ - ["npm:4.7.0", {\ - "packageLocation": "./.yarn/cache/lodash.sortby-npm-4.7.0-fda8ab950d-db170c9396.zip/node_modules/lodash.sortby/",\ - "packageDependencies": [\ - ["lodash.sortby", "npm:4.7.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["log-symbols", [\ - ["npm:4.1.0", {\ - "packageLocation": "./.yarn/cache/log-symbols-npm-4.1.0-0a13492d8b-fce1497b31.zip/node_modules/log-symbols/",\ - "packageDependencies": [\ - ["log-symbols", "npm:4.1.0"],\ - ["chalk", "npm:4.1.2"],\ - ["is-unicode-supported", "npm:0.1.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["log-update", [\ - ["npm:4.0.0", {\ - "packageLocation": "./.yarn/cache/log-update-npm-4.0.0-9d0554261c-ae2f85bbab.zip/node_modules/log-update/",\ - "packageDependencies": [\ - ["log-update", "npm:4.0.0"],\ - ["ansi-escapes", "npm:4.3.2"],\ - ["cli-cursor", "npm:3.1.0"],\ - ["slice-ansi", "npm:4.0.0"],\ - ["wrap-ansi", "npm:6.2.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["loupe", [\ - ["npm:2.3.4", {\ - "packageLocation": "./.yarn/cache/loupe-npm-2.3.4-2067703c8d-5af91db61a.zip/node_modules/loupe/",\ - "packageDependencies": [\ - ["loupe", "npm:2.3.4"],\ - ["get-func-name", "npm:2.0.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["lru-cache", [\ - ["npm:6.0.0", {\ - "packageLocation": "./.yarn/cache/lru-cache-npm-6.0.0-b4c8668fe1-f97f499f89.zip/node_modules/lru-cache/",\ - "packageDependencies": [\ - ["lru-cache", "npm:6.0.0"],\ - ["yallist", "npm:4.0.0"]\ - ],\ - "linkType": "HARD"\ - }],\ - ["npm:7.10.1", {\ - "packageLocation": "./.yarn/cache/lru-cache-npm-7.10.1-5af910d0ed-e8b190d71e.zip/node_modules/lru-cache/",\ - "packageDependencies": [\ - ["lru-cache", "npm:7.10.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["luxon", [\ - ["npm:3.0.1", {\ - "packageLocation": "./.yarn/cache/luxon-npm-3.0.1-c6377bcf9a-aa966eb919.zip/node_modules/luxon/",\ - "packageDependencies": [\ - ["luxon", "npm:3.0.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["magic-string", [\ - ["npm:0.25.9", {\ - "packageLocation": "./.yarn/cache/magic-string-npm-0.25.9-0b51c0ea50-9a0e55a15c.zip/node_modules/magic-string/",\ - "packageDependencies": [\ - ["magic-string", "npm:0.25.9"],\ - ["sourcemap-codec", "npm:1.4.8"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["make-dir", [\ - ["npm:3.1.0", {\ - "packageLocation": "./.yarn/cache/make-dir-npm-3.1.0-d1d7505142-484200020a.zip/node_modules/make-dir/",\ - "packageDependencies": [\ - ["make-dir", "npm:3.1.0"],\ - ["semver", "npm:6.3.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["make-fetch-happen", [\ - ["npm:10.1.5", {\ - "packageLocation": "./.yarn/cache/make-fetch-happen-npm-10.1.5-d805393723-b0b42a1ccd.zip/node_modules/make-fetch-happen/",\ - "packageDependencies": [\ - ["make-fetch-happen", "npm:10.1.5"],\ - ["agentkeepalive", "npm:4.2.1"],\ - ["cacache", "npm:16.1.0"],\ - ["http-cache-semantics", "npm:4.1.0"],\ - ["http-proxy-agent", "npm:5.0.0"],\ - ["https-proxy-agent", "npm:5.0.1"],\ - ["is-lambda", "npm:1.0.1"],\ - ["lru-cache", "npm:7.10.1"],\ - ["minipass", "npm:3.1.6"],\ - ["minipass-collect", "npm:1.0.2"],\ - ["minipass-fetch", "npm:2.1.0"],\ - ["minipass-flush", "npm:1.0.5"],\ - ["minipass-pipeline", "npm:1.2.4"],\ - ["negotiator", "npm:0.6.3"],\ - ["promise-retry", "npm:2.0.1"],\ - ["socks-proxy-agent", "npm:6.2.0"],\ - ["ssri", "npm:9.0.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["mdn-data", [\ - ["npm:2.0.14", {\ - "packageLocation": "./.yarn/cache/mdn-data-npm-2.0.14-0acd669f0d-9d0128ed42.zip/node_modules/mdn-data/",\ - "packageDependencies": [\ - ["mdn-data", "npm:2.0.14"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["merge-stream", [\ - ["npm:2.0.0", {\ - "packageLocation": "./.yarn/cache/merge-stream-npm-2.0.0-2ac83efea5-6fa4dcc8d8.zip/node_modules/merge-stream/",\ - "packageDependencies": [\ - ["merge-stream", "npm:2.0.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["mime-db", [\ - ["npm:1.52.0", {\ - "packageLocation": "./.yarn/cache/mime-db-npm-1.52.0-b5371d6fd2-0d99a03585.zip/node_modules/mime-db/",\ - "packageDependencies": [\ - ["mime-db", "npm:1.52.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["mime-types", [\ - ["npm:2.1.35", {\ - "packageLocation": "./.yarn/cache/mime-types-npm-2.1.35-dd9ea9f3e2-89a5b7f1de.zip/node_modules/mime-types/",\ - "packageDependencies": [\ - ["mime-types", "npm:2.1.35"],\ - ["mime-db", "npm:1.52.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["mimic-fn", [\ - ["npm:2.1.0", {\ - "packageLocation": "./.yarn/cache/mimic-fn-npm-2.1.0-4fbeb3abb4-d2421a3444.zip/node_modules/mimic-fn/",\ - "packageDependencies": [\ - ["mimic-fn", "npm:2.1.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["minimatch", [\ - ["npm:3.1.2", {\ - "packageLocation": "./.yarn/cache/minimatch-npm-3.1.2-9405269906-c154e56640.zip/node_modules/minimatch/",\ - "packageDependencies": [\ - ["minimatch", "npm:3.1.2"],\ - ["brace-expansion", "npm:1.1.11"]\ - ],\ - "linkType": "HARD"\ - }],\ - ["npm:5.1.0", {\ - "packageLocation": "./.yarn/cache/minimatch-npm-5.1.0-34f6240621-15ce53d31a.zip/node_modules/minimatch/",\ - "packageDependencies": [\ - ["minimatch", "npm:5.1.0"],\ - ["brace-expansion", "npm:2.0.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["minimist", [\ - ["npm:1.2.6", {\ - "packageLocation": "./.yarn/cache/minimist-npm-1.2.6-f4cee4b4af-d15428cd1e.zip/node_modules/minimist/",\ - "packageDependencies": [\ - ["minimist", "npm:1.2.6"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["minipass", [\ - ["npm:3.1.6", {\ - "packageLocation": "./.yarn/cache/minipass-npm-3.1.6-f032df1661-57a0404141.zip/node_modules/minipass/",\ - "packageDependencies": [\ - ["minipass", "npm:3.1.6"],\ - ["yallist", "npm:4.0.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["minipass-collect", [\ - ["npm:1.0.2", {\ - "packageLocation": "./.yarn/cache/minipass-collect-npm-1.0.2-3b4676eab5-14df761028.zip/node_modules/minipass-collect/",\ - "packageDependencies": [\ - ["minipass-collect", "npm:1.0.2"],\ - ["minipass", "npm:3.1.6"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["minipass-fetch", [\ - ["npm:2.1.0", {\ - "packageLocation": "./.yarn/cache/minipass-fetch-npm-2.1.0-300ce55188-1334732859.zip/node_modules/minipass-fetch/",\ - "packageDependencies": [\ - ["minipass-fetch", "npm:2.1.0"],\ - ["encoding", "npm:0.1.13"],\ - ["minipass", "npm:3.1.6"],\ - ["minipass-sized", "npm:1.0.3"],\ - ["minizlib", "npm:2.1.2"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["minipass-flush", [\ - ["npm:1.0.5", {\ - "packageLocation": "./.yarn/cache/minipass-flush-npm-1.0.5-efe79d9826-56269a0b22.zip/node_modules/minipass-flush/",\ - "packageDependencies": [\ - ["minipass-flush", "npm:1.0.5"],\ - ["minipass", "npm:3.1.6"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["minipass-pipeline", [\ - ["npm:1.2.4", {\ - "packageLocation": "./.yarn/cache/minipass-pipeline-npm-1.2.4-5924cb077f-b14240dac0.zip/node_modules/minipass-pipeline/",\ - "packageDependencies": [\ - ["minipass-pipeline", "npm:1.2.4"],\ - ["minipass", "npm:3.1.6"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["minipass-sized", [\ - ["npm:1.0.3", {\ - "packageLocation": "./.yarn/cache/minipass-sized-npm-1.0.3-306d86f432-79076749fc.zip/node_modules/minipass-sized/",\ - "packageDependencies": [\ - ["minipass-sized", "npm:1.0.3"],\ - ["minipass", "npm:3.1.6"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["minizlib", [\ - ["npm:2.1.2", {\ - "packageLocation": "./.yarn/cache/minizlib-npm-2.1.2-ea89cd0cfb-f1fdeac0b0.zip/node_modules/minizlib/",\ - "packageDependencies": [\ - ["minizlib", "npm:2.1.2"],\ - ["minipass", "npm:3.1.6"],\ - ["yallist", "npm:4.0.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["mkdirp", [\ - ["npm:1.0.4", {\ - "packageLocation": "./.yarn/cache/mkdirp-npm-1.0.4-37f6ef56b9-a96865108c.zip/node_modules/mkdirp/",\ - "packageDependencies": [\ - ["mkdirp", "npm:1.0.4"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["moment", [\ - ["npm:2.29.3", {\ - "packageLocation": "./.yarn/cache/moment-npm-2.29.3-fe4ba99bae-2e780e36d9.zip/node_modules/moment/",\ - "packageDependencies": [\ - ["moment", "npm:2.29.3"]\ - ],\ - "linkType": "HARD"\ - }],\ - ["npm:2.29.4", {\ - "packageLocation": "./.yarn/cache/moment-npm-2.29.4-902943305d-0ec3f9c2bc.zip/node_modules/moment/",\ - "packageDependencies": [\ - ["moment", "npm:2.29.4"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["moment-timezone", [\ - ["npm:0.5.34", {\ - "packageLocation": "./.yarn/cache/moment-timezone-npm-0.5.34-e4fe2d01f6-12a1d3d52e.zip/node_modules/moment-timezone/",\ - "packageDependencies": [\ - ["moment-timezone", "npm:0.5.34"],\ - ["moment", "npm:2.29.3"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["ms", [\ - ["npm:2.0.0", {\ - "packageLocation": "./.yarn/cache/ms-npm-2.0.0-9e1101a471-0e6a22b8b7.zip/node_modules/ms/",\ - "packageDependencies": [\ - ["ms", "npm:2.0.0"]\ - ],\ - "linkType": "HARD"\ - }],\ - ["npm:2.1.2", {\ - "packageLocation": "./.yarn/cache/ms-npm-2.1.2-ec0c1512ff-673cdb2c31.zip/node_modules/ms/",\ - "packageDependencies": [\ - ["ms", "npm:2.1.2"]\ - ],\ - "linkType": "HARD"\ - }],\ - ["npm:2.1.3", {\ - "packageLocation": "./.yarn/cache/ms-npm-2.1.3-81ff3cfac1-aa92de6080.zip/node_modules/ms/",\ - "packageDependencies": [\ - ["ms", "npm:2.1.3"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["msgpackr", [\ - ["npm:1.6.0", {\ - "packageLocation": "./.yarn/cache/msgpackr-npm-1.6.0-de9303a46e-7f94acbe93.zip/node_modules/msgpackr/",\ - "packageDependencies": [\ - ["msgpackr", "npm:1.6.0"],\ - ["msgpackr-extract", "npm:2.0.2"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["msgpackr-extract", [\ - ["npm:2.0.2", {\ - "packageLocation": "./.yarn/unplugged/msgpackr-extract-npm-2.0.2-27402474ca/node_modules/msgpackr-extract/",\ - "packageDependencies": [\ - ["msgpackr-extract", "npm:2.0.2"],\ - ["@msgpackr-extract/msgpackr-extract-darwin-arm64", "npm:2.0.2"],\ - ["@msgpackr-extract/msgpackr-extract-darwin-x64", "npm:2.0.2"],\ - ["@msgpackr-extract/msgpackr-extract-linux-arm", "npm:2.0.2"],\ - ["@msgpackr-extract/msgpackr-extract-linux-arm64", "npm:2.0.2"],\ - ["@msgpackr-extract/msgpackr-extract-linux-x64", "npm:2.0.2"],\ - ["@msgpackr-extract/msgpackr-extract-win32-x64", "npm:2.0.2"],\ - ["node-gyp", "npm:9.0.0"],\ - ["node-gyp-build-optional-packages", "npm:5.0.2"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["murmurhash-js", [\ - ["npm:1.0.0", {\ - "packageLocation": "./.yarn/cache/murmurhash-js-npm-1.0.0-b1fa804bc0-083cea92a1.zip/node_modules/murmurhash-js/",\ - "packageDependencies": [\ - ["murmurhash-js", "npm:1.0.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["naive-ui", [\ - ["npm:2.31.0", {\ - "packageLocation": "./.yarn/cache/naive-ui-npm-2.31.0-99dec18d2b-7194b4a814.zip/node_modules/naive-ui/",\ - "packageDependencies": [\ - ["naive-ui", "npm:2.31.0"]\ - ],\ - "linkType": "SOFT"\ - }],\ - ["virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:2.31.0", {\ - "packageLocation": "./.yarn/__virtual__/naive-ui-virtual-9f096c2330/0/cache/naive-ui-npm-2.31.0-99dec18d2b-7194b4a814.zip/node_modules/naive-ui/",\ - "packageDependencies": [\ - ["naive-ui", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:2.31.0"],\ - ["@css-render/plugin-bem", "virtual:9f096c233074b200486016c951159c23194337e7c7d59a71ca2c42d04bf345037b52ab329d71315b0e0d2a9be58321dfafc718b2bc37ea4bde4e8e682754a169#npm:0.15.10"],\ - ["@css-render/vue3-ssr", "virtual:9f096c233074b200486016c951159c23194337e7c7d59a71ca2c42d04bf345037b52ab329d71315b0e0d2a9be58321dfafc718b2bc37ea4bde4e8e682754a169#npm:0.15.10"],\ - ["@types/lodash", "npm:4.14.182"],\ - ["@types/lodash-es", "npm:4.17.6"],\ - ["@types/vue", null],\ - ["async-validator", "npm:4.1.1"],\ - ["css-render", "npm:0.15.10"],\ - ["date-fns", "npm:2.28.0"],\ - ["date-fns-tz", "virtual:9f096c233074b200486016c951159c23194337e7c7d59a71ca2c42d04bf345037b52ab329d71315b0e0d2a9be58321dfafc718b2bc37ea4bde4e8e682754a169#npm:1.3.3"],\ - ["evtd", "npm:0.2.3"],\ - ["highlight.js", "npm:11.5.1"],\ - ["lodash", "npm:4.17.21"],\ - ["lodash-es", "npm:4.17.21"],\ - ["seemly", "npm:0.3.4"],\ - ["treemate", "npm:0.3.11"],\ - ["vdirs", "virtual:9f096c233074b200486016c951159c23194337e7c7d59a71ca2c42d04bf345037b52ab329d71315b0e0d2a9be58321dfafc718b2bc37ea4bde4e8e682754a169#npm:0.1.8"],\ - ["vooks", "virtual:9f096c233074b200486016c951159c23194337e7c7d59a71ca2c42d04bf345037b52ab329d71315b0e0d2a9be58321dfafc718b2bc37ea4bde4e8e682754a169#npm:0.2.12"],\ - ["vue", "npm:3.2.37"],\ - ["vueuc", "virtual:9f096c233074b200486016c951159c23194337e7c7d59a71ca2c42d04bf345037b52ab329d71315b0e0d2a9be58321dfafc718b2bc37ea4bde4e8e682754a169#npm:0.4.47"]\ - ],\ - "packagePeers": [\ - "@types/vue",\ - "vue"\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["nanoid", [\ - ["npm:3.3.3", {\ - "packageLocation": "./.yarn/cache/nanoid-npm-3.3.3-25d865be84-ada019402a.zip/node_modules/nanoid/",\ - "packageDependencies": [\ - ["nanoid", "npm:3.3.3"]\ - ],\ - "linkType": "HARD"\ - }],\ - ["npm:3.3.4", {\ - "packageLocation": "./.yarn/cache/nanoid-npm-3.3.4-3d250377d6-2fddd6dee9.zip/node_modules/nanoid/",\ - "packageDependencies": [\ - ["nanoid", "npm:3.3.4"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["natural-compare", [\ - ["npm:1.4.0", {\ - "packageLocation": "./.yarn/cache/natural-compare-npm-1.4.0-97b75b362d-23ad088b08.zip/node_modules/natural-compare/",\ - "packageDependencies": [\ - ["natural-compare", "npm:1.4.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["negotiator", [\ - ["npm:0.6.3", {\ - "packageLocation": "./.yarn/cache/negotiator-npm-0.6.3-9d50e36171-b8ffeb1e26.zip/node_modules/negotiator/",\ - "packageDependencies": [\ - ["negotiator", "npm:0.6.3"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["node-addon-api", [\ - ["npm:3.2.1", {\ - "packageLocation": "./.yarn/unplugged/node-addon-api-npm-3.2.1-a29528f81d/node_modules/node-addon-api/",\ - "packageDependencies": [\ - ["node-addon-api", "npm:3.2.1"],\ - ["node-gyp", "npm:9.0.0"]\ - ],\ - "linkType": "HARD"\ - }],\ - ["npm:4.3.0", {\ - "packageLocation": "./.yarn/unplugged/node-addon-api-npm-4.3.0-a07a1232df/node_modules/node-addon-api/",\ - "packageDependencies": [\ - ["node-addon-api", "npm:4.3.0"],\ - ["node-gyp", "npm:9.0.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["node-gyp", [\ - ["npm:9.0.0", {\ - "packageLocation": "./.yarn/unplugged/node-gyp-npm-9.0.0-0eccfca4d1/node_modules/node-gyp/",\ - "packageDependencies": [\ - ["node-gyp", "npm:9.0.0"],\ - ["env-paths", "npm:2.2.1"],\ - ["glob", "npm:7.2.3"],\ - ["graceful-fs", "npm:4.2.10"],\ - ["make-fetch-happen", "npm:10.1.5"],\ - ["nopt", "npm:5.0.0"],\ - ["npmlog", "npm:6.0.2"],\ - ["rimraf", "npm:3.0.2"],\ - ["semver", "npm:7.3.7"],\ - ["tar", "npm:6.1.11"],\ - ["which", "npm:2.0.2"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["node-gyp-build", [\ - ["npm:4.4.0", {\ - "packageLocation": "./.yarn/cache/node-gyp-build-npm-4.4.0-d95e1857d1-972a059f96.zip/node_modules/node-gyp-build/",\ - "packageDependencies": [\ - ["node-gyp-build", "npm:4.4.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["node-gyp-build-optional-packages", [\ - ["npm:5.0.2", {\ - "packageLocation": "./.yarn/cache/node-gyp-build-optional-packages-npm-5.0.2-2917525a31-6fca33cd1e.zip/node_modules/node-gyp-build-optional-packages/",\ - "packageDependencies": [\ - ["node-gyp-build-optional-packages", "npm:5.0.2"]\ - ],\ - "linkType": "HARD"\ - }],\ - ["npm:5.0.3", {\ - "packageLocation": "./.yarn/cache/node-gyp-build-optional-packages-npm-5.0.3-50b9c76481-be3f023592.zip/node_modules/node-gyp-build-optional-packages/",\ - "packageDependencies": [\ - ["node-gyp-build-optional-packages", "npm:5.0.3"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["node-releases", [\ - ["npm:2.0.4", {\ - "packageLocation": "./.yarn/cache/node-releases-npm-2.0.4-7d25d174cd-b32d6c2032.zip/node_modules/node-releases/",\ - "packageDependencies": [\ - ["node-releases", "npm:2.0.4"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["nopt", [\ - ["npm:5.0.0", {\ - "packageLocation": "./.yarn/cache/nopt-npm-5.0.0-304b40fbfe-d35fdec187.zip/node_modules/nopt/",\ - "packageDependencies": [\ - ["nopt", "npm:5.0.0"],\ - ["abbrev", "npm:1.1.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["normalize-path", [\ - ["npm:3.0.0", {\ - "packageLocation": "./.yarn/cache/normalize-path-npm-3.0.0-658ba7d77f-88eeb4da89.zip/node_modules/normalize-path/",\ - "packageDependencies": [\ - ["normalize-path", "npm:3.0.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["npm-run-path", [\ - ["npm:4.0.1", {\ - "packageLocation": "./.yarn/cache/npm-run-path-npm-4.0.1-7aebd8bab3-5374c0cea4.zip/node_modules/npm-run-path/",\ - "packageDependencies": [\ - ["npm-run-path", "npm:4.0.1"],\ - ["path-key", "npm:3.1.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["npmlog", [\ - ["npm:6.0.2", {\ - "packageLocation": "./.yarn/cache/npmlog-npm-6.0.2-e0e69455c7-ae238cd264.zip/node_modules/npmlog/",\ - "packageDependencies": [\ - ["npmlog", "npm:6.0.2"],\ - ["are-we-there-yet", "npm:3.0.0"],\ - ["console-control-strings", "npm:1.1.0"],\ - ["gauge", "npm:4.0.4"],\ - ["set-blocking", "npm:2.0.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["nth-check", [\ - ["npm:2.1.1", {\ - "packageLocation": "./.yarn/cache/nth-check-npm-2.1.1-f97afc8169-5afc3dafcd.zip/node_modules/nth-check/",\ - "packageDependencies": [\ - ["nth-check", "npm:2.1.1"],\ - ["boolbase", "npm:1.0.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["nullthrows", [\ - ["npm:1.1.1", {\ - "packageLocation": "./.yarn/cache/nullthrows-npm-1.1.1-3d1f817134-10806b9212.zip/node_modules/nullthrows/",\ - "packageDependencies": [\ - ["nullthrows", "npm:1.1.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["object-assign", [\ - ["npm:4.1.1", {\ - "packageLocation": "./.yarn/cache/object-assign-npm-4.1.1-1004ad6dec-fcc6e4ea8c.zip/node_modules/object-assign/",\ - "packageDependencies": [\ - ["object-assign", "npm:4.1.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["object-inspect", [\ - ["npm:1.12.0", {\ - "packageLocation": "./.yarn/cache/object-inspect-npm-1.12.0-d064fa559a-2b36d4001a.zip/node_modules/object-inspect/",\ - "packageDependencies": [\ - ["object-inspect", "npm:1.12.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["object-keys", [\ - ["npm:1.1.1", {\ - "packageLocation": "./.yarn/cache/object-keys-npm-1.1.1-1bf2f1be93-b363c5e764.zip/node_modules/object-keys/",\ - "packageDependencies": [\ - ["object-keys", "npm:1.1.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["object.assign", [\ - ["npm:4.1.2", {\ - "packageLocation": "./.yarn/cache/object.assign-npm-4.1.2-d52edada1c-d621d832ed.zip/node_modules/object.assign/",\ - "packageDependencies": [\ - ["object.assign", "npm:4.1.2"],\ - ["call-bind", "npm:1.0.2"],\ - ["define-properties", "npm:1.1.4"],\ - ["has-symbols", "npm:1.0.3"],\ - ["object-keys", "npm:1.1.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["object.values", [\ - ["npm:1.1.5", {\ - "packageLocation": "./.yarn/cache/object.values-npm-1.1.5-f1de7f3742-0f17e99741.zip/node_modules/object.values/",\ - "packageDependencies": [\ - ["object.values", "npm:1.1.5"],\ - ["call-bind", "npm:1.0.2"],\ - ["define-properties", "npm:1.1.4"],\ - ["es-abstract", "npm:1.19.5"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["once", [\ - ["npm:1.4.0", {\ - "packageLocation": "./.yarn/cache/once-npm-1.4.0-ccf03ef07a-cd0a885013.zip/node_modules/once/",\ - "packageDependencies": [\ - ["once", "npm:1.4.0"],\ - ["wrappy", "npm:1.0.2"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["onetime", [\ - ["npm:5.1.2", {\ - "packageLocation": "./.yarn/cache/onetime-npm-5.1.2-3ed148fa42-2478859ef8.zip/node_modules/onetime/",\ - "packageDependencies": [\ - ["onetime", "npm:5.1.2"],\ - ["mimic-fn", "npm:2.1.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["optionator", [\ - ["npm:0.9.1", {\ - "packageLocation": "./.yarn/cache/optionator-npm-0.9.1-577e397aae-dbc6fa0656.zip/node_modules/optionator/",\ - "packageDependencies": [\ - ["optionator", "npm:0.9.1"],\ - ["deep-is", "npm:0.1.4"],\ - ["fast-levenshtein", "npm:2.0.6"],\ - ["levn", "npm:0.4.1"],\ - ["prelude-ls", "npm:1.2.1"],\ - ["type-check", "npm:0.4.0"],\ - ["word-wrap", "npm:1.2.3"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["ordered-binary", [\ - ["npm:1.2.5", {\ - "packageLocation": "./.yarn/cache/ordered-binary-npm-1.2.5-c6ab9248f9-fd0f1322a6.zip/node_modules/ordered-binary/",\ - "packageDependencies": [\ - ["ordered-binary", "npm:1.2.5"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["ospath", [\ - ["npm:1.2.2", {\ - "packageLocation": "./.yarn/cache/ospath-npm-1.2.2-c8f45523a8-505f48a4f4.zip/node_modules/ospath/",\ - "packageDependencies": [\ - ["ospath", "npm:1.2.2"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["p-limit", [\ - ["npm:1.3.0", {\ - "packageLocation": "./.yarn/cache/p-limit-npm-1.3.0-fdb471d864-281c1c0b8c.zip/node_modules/p-limit/",\ - "packageDependencies": [\ - ["p-limit", "npm:1.3.0"],\ - ["p-try", "npm:1.0.0"]\ - ],\ - "linkType": "HARD"\ - }],\ - ["npm:3.1.0", {\ - "packageLocation": "./.yarn/cache/p-limit-npm-3.1.0-05d2ede37f-7c3690c4db.zip/node_modules/p-limit/",\ - "packageDependencies": [\ - ["p-limit", "npm:3.1.0"],\ - ["yocto-queue", "npm:0.1.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["p-locate", [\ - ["npm:2.0.0", {\ - "packageLocation": "./.yarn/cache/p-locate-npm-2.0.0-3a2ee263dd-e2dceb9b49.zip/node_modules/p-locate/",\ - "packageDependencies": [\ - ["p-locate", "npm:2.0.0"],\ - ["p-limit", "npm:1.3.0"]\ - ],\ - "linkType": "HARD"\ - }],\ - ["npm:5.0.0", {\ - "packageLocation": "./.yarn/cache/p-locate-npm-5.0.0-92cc7c7a3e-1623088f36.zip/node_modules/p-locate/",\ - "packageDependencies": [\ - ["p-locate", "npm:5.0.0"],\ - ["p-limit", "npm:3.1.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["p-map", [\ - ["npm:4.0.0", {\ - "packageLocation": "./.yarn/cache/p-map-npm-4.0.0-4677ae07c7-cb0ab21ec0.zip/node_modules/p-map/",\ - "packageDependencies": [\ - ["p-map", "npm:4.0.0"],\ - ["aggregate-error", "npm:3.1.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["p-try", [\ - ["npm:1.0.0", {\ - "packageLocation": "./.yarn/cache/p-try-npm-1.0.0-7373139e40-3b5303f77e.zip/node_modules/p-try/",\ - "packageDependencies": [\ - ["p-try", "npm:1.0.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["parcel", [\ - ["npm:2.6.2", {\ - "packageLocation": "./.yarn/cache/parcel-npm-2.6.2-91cd9ac49d-4c0de2d27a.zip/node_modules/parcel/",\ - "packageDependencies": [\ - ["parcel", "npm:2.6.2"]\ - ],\ - "linkType": "SOFT"\ - }],\ - ["virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:2.6.2", {\ - "packageLocation": "./.yarn/__virtual__/parcel-virtual-84b0bbf7cd/0/cache/parcel-npm-2.6.2-91cd9ac49d-4c0de2d27a.zip/node_modules/parcel/",\ - "packageDependencies": [\ - ["parcel", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:2.6.2"],\ - ["@parcel/config-default", "virtual:84b0bbf7cdbd64ba6288b0a2db70a23b27d744d0bbf8200bb4b5364e102414e474ed93cd3bc30c30f0b0610197107cf6b488ea300fecc519f56b3d8403250c31#npm:2.6.2"],\ - ["@parcel/core", "npm:2.6.2"],\ - ["@parcel/diagnostic", "npm:2.6.2"],\ - ["@parcel/events", "npm:2.6.2"],\ - ["@parcel/fs", "virtual:aa1797faca4a934b86d07dfa52e0db4db288b85fed415e745782ef9bd4bd39771970f9017a79cb7ed092d23d2539cea12a1cec949dfa0bb86e0fda2290caa70e#npm:2.6.2"],\ - ["@parcel/logger", "npm:2.6.2"],\ - ["@parcel/package-manager", "virtual:aa1797faca4a934b86d07dfa52e0db4db288b85fed415e745782ef9bd4bd39771970f9017a79cb7ed092d23d2539cea12a1cec949dfa0bb86e0fda2290caa70e#npm:2.6.2"],\ - ["@parcel/reporter-cli", "npm:2.6.2"],\ - ["@parcel/reporter-dev-server", "npm:2.6.2"],\ - ["@parcel/utils", "npm:2.6.2"],\ - ["@types/parcel__core", null],\ - ["chalk", "npm:4.1.2"],\ - ["commander", "npm:7.2.0"],\ - ["get-port", "npm:4.2.0"],\ - ["v8-compile-cache", "npm:2.3.0"]\ - ],\ - "packagePeers": [\ - "@types/parcel__core"\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["parent-module", [\ - ["npm:1.0.1", {\ - "packageLocation": "./.yarn/cache/parent-module-npm-1.0.1-1fae11b095-6ba8b25514.zip/node_modules/parent-module/",\ - "packageDependencies": [\ - ["parent-module", "npm:1.0.1"],\ - ["callsites", "npm:3.1.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["parse-json", [\ - ["npm:5.2.0", {\ - "packageLocation": "./.yarn/cache/parse-json-npm-5.2.0-00a63b1199-62085b17d6.zip/node_modules/parse-json/",\ - "packageDependencies": [\ - ["parse-json", "npm:5.2.0"],\ - ["@babel/code-frame", "npm:7.16.7"],\ - ["error-ex", "npm:1.3.2"],\ - ["json-parse-even-better-errors", "npm:2.3.1"],\ - ["lines-and-columns", "npm:1.2.4"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["path-exists", [\ - ["npm:3.0.0", {\ - "packageLocation": "./.yarn/cache/path-exists-npm-3.0.0-e80371aa68-96e92643aa.zip/node_modules/path-exists/",\ - "packageDependencies": [\ - ["path-exists", "npm:3.0.0"]\ - ],\ - "linkType": "HARD"\ - }],\ - ["npm:4.0.0", {\ - "packageLocation": "./.yarn/cache/path-exists-npm-4.0.0-e9e4f63eb0-505807199d.zip/node_modules/path-exists/",\ - "packageDependencies": [\ - ["path-exists", "npm:4.0.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["path-is-absolute", [\ - ["npm:1.0.1", {\ - "packageLocation": "./.yarn/cache/path-is-absolute-npm-1.0.1-31bc695ffd-060840f92c.zip/node_modules/path-is-absolute/",\ - "packageDependencies": [\ - ["path-is-absolute", "npm:1.0.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["path-key", [\ - ["npm:3.1.1", {\ - "packageLocation": "./.yarn/cache/path-key-npm-3.1.1-0e66ea8321-55cd7a9dd4.zip/node_modules/path-key/",\ - "packageDependencies": [\ - ["path-key", "npm:3.1.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["path-parse", [\ - ["npm:1.0.7", {\ - "packageLocation": "./.yarn/cache/path-parse-npm-1.0.7-09564527b7-49abf3d811.zip/node_modules/path-parse/",\ - "packageDependencies": [\ - ["path-parse", "npm:1.0.7"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["path-type", [\ - ["npm:4.0.0", {\ - "packageLocation": "./.yarn/cache/path-type-npm-4.0.0-10d47fc86a-5b1e2daa24.zip/node_modules/path-type/",\ - "packageDependencies": [\ - ["path-type", "npm:4.0.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["pathval", [\ - ["npm:1.1.1", {\ - "packageLocation": "./.yarn/cache/pathval-npm-1.1.1-ce0311d7e0-090e314771.zip/node_modules/pathval/",\ - "packageDependencies": [\ - ["pathval", "npm:1.1.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["pend", [\ - ["npm:1.2.0", {\ - "packageLocation": "./.yarn/cache/pend-npm-1.2.0-7a13d93266-6c72f52433.zip/node_modules/pend/",\ - "packageDependencies": [\ - ["pend", "npm:1.2.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["performance-now", [\ - ["npm:2.1.0", {\ - "packageLocation": "./.yarn/cache/performance-now-npm-2.1.0-45e3ce7e49-534e641aa8.zip/node_modules/performance-now/",\ - "packageDependencies": [\ - ["performance-now", "npm:2.1.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["picocolors", [\ - ["npm:1.0.0", {\ - "packageLocation": "./.yarn/cache/picocolors-npm-1.0.0-d81e0b1927-a2e8092dd8.zip/node_modules/picocolors/",\ - "packageDependencies": [\ - ["picocolors", "npm:1.0.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["picomatch", [\ - ["npm:2.3.1", {\ - "packageLocation": "./.yarn/cache/picomatch-npm-2.3.1-c782cfd986-050c865ce8.zip/node_modules/picomatch/",\ - "packageDependencies": [\ - ["picomatch", "npm:2.3.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["pify", [\ - ["npm:2.3.0", {\ - "packageLocation": "./.yarn/cache/pify-npm-2.3.0-8b63310934-9503aaeaf4.zip/node_modules/pify/",\ - "packageDependencies": [\ - ["pify", "npm:2.3.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["pinia", [\ - ["npm:2.0.16", {\ - "packageLocation": "./.yarn/cache/pinia-npm-2.0.16-5cedac4949-226aaf57a8.zip/node_modules/pinia/",\ - "packageDependencies": [\ - ["pinia", "npm:2.0.16"]\ - ],\ - "linkType": "SOFT"\ - }],\ - ["virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:2.0.16", {\ - "packageLocation": "./.yarn/__virtual__/pinia-virtual-5ab4c103d6/0/cache/pinia-npm-2.0.16-5cedac4949-226aaf57a8.zip/node_modules/pinia/",\ - "packageDependencies": [\ - ["pinia", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:2.0.16"],\ - ["@types/typescript", null],\ - ["@types/vue", null],\ - ["@types/vue__composition-api", null],\ - ["@vue/composition-api", null],\ - ["@vue/devtools-api", "npm:6.1.4"],\ - ["typescript", null],\ - ["vue", "npm:3.2.37"],\ - ["vue-demi", "virtual:5ab4c103d6244530b5b0e205eaa53ec3e9ba3fb62183d05dc99cae2b048234bb8882fd551ea98b3988ff38ddb73c47e86ce5761c9ada2a778cfb0ca0b86c74e5#npm:0.13.1"]\ - ],\ - "packagePeers": [\ - "@types/typescript",\ - "@types/vue",\ - "@types/vue__composition-api",\ - "@vue/composition-api",\ - "typescript",\ - "vue"\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["pinia-plugin-persist", [\ - ["npm:1.0.0", {\ - "packageLocation": "./.yarn/cache/pinia-plugin-persist-npm-1.0.0-b6b3a94cc9-49335d7207.zip/node_modules/pinia-plugin-persist/",\ - "packageDependencies": [\ - ["pinia-plugin-persist", "npm:1.0.0"]\ - ],\ - "linkType": "SOFT"\ - }],\ - ["virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:1.0.0", {\ - "packageLocation": "./.yarn/__virtual__/pinia-plugin-persist-virtual-f56fcf19bb/0/cache/pinia-plugin-persist-npm-1.0.0-b6b3a94cc9-49335d7207.zip/node_modules/pinia-plugin-persist/",\ - "packageDependencies": [\ - ["pinia-plugin-persist", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:1.0.0"],\ - ["@types/pinia", null],\ - ["@types/vue", null],\ - ["@types/vue__composition-api", null],\ - ["@vue/composition-api", null],\ - ["pinia", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:2.0.16"],\ - ["vue", "npm:3.2.37"],\ - ["vue-demi", "virtual:f56fcf19bbebc2ada1b28955da8cc216b1e9a569a1a7337d2d1926c1ebd1bc7a5bd91aedae1d05c15c8562f33caf7c59bd3020a667340f6bdc6a7b13fc2ba847#npm:0.12.5"]\ - ],\ - "packagePeers": [\ - "@types/pinia",\ - "@types/vue",\ - "@types/vue__composition-api",\ - "@vue/composition-api",\ - "pinia",\ - "vue"\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["postcss", [\ - ["npm:8.4.12", {\ - "packageLocation": "./.yarn/cache/postcss-npm-8.4.12-e941d78a98-248e3d0f9b.zip/node_modules/postcss/",\ - "packageDependencies": [\ - ["postcss", "npm:8.4.12"],\ - ["nanoid", "npm:3.3.3"],\ - ["picocolors", "npm:1.0.0"],\ - ["source-map-js", "npm:1.0.2"]\ - ],\ - "linkType": "HARD"\ - }],\ - ["npm:8.4.14", {\ - "packageLocation": "./.yarn/cache/postcss-npm-8.4.14-c0d448b728-fe58766ff3.zip/node_modules/postcss/",\ - "packageDependencies": [\ - ["postcss", "npm:8.4.14"],\ - ["nanoid", "npm:3.3.4"],\ - ["picocolors", "npm:1.0.0"],\ - ["source-map-js", "npm:1.0.2"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["postcss-selector-parser", [\ - ["npm:6.0.10", {\ - "packageLocation": "./.yarn/cache/postcss-selector-parser-npm-6.0.10-a4d7aaa270-46afaa60e3.zip/node_modules/postcss-selector-parser/",\ - "packageDependencies": [\ - ["postcss-selector-parser", "npm:6.0.10"],\ - ["cssesc", "npm:3.0.0"],\ - ["util-deprecate", "npm:1.0.2"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["postcss-value-parser", [\ - ["npm:4.2.0", {\ - "packageLocation": "./.yarn/cache/postcss-value-parser-npm-4.2.0-3cef602a6a-819ffab0c9.zip/node_modules/postcss-value-parser/",\ - "packageDependencies": [\ - ["postcss-value-parser", "npm:4.2.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["posthtml", [\ - ["npm:0.16.6", {\ - "packageLocation": "./.yarn/cache/posthtml-npm-0.16.6-c3387f43c9-8b9b9d27bd.zip/node_modules/posthtml/",\ - "packageDependencies": [\ - ["posthtml", "npm:0.16.6"],\ - ["posthtml-parser", "npm:0.11.0"],\ - ["posthtml-render", "npm:3.0.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["posthtml-parser", [\ - ["npm:0.10.2", {\ - "packageLocation": "./.yarn/cache/posthtml-parser-npm-0.10.2-f553bc0146-63ec8e8631.zip/node_modules/posthtml-parser/",\ - "packageDependencies": [\ - ["posthtml-parser", "npm:0.10.2"],\ - ["htmlparser2", "npm:7.2.0"]\ - ],\ - "linkType": "HARD"\ - }],\ - ["npm:0.11.0", {\ - "packageLocation": "./.yarn/cache/posthtml-parser-npm-0.11.0-88a39d3d19-37dca546a0.zip/node_modules/posthtml-parser/",\ - "packageDependencies": [\ - ["posthtml-parser", "npm:0.11.0"],\ - ["htmlparser2", "npm:7.2.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["posthtml-render", [\ - ["npm:3.0.0", {\ - "packageLocation": "./.yarn/cache/posthtml-render-npm-3.0.0-7d46185567-5ed2d6e881.zip/node_modules/posthtml-render/",\ - "packageDependencies": [\ - ["posthtml-render", "npm:3.0.0"],\ - ["is-json", "npm:2.0.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["preact", [\ - ["npm:10.7.2", {\ - "packageLocation": "./.yarn/cache/preact-npm-10.7.2-dffb68bd4b-2f0655e043.zip/node_modules/preact/",\ - "packageDependencies": [\ - ["preact", "npm:10.7.2"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["prelude-ls", [\ - ["npm:1.2.1", {\ - "packageLocation": "./.yarn/cache/prelude-ls-npm-1.2.1-3e4d272a55-cd192ec0d0.zip/node_modules/prelude-ls/",\ - "packageDependencies": [\ - ["prelude-ls", "npm:1.2.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["pretty-bytes", [\ - ["npm:5.6.0", {\ - "packageLocation": "./.yarn/cache/pretty-bytes-npm-5.6.0-0061079c9f-9c082500d1.zip/node_modules/pretty-bytes/",\ - "packageDependencies": [\ - ["pretty-bytes", "npm:5.6.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["pretty-format", [\ - ["npm:27.5.1", {\ - "packageLocation": "./.yarn/cache/pretty-format-npm-27.5.1-cd7d49696f-cf610cffcb.zip/node_modules/pretty-format/",\ - "packageDependencies": [\ - ["pretty-format", "npm:27.5.1"],\ - ["ansi-regex", "npm:5.0.1"],\ - ["ansi-styles", "npm:5.2.0"],\ - ["react-is", "npm:17.0.2"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["promise", [\ - ["npm:7.3.1", {\ - "packageLocation": "./.yarn/cache/promise-npm-7.3.1-5d81d474c0-475bb06913.zip/node_modules/promise/",\ - "packageDependencies": [\ - ["promise", "npm:7.3.1"],\ - ["asap", "npm:2.0.6"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["promise-inflight", [\ - ["npm:1.0.1", {\ - "packageLocation": "./.yarn/cache/promise-inflight-npm-1.0.1-5bb925afac-2274948309.zip/node_modules/promise-inflight/",\ - "packageDependencies": [\ - ["promise-inflight", "npm:1.0.1"]\ - ],\ - "linkType": "SOFT"\ - }],\ - ["virtual:e24d9a7d5bfafeb0e9feff2818e85407e1cf44a276d18b9ca6dfb49cddb2524392de2fcf443eda17f1ea0d182e400e896df3142d004a89f718873309f2bace8e#npm:1.0.1", {\ - "packageLocation": "./.yarn/__virtual__/promise-inflight-virtual-8305051473/0/cache/promise-inflight-npm-1.0.1-5bb925afac-2274948309.zip/node_modules/promise-inflight/",\ - "packageDependencies": [\ - ["promise-inflight", "virtual:e24d9a7d5bfafeb0e9feff2818e85407e1cf44a276d18b9ca6dfb49cddb2524392de2fcf443eda17f1ea0d182e400e896df3142d004a89f718873309f2bace8e#npm:1.0.1"],\ - ["@types/bluebird", null],\ - ["bluebird", null]\ - ],\ - "packagePeers": [\ - "@types/bluebird",\ - "bluebird"\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["promise-retry", [\ - ["npm:2.0.1", {\ - "packageLocation": "./.yarn/cache/promise-retry-npm-2.0.1-871f0b01b7-f96a3f6d90.zip/node_modules/promise-retry/",\ - "packageDependencies": [\ - ["promise-retry", "npm:2.0.1"],\ - ["err-code", "npm:2.0.3"],\ - ["retry", "npm:0.12.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["prompts", [\ - ["npm:2.4.2", {\ - "packageLocation": "./.yarn/cache/prompts-npm-2.4.2-f5d25d5eea-d8fd1fe638.zip/node_modules/prompts/",\ - "packageDependencies": [\ - ["prompts", "npm:2.4.2"],\ - ["kleur", "npm:3.0.3"],\ - ["sisteransi", "npm:1.0.5"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["proxy-from-env", [\ - ["npm:1.0.0", {\ - "packageLocation": "./.yarn/cache/proxy-from-env-npm-1.0.0-679b82b4ec-292e28d1de.zip/node_modules/proxy-from-env/",\ - "packageDependencies": [\ - ["proxy-from-env", "npm:1.0.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["psl", [\ - ["npm:1.8.0", {\ - "packageLocation": "./.yarn/cache/psl-npm-1.8.0-226099d70e-6150048ed2.zip/node_modules/psl/",\ - "packageDependencies": [\ - ["psl", "npm:1.8.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["pug", [\ - ["npm:3.0.2", {\ - "packageLocation": "./.yarn/cache/pug-npm-3.0.2-a900d45f03-3e1a3d4889.zip/node_modules/pug/",\ - "packageDependencies": [\ - ["pug", "npm:3.0.2"],\ - ["pug-code-gen", "npm:3.0.2"],\ - ["pug-filters", "npm:4.0.0"],\ - ["pug-lexer", "npm:5.0.1"],\ - ["pug-linker", "npm:4.0.0"],\ - ["pug-load", "npm:3.0.0"],\ - ["pug-parser", "npm:6.0.0"],\ - ["pug-runtime", "npm:3.0.1"],\ - ["pug-strip-comments", "npm:2.0.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["pug-attrs", [\ - ["npm:3.0.0", {\ - "packageLocation": "./.yarn/cache/pug-attrs-npm-3.0.0-31b331fe79-2ca2d34de3.zip/node_modules/pug-attrs/",\ - "packageDependencies": [\ - ["pug-attrs", "npm:3.0.0"],\ - ["constantinople", "npm:4.0.1"],\ - ["js-stringify", "npm:1.0.2"],\ - ["pug-runtime", "npm:3.0.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["pug-code-gen", [\ - ["npm:3.0.2", {\ - "packageLocation": "./.yarn/cache/pug-code-gen-npm-3.0.2-1cc7d40723-1644d3a4d6.zip/node_modules/pug-code-gen/",\ - "packageDependencies": [\ - ["pug-code-gen", "npm:3.0.2"],\ - ["constantinople", "npm:4.0.1"],\ - ["doctypes", "npm:1.1.0"],\ - ["js-stringify", "npm:1.0.2"],\ - ["pug-attrs", "npm:3.0.0"],\ - ["pug-error", "npm:2.0.0"],\ - ["pug-runtime", "npm:3.0.1"],\ - ["void-elements", "npm:3.1.0"],\ - ["with", "npm:7.0.2"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["pug-error", [\ - ["npm:2.0.0", {\ - "packageLocation": "./.yarn/cache/pug-error-npm-2.0.0-13b776f97b-c5372d018c.zip/node_modules/pug-error/",\ - "packageDependencies": [\ - ["pug-error", "npm:2.0.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["pug-filters", [\ - ["npm:4.0.0", {\ - "packageLocation": "./.yarn/cache/pug-filters-npm-4.0.0-d2cf0196e7-44eb327319.zip/node_modules/pug-filters/",\ - "packageDependencies": [\ - ["pug-filters", "npm:4.0.0"],\ - ["constantinople", "npm:4.0.1"],\ - ["jstransformer", "npm:1.0.0"],\ - ["pug-error", "npm:2.0.0"],\ - ["pug-walk", "npm:2.0.0"],\ - ["resolve", "patch:resolve@npm%3A1.22.0#~builtin::version=1.22.0&hash=07638b"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["pug-lexer", [\ - ["npm:5.0.1", {\ - "packageLocation": "./.yarn/cache/pug-lexer-npm-5.0.1-3bdff5fe60-afdd2f43f2.zip/node_modules/pug-lexer/",\ - "packageDependencies": [\ - ["pug-lexer", "npm:5.0.1"],\ - ["character-parser", "npm:2.2.0"],\ - ["is-expression", "npm:4.0.0"],\ - ["pug-error", "npm:2.0.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["pug-linker", [\ - ["npm:4.0.0", {\ - "packageLocation": "./.yarn/cache/pug-linker-npm-4.0.0-b140c7e607-7433aa6518.zip/node_modules/pug-linker/",\ - "packageDependencies": [\ - ["pug-linker", "npm:4.0.0"],\ - ["pug-error", "npm:2.0.0"],\ - ["pug-walk", "npm:2.0.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["pug-load", [\ - ["npm:3.0.0", {\ - "packageLocation": "./.yarn/cache/pug-load-npm-3.0.0-dc9f2273d3-1800ec5199.zip/node_modules/pug-load/",\ - "packageDependencies": [\ - ["pug-load", "npm:3.0.0"],\ - ["object-assign", "npm:4.1.1"],\ - ["pug-walk", "npm:2.0.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["pug-parser", [\ - ["npm:6.0.0", {\ - "packageLocation": "./.yarn/cache/pug-parser-npm-6.0.0-87b7dc8a83-a6954d1383.zip/node_modules/pug-parser/",\ - "packageDependencies": [\ - ["pug-parser", "npm:6.0.0"],\ - ["pug-error", "npm:2.0.0"],\ - ["token-stream", "npm:1.0.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["pug-runtime", [\ - ["npm:3.0.1", {\ - "packageLocation": "./.yarn/cache/pug-runtime-npm-3.0.1-13038c62ae-48a71b587c.zip/node_modules/pug-runtime/",\ - "packageDependencies": [\ - ["pug-runtime", "npm:3.0.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["pug-strip-comments", [\ - ["npm:2.0.0", {\ - "packageLocation": "./.yarn/cache/pug-strip-comments-npm-2.0.0-7baa7bca2f-2cfcbf506c.zip/node_modules/pug-strip-comments/",\ - "packageDependencies": [\ - ["pug-strip-comments", "npm:2.0.0"],\ - ["pug-error", "npm:2.0.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["pug-walk", [\ - ["npm:2.0.0", {\ - "packageLocation": "./.yarn/cache/pug-walk-npm-2.0.0-a8a11880fc-bee64e133b.zip/node_modules/pug-walk/",\ - "packageDependencies": [\ - ["pug-walk", "npm:2.0.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["pump", [\ - ["npm:3.0.0", {\ - "packageLocation": "./.yarn/cache/pump-npm-3.0.0-0080bf6a7a-e42e9229fb.zip/node_modules/pump/",\ - "packageDependencies": [\ - ["pump", "npm:3.0.0"],\ - ["end-of-stream", "npm:1.4.4"],\ - ["once", "npm:1.4.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["punycode", [\ - ["npm:2.1.1", {\ - "packageLocation": "./.yarn/cache/punycode-npm-2.1.1-26eb3e15cf-823bf443c6.zip/node_modules/punycode/",\ - "packageDependencies": [\ - ["punycode", "npm:2.1.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["qs", [\ - ["npm:6.5.3", {\ - "packageLocation": "./.yarn/cache/qs-npm-6.5.3-90b2635484-6f20bf08ca.zip/node_modules/qs/",\ - "packageDependencies": [\ - ["qs", "npm:6.5.3"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["react-error-overlay", [\ - ["npm:6.0.9", {\ - "packageLocation": "./.yarn/cache/react-error-overlay-npm-6.0.9-96e7e1e53a-695853bc88.zip/node_modules/react-error-overlay/",\ - "packageDependencies": [\ - ["react-error-overlay", "npm:6.0.9"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["react-is", [\ - ["npm:17.0.2", {\ - "packageLocation": "./.yarn/cache/react-is-npm-17.0.2-091bbb8db6-9d6d111d89.zip/node_modules/react-is/",\ - "packageDependencies": [\ - ["react-is", "npm:17.0.2"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["react-refresh", [\ - ["npm:0.9.0", {\ - "packageLocation": "./.yarn/cache/react-refresh-npm-0.9.0-02c61ee045-6440146176.zip/node_modules/react-refresh/",\ - "packageDependencies": [\ - ["react-refresh", "npm:0.9.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["readable-stream", [\ - ["npm:3.6.0", {\ - "packageLocation": "./.yarn/cache/readable-stream-npm-3.6.0-23a4a5eb56-d4ea81502d.zip/node_modules/readable-stream/",\ - "packageDependencies": [\ - ["readable-stream", "npm:3.6.0"],\ - ["inherits", "npm:2.0.4"],\ - ["string_decoder", "npm:1.3.0"],\ - ["util-deprecate", "npm:1.0.2"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["readdirp", [\ - ["npm:3.6.0", {\ - "packageLocation": "./.yarn/cache/readdirp-npm-3.6.0-f950cc74ab-1ced032e6e.zip/node_modules/readdirp/",\ - "packageDependencies": [\ - ["readdirp", "npm:3.6.0"],\ - ["picomatch", "npm:2.3.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["regenerator-runtime", [\ - ["npm:0.13.9", {\ - "packageLocation": "./.yarn/cache/regenerator-runtime-npm-0.13.9-6d02340eec-65ed455fe5.zip/node_modules/regenerator-runtime/",\ - "packageDependencies": [\ - ["regenerator-runtime", "npm:0.13.9"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["regexpp", [\ - ["npm:3.2.0", {\ - "packageLocation": "./.yarn/cache/regexpp-npm-3.2.0-2513f32cfc-a78dc5c715.zip/node_modules/regexpp/",\ - "packageDependencies": [\ - ["regexpp", "npm:3.2.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["request-progress", [\ - ["npm:3.0.0", {\ - "packageLocation": "./.yarn/cache/request-progress-npm-3.0.0-f79f1c9e67-6ea1761dcc.zip/node_modules/request-progress/",\ - "packageDependencies": [\ - ["request-progress", "npm:3.0.0"],\ - ["throttleit", "npm:1.0.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["require-directory", [\ - ["npm:2.1.1", {\ - "packageLocation": "./.yarn/cache/require-directory-npm-2.1.1-8608aee50b-fb47e70bf0.zip/node_modules/require-directory/",\ - "packageDependencies": [\ - ["require-directory", "npm:2.1.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["require-from-string", [\ - ["npm:2.0.2", {\ - "packageLocation": "./.yarn/cache/require-from-string-npm-2.0.2-8557e0db12-a03ef68954.zip/node_modules/require-from-string/",\ - "packageDependencies": [\ - ["require-from-string", "npm:2.0.2"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["resolve", [\ - ["patch:resolve@npm%3A1.22.0#~builtin::version=1.22.0&hash=07638b", {\ - "packageLocation": "./.yarn/cache/resolve-patch-bad885c6ea-c79ecaea36.zip/node_modules/resolve/",\ - "packageDependencies": [\ - ["resolve", "patch:resolve@npm%3A1.22.0#~builtin::version=1.22.0&hash=07638b"],\ - ["is-core-module", "npm:2.9.0"],\ - ["path-parse", "npm:1.0.7"],\ - ["supports-preserve-symlinks-flag", "npm:1.0.0"]\ - ],\ - "linkType": "HARD"\ - }],\ - ["patch:resolve@npm%3A1.22.1#~builtin::version=1.22.1&hash=07638b", {\ - "packageLocation": "./.yarn/cache/resolve-patch-46f9469d0d-5656f4d0be.zip/node_modules/resolve/",\ - "packageDependencies": [\ - ["resolve", "patch:resolve@npm%3A1.22.1#~builtin::version=1.22.1&hash=07638b"],\ - ["is-core-module", "npm:2.9.0"],\ - ["path-parse", "npm:1.0.7"],\ - ["supports-preserve-symlinks-flag", "npm:1.0.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["resolve-from", [\ - ["npm:4.0.0", {\ - "packageLocation": "./.yarn/cache/resolve-from-npm-4.0.0-f758ec21bf-f4ba0b8494.zip/node_modules/resolve-from/",\ - "packageDependencies": [\ - ["resolve-from", "npm:4.0.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["restore-cursor", [\ - ["npm:3.1.0", {\ - "packageLocation": "./.yarn/cache/restore-cursor-npm-3.1.0-52c5a4c98f-f877dd8741.zip/node_modules/restore-cursor/",\ - "packageDependencies": [\ - ["restore-cursor", "npm:3.1.0"],\ - ["onetime", "npm:5.1.2"],\ - ["signal-exit", "npm:3.0.7"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["retry", [\ - ["npm:0.12.0", {\ - "packageLocation": "./.yarn/cache/retry-npm-0.12.0-72ac7fb4cc-623bd7d2e5.zip/node_modules/retry/",\ - "packageDependencies": [\ - ["retry", "npm:0.12.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["rfdc", [\ - ["npm:1.3.0", {\ - "packageLocation": "./.yarn/cache/rfdc-npm-1.3.0-272f288ad8-fb2ba8512e.zip/node_modules/rfdc/",\ - "packageDependencies": [\ - ["rfdc", "npm:1.3.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["rimraf", [\ - ["npm:3.0.2", {\ - "packageLocation": "./.yarn/cache/rimraf-npm-3.0.2-2cb7dac69a-87f4164e39.zip/node_modules/rimraf/",\ - "packageDependencies": [\ - ["rimraf", "npm:3.0.2"],\ - ["glob", "npm:7.2.3"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["robust-predicates", [\ - ["npm:3.0.1", {\ - "packageLocation": "./.yarn/cache/robust-predicates-npm-3.0.1-550da1ca46-45e9de2df4.zip/node_modules/robust-predicates/",\ - "packageDependencies": [\ - ["robust-predicates", "npm:3.0.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["rollup", [\ - ["npm:2.75.3", {\ - "packageLocation": "./.yarn/cache/rollup-npm-2.75.3-7efa4583e0-ac33a2336d.zip/node_modules/rollup/",\ - "packageDependencies": [\ - ["rollup", "npm:2.75.3"],\ - ["fsevents", "patch:fsevents@npm%3A2.3.2#~builtin::version=2.3.2&hash=18f3a7"]\ - ],\ - "linkType": "HARD"\ - }],\ - ["npm:2.76.0", {\ - "packageLocation": "./.yarn/cache/rollup-npm-2.76.0-50edb80f3c-58293e1c63.zip/node_modules/rollup/",\ - "packageDependencies": [\ - ["rollup", "npm:2.76.0"],\ - ["fsevents", "patch:fsevents@npm%3A2.3.2#~builtin::version=2.3.2&hash=18f3a7"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["root-workspace-0b6124", [\ - ["workspace:.", {\ - "packageLocation": "./",\ - "packageDependencies": [\ - ["root-workspace-0b6124", "workspace:."],\ - ["@fullcalendar/bootstrap5", "npm:5.11.0"],\ - ["@fullcalendar/core", "npm:5.11.0"],\ - ["@fullcalendar/daygrid", "npm:5.11.0"],\ - ["@fullcalendar/interaction", "npm:5.11.0"],\ - ["@fullcalendar/list", "npm:5.11.0"],\ - ["@fullcalendar/luxon2", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:5.11.0"],\ - ["@fullcalendar/timegrid", "npm:5.11.0"],\ - ["@fullcalendar/vue3", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:5.11.1"],\ - ["@parcel/transformer-sass", "npm:2.6.2"],\ - ["@popperjs/core", "npm:2.11.5"],\ - ["@vitejs/plugin-vue", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:2.3.3"],\ - ["@vue/test-utils", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:2.0.2"],\ - ["bootstrap", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:5.2.0"],\ - ["bootstrap-icons", "npm:1.9.1"],\ - ["browser-fs-access", "npm:0.31.0"],\ - ["browserlist", "npm:1.0.1"],\ - ["c8", "npm:7.12.0"],\ - ["caniuse-lite", "npm:1.0.30001368"],\ - ["cypress", "npm:10.3.1"],\ - ["cypress-real-events", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:1.7.1"],\ - ["d3", "npm:7.6.1"],\ - ["eslint", "npm:8.20.0"],\ - ["eslint-config-standard", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:17.0.0"],\ - ["eslint-plugin-cypress", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:2.12.1"],\ - ["eslint-plugin-import", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:2.26.0"],\ - ["eslint-plugin-node", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:11.1.0"],\ - ["eslint-plugin-promise", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:6.0.0"],\ - ["eslint-plugin-vue", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:9.2.0"],\ - ["file-saver", "npm:2.0.5"],\ - ["highcharts", "npm:10.2.0"],\ - ["html-validate", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:7.1.2"],\ - ["jquery", "npm:3.6.0"],\ - ["jquery-migrate", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:3.4.0"],\ - ["jquery-ui-dist", "npm:1.13.1"],\ - ["js-cookie", "npm:3.0.1"],\ - ["list.js", "npm:2.3.1"],\ - ["lodash", "npm:4.17.21"],\ - ["luxon", "npm:3.0.1"],\ - ["moment", "npm:2.29.4"],\ - ["moment-timezone", "npm:0.5.34"],\ - ["murmurhash-js", "npm:1.0.0"],\ - ["naive-ui", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:2.31.0"],\ - ["parcel", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:2.6.2"],\ - ["pinia", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:2.0.16"],\ - ["pinia-plugin-persist", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:1.0.0"],\ - ["pug", "npm:3.0.2"],\ - ["sass", "npm:1.53.0"],\ - ["select2", "npm:4.1.0-rc.0"],\ - ["select2-bootstrap-5-theme", "npm:1.3.0"],\ - ["slugify", "npm:1.6.5"],\ - ["sortablejs", "npm:1.15.0"],\ - ["vite", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:2.9.14"],\ - ["vitest", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:0.18.1"],\ - ["vue", "npm:3.2.37"],\ - ["vue-router", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:4.1.2"],\ - ["zxcvbn", "npm:4.4.2"]\ - ],\ - "linkType": "SOFT"\ - }]\ - ]],\ - ["rw", [\ - ["npm:1.3.3", {\ - "packageLocation": "./.yarn/cache/rw-npm-1.3.3-2197930a8d-c20d82421f.zip/node_modules/rw/",\ - "packageDependencies": [\ - ["rw", "npm:1.3.3"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["rxjs", [\ - ["npm:7.5.5", {\ - "packageLocation": "./.yarn/cache/rxjs-npm-7.5.5-d0546b1ccb-e034f60805.zip/node_modules/rxjs/",\ - "packageDependencies": [\ - ["rxjs", "npm:7.5.5"],\ - ["tslib", "npm:2.4.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["safe-buffer", [\ - ["npm:5.1.2", {\ - "packageLocation": "./.yarn/cache/safe-buffer-npm-5.1.2-c27fedf6c4-f2f1f7943c.zip/node_modules/safe-buffer/",\ - "packageDependencies": [\ - ["safe-buffer", "npm:5.1.2"]\ - ],\ - "linkType": "HARD"\ - }],\ - ["npm:5.2.1", {\ - "packageLocation": "./.yarn/cache/safe-buffer-npm-5.2.1-3481c8aa9b-b99c4b41fd.zip/node_modules/safe-buffer/",\ - "packageDependencies": [\ - ["safe-buffer", "npm:5.2.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["safer-buffer", [\ - ["npm:2.1.2", {\ - "packageLocation": "./.yarn/cache/safer-buffer-npm-2.1.2-8d5c0b705e-cab8f25ae6.zip/node_modules/safer-buffer/",\ - "packageDependencies": [\ - ["safer-buffer", "npm:2.1.2"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["sass", [\ - ["npm:1.52.1", {\ - "packageLocation": "./.yarn/cache/sass-npm-1.52.1-7f0eb7e72c-a0508c88b1.zip/node_modules/sass/",\ - "packageDependencies": [\ - ["sass", "npm:1.52.1"],\ - ["chokidar", "npm:3.5.3"],\ - ["immutable", "npm:4.0.0"],\ - ["source-map-js", "npm:1.0.2"]\ - ],\ - "linkType": "HARD"\ - }],\ - ["npm:1.53.0", {\ - "packageLocation": "./.yarn/cache/sass-npm-1.53.0-84886439f0-4bcb0617d6.zip/node_modules/sass/",\ - "packageDependencies": [\ - ["sass", "npm:1.53.0"],\ - ["chokidar", "npm:3.5.3"],\ - ["immutable", "npm:4.0.0"],\ - ["source-map-js", "npm:1.0.2"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["seemly", [\ - ["npm:0.3.3", {\ - "packageLocation": "./.yarn/cache/seemly-npm-0.3.3-1df3254399-b6445553f8.zip/node_modules/seemly/",\ - "packageDependencies": [\ - ["seemly", "npm:0.3.3"],\ - ["@types/jest", "npm:27.4.1"]\ - ],\ - "linkType": "HARD"\ - }],\ - ["npm:0.3.4", {\ - "packageLocation": "./.yarn/cache/seemly-npm-0.3.4-2c676840e8-7b422b0d51.zip/node_modules/seemly/",\ - "packageDependencies": [\ - ["seemly", "npm:0.3.4"],\ - ["@types/jest", "npm:27.4.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["select2", [\ - ["npm:4.1.0-rc.0", {\ - "packageLocation": "./.yarn/cache/select2-npm-4.1.0-rc.0-4f6f223d12-c27cefc396.zip/node_modules/select2/",\ - "packageDependencies": [\ - ["select2", "npm:4.1.0-rc.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["select2-bootstrap-5-theme", [\ - ["npm:1.3.0", {\ - "packageLocation": "./.yarn/cache/select2-bootstrap-5-theme-npm-1.3.0-10122bfbcb-248a869835.zip/node_modules/select2-bootstrap-5-theme/",\ - "packageDependencies": [\ - ["select2-bootstrap-5-theme", "npm:1.3.0"],\ - ["@popperjs/core", "npm:2.11.5"],\ - ["bootstrap", "virtual:10122bfbcba1a448fa8cd209500287123cf7dd2abe325c6afac0050500c2a7843d4fa38428d3ef45d200d480f092839e6533b4c96c028b4d6e4e1d970111b151#npm:5.1.3"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["semver", [\ - ["npm:5.7.1", {\ - "packageLocation": "./.yarn/cache/semver-npm-5.7.1-40bcea106b-57fd0acfd0.zip/node_modules/semver/",\ - "packageDependencies": [\ - ["semver", "npm:5.7.1"]\ - ],\ - "linkType": "HARD"\ - }],\ - ["npm:6.3.0", {\ - "packageLocation": "./.yarn/cache/semver-npm-6.3.0-b3eace8bfd-1b26ecf6db.zip/node_modules/semver/",\ - "packageDependencies": [\ - ["semver", "npm:6.3.0"]\ - ],\ - "linkType": "HARD"\ - }],\ - ["npm:7.3.7", {\ - "packageLocation": "./.yarn/cache/semver-npm-7.3.7-3bfe704194-2fa3e87756.zip/node_modules/semver/",\ - "packageDependencies": [\ - ["semver", "npm:7.3.7"],\ - ["lru-cache", "npm:6.0.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["set-blocking", [\ - ["npm:2.0.0", {\ - "packageLocation": "./.yarn/cache/set-blocking-npm-2.0.0-49e2cffa24-6e65a05f7c.zip/node_modules/set-blocking/",\ - "packageDependencies": [\ - ["set-blocking", "npm:2.0.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["shebang-command", [\ - ["npm:2.0.0", {\ - "packageLocation": "./.yarn/cache/shebang-command-npm-2.0.0-eb2b01921d-6b52fe8727.zip/node_modules/shebang-command/",\ - "packageDependencies": [\ - ["shebang-command", "npm:2.0.0"],\ - ["shebang-regex", "npm:3.0.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["shebang-regex", [\ - ["npm:3.0.0", {\ - "packageLocation": "./.yarn/cache/shebang-regex-npm-3.0.0-899a0cd65e-1a2bcae50d.zip/node_modules/shebang-regex/",\ - "packageDependencies": [\ - ["shebang-regex", "npm:3.0.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["side-channel", [\ - ["npm:1.0.4", {\ - "packageLocation": "./.yarn/cache/side-channel-npm-1.0.4-e1f38b9e06-351e41b947.zip/node_modules/side-channel/",\ - "packageDependencies": [\ - ["side-channel", "npm:1.0.4"],\ - ["call-bind", "npm:1.0.2"],\ - ["get-intrinsic", "npm:1.1.1"],\ - ["object-inspect", "npm:1.12.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["signal-exit", [\ - ["npm:3.0.7", {\ - "packageLocation": "./.yarn/cache/signal-exit-npm-3.0.7-bd270458a3-a2f098f247.zip/node_modules/signal-exit/",\ - "packageDependencies": [\ - ["signal-exit", "npm:3.0.7"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["sisteransi", [\ - ["npm:1.0.5", {\ - "packageLocation": "./.yarn/cache/sisteransi-npm-1.0.5-af60cc0cfa-aba6438f46.zip/node_modules/sisteransi/",\ - "packageDependencies": [\ - ["sisteransi", "npm:1.0.5"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["slice-ansi", [\ - ["npm:3.0.0", {\ - "packageLocation": "./.yarn/cache/slice-ansi-npm-3.0.0-d9999864af-5ec6d022d1.zip/node_modules/slice-ansi/",\ - "packageDependencies": [\ - ["slice-ansi", "npm:3.0.0"],\ - ["ansi-styles", "npm:4.3.0"],\ - ["astral-regex", "npm:2.0.0"],\ - ["is-fullwidth-code-point", "npm:3.0.0"]\ - ],\ - "linkType": "HARD"\ - }],\ - ["npm:4.0.0", {\ - "packageLocation": "./.yarn/cache/slice-ansi-npm-4.0.0-6eeca1d10e-4a82d7f085.zip/node_modules/slice-ansi/",\ - "packageDependencies": [\ - ["slice-ansi", "npm:4.0.0"],\ - ["ansi-styles", "npm:4.3.0"],\ - ["astral-regex", "npm:2.0.0"],\ - ["is-fullwidth-code-point", "npm:3.0.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["slugify", [\ - ["npm:1.6.5", {\ - "packageLocation": "./.yarn/cache/slugify-npm-1.6.5-6db25d7016-a955a1b600.zip/node_modules/slugify/",\ - "packageDependencies": [\ - ["slugify", "npm:1.6.5"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["smart-buffer", [\ - ["npm:4.2.0", {\ - "packageLocation": "./.yarn/cache/smart-buffer-npm-4.2.0-5ac3f668bb-b5167a7142.zip/node_modules/smart-buffer/",\ - "packageDependencies": [\ - ["smart-buffer", "npm:4.2.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["socks", [\ - ["npm:2.6.2", {\ - "packageLocation": "./.yarn/cache/socks-npm-2.6.2-94c1dcb8b8-dd91942930.zip/node_modules/socks/",\ - "packageDependencies": [\ - ["socks", "npm:2.6.2"],\ - ["ip", "npm:1.1.8"],\ - ["smart-buffer", "npm:4.2.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["socks-proxy-agent", [\ - ["npm:6.2.0", {\ - "packageLocation": "./.yarn/cache/socks-proxy-agent-npm-6.2.0-9c332b84bc-6723fd64fb.zip/node_modules/socks-proxy-agent/",\ - "packageDependencies": [\ - ["socks-proxy-agent", "npm:6.2.0"],\ - ["agent-base", "npm:6.0.2"],\ - ["debug", "virtual:b86a9fb34323a98c6519528ed55faa0d9b44ca8879307c0b29aa384bde47ff59a7d0c9051b31246f14521dfb71ba3c5d6d0b35c29fffc17bf875aa6ad977d9e8#npm:4.3.4"],\ - ["socks", "npm:2.6.2"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["sortablejs", [\ - ["npm:1.15.0", {\ - "packageLocation": "./.yarn/cache/sortablejs-npm-1.15.0-f3a393abcc-bb82223a66.zip/node_modules/sortablejs/",\ - "packageDependencies": [\ - ["sortablejs", "npm:1.15.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["source-map", [\ - ["npm:0.6.1", {\ - "packageLocation": "./.yarn/cache/source-map-npm-0.6.1-1a3621db16-59ce8640cf.zip/node_modules/source-map/",\ - "packageDependencies": [\ - ["source-map", "npm:0.6.1"]\ - ],\ - "linkType": "HARD"\ - }],\ - ["npm:0.8.0-beta.0", {\ - "packageLocation": "./.yarn/cache/source-map-npm-0.8.0-beta.0-688a309e94-e94169be64.zip/node_modules/source-map/",\ - "packageDependencies": [\ - ["source-map", "npm:0.8.0-beta.0"],\ - ["whatwg-url", "npm:7.1.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["source-map-js", [\ - ["npm:1.0.2", {\ - "packageLocation": "./.yarn/cache/source-map-js-npm-1.0.2-ee4f9f9b30-c049a7fc4d.zip/node_modules/source-map-js/",\ - "packageDependencies": [\ - ["source-map-js", "npm:1.0.2"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["source-map-support", [\ - ["npm:0.5.21", {\ - "packageLocation": "./.yarn/cache/source-map-support-npm-0.5.21-09ca99e250-43e98d700d.zip/node_modules/source-map-support/",\ - "packageDependencies": [\ - ["source-map-support", "npm:0.5.21"],\ - ["buffer-from", "npm:1.1.2"],\ - ["source-map", "npm:0.6.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["sourcemap-codec", [\ - ["npm:1.4.8", {\ - "packageLocation": "./.yarn/cache/sourcemap-codec-npm-1.4.8-3a1a9e60b1-b57981c056.zip/node_modules/sourcemap-codec/",\ - "packageDependencies": [\ - ["sourcemap-codec", "npm:1.4.8"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["sshpk", [\ - ["npm:1.17.0", {\ - "packageLocation": "./.yarn/cache/sshpk-npm-1.17.0-95f17f597f-ba109f65c8.zip/node_modules/sshpk/",\ - "packageDependencies": [\ - ["sshpk", "npm:1.17.0"],\ - ["asn1", "npm:0.2.6"],\ - ["assert-plus", "npm:1.0.0"],\ - ["bcrypt-pbkdf", "npm:1.0.2"],\ - ["dashdash", "npm:1.14.1"],\ - ["ecc-jsbn", "npm:0.1.2"],\ - ["getpass", "npm:0.1.7"],\ - ["jsbn", "npm:0.1.1"],\ - ["safer-buffer", "npm:2.1.2"],\ - ["tweetnacl", "npm:0.14.5"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["ssri", [\ - ["npm:9.0.1", {\ - "packageLocation": "./.yarn/cache/ssri-npm-9.0.1-33ce27f4f8-fb58f5e46b.zip/node_modules/ssri/",\ - "packageDependencies": [\ - ["ssri", "npm:9.0.1"],\ - ["minipass", "npm:3.1.6"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["stable", [\ - ["npm:0.1.8", {\ - "packageLocation": "./.yarn/cache/stable-npm-0.1.8-feb4e06de8-2ff482bb10.zip/node_modules/stable/",\ - "packageDependencies": [\ - ["stable", "npm:0.1.8"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["string-natural-compare", [\ - ["npm:2.0.3", {\ - "packageLocation": "./.yarn/cache/string-natural-compare-npm-2.0.3-9ad7314e5b-e0f22bb0de.zip/node_modules/string-natural-compare/",\ - "packageDependencies": [\ - ["string-natural-compare", "npm:2.0.3"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["string-width", [\ - ["npm:4.2.3", {\ - "packageLocation": "./.yarn/cache/string-width-npm-4.2.3-2c27177bae-e52c10dc3f.zip/node_modules/string-width/",\ - "packageDependencies": [\ - ["string-width", "npm:4.2.3"],\ - ["emoji-regex", "npm:8.0.0"],\ - ["is-fullwidth-code-point", "npm:3.0.0"],\ - ["strip-ansi", "npm:6.0.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["string.prototype.trimend", [\ - ["npm:1.0.4", {\ - "packageLocation": "./.yarn/cache/string.prototype.trimend-npm-1.0.4-a656b8fe24-17e5aa45c3.zip/node_modules/string.prototype.trimend/",\ - "packageDependencies": [\ - ["string.prototype.trimend", "npm:1.0.4"],\ - ["call-bind", "npm:1.0.2"],\ - ["define-properties", "npm:1.1.4"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["string.prototype.trimstart", [\ - ["npm:1.0.4", {\ - "packageLocation": "./.yarn/cache/string.prototype.trimstart-npm-1.0.4-b31f5e7c85-3fb06818d3.zip/node_modules/string.prototype.trimstart/",\ - "packageDependencies": [\ - ["string.prototype.trimstart", "npm:1.0.4"],\ - ["call-bind", "npm:1.0.2"],\ - ["define-properties", "npm:1.1.4"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["string_decoder", [\ - ["npm:1.3.0", {\ - "packageLocation": "./.yarn/cache/string_decoder-npm-1.3.0-2422117fd0-8417646695.zip/node_modules/string_decoder/",\ - "packageDependencies": [\ - ["string_decoder", "npm:1.3.0"],\ - ["safe-buffer", "npm:5.2.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["strip-ansi", [\ - ["npm:6.0.1", {\ - "packageLocation": "./.yarn/cache/strip-ansi-npm-6.0.1-caddc7cb40-f3cd25890a.zip/node_modules/strip-ansi/",\ - "packageDependencies": [\ - ["strip-ansi", "npm:6.0.1"],\ - ["ansi-regex", "npm:5.0.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["strip-bom", [\ - ["npm:3.0.0", {\ - "packageLocation": "./.yarn/cache/strip-bom-npm-3.0.0-71e8f81ff9-8d50ff27b7.zip/node_modules/strip-bom/",\ - "packageDependencies": [\ - ["strip-bom", "npm:3.0.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["strip-final-newline", [\ - ["npm:2.0.0", {\ - "packageLocation": "./.yarn/cache/strip-final-newline-npm-2.0.0-340c4f7c66-69412b5e25.zip/node_modules/strip-final-newline/",\ - "packageDependencies": [\ - ["strip-final-newline", "npm:2.0.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["strip-json-comments", [\ - ["npm:3.1.1", {\ - "packageLocation": "./.yarn/cache/strip-json-comments-npm-3.1.1-dcb2324823-492f73e272.zip/node_modules/strip-json-comments/",\ - "packageDependencies": [\ - ["strip-json-comments", "npm:3.1.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["supports-color", [\ - ["npm:5.5.0", {\ - "packageLocation": "./.yarn/cache/supports-color-npm-5.5.0-183ac537bc-95f6f4ba5a.zip/node_modules/supports-color/",\ - "packageDependencies": [\ - ["supports-color", "npm:5.5.0"],\ - ["has-flag", "npm:3.0.0"]\ - ],\ - "linkType": "HARD"\ - }],\ - ["npm:7.2.0", {\ - "packageLocation": "./.yarn/cache/supports-color-npm-7.2.0-606bfcf7da-3dda818de0.zip/node_modules/supports-color/",\ - "packageDependencies": [\ - ["supports-color", "npm:7.2.0"],\ - ["has-flag", "npm:4.0.0"]\ - ],\ - "linkType": "HARD"\ - }],\ - ["npm:8.1.1", {\ - "packageLocation": "./.yarn/cache/supports-color-npm-8.1.1-289e937149-c052193a7e.zip/node_modules/supports-color/",\ - "packageDependencies": [\ - ["supports-color", "npm:8.1.1"],\ - ["has-flag", "npm:4.0.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["supports-preserve-symlinks-flag", [\ - ["npm:1.0.0", {\ - "packageLocation": "./.yarn/cache/supports-preserve-symlinks-flag-npm-1.0.0-f17c4d0028-53b1e247e6.zip/node_modules/supports-preserve-symlinks-flag/",\ - "packageDependencies": [\ - ["supports-preserve-symlinks-flag", "npm:1.0.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["svgo", [\ - ["npm:2.8.0", {\ - "packageLocation": "./.yarn/cache/svgo-npm-2.8.0-43b4f3debe-b92f71a854.zip/node_modules/svgo/",\ - "packageDependencies": [\ - ["svgo", "npm:2.8.0"],\ - ["@trysound/sax", "npm:0.2.0"],\ - ["commander", "npm:7.2.0"],\ - ["css-select", "npm:4.3.0"],\ - ["css-tree", "npm:1.1.3"],\ - ["csso", "npm:4.2.0"],\ - ["picocolors", "npm:1.0.0"],\ - ["stable", "npm:0.1.8"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["tar", [\ - ["npm:6.1.11", {\ - "packageLocation": "./.yarn/cache/tar-npm-6.1.11-e6ac3cba9c-a04c07bb9e.zip/node_modules/tar/",\ - "packageDependencies": [\ - ["tar", "npm:6.1.11"],\ - ["chownr", "npm:2.0.0"],\ - ["fs-minipass", "npm:2.1.0"],\ - ["minipass", "npm:3.1.6"],\ - ["minizlib", "npm:2.1.2"],\ - ["mkdirp", "npm:1.0.4"],\ - ["yallist", "npm:4.0.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["term-size", [\ - ["npm:2.2.1", {\ - "packageLocation": "./.yarn/unplugged/term-size-npm-2.2.1-77ce7141d0/node_modules/term-size/",\ - "packageDependencies": [\ - ["term-size", "npm:2.2.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["terser", [\ - ["npm:5.13.1", {\ - "packageLocation": "./.yarn/cache/terser-npm-5.13.1-c7df10bd07-0b1f5043cf.zip/node_modules/terser/",\ - "packageDependencies": [\ - ["terser", "npm:5.13.1"],\ - ["acorn", "npm:8.7.1"],\ - ["commander", "npm:2.20.3"],\ - ["source-map", "npm:0.8.0-beta.0"],\ - ["source-map-support", "npm:0.5.21"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["test-exclude", [\ - ["npm:6.0.0", {\ - "packageLocation": "./.yarn/cache/test-exclude-npm-6.0.0-3fb03d69df-3b34a3d771.zip/node_modules/test-exclude/",\ - "packageDependencies": [\ - ["test-exclude", "npm:6.0.0"],\ - ["@istanbuljs/schema", "npm:0.1.3"],\ - ["glob", "npm:7.2.3"],\ - ["minimatch", "npm:3.1.2"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["text-table", [\ - ["npm:0.2.0", {\ - "packageLocation": "./.yarn/cache/text-table-npm-0.2.0-d92a778b59-b6937a38c8.zip/node_modules/text-table/",\ - "packageDependencies": [\ - ["text-table", "npm:0.2.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["throttleit", [\ - ["npm:1.0.0", {\ - "packageLocation": "./.yarn/cache/throttleit-npm-1.0.0-6cbcfe7b7b-1b2db4d245.zip/node_modules/throttleit/",\ - "packageDependencies": [\ - ["throttleit", "npm:1.0.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["through", [\ - ["npm:2.3.8", {\ - "packageLocation": "./.yarn/cache/through-npm-2.3.8-df5f72a16e-a38c3e0598.zip/node_modules/through/",\ - "packageDependencies": [\ - ["through", "npm:2.3.8"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["timsort", [\ - ["npm:0.3.0", {\ - "packageLocation": "./.yarn/cache/timsort-npm-0.3.0-868a28166c-1a66cb897d.zip/node_modules/timsort/",\ - "packageDependencies": [\ - ["timsort", "npm:0.3.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["tinypool", [\ - ["npm:0.2.4", {\ - "packageLocation": "./.yarn/cache/tinypool-npm-0.2.4-1940a28d43-f050bd36c8.zip/node_modules/tinypool/",\ - "packageDependencies": [\ - ["tinypool", "npm:0.2.4"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["tinyspy", [\ - ["npm:1.0.0", {\ - "packageLocation": "./.yarn/cache/tinyspy-npm-1.0.0-6b0cbea3cc-f9a7cea406.zip/node_modules/tinyspy/",\ - "packageDependencies": [\ - ["tinyspy", "npm:1.0.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["tmp", [\ - ["npm:0.2.1", {\ - "packageLocation": "./.yarn/cache/tmp-npm-0.2.1-a9c8d9c0ca-8b12146541.zip/node_modules/tmp/",\ - "packageDependencies": [\ - ["tmp", "npm:0.2.1"],\ - ["rimraf", "npm:3.0.2"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["to-fast-properties", [\ - ["npm:2.0.0", {\ - "packageLocation": "./.yarn/cache/to-fast-properties-npm-2.0.0-0dc60cc481-be2de62fe5.zip/node_modules/to-fast-properties/",\ - "packageDependencies": [\ - ["to-fast-properties", "npm:2.0.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["to-regex-range", [\ - ["npm:5.0.1", {\ - "packageLocation": "./.yarn/cache/to-regex-range-npm-5.0.1-f1e8263b00-f76fa01b3d.zip/node_modules/to-regex-range/",\ - "packageDependencies": [\ - ["to-regex-range", "npm:5.0.1"],\ - ["is-number", "npm:7.0.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["token-stream", [\ - ["npm:1.0.0", {\ - "packageLocation": "./.yarn/cache/token-stream-npm-1.0.0-b6bc01bff8-e8adb56f31.zip/node_modules/token-stream/",\ - "packageDependencies": [\ - ["token-stream", "npm:1.0.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["tough-cookie", [\ - ["npm:2.5.0", {\ - "packageLocation": "./.yarn/cache/tough-cookie-npm-2.5.0-79a2fe43fe-16a8cd0902.zip/node_modules/tough-cookie/",\ - "packageDependencies": [\ - ["tough-cookie", "npm:2.5.0"],\ - ["psl", "npm:1.8.0"],\ - ["punycode", "npm:2.1.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["tr46", [\ - ["npm:1.0.1", {\ - "packageLocation": "./.yarn/cache/tr46-npm-1.0.1-9547f343a4-96d4ed46bc.zip/node_modules/tr46/",\ - "packageDependencies": [\ - ["tr46", "npm:1.0.1"],\ - ["punycode", "npm:2.1.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["treemate", [\ - ["npm:0.3.11", {\ - "packageLocation": "./.yarn/cache/treemate-npm-0.3.11-7be66c23fc-0c6ccbc6c5.zip/node_modules/treemate/",\ - "packageDependencies": [\ - ["treemate", "npm:0.3.11"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["tsconfig-paths", [\ - ["npm:3.14.1", {\ - "packageLocation": "./.yarn/cache/tsconfig-paths-npm-3.14.1-17a815b5c5-8afa01c673.zip/node_modules/tsconfig-paths/",\ - "packageDependencies": [\ - ["tsconfig-paths", "npm:3.14.1"],\ - ["@types/json5", "npm:0.0.29"],\ - ["json5", "npm:1.0.1"],\ - ["minimist", "npm:1.2.6"],\ - ["strip-bom", "npm:3.0.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["tslib", [\ - ["npm:2.4.0", {\ - "packageLocation": "./.yarn/cache/tslib-npm-2.4.0-9cb6dc5030-8c4aa6a3c5.zip/node_modules/tslib/",\ - "packageDependencies": [\ - ["tslib", "npm:2.4.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["tunnel-agent", [\ - ["npm:0.6.0", {\ - "packageLocation": "./.yarn/cache/tunnel-agent-npm-0.6.0-64345ab7eb-05f6510358.zip/node_modules/tunnel-agent/",\ - "packageDependencies": [\ - ["tunnel-agent", "npm:0.6.0"],\ - ["safe-buffer", "npm:5.2.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["tweetnacl", [\ - ["npm:0.14.5", {\ - "packageLocation": "./.yarn/cache/tweetnacl-npm-0.14.5-a3f766c0d1-6061daba17.zip/node_modules/tweetnacl/",\ - "packageDependencies": [\ - ["tweetnacl", "npm:0.14.5"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["type-check", [\ - ["npm:0.4.0", {\ - "packageLocation": "./.yarn/cache/type-check-npm-0.4.0-60565800ce-ec688ebfc9.zip/node_modules/type-check/",\ - "packageDependencies": [\ - ["type-check", "npm:0.4.0"],\ - ["prelude-ls", "npm:1.2.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["type-detect", [\ - ["npm:4.0.8", {\ - "packageLocation": "./.yarn/cache/type-detect-npm-4.0.8-8d8127b901-62b5628bff.zip/node_modules/type-detect/",\ - "packageDependencies": [\ - ["type-detect", "npm:4.0.8"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["type-fest", [\ - ["npm:0.20.2", {\ - "packageLocation": "./.yarn/cache/type-fest-npm-0.20.2-b36432617f-4fb3272df2.zip/node_modules/type-fest/",\ - "packageDependencies": [\ - ["type-fest", "npm:0.20.2"]\ - ],\ - "linkType": "HARD"\ - }],\ - ["npm:0.21.3", {\ - "packageLocation": "./.yarn/cache/type-fest-npm-0.21.3-5ff2a9c6fd-e6b32a3b38.zip/node_modules/type-fest/",\ - "packageDependencies": [\ - ["type-fest", "npm:0.21.3"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["unbox-primitive", [\ - ["npm:1.0.2", {\ - "packageLocation": "./.yarn/cache/unbox-primitive-npm-1.0.2-cb56a05066-b7a1cf5862.zip/node_modules/unbox-primitive/",\ - "packageDependencies": [\ - ["unbox-primitive", "npm:1.0.2"],\ - ["call-bind", "npm:1.0.2"],\ - ["has-bigints", "npm:1.0.2"],\ - ["has-symbols", "npm:1.0.3"],\ - ["which-boxed-primitive", "npm:1.0.2"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["unique-filename", [\ - ["npm:1.1.1", {\ - "packageLocation": "./.yarn/cache/unique-filename-npm-1.1.1-c885c5095b-cf4998c922.zip/node_modules/unique-filename/",\ - "packageDependencies": [\ - ["unique-filename", "npm:1.1.1"],\ - ["unique-slug", "npm:2.0.2"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["unique-slug", [\ - ["npm:2.0.2", {\ - "packageLocation": "./.yarn/cache/unique-slug-npm-2.0.2-f6ba1ddeb7-5b6876a645.zip/node_modules/unique-slug/",\ - "packageDependencies": [\ - ["unique-slug", "npm:2.0.2"],\ - ["imurmurhash", "npm:0.1.4"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["universalify", [\ - ["npm:2.0.0", {\ - "packageLocation": "./.yarn/cache/universalify-npm-2.0.0-03b8b418a8-2406a4edf4.zip/node_modules/universalify/",\ - "packageDependencies": [\ - ["universalify", "npm:2.0.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["untildify", [\ - ["npm:4.0.0", {\ - "packageLocation": "./.yarn/cache/untildify-npm-4.0.0-4a8b569825-39ced9c418.zip/node_modules/untildify/",\ - "packageDependencies": [\ - ["untildify", "npm:4.0.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["uri-js", [\ - ["npm:4.4.1", {\ - "packageLocation": "./.yarn/cache/uri-js-npm-4.4.1-66d11cbcaf-7167432de6.zip/node_modules/uri-js/",\ - "packageDependencies": [\ - ["uri-js", "npm:4.4.1"],\ - ["punycode", "npm:2.1.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["util-deprecate", [\ - ["npm:1.0.2", {\ - "packageLocation": "./.yarn/cache/util-deprecate-npm-1.0.2-e3fe1a219c-474acf1146.zip/node_modules/util-deprecate/",\ - "packageDependencies": [\ - ["util-deprecate", "npm:1.0.2"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["utility-types", [\ - ["npm:3.10.0", {\ - "packageLocation": "./.yarn/cache/utility-types-npm-3.10.0-747e7c6549-8f274415c6.zip/node_modules/utility-types/",\ - "packageDependencies": [\ - ["utility-types", "npm:3.10.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["uuid", [\ - ["npm:8.3.2", {\ - "packageLocation": "./.yarn/cache/uuid-npm-8.3.2-eca0baba53-5575a8a75c.zip/node_modules/uuid/",\ - "packageDependencies": [\ - ["uuid", "npm:8.3.2"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["v8-compile-cache", [\ - ["npm:2.3.0", {\ - "packageLocation": "./.yarn/cache/v8-compile-cache-npm-2.3.0-961375f150-adb0a271ea.zip/node_modules/v8-compile-cache/",\ - "packageDependencies": [\ - ["v8-compile-cache", "npm:2.3.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["v8-to-istanbul", [\ - ["npm:9.0.1", {\ - "packageLocation": "./.yarn/cache/v8-to-istanbul-npm-9.0.1-58bbce7857-a49c34bf0a.zip/node_modules/v8-to-istanbul/",\ - "packageDependencies": [\ - ["v8-to-istanbul", "npm:9.0.1"],\ - ["@jridgewell/trace-mapping", "npm:0.3.14"],\ - ["@types/istanbul-lib-coverage", "npm:2.0.4"],\ - ["convert-source-map", "npm:1.8.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["vdirs", [\ - ["npm:0.1.8", {\ - "packageLocation": "./.yarn/cache/vdirs-npm-0.1.8-59a32a98d6-a7be8ccad3.zip/node_modules/vdirs/",\ - "packageDependencies": [\ - ["vdirs", "npm:0.1.8"]\ - ],\ - "linkType": "SOFT"\ - }],\ - ["virtual:9f096c233074b200486016c951159c23194337e7c7d59a71ca2c42d04bf345037b52ab329d71315b0e0d2a9be58321dfafc718b2bc37ea4bde4e8e682754a169#npm:0.1.8", {\ - "packageLocation": "./.yarn/__virtual__/vdirs-virtual-aef23ee679/0/cache/vdirs-npm-0.1.8-59a32a98d6-a7be8ccad3.zip/node_modules/vdirs/",\ - "packageDependencies": [\ - ["vdirs", "virtual:9f096c233074b200486016c951159c23194337e7c7d59a71ca2c42d04bf345037b52ab329d71315b0e0d2a9be58321dfafc718b2bc37ea4bde4e8e682754a169#npm:0.1.8"],\ - ["@types/vue", null],\ - ["evtd", "npm:0.2.3"],\ - ["vue", "npm:3.2.37"]\ - ],\ - "packagePeers": [\ - "@types/vue",\ - "vue"\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["verror", [\ - ["npm:1.10.0", {\ - "packageLocation": "./.yarn/cache/verror-npm-1.10.0-c3f839c579-c431df0bed.zip/node_modules/verror/",\ - "packageDependencies": [\ - ["verror", "npm:1.10.0"],\ - ["assert-plus", "npm:1.0.0"],\ - ["core-util-is", "npm:1.0.2"],\ - ["extsprintf", "npm:1.3.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["vite", [\ - ["npm:2.9.14", {\ - "packageLocation": "./.yarn/cache/vite-npm-2.9.14-6654defddb-f78b54f584.zip/node_modules/vite/",\ - "packageDependencies": [\ - ["vite", "npm:2.9.14"]\ - ],\ - "linkType": "SOFT"\ - }],\ - ["npm:3.0.0-beta.10", {\ - "packageLocation": "./.yarn/cache/vite-npm-3.0.0-beta.10-1e22aa4d4f-2b27107dac.zip/node_modules/vite/",\ - "packageDependencies": [\ - ["vite", "npm:3.0.0-beta.10"]\ - ],\ - "linkType": "SOFT"\ - }],\ - ["virtual:1fc33f4bd6116a9fc7ed51fd7378f3446ce4639067e8bf74a88ca6296c7ed2b0f7caf5fcb0663dcbe087d9cbcbbf6d979d5db1a32d0e8c64b86ed894884a5422#npm:3.0.0-beta.10", {\ - "packageLocation": "./.yarn/__virtual__/vite-virtual-98b4265b36/0/cache/vite-npm-3.0.0-beta.10-1e22aa4d4f-2b27107dac.zip/node_modules/vite/",\ - "packageDependencies": [\ - ["vite", "virtual:1fc33f4bd6116a9fc7ed51fd7378f3446ce4639067e8bf74a88ca6296c7ed2b0f7caf5fcb0663dcbe087d9cbcbbf6d979d5db1a32d0e8c64b86ed894884a5422#npm:3.0.0-beta.10"],\ - ["@types/less", null],\ - ["@types/sass", null],\ - ["@types/stylus", null],\ - ["@types/terser", null],\ - ["esbuild", "npm:0.14.49"],\ - ["fsevents", "patch:fsevents@npm%3A2.3.2#~builtin::version=2.3.2&hash=18f3a7"],\ - ["less", null],\ - ["postcss", "npm:8.4.14"],\ - ["resolve", "patch:resolve@npm%3A1.22.1#~builtin::version=1.22.1&hash=07638b"],\ - ["rollup", "npm:2.76.0"],\ - ["sass", null],\ - ["stylus", null],\ - ["terser", null]\ - ],\ - "packagePeers": [\ - "@types/less",\ - "@types/sass",\ - "@types/stylus",\ - "@types/terser",\ - "less",\ - "sass",\ - "stylus",\ - "terser"\ - ],\ - "linkType": "HARD"\ - }],\ - ["virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:2.9.14", {\ - "packageLocation": "./.yarn/__virtual__/vite-virtual-2d90dfcffc/0/cache/vite-npm-2.9.14-6654defddb-f78b54f584.zip/node_modules/vite/",\ - "packageDependencies": [\ - ["vite", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:2.9.14"],\ - ["@types/less", null],\ - ["@types/sass", null],\ - ["@types/stylus", null],\ - ["esbuild", "npm:0.14.38"],\ - ["fsevents", "patch:fsevents@npm%3A2.3.2#~builtin::version=2.3.2&hash=18f3a7"],\ - ["less", null],\ - ["postcss", "npm:8.4.14"],\ - ["resolve", "patch:resolve@npm%3A1.22.0#~builtin::version=1.22.0&hash=07638b"],\ - ["rollup", "npm:2.75.3"],\ - ["sass", "npm:1.53.0"],\ - ["stylus", null]\ - ],\ - "packagePeers": [\ - "@types/less",\ - "@types/sass",\ - "@types/stylus",\ - "less",\ - "sass",\ - "stylus"\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["vitest", [\ - ["npm:0.18.1", {\ - "packageLocation": "./.yarn/cache/vitest-npm-0.18.1-e5f5447995-0d3a77625e.zip/node_modules/vitest/",\ - "packageDependencies": [\ - ["vitest", "npm:0.18.1"]\ - ],\ - "linkType": "SOFT"\ - }],\ - ["virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:0.18.1", {\ - "packageLocation": "./.yarn/__virtual__/vitest-virtual-1fc33f4bd6/0/cache/vitest-npm-0.18.1-e5f5447995-0d3a77625e.zip/node_modules/vitest/",\ - "packageDependencies": [\ - ["vitest", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:0.18.1"],\ - ["@edge-runtime/vm", null],\ - ["@types/c8", null],\ - ["@types/chai", "npm:4.3.1"],\ - ["@types/chai-subset", "npm:1.3.3"],\ - ["@types/edge-runtime__vm", null],\ - ["@types/happy-dom", null],\ - ["@types/jsdom", null],\ - ["@types/node", "npm:14.18.18"],\ - ["@types/vitest__ui", null],\ - ["@vitest/ui", null],\ - ["c8", "npm:7.12.0"],\ - ["chai", "npm:4.3.6"],\ - ["debug", "virtual:b86a9fb34323a98c6519528ed55faa0d9b44ca8879307c0b29aa384bde47ff59a7d0c9051b31246f14521dfb71ba3c5d6d0b35c29fffc17bf875aa6ad977d9e8#npm:4.3.4"],\ - ["happy-dom", null],\ - ["jsdom", null],\ - ["local-pkg", "npm:0.4.2"],\ - ["tinypool", "npm:0.2.4"],\ - ["tinyspy", "npm:1.0.0"],\ - ["vite", "virtual:1fc33f4bd6116a9fc7ed51fd7378f3446ce4639067e8bf74a88ca6296c7ed2b0f7caf5fcb0663dcbe087d9cbcbbf6d979d5db1a32d0e8c64b86ed894884a5422#npm:3.0.0-beta.10"]\ - ],\ - "packagePeers": [\ - "@edge-runtime/vm",\ - "@types/c8",\ - "@types/edge-runtime__vm",\ - "@types/happy-dom",\ - "@types/jsdom",\ - "@types/vitest__ui",\ - "@vitest/ui",\ - "c8",\ - "happy-dom",\ - "jsdom"\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["void-elements", [\ - ["npm:3.1.0", {\ - "packageLocation": "./.yarn/cache/void-elements-npm-3.1.0-4f43780839-0390f81810.zip/node_modules/void-elements/",\ - "packageDependencies": [\ - ["void-elements", "npm:3.1.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["vooks", [\ - ["npm:0.2.12", {\ - "packageLocation": "./.yarn/cache/vooks-npm-0.2.12-0d1a2d856b-e6841ec5b6.zip/node_modules/vooks/",\ - "packageDependencies": [\ - ["vooks", "npm:0.2.12"]\ - ],\ - "linkType": "SOFT"\ - }],\ - ["virtual:9f096c233074b200486016c951159c23194337e7c7d59a71ca2c42d04bf345037b52ab329d71315b0e0d2a9be58321dfafc718b2bc37ea4bde4e8e682754a169#npm:0.2.12", {\ - "packageLocation": "./.yarn/__virtual__/vooks-virtual-3f58d63b51/0/cache/vooks-npm-0.2.12-0d1a2d856b-e6841ec5b6.zip/node_modules/vooks/",\ - "packageDependencies": [\ - ["vooks", "virtual:9f096c233074b200486016c951159c23194337e7c7d59a71ca2c42d04bf345037b52ab329d71315b0e0d2a9be58321dfafc718b2bc37ea4bde4e8e682754a169#npm:0.2.12"],\ - ["@types/vue", null],\ - ["evtd", "npm:0.2.3"],\ - ["vue", "npm:3.2.37"]\ - ],\ - "packagePeers": [\ - "@types/vue",\ - "vue"\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["vue", [\ - ["npm:3.2.37", {\ - "packageLocation": "./.yarn/cache/vue-npm-3.2.37-c15242c7af-cd20069c31.zip/node_modules/vue/",\ - "packageDependencies": [\ - ["vue", "npm:3.2.37"],\ - ["@vue/compiler-dom", "npm:3.2.37"],\ - ["@vue/compiler-sfc", "npm:3.2.37"],\ - ["@vue/runtime-dom", "npm:3.2.37"],\ - ["@vue/server-renderer", "virtual:c15242c7af88e957688e92d9c054d0c6533fd55fdb771c3854473b923e00751099a2c292023fc5bcf1d904adde806541a7f6b2b8e48d11e76ccb2ee0856b45bd#npm:3.2.37"],\ - ["@vue/shared", "npm:3.2.37"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["vue-demi", [\ - ["npm:0.12.5", {\ - "packageLocation": "./.yarn/unplugged/vue-demi-virtual-f447b32deb/node_modules/vue-demi/",\ - "packageDependencies": [\ - ["vue-demi", "npm:0.12.5"]\ - ],\ - "linkType": "SOFT"\ - }],\ - ["npm:0.13.1", {\ - "packageLocation": "./.yarn/unplugged/vue-demi-virtual-b58fb21b61/node_modules/vue-demi/",\ - "packageDependencies": [\ - ["vue-demi", "npm:0.13.1"]\ - ],\ - "linkType": "SOFT"\ - }],\ - ["virtual:5ab4c103d6244530b5b0e205eaa53ec3e9ba3fb62183d05dc99cae2b048234bb8882fd551ea98b3988ff38ddb73c47e86ce5761c9ada2a778cfb0ca0b86c74e5#npm:0.13.1", {\ - "packageLocation": "./.yarn/unplugged/vue-demi-virtual-b58fb21b61/node_modules/vue-demi/",\ - "packageDependencies": [\ - ["vue-demi", "virtual:5ab4c103d6244530b5b0e205eaa53ec3e9ba3fb62183d05dc99cae2b048234bb8882fd551ea98b3988ff38ddb73c47e86ce5761c9ada2a778cfb0ca0b86c74e5#npm:0.13.1"],\ - ["@types/vue", null],\ - ["@types/vue__composition-api", null],\ - ["@vue/composition-api", null],\ - ["vue", "npm:3.2.37"]\ - ],\ - "packagePeers": [\ - "@types/vue",\ - "@types/vue__composition-api",\ - "@vue/composition-api",\ - "vue"\ - ],\ - "linkType": "HARD"\ - }],\ - ["virtual:f56fcf19bbebc2ada1b28955da8cc216b1e9a569a1a7337d2d1926c1ebd1bc7a5bd91aedae1d05c15c8562f33caf7c59bd3020a667340f6bdc6a7b13fc2ba847#npm:0.12.5", {\ - "packageLocation": "./.yarn/unplugged/vue-demi-virtual-f447b32deb/node_modules/vue-demi/",\ - "packageDependencies": [\ - ["vue-demi", "virtual:f56fcf19bbebc2ada1b28955da8cc216b1e9a569a1a7337d2d1926c1ebd1bc7a5bd91aedae1d05c15c8562f33caf7c59bd3020a667340f6bdc6a7b13fc2ba847#npm:0.12.5"],\ - ["@types/vue", null],\ - ["@types/vue__composition-api", null],\ - ["@vue/composition-api", null],\ - ["vue", "npm:3.2.37"]\ - ],\ - "packagePeers": [\ - "@types/vue",\ - "@types/vue__composition-api",\ - "@vue/composition-api",\ - "vue"\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["vue-eslint-parser", [\ - ["npm:9.0.3", {\ - "packageLocation": "./.yarn/cache/vue-eslint-parser-npm-9.0.3-1d52721799-61248eb504.zip/node_modules/vue-eslint-parser/",\ - "packageDependencies": [\ - ["vue-eslint-parser", "npm:9.0.3"]\ - ],\ - "linkType": "SOFT"\ - }],\ - ["virtual:9414c87416def0a63dceb2f6f5fb7f6686d5c8cb4f316560809cc3f0b442b2490e362606443411ef0a3ef5d60343598226e3c932fec0ce0ca7dcbb584729a7b1#npm:9.0.3", {\ - "packageLocation": "./.yarn/__virtual__/vue-eslint-parser-virtual-402ba2ba99/0/cache/vue-eslint-parser-npm-9.0.3-1d52721799-61248eb504.zip/node_modules/vue-eslint-parser/",\ - "packageDependencies": [\ - ["vue-eslint-parser", "virtual:9414c87416def0a63dceb2f6f5fb7f6686d5c8cb4f316560809cc3f0b442b2490e362606443411ef0a3ef5d60343598226e3c932fec0ce0ca7dcbb584729a7b1#npm:9.0.3"],\ - ["@types/eslint", null],\ - ["debug", "virtual:b86a9fb34323a98c6519528ed55faa0d9b44ca8879307c0b29aa384bde47ff59a7d0c9051b31246f14521dfb71ba3c5d6d0b35c29fffc17bf875aa6ad977d9e8#npm:4.3.4"],\ - ["eslint", "npm:8.20.0"],\ - ["eslint-scope", "npm:7.1.1"],\ - ["eslint-visitor-keys", "npm:3.3.0"],\ - ["espree", "npm:9.3.2"],\ - ["esquery", "npm:1.4.0"],\ - ["lodash", "npm:4.17.21"],\ - ["semver", "npm:7.3.7"]\ - ],\ - "packagePeers": [\ - "@types/eslint",\ - "eslint"\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["vue-router", [\ - ["npm:4.1.2", {\ - "packageLocation": "./.yarn/cache/vue-router-npm-4.1.2-fb1ea78cc7-f4b900f0db.zip/node_modules/vue-router/",\ - "packageDependencies": [\ - ["vue-router", "npm:4.1.2"]\ - ],\ - "linkType": "SOFT"\ - }],\ - ["virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:4.1.2", {\ - "packageLocation": "./.yarn/__virtual__/vue-router-virtual-21390421ce/0/cache/vue-router-npm-4.1.2-fb1ea78cc7-f4b900f0db.zip/node_modules/vue-router/",\ - "packageDependencies": [\ - ["vue-router", "virtual:dc3fc578bfa5e06182a4d2be39ede0bc5b74940b1ffe0d70c26892ab140a4699787750fba175dc306292e80b4aa2c8c5f68c2a821e69b2c37e360c0dff36ff66#npm:4.1.2"],\ - ["@types/vue", null],\ - ["@vue/devtools-api", "npm:6.1.4"],\ - ["vue", "npm:3.2.37"]\ - ],\ - "packagePeers": [\ - "@types/vue",\ - "vue"\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["vueuc", [\ - ["npm:0.4.47", {\ - "packageLocation": "./.yarn/cache/vueuc-npm-0.4.47-ad081ddd15-b82b77a882.zip/node_modules/vueuc/",\ - "packageDependencies": [\ - ["vueuc", "npm:0.4.47"]\ - ],\ - "linkType": "SOFT"\ - }],\ - ["virtual:9f096c233074b200486016c951159c23194337e7c7d59a71ca2c42d04bf345037b52ab329d71315b0e0d2a9be58321dfafc718b2bc37ea4bde4e8e682754a169#npm:0.4.47", {\ - "packageLocation": "./.yarn/__virtual__/vueuc-virtual-797371cddc/0/cache/vueuc-npm-0.4.47-ad081ddd15-b82b77a882.zip/node_modules/vueuc/",\ - "packageDependencies": [\ - ["vueuc", "virtual:9f096c233074b200486016c951159c23194337e7c7d59a71ca2c42d04bf345037b52ab329d71315b0e0d2a9be58321dfafc718b2bc37ea4bde4e8e682754a169#npm:0.4.47"],\ - ["@css-render/vue3-ssr", "virtual:9f096c233074b200486016c951159c23194337e7c7d59a71ca2c42d04bf345037b52ab329d71315b0e0d2a9be58321dfafc718b2bc37ea4bde4e8e682754a169#npm:0.15.10"],\ - ["@juggle/resize-observer", "npm:3.3.1"],\ - ["@types/vue", null],\ - ["css-render", "npm:0.15.10"],\ - ["evtd", "npm:0.2.3"],\ - ["seemly", "npm:0.3.3"],\ - ["vdirs", "virtual:9f096c233074b200486016c951159c23194337e7c7d59a71ca2c42d04bf345037b52ab329d71315b0e0d2a9be58321dfafc718b2bc37ea4bde4e8e682754a169#npm:0.1.8"],\ - ["vooks", "virtual:9f096c233074b200486016c951159c23194337e7c7d59a71ca2c42d04bf345037b52ab329d71315b0e0d2a9be58321dfafc718b2bc37ea4bde4e8e682754a169#npm:0.2.12"],\ - ["vue", "npm:3.2.37"]\ - ],\ - "packagePeers": [\ - "@types/vue",\ - "vue"\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["weak-lru-cache", [\ - ["npm:1.2.2", {\ - "packageLocation": "./.yarn/cache/weak-lru-cache-npm-1.2.2-0dc8dfa322-0fbe16839d.zip/node_modules/weak-lru-cache/",\ - "packageDependencies": [\ - ["weak-lru-cache", "npm:1.2.2"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["webidl-conversions", [\ - ["npm:4.0.2", {\ - "packageLocation": "./.yarn/cache/webidl-conversions-npm-4.0.2-1d159e6409-c93d8dfe90.zip/node_modules/webidl-conversions/",\ - "packageDependencies": [\ - ["webidl-conversions", "npm:4.0.2"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["whatwg-url", [\ - ["npm:7.1.0", {\ - "packageLocation": "./.yarn/cache/whatwg-url-npm-7.1.0-d6cae01571-fecb07c872.zip/node_modules/whatwg-url/",\ - "packageDependencies": [\ - ["whatwg-url", "npm:7.1.0"],\ - ["lodash.sortby", "npm:4.7.0"],\ - ["tr46", "npm:1.0.1"],\ - ["webidl-conversions", "npm:4.0.2"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["which", [\ - ["npm:2.0.2", {\ - "packageLocation": "./.yarn/cache/which-npm-2.0.2-320ddf72f7-1a5c563d3c.zip/node_modules/which/",\ - "packageDependencies": [\ - ["which", "npm:2.0.2"],\ - ["isexe", "npm:2.0.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["which-boxed-primitive", [\ - ["npm:1.0.2", {\ - "packageLocation": "./.yarn/cache/which-boxed-primitive-npm-1.0.2-e214f9ae5a-53ce774c73.zip/node_modules/which-boxed-primitive/",\ - "packageDependencies": [\ - ["which-boxed-primitive", "npm:1.0.2"],\ - ["is-bigint", "npm:1.0.4"],\ - ["is-boolean-object", "npm:1.1.2"],\ - ["is-number-object", "npm:1.0.7"],\ - ["is-string", "npm:1.0.7"],\ - ["is-symbol", "npm:1.0.4"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["wide-align", [\ - ["npm:1.1.5", {\ - "packageLocation": "./.yarn/cache/wide-align-npm-1.1.5-889d77e592-d5fc37cd56.zip/node_modules/wide-align/",\ - "packageDependencies": [\ - ["wide-align", "npm:1.1.5"],\ - ["string-width", "npm:4.2.3"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["with", [\ - ["npm:7.0.2", {\ - "packageLocation": "./.yarn/cache/with-npm-7.0.2-135a242adb-a00fe87b73.zip/node_modules/with/",\ - "packageDependencies": [\ - ["with", "npm:7.0.2"],\ - ["@babel/parser", "npm:7.18.4"],\ - ["@babel/types", "npm:7.18.4"],\ - ["assert-never", "npm:1.2.1"],\ - ["babel-walk", "npm:3.0.0-canary-5"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["word-wrap", [\ - ["npm:1.2.3", {\ - "packageLocation": "./.yarn/cache/word-wrap-npm-1.2.3-7fb15ab002-30b48f91fc.zip/node_modules/word-wrap/",\ - "packageDependencies": [\ - ["word-wrap", "npm:1.2.3"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["wrap-ansi", [\ - ["npm:6.2.0", {\ - "packageLocation": "./.yarn/cache/wrap-ansi-npm-6.2.0-439a7246d8-6cd96a4101.zip/node_modules/wrap-ansi/",\ - "packageDependencies": [\ - ["wrap-ansi", "npm:6.2.0"],\ - ["ansi-styles", "npm:4.3.0"],\ - ["string-width", "npm:4.2.3"],\ - ["strip-ansi", "npm:6.0.1"]\ - ],\ - "linkType": "HARD"\ - }],\ - ["npm:7.0.0", {\ - "packageLocation": "./.yarn/cache/wrap-ansi-npm-7.0.0-ad6e1a0554-a790b846fd.zip/node_modules/wrap-ansi/",\ - "packageDependencies": [\ - ["wrap-ansi", "npm:7.0.0"],\ - ["ansi-styles", "npm:4.3.0"],\ - ["string-width", "npm:4.2.3"],\ - ["strip-ansi", "npm:6.0.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["wrappy", [\ - ["npm:1.0.2", {\ - "packageLocation": "./.yarn/cache/wrappy-npm-1.0.2-916de4d4b3-159da4805f.zip/node_modules/wrappy/",\ - "packageDependencies": [\ - ["wrappy", "npm:1.0.2"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["xml-name-validator", [\ - ["npm:4.0.0", {\ - "packageLocation": "./.yarn/cache/xml-name-validator-npm-4.0.0-0857c21729-af100b79c2.zip/node_modules/xml-name-validator/",\ - "packageDependencies": [\ - ["xml-name-validator", "npm:4.0.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["xxhash-wasm", [\ - ["npm:0.4.2", {\ - "packageLocation": "./.yarn/cache/xxhash-wasm-npm-0.4.2-afa0b23648-747b32fcfe.zip/node_modules/xxhash-wasm/",\ - "packageDependencies": [\ - ["xxhash-wasm", "npm:0.4.2"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["y18n", [\ - ["npm:5.0.8", {\ - "packageLocation": "./.yarn/cache/y18n-npm-5.0.8-5f3a0a7e62-54f0fb9562.zip/node_modules/y18n/",\ - "packageDependencies": [\ - ["y18n", "npm:5.0.8"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["yallist", [\ - ["npm:4.0.0", {\ - "packageLocation": "./.yarn/cache/yallist-npm-4.0.0-b493d9e907-343617202a.zip/node_modules/yallist/",\ - "packageDependencies": [\ - ["yallist", "npm:4.0.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["yaml", [\ - ["npm:1.10.2", {\ - "packageLocation": "./.yarn/cache/yaml-npm-1.10.2-0e780aebdf-ce4ada136e.zip/node_modules/yaml/",\ - "packageDependencies": [\ - ["yaml", "npm:1.10.2"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["yargs", [\ - ["npm:16.2.0", {\ - "packageLocation": "./.yarn/cache/yargs-npm-16.2.0-547873d425-b14afbb51e.zip/node_modules/yargs/",\ - "packageDependencies": [\ - ["yargs", "npm:16.2.0"],\ - ["cliui", "npm:7.0.4"],\ - ["escalade", "npm:3.1.1"],\ - ["get-caller-file", "npm:2.0.5"],\ - ["require-directory", "npm:2.1.1"],\ - ["string-width", "npm:4.2.3"],\ - ["y18n", "npm:5.0.8"],\ - ["yargs-parser", "npm:20.2.9"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["yargs-parser", [\ - ["npm:20.2.9", {\ - "packageLocation": "./.yarn/cache/yargs-parser-npm-20.2.9-a1d19e598d-8bb69015f2.zip/node_modules/yargs-parser/",\ - "packageDependencies": [\ - ["yargs-parser", "npm:20.2.9"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["yauzl", [\ - ["npm:2.10.0", {\ - "packageLocation": "./.yarn/cache/yauzl-npm-2.10.0-72e70ea021-7f21fe0bba.zip/node_modules/yauzl/",\ - "packageDependencies": [\ - ["yauzl", "npm:2.10.0"],\ - ["buffer-crc32", "npm:0.2.13"],\ - ["fd-slicer", "npm:1.1.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["yocto-queue", [\ - ["npm:0.1.0", {\ - "packageLocation": "./.yarn/cache/yocto-queue-npm-0.1.0-c6c9a7db29-f77b3d8d00.zip/node_modules/yocto-queue/",\ - "packageDependencies": [\ - ["yocto-queue", "npm:0.1.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["zxcvbn", [\ - ["npm:4.4.2", {\ - "packageLocation": "./.yarn/cache/zxcvbn-npm-4.4.2-6527983856-76ab32c066.zip/node_modules/zxcvbn/",\ - "packageDependencies": [\ - ["zxcvbn", "npm:4.4.2"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]]\ - ]\ - }'), {basePath: basePath || __dirname}); - } - -const fs = require('fs'); -const path = require('path'); -const require$$0 = require('module'); -const StringDecoder = require('string_decoder'); -const url = require('url'); -const os = require('os'); -const nodeUtils = require('util'); -const stream = require('stream'); -const zlib = require('zlib'); -const events = require('events'); - -const _interopDefaultLegacy = e => e && typeof e === 'object' && 'default' in e ? e : { default: e }; - -function _interopNamespace(e) { - if (e && e.__esModule) return e; - const n = Object.create(null); - if (e) { - for (const k in e) { - if (k !== 'default') { - const d = Object.getOwnPropertyDescriptor(e, k); - Object.defineProperty(n, k, d.get ? d : { - enumerable: true, - get: () => e[k] - }); - } - } - } - n.default = e; - return Object.freeze(n); -} - -const fs__default = /*#__PURE__*/_interopDefaultLegacy(fs); -const path__default = /*#__PURE__*/_interopDefaultLegacy(path); -const require$$0__default = /*#__PURE__*/_interopDefaultLegacy(require$$0); -const StringDecoder__default = /*#__PURE__*/_interopDefaultLegacy(StringDecoder); -const nodeUtils__namespace = /*#__PURE__*/_interopNamespace(nodeUtils); -const zlib__default = /*#__PURE__*/_interopDefaultLegacy(zlib); - -const S_IFMT = 61440; -const S_IFDIR = 16384; -const S_IFREG = 32768; -const S_IFLNK = 40960; -const SAFE_TIME = 456789e3; - -const DEFAULT_MODE = S_IFREG | 420; -class StatEntry { - 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 = DEFAULT_MODE; - this.nlink = 1; - this.rdev = 0; - this.blocks = 1; - } - isBlockDevice() { - return false; - } - isCharacterDevice() { - return false; - } - isDirectory() { - return (this.mode & S_IFMT) === S_IFDIR; - } - isFIFO() { - return false; - } - isFile() { - return (this.mode & S_IFMT) === S_IFREG; - } - isSocket() { - return false; - } - isSymbolicLink() { - return (this.mode & S_IFMT) === S_IFLNK; - } -} -class BigIntStatsEntry { - 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(DEFAULT_MODE); - this.nlink = BigInt(1); - this.rdev = BigInt(0); - this.blocks = BigInt(1); - } - isBlockDevice() { - return false; - } - isCharacterDevice() { - return false; - } - isDirectory() { - return (this.mode & BigInt(S_IFMT)) === BigInt(S_IFDIR); - } - isFIFO() { - return false; - } - isFile() { - return (this.mode & BigInt(S_IFMT)) === BigInt(S_IFREG); - } - isSocket() { - return false; - } - isSymbolicLink() { - return (this.mode & BigInt(S_IFMT)) === BigInt(S_IFLNK); - } -} -function makeDefaultStats() { - return new StatEntry(); -} -function clearStats(stats) { - for (const key in stats) { - if (Object.prototype.hasOwnProperty.call(stats, key)) { - const element = stats[key]; - if (typeof element === `number`) { - stats[key] = 0; - } else if (typeof element === `bigint`) { - stats[key] = BigInt(0); - } else if (nodeUtils__namespace.types.isDate(element)) { - stats[key] = new Date(0); - } - } - } - return stats; -} -function convertToBigIntStats(stats) { - const bigintStats = new BigIntStatsEntry(); - for (const key in stats) { - if (Object.prototype.hasOwnProperty.call(stats, key)) { - const element = stats[key]; - if (typeof element === `number`) { - bigintStats[key] = BigInt(element); - } else if (nodeUtils__namespace.types.isDate(element)) { - bigintStats[key] = new Date(element); - } - } - } - bigintStats.atimeNs = bigintStats.atimeMs * BigInt(1e6); - bigintStats.mtimeNs = bigintStats.mtimeMs * BigInt(1e6); - bigintStats.ctimeNs = bigintStats.ctimeMs * BigInt(1e6); - bigintStats.birthtimeNs = bigintStats.birthtimeMs * BigInt(1e6); - return bigintStats; -} -function areStatsEqual(a, b) { - if (a.atimeMs !== b.atimeMs) - return false; - if (a.birthtimeMs !== b.birthtimeMs) - return false; - if (a.blksize !== b.blksize) - return false; - if (a.blocks !== b.blocks) - return false; - if (a.ctimeMs !== b.ctimeMs) - return false; - if (a.dev !== b.dev) - return false; - if (a.gid !== b.gid) - return false; - if (a.ino !== b.ino) - return false; - if (a.isBlockDevice() !== b.isBlockDevice()) - return false; - if (a.isCharacterDevice() !== b.isCharacterDevice()) - return false; - if (a.isDirectory() !== b.isDirectory()) - return false; - if (a.isFIFO() !== b.isFIFO()) - return false; - if (a.isFile() !== b.isFile()) - return false; - if (a.isSocket() !== b.isSocket()) - return false; - if (a.isSymbolicLink() !== b.isSymbolicLink()) - return false; - if (a.mode !== b.mode) - return false; - if (a.mtimeMs !== b.mtimeMs) - return false; - if (a.nlink !== b.nlink) - return false; - if (a.rdev !== b.rdev) - return false; - if (a.size !== b.size) - return false; - if (a.uid !== b.uid) - return false; - const aN = a; - const bN = b; - if (aN.atimeNs !== bN.atimeNs) - return false; - if (aN.mtimeNs !== bN.mtimeNs) - return false; - if (aN.ctimeNs !== bN.ctimeNs) - return false; - if (aN.birthtimeNs !== bN.birthtimeNs) - return false; - return true; -} - -var PathType; -(function(PathType2) { - PathType2[PathType2["File"] = 0] = "File"; - PathType2[PathType2["Portable"] = 1] = "Portable"; - PathType2[PathType2["Native"] = 2] = "Native"; -})(PathType || (PathType = {})); -const PortablePath = { - root: `/`, - dot: `.` -}; -const Filename = { - nodeModules: `node_modules`, - manifest: `package.json`, - lockfile: `yarn.lock`, - virtual: `__virtual__`, - pnpJs: `.pnp.js`, - pnpCjs: `.pnp.cjs`, - rc: `.yarnrc.yml` -}; -const npath = Object.create(path__default.default); -const ppath = Object.create(path__default.default.posix); -npath.cwd = () => process.cwd(); -ppath.cwd = () => toPortablePath(process.cwd()); -ppath.resolve = (...segments) => { - if (segments.length > 0 && ppath.isAbsolute(segments[0])) { - return path__default.default.posix.resolve(...segments); - } else { - return path__default.default.posix.resolve(ppath.cwd(), ...segments); - } -}; -const contains = function(pathUtils, from, to) { - from = pathUtils.normalize(from); - to = pathUtils.normalize(to); - if (from === to) - return `.`; - if (!from.endsWith(pathUtils.sep)) - from = from + pathUtils.sep; - if (to.startsWith(from)) { - return to.slice(from.length); - } else { - return null; - } -}; -npath.fromPortablePath = fromPortablePath; -npath.toPortablePath = toPortablePath; -npath.contains = (from, to) => contains(npath, from, to); -ppath.contains = (from, to) => contains(ppath, from, to); -const WINDOWS_PATH_REGEXP = /^([a-zA-Z]:.*)$/; -const UNC_WINDOWS_PATH_REGEXP = /^\/\/(\.\/)?(.*)$/; -const PORTABLE_PATH_REGEXP = /^\/([a-zA-Z]:.*)$/; -const UNC_PORTABLE_PATH_REGEXP = /^\/unc\/(\.dot\/)?(.*)$/; -function fromPortablePath(p) { - if (process.platform !== `win32`) - return p; - let portablePathMatch, uncPortablePathMatch; - if (portablePathMatch = p.match(PORTABLE_PATH_REGEXP)) - p = portablePathMatch[1]; - else if (uncPortablePathMatch = p.match(UNC_PORTABLE_PATH_REGEXP)) - p = `\\\\${uncPortablePathMatch[1] ? `.\\` : ``}${uncPortablePathMatch[2]}`; - else - return p; - return p.replace(/\//g, `\\`); -} -function toPortablePath(p) { - if (process.platform !== `win32`) - return p; - p = p.replace(/\\/g, `/`); - let windowsPathMatch, uncWindowsPathMatch; - if (windowsPathMatch = p.match(WINDOWS_PATH_REGEXP)) - p = `/${windowsPathMatch[1]}`; - else if (uncWindowsPathMatch = p.match(UNC_WINDOWS_PATH_REGEXP)) - p = `/unc/${uncWindowsPathMatch[1] ? `.dot/` : ``}${uncWindowsPathMatch[2]}`; - return p; -} -function convertPath(targetPathUtils, sourcePath) { - return targetPathUtils === npath ? fromPortablePath(sourcePath) : toPortablePath(sourcePath); -} - -var __defProp$5 = Object.defineProperty; -var __defProps$3 = Object.defineProperties; -var __getOwnPropDescs$3 = Object.getOwnPropertyDescriptors; -var __getOwnPropSymbols$6 = Object.getOwnPropertySymbols; -var __hasOwnProp$6 = Object.prototype.hasOwnProperty; -var __propIsEnum$6 = Object.prototype.propertyIsEnumerable; -var __defNormalProp$5 = (obj, key, value) => key in obj ? __defProp$5(obj, key, {enumerable: true, configurable: true, writable: true, value}) : obj[key] = value; -var __spreadValues$5 = (a, b) => { - for (var prop in b || (b = {})) - if (__hasOwnProp$6.call(b, prop)) - __defNormalProp$5(a, prop, b[prop]); - if (__getOwnPropSymbols$6) - for (var prop of __getOwnPropSymbols$6(b)) { - if (__propIsEnum$6.call(b, prop)) - __defNormalProp$5(a, prop, b[prop]); - } - return a; -}; -var __spreadProps$3 = (a, b) => __defProps$3(a, __getOwnPropDescs$3(b)); -const defaultTime = new Date(SAFE_TIME * 1e3); -var LinkStrategy; -(function(LinkStrategy2) { - LinkStrategy2["Allow"] = `allow`; - LinkStrategy2["ReadOnly"] = `readOnly`; -})(LinkStrategy || (LinkStrategy = {})); -async function copyPromise(destinationFs, destination, sourceFs, source, opts) { - const normalizedDestination = destinationFs.pathUtils.normalize(destination); - const normalizedSource = sourceFs.pathUtils.normalize(source); - const prelayout = []; - const postlayout = []; - const {atime, mtime} = opts.stableTime ? {atime: defaultTime, mtime: defaultTime} : await sourceFs.lstatPromise(normalizedSource); - await destinationFs.mkdirpPromise(destinationFs.pathUtils.dirname(destination), {utimes: [atime, mtime]}); - const updateTime = typeof destinationFs.lutimesPromise === `function` ? destinationFs.lutimesPromise.bind(destinationFs) : destinationFs.utimesPromise.bind(destinationFs); - await copyImpl(prelayout, postlayout, updateTime, destinationFs, normalizedDestination, sourceFs, normalizedSource, __spreadProps$3(__spreadValues$5({}, opts), {didParentExist: true})); - for (const operation of prelayout) - await operation(); - await Promise.all(postlayout.map((operation) => { - return operation(); - })); -} -async function copyImpl(prelayout, postlayout, updateTime, destinationFs, destination, sourceFs, source, opts) { - var _a, _b; - const destinationStat = opts.didParentExist ? await maybeLStat(destinationFs, destination) : null; - const sourceStat = await sourceFs.lstatPromise(source); - const {atime, mtime} = opts.stableTime ? {atime: defaultTime, mtime: defaultTime} : sourceStat; - let updated; - switch (true) { - case sourceStat.isDirectory(): - { - updated = await copyFolder(prelayout, postlayout, updateTime, destinationFs, destination, destinationStat, sourceFs, source, sourceStat, opts); - } - break; - case sourceStat.isFile(): - { - updated = await copyFile(prelayout, postlayout, updateTime, destinationFs, destination, destinationStat, sourceFs, source, sourceStat, opts); - } - break; - case sourceStat.isSymbolicLink(): - { - updated = await copySymlink(prelayout, postlayout, updateTime, destinationFs, destination, destinationStat, sourceFs, source, sourceStat, opts); - } - break; - default: - { - throw new Error(`Unsupported file type (${sourceStat.mode})`); - } - } - if (updated || ((_a = destinationStat == null ? void 0 : destinationStat.mtime) == null ? void 0 : _a.getTime()) !== mtime.getTime() || ((_b = destinationStat == null ? void 0 : destinationStat.atime) == null ? void 0 : _b.getTime()) !== atime.getTime()) { - postlayout.push(() => updateTime(destination, atime, mtime)); - updated = true; - } - if (destinationStat === null || (destinationStat.mode & 511) !== (sourceStat.mode & 511)) { - postlayout.push(() => destinationFs.chmodPromise(destination, sourceStat.mode & 511)); - updated = true; - } - return updated; -} -async function maybeLStat(baseFs, p) { - try { - return await baseFs.lstatPromise(p); - } catch (e) { - return null; - } -} -async function copyFolder(prelayout, postlayout, updateTime, destinationFs, destination, destinationStat, sourceFs, source, sourceStat, opts) { - if (destinationStat !== null && !destinationStat.isDirectory()) { - if (opts.overwrite) { - prelayout.push(async () => destinationFs.removePromise(destination)); - destinationStat = null; - } else { - return false; - } - } - let updated = false; - if (destinationStat === null) { - prelayout.push(async () => { - try { - await destinationFs.mkdirPromise(destination, {mode: sourceStat.mode}); - } catch (err) { - if (err.code !== `EEXIST`) { - throw err; - } - } - }); - updated = true; - } - const entries = await sourceFs.readdirPromise(source); - const nextOpts = opts.didParentExist && !destinationStat ? __spreadProps$3(__spreadValues$5({}, opts), {didParentExist: false}) : opts; - if (opts.stableSort) { - for (const entry of entries.sort()) { - if (await copyImpl(prelayout, postlayout, updateTime, destinationFs, destinationFs.pathUtils.join(destination, entry), sourceFs, sourceFs.pathUtils.join(source, entry), nextOpts)) { - updated = true; - } - } - } else { - const entriesUpdateStatus = await Promise.all(entries.map(async (entry) => { - await copyImpl(prelayout, postlayout, updateTime, destinationFs, destinationFs.pathUtils.join(destination, entry), sourceFs, sourceFs.pathUtils.join(source, entry), nextOpts); - })); - if (entriesUpdateStatus.some((status) => status)) { - updated = true; - } - } - return updated; -} -const isCloneSupportedCache = new WeakMap(); -function makeLinkOperation(opFs, destination, source, sourceStat, linkStrategy) { - return async () => { - await opFs.linkPromise(source, destination); - if (linkStrategy === LinkStrategy.ReadOnly) { - sourceStat.mode &= ~146; - await opFs.chmodPromise(destination, sourceStat.mode); - } - }; -} -function makeCloneLinkOperation(opFs, destination, source, sourceStat, linkStrategy) { - const isCloneSupported = isCloneSupportedCache.get(opFs); - if (typeof isCloneSupported === `undefined`) { - return async () => { - try { - await opFs.copyFilePromise(source, destination, fs__default.default.constants.COPYFILE_FICLONE_FORCE); - isCloneSupportedCache.set(opFs, true); - } catch (err) { - if (err.code === `ENOSYS` || err.code === `ENOTSUP`) { - isCloneSupportedCache.set(opFs, false); - await makeLinkOperation(opFs, destination, source, sourceStat, linkStrategy)(); - } else { - throw err; - } - } - }; - } else { - if (isCloneSupported) { - return async () => opFs.copyFilePromise(source, destination, fs__default.default.constants.COPYFILE_FICLONE_FORCE); - } else { - return makeLinkOperation(opFs, destination, source, sourceStat, linkStrategy); - } - } -} -async function copyFile(prelayout, postlayout, updateTime, destinationFs, destination, destinationStat, sourceFs, source, sourceStat, opts) { - var _a; - if (destinationStat !== null) { - if (opts.overwrite) { - prelayout.push(async () => destinationFs.removePromise(destination)); - destinationStat = null; - } else { - return false; - } - } - const linkStrategy = (_a = opts.linkStrategy) != null ? _a : null; - const op = destinationFs === sourceFs ? linkStrategy !== null ? makeCloneLinkOperation(destinationFs, destination, source, sourceStat, linkStrategy) : async () => destinationFs.copyFilePromise(source, destination, fs__default.default.constants.COPYFILE_FICLONE) : linkStrategy !== null ? makeLinkOperation(destinationFs, destination, source, sourceStat, linkStrategy) : async () => destinationFs.writeFilePromise(destination, await sourceFs.readFilePromise(source)); - prelayout.push(async () => op()); - return true; -} -async function copySymlink(prelayout, postlayout, updateTime, destinationFs, destination, destinationStat, sourceFs, source, sourceStat, opts) { - if (destinationStat !== null) { - if (opts.overwrite) { - prelayout.push(async () => destinationFs.removePromise(destination)); - destinationStat = null; - } else { - return false; - } - } - prelayout.push(async () => { - await destinationFs.symlinkPromise(convertPath(destinationFs.pathUtils, await sourceFs.readlinkPromise(source)), destination); - }); - return true; -} - -function makeError$1(code, message) { - return Object.assign(new Error(`${code}: ${message}`), {code}); -} -function EBUSY(message) { - return makeError$1(`EBUSY`, message); -} -function ENOSYS(message, reason) { - return makeError$1(`ENOSYS`, `${message}, ${reason}`); -} -function EINVAL(reason) { - return makeError$1(`EINVAL`, `invalid argument, ${reason}`); -} -function EBADF(reason) { - return makeError$1(`EBADF`, `bad file descriptor, ${reason}`); -} -function ENOENT(reason) { - return makeError$1(`ENOENT`, `no such file or directory, ${reason}`); -} -function ENOTDIR(reason) { - return makeError$1(`ENOTDIR`, `not a directory, ${reason}`); -} -function EISDIR(reason) { - return makeError$1(`EISDIR`, `illegal operation on a directory, ${reason}`); -} -function EEXIST(reason) { - return makeError$1(`EEXIST`, `file already exists, ${reason}`); -} -function EROFS(reason) { - return makeError$1(`EROFS`, `read-only filesystem, ${reason}`); -} -function ENOTEMPTY(reason) { - return makeError$1(`ENOTEMPTY`, `directory not empty, ${reason}`); -} -function EOPNOTSUPP(reason) { - return makeError$1(`EOPNOTSUPP`, `operation not supported, ${reason}`); -} -function ERR_DIR_CLOSED() { - return makeError$1(`ERR_DIR_CLOSED`, `Directory handle was closed`); -} -class LibzipError extends Error { - constructor(message, code) { - super(message); - this.name = `Libzip Error`; - this.code = code; - } -} - -class CustomDir { - constructor(path, nextDirent, opts = {}) { - this.path = path; - this.nextDirent = nextDirent; - this.opts = opts; - this.closed = false; - } - throwIfClosed() { - if (this.closed) { - throw ERR_DIR_CLOSED(); - } - } - async *[Symbol.asyncIterator]() { - try { - let dirent; - while ((dirent = await this.read()) !== null) { - yield dirent; - } - } finally { - await this.close(); - } - } - read(cb) { - const dirent = this.readSync(); - if (typeof cb !== `undefined`) - return cb(null, dirent); - return Promise.resolve(dirent); - } - readSync() { - this.throwIfClosed(); - return this.nextDirent(); - } - close(cb) { - this.closeSync(); - if (typeof cb !== `undefined`) - return cb(null); - return Promise.resolve(); - } - closeSync() { - var _a, _b; - this.throwIfClosed(); - (_b = (_a = this.opts).onClose) == null ? void 0 : _b.call(_a); - this.closed = true; - } -} -function opendir(fakeFs, path, entries, opts) { - const nextDirent = () => { - const filename = entries.shift(); - if (typeof filename === `undefined`) - return null; - return Object.assign(fakeFs.statSync(fakeFs.pathUtils.join(path, filename)), { - name: filename - }); - }; - return new CustomDir(path, nextDirent, opts); -} - -class FakeFS { - constructor(pathUtils) { - this.pathUtils = pathUtils; - } - async *genTraversePromise(init, {stableSort = false} = {}) { - const stack = [init]; - while (stack.length > 0) { - const p = stack.shift(); - const entry = await this.lstatPromise(p); - if (entry.isDirectory()) { - const entries = await this.readdirPromise(p); - if (stableSort) { - for (const entry2 of entries.sort()) { - stack.push(this.pathUtils.join(p, entry2)); - } - } else { - throw new Error(`Not supported`); - } - } else { - yield p; - } - } - } - async removePromise(p, {recursive = true, maxRetries = 5} = {}) { - let stat; - try { - stat = await this.lstatPromise(p); - } catch (error) { - if (error.code === `ENOENT`) { - return; - } else { - throw error; - } - } - if (stat.isDirectory()) { - if (recursive) { - const entries = await this.readdirPromise(p); - await Promise.all(entries.map((entry) => { - return this.removePromise(this.pathUtils.resolve(p, entry)); - })); - } - for (let t = 0; t <= maxRetries; t++) { - try { - await this.rmdirPromise(p); - break; - } catch (error) { - if (error.code !== `EBUSY` && error.code !== `ENOTEMPTY`) { - throw error; - } else if (t < maxRetries) { - await new Promise((resolve) => setTimeout(resolve, t * 100)); - } - } - } - } else { - await this.unlinkPromise(p); - } - } - removeSync(p, {recursive = true} = {}) { - let stat; - try { - stat = this.lstatSync(p); - } catch (error) { - if (error.code === `ENOENT`) { - return; - } else { - throw error; - } - } - if (stat.isDirectory()) { - if (recursive) - for (const entry of this.readdirSync(p)) - this.removeSync(this.pathUtils.resolve(p, entry)); - this.rmdirSync(p); - } else { - this.unlinkSync(p); - } - } - async mkdirpPromise(p, {chmod, utimes} = {}) { - p = this.resolve(p); - if (p === this.pathUtils.dirname(p)) - return void 0; - const parts = p.split(this.pathUtils.sep); - let createdDirectory; - for (let u = 2; u <= parts.length; ++u) { - const subPath = parts.slice(0, u).join(this.pathUtils.sep); - if (!this.existsSync(subPath)) { - try { - await this.mkdirPromise(subPath); - } catch (error) { - if (error.code === `EEXIST`) { - continue; - } else { - throw error; - } - } - createdDirectory != null ? createdDirectory : createdDirectory = subPath; - if (chmod != null) - await this.chmodPromise(subPath, chmod); - if (utimes != null) { - await this.utimesPromise(subPath, utimes[0], utimes[1]); - } else { - const parentStat = await this.statPromise(this.pathUtils.dirname(subPath)); - await this.utimesPromise(subPath, parentStat.atime, parentStat.mtime); - } - } - } - return createdDirectory; - } - mkdirpSync(p, {chmod, utimes} = {}) { - p = this.resolve(p); - if (p === this.pathUtils.dirname(p)) - return void 0; - const parts = p.split(this.pathUtils.sep); - let createdDirectory; - for (let u = 2; u <= parts.length; ++u) { - const subPath = parts.slice(0, u).join(this.pathUtils.sep); - if (!this.existsSync(subPath)) { - try { - this.mkdirSync(subPath); - } catch (error) { - if (error.code === `EEXIST`) { - continue; - } else { - throw error; - } - } - createdDirectory != null ? createdDirectory : createdDirectory = subPath; - if (chmod != null) - this.chmodSync(subPath, chmod); - if (utimes != null) { - this.utimesSync(subPath, utimes[0], utimes[1]); - } else { - const parentStat = this.statSync(this.pathUtils.dirname(subPath)); - this.utimesSync(subPath, parentStat.atime, parentStat.mtime); - } - } - } - return createdDirectory; - } - async copyPromise(destination, source, {baseFs = this, overwrite = true, stableSort = false, stableTime = false, linkStrategy = null} = {}) { - return await copyPromise(this, destination, baseFs, source, {overwrite, stableSort, stableTime, linkStrategy}); - } - copySync(destination, source, {baseFs = this, overwrite = true} = {}) { - const stat = baseFs.lstatSync(source); - const exists = this.existsSync(destination); - if (stat.isDirectory()) { - this.mkdirpSync(destination); - const directoryListing = baseFs.readdirSync(source); - for (const entry of directoryListing) { - this.copySync(this.pathUtils.join(destination, entry), baseFs.pathUtils.join(source, entry), {baseFs, overwrite}); - } - } else if (stat.isFile()) { - if (!exists || overwrite) { - if (exists) - this.removeSync(destination); - const content = baseFs.readFileSync(source); - this.writeFileSync(destination, content); - } - } else if (stat.isSymbolicLink()) { - if (!exists || overwrite) { - if (exists) - this.removeSync(destination); - const target = baseFs.readlinkSync(source); - this.symlinkSync(convertPath(this.pathUtils, target), destination); - } - } else { - throw new Error(`Unsupported file type (file: ${source}, mode: 0o${stat.mode.toString(8).padStart(6, `0`)})`); - } - const mode = stat.mode & 511; - this.chmodSync(destination, mode); - } - async changeFilePromise(p, content, opts = {}) { - if (Buffer.isBuffer(content)) { - return this.changeFileBufferPromise(p, content, opts); - } else { - return this.changeFileTextPromise(p, content, opts); - } - } - async changeFileBufferPromise(p, content, {mode} = {}) { - let current = Buffer.alloc(0); - try { - current = await this.readFilePromise(p); - } catch (error) { - } - if (Buffer.compare(current, content) === 0) - return; - await this.writeFilePromise(p, content, {mode}); - } - async changeFileTextPromise(p, content, {automaticNewlines, mode} = {}) { - let current = ``; - try { - current = await this.readFilePromise(p, `utf8`); - } catch (error) { - } - const normalizedContent = automaticNewlines ? normalizeLineEndings(current, content) : content; - if (current === normalizedContent) - return; - await this.writeFilePromise(p, normalizedContent, {mode}); - } - changeFileSync(p, content, opts = {}) { - if (Buffer.isBuffer(content)) { - return this.changeFileBufferSync(p, content, opts); - } else { - return this.changeFileTextSync(p, content, opts); - } - } - changeFileBufferSync(p, content, {mode} = {}) { - let current = Buffer.alloc(0); - try { - current = this.readFileSync(p); - } catch (error) { - } - if (Buffer.compare(current, content) === 0) - return; - this.writeFileSync(p, content, {mode}); - } - changeFileTextSync(p, content, {automaticNewlines = false, mode} = {}) { - let current = ``; - try { - current = this.readFileSync(p, `utf8`); - } catch (error) { - } - const normalizedContent = automaticNewlines ? normalizeLineEndings(current, content) : content; - if (current === normalizedContent) - return; - this.writeFileSync(p, normalizedContent, {mode}); - } - async movePromise(fromP, toP) { - try { - await this.renamePromise(fromP, toP); - } catch (error) { - if (error.code === `EXDEV`) { - await this.copyPromise(toP, fromP); - await this.removePromise(fromP); - } else { - throw error; - } - } - } - moveSync(fromP, toP) { - try { - this.renameSync(fromP, toP); - } catch (error) { - if (error.code === `EXDEV`) { - this.copySync(toP, fromP); - this.removeSync(fromP); - } else { - throw error; - } - } - } - async lockPromise(affectedPath, callback) { - const lockPath = `${affectedPath}.flock`; - const interval = 1e3 / 60; - const startTime = Date.now(); - let fd = null; - const isAlive = async () => { - let pid; - try { - [pid] = await this.readJsonPromise(lockPath); - } catch (error) { - return Date.now() - startTime < 500; - } - try { - process.kill(pid, 0); - return true; - } catch (error) { - return false; - } - }; - while (fd === null) { - try { - fd = await this.openPromise(lockPath, `wx`); - } catch (error) { - if (error.code === `EEXIST`) { - if (!await isAlive()) { - try { - await this.unlinkPromise(lockPath); - continue; - } catch (error2) { - } - } - if (Date.now() - startTime < 60 * 1e3) { - await new Promise((resolve) => setTimeout(resolve, interval)); - } else { - throw new Error(`Couldn't acquire a lock in a reasonable time (via ${lockPath})`); - } - } else { - throw error; - } - } - } - await this.writePromise(fd, JSON.stringify([process.pid])); - try { - return await callback(); - } finally { - try { - await this.closePromise(fd); - await this.unlinkPromise(lockPath); - } catch (error) { - } - } - } - async readJsonPromise(p) { - const content = await this.readFilePromise(p, `utf8`); - try { - return JSON.parse(content); - } catch (error) { - error.message += ` (in ${p})`; - throw error; - } - } - readJsonSync(p) { - const content = this.readFileSync(p, `utf8`); - try { - return JSON.parse(content); - } catch (error) { - error.message += ` (in ${p})`; - throw error; - } - } - async writeJsonPromise(p, data) { - return await this.writeFilePromise(p, `${JSON.stringify(data, null, 2)} -`); - } - writeJsonSync(p, data) { - return this.writeFileSync(p, `${JSON.stringify(data, null, 2)} -`); - } - async preserveTimePromise(p, cb) { - const stat = await this.lstatPromise(p); - const result = await cb(); - if (typeof result !== `undefined`) - p = result; - if (this.lutimesPromise) { - await this.lutimesPromise(p, stat.atime, stat.mtime); - } else if (!stat.isSymbolicLink()) { - await this.utimesPromise(p, stat.atime, stat.mtime); - } - } - async preserveTimeSync(p, cb) { - const stat = this.lstatSync(p); - const result = cb(); - if (typeof result !== `undefined`) - p = result; - if (this.lutimesSync) { - this.lutimesSync(p, stat.atime, stat.mtime); - } else if (!stat.isSymbolicLink()) { - this.utimesSync(p, stat.atime, stat.mtime); - } - } -} -class BasePortableFakeFS extends FakeFS { - constructor() { - super(ppath); - } -} -function getEndOfLine(content) { - const matches = content.match(/\r?\n/g); - if (matches === null) - return os.EOL; - const crlf = matches.filter((nl) => nl === `\r -`).length; - const lf = matches.length - crlf; - return crlf > lf ? `\r -` : ` -`; -} -function normalizeLineEndings(originalContent, newContent) { - return newContent.replace(/\r?\n/g, getEndOfLine(originalContent)); -} - -class NodeFS extends BasePortableFakeFS { - constructor(realFs = fs__default.default) { - super(); - this.realFs = realFs; - if (typeof this.realFs.lutimes !== `undefined`) { - this.lutimesPromise = this.lutimesPromiseImpl; - this.lutimesSync = this.lutimesSyncImpl; - } - } - getExtractHint() { - return false; - } - getRealPath() { - return PortablePath.root; - } - resolve(p) { - return ppath.resolve(p); - } - async openPromise(p, flags, mode) { - return await new Promise((resolve, reject) => { - this.realFs.open(npath.fromPortablePath(p), flags, mode, this.makeCallback(resolve, reject)); - }); - } - openSync(p, flags, mode) { - return this.realFs.openSync(npath.fromPortablePath(p), flags, mode); - } - async opendirPromise(p, opts) { - return await new Promise((resolve, reject) => { - if (typeof opts !== `undefined`) { - this.realFs.opendir(npath.fromPortablePath(p), opts, this.makeCallback(resolve, reject)); - } else { - this.realFs.opendir(npath.fromPortablePath(p), this.makeCallback(resolve, reject)); - } - }).then((dir) => { - return Object.defineProperty(dir, `path`, {value: p, configurable: true, writable: true}); - }); - } - opendirSync(p, opts) { - const dir = typeof opts !== `undefined` ? this.realFs.opendirSync(npath.fromPortablePath(p), opts) : this.realFs.opendirSync(npath.fromPortablePath(p)); - return Object.defineProperty(dir, `path`, {value: p, configurable: true, writable: true}); - } - async readPromise(fd, buffer, offset = 0, length = 0, position = -1) { - return await new Promise((resolve, reject) => { - this.realFs.read(fd, buffer, offset, length, position, (error, bytesRead) => { - if (error) { - reject(error); - } else { - resolve(bytesRead); - } - }); - }); - } - readSync(fd, buffer, offset, length, position) { - return this.realFs.readSync(fd, buffer, offset, length, position); - } - async writePromise(fd, buffer, offset, length, position) { - return await new Promise((resolve, reject) => { - if (typeof buffer === `string`) { - return this.realFs.write(fd, buffer, offset, this.makeCallback(resolve, reject)); - } else { - return this.realFs.write(fd, buffer, offset, length, position, this.makeCallback(resolve, reject)); - } - }); - } - writeSync(fd, buffer, offset, length, position) { - if (typeof buffer === `string`) { - return this.realFs.writeSync(fd, buffer, offset); - } else { - return this.realFs.writeSync(fd, buffer, offset, length, position); - } - } - async closePromise(fd) { - await new Promise((resolve, reject) => { - this.realFs.close(fd, this.makeCallback(resolve, reject)); - }); - } - closeSync(fd) { - this.realFs.closeSync(fd); - } - createReadStream(p, opts) { - const realPath = p !== null ? npath.fromPortablePath(p) : p; - return this.realFs.createReadStream(realPath, opts); - } - createWriteStream(p, opts) { - const realPath = p !== null ? npath.fromPortablePath(p) : p; - return this.realFs.createWriteStream(realPath, opts); - } - async realpathPromise(p) { - return await new Promise((resolve, reject) => { - this.realFs.realpath(npath.fromPortablePath(p), {}, this.makeCallback(resolve, reject)); - }).then((path) => { - return npath.toPortablePath(path); - }); - } - realpathSync(p) { - return npath.toPortablePath(this.realFs.realpathSync(npath.fromPortablePath(p), {})); - } - async existsPromise(p) { - return await new Promise((resolve) => { - this.realFs.exists(npath.fromPortablePath(p), resolve); - }); - } - accessSync(p, mode) { - return this.realFs.accessSync(npath.fromPortablePath(p), mode); - } - async accessPromise(p, mode) { - return await new Promise((resolve, reject) => { - this.realFs.access(npath.fromPortablePath(p), mode, this.makeCallback(resolve, reject)); - }); - } - existsSync(p) { - return this.realFs.existsSync(npath.fromPortablePath(p)); - } - async statPromise(p, opts) { - return await new Promise((resolve, reject) => { - if (opts) { - this.realFs.stat(npath.fromPortablePath(p), opts, this.makeCallback(resolve, reject)); - } else { - this.realFs.stat(npath.fromPortablePath(p), this.makeCallback(resolve, reject)); - } - }); - } - statSync(p, opts) { - if (opts) { - return this.realFs.statSync(npath.fromPortablePath(p), opts); - } else { - return this.realFs.statSync(npath.fromPortablePath(p)); - } - } - async fstatPromise(fd, opts) { - return await new Promise((resolve, reject) => { - if (opts) { - this.realFs.fstat(fd, opts, this.makeCallback(resolve, reject)); - } else { - this.realFs.fstat(fd, this.makeCallback(resolve, reject)); - } - }); - } - fstatSync(fd, opts) { - if (opts) { - return this.realFs.fstatSync(fd, opts); - } else { - return this.realFs.fstatSync(fd); - } - } - async lstatPromise(p, opts) { - return await new Promise((resolve, reject) => { - if (opts) { - this.realFs.lstat(npath.fromPortablePath(p), opts, this.makeCallback(resolve, reject)); - } else { - this.realFs.lstat(npath.fromPortablePath(p), this.makeCallback(resolve, reject)); - } - }); - } - lstatSync(p, opts) { - if (opts) { - return this.realFs.lstatSync(npath.fromPortablePath(p), opts); - } else { - return this.realFs.lstatSync(npath.fromPortablePath(p)); - } - } - async fchmodPromise(fd, mask) { - return await new Promise((resolve, reject) => { - this.realFs.fchmod(fd, mask, this.makeCallback(resolve, reject)); - }); - } - fchmodSync(fd, mask) { - return this.realFs.fchmodSync(fd, mask); - } - async chmodPromise(p, mask) { - return await new Promise((resolve, reject) => { - this.realFs.chmod(npath.fromPortablePath(p), mask, this.makeCallback(resolve, reject)); - }); - } - chmodSync(p, mask) { - return this.realFs.chmodSync(npath.fromPortablePath(p), mask); - } - async chownPromise(p, uid, gid) { - return await new Promise((resolve, reject) => { - this.realFs.chown(npath.fromPortablePath(p), uid, gid, this.makeCallback(resolve, reject)); - }); - } - chownSync(p, uid, gid) { - return this.realFs.chownSync(npath.fromPortablePath(p), uid, gid); - } - async renamePromise(oldP, newP) { - return await new Promise((resolve, reject) => { - this.realFs.rename(npath.fromPortablePath(oldP), npath.fromPortablePath(newP), this.makeCallback(resolve, reject)); - }); - } - renameSync(oldP, newP) { - return this.realFs.renameSync(npath.fromPortablePath(oldP), npath.fromPortablePath(newP)); - } - async copyFilePromise(sourceP, destP, flags = 0) { - return await new Promise((resolve, reject) => { - this.realFs.copyFile(npath.fromPortablePath(sourceP), npath.fromPortablePath(destP), flags, this.makeCallback(resolve, reject)); - }); - } - copyFileSync(sourceP, destP, flags = 0) { - return this.realFs.copyFileSync(npath.fromPortablePath(sourceP), npath.fromPortablePath(destP), flags); - } - async appendFilePromise(p, content, opts) { - return await new Promise((resolve, reject) => { - const fsNativePath = typeof p === `string` ? npath.fromPortablePath(p) : p; - if (opts) { - this.realFs.appendFile(fsNativePath, content, opts, this.makeCallback(resolve, reject)); - } else { - this.realFs.appendFile(fsNativePath, content, this.makeCallback(resolve, reject)); - } - }); - } - appendFileSync(p, content, opts) { - const fsNativePath = typeof p === `string` ? npath.fromPortablePath(p) : p; - if (opts) { - this.realFs.appendFileSync(fsNativePath, content, opts); - } else { - this.realFs.appendFileSync(fsNativePath, content); - } - } - async writeFilePromise(p, content, opts) { - return await new Promise((resolve, reject) => { - const fsNativePath = typeof p === `string` ? npath.fromPortablePath(p) : p; - if (opts) { - this.realFs.writeFile(fsNativePath, content, opts, this.makeCallback(resolve, reject)); - } else { - this.realFs.writeFile(fsNativePath, content, this.makeCallback(resolve, reject)); - } - }); - } - writeFileSync(p, content, opts) { - const fsNativePath = typeof p === `string` ? npath.fromPortablePath(p) : p; - if (opts) { - this.realFs.writeFileSync(fsNativePath, content, opts); - } else { - this.realFs.writeFileSync(fsNativePath, content); - } - } - async unlinkPromise(p) { - return await new Promise((resolve, reject) => { - this.realFs.unlink(npath.fromPortablePath(p), this.makeCallback(resolve, reject)); - }); - } - unlinkSync(p) { - return this.realFs.unlinkSync(npath.fromPortablePath(p)); - } - async utimesPromise(p, atime, mtime) { - return await new Promise((resolve, reject) => { - this.realFs.utimes(npath.fromPortablePath(p), atime, mtime, this.makeCallback(resolve, reject)); - }); - } - utimesSync(p, atime, mtime) { - this.realFs.utimesSync(npath.fromPortablePath(p), atime, mtime); - } - async lutimesPromiseImpl(p, atime, mtime) { - const lutimes = this.realFs.lutimes; - if (typeof lutimes === `undefined`) - throw ENOSYS(`unavailable Node binding`, `lutimes '${p}'`); - return await new Promise((resolve, reject) => { - lutimes.call(this.realFs, npath.fromPortablePath(p), atime, mtime, this.makeCallback(resolve, reject)); - }); - } - lutimesSyncImpl(p, atime, mtime) { - const lutimesSync = this.realFs.lutimesSync; - if (typeof lutimesSync === `undefined`) - throw ENOSYS(`unavailable Node binding`, `lutimes '${p}'`); - lutimesSync.call(this.realFs, npath.fromPortablePath(p), atime, mtime); - } - async mkdirPromise(p, opts) { - return await new Promise((resolve, reject) => { - this.realFs.mkdir(npath.fromPortablePath(p), opts, this.makeCallback(resolve, reject)); - }); - } - mkdirSync(p, opts) { - return this.realFs.mkdirSync(npath.fromPortablePath(p), opts); - } - async rmdirPromise(p, opts) { - return await new Promise((resolve, reject) => { - if (opts) { - this.realFs.rmdir(npath.fromPortablePath(p), opts, this.makeCallback(resolve, reject)); - } else { - this.realFs.rmdir(npath.fromPortablePath(p), this.makeCallback(resolve, reject)); - } - }); - } - rmdirSync(p, opts) { - return this.realFs.rmdirSync(npath.fromPortablePath(p), opts); - } - async linkPromise(existingP, newP) { - return await new Promise((resolve, reject) => { - this.realFs.link(npath.fromPortablePath(existingP), npath.fromPortablePath(newP), this.makeCallback(resolve, reject)); - }); - } - linkSync(existingP, newP) { - return this.realFs.linkSync(npath.fromPortablePath(existingP), npath.fromPortablePath(newP)); - } - async symlinkPromise(target, p, type) { - return await new Promise((resolve, reject) => { - this.realFs.symlink(npath.fromPortablePath(target.replace(/\/+$/, ``)), npath.fromPortablePath(p), type, this.makeCallback(resolve, reject)); - }); - } - symlinkSync(target, p, type) { - return this.realFs.symlinkSync(npath.fromPortablePath(target.replace(/\/+$/, ``)), npath.fromPortablePath(p), type); - } - async readFilePromise(p, encoding) { - return await new Promise((resolve, reject) => { - const fsNativePath = typeof p === `string` ? npath.fromPortablePath(p) : p; - this.realFs.readFile(fsNativePath, encoding, this.makeCallback(resolve, reject)); - }); - } - readFileSync(p, encoding) { - const fsNativePath = typeof p === `string` ? npath.fromPortablePath(p) : p; - return this.realFs.readFileSync(fsNativePath, encoding); - } - async readdirPromise(p, opts) { - return await new Promise((resolve, reject) => { - if (opts == null ? void 0 : opts.withFileTypes) { - this.realFs.readdir(npath.fromPortablePath(p), {withFileTypes: true}, this.makeCallback(resolve, reject)); - } else { - this.realFs.readdir(npath.fromPortablePath(p), this.makeCallback((value) => resolve(value), reject)); - } - }); - } - readdirSync(p, opts) { - if (opts == null ? void 0 : opts.withFileTypes) { - return this.realFs.readdirSync(npath.fromPortablePath(p), {withFileTypes: true}); - } else { - return this.realFs.readdirSync(npath.fromPortablePath(p)); - } - } - async readlinkPromise(p) { - return await new Promise((resolve, reject) => { - this.realFs.readlink(npath.fromPortablePath(p), this.makeCallback(resolve, reject)); - }).then((path) => { - return npath.toPortablePath(path); - }); - } - readlinkSync(p) { - return npath.toPortablePath(this.realFs.readlinkSync(npath.fromPortablePath(p))); - } - async truncatePromise(p, len) { - return await new Promise((resolve, reject) => { - this.realFs.truncate(npath.fromPortablePath(p), len, this.makeCallback(resolve, reject)); - }); - } - truncateSync(p, len) { - return this.realFs.truncateSync(npath.fromPortablePath(p), len); - } - async ftruncatePromise(fd, len) { - return await new Promise((resolve, reject) => { - this.realFs.ftruncate(fd, len, this.makeCallback(resolve, reject)); - }); - } - ftruncateSync(fd, len) { - return this.realFs.ftruncateSync(fd, len); - } - watch(p, a, b) { - return this.realFs.watch(npath.fromPortablePath(p), a, b); - } - watchFile(p, a, b) { - return this.realFs.watchFile(npath.fromPortablePath(p), a, b); - } - unwatchFile(p, cb) { - return this.realFs.unwatchFile(npath.fromPortablePath(p), cb); - } - makeCallback(resolve, reject) { - return (err, result) => { - if (err) { - reject(err); - } else { - resolve(result); - } - }; - } -} - -var Event; -(function(Event2) { - Event2["Change"] = `change`; - Event2["Stop"] = `stop`; -})(Event || (Event = {})); -var Status; -(function(Status2) { - Status2["Ready"] = `ready`; - Status2["Running"] = `running`; - Status2["Stopped"] = `stopped`; -})(Status || (Status = {})); -function assertStatus(current, expected) { - if (current !== expected) { - throw new Error(`Invalid StatWatcher status: expected '${expected}', got '${current}'`); - } -} -class CustomStatWatcher extends events.EventEmitter { - constructor(fakeFs, path, {bigint = false} = {}) { - super(); - this.status = Status.Ready; - this.changeListeners = new Map(); - this.startTimeout = null; - this.fakeFs = fakeFs; - this.path = path; - this.bigint = bigint; - this.lastStats = this.stat(); - } - static create(fakeFs, path, opts) { - const statWatcher = new CustomStatWatcher(fakeFs, path, opts); - statWatcher.start(); - return statWatcher; - } - start() { - assertStatus(this.status, Status.Ready); - this.status = Status.Running; - this.startTimeout = setTimeout(() => { - this.startTimeout = null; - if (!this.fakeFs.existsSync(this.path)) { - this.emit(Event.Change, this.lastStats, this.lastStats); - } - }, 3); - } - stop() { - assertStatus(this.status, Status.Running); - this.status = Status.Stopped; - if (this.startTimeout !== null) { - clearTimeout(this.startTimeout); - this.startTimeout = null; - } - this.emit(Event.Stop); - } - stat() { - try { - return this.fakeFs.statSync(this.path, {bigint: this.bigint}); - } catch (error) { - const statInstance = this.bigint ? new BigIntStatsEntry() : new StatEntry(); - return clearStats(statInstance); - } - } - makeInterval(opts) { - const interval = setInterval(() => { - const currentStats = this.stat(); - const previousStats = this.lastStats; - if (areStatsEqual(currentStats, previousStats)) - return; - this.lastStats = currentStats; - this.emit(Event.Change, currentStats, previousStats); - }, opts.interval); - return opts.persistent ? interval : interval.unref(); - } - registerChangeListener(listener, opts) { - this.addListener(Event.Change, listener); - this.changeListeners.set(listener, this.makeInterval(opts)); - } - unregisterChangeListener(listener) { - this.removeListener(Event.Change, listener); - const interval = this.changeListeners.get(listener); - if (typeof interval !== `undefined`) - clearInterval(interval); - this.changeListeners.delete(listener); - } - unregisterAllChangeListeners() { - for (const listener of this.changeListeners.keys()) { - this.unregisterChangeListener(listener); - } - } - hasChangeListeners() { - return this.changeListeners.size > 0; - } - ref() { - for (const interval of this.changeListeners.values()) - interval.ref(); - return this; - } - unref() { - for (const interval of this.changeListeners.values()) - interval.unref(); - return this; - } -} - -const statWatchersByFakeFS = new WeakMap(); -function watchFile(fakeFs, path, a, b) { - let bigint; - let persistent; - let interval; - let listener; - switch (typeof a) { - case `function`: - { - bigint = false; - persistent = true; - interval = 5007; - listener = a; - } - break; - default: - { - ({ - bigint = false, - persistent = true, - interval = 5007 - } = a); - listener = b; - } - break; - } - let statWatchers = statWatchersByFakeFS.get(fakeFs); - if (typeof statWatchers === `undefined`) - statWatchersByFakeFS.set(fakeFs, statWatchers = new Map()); - let statWatcher = statWatchers.get(path); - if (typeof statWatcher === `undefined`) { - statWatcher = CustomStatWatcher.create(fakeFs, path, {bigint}); - statWatchers.set(path, statWatcher); - } - statWatcher.registerChangeListener(listener, {persistent, interval}); - return statWatcher; -} -function unwatchFile(fakeFs, path, cb) { - const statWatchers = statWatchersByFakeFS.get(fakeFs); - if (typeof statWatchers === `undefined`) - return; - const statWatcher = statWatchers.get(path); - if (typeof statWatcher === `undefined`) - return; - if (typeof cb === `undefined`) - statWatcher.unregisterAllChangeListeners(); - else - statWatcher.unregisterChangeListener(cb); - if (!statWatcher.hasChangeListeners()) { - statWatcher.stop(); - statWatchers.delete(path); - } -} -function unwatchAllFiles(fakeFs) { - const statWatchers = statWatchersByFakeFS.get(fakeFs); - if (typeof statWatchers === `undefined`) - return; - for (const path of statWatchers.keys()) { - unwatchFile(fakeFs, path); - } -} - -var __defProp$4 = Object.defineProperty; -var __getOwnPropSymbols$5 = Object.getOwnPropertySymbols; -var __hasOwnProp$5 = Object.prototype.hasOwnProperty; -var __propIsEnum$5 = Object.prototype.propertyIsEnumerable; -var __defNormalProp$4 = (obj, key, value) => key in obj ? __defProp$4(obj, key, {enumerable: true, configurable: true, writable: true, value}) : obj[key] = value; -var __spreadValues$4 = (a, b) => { - for (var prop in b || (b = {})) - if (__hasOwnProp$5.call(b, prop)) - __defNormalProp$4(a, prop, b[prop]); - if (__getOwnPropSymbols$5) - for (var prop of __getOwnPropSymbols$5(b)) { - if (__propIsEnum$5.call(b, prop)) - __defNormalProp$4(a, prop, b[prop]); - } - return a; -}; -const DEFAULT_COMPRESSION_LEVEL = `mixed`; -function toUnixTimestamp(time) { - if (typeof time === `string` && String(+time) === time) - return +time; - if (Number.isFinite(time)) { - if (time < 0) { - return Date.now() / 1e3; - } else { - return time; - } - } - if (nodeUtils.types.isDate(time)) - return time.getTime() / 1e3; - throw new Error(`Invalid time`); -} -function makeEmptyArchive() { - 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 - ]); -} -class ZipFS extends BasePortableFakeFS { - constructor(source, opts) { - 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 = false; - this.readOnly = false; - this.libzip = opts.libzip; - const pathOptions = opts; - this.level = typeof pathOptions.level !== `undefined` ? pathOptions.level : DEFAULT_COMPRESSION_LEVEL; - source != null ? source : source = makeEmptyArchive(); - if (typeof source === `string`) { - const {baseFs = new NodeFS()} = pathOptions; - this.baseFs = baseFs; - this.path = source; - } else { - this.path = null; - this.baseFs = null; - } - if (opts.stats) { - this.stats = opts.stats; - } else { - if (typeof source === `string`) { - try { - this.stats = this.baseFs.statSync(source); - } catch (error) { - if (error.code === `ENOENT` && pathOptions.create) { - this.stats = makeDefaultStats(); - } else { - throw error; - } - } - } else { - this.stats = makeDefaultStats(); - } - } - const errPtr = this.libzip.malloc(4); - try { - let flags = 0; - if (typeof source === `string` && pathOptions.create) - flags |= this.libzip.ZIP_CREATE | this.libzip.ZIP_TRUNCATE; - if (opts.readOnly) { - flags |= this.libzip.ZIP_RDONLY; - this.readOnly = true; - } - if (typeof source === `string`) { - this.zip = this.libzip.open(npath.fromPortablePath(source), flags, errPtr); - } else { - const lzSource = this.allocateUnattachedSource(source); - try { - this.zip = this.libzip.openFromSource(lzSource, flags, errPtr); - this.lzSource = lzSource; - } catch (error) { - this.libzip.source.free(lzSource); - throw error; - } - } - if (this.zip === 0) { - const error = this.libzip.struct.errorS(); - this.libzip.error.initWithCode(error, this.libzip.getValue(errPtr, `i32`)); - throw this.makeLibzipError(error); - } - } finally { - this.libzip.free(errPtr); - } - this.listings.set(PortablePath.root, new Set()); - const entryCount = this.libzip.getNumEntries(this.zip, 0); - for (let t = 0; t < entryCount; ++t) { - const raw = this.libzip.getName(this.zip, t, 0); - if (ppath.isAbsolute(raw)) - continue; - const p = ppath.resolve(PortablePath.root, raw); - this.registerEntry(p, t); - if (raw.endsWith(`/`)) { - this.registerListing(p); - } - } - this.symlinkCount = this.libzip.ext.countSymlinks(this.zip); - if (this.symlinkCount === -1) - throw this.makeLibzipError(this.libzip.getError(this.zip)); - this.ready = true; - } - makeLibzipError(error) { - const errorCode = this.libzip.struct.errorCodeZip(error); - const strerror = this.libzip.error.strerror(error); - const libzipError = new LibzipError(strerror, this.libzip.errors[errorCode]); - if (errorCode === this.libzip.errors.ZIP_ER_CHANGED) - throw new Error(`Assertion failed: Unexpected libzip error: ${libzipError.message}`); - return libzipError; - } - getExtractHint(hints) { - for (const fileName of this.entries.keys()) { - const ext = this.pathUtils.extname(fileName); - if (hints.relevantExtensions.has(ext)) { - return true; - } - } - return false; - } - getAllFiles() { - return Array.from(this.entries.keys()); - } - getRealPath() { - if (!this.path) - throw new Error(`ZipFS don't have real paths when loaded from a buffer`); - return this.path; - } - getBufferAndClose() { - this.prepareClose(); - if (!this.lzSource) - throw new Error(`ZipFS was not created from a Buffer`); - try { - this.libzip.source.keep(this.lzSource); - if (this.libzip.close(this.zip) === -1) - throw this.makeLibzipError(this.libzip.getError(this.zip)); - if (this.libzip.source.open(this.lzSource) === -1) - throw this.makeLibzipError(this.libzip.source.error(this.lzSource)); - if (this.libzip.source.seek(this.lzSource, 0, 0, this.libzip.SEEK_END) === -1) - throw this.makeLibzipError(this.libzip.source.error(this.lzSource)); - const size = this.libzip.source.tell(this.lzSource); - if (size === -1) - throw this.makeLibzipError(this.libzip.source.error(this.lzSource)); - if (this.libzip.source.seek(this.lzSource, 0, 0, this.libzip.SEEK_SET) === -1) - throw this.makeLibzipError(this.libzip.source.error(this.lzSource)); - const buffer = this.libzip.malloc(size); - if (!buffer) - throw new Error(`Couldn't allocate enough memory`); - try { - const rc = this.libzip.source.read(this.lzSource, buffer, size); - if (rc === -1) - throw this.makeLibzipError(this.libzip.source.error(this.lzSource)); - else if (rc < size) - throw new Error(`Incomplete read`); - else if (rc > size) - throw new Error(`Overread`); - const memory = this.libzip.HEAPU8.subarray(buffer, buffer + size); - return Buffer.from(memory); - } finally { - this.libzip.free(buffer); - } - } finally { - this.libzip.source.close(this.lzSource); - this.libzip.source.free(this.lzSource); - this.ready = false; - } - } - prepareClose() { - if (!this.ready) - throw EBUSY(`archive closed, close`); - unwatchAllFiles(this); - } - saveAndClose() { - if (!this.path || !this.baseFs) - throw new Error(`ZipFS cannot be saved and must be discarded when loaded from a buffer`); - this.prepareClose(); - if (this.readOnly) { - this.discardAndClose(); - return; - } - const newMode = this.baseFs.existsSync(this.path) || this.stats.mode === DEFAULT_MODE ? void 0 : this.stats.mode; - if (this.entries.size === 0) { - this.discardAndClose(); - this.baseFs.writeFileSync(this.path, makeEmptyArchive(), {mode: newMode}); - } else { - const rc = this.libzip.close(this.zip); - if (rc === -1) - throw this.makeLibzipError(this.libzip.getError(this.zip)); - if (typeof newMode !== `undefined`) { - this.baseFs.chmodSync(this.path, newMode); - } - } - this.ready = false; - } - discardAndClose() { - this.prepareClose(); - this.libzip.discard(this.zip); - this.ready = false; - } - resolve(p) { - return ppath.resolve(PortablePath.root, p); - } - async openPromise(p, flags, mode) { - return this.openSync(p, flags, mode); - } - openSync(p, flags, mode) { - const fd = this.nextFd++; - this.fds.set(fd, {cursor: 0, p}); - return fd; - } - hasOpenFileHandles() { - return !!this.fds.size; - } - async opendirPromise(p, opts) { - return this.opendirSync(p, opts); - } - opendirSync(p, opts = {}) { - const resolvedP = this.resolveFilename(`opendir '${p}'`, p); - if (!this.entries.has(resolvedP) && !this.listings.has(resolvedP)) - throw ENOENT(`opendir '${p}'`); - const directoryListing = this.listings.get(resolvedP); - if (!directoryListing) - throw ENOTDIR(`opendir '${p}'`); - const entries = [...directoryListing]; - const fd = this.openSync(resolvedP, `r`); - const onClose = () => { - this.closeSync(fd); - }; - return opendir(this, resolvedP, entries, {onClose}); - } - async readPromise(fd, buffer, offset, length, position) { - return this.readSync(fd, buffer, offset, length, position); - } - readSync(fd, buffer, offset = 0, length = buffer.byteLength, position = -1) { - const entry = this.fds.get(fd); - if (typeof entry === `undefined`) - throw EBADF(`read`); - const realPosition = position === -1 || position === null ? entry.cursor : position; - const source = this.readFileSync(entry.p); - source.copy(buffer, offset, realPosition, realPosition + length); - const bytesRead = Math.max(0, Math.min(source.length - realPosition, length)); - if (position === -1 || position === null) - entry.cursor += bytesRead; - return bytesRead; - } - async writePromise(fd, buffer, offset, length, position) { - if (typeof buffer === `string`) { - return this.writeSync(fd, buffer, position); - } else { - return this.writeSync(fd, buffer, offset, length, position); - } - } - writeSync(fd, buffer, offset, length, position) { - const entry = this.fds.get(fd); - if (typeof entry === `undefined`) - throw EBADF(`read`); - throw new Error(`Unimplemented`); - } - async closePromise(fd) { - return this.closeSync(fd); - } - closeSync(fd) { - const entry = this.fds.get(fd); - if (typeof entry === `undefined`) - throw EBADF(`read`); - this.fds.delete(fd); - } - createReadStream(p, {encoding} = {}) { - if (p === null) - throw new Error(`Unimplemented`); - const fd = this.openSync(p, `r`); - const stream$1 = Object.assign(new stream.PassThrough({ - emitClose: true, - autoDestroy: true, - destroy: (error, callback) => { - clearImmediate(immediate); - this.closeSync(fd); - callback(error); - } - }), { - close() { - stream$1.destroy(); - }, - bytesRead: 0, - path: p - }); - const immediate = setImmediate(async () => { - try { - const data = await this.readFilePromise(p, encoding); - stream$1.bytesRead = data.length; - stream$1.end(data); - } catch (error) { - stream$1.destroy(error); - } - }); - return stream$1; - } - createWriteStream(p, {encoding} = {}) { - if (this.readOnly) - throw EROFS(`open '${p}'`); - if (p === null) - throw new Error(`Unimplemented`); - const chunks = []; - const fd = this.openSync(p, `w`); - const stream$1 = Object.assign(new stream.PassThrough({ - autoDestroy: true, - emitClose: true, - destroy: (error, callback) => { - try { - if (error) { - callback(error); - } else { - this.writeFileSync(p, Buffer.concat(chunks), encoding); - callback(null); - } - } catch (err) { - callback(err); - } finally { - this.closeSync(fd); - } - } - }), { - bytesWritten: 0, - path: p, - close() { - stream$1.destroy(); - } - }); - stream$1.on(`data`, (chunk) => { - const chunkBuffer = Buffer.from(chunk); - stream$1.bytesWritten += chunkBuffer.length; - chunks.push(chunkBuffer); - }); - return stream$1; - } - async realpathPromise(p) { - return this.realpathSync(p); - } - realpathSync(p) { - const resolvedP = this.resolveFilename(`lstat '${p}'`, p); - if (!this.entries.has(resolvedP) && !this.listings.has(resolvedP)) - throw ENOENT(`lstat '${p}'`); - return resolvedP; - } - async existsPromise(p) { - return this.existsSync(p); - } - existsSync(p) { - if (!this.ready) - throw EBUSY(`archive closed, existsSync '${p}'`); - if (this.symlinkCount === 0) { - const resolvedP2 = ppath.resolve(PortablePath.root, p); - return this.entries.has(resolvedP2) || this.listings.has(resolvedP2); - } - let resolvedP; - try { - resolvedP = this.resolveFilename(`stat '${p}'`, p, void 0, false); - } catch (error) { - return false; - } - if (resolvedP === void 0) - return false; - return this.entries.has(resolvedP) || this.listings.has(resolvedP); - } - async accessPromise(p, mode) { - return this.accessSync(p, mode); - } - accessSync(p, mode = fs.constants.F_OK) { - const resolvedP = this.resolveFilename(`access '${p}'`, p); - if (!this.entries.has(resolvedP) && !this.listings.has(resolvedP)) - throw ENOENT(`access '${p}'`); - if (this.readOnly && mode & fs.constants.W_OK) { - throw EROFS(`access '${p}'`); - } - } - async statPromise(p, opts = {bigint: false}) { - if (opts.bigint) - return this.statSync(p, {bigint: true}); - return this.statSync(p); - } - statSync(p, opts = {bigint: false, throwIfNoEntry: true}) { - const resolvedP = this.resolveFilename(`stat '${p}'`, p, void 0, opts.throwIfNoEntry); - if (resolvedP === void 0) - return void 0; - if (!this.entries.has(resolvedP) && !this.listings.has(resolvedP)) { - if (opts.throwIfNoEntry === false) - return void 0; - throw ENOENT(`stat '${p}'`); - } - if (p[p.length - 1] === `/` && !this.listings.has(resolvedP)) - throw ENOTDIR(`stat '${p}'`); - return this.statImpl(`stat '${p}'`, resolvedP, opts); - } - async fstatPromise(fd, opts) { - return this.fstatSync(fd, opts); - } - fstatSync(fd, opts) { - const entry = this.fds.get(fd); - if (typeof entry === `undefined`) - throw EBADF(`fstatSync`); - const {p} = entry; - const resolvedP = this.resolveFilename(`stat '${p}'`, p); - if (!this.entries.has(resolvedP) && !this.listings.has(resolvedP)) - throw ENOENT(`stat '${p}'`); - if (p[p.length - 1] === `/` && !this.listings.has(resolvedP)) - throw ENOTDIR(`stat '${p}'`); - return this.statImpl(`fstat '${p}'`, resolvedP, opts); - } - async lstatPromise(p, opts = {bigint: false}) { - if (opts.bigint) - return this.lstatSync(p, {bigint: true}); - return this.lstatSync(p); - } - lstatSync(p, opts = {bigint: false, throwIfNoEntry: true}) { - const resolvedP = this.resolveFilename(`lstat '${p}'`, p, false, opts.throwIfNoEntry); - if (resolvedP === void 0) - return void 0; - if (!this.entries.has(resolvedP) && !this.listings.has(resolvedP)) { - if (opts.throwIfNoEntry === false) - return void 0; - throw ENOENT(`lstat '${p}'`); - } - if (p[p.length - 1] === `/` && !this.listings.has(resolvedP)) - throw ENOTDIR(`lstat '${p}'`); - return this.statImpl(`lstat '${p}'`, resolvedP, opts); - } - statImpl(reason, p, opts = {}) { - const entry = this.entries.get(p); - if (typeof entry !== `undefined`) { - const stat = this.libzip.struct.statS(); - const rc = this.libzip.statIndex(this.zip, entry, 0, 0, stat); - if (rc === -1) - throw this.makeLibzipError(this.libzip.getError(this.zip)); - const uid = this.stats.uid; - const gid = this.stats.gid; - const size = this.libzip.struct.statSize(stat) >>> 0; - const blksize = 512; - const blocks = Math.ceil(size / blksize); - const mtimeMs = (this.libzip.struct.statMtime(stat) >>> 0) * 1e3; - const atimeMs = mtimeMs; - const birthtimeMs = mtimeMs; - const ctimeMs = mtimeMs; - const atime = new Date(atimeMs); - const birthtime = new Date(birthtimeMs); - const ctime = new Date(ctimeMs); - const mtime = new Date(mtimeMs); - const type = this.listings.has(p) ? S_IFDIR : this.isSymbolicLink(entry) ? S_IFLNK : S_IFREG; - const defaultMode = type === S_IFDIR ? 493 : 420; - const mode = type | this.getUnixMode(entry, defaultMode) & 511; - const crc = this.libzip.struct.statCrc(stat); - const statInstance = Object.assign(new StatEntry(), {uid, gid, size, blksize, blocks, atime, birthtime, ctime, mtime, atimeMs, birthtimeMs, ctimeMs, mtimeMs, mode, crc}); - return opts.bigint === true ? convertToBigIntStats(statInstance) : statInstance; - } - if (this.listings.has(p)) { - const uid = this.stats.uid; - const gid = this.stats.gid; - const size = 0; - const blksize = 512; - const blocks = 0; - const atimeMs = this.stats.mtimeMs; - const birthtimeMs = this.stats.mtimeMs; - const ctimeMs = this.stats.mtimeMs; - const mtimeMs = this.stats.mtimeMs; - const atime = new Date(atimeMs); - const birthtime = new Date(birthtimeMs); - const ctime = new Date(ctimeMs); - const mtime = new Date(mtimeMs); - const mode = S_IFDIR | 493; - const crc = 0; - const statInstance = Object.assign(new StatEntry(), {uid, gid, size, blksize, blocks, atime, birthtime, ctime, mtime, atimeMs, birthtimeMs, ctimeMs, mtimeMs, mode, crc}); - return opts.bigint === true ? convertToBigIntStats(statInstance) : statInstance; - } - throw new Error(`Unreachable`); - } - getUnixMode(index, defaultMode) { - const rc = this.libzip.file.getExternalAttributes(this.zip, index, 0, 0, this.libzip.uint08S, this.libzip.uint32S); - if (rc === -1) - throw this.makeLibzipError(this.libzip.getError(this.zip)); - const opsys = this.libzip.getValue(this.libzip.uint08S, `i8`) >>> 0; - if (opsys !== this.libzip.ZIP_OPSYS_UNIX) - return defaultMode; - return this.libzip.getValue(this.libzip.uint32S, `i32`) >>> 16; - } - registerListing(p) { - const existingListing = this.listings.get(p); - if (existingListing) - return existingListing; - const parentListing = this.registerListing(ppath.dirname(p)); - parentListing.add(ppath.basename(p)); - const newListing = new Set(); - this.listings.set(p, newListing); - return newListing; - } - registerEntry(p, index) { - const parentListing = this.registerListing(ppath.dirname(p)); - parentListing.add(ppath.basename(p)); - this.entries.set(p, index); - } - unregisterListing(p) { - this.listings.delete(p); - const parentListing = this.listings.get(ppath.dirname(p)); - parentListing == null ? void 0 : parentListing.delete(ppath.basename(p)); - } - unregisterEntry(p) { - this.unregisterListing(p); - const entry = this.entries.get(p); - this.entries.delete(p); - if (typeof entry === `undefined`) - return; - this.fileSources.delete(entry); - if (this.isSymbolicLink(entry)) { - this.symlinkCount--; - } - } - deleteEntry(p, index) { - this.unregisterEntry(p); - const rc = this.libzip.delete(this.zip, index); - if (rc === -1) { - throw this.makeLibzipError(this.libzip.getError(this.zip)); - } - } - resolveFilename(reason, p, resolveLastComponent = true, throwIfNoEntry = true) { - if (!this.ready) - throw EBUSY(`archive closed, ${reason}`); - let resolvedP = ppath.resolve(PortablePath.root, p); - if (resolvedP === `/`) - return PortablePath.root; - const fileIndex = this.entries.get(resolvedP); - if (resolveLastComponent && fileIndex !== void 0) { - if (this.symlinkCount !== 0 && this.isSymbolicLink(fileIndex)) { - const target = this.getFileSource(fileIndex).toString(); - return this.resolveFilename(reason, ppath.resolve(ppath.dirname(resolvedP), target), true, throwIfNoEntry); - } else { - return resolvedP; - } - } - while (true) { - const parentP = this.resolveFilename(reason, ppath.dirname(resolvedP), true, throwIfNoEntry); - if (parentP === void 0) - return parentP; - const isDir = this.listings.has(parentP); - const doesExist = this.entries.has(parentP); - if (!isDir && !doesExist) { - if (throwIfNoEntry === false) - return void 0; - throw ENOENT(reason); - } - if (!isDir) - throw ENOTDIR(reason); - resolvedP = ppath.resolve(parentP, ppath.basename(resolvedP)); - if (!resolveLastComponent || this.symlinkCount === 0) - break; - const index = this.libzip.name.locate(this.zip, resolvedP.slice(1)); - if (index === -1) - break; - if (this.isSymbolicLink(index)) { - const target = this.getFileSource(index).toString(); - resolvedP = ppath.resolve(ppath.dirname(resolvedP), target); - } else { - break; - } - } - return resolvedP; - } - allocateBuffer(content) { - if (!Buffer.isBuffer(content)) - content = Buffer.from(content); - const buffer = this.libzip.malloc(content.byteLength); - if (!buffer) - throw new Error(`Couldn't allocate enough memory`); - const heap = new Uint8Array(this.libzip.HEAPU8.buffer, buffer, content.byteLength); - heap.set(content); - return {buffer, byteLength: content.byteLength}; - } - allocateUnattachedSource(content) { - const error = this.libzip.struct.errorS(); - const {buffer, byteLength} = this.allocateBuffer(content); - const source = this.libzip.source.fromUnattachedBuffer(buffer, byteLength, 0, true, error); - if (source === 0) { - this.libzip.free(error); - throw this.makeLibzipError(error); - } - return source; - } - allocateSource(content) { - const {buffer, byteLength} = this.allocateBuffer(content); - const source = this.libzip.source.fromBuffer(this.zip, buffer, byteLength, 0, true); - if (source === 0) { - this.libzip.free(buffer); - throw this.makeLibzipError(this.libzip.getError(this.zip)); - } - return source; - } - setFileSource(p, content) { - const buffer = Buffer.isBuffer(content) ? content : Buffer.from(content); - const target = ppath.relative(PortablePath.root, p); - const lzSource = this.allocateSource(content); - try { - const newIndex = this.libzip.file.add(this.zip, target, lzSource, this.libzip.ZIP_FL_OVERWRITE); - if (newIndex === -1) - throw this.makeLibzipError(this.libzip.getError(this.zip)); - if (this.level !== `mixed`) { - const method = this.level === 0 ? this.libzip.ZIP_CM_STORE : this.libzip.ZIP_CM_DEFLATE; - const rc = this.libzip.file.setCompression(this.zip, newIndex, 0, method, this.level); - if (rc === -1) { - throw this.makeLibzipError(this.libzip.getError(this.zip)); - } - } - this.fileSources.set(newIndex, buffer); - return newIndex; - } catch (error) { - this.libzip.source.free(lzSource); - throw error; - } - } - isSymbolicLink(index) { - if (this.symlinkCount === 0) - return false; - const attrs = this.libzip.file.getExternalAttributes(this.zip, index, 0, 0, this.libzip.uint08S, this.libzip.uint32S); - if (attrs === -1) - throw this.makeLibzipError(this.libzip.getError(this.zip)); - const opsys = this.libzip.getValue(this.libzip.uint08S, `i8`) >>> 0; - if (opsys !== this.libzip.ZIP_OPSYS_UNIX) - return false; - const attributes = this.libzip.getValue(this.libzip.uint32S, `i32`) >>> 16; - return (attributes & S_IFMT) === S_IFLNK; - } - getFileSource(index, opts = {asyncDecompress: false}) { - const cachedFileSource = this.fileSources.get(index); - if (typeof cachedFileSource !== `undefined`) - return cachedFileSource; - const stat = this.libzip.struct.statS(); - const rc = this.libzip.statIndex(this.zip, index, 0, 0, stat); - if (rc === -1) - throw this.makeLibzipError(this.libzip.getError(this.zip)); - const size = this.libzip.struct.statCompSize(stat); - const compressionMethod = this.libzip.struct.statCompMethod(stat); - const buffer = this.libzip.malloc(size); - try { - const file = this.libzip.fopenIndex(this.zip, index, 0, this.libzip.ZIP_FL_COMPRESSED); - if (file === 0) - throw this.makeLibzipError(this.libzip.getError(this.zip)); - try { - const rc2 = this.libzip.fread(file, buffer, size, 0); - if (rc2 === -1) - throw this.makeLibzipError(this.libzip.file.getError(file)); - else if (rc2 < size) - throw new Error(`Incomplete read`); - else if (rc2 > size) - throw new Error(`Overread`); - const memory = this.libzip.HEAPU8.subarray(buffer, buffer + size); - const data = Buffer.from(memory); - if (compressionMethod === 0) { - this.fileSources.set(index, data); - return data; - } else if (opts.asyncDecompress) { - return new Promise((resolve, reject) => { - zlib__default.default.inflateRaw(data, (error, result) => { - if (error) { - reject(error); - } else { - this.fileSources.set(index, result); - resolve(result); - } - }); - }); - } else { - const decompressedData = zlib__default.default.inflateRawSync(data); - this.fileSources.set(index, decompressedData); - return decompressedData; - } - } finally { - this.libzip.fclose(file); - } - } finally { - this.libzip.free(buffer); - } - } - async fchmodPromise(fd, mask) { - return this.chmodPromise(this.fdToPath(fd, `fchmod`), mask); - } - fchmodSync(fd, mask) { - return this.chmodSync(this.fdToPath(fd, `fchmodSync`), mask); - } - async chmodPromise(p, mask) { - return this.chmodSync(p, mask); - } - chmodSync(p, mask) { - if (this.readOnly) - throw EROFS(`chmod '${p}'`); - mask &= 493; - const resolvedP = this.resolveFilename(`chmod '${p}'`, p, false); - const entry = this.entries.get(resolvedP); - if (typeof entry === `undefined`) - throw new Error(`Assertion failed: The entry should have been registered (${resolvedP})`); - const oldMod = this.getUnixMode(entry, S_IFREG | 0); - const newMod = oldMod & ~511 | mask; - const rc = this.libzip.file.setExternalAttributes(this.zip, entry, 0, 0, this.libzip.ZIP_OPSYS_UNIX, newMod << 16); - if (rc === -1) { - throw this.makeLibzipError(this.libzip.getError(this.zip)); - } - } - async chownPromise(p, uid, gid) { - return this.chownSync(p, uid, gid); - } - chownSync(p, uid, gid) { - throw new Error(`Unimplemented`); - } - async renamePromise(oldP, newP) { - return this.renameSync(oldP, newP); - } - renameSync(oldP, newP) { - throw new Error(`Unimplemented`); - } - async copyFilePromise(sourceP, destP, flags) { - const {indexSource, indexDest, resolvedDestP} = this.prepareCopyFile(sourceP, destP, flags); - const source = await this.getFileSource(indexSource, {asyncDecompress: true}); - const newIndex = this.setFileSource(resolvedDestP, source); - if (newIndex !== indexDest) { - this.registerEntry(resolvedDestP, newIndex); - } - } - copyFileSync(sourceP, destP, flags = 0) { - const {indexSource, indexDest, resolvedDestP} = this.prepareCopyFile(sourceP, destP, flags); - const source = this.getFileSource(indexSource); - const newIndex = this.setFileSource(resolvedDestP, source); - if (newIndex !== indexDest) { - this.registerEntry(resolvedDestP, newIndex); - } - } - prepareCopyFile(sourceP, destP, flags = 0) { - if (this.readOnly) - throw EROFS(`copyfile '${sourceP} -> '${destP}'`); - if ((flags & fs.constants.COPYFILE_FICLONE_FORCE) !== 0) - throw ENOSYS(`unsupported clone operation`, `copyfile '${sourceP}' -> ${destP}'`); - const resolvedSourceP = this.resolveFilename(`copyfile '${sourceP} -> ${destP}'`, sourceP); - const indexSource = this.entries.get(resolvedSourceP); - if (typeof indexSource === `undefined`) - throw EINVAL(`copyfile '${sourceP}' -> '${destP}'`); - const resolvedDestP = this.resolveFilename(`copyfile '${sourceP}' -> ${destP}'`, destP); - const indexDest = this.entries.get(resolvedDestP); - if ((flags & (fs.constants.COPYFILE_EXCL | fs.constants.COPYFILE_FICLONE_FORCE)) !== 0 && typeof indexDest !== `undefined`) - throw EEXIST(`copyfile '${sourceP}' -> '${destP}'`); - return { - indexSource, - resolvedDestP, - indexDest - }; - } - async appendFilePromise(p, content, opts) { - if (this.readOnly) - throw EROFS(`open '${p}'`); - if (typeof opts === `undefined`) - opts = {flag: `a`}; - else if (typeof opts === `string`) - opts = {flag: `a`, encoding: opts}; - else if (typeof opts.flag === `undefined`) - opts = __spreadValues$4({flag: `a`}, opts); - return this.writeFilePromise(p, content, opts); - } - appendFileSync(p, content, opts = {}) { - if (this.readOnly) - throw EROFS(`open '${p}'`); - if (typeof opts === `undefined`) - opts = {flag: `a`}; - else if (typeof opts === `string`) - opts = {flag: `a`, encoding: opts}; - else if (typeof opts.flag === `undefined`) - opts = __spreadValues$4({flag: `a`}, opts); - return this.writeFileSync(p, content, opts); - } - fdToPath(fd, reason) { - var _a; - const path = (_a = this.fds.get(fd)) == null ? void 0 : _a.p; - if (typeof path === `undefined`) - throw EBADF(reason); - return path; - } - async writeFilePromise(p, content, opts) { - const {encoding, mode, index, resolvedP} = this.prepareWriteFile(p, opts); - if (index !== void 0 && typeof opts === `object` && opts.flag && opts.flag.includes(`a`)) - content = Buffer.concat([await this.getFileSource(index, {asyncDecompress: true}), Buffer.from(content)]); - if (encoding !== null) - content = content.toString(encoding); - const newIndex = this.setFileSource(resolvedP, content); - if (newIndex !== index) - this.registerEntry(resolvedP, newIndex); - if (mode !== null) { - await this.chmodPromise(resolvedP, mode); - } - } - writeFileSync(p, content, opts) { - const {encoding, mode, index, resolvedP} = this.prepareWriteFile(p, opts); - if (index !== void 0 && typeof opts === `object` && opts.flag && opts.flag.includes(`a`)) - content = Buffer.concat([this.getFileSource(index), Buffer.from(content)]); - if (encoding !== null) - content = content.toString(encoding); - const newIndex = this.setFileSource(resolvedP, content); - if (newIndex !== index) - this.registerEntry(resolvedP, newIndex); - if (mode !== null) { - this.chmodSync(resolvedP, mode); - } - } - prepareWriteFile(p, opts) { - if (typeof p === `number`) - p = this.fdToPath(p, `read`); - if (this.readOnly) - throw EROFS(`open '${p}'`); - const resolvedP = this.resolveFilename(`open '${p}'`, p); - if (this.listings.has(resolvedP)) - throw EISDIR(`open '${p}'`); - let encoding = null, mode = null; - if (typeof opts === `string`) { - encoding = opts; - } else if (typeof opts === `object`) { - ({ - encoding = null, - mode = null - } = opts); - } - const index = this.entries.get(resolvedP); - return { - encoding, - mode, - resolvedP, - index - }; - } - async unlinkPromise(p) { - return this.unlinkSync(p); - } - unlinkSync(p) { - if (this.readOnly) - throw EROFS(`unlink '${p}'`); - const resolvedP = this.resolveFilename(`unlink '${p}'`, p); - if (this.listings.has(resolvedP)) - throw EISDIR(`unlink '${p}'`); - const index = this.entries.get(resolvedP); - if (typeof index === `undefined`) - throw EINVAL(`unlink '${p}'`); - this.deleteEntry(resolvedP, index); - } - async utimesPromise(p, atime, mtime) { - return this.utimesSync(p, atime, mtime); - } - utimesSync(p, atime, mtime) { - if (this.readOnly) - throw EROFS(`utimes '${p}'`); - const resolvedP = this.resolveFilename(`utimes '${p}'`, p); - this.utimesImpl(resolvedP, mtime); - } - async lutimesPromise(p, atime, mtime) { - return this.lutimesSync(p, atime, mtime); - } - lutimesSync(p, atime, mtime) { - if (this.readOnly) - throw EROFS(`lutimes '${p}'`); - const resolvedP = this.resolveFilename(`utimes '${p}'`, p, false); - this.utimesImpl(resolvedP, mtime); - } - utimesImpl(resolvedP, mtime) { - if (this.listings.has(resolvedP)) { - if (!this.entries.has(resolvedP)) - this.hydrateDirectory(resolvedP); - } - const entry = this.entries.get(resolvedP); - if (entry === void 0) - throw new Error(`Unreachable`); - const rc = this.libzip.file.setMtime(this.zip, entry, 0, toUnixTimestamp(mtime), 0); - if (rc === -1) { - throw this.makeLibzipError(this.libzip.getError(this.zip)); - } - } - async mkdirPromise(p, opts) { - return this.mkdirSync(p, opts); - } - mkdirSync(p, {mode = 493, recursive = false} = {}) { - if (recursive) - return this.mkdirpSync(p, {chmod: mode}); - if (this.readOnly) - throw EROFS(`mkdir '${p}'`); - const resolvedP = this.resolveFilename(`mkdir '${p}'`, p); - if (this.entries.has(resolvedP) || this.listings.has(resolvedP)) - throw EEXIST(`mkdir '${p}'`); - this.hydrateDirectory(resolvedP); - this.chmodSync(resolvedP, mode); - return void 0; - } - async rmdirPromise(p, opts) { - return this.rmdirSync(p, opts); - } - rmdirSync(p, {recursive = false} = {}) { - if (this.readOnly) - throw EROFS(`rmdir '${p}'`); - if (recursive) { - this.removeSync(p); - return; - } - const resolvedP = this.resolveFilename(`rmdir '${p}'`, p); - const directoryListing = this.listings.get(resolvedP); - if (!directoryListing) - throw ENOTDIR(`rmdir '${p}'`); - if (directoryListing.size > 0) - throw ENOTEMPTY(`rmdir '${p}'`); - const index = this.entries.get(resolvedP); - if (typeof index === `undefined`) - throw EINVAL(`rmdir '${p}'`); - this.deleteEntry(p, index); - } - hydrateDirectory(resolvedP) { - const index = this.libzip.dir.add(this.zip, ppath.relative(PortablePath.root, resolvedP)); - if (index === -1) - throw this.makeLibzipError(this.libzip.getError(this.zip)); - this.registerListing(resolvedP); - this.registerEntry(resolvedP, index); - return index; - } - async linkPromise(existingP, newP) { - return this.linkSync(existingP, newP); - } - linkSync(existingP, newP) { - throw EOPNOTSUPP(`link '${existingP}' -> '${newP}'`); - } - async symlinkPromise(target, p) { - return this.symlinkSync(target, p); - } - symlinkSync(target, p) { - if (this.readOnly) - throw EROFS(`symlink '${target}' -> '${p}'`); - const resolvedP = this.resolveFilename(`symlink '${target}' -> '${p}'`, p); - if (this.listings.has(resolvedP)) - throw EISDIR(`symlink '${target}' -> '${p}'`); - if (this.entries.has(resolvedP)) - throw EEXIST(`symlink '${target}' -> '${p}'`); - const index = this.setFileSource(resolvedP, target); - this.registerEntry(resolvedP, index); - const rc = this.libzip.file.setExternalAttributes(this.zip, index, 0, 0, this.libzip.ZIP_OPSYS_UNIX, (S_IFLNK | 511) << 16); - if (rc === -1) - throw this.makeLibzipError(this.libzip.getError(this.zip)); - this.symlinkCount += 1; - } - async readFilePromise(p, encoding) { - if (typeof encoding === `object`) - encoding = encoding ? encoding.encoding : void 0; - const data = await this.readFileBuffer(p, {asyncDecompress: true}); - return encoding ? data.toString(encoding) : data; - } - readFileSync(p, encoding) { - if (typeof encoding === `object`) - encoding = encoding ? encoding.encoding : void 0; - const data = this.readFileBuffer(p); - return encoding ? data.toString(encoding) : data; - } - readFileBuffer(p, opts = {asyncDecompress: false}) { - if (typeof p === `number`) - p = this.fdToPath(p, `read`); - const resolvedP = this.resolveFilename(`open '${p}'`, p); - if (!this.entries.has(resolvedP) && !this.listings.has(resolvedP)) - throw ENOENT(`open '${p}'`); - if (p[p.length - 1] === `/` && !this.listings.has(resolvedP)) - throw ENOTDIR(`open '${p}'`); - if (this.listings.has(resolvedP)) - throw EISDIR(`read`); - const entry = this.entries.get(resolvedP); - if (entry === void 0) - throw new Error(`Unreachable`); - return this.getFileSource(entry, opts); - } - async readdirPromise(p, opts) { - return this.readdirSync(p, opts); - } - readdirSync(p, opts) { - const resolvedP = this.resolveFilename(`scandir '${p}'`, p); - if (!this.entries.has(resolvedP) && !this.listings.has(resolvedP)) - throw ENOENT(`scandir '${p}'`); - const directoryListing = this.listings.get(resolvedP); - if (!directoryListing) - throw ENOTDIR(`scandir '${p}'`); - const entries = [...directoryListing]; - if (!(opts == null ? void 0 : opts.withFileTypes)) - return entries; - return entries.map((name) => { - return Object.assign(this.statImpl(`lstat`, ppath.join(p, name)), { - name - }); - }); - } - async readlinkPromise(p) { - const entry = this.prepareReadlink(p); - return (await this.getFileSource(entry, {asyncDecompress: true})).toString(); - } - readlinkSync(p) { - const entry = this.prepareReadlink(p); - return this.getFileSource(entry).toString(); - } - prepareReadlink(p) { - const resolvedP = this.resolveFilename(`readlink '${p}'`, p, false); - if (!this.entries.has(resolvedP) && !this.listings.has(resolvedP)) - throw ENOENT(`readlink '${p}'`); - if (p[p.length - 1] === `/` && !this.listings.has(resolvedP)) - throw ENOTDIR(`open '${p}'`); - if (this.listings.has(resolvedP)) - throw EINVAL(`readlink '${p}'`); - const entry = this.entries.get(resolvedP); - if (entry === void 0) - throw new Error(`Unreachable`); - if (!this.isSymbolicLink(entry)) - throw EINVAL(`readlink '${p}'`); - return entry; - } - async truncatePromise(p, len = 0) { - const resolvedP = this.resolveFilename(`open '${p}'`, p); - const index = this.entries.get(resolvedP); - if (typeof index === `undefined`) - throw EINVAL(`open '${p}'`); - const source = await this.getFileSource(index, {asyncDecompress: true}); - const truncated = Buffer.alloc(len, 0); - source.copy(truncated); - return await this.writeFilePromise(p, truncated); - } - truncateSync(p, len = 0) { - const resolvedP = this.resolveFilename(`open '${p}'`, p); - const index = this.entries.get(resolvedP); - if (typeof index === `undefined`) - throw EINVAL(`open '${p}'`); - const source = this.getFileSource(index); - const truncated = Buffer.alloc(len, 0); - source.copy(truncated); - return this.writeFileSync(p, truncated); - } - async ftruncatePromise(fd, len) { - return this.truncatePromise(this.fdToPath(fd, `ftruncate`), len); - } - ftruncateSync(fd, len) { - return this.truncateSync(this.fdToPath(fd, `ftruncateSync`), len); - } - watch(p, a, b) { - let persistent; - switch (typeof a) { - case `function`: - case `string`: - case `undefined`: - { - persistent = true; - } - break; - default: - { - ({persistent = true} = a); - } - break; - } - if (!persistent) - return {on: () => { - }, close: () => { - }}; - const interval = setInterval(() => { - }, 24 * 60 * 60 * 1e3); - return {on: () => { - }, close: () => { - clearInterval(interval); - }}; - } - watchFile(p, a, b) { - const resolvedP = ppath.resolve(PortablePath.root, p); - return watchFile(this, resolvedP, a, b); - } - unwatchFile(p, cb) { - const resolvedP = ppath.resolve(PortablePath.root, p); - return unwatchFile(this, resolvedP, cb); - } -} - -class ProxiedFS extends FakeFS { - getExtractHint(hints) { - return this.baseFs.getExtractHint(hints); - } - resolve(path) { - return this.mapFromBase(this.baseFs.resolve(this.mapToBase(path))); - } - getRealPath() { - return this.mapFromBase(this.baseFs.getRealPath()); - } - async openPromise(p, flags, mode) { - return this.baseFs.openPromise(this.mapToBase(p), flags, mode); - } - openSync(p, flags, mode) { - return this.baseFs.openSync(this.mapToBase(p), flags, mode); - } - async opendirPromise(p, opts) { - return Object.assign(await this.baseFs.opendirPromise(this.mapToBase(p), opts), {path: p}); - } - opendirSync(p, opts) { - return Object.assign(this.baseFs.opendirSync(this.mapToBase(p), opts), {path: p}); - } - async readPromise(fd, buffer, offset, length, position) { - return await this.baseFs.readPromise(fd, buffer, offset, length, position); - } - readSync(fd, buffer, offset, length, position) { - return this.baseFs.readSync(fd, buffer, offset, length, position); - } - async writePromise(fd, buffer, offset, length, position) { - if (typeof buffer === `string`) { - return await this.baseFs.writePromise(fd, buffer, offset); - } else { - return await this.baseFs.writePromise(fd, buffer, offset, length, position); - } - } - writeSync(fd, buffer, offset, length, position) { - if (typeof buffer === `string`) { - return this.baseFs.writeSync(fd, buffer, offset); - } else { - return this.baseFs.writeSync(fd, buffer, offset, length, position); - } - } - async closePromise(fd) { - return this.baseFs.closePromise(fd); - } - closeSync(fd) { - this.baseFs.closeSync(fd); - } - createReadStream(p, opts) { - return this.baseFs.createReadStream(p !== null ? this.mapToBase(p) : p, opts); - } - createWriteStream(p, opts) { - return this.baseFs.createWriteStream(p !== null ? this.mapToBase(p) : p, opts); - } - async realpathPromise(p) { - return this.mapFromBase(await this.baseFs.realpathPromise(this.mapToBase(p))); - } - realpathSync(p) { - return this.mapFromBase(this.baseFs.realpathSync(this.mapToBase(p))); - } - async existsPromise(p) { - return this.baseFs.existsPromise(this.mapToBase(p)); - } - existsSync(p) { - return this.baseFs.existsSync(this.mapToBase(p)); - } - accessSync(p, mode) { - return this.baseFs.accessSync(this.mapToBase(p), mode); - } - async accessPromise(p, mode) { - return this.baseFs.accessPromise(this.mapToBase(p), mode); - } - async statPromise(p, opts) { - return this.baseFs.statPromise(this.mapToBase(p), opts); - } - statSync(p, opts) { - return this.baseFs.statSync(this.mapToBase(p), opts); - } - async fstatPromise(fd, opts) { - return this.baseFs.fstatPromise(fd, opts); - } - fstatSync(fd, opts) { - return this.baseFs.fstatSync(fd, opts); - } - lstatPromise(p, opts) { - return this.baseFs.lstatPromise(this.mapToBase(p), opts); - } - lstatSync(p, opts) { - return this.baseFs.lstatSync(this.mapToBase(p), opts); - } - async fchmodPromise(fd, mask) { - return this.baseFs.fchmodPromise(fd, mask); - } - fchmodSync(fd, mask) { - return this.baseFs.fchmodSync(fd, mask); - } - async chmodPromise(p, mask) { - return this.baseFs.chmodPromise(this.mapToBase(p), mask); - } - chmodSync(p, mask) { - return this.baseFs.chmodSync(this.mapToBase(p), mask); - } - async chownPromise(p, uid, gid) { - return this.baseFs.chownPromise(this.mapToBase(p), uid, gid); - } - chownSync(p, uid, gid) { - return this.baseFs.chownSync(this.mapToBase(p), uid, gid); - } - async renamePromise(oldP, newP) { - return this.baseFs.renamePromise(this.mapToBase(oldP), this.mapToBase(newP)); - } - renameSync(oldP, newP) { - return this.baseFs.renameSync(this.mapToBase(oldP), this.mapToBase(newP)); - } - async copyFilePromise(sourceP, destP, flags = 0) { - return this.baseFs.copyFilePromise(this.mapToBase(sourceP), this.mapToBase(destP), flags); - } - copyFileSync(sourceP, destP, flags = 0) { - return this.baseFs.copyFileSync(this.mapToBase(sourceP), this.mapToBase(destP), flags); - } - async appendFilePromise(p, content, opts) { - return this.baseFs.appendFilePromise(this.fsMapToBase(p), content, opts); - } - appendFileSync(p, content, opts) { - return this.baseFs.appendFileSync(this.fsMapToBase(p), content, opts); - } - async writeFilePromise(p, content, opts) { - return this.baseFs.writeFilePromise(this.fsMapToBase(p), content, opts); - } - writeFileSync(p, content, opts) { - return this.baseFs.writeFileSync(this.fsMapToBase(p), content, opts); - } - async unlinkPromise(p) { - return this.baseFs.unlinkPromise(this.mapToBase(p)); - } - unlinkSync(p) { - return this.baseFs.unlinkSync(this.mapToBase(p)); - } - async utimesPromise(p, atime, mtime) { - return this.baseFs.utimesPromise(this.mapToBase(p), atime, mtime); - } - utimesSync(p, atime, mtime) { - return this.baseFs.utimesSync(this.mapToBase(p), atime, mtime); - } - async mkdirPromise(p, opts) { - return this.baseFs.mkdirPromise(this.mapToBase(p), opts); - } - mkdirSync(p, opts) { - return this.baseFs.mkdirSync(this.mapToBase(p), opts); - } - async rmdirPromise(p, opts) { - return this.baseFs.rmdirPromise(this.mapToBase(p), opts); - } - rmdirSync(p, opts) { - return this.baseFs.rmdirSync(this.mapToBase(p), opts); - } - async linkPromise(existingP, newP) { - return this.baseFs.linkPromise(this.mapToBase(existingP), this.mapToBase(newP)); - } - linkSync(existingP, newP) { - return this.baseFs.linkSync(this.mapToBase(existingP), this.mapToBase(newP)); - } - async symlinkPromise(target, p, type) { - const mappedP = this.mapToBase(p); - if (this.pathUtils.isAbsolute(target)) - return this.baseFs.symlinkPromise(this.mapToBase(target), mappedP, type); - const mappedAbsoluteTarget = this.mapToBase(this.pathUtils.join(this.pathUtils.dirname(p), target)); - const mappedTarget = this.baseFs.pathUtils.relative(this.baseFs.pathUtils.dirname(mappedP), mappedAbsoluteTarget); - return this.baseFs.symlinkPromise(mappedTarget, mappedP, type); - } - symlinkSync(target, p, type) { - const mappedP = this.mapToBase(p); - if (this.pathUtils.isAbsolute(target)) - return this.baseFs.symlinkSync(this.mapToBase(target), mappedP, type); - const mappedAbsoluteTarget = this.mapToBase(this.pathUtils.join(this.pathUtils.dirname(p), target)); - const mappedTarget = this.baseFs.pathUtils.relative(this.baseFs.pathUtils.dirname(mappedP), mappedAbsoluteTarget); - return this.baseFs.symlinkSync(mappedTarget, mappedP, type); - } - async readFilePromise(p, encoding) { - if (encoding === `utf8`) { - return this.baseFs.readFilePromise(this.fsMapToBase(p), encoding); - } else { - return this.baseFs.readFilePromise(this.fsMapToBase(p), encoding); - } - } - readFileSync(p, encoding) { - if (encoding === `utf8`) { - return this.baseFs.readFileSync(this.fsMapToBase(p), encoding); - } else { - return this.baseFs.readFileSync(this.fsMapToBase(p), encoding); - } - } - async readdirPromise(p, opts) { - return this.baseFs.readdirPromise(this.mapToBase(p), opts); - } - readdirSync(p, opts) { - return this.baseFs.readdirSync(this.mapToBase(p), opts); - } - async readlinkPromise(p) { - return this.mapFromBase(await this.baseFs.readlinkPromise(this.mapToBase(p))); - } - readlinkSync(p) { - return this.mapFromBase(this.baseFs.readlinkSync(this.mapToBase(p))); - } - async truncatePromise(p, len) { - return this.baseFs.truncatePromise(this.mapToBase(p), len); - } - truncateSync(p, len) { - return this.baseFs.truncateSync(this.mapToBase(p), len); - } - async ftruncatePromise(fd, len) { - return this.baseFs.ftruncatePromise(fd, len); - } - ftruncateSync(fd, len) { - return this.baseFs.ftruncateSync(fd, len); - } - watch(p, a, b) { - return this.baseFs.watch(this.mapToBase(p), a, b); - } - watchFile(p, a, b) { - return this.baseFs.watchFile(this.mapToBase(p), a, b); - } - unwatchFile(p, cb) { - return this.baseFs.unwatchFile(this.mapToBase(p), cb); - } - fsMapToBase(p) { - if (typeof p === `number`) { - return p; - } else { - return this.mapToBase(p); - } - } -} - -class PosixFS extends ProxiedFS { - constructor(baseFs) { - super(npath); - this.baseFs = baseFs; - } - mapFromBase(path) { - return npath.fromPortablePath(path); - } - mapToBase(path) { - return npath.toPortablePath(path); - } -} - -const NUMBER_REGEXP = /^[0-9]+$/; -const VIRTUAL_REGEXP = /^(\/(?:[^/]+\/)*?(?:\$\$virtual|__virtual__))((?:\/((?:[^/]+-)?[a-f0-9]+)(?:\/([^/]+))?)?((?:\/.*)?))$/; -const VALID_COMPONENT = /^([^/]+-)?[a-f0-9]+$/; -class VirtualFS extends ProxiedFS { - static makeVirtualPath(base, component, to) { - if (ppath.basename(base) !== `__virtual__`) - throw new Error(`Assertion failed: Virtual folders must be named "__virtual__"`); - if (!ppath.basename(component).match(VALID_COMPONENT)) - throw new Error(`Assertion failed: Virtual components must be ended by an hexadecimal hash`); - const target = ppath.relative(ppath.dirname(base), to); - const segments = target.split(`/`); - let depth = 0; - while (depth < segments.length && segments[depth] === `..`) - depth += 1; - const finalSegments = segments.slice(depth); - const fullVirtualPath = ppath.join(base, component, String(depth), ...finalSegments); - return fullVirtualPath; - } - static resolveVirtual(p) { - const match = p.match(VIRTUAL_REGEXP); - if (!match || !match[3] && match[5]) - return p; - const target = ppath.dirname(match[1]); - if (!match[3] || !match[4]) - return target; - const isnum = NUMBER_REGEXP.test(match[4]); - if (!isnum) - return p; - const depth = Number(match[4]); - const backstep = `../`.repeat(depth); - const subpath = match[5] || `.`; - return VirtualFS.resolveVirtual(ppath.join(target, backstep, subpath)); - } - constructor({baseFs = new NodeFS()} = {}) { - super(ppath); - this.baseFs = baseFs; - } - getExtractHint(hints) { - return this.baseFs.getExtractHint(hints); - } - getRealPath() { - return this.baseFs.getRealPath(); - } - realpathSync(p) { - const match = p.match(VIRTUAL_REGEXP); - if (!match) - return this.baseFs.realpathSync(p); - if (!match[5]) - return p; - const realpath = this.baseFs.realpathSync(this.mapToBase(p)); - return VirtualFS.makeVirtualPath(match[1], match[3], realpath); - } - async realpathPromise(p) { - const match = p.match(VIRTUAL_REGEXP); - if (!match) - return await this.baseFs.realpathPromise(p); - if (!match[5]) - return p; - const realpath = await this.baseFs.realpathPromise(this.mapToBase(p)); - return VirtualFS.makeVirtualPath(match[1], match[3], realpath); - } - mapToBase(p) { - if (p === ``) - return p; - if (this.pathUtils.isAbsolute(p)) - return VirtualFS.resolveVirtual(p); - const resolvedRoot = VirtualFS.resolveVirtual(this.baseFs.resolve(PortablePath.dot)); - const resolvedP = VirtualFS.resolveVirtual(this.baseFs.resolve(p)); - return ppath.relative(resolvedRoot, resolvedP) || PortablePath.dot; - } - mapFromBase(p) { - return p; - } -} - -const ZIP_FD = 2147483648; -const getArchivePart = (path, extension) => { - let idx = path.indexOf(extension); - if (idx <= 0) - return null; - let nextCharIdx = idx; - while (idx >= 0) { - nextCharIdx = idx + extension.length; - if (path[nextCharIdx] === ppath.sep) - break; - if (path[idx - 1] === ppath.sep) - return null; - idx = path.indexOf(extension, nextCharIdx); - } - if (path.length > nextCharIdx && path[nextCharIdx] !== ppath.sep) - return null; - return path.slice(0, nextCharIdx); -}; -class ZipOpenFS extends BasePortableFakeFS { - constructor({libzip, baseFs = new NodeFS(), filter = null, maxOpenFiles = Infinity, readOnlyArchives = false, useCache = true, maxAge = 5e3, fileExtensions = 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 libzip !== `function` ? () => libzip : libzip; - this.baseFs = baseFs; - this.zipInstances = useCache ? new Map() : null; - this.filter = filter; - this.maxOpenFiles = maxOpenFiles; - this.readOnlyArchives = readOnlyArchives; - this.maxAge = maxAge; - this.fileExtensions = fileExtensions; - } - static async openPromise(fn, opts) { - const zipOpenFs = new ZipOpenFS(opts); - try { - return await fn(zipOpenFs); - } finally { - zipOpenFs.saveAndClose(); - } - } - get libzip() { - if (typeof this.libzipInstance === `undefined`) - this.libzipInstance = this.libzipFactory(); - return this.libzipInstance; - } - getExtractHint(hints) { - return this.baseFs.getExtractHint(hints); - } - getRealPath() { - return this.baseFs.getRealPath(); - } - saveAndClose() { - unwatchAllFiles(this); - if (this.zipInstances) { - for (const [path, {zipFs}] of this.zipInstances.entries()) { - zipFs.saveAndClose(); - this.zipInstances.delete(path); - } - } - } - discardAndClose() { - unwatchAllFiles(this); - if (this.zipInstances) { - for (const [path, {zipFs}] of this.zipInstances.entries()) { - zipFs.discardAndClose(); - this.zipInstances.delete(path); - } - } - } - resolve(p) { - return this.baseFs.resolve(p); - } - remapFd(zipFs, fd) { - const remappedFd = this.nextFd++ | ZIP_FD; - this.fdMap.set(remappedFd, [zipFs, fd]); - return remappedFd; - } - async openPromise(p, flags, mode) { - return await this.makeCallPromise(p, async () => { - return await this.baseFs.openPromise(p, flags, mode); - }, async (zipFs, {subPath}) => { - return this.remapFd(zipFs, await zipFs.openPromise(subPath, flags, mode)); - }); - } - openSync(p, flags, mode) { - return this.makeCallSync(p, () => { - return this.baseFs.openSync(p, flags, mode); - }, (zipFs, {subPath}) => { - return this.remapFd(zipFs, zipFs.openSync(subPath, flags, mode)); - }); - } - async opendirPromise(p, opts) { - return await this.makeCallPromise(p, async () => { - return await this.baseFs.opendirPromise(p, opts); - }, async (zipFs, {subPath}) => { - return await zipFs.opendirPromise(subPath, opts); - }, { - requireSubpath: false - }); - } - opendirSync(p, opts) { - return this.makeCallSync(p, () => { - return this.baseFs.opendirSync(p, opts); - }, (zipFs, {subPath}) => { - return zipFs.opendirSync(subPath, opts); - }, { - requireSubpath: false - }); - } - async readPromise(fd, buffer, offset, length, position) { - if ((fd & ZIP_FD) === 0) - return await this.baseFs.readPromise(fd, buffer, offset, length, position); - const entry = this.fdMap.get(fd); - if (typeof entry === `undefined`) - throw EBADF(`read`); - const [zipFs, realFd] = entry; - return await zipFs.readPromise(realFd, buffer, offset, length, position); - } - readSync(fd, buffer, offset, length, position) { - if ((fd & ZIP_FD) === 0) - return this.baseFs.readSync(fd, buffer, offset, length, position); - const entry = this.fdMap.get(fd); - if (typeof entry === `undefined`) - throw EBADF(`readSync`); - const [zipFs, realFd] = entry; - return zipFs.readSync(realFd, buffer, offset, length, position); - } - async writePromise(fd, buffer, offset, length, position) { - if ((fd & ZIP_FD) === 0) { - if (typeof buffer === `string`) { - return await this.baseFs.writePromise(fd, buffer, offset); - } else { - return await this.baseFs.writePromise(fd, buffer, offset, length, position); - } - } - const entry = this.fdMap.get(fd); - if (typeof entry === `undefined`) - throw EBADF(`write`); - const [zipFs, realFd] = entry; - if (typeof buffer === `string`) { - return await zipFs.writePromise(realFd, buffer, offset); - } else { - return await zipFs.writePromise(realFd, buffer, offset, length, position); - } - } - writeSync(fd, buffer, offset, length, position) { - if ((fd & ZIP_FD) === 0) { - if (typeof buffer === `string`) { - return this.baseFs.writeSync(fd, buffer, offset); - } else { - return this.baseFs.writeSync(fd, buffer, offset, length, position); - } - } - const entry = this.fdMap.get(fd); - if (typeof entry === `undefined`) - throw EBADF(`writeSync`); - const [zipFs, realFd] = entry; - if (typeof buffer === `string`) { - return zipFs.writeSync(realFd, buffer, offset); - } else { - return zipFs.writeSync(realFd, buffer, offset, length, position); - } - } - async closePromise(fd) { - if ((fd & ZIP_FD) === 0) - return await this.baseFs.closePromise(fd); - const entry = this.fdMap.get(fd); - if (typeof entry === `undefined`) - throw EBADF(`close`); - this.fdMap.delete(fd); - const [zipFs, realFd] = entry; - return await zipFs.closePromise(realFd); - } - closeSync(fd) { - if ((fd & ZIP_FD) === 0) - return this.baseFs.closeSync(fd); - const entry = this.fdMap.get(fd); - if (typeof entry === `undefined`) - throw EBADF(`closeSync`); - this.fdMap.delete(fd); - const [zipFs, realFd] = entry; - return zipFs.closeSync(realFd); - } - createReadStream(p, opts) { - if (p === null) - return this.baseFs.createReadStream(p, opts); - return this.makeCallSync(p, () => { - return this.baseFs.createReadStream(p, opts); - }, (zipFs, {archivePath, subPath}) => { - const stream = zipFs.createReadStream(subPath, opts); - stream.path = npath.fromPortablePath(this.pathUtils.join(archivePath, subPath)); - return stream; - }); - } - createWriteStream(p, opts) { - if (p === null) - return this.baseFs.createWriteStream(p, opts); - return this.makeCallSync(p, () => { - return this.baseFs.createWriteStream(p, opts); - }, (zipFs, {subPath}) => { - return zipFs.createWriteStream(subPath, opts); - }); - } - async realpathPromise(p) { - return await this.makeCallPromise(p, async () => { - return await this.baseFs.realpathPromise(p); - }, async (zipFs, {archivePath, subPath}) => { - let realArchivePath = this.realPaths.get(archivePath); - if (typeof realArchivePath === `undefined`) { - realArchivePath = await this.baseFs.realpathPromise(archivePath); - this.realPaths.set(archivePath, realArchivePath); - } - return this.pathUtils.join(realArchivePath, this.pathUtils.relative(PortablePath.root, await zipFs.realpathPromise(subPath))); - }); - } - realpathSync(p) { - return this.makeCallSync(p, () => { - return this.baseFs.realpathSync(p); - }, (zipFs, {archivePath, subPath}) => { - let realArchivePath = this.realPaths.get(archivePath); - if (typeof realArchivePath === `undefined`) { - realArchivePath = this.baseFs.realpathSync(archivePath); - this.realPaths.set(archivePath, realArchivePath); - } - return this.pathUtils.join(realArchivePath, this.pathUtils.relative(PortablePath.root, zipFs.realpathSync(subPath))); - }); - } - async existsPromise(p) { - return await this.makeCallPromise(p, async () => { - return await this.baseFs.existsPromise(p); - }, async (zipFs, {subPath}) => { - return await zipFs.existsPromise(subPath); - }); - } - existsSync(p) { - return this.makeCallSync(p, () => { - return this.baseFs.existsSync(p); - }, (zipFs, {subPath}) => { - return zipFs.existsSync(subPath); - }); - } - async accessPromise(p, mode) { - return await this.makeCallPromise(p, async () => { - return await this.baseFs.accessPromise(p, mode); - }, async (zipFs, {subPath}) => { - return await zipFs.accessPromise(subPath, mode); - }); - } - accessSync(p, mode) { - return this.makeCallSync(p, () => { - return this.baseFs.accessSync(p, mode); - }, (zipFs, {subPath}) => { - return zipFs.accessSync(subPath, mode); - }); - } - async statPromise(p, opts) { - return await this.makeCallPromise(p, async () => { - return await this.baseFs.statPromise(p, opts); - }, async (zipFs, {subPath}) => { - return await zipFs.statPromise(subPath, opts); - }); - } - statSync(p, opts) { - return this.makeCallSync(p, () => { - return this.baseFs.statSync(p, opts); - }, (zipFs, {subPath}) => { - return zipFs.statSync(subPath, opts); - }); - } - async fstatPromise(fd, opts) { - if ((fd & ZIP_FD) === 0) - return this.baseFs.fstatPromise(fd, opts); - const entry = this.fdMap.get(fd); - if (typeof entry === `undefined`) - throw EBADF(`fstat`); - const [zipFs, realFd] = entry; - return zipFs.fstatPromise(realFd, opts); - } - fstatSync(fd, opts) { - if ((fd & ZIP_FD) === 0) - return this.baseFs.fstatSync(fd, opts); - const entry = this.fdMap.get(fd); - if (typeof entry === `undefined`) - throw EBADF(`fstatSync`); - const [zipFs, realFd] = entry; - return zipFs.fstatSync(realFd, opts); - } - async lstatPromise(p, opts) { - return await this.makeCallPromise(p, async () => { - return await this.baseFs.lstatPromise(p, opts); - }, async (zipFs, {subPath}) => { - return await zipFs.lstatPromise(subPath, opts); - }); - } - lstatSync(p, opts) { - return this.makeCallSync(p, () => { - return this.baseFs.lstatSync(p, opts); - }, (zipFs, {subPath}) => { - return zipFs.lstatSync(subPath, opts); - }); - } - async fchmodPromise(fd, mask) { - if ((fd & ZIP_FD) === 0) - return this.baseFs.fchmodPromise(fd, mask); - const entry = this.fdMap.get(fd); - if (typeof entry === `undefined`) - throw EBADF(`fchmod`); - const [zipFs, realFd] = entry; - return zipFs.fchmodPromise(realFd, mask); - } - fchmodSync(fd, mask) { - if ((fd & ZIP_FD) === 0) - return this.baseFs.fchmodSync(fd, mask); - const entry = this.fdMap.get(fd); - if (typeof entry === `undefined`) - throw EBADF(`fchmodSync`); - const [zipFs, realFd] = entry; - return zipFs.fchmodSync(realFd, mask); - } - async chmodPromise(p, mask) { - return await this.makeCallPromise(p, async () => { - return await this.baseFs.chmodPromise(p, mask); - }, async (zipFs, {subPath}) => { - return await zipFs.chmodPromise(subPath, mask); - }); - } - chmodSync(p, mask) { - return this.makeCallSync(p, () => { - return this.baseFs.chmodSync(p, mask); - }, (zipFs, {subPath}) => { - return zipFs.chmodSync(subPath, mask); - }); - } - async chownPromise(p, uid, gid) { - return await this.makeCallPromise(p, async () => { - return await this.baseFs.chownPromise(p, uid, gid); - }, async (zipFs, {subPath}) => { - return await zipFs.chownPromise(subPath, uid, gid); - }); - } - chownSync(p, uid, gid) { - return this.makeCallSync(p, () => { - return this.baseFs.chownSync(p, uid, gid); - }, (zipFs, {subPath}) => { - return zipFs.chownSync(subPath, uid, gid); - }); - } - async renamePromise(oldP, newP) { - return await this.makeCallPromise(oldP, async () => { - return await this.makeCallPromise(newP, async () => { - return await this.baseFs.renamePromise(oldP, newP); - }, async () => { - throw Object.assign(new Error(`EEXDEV: cross-device link not permitted`), {code: `EEXDEV`}); - }); - }, async (zipFsO, {subPath: subPathO}) => { - return await this.makeCallPromise(newP, async () => { - throw Object.assign(new Error(`EEXDEV: cross-device link not permitted`), {code: `EEXDEV`}); - }, async (zipFsN, {subPath: subPathN}) => { - if (zipFsO !== zipFsN) { - throw Object.assign(new Error(`EEXDEV: cross-device link not permitted`), {code: `EEXDEV`}); - } else { - return await zipFsO.renamePromise(subPathO, subPathN); - } - }); - }); - } - renameSync(oldP, newP) { - return this.makeCallSync(oldP, () => { - return this.makeCallSync(newP, () => { - return this.baseFs.renameSync(oldP, newP); - }, () => { - throw Object.assign(new Error(`EEXDEV: cross-device link not permitted`), {code: `EEXDEV`}); - }); - }, (zipFsO, {subPath: subPathO}) => { - return this.makeCallSync(newP, () => { - throw Object.assign(new Error(`EEXDEV: cross-device link not permitted`), {code: `EEXDEV`}); - }, (zipFsN, {subPath: subPathN}) => { - if (zipFsO !== zipFsN) { - throw Object.assign(new Error(`EEXDEV: cross-device link not permitted`), {code: `EEXDEV`}); - } else { - return zipFsO.renameSync(subPathO, subPathN); - } - }); - }); - } - async copyFilePromise(sourceP, destP, flags = 0) { - const fallback = async (sourceFs, sourceP2, destFs, destP2) => { - if ((flags & fs.constants.COPYFILE_FICLONE_FORCE) !== 0) - throw Object.assign(new Error(`EXDEV: cross-device clone not permitted, copyfile '${sourceP2}' -> ${destP2}'`), {code: `EXDEV`}); - if (flags & fs.constants.COPYFILE_EXCL && await this.existsPromise(sourceP2)) - throw Object.assign(new Error(`EEXIST: file already exists, copyfile '${sourceP2}' -> '${destP2}'`), {code: `EEXIST`}); - let content; - try { - content = await sourceFs.readFilePromise(sourceP2); - } catch (error) { - throw Object.assign(new Error(`EINVAL: invalid argument, copyfile '${sourceP2}' -> '${destP2}'`), {code: `EINVAL`}); - } - await destFs.writeFilePromise(destP2, content); - }; - return await this.makeCallPromise(sourceP, async () => { - return await this.makeCallPromise(destP, async () => { - return await this.baseFs.copyFilePromise(sourceP, destP, flags); - }, async (zipFsD, {subPath: subPathD}) => { - return await fallback(this.baseFs, sourceP, zipFsD, subPathD); - }); - }, async (zipFsS, {subPath: subPathS}) => { - return await this.makeCallPromise(destP, async () => { - return await fallback(zipFsS, subPathS, this.baseFs, destP); - }, async (zipFsD, {subPath: subPathD}) => { - if (zipFsS !== zipFsD) { - return await fallback(zipFsS, subPathS, zipFsD, subPathD); - } else { - return await zipFsS.copyFilePromise(subPathS, subPathD, flags); - } - }); - }); - } - copyFileSync(sourceP, destP, flags = 0) { - const fallback = (sourceFs, sourceP2, destFs, destP2) => { - if ((flags & fs.constants.COPYFILE_FICLONE_FORCE) !== 0) - throw Object.assign(new Error(`EXDEV: cross-device clone not permitted, copyfile '${sourceP2}' -> ${destP2}'`), {code: `EXDEV`}); - if (flags & fs.constants.COPYFILE_EXCL && this.existsSync(sourceP2)) - throw Object.assign(new Error(`EEXIST: file already exists, copyfile '${sourceP2}' -> '${destP2}'`), {code: `EEXIST`}); - let content; - try { - content = sourceFs.readFileSync(sourceP2); - } catch (error) { - throw Object.assign(new Error(`EINVAL: invalid argument, copyfile '${sourceP2}' -> '${destP2}'`), {code: `EINVAL`}); - } - destFs.writeFileSync(destP2, content); - }; - return this.makeCallSync(sourceP, () => { - return this.makeCallSync(destP, () => { - return this.baseFs.copyFileSync(sourceP, destP, flags); - }, (zipFsD, {subPath: subPathD}) => { - return fallback(this.baseFs, sourceP, zipFsD, subPathD); - }); - }, (zipFsS, {subPath: subPathS}) => { - return this.makeCallSync(destP, () => { - return fallback(zipFsS, subPathS, this.baseFs, destP); - }, (zipFsD, {subPath: subPathD}) => { - if (zipFsS !== zipFsD) { - return fallback(zipFsS, subPathS, zipFsD, subPathD); - } else { - return zipFsS.copyFileSync(subPathS, subPathD, flags); - } - }); - }); - } - async appendFilePromise(p, content, opts) { - return await this.makeCallPromise(p, async () => { - return await this.baseFs.appendFilePromise(p, content, opts); - }, async (zipFs, {subPath}) => { - return await zipFs.appendFilePromise(subPath, content, opts); - }); - } - appendFileSync(p, content, opts) { - return this.makeCallSync(p, () => { - return this.baseFs.appendFileSync(p, content, opts); - }, (zipFs, {subPath}) => { - return zipFs.appendFileSync(subPath, content, opts); - }); - } - async writeFilePromise(p, content, opts) { - return await this.makeCallPromise(p, async () => { - return await this.baseFs.writeFilePromise(p, content, opts); - }, async (zipFs, {subPath}) => { - return await zipFs.writeFilePromise(subPath, content, opts); - }); - } - writeFileSync(p, content, opts) { - return this.makeCallSync(p, () => { - return this.baseFs.writeFileSync(p, content, opts); - }, (zipFs, {subPath}) => { - return zipFs.writeFileSync(subPath, content, opts); - }); - } - async unlinkPromise(p) { - return await this.makeCallPromise(p, async () => { - return await this.baseFs.unlinkPromise(p); - }, async (zipFs, {subPath}) => { - return await zipFs.unlinkPromise(subPath); - }); - } - unlinkSync(p) { - return this.makeCallSync(p, () => { - return this.baseFs.unlinkSync(p); - }, (zipFs, {subPath}) => { - return zipFs.unlinkSync(subPath); - }); - } - async utimesPromise(p, atime, mtime) { - return await this.makeCallPromise(p, async () => { - return await this.baseFs.utimesPromise(p, atime, mtime); - }, async (zipFs, {subPath}) => { - return await zipFs.utimesPromise(subPath, atime, mtime); - }); - } - utimesSync(p, atime, mtime) { - return this.makeCallSync(p, () => { - return this.baseFs.utimesSync(p, atime, mtime); - }, (zipFs, {subPath}) => { - return zipFs.utimesSync(subPath, atime, mtime); - }); - } - async mkdirPromise(p, opts) { - return await this.makeCallPromise(p, async () => { - return await this.baseFs.mkdirPromise(p, opts); - }, async (zipFs, {subPath}) => { - return await zipFs.mkdirPromise(subPath, opts); - }); - } - mkdirSync(p, opts) { - return this.makeCallSync(p, () => { - return this.baseFs.mkdirSync(p, opts); - }, (zipFs, {subPath}) => { - return zipFs.mkdirSync(subPath, opts); - }); - } - async rmdirPromise(p, opts) { - return await this.makeCallPromise(p, async () => { - return await this.baseFs.rmdirPromise(p, opts); - }, async (zipFs, {subPath}) => { - return await zipFs.rmdirPromise(subPath, opts); - }); - } - rmdirSync(p, opts) { - return this.makeCallSync(p, () => { - return this.baseFs.rmdirSync(p, opts); - }, (zipFs, {subPath}) => { - return zipFs.rmdirSync(subPath, opts); - }); - } - async linkPromise(existingP, newP) { - return await this.makeCallPromise(newP, async () => { - return await this.baseFs.linkPromise(existingP, newP); - }, async (zipFs, {subPath}) => { - return await zipFs.linkPromise(existingP, subPath); - }); - } - linkSync(existingP, newP) { - return this.makeCallSync(newP, () => { - return this.baseFs.linkSync(existingP, newP); - }, (zipFs, {subPath}) => { - return zipFs.linkSync(existingP, subPath); - }); - } - async symlinkPromise(target, p, type) { - return await this.makeCallPromise(p, async () => { - return await this.baseFs.symlinkPromise(target, p, type); - }, async (zipFs, {subPath}) => { - return await zipFs.symlinkPromise(target, subPath); - }); - } - symlinkSync(target, p, type) { - return this.makeCallSync(p, () => { - return this.baseFs.symlinkSync(target, p, type); - }, (zipFs, {subPath}) => { - return zipFs.symlinkSync(target, subPath); - }); - } - async readFilePromise(p, encoding) { - return this.makeCallPromise(p, async () => { - switch (encoding) { - case `utf8`: - return await this.baseFs.readFilePromise(p, encoding); - default: - return await this.baseFs.readFilePromise(p, encoding); - } - }, async (zipFs, {subPath}) => { - return await zipFs.readFilePromise(subPath, encoding); - }); - } - readFileSync(p, encoding) { - return this.makeCallSync(p, () => { - switch (encoding) { - case `utf8`: - return this.baseFs.readFileSync(p, encoding); - default: - return this.baseFs.readFileSync(p, encoding); - } - }, (zipFs, {subPath}) => { - return zipFs.readFileSync(subPath, encoding); - }); - } - async readdirPromise(p, opts) { - return await this.makeCallPromise(p, async () => { - return await this.baseFs.readdirPromise(p, opts); - }, async (zipFs, {subPath}) => { - return await zipFs.readdirPromise(subPath, opts); - }, { - requireSubpath: false - }); - } - readdirSync(p, opts) { - return this.makeCallSync(p, () => { - return this.baseFs.readdirSync(p, opts); - }, (zipFs, {subPath}) => { - return zipFs.readdirSync(subPath, opts); - }, { - requireSubpath: false - }); - } - async readlinkPromise(p) { - return await this.makeCallPromise(p, async () => { - return await this.baseFs.readlinkPromise(p); - }, async (zipFs, {subPath}) => { - return await zipFs.readlinkPromise(subPath); - }); - } - readlinkSync(p) { - return this.makeCallSync(p, () => { - return this.baseFs.readlinkSync(p); - }, (zipFs, {subPath}) => { - return zipFs.readlinkSync(subPath); - }); - } - async truncatePromise(p, len) { - return await this.makeCallPromise(p, async () => { - return await this.baseFs.truncatePromise(p, len); - }, async (zipFs, {subPath}) => { - return await zipFs.truncatePromise(subPath, len); - }); - } - truncateSync(p, len) { - return this.makeCallSync(p, () => { - return this.baseFs.truncateSync(p, len); - }, (zipFs, {subPath}) => { - return zipFs.truncateSync(subPath, len); - }); - } - async ftruncatePromise(fd, len) { - if ((fd & ZIP_FD) === 0) - return this.baseFs.ftruncatePromise(fd, len); - const entry = this.fdMap.get(fd); - if (typeof entry === `undefined`) - throw EBADF(`ftruncate`); - const [zipFs, realFd] = entry; - return zipFs.ftruncatePromise(realFd, len); - } - ftruncateSync(fd, len) { - if ((fd & ZIP_FD) === 0) - return this.baseFs.ftruncateSync(fd, len); - const entry = this.fdMap.get(fd); - if (typeof entry === `undefined`) - throw EBADF(`ftruncateSync`); - const [zipFs, realFd] = entry; - return zipFs.ftruncateSync(realFd, len); - } - watch(p, a, b) { - return this.makeCallSync(p, () => { - return this.baseFs.watch(p, a, b); - }, (zipFs, {subPath}) => { - return zipFs.watch(subPath, a, b); - }); - } - watchFile(p, a, b) { - return this.makeCallSync(p, () => { - return this.baseFs.watchFile(p, a, b); - }, () => { - return watchFile(this, p, a, b); - }); - } - unwatchFile(p, cb) { - return this.makeCallSync(p, () => { - return this.baseFs.unwatchFile(p, cb); - }, () => { - return unwatchFile(this, p, cb); - }); - } - async makeCallPromise(p, discard, accept, {requireSubpath = true} = {}) { - if (typeof p !== `string`) - return await discard(); - const normalizedP = this.resolve(p); - const zipInfo = this.findZip(normalizedP); - if (!zipInfo) - return await discard(); - if (requireSubpath && zipInfo.subPath === `/`) - return await discard(); - return await this.getZipPromise(zipInfo.archivePath, async (zipFs) => await accept(zipFs, zipInfo)); - } - makeCallSync(p, discard, accept, {requireSubpath = true} = {}) { - if (typeof p !== `string`) - return discard(); - const normalizedP = this.resolve(p); - const zipInfo = this.findZip(normalizedP); - if (!zipInfo) - return discard(); - if (requireSubpath && zipInfo.subPath === `/`) - return discard(); - return this.getZipSync(zipInfo.archivePath, (zipFs) => accept(zipFs, zipInfo)); - } - findZip(p) { - if (this.filter && !this.filter.test(p)) - return null; - let filePath = ``; - while (true) { - const pathPartWithArchive = p.substring(filePath.length); - let archivePart; - if (!this.fileExtensions) { - archivePart = getArchivePart(pathPartWithArchive, `.zip`); - } else { - for (const ext of this.fileExtensions) { - archivePart = getArchivePart(pathPartWithArchive, ext); - if (archivePart) { - break; - } - } - } - if (!archivePart) - return null; - filePath = this.pathUtils.join(filePath, archivePart); - if (this.isZip.has(filePath) === false) { - if (this.notZip.has(filePath)) - continue; - try { - if (!this.baseFs.lstatSync(filePath).isFile()) { - this.notZip.add(filePath); - continue; - } - } catch { - return null; - } - this.isZip.add(filePath); - } - return { - archivePath: filePath, - subPath: this.pathUtils.join(PortablePath.root, p.substring(filePath.length)) - }; - } - } - limitOpenFiles(max) { - if (this.zipInstances === null) - return; - const now = Date.now(); - let nextExpiresAt = now + this.maxAge; - let closeCount = max === null ? 0 : this.zipInstances.size - max; - for (const [path, {zipFs, expiresAt, refCount}] of this.zipInstances.entries()) { - if (refCount !== 0 || zipFs.hasOpenFileHandles()) { - continue; - } else if (now >= expiresAt) { - zipFs.saveAndClose(); - this.zipInstances.delete(path); - closeCount -= 1; - continue; - } else if (max === null || closeCount <= 0) { - nextExpiresAt = expiresAt; - break; - } - zipFs.saveAndClose(); - this.zipInstances.delete(path); - closeCount -= 1; - } - if (this.limitOpenFilesTimeout === null && (max === null && this.zipInstances.size > 0 || max !== null)) { - this.limitOpenFilesTimeout = setTimeout(() => { - this.limitOpenFilesTimeout = null; - this.limitOpenFiles(null); - }, nextExpiresAt - now).unref(); - } - } - async getZipPromise(p, accept) { - const getZipOptions = async () => ({ - baseFs: this.baseFs, - libzip: this.libzip, - readOnly: this.readOnlyArchives, - stats: await this.baseFs.statPromise(p) - }); - if (this.zipInstances) { - let cachedZipFs = this.zipInstances.get(p); - if (!cachedZipFs) { - const zipOptions = await getZipOptions(); - cachedZipFs = this.zipInstances.get(p); - if (!cachedZipFs) { - cachedZipFs = { - zipFs: new ZipFS(p, zipOptions), - expiresAt: 0, - refCount: 0 - }; - } - } - this.zipInstances.delete(p); - this.limitOpenFiles(this.maxOpenFiles - 1); - this.zipInstances.set(p, cachedZipFs); - cachedZipFs.expiresAt = Date.now() + this.maxAge; - cachedZipFs.refCount += 1; - try { - return await accept(cachedZipFs.zipFs); - } finally { - cachedZipFs.refCount -= 1; - } - } else { - const zipFs = new ZipFS(p, await getZipOptions()); - try { - return await accept(zipFs); - } finally { - zipFs.saveAndClose(); - } - } - } - getZipSync(p, accept) { - const getZipOptions = () => ({ - baseFs: this.baseFs, - libzip: this.libzip, - readOnly: this.readOnlyArchives, - stats: this.baseFs.statSync(p) - }); - if (this.zipInstances) { - let cachedZipFs = this.zipInstances.get(p); - if (!cachedZipFs) { - cachedZipFs = { - zipFs: new ZipFS(p, getZipOptions()), - expiresAt: 0, - refCount: 0 - }; - } - this.zipInstances.delete(p); - this.limitOpenFiles(this.maxOpenFiles - 1); - this.zipInstances.set(p, cachedZipFs); - cachedZipFs.expiresAt = Date.now() + this.maxAge; - return accept(cachedZipFs.zipFs); - } else { - const zipFs = new ZipFS(p, getZipOptions()); - try { - return accept(zipFs); - } finally { - zipFs.saveAndClose(); - } - } - } -} - -class URLFS extends ProxiedFS { - constructor(baseFs) { - super(npath); - this.baseFs = baseFs; - } - mapFromBase(path) { - return path; - } - mapToBase(path) { - if (path instanceof url.URL) - return url.fileURLToPath(path); - return path; - } -} - -var __defProp$3 = Object.defineProperty; -var __defProps$2 = Object.defineProperties; -var __getOwnPropDescs$2 = Object.getOwnPropertyDescriptors; -var __getOwnPropSymbols$4 = Object.getOwnPropertySymbols; -var __hasOwnProp$4 = Object.prototype.hasOwnProperty; -var __propIsEnum$4 = Object.prototype.propertyIsEnumerable; -var __defNormalProp$3 = (obj, key, value) => key in obj ? __defProp$3(obj, key, {enumerable: true, configurable: true, writable: true, value}) : obj[key] = value; -var __spreadValues$3 = (a, b) => { - for (var prop in b || (b = {})) - if (__hasOwnProp$4.call(b, prop)) - __defNormalProp$3(a, prop, b[prop]); - if (__getOwnPropSymbols$4) - for (var prop of __getOwnPropSymbols$4(b)) { - if (__propIsEnum$4.call(b, prop)) - __defNormalProp$3(a, prop, b[prop]); - } - return a; -}; -var __spreadProps$2 = (a, b) => __defProps$2(a, __getOwnPropDescs$2(b)); -var _a, _b, _c, _d; -const kBaseFs = Symbol(`kBaseFs`); -const kFd = Symbol(`kFd`); -const kClosePromise = Symbol(`kClosePromise`); -const kCloseResolve = Symbol(`kCloseResolve`); -const kCloseReject = Symbol(`kCloseReject`); -const kRefs = Symbol(`kRefs`); -const kRef = Symbol(`kRef`); -const kUnref = Symbol(`kUnref`); -class FileHandle { - constructor(fd, baseFs) { - this[_a] = 1; - this[_b] = void 0; - this[_c] = void 0; - this[_d] = void 0; - this[kBaseFs] = baseFs; - this[kFd] = fd; - } - get fd() { - return this[kFd]; - } - async appendFile(data, options) { - var _a2; - try { - this[kRef](this.appendFile); - const encoding = (_a2 = typeof options === `string` ? options : options == null ? void 0 : options.encoding) != null ? _a2 : void 0; - return await this[kBaseFs].appendFilePromise(this.fd, data, encoding ? {encoding} : void 0); - } finally { - this[kUnref](); - } - } - chown(uid, gid) { - throw new Error(`Method not implemented.`); - } - async chmod(mode) { - try { - this[kRef](this.chmod); - return await this[kBaseFs].fchmodPromise(this.fd, mode); - } finally { - this[kUnref](); - } - } - createReadStream(options) { - return this[kBaseFs].createReadStream(null, __spreadProps$2(__spreadValues$3({}, options), {fd: this.fd})); - } - createWriteStream(options) { - return this[kBaseFs].createWriteStream(null, __spreadProps$2(__spreadValues$3({}, options), {fd: this.fd})); - } - datasync() { - throw new Error(`Method not implemented.`); - } - sync() { - throw new Error(`Method not implemented.`); - } - async read(bufferOrOptions, offset, length, position) { - var _a2, _b2, _c2; - try { - this[kRef](this.read); - let buffer; - if (!Buffer.isBuffer(bufferOrOptions)) { - bufferOrOptions != null ? bufferOrOptions : bufferOrOptions = {}; - buffer = (_a2 = bufferOrOptions.buffer) != null ? _a2 : Buffer.alloc(16384); - offset = bufferOrOptions.offset || 0; - length = (_b2 = bufferOrOptions.length) != null ? _b2 : buffer.byteLength; - position = (_c2 = bufferOrOptions.position) != null ? _c2 : null; - } else { - buffer = bufferOrOptions; - } - offset != null ? offset : offset = 0; - length != null ? length : length = 0; - if (length === 0) { - return { - bytesRead: length, - buffer - }; - } - const bytesRead = await this[kBaseFs].readPromise(this.fd, buffer, offset, length, position); - return { - bytesRead, - buffer - }; - } finally { - this[kUnref](); - } - } - async readFile(options) { - var _a2; - try { - this[kRef](this.readFile); - const encoding = (_a2 = typeof options === `string` ? options : options == null ? void 0 : options.encoding) != null ? _a2 : void 0; - return await this[kBaseFs].readFilePromise(this.fd, encoding); - } finally { - this[kUnref](); - } - } - async stat(opts) { - try { - this[kRef](this.stat); - return await this[kBaseFs].fstatPromise(this.fd, opts); - } finally { - this[kUnref](); - } - } - async truncate(len) { - try { - this[kRef](this.truncate); - return await this[kBaseFs].ftruncatePromise(this.fd, len); - } finally { - this[kUnref](); - } - } - utimes(atime, mtime) { - throw new Error(`Method not implemented.`); - } - async writeFile(data, options) { - var _a2; - try { - this[kRef](this.writeFile); - const encoding = (_a2 = typeof options === `string` ? options : options == null ? void 0 : options.encoding) != null ? _a2 : void 0; - await this[kBaseFs].writeFilePromise(this.fd, data, encoding); - } finally { - this[kUnref](); - } - } - async write(...args) { - try { - this[kRef](this.write); - if (ArrayBuffer.isView(args[0])) { - const [buffer, offset, length, position] = args; - const bytesWritten = await this[kBaseFs].writePromise(this.fd, buffer, offset != null ? offset : void 0, length != null ? length : void 0, position != null ? position : void 0); - return {bytesWritten, buffer}; - } else { - const [data, position, encoding] = args; - const bytesWritten = await this[kBaseFs].writePromise(this.fd, data, position, encoding); - return {bytesWritten, buffer: data}; - } - } finally { - this[kUnref](); - } - } - async writev(buffers, position) { - try { - this[kRef](this.writev); - let bytesWritten = 0; - if (typeof position !== `undefined`) { - for (const buffer of buffers) { - const writeResult = await this.write(buffer, void 0, void 0, position); - bytesWritten += writeResult.bytesWritten; - position += writeResult.bytesWritten; - } - } else { - for (const buffer of buffers) { - const writeResult = await this.write(buffer); - bytesWritten += writeResult.bytesWritten; - } - } - return { - buffers, - bytesWritten - }; - } finally { - this[kUnref](); - } - } - readv(buffers, position) { - throw new Error(`Method not implemented.`); - } - close() { - if (this[kFd] === -1) - return Promise.resolve(); - if (this[kClosePromise]) - return this[kClosePromise]; - this[kRefs]--; - if (this[kRefs] === 0) { - const fd = this[kFd]; - this[kFd] = -1; - this[kClosePromise] = this[kBaseFs].closePromise(fd).finally(() => { - this[kClosePromise] = void 0; - }); - } else { - this[kClosePromise] = new Promise((resolve, reject) => { - this[kCloseResolve] = resolve; - this[kCloseReject] = reject; - }).finally(() => { - this[kClosePromise] = void 0; - this[kCloseReject] = void 0; - this[kCloseResolve] = void 0; - }); - } - return this[kClosePromise]; - } - [(_a = kRefs, _b = kClosePromise, _c = kCloseResolve, _d = kCloseReject, kRef)](caller) { - if (this[kFd] === -1) { - const err = new Error(`file closed`); - err.code = `EBADF`; - err.syscall = caller.name; - throw err; - } - this[kRefs]++; - } - [kUnref]() { - this[kRefs]--; - if (this[kRefs] === 0) { - const fd = this[kFd]; - this[kFd] = -1; - this[kBaseFs].closePromise(fd).then(this[kCloseResolve], this[kCloseReject]); - } - } -} - -const SYNC_IMPLEMENTATIONS = new Set([ - `accessSync`, - `appendFileSync`, - `createReadStream`, - `createWriteStream`, - `chmodSync`, - `fchmodSync`, - `chownSync`, - `closeSync`, - `copyFileSync`, - `linkSync`, - `lstatSync`, - `fstatSync`, - `lutimesSync`, - `mkdirSync`, - `openSync`, - `opendirSync`, - `readlinkSync`, - `readFileSync`, - `readdirSync`, - `readlinkSync`, - `realpathSync`, - `renameSync`, - `rmdirSync`, - `statSync`, - `symlinkSync`, - `truncateSync`, - `ftruncateSync`, - `unlinkSync`, - `unwatchFile`, - `utimesSync`, - `watch`, - `watchFile`, - `writeFileSync`, - `writeSync` -]); -const ASYNC_IMPLEMENTATIONS = new Set([ - `accessPromise`, - `appendFilePromise`, - `fchmodPromise`, - `chmodPromise`, - `chownPromise`, - `closePromise`, - `copyFilePromise`, - `linkPromise`, - `fstatPromise`, - `lstatPromise`, - `lutimesPromise`, - `mkdirPromise`, - `openPromise`, - `opendirPromise`, - `readdirPromise`, - `realpathPromise`, - `readFilePromise`, - `readdirPromise`, - `readlinkPromise`, - `renamePromise`, - `rmdirPromise`, - `statPromise`, - `symlinkPromise`, - `truncatePromise`, - `ftruncatePromise`, - `unlinkPromise`, - `utimesPromise`, - `writeFilePromise`, - `writeSync` -]); -function patchFs(patchedFs, fakeFs) { - fakeFs = new URLFS(fakeFs); - const setupFn = (target, name, replacement) => { - const orig = target[name]; - target[name] = replacement; - if (typeof (orig == null ? void 0 : orig[nodeUtils.promisify.custom]) !== `undefined`) { - replacement[nodeUtils.promisify.custom] = orig[nodeUtils.promisify.custom]; - } - }; - { - setupFn(patchedFs, `exists`, (p, ...args) => { - const hasCallback = typeof args[args.length - 1] === `function`; - const callback = hasCallback ? args.pop() : () => { - }; - process.nextTick(() => { - fakeFs.existsPromise(p).then((exists) => { - callback(exists); - }, () => { - callback(false); - }); - }); - }); - setupFn(patchedFs, `read`, (...args) => { - let [fd, buffer, offset, length, position, callback] = args; - if (args.length <= 3) { - let options = {}; - if (args.length < 3) { - callback = args[1]; - } else { - options = args[1]; - callback = args[2]; - } - ({ - buffer = Buffer.alloc(16384), - offset = 0, - length = buffer.byteLength, - position - } = options); - } - if (offset == null) - offset = 0; - length |= 0; - if (length === 0) { - process.nextTick(() => { - callback(null, 0, buffer); - }); - return; - } - if (position == null) - position = -1; - process.nextTick(() => { - fakeFs.readPromise(fd, buffer, offset, length, position).then((bytesRead) => { - callback(null, bytesRead, buffer); - }, (error) => { - callback(error, 0, buffer); - }); - }); - }); - for (const fnName of ASYNC_IMPLEMENTATIONS) { - const origName = fnName.replace(/Promise$/, ``); - if (typeof patchedFs[origName] === `undefined`) - continue; - const fakeImpl = fakeFs[fnName]; - if (typeof fakeImpl === `undefined`) - continue; - const wrapper = (...args) => { - const hasCallback = typeof args[args.length - 1] === `function`; - const callback = hasCallback ? args.pop() : () => { - }; - process.nextTick(() => { - fakeImpl.apply(fakeFs, args).then((result) => { - callback(null, result); - }, (error) => { - callback(error); - }); - }); - }; - setupFn(patchedFs, origName, wrapper); - } - patchedFs.realpath.native = patchedFs.realpath; - } - { - setupFn(patchedFs, `existsSync`, (p) => { - try { - return fakeFs.existsSync(p); - } catch (error) { - return false; - } - }); - setupFn(patchedFs, `readSync`, (...args) => { - let [fd, buffer, offset, length, position] = args; - if (args.length <= 3) { - const options = args[2] || {}; - ({offset = 0, length = buffer.byteLength, position} = options); - } - if (offset == null) - offset = 0; - length |= 0; - if (length === 0) - return 0; - if (position == null) - position = -1; - return fakeFs.readSync(fd, buffer, offset, length, position); - }); - for (const fnName of SYNC_IMPLEMENTATIONS) { - const origName = fnName; - if (typeof patchedFs[origName] === `undefined`) - continue; - const fakeImpl = fakeFs[fnName]; - if (typeof fakeImpl === `undefined`) - continue; - setupFn(patchedFs, origName, fakeImpl.bind(fakeFs)); - } - patchedFs.realpathSync.native = patchedFs.realpathSync; - } - { - const origEmitWarning = process.emitWarning; - process.emitWarning = () => { - }; - let patchedFsPromises; - try { - patchedFsPromises = patchedFs.promises; - } finally { - process.emitWarning = origEmitWarning; - } - if (typeof patchedFsPromises !== `undefined`) { - for (const fnName of ASYNC_IMPLEMENTATIONS) { - const origName = fnName.replace(/Promise$/, ``); - if (typeof patchedFsPromises[origName] === `undefined`) - continue; - const fakeImpl = fakeFs[fnName]; - if (typeof fakeImpl === `undefined`) - continue; - if (fnName === `open`) - continue; - setupFn(patchedFsPromises, origName, (pathLike, ...args) => { - if (pathLike instanceof FileHandle) { - return pathLike[origName].apply(pathLike, args); - } else { - return fakeImpl.call(fakeFs, pathLike, ...args); - } - }); - } - setupFn(patchedFsPromises, `open`, async (...args) => { - const fd = await fakeFs.openPromise(...args); - return new FileHandle(fd, fakeFs); - }); - } - } - { - patchedFs.read[nodeUtils.promisify.custom] = async (fd, buffer, ...args) => { - const res = fakeFs.readPromise(fd, buffer, ...args); - return {bytesRead: await res, buffer}; - }; - patchedFs.write[nodeUtils.promisify.custom] = async (fd, buffer, ...args) => { - const res = fakeFs.writePromise(fd, buffer, ...args); - return {bytesWritten: await res, buffer}; - }; - } -} - -var libzipSync = {exports: {}}; - -(function (module, exports) { -var frozenFs = Object.assign({}, fs__default.default); -var createModule = function() { - var _scriptDir = void 0; - if (typeof __filename !== "undefined") - _scriptDir = _scriptDir || __filename; - return function(createModule2) { - createModule2 = createModule2 || {}; - var Module = typeof createModule2 !== "undefined" ? createModule2 : {}; - var readyPromiseResolve, readyPromiseReject; - Module["ready"] = new Promise(function(resolve, reject) { - readyPromiseResolve = resolve; - readyPromiseReject = reject; - }); - var moduleOverrides = {}; - var key; - for (key in Module) { - if (Module.hasOwnProperty(key)) { - moduleOverrides[key] = Module[key]; - } - } - var scriptDirectory = ""; - function locateFile(path) { - if (Module["locateFile"]) { - return Module["locateFile"](path, scriptDirectory); - } - return scriptDirectory + path; - } - var read_, readBinary; - var nodeFS; - var nodePath; - { - { - scriptDirectory = __dirname + "/"; - } - read_ = function shell_read(filename, binary) { - var ret = tryParseAsDataURI(filename); - if (ret) { - return binary ? ret : ret.toString(); - } - if (!nodeFS) - nodeFS = frozenFs; - if (!nodePath) - nodePath = path__default.default; - filename = nodePath["normalize"](filename); - return nodeFS["readFileSync"](filename, binary ? null : "utf8"); - }; - readBinary = function readBinary2(filename) { - var ret = read_(filename, true); - if (!ret.buffer) { - ret = new Uint8Array(ret); - } - assert(ret.buffer); - return ret; - }; - if (process["argv"].length > 1) { - process["argv"][1].replace(/\\/g, "/"); - } - process["argv"].slice(2); - Module["inspect"] = function() { - return "[Emscripten Module object]"; - }; - } - var out = Module["print"] || console.log.bind(console); - var err = Module["printErr"] || console.warn.bind(console); - for (key in moduleOverrides) { - if (moduleOverrides.hasOwnProperty(key)) { - Module[key] = moduleOverrides[key]; - } - } - moduleOverrides = null; - if (Module["arguments"]) - ; - if (Module["thisProgram"]) - ; - if (Module["quit"]) - ; - var STACK_ALIGN = 16; - function alignMemory(size, factor) { - if (!factor) - factor = STACK_ALIGN; - return Math.ceil(size / factor) * factor; - } - var wasmBinary; - if (Module["wasmBinary"]) - wasmBinary = Module["wasmBinary"]; - Module["noExitRuntime"] || true; - if (typeof WebAssembly !== "object") { - abort("no native wasm support detected"); - } - function getValue(ptr, type, noSafe) { - type = type || "i8"; - if (type.charAt(type.length - 1) === "*") - type = "i32"; - switch (type) { - case "i1": - return HEAP8[ptr >> 0]; - case "i8": - return HEAP8[ptr >> 0]; - case "i16": - return HEAP16[ptr >> 1]; - case "i32": - return HEAP32[ptr >> 2]; - case "i64": - return HEAP32[ptr >> 2]; - case "float": - return HEAPF32[ptr >> 2]; - case "double": - return HEAPF64[ptr >> 3]; - default: - abort("invalid type for getValue: " + type); - } - return null; - } - var wasmMemory; - var ABORT = false; - function assert(condition, text) { - if (!condition) { - abort("Assertion failed: " + text); - } - } - function getCFunc(ident) { - var func = Module["_" + ident]; - assert(func, "Cannot call unknown function " + ident + ", make sure it is exported"); - return func; - } - function ccall(ident, returnType, argTypes, args, opts) { - var toC = { - string: function(str) { - var ret2 = 0; - if (str !== null && str !== void 0 && str !== 0) { - var len = (str.length << 2) + 1; - ret2 = stackAlloc(len); - stringToUTF8(str, ret2, len); - } - return ret2; - }, - array: function(arr) { - var ret2 = stackAlloc(arr.length); - writeArrayToMemory(arr, ret2); - return ret2; - } - }; - function convertReturnValue(ret2) { - if (returnType === "string") - return UTF8ToString(ret2); - if (returnType === "boolean") - return Boolean(ret2); - return ret2; - } - var func = getCFunc(ident); - var cArgs = []; - var stack = 0; - if (args) { - for (var i = 0; i < args.length; i++) { - var converter = toC[argTypes[i]]; - if (converter) { - if (stack === 0) - stack = stackSave(); - cArgs[i] = converter(args[i]); - } else { - cArgs[i] = args[i]; - } - } - } - var ret = func.apply(null, cArgs); - ret = convertReturnValue(ret); - if (stack !== 0) - stackRestore(stack); - return ret; - } - function cwrap(ident, returnType, argTypes, opts) { - argTypes = argTypes || []; - var numericArgs = argTypes.every(function(type) { - return type === "number"; - }); - var numericRet = returnType !== "string"; - if (numericRet && numericArgs && !opts) { - return getCFunc(ident); - } - return function() { - return ccall(ident, returnType, argTypes, arguments); - }; - } - var UTF8Decoder = typeof TextDecoder !== "undefined" ? new TextDecoder("utf8") : void 0; - function UTF8ArrayToString(heap, idx, maxBytesToRead) { - var endIdx = idx + maxBytesToRead; - var endPtr = idx; - while (heap[endPtr] && !(endPtr >= endIdx)) - ++endPtr; - if (endPtr - idx > 16 && heap.subarray && UTF8Decoder) { - return UTF8Decoder.decode(heap.subarray(idx, endPtr)); - } else { - var str = ""; - while (idx < endPtr) { - var u0 = heap[idx++]; - if (!(u0 & 128)) { - str += String.fromCharCode(u0); - continue; - } - var u1 = heap[idx++] & 63; - if ((u0 & 224) == 192) { - str += String.fromCharCode((u0 & 31) << 6 | u1); - continue; - } - var u2 = heap[idx++] & 63; - if ((u0 & 240) == 224) { - u0 = (u0 & 15) << 12 | u1 << 6 | u2; - } else { - u0 = (u0 & 7) << 18 | u1 << 12 | u2 << 6 | heap[idx++] & 63; - } - if (u0 < 65536) { - str += String.fromCharCode(u0); - } else { - var ch = u0 - 65536; - str += String.fromCharCode(55296 | ch >> 10, 56320 | ch & 1023); - } - } - } - return str; - } - function UTF8ToString(ptr, maxBytesToRead) { - return ptr ? UTF8ArrayToString(HEAPU8, ptr, maxBytesToRead) : ""; - } - function stringToUTF8Array(str, heap, outIdx, maxBytesToWrite) { - if (!(maxBytesToWrite > 0)) - return 0; - var startIdx = outIdx; - var endIdx = outIdx + maxBytesToWrite - 1; - for (var i = 0; i < str.length; ++i) { - var u = str.charCodeAt(i); - if (u >= 55296 && u <= 57343) { - var u1 = str.charCodeAt(++i); - u = 65536 + ((u & 1023) << 10) | u1 & 1023; - } - if (u <= 127) { - if (outIdx >= endIdx) - break; - heap[outIdx++] = u; - } else if (u <= 2047) { - if (outIdx + 1 >= endIdx) - break; - heap[outIdx++] = 192 | u >> 6; - heap[outIdx++] = 128 | u & 63; - } else if (u <= 65535) { - if (outIdx + 2 >= endIdx) - break; - heap[outIdx++] = 224 | u >> 12; - heap[outIdx++] = 128 | u >> 6 & 63; - heap[outIdx++] = 128 | u & 63; - } else { - if (outIdx + 3 >= endIdx) - break; - heap[outIdx++] = 240 | u >> 18; - heap[outIdx++] = 128 | u >> 12 & 63; - heap[outIdx++] = 128 | u >> 6 & 63; - heap[outIdx++] = 128 | u & 63; - } - } - heap[outIdx] = 0; - return outIdx - startIdx; - } - function stringToUTF8(str, outPtr, maxBytesToWrite) { - return stringToUTF8Array(str, HEAPU8, outPtr, maxBytesToWrite); - } - function lengthBytesUTF8(str) { - var len = 0; - for (var i = 0; i < str.length; ++i) { - var u = str.charCodeAt(i); - if (u >= 55296 && u <= 57343) - u = 65536 + ((u & 1023) << 10) | str.charCodeAt(++i) & 1023; - if (u <= 127) - ++len; - else if (u <= 2047) - len += 2; - else if (u <= 65535) - len += 3; - else - len += 4; - } - return len; - } - function allocateUTF8(str) { - var size = lengthBytesUTF8(str) + 1; - var ret = _malloc(size); - if (ret) - stringToUTF8Array(str, HEAP8, ret, size); - return ret; - } - function writeArrayToMemory(array, buffer2) { - HEAP8.set(array, buffer2); - } - function alignUp(x, multiple) { - if (x % multiple > 0) { - x += multiple - x % multiple; - } - return x; - } - var buffer, HEAP8, HEAPU8, HEAP16, HEAP32, HEAPF32, HEAPF64; - function updateGlobalBufferAndViews(buf) { - buffer = buf; - Module["HEAP8"] = HEAP8 = new Int8Array(buf); - Module["HEAP16"] = HEAP16 = new Int16Array(buf); - Module["HEAP32"] = HEAP32 = new Int32Array(buf); - Module["HEAPU8"] = HEAPU8 = new Uint8Array(buf); - Module["HEAPU16"] = new Uint16Array(buf); - Module["HEAPU32"] = new Uint32Array(buf); - Module["HEAPF32"] = HEAPF32 = new Float32Array(buf); - Module["HEAPF64"] = HEAPF64 = new Float64Array(buf); - } - Module["INITIAL_MEMORY"] || 16777216; - var wasmTable; - var __ATPRERUN__ = []; - var __ATINIT__ = []; - var __ATPOSTRUN__ = []; - function preRun() { - if (Module["preRun"]) { - if (typeof Module["preRun"] == "function") - Module["preRun"] = [Module["preRun"]]; - while (Module["preRun"].length) { - addOnPreRun(Module["preRun"].shift()); - } - } - callRuntimeCallbacks(__ATPRERUN__); - } - function initRuntime() { - if (!Module["noFSInit"] && !FS.init.initialized) - FS.init(); - callRuntimeCallbacks(__ATINIT__); - } - function postRun() { - if (Module["postRun"]) { - if (typeof Module["postRun"] == "function") - Module["postRun"] = [Module["postRun"]]; - while (Module["postRun"].length) { - addOnPostRun(Module["postRun"].shift()); - } - } - callRuntimeCallbacks(__ATPOSTRUN__); - } - function addOnPreRun(cb) { - __ATPRERUN__.unshift(cb); - } - function addOnInit(cb) { - __ATINIT__.unshift(cb); - } - function addOnPostRun(cb) { - __ATPOSTRUN__.unshift(cb); - } - var runDependencies = 0; - var dependenciesFulfilled = null; - function addRunDependency(id) { - runDependencies++; - if (Module["monitorRunDependencies"]) { - Module["monitorRunDependencies"](runDependencies); - } - } - function removeRunDependency(id) { - runDependencies--; - if (Module["monitorRunDependencies"]) { - Module["monitorRunDependencies"](runDependencies); - } - if (runDependencies == 0) { - if (dependenciesFulfilled) { - var callback = dependenciesFulfilled; - dependenciesFulfilled = null; - callback(); - } - } - } - Module["preloadedImages"] = {}; - Module["preloadedAudios"] = {}; - function abort(what) { - if (Module["onAbort"]) { - Module["onAbort"](what); - } - what += ""; - err(what); - ABORT = true; - what = "abort(" + what + "). Build with -s ASSERTIONS=1 for more info."; - var e = new WebAssembly.RuntimeError(what); - readyPromiseReject(e); - throw e; - } - var dataURIPrefix = "data:application/octet-stream;base64,"; - function isDataURI(filename) { - return filename.startsWith(dataURIPrefix); - } - var wasmBinaryFile = "data:application/octet-stream;base64,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ACgCFC0AAiAAKAIYajYCGCAAIAAoAhggACgCDGo2AgwgACAAKAIULQADIAAoAhhqNgIYIAAgACgCGCAAKAIMajYCDCAAIAAoAhQtAAQgACgCGGo2AhggACAAKAIYIAAoAgxqNgIMIAAgACgCFC0ABSAAKAIYajYCGCAAIAAoAhggACgCDGo2AgwgACAAKAIULQAGIAAoAhhqNgIYIAAgACgCGCAAKAIMajYCDCAAIAAoAhQtAAcgACgCGGo2AhggACAAKAIYIAAoAgxqNgIMIAAgACgCFC0ACCAAKAIYajYCGCAAIAAoAhggACgCDGo2AgwgACAAKAIULQAJIAAoAhhqNgIYIAAgACgCGCAAKAIMajYCDCAAIAAoAhQtAAogACgCGGo2AhggACAAKAIYIAAoAgxqNgIMIAAgACgCFC0ACyAAKAIYajYCGCAAIAAoAhggACgCDGo2AgwgACAAKAIULQAMIAAoAhhqNgIYIAAgACgCGCAAKAIMajYCDCAAIAAoAhQtAA0gACgCGGo2AhggACAAKAIYIAAoAgxqNgIMIAAgACgCFC0ADiAAKAIYajYCGCAAIAAoAhggACgCDGo2AgwgACAAKAIULQAPIAAoAhhqNgIYIAAgACgCGCAAKAIMajYCDCAAIAAoAhRBEGo2AhQgACAAKAIIQQFrIgE2AgggAQ0ACyAAIAAoAhhB8f8DcDYCGCAAIAAoAgxB8f8DcDYCDAwBCwsgACgCEARAA0AgACgCEEEQTwRAIAAgACgCEEEQazYCECAAIAAoAhQtAAAgACgCGGo2AhggACAAKAIYIAAoAgxqNgIMIAAgACgCFC0AASAAKAIYajYCGCAAIAAoAhggACgCDGo2AgwgACAAKAIULQACIAAoAhhqNgIYIAAgACgCGCAAKAIMajYCDCAAIAAoAhQtAAMgACgCGGo2AhggACAAKAIYIAAoAgxqNgIMIAAgACgCFC0ABCAAKAIYajYCGCAAIAAoAhggACgCDGo2AgwgACAAKAIULQAFIAAoAhhqNgIYIAAgACgCGCAAKAIMajYCDCAAIAAoAhQtAAYgACgCGGo2AhggACAAKAIYIAAoAgxqNgIMIAAgACgCFC0AByAAKAIYajYCGCAAIAAoAhggACgCDGo2AgwgACAAKAIULQAIIAAoAhhqNgIYIAAgACgCGCAAKAIMajYC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NgIYIAEoAgxCADcDICABKAIMQgA3AyggASgCDEEANgIwIAEoAgxBADYCNCABKAIMQQA2AjggASgCDEEANgI8IAEoAgxBADsBQCABKAIMQYCA2I14NgJEIAEoAgxCADcDSCABKAIMQQA7AVAgASgCDEEAOwFSIAEoAgxBADYCVAvSEwEBfyMAQbABayIDJAAgAyAANgKoASADIAE2AqQBIAMgAjYCoAEgA0EANgKQASADIAMoAqQBKAIwQQAQOjYClAEgAyADKAKkASgCOEEAEDo2ApgBAkACQAJAAkAgAygClAFBAkYEQCADKAKYAUEBRg0BCyADKAKUAUEBRgRAIAMoApgBQQJGDQELIAMoApQBQQJHDQEgAygCmAFBAkcNAQsgAygCpAEiACAALwEMQYAQcjsBDAwBCyADKAKkASIAIAAvAQxB/+8DcTsBDCADKAKUAUECRgRAIANB9eABIAMoAqQBKAIwIAMoAqgBQQhqEI4BNgKQASADKAKQAUUEQCADQX82AqwBDAMLCwJAIAMoAqABQYACcQ0AIAMoApgBQQJHDQAgA0H1xgEgAygCpAEoAjggAygCqAFBCGoQjgE2AkggAygCSEUEQCADKAKQARAjIANBfzYCrAEMAwsgAygCSCADKAKQATYCACADIAMoAkg2ApABCwsCQCADKAKkAS8BUkUEQCADKAKkASIAIAAvAQxB/v8DcTsBDAwBCyADKAKkASIAIAAvAQxBAXI7AQwLIAMgAygCpAEgAygCoAEQZUEBcToAhgEgAyADKAKgAUGACnFBgApHBH8gAy0AhgEFQQELQQFxOgCHASADAn9BASADKAKkAS8BUkGBAkYNABpBASADKAKkAS8BUkGCAkYNABogAygCpAEvAVJBgwJGC0EBcToAhQEgAy0AhwFBAXEEQCADIANBIGpCHBApNgIcIAMoAhxFBEAgAygCqAFBCGpBDkEAEBQgAygCkAEQIyADQX82AqwBDAILAkAgAygCoAFBgAJxBEACQCADKAKgAUGACHENACADKAKkASkDIEL/////D1YNACADKAKkASkDKEL/////D1gNAgsgAygCHCADKAKkASkDKBAtIAMoAhwgAygCpAEpAyAQLQwBCwJAAkAgAygCoAFBgAhxDQAgAygCpAEpAyBC/////w9WDQAgAygCpAEpAyhC/////w9WDQAgAygCpAEpA0hC/////w9YDQELIAMoAqQBKQMoQv////8PWgRAIAMoAhwgAygCpAEpAygQLQsgAygCpAEpAyBC/////w9aBEAgAygCHCADKAKkASkDIBAtCyADKAKkASkDSEL/////D1oEQCADKAIcIAMoAqQBKQNIEC0LCwsCfyMAQRBrIgAgAygCHDYCDCAAKAIMLQAAQQFxRQsEQCADKAKoAUEIakEUQQAQFCADKAIcEBYgAygCkAEQIyADQX82AqwBDAILIANBAQJ/IwBBEGsiACADKAIcNgIMAn4gACgCDC0AAEEBcQRAIAAoAgwpAxAMAQtCAAunQf//A3ELIANBIGpBgAYQVTYCjAEgAygCHBAWIAMoAowBIAMoApABNgIAIAMgAygCjAE2ApABCyADLQCFAUEBcQRAIAMgA0EVakIHECk2AhAgAygCEEUEQCADKAKoAUEIakEOQQAQFCADKAKQARAjIANBfzYCrAEMAgsgAygCEEECEB8gAygCEEG9EkECEEEgAygCECADKAKkAS8BUkH/AXEQlgEgAygCECADKAKkASgCEEH//wNxEB8CfyMAQRBrIgAgAygCEDYCDCAAKAIMLQAAQQFxRQsEQCADKAKoAUEIakEUQQAQFCADKAIQEBYgAygCkAEQIyADQX82AqwBDAILIANBgbICQQcgA0EVakGABhBVNgIMIAMoAhAQFiADKAIMIAMoApABNgIAIAMgAygCDDYCkAELIAMgA0HQAGpCLhApIgA2AkwgAEUEQCADKAKoAUEIakEOQQAQFCADKAKQARAjIANBfzYCrAEMAQsgAygCTEHxEkH2EiADKAKgAUGAAnEbQQQQQSADKAKgAUGAAnFFBEAgAygCTCADLQCGAUEBcQR/QS0FIAMoAqQBLwEIC0H//wNxEB8LIAMoAkwgAy0AhgFBAXEEf0EtBSADKAKkAS8BCgtB//8DcRAfIAMoAkwgAygCpAEvAQwQHwJAIAMtAIUBQQFxBEAgAygCTEHjABAfDAELIAMoAkwgAygCpAEoAhBB//8DcRAfCyADKAKkASgCFCADQZ4BaiADQZwBahCNASADKAJMIAMvAZ4BEB8gAygCTCADLwGcARAfAkACQCADLQCFAUEBcUUNACADKAKkASkDKEIUWg0AIAMoAkxBABAhDAELIAMoAkwgAygCpAEoAhgQIQsCQAJAIAMoAqABQYACcUGAAkcNACADKAKkASkDIEL/////D1QEQCADKAKkASkDKEL/////D1QNAQsgAygCTEF/ECEgAygCTEF/ECEMAQsCQCADKAKkASkDIEL/////D1QEQCADKAJMIAMoAqQBKQMgpxAhDAELIAMoAkxBfxAhCwJAIAMoAqQBKQMoQv////8PVARAIAMoAkwgAygCpAEpAyinECEMAQsgAygCTEF/ECELCyADKAJMIAMoAqQBKAIwEFFB//8DcRAfIAMgAygCpAEoAjQgAygCoAEQkgFB//8DcSADKAKQAUGABhCSAUH//wNxajYCiAEgAygCTCADKAKIAUH//wNxEB8gAygCoAFBgAJxRQRAIAMoAkwgAygCpAEoAjgQUUH//wNxEB8gAygCTCADKAKkASgCPEH//wNxEB8gAygCTCADKAKkAS8BQBAfIAMoAkwgAygCpAEoAkQQIQJAIAMoAqQBKQNIQv////8PVARAIAMoAkwgAygCpAEpA0inECEMAQsgAygCTEF/ECELCwJ/IwBBEGsiACADKAJMNgIMIAAoAgwtAABBAXFFCwRAIAMoAqgBQQhqQRRBABAUIAMoAkwQFiADKAKQARAjIANBfzYCrAEMAQsgAygCqAEgA0HQAGoCfiMAQRBrIgAgAygCTDYCDAJ+IAAoAgwtAABBAXEEQCAAKAIMKQMQDAELQgALCxA2QQBIBEAgAygCTBAWIAMoApABECMgA0F/NgKsAQwBCyADKAJMEBYgAygCpAEoAjAEQCADKAKoASADKAKkASgCMBCFAUEASARAIAMoApABECMgA0F/NgKsAQwCCwsgAygCkAEEQCADKAKoASADKAKQAUGABhCRAUEASARAIAMoApABECMgA0F/NgKsAQwCCwsgAygCkAEQIyADKAKkASgCNARAIAMoAqgBIAMoAqQBKAI0IAMoAqABEJEBQQBIBEAgA0F/NgKsAQwCCwsgAygCoAFBgAJxRQRAIAMoAqQBKAI4BEAgAygCqAEgAygCpAEoAjgQhQFBAEgEQCADQX82AqwBDAMLCwsgAyADLQCHAUEBcTYCrAELIAMoAqwBIQAgA0GwAWokACAAC+ACAQF/IwBBIGsiBCQAIAQgADsBGiAEIAE7ARggBCACNgIUIAQgAzYCECAEQRAQGCIANgIMAkAg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AAAgAygCHEHcFmogAygCDEECdGooAgAgAygCHEHYKGpqLQAASg0ADAELIAMoAhxB3BZqIAMoAhRBAnRqIAMoAhxB3BZqIAMoAgxBAnRqKAIANgIAIAMgAygCDDYCFCADIAMoAgxBAXQ2AgwMAQsLIAMoAhxB3BZqIAMoAhRBAnRqIAMoAhA2AgAL1xMBA38jAEEwayICJAAgAiAANgIsIAIgATYCKCACIAIoAigoAgA2AiQgAiACKAIoKAIIKAIANgIgIAIgAigCKCgCCCgCDDYCHCACQX82AhAgAigCLEEANgLQKCACKAIsQb0ENgLUKCACQQA2AhgDQCACKAIYIAIoAhxIBEACQCACKAIkIAIoAhhBAnRqLwEABEAgAiACKAIYIgE2AhAgAigCLEHcFmohAyACKAIsIgQoAtAoQQFqIQAgBCAANgLQKCAAQQJ0IANqIAE2AgAgAigCGCACKAIsQdgoampBADoAAAwBCyACKAIkIAIoAhhBAnRqQQA7AQILIAIgAigCGEEBajYCGAwBCwsDQCACKAIsKALQKEECSARAAkAgAigCEEECSARAIAIgAigCEEEBaiIANgIQDAELQQAhAAsgAigCLEHcFmohAyACKAIsIgQoAtAoQQFqIQEgBCABNgLQKCABQQJ0IANqIAA2AgAgAiAANgIMIAIoAiQgAigCDEECdGpBATsBACACKAIMIAIoAixB2ChqakEAOgAAIAIoAiwiACAAKAKoLUEBazYCqC0gAigCIARAIAIoAiwiACAAKAKsLSACKAIgIAIoAgxBAnRqLwECazYCrC0LDAELCyACKAIoIAIoAhA2AgQgAiACKAIsKALQKEECbTYCGANAIAIoAhhBAU4EQCACKAIsIAIoAiQgAigCGBB5IAIgAigCGEEBazYCGAwBCwsgAiACKAIcNgIMA0AgAiACKAIsKALgFjYCGCACKAIsQdwWaiEBIAIoAiwiAygC0CghACADIABBAWs2AtAoIAIoAiwgAEECdCABaigCADYC4BYgAigCLCACKAIkQQEQeSACIAIoAiwoAuAWNgIUIAIoAhghASACKAIsQdwWaiEDIAIoAiwiBCgC1ChBAWshACAEIAA2AtQoIABBAnQgA2ogATYCACACKAIUIQEgAigCLEHcFmohAyACKAIsIgQoAtQoQQFrIQAgBCAANgLUKCAA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AQsgAigCCEEANgIAIAIoAghCADcDECACKAIIQgA3AwggAigCCEIANwMgIAIoAghCADcDGCACKAIIQQA2AiggAigCCEEAOgAsIAIoAgggAikDECACKAIMEI8BQQFxRQRAIAIoAggQJSACQQA2AhwMAQsgAiACKAIINgIcCyACKAIcIQEgAkEgaiQAIAEL1gIBAX8jAEEgayIDJAAgAyAANgIYIAMgATYCFCADIAI2AhAgAyADQQxqQgQQKTYCCAJAIAMoAghFBEAgA0F/NgIcDAELA0AgAygCFARAIAMoAhQoAgQgAygCEHFBgAZxBEAgAygCCEIAECwaIAMoAgggAygCFC8BCBAfIAMoAgggAygCFC8BChAfAn8jAEEQayIAIAMoAgg2AgwgACgCDC0AAEEBcUULBEAgAygCGEEIakEUQQAQFCADKAIIEBYgA0F/NgIcDAQLIAMoAhggA0EMakIEEDZBAEgEQCADKAIIEBYgA0F/NgIcDAQLIAMoAhQvAQoEQCADKAIYIAMoAhQoAgwgAygCFC8BCq0QNkEASARAIAMoAggQFiADQX82AhwMBQsLCyADIAMoAhQoAgA2AhQMAQsLIAMoAggQFiADQQA2AhwLIAMoAhwhACADQSBqJAAgAAtoAQF/IwBBEGsiAiAANgIMIAIgATYCCCACQQA7AQYDQCACKAIMBEAgAigCDCgCBCACKAIIcUGABnEEQCACIAIoAgwvAQogAi8BBkEEamo7AQYLIAIgAigCDCgCADYCDAwBCwsgAi8BBgvwAQEBfyMAQRBrIgEkACABIAA2AgwgASABKAIMNgIIIAFBADYCBANAIAEoAgwEQAJAAkAgASgCDC8BCEH1xgFGDQAgASgCDC8BCEH14AFGDQAgASgCDC8BCEGBsgJGDQAgASgCDC8BCEEBRw0BCyABIAEoAgwoAgA2AgAgASgCCCABKAIMRgRAIAEgASgCADYCCAsgASgCDEEANgIAIAEoAgwQIyABKAIEBEAgASgCBCABKAIANgIACyABIAEoAgA2AgwMAgsgASABKAIMNgIEIAEgASgCDCgCADYCDAwBCwsgASgCCCEAIAFBEGokACAAC7IEAQF/IwBBQGoiBSQAIAUgADYCOCAFIAE7ATYgBSACNgIwIAUgAzYCLCAFIAQ2AiggBSAFKAI4IAUvATatECkiADYC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IAEoAhBB//8DRgRAIAEgASgCDDYCEAsgASgCCEH//wNGBEAgASABKAIENgIICwJAIAEoApQBQQRxRQ0AIAEoAgggASgCBEYEQCABKAIQIAEoAgxGDQELIAEoApABQRVBABAUIAEtABdBAXEEQCABKAKkARAWCyABQQA2AqwBDAELAkAgASgCEEUEQCABKAIIRQ0BCyABKAKQAUEBQQAQFCABLQAXQQFxBEAgASgCpAEQFgsgAUEANgKsAQwBCyABIAEoAqQBEDE3AyggASABKAKkARAxNwMgIAEpAyggASkDIFIEQCABKAKQAUEBQQAQFCABLQAXQQFxBEAgASgCpAEQFgsgAUEANgKsAQwBCyABIAEoAqQBEDE3AzAgASABKAKkARAxNwOAAQJ/IwBBEGsiBSABKAKkATYCDCAFKAIMLQAAQQFxRQsEQCABKAKQAUEUQQAQFCABLQAXQQFxBEAgASgCpAEQFgsgAUEANgKsAQwBCyABLQAXQQFxBEAgASgCpAEQFgsCQCABKQOAAUL///////////8AWARAIAEpA4ABIAEpA4ABIAEpAzB8WA0BCyABKAKQAUEEQRYQFCABQQA2AqwBDAELIAEpA4ABIAEpAzB8IAEpA5gBIAEpAzh8VgRAIAEoApABQRVBABAUIAFBADYCrAEMAQsCQCABKAKUAUEEcUUNACABKQOAASABKQMwfCABKQOYASABKQM4fFENACABKAKQAUEVQQAQFCABQQA2AqwBDAELIAEpAyggASkDMEIugFYEQCABKAKQAUEVQQAQFCABQQA2AqwBDAELIAEgASkDKCABKAKQARCQASIFNgKMASAFRQRAIAFBADYCrAEMAQsgASgCjAFBAToALCABKAKMASABKQMwNwMYIAEoAowBIAEpA4ABNwMgIAEgASgCjAE2AqwBCyABKAKsASEFIAFBsAFqJAAgACAFNgJQDAELIAAoAmQgACkDMBAsGiAAKAJkIQUgACkDWCEJIAAoAmgoAhQhBiAAKAJUIQcjAEHQAGsiASQAIAEgBTYCSCABIAk3A0AgASAGNgI8IAEgBzYCOAJAIAEoAkgQMEIWVARAIAEoAjhBFUEAEBQgAUEANgJMDAELIwBBEGsiBSABKAJINgIMIAECfiAFKAIMLQAAQQFxBEAgBSgCDCkDEAwBC0IACzcDCCABKAJI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ECADQcgAEBgiADYCDAJAIABFBEAgAygCEEEBQbSbASgCABAUIANBADYCHAwBCyADKAIMIAMoAhA2AgAgAygCDCADLQAbQQFxOgAEIAMoAgwgAygCFDYCCAJAIAMoAgwoAghBAU4EQCADKAIMKAIIQQlMDQELIAMoAgxBCTYCCAsgAygCDEEAOgAMIAMoAgxBADYCMCADKAIMQQA2AjQgAygCDEEANgI4IAMgAygCDDYCHAsgAygCHCEAIANBIGokACAACzgBAX8jAEEQayIBIAA2AgwgASgCDEEANgIAIAEoAgxBADYCBCABKAIMQQA2AgggASgCDEEAOgAMC+MIAQF/IwBBQGoiAiAANgI4IAIgATYCNCACIAIoAjgoAnw2AjAgAiACKAI4KAI4IAIoAjgoAmxqNgIsIAIgAigCOCgCeDYCICACIAIoAjgoApABNgIcIAICfyACKAI4KAJsIAIoAjgoAixBhgJrSwRAIAIoAjgoAmwgAigCOCgCLEGGAmtrDAELQQALNgIYIAIgAigCOCgCQDYCFCACIAIoAjgoAjQ2AhAgAiACKAI4KAI4IAIoAjgoAmxqQYICajYCDCACIAIoAiwgAigCIEEBa2otAAA6AAsgAiACKAIsIAIoAiBqLQAAOgAKIAIoAjgoAnggAigCOCgCjAFPBEAgAiACKAIwQQJ2NgIwCyACKAIcIAIoAjgoAnRLBEAgAiACKAI4KAJ0NgIcCwNAAkAgAiACKAI4KAI4IAIoAjRqNgIoAkAgAigCKCACKAIgai0AACACLQAKRw0AIAIoAiggAigCIEEBa2otAAAgAi0AC0cNACACKAIoLQAAIAIoAiwtAABHDQAgAiACKAIoIgBBAWo2AiggAC0AASACKAIsLQABRwRADAELIAIgAigCLEECajYCLCACIAIoAihBAWo2AigDQCACIAIoAiwiAEEBajYCLCAALQABIQEgAiACKAIoIgBBAWo2AigCf0EAIAAtAAEgAUcNABogAiACKAIsIgBBAWo2AiwgAC0AASEBIAIgAigCKCIAQQFqNgIoQQAgAC0AASABRw0AGiACIAIoAiwiAEEBajYCLCAALQABIQEgAiACKAIoIgBBAWo2AihBACAALQABIAFHDQAaIAIgAigCLCIAQQFqNgIsIAAtAAEhASACIAIoAigiAEEBajYCKEEAIAAtAAEgAUcNABogAiACKAIsIgBBAWo2AiwgAC0AASEBIAIgAigCKCIAQQFqNgIoQQAgAC0AASABRw0AGiACIAIoAiwiAEEBajYCLCAALQABIQEgAiACKAIoIgBBAWo2AihBACAALQABIAFHDQAaIAIgAigCLCIAQQFqNgIsIAAtAAEhASACIAIoAigiAEEBajYCKEEAIAAtAAEgAUcNABogAiACKAIsIgBBAWo2AiwgAC0AASEBIAIgAigCKCIAQQFqNgIoQQAgAC0AASABRw0AGiACKAIsIAIoAgxJC0EBcQ0ACyACQYICIAIoAgwgAigCLGtrNgIkIAIgAigCDEGCAms2AiwgAigCJCACKAIgSgRAIAIoAjggAigCNDYCcCACIAIoAiQ2AiAgAigCJCACKAIcTg0CIAIgAigCLCACKAIgQQFrai0AADoACyACIAIoAiwgAigCIGotAAA6AAoLCyACIAIoAhQgAigCNCACKAIQcUEBdGovAQAiATYCNEEAIQAgASACKAIYSwR/IAIgAigCMEEBayIANgIwIABBAEcFQQALQQFxDQELCwJAIAIoAiAgAigCOCgCdE0EQCACIAIoAiA2AjwMAQsgAiACKAI4KAJ0NgI8CyACKAI8C5IQAQF/IwBBMGsiAiQAIAIgADYCKCACIAE2AiQgAgJ/IAIoAigoAiwgAigCKCgCDEEFa0kEQCACKAIoKAIsDAELIAIoAigoAgxBBWsLNgIgIAJBADYCECACIAIoAigoAgAoAgQ2AgwDQAJAIAJB//8DNgIcIAIgAigCKCgCvC1BKmpBA3U2AhQgAigCKCgCACgCECACKAIUSQ0AIAIgAigCKCgCACgCECACKAIUazYCFCACIAIoAigoAmwgAigCKCgCXGs2AhggAigCHCACKAIYIAIoAigoAgAoAgRqSwRAIAIgAigCGCACKAIoKAIAKAIEajYCHAsgAigCHCACKAIUSwRAIAIgAigCFDYCHAsCQCACKAIcIAIoAiBPDQACQCACKAIcRQRAIAIoAiRBBEcNAQsgAigCJEUNACACKAIcIAIoAhggAigCKCgCACgCBGpGDQELDAELQQAhACACIAIoAiRBBEYEfyACKAIcIAIoAhggAigCKCgCACgCBGpGBUEAC0EBcTYCECACKAIoQQBBACACKAIQEF0gAigCKCgCCCACKAIoKAIUQQRraiACKAIcOgAAIAIoAigoAgggAigCKCgCFEEDa2ogAigCHEEIdjoAACACKAIoKAIIIAIoAigoAhRBAmtqIAIoAhxBf3M6AAAgAigCKCgCCCACKAIoKAIUQQFraiACKAIcQX9zQQh2OgAAIAIoAigoAgAQHCACKAIYBEAgAigCGCACKAIcSwRAIAIgAigCHDYCGAsgAigCKCgCACgCDCACKAIoKAI4IAIoAigoAlxqIAIoAhgQGRogAigCKCgCACIAIAIoAhggACgCDGo2AgwgAigCKCgCACIAIAAoAhAgAigCGGs2AhAgAigCKCgCACIAIAIoAhggACgCFGo2AhQgAigCKCIAIAIoAhggACgCXGo2AlwgAiACKAIcIAIoAhhrNgIcCyACKAIcBEAgAigCKCgCACACKAIoKAIAKAIMIAIoAhwQdhogAigCKCgCACIAIAIoAhwgACgCDGo2AgwgAigCKCgCACIAIAAoAhAgAigCHGs2AhAgAigCKCgCACIAIAIoAhwgACgCFGo2AhQLIAIoAhBFDQELCyACIAIoAgwgAigCKCgCACgCBGs2AgwgAigCDARAAkAgAigCDCACKAIoKAIsTwRAIAIoAihBAjYCsC0gAigCKCgCOCACKAIoKAIAKAIAIAIoAigoAixrIAIoAigoAiwQGRogAigCKCACKAIoKAIsNgJsDAELIAIoAgwgAigCKCgCPCACKAIoKAJsa08EQCACKAIoIgAgACgCbCACKAIoKAIsazYCbCACKAIoKAI4IAIoAigoAjggAigCKCgCLGogAigCKCgCbBAZGiACKAIoKAKwLUECSQRAIAIoAigiACAAKAKwLUEBajYCsC0LCyACKAIoKAI4IAIoAigoAmxqIAIoAigoAgAoAgAgAigCDGsgAigCDBAZGiACKAIoIgAgAigCDCAAKAJsajYCbAsgAigCKCACKAIoKAJsNgJcIAIoAigiAQJ/IAIoAgwgAigCKCgCLCACKAIoKAK0LWtLBEAgAigCKCgCLCACKAIoKAK0LWsMAQsgAigCDAsgASgCtC1qNgK0LQsgAigCKCgCwC0gAigCKCgCbEkEQCACKAIoIAIoAigoAmw2AsAtCwJAIAIoAhAEQCACQQM2AiwMAQsCQCACKAIkRQ0AIAIoAiRBBEYNACACKAIoKAIAKAIEDQAgAigCKCgCbCACKAIoKAJcRw0AIAJBATYCLAwBCyACIAIoAigoAjwgAigCKCgCbGtBAWs2AhQCQCACKAIoKAIAKAIEIAIoAhRNDQAgAigCKCgCXCACKAIoKAIsSA0AIAIoAigiACAAKAJcIAIoAigoAixrNgJcIAIoAigiACAAKAJsIAIoAigoAixrNgJsIAIoAigoAjggAigCKCgCOCACKAIoKAIsaiACKAIoKAJsEBkaIAIoAigoArAtQQJJBEAgAigCKCIAIAAoArAtQQFqNgKwLQsgAiACKAIoKAIsIAIoAhRqNgIUCyACKAIUIAIoAigoAgAoAgRLBEAgAiACKAIoKAIAKAIENgIUCyACKAIUBEAgAigCKCgCACACKAIoKAI4IAIoAigoAmxqIAIoAhQQdhogAigCKCIAIAIoAhQgACgCbGo2AmwLIAIoAigoAsAtIAIoAigoAmxJBEAgAigCKCACKAIoKAJsNgLALQsgAiACKAIoKAK8LUEqakEDdTYCFCACIAIoAigoAgwgAigCFGtB//8DSwR/Qf//AwUgAigCKCgCDCACKAIUaws2AhQgAgJ/IAIoAhQgAigCKCgCLEsEQCACKAIoKAIsDAELIAIoAhQLNgIgIAIgAigCKCgCbCACKAIoKAJcazYCGAJAIAIoAhggAigCIEkEQCACKAIYRQRAIAIoAiRBBEcNAgsgAigCJEUNASACKAIoKAIAKAIEDQEgAigCGCACKAIUSw0BCyACAn8gAigCGCACKAIUSwRAIAIoAhQMAQsgAigCGAs2AhwgAgJ/QQAgAigCJEEERw0AGkEAIAIoAigoAgAoAgQNABogAigCHCACKAIYRgtBAXE2AhAgAigCKCACKAIoKAI4IAIoAigoAlxqIAIoAhwgAigCEBBdIAIoAigiACACKAIcIAAoAlxqNgJcIAIoAigoAgAQHAsgAkECQQAgAigCEBs2AiwLIAIoAiwhACACQTBqJAAgAAuyAgEBfyMAQRBrIgEkACABIAA2AggCQCABKAIIEHgEQCABQX42AgwMAQsgASABKAIIKAIcKAIENgIEIAEoAggoAhwoAggEQCABKAIIKAIoIAEoAggoAhwoAgggASgCCCgCJBEEAAsgASgCCCgCHCgCRARAIAEoAggoAiggASgCCCgCHCgCRCABKAIIKAIkEQQACyABKAIIKAIc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DQAgAiEAIANBAWsiAw0ACwsgBCgCFBogASACNgKgAQwCCyMAQRBrIgAgASgCqAEoAgQ2AgwgAUEAIAAoAgxrQQJ0QajZAGooAgA2AqABDAELIAFBADYCoAELCwJAIAEoAqABRQRAIAEgASgCpAE2AqwBDAELIAEgASgCoAEQLgJ/IAEoAqQBBEAgASgCpAEQLkECagwBC0EAC2pBAWoQGCIANgIcIABFBEAgAUG4EygCADYCrAEMAQsgASgCHCEAAn8gASgCpAEEQCABKAKkAQwBC0H6EgshA0HfEkH6EiABKAKkARshAiABIAEoAqABNgIIIAEgAjYCBCABIAM2AgAgAEG+CiABEG8gASgCqAEgASgCHDYCCCABIAEoAhw2AqwBCyABKAKsASEAIAFBsAFqJAAgAAsIAEEBQTgQfwszAQF/IAAoAhQiAyABIAIgACgCECADayIBIAEgAksbIgEQGRogACAAKAIUIAFqNgIUIAILjwUCBn4BfyABIAEoAgBBD2pBcHEiAUEQajYCACAAAnwgASkDACEDIAEpAwghBiMAQSBrIggkAAJAIAZC////////////AIMiBEKAgICAgIDAgDx9IARCgICAgICAwP/DAH1UBEAgBkIEhiADQjyIhCEEIANC//////////8PgyIDQoGAgICAgICACFoEQCAEQoGAgICAgICAwAB8IQIMAgsgBEKAgICAgICAgEB9IQIgA0KAgICAgICAgAiFQgBSDQEgAiAEQgGDfCECDAELIANQIARCgICAgICAwP//AFQgBEKAgICAgIDA//8AURtFBEAgBkIEhiADQjyIhEL/////////A4NCgICAgICAgPz/AIQhAgwBC0KAgICAgICA+P8AIQIgBEL///////+//8MAVg0AQgAhAiAEQjCIpyIAQZH3AEkNACADIQIgBkL///////8/g0KAgICAgIDAAIQiBSEHAkAgAEGB9wBrIgFBwABxBEAgAiABQUBqrYYhB0IAIQIMAQsgAUUNACAHIAGtIgSGIAJBwAAgAWutiIQhByACIASGIQILIAggAjcDECAIIAc3AxgCQEGB+AAgAGsiAEHAAHEEQCAFIABBQGqtiCEDQgAhBQwBCyAARQ0AIAVBwAAgAGuthiADIACtIgKIhCEDIAUgAoghBQsgCCADNwMAIAggBTcDCCAIKQMI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ADYCtC0gASgCFEEERgRAIAEoAhgCfyABKAIYKAJcQQBOBEAgASgCGCgCOCABKAIYKAJcagwBC0EACyABKAIYKAJsIAEoAhgoAlxrQQEQKCABKAIYIAEoAhgoAmw2AlwgASgCGCgCABAcIAEoAhgoAgAoAhBFBEAgAUECNgIcDAILIAFBAzYCHAwBCyABKAIYKAKgLQRAIAEoAhgCfyABKAIYKAJcQQBOBEAgASgCGCgCOCABKAIYKAJcagwBC0EACyABKAIYKAJsIAEoAhgoAlxrQQAQKCABKAIYIAEoAhgoAmw2AlwgASgCGCgCABAcIAEoAhgoAgAoAhBFBEAgAUEANgIcDAILCyABQQE2AhwLIAEoAhwhAiABQSBqJAAgAgwBCwJ/IAAoAiwoAogBQQNGBEAgACgCLCECIAAoAjQhAyMAQTBrIgEkACABIAI2AiggASADNgIkAkADQAJAIAEoAigoAnRBggJNBEAgASgCKBBcAkAgASgCKCgCdEGCAksNACABKAIkDQAgAUEANgIsDAQLIAEoAigoAnRFDQELIAEoAihBADYCYAJAIAEoAigoAnRBA0kNACABKAIoKAJsRQ0AIAEgASgCKCgCOCABKAIoKAJsakEBazYCGCABIAEoAhgtAAA2AhwgASgCHCECIAEgASgCGCIDQQFqNgIYAkAgAy0AASACRw0AIAEoAhwhAiABIAEoAhgiA0EBajYCGCADLQABIAJHDQAgASgCHCECIAEgASgCGCIDQQFqNgIYIAMtAAEgAkcNACABIAEoAigoAjggASgCKCgCbGpBggJqNgIUA0AgASgCHCECIAEgASgCGCIDQQFqNgIYAn9BACADLQABIAJHDQAaIAEoAhwhAiABIAEoAhgiA0EBajYCGEEAIAMtAAEgAkcNABogASgCHCECIAEgASgCGCIDQQFqNgIYQQAgAy0AASACRw0AGiABKAIcIQIgASABKAIYIgNBAWo2AhhBACADLQABIAJHDQAaIAEoAhwhAiABIAEoAhgiA0EBajYCGEEAIAMtAAEgAkcNABogASgCHCECIAEgASgCGCIDQQFqNgIYQQAgAy0AASACRw0AGiABKAIcIQIgASABKAIYIgNBAWo2AhhBACADLQABIAJHDQAaIAEoAhwhAiABIAEoAhgiA0EBajYCGEEAIAMtAAEgAkcNABog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AS8BEiECIAEgASgCSCIDQQFqNgJIIAMgAjoAAAwCCyABKAIMQRBxBEAgASABLwESNgIIIAEgASgCDEEPcTYCDCABKAIMBEAgASgCKCABKAIMSQRAIAEgASgCUCICQQFqNgJQIAEgASgCLCACLQAAIAEoAih0ajYCLCABIAEoAihBCGo2AigLIAEgASgCCCABKAIsQQEgASgCDHRBAWtxajYCCCABIAEoAiwgASgCDHY2AiwgASABKAIoIAEoAgxrNgIoCyABKAIoQQ9JBEAgASABKAJQIgJBAWo2AlAgASABKAIsIAItAAAgASgCKHRqNgIsIAEgASgCKEEIajYCKCABIAEoAlAiAkEBajYCUCABIAEoAiwgAi0AACABKAIodGo2AiwgASABKAIoQQhqNgIoCyABIAEoAiAgASgCLCABKAIYcUECdGooAQA2ARACQANAIAEgAS0AETYCDCABIAEoAiwgASgCDHY2AiwgASABKAIoIAEoAgxrNgIoIAEgAS0AEDYCDCABKAIMQRBxBEAgASABLwESNgIEIAEgASgCDEEPcTYCDCABKAIoIAEoAgxJBEAgASABKAJQIgJBAWo2AlAgASABKAIsIAItAAAgASgCKHRqNgIsIAEgASgCKEEIajYCKCABKAIoIAEoAgxJBEAgASABKAJQIgJBAWo2AlAgASABKAIsIAItAAAgASgCKHRqNgIsIAEgASgCKEEIajYCKAsLIAEgASgCBCABKAIsQQEgASgCDHRBAWtxajYCBCABIAEoAiwgASgCDHY2AiwgASABKAIoIAEoAgxrNgIoIAEgASgCSCABKAJEazYCDAJAIAEoAgQgASgCDEsEQCABIAEoAgQgASgCDGs2AgwgASgCDCABKAI4SwRAIAEoAlQoAsQ3BEAgASgCXEHdDDYCGCABKAJUQdH+ADYCBAwKCwsgASABKAIwNgIAAkAgASgCNEUEQCABIAEoAgAgASgCPCABKAIMa2o2AgAgASgCDCABKAIISQRAIAEgASgCCCABKAIMazYCCANAIAEgASgCACICQQFqNgIAIAItAAAhAiABIAEoAkgiA0EBajYCSCADIAI6AAAgASABKAIMQQFrIgI2AgwgAg0ACyABIAEoAkggASgCBGs2AgALDAELAkAgASgCNCABKAIMSQRAIAEgASgCACABKAI8IAEoAjRqIAEoAgxrajYCACABIAEoAgwgASgCNGs2AgwgASgCDCABKAIISQRAIAEgASgCCCABKAIMazYCCANAIAEgASgCACICQQFqNgIAIAItAAAhAiABIAEoAkgiA0EBajYCSCADIAI6AAAgASABKAIMQQFrIgI2AgwgAg0ACyABIAEoAjA2AgAgASgCNCABKAIISQRAIAEgASgCNDYCDCABIAEoAgggASgCDGs2AggDQCABIAEoAgAiAkEBajYCACACLQAAIQIgASABKAJIIgNBAWo2AkggAyACOgAAIAEgASgCDEEBayICNgIMIAINAAsgASABKAJIIAEoAgRrNgIACwsMAQsgASABKAIAIAEoAjQgASgCDGtqNgIAIAEoAgwgASgCCEkEQCABIAEoAgggASgCDGs2AggDQCABIAEoAgAiAkEBajYCACACLQAAIQIgASABKAJIIgNBAWo2AkggAyACOgAAIAEgASgCDEEBayICNgIMIAINAAsgASABKAJIIAEoAgRrNgIACwsLA0AgASgCCEECSwRAIAEgASgCACICQQFqNgIAIAItAAAhAiABIAEoAkgiA0EBajYCSCADIAI6AAAgASABKAIAIgJBAWo2AgAgAi0AACECIAEgASgCSCIDQQFqNgJIIAMgAjoAACABIAEoAgAiAkEBajYCACACLQAAIQIgASABKAJIIgNBAWo2AkggAyACOgAAIAEgASgCCEEDazYCCAwBCwsMAQsgASABKAJIIAEoAgRrNgIAA0AgASABKAIAIgJBAWo2AgAgAi0AACECIAEgASgCSCIDQQFqNgJIIAMgAjoAACABIAEoAgAiAkEBajYCACACLQAAIQIgASABKAJIIgNBAWo2AkggAyACOgAAIAEgASgCACICQQFqNgIAIAItAAAhAiABIAEoAkgiA0EBajYCSCADIAI6AAAgASABKAIIQQNrNgIIIAEoAghBAksNAAsLIAEoAggEQCABIAEoAgAiAkEBajYCACACLQAAIQIgASABKAJIIgNBAWo2AkggAyACOgAAIAEoAghBAUsEQCABIAEoAgAiAkEBajYCACACLQAAIQIgASABKAJIIgNBAWo2AkggAyACOgAACwsMAgsgASgCDEHAAHFFBEAgASABKAIgIAEvARIgASgCLEEBIAEoAgx0QQFrcWpBAnRqKAEANgEQDAELCyAB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AG5hbgAvZGV2L3VyYW5kb20AaW52YWxpZCBjb2RlIC0tIG1pc3NpbmcgZW5kLW9mLWJsb2NrAGluY29ycmVjdCBoZWFkZXIgY2hlY2sAaW5jb3JyZWN0IGxlbmd0aCBjaGVjawBpbmNvcnJlY3QgZGF0YSBjaGVjawBpbnZhbGlkIGRpc3RhbmNlIHRvbyBmYXIgYmFjawBoZWFkZXIgY3JjIG1pc21hdGNoAGluZgBpbnZhbGlkIHdpbmRvdyBzaXplAFJlYWQtb25seSBhcmNoaXZlAE5vdCBhIHppcCBhcmNoaXZlAFJlc291cmNlIHN0aWxsIGluIHVzZQBNYWxsb2MgZmFpbHVyZQBpbnZhbGlkIGJsb2NrIHR5cGUARmFpbHVyZSB0byBjcmVhdGUgdGVtcG9yYXJ5IGZpbGUAQ2FuJ3Qgb3BlbiBmaWxlAE5vIHN1Y2ggZmlsZQBQcmVtYXR1cmUgZW5kIG9mIGZpbGUAQ2FuJ3QgcmVtb3ZlIGZpbGUAaW52YWxpZCBsaXRlcmFsL2xlbmd0aCBjb2RlAGludmFsaWQgZGlzdGFuY2UgY29kZQB1bmtub3duIGNvbXByZXNzaW9uIG1ldGhvZABzdHJlYW0gZW5kAENvbXByZXNzZWQgZGF0YSBpbnZhbGlkAE11bHRpLWRpc2sgemlwIGFyY2hpdmVzIG5vdCBzdXBwb3J0ZWQAT3BlcmF0aW9uIG5vdCBzdXBwb3J0ZWQARW5jcnlwdGlvbiBtZXRob2Qgbm90IHN1cHBvcnRlZABDb21wcmVzc2lvbiBtZXRob2Qgbm90IHN1cHBvcnRlZABFbnRyeSBoYXMgYmVlbiBkZWxldGVkAENvbnRhaW5pbmcgemlwIGFyY2hpdmUgd2FzIGNsb3NlZABDbG9zaW5nIHppcCBhcmNoaXZlIGZhaWxlZABSZW5hbWluZyB0ZW1wb3JhcnkgZmlsZSBmYWlsZWQARW50cnkgaGFzIGJlZW4gY2hhbmdlZABObyBwYXNzd29yZCBwcm92aWRlZABXcm9uZyBwYXNzd29yZCBwcm92aWRlZABVbmtub3duIGVycm9yICVkAHJiAHIrYgByd2EAJXMuWFhYWFhYAE5BTgBJTkYAQUUAMS4yLjExAC9wcm9jL3NlbGYvZmQvAC4AKG51bGwpADogAFBLBgcA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0gAIADIACACyAAgAcgAIAPIACAAKAAgAigAIAEoACADKAAgAKgAIAKoACABqAAgA6gAIABoACACaAAgAWgAIANoACAA6AAgAugAIAHoACAD6AAgABgAIAIYACABGAAgAxgAIACYACACmAAgAZgAIAOYACAAWAAgAlgAIAFYACADWAAgANgAIALYACAB2AAgA9gAIAA4ACACOAAgATgAIAM4ACAAuAAgArgAIAG4ACADuAAgAHgAIAJ4ACABeAAgA3gAIAD4ACAC+AAgAfgAIAP4ACAABAAgAgQAIAEEACADBAAgAIQAIAKEACABhAAgA4QAIABEACACRAAgAUQAIANEACAAxAAgAsQAIAHEACADxAAgACQAIAIkACABJAAgAyQAIACkACACpAAgAaQAIAOkACAAZAAgAmQAIAFkACADZAAgAOQAIALkACAB5AAgA+QAIAAUACACFAAgARQAIAMUACAAlAAgApQAIAGUACADlAAgAFQAIAJUACABVAAgA1QAIADUACAC1AAgAdQAIAPUACAANAAgAjQAIAE0ACADNAAgALQAIAK0ACABtAAgA7QAIAB0ACACdAAgAXQAIAN0ACAA9AAgAvQAIAH0ACAD9AAgAEwAJABMBCQCTAAkAkwEJAFMACQBTAQkA0wAJANMBCQAzAAkAMwEJALMACQCzAQkAcwAJAHMBCQDzAAkA8wEJAAsACQALAQkAiwAJAIsBCQBLAAkASwEJAMsACQDLAQkAKwAJACsBCQCrAAkAqwEJAGsACQBrAQkA6wAJAOsBCQAbAAkAGwEJAJsACQCbAQkAWwAJAFsBCQDbAAkA2wEJADsACQA7AQkAuwAJALsBCQB7AAkAewEJAPsACQD7AQkABwAJAAcBCQCHAAkAhwEJAEcACQBHAQkAxwAJAMcBCQAnAAkAJwEJAKcACQCnAQkAZwAJAGcBCQDnAAkA5wEJABcACQAXAQkAlwAJAJcBCQBXAAkAVwEJANcACQDXAQkANwAJADcBCQC3AAkAtwEJAHcACQB3AQkA9wAJAPcBCQAPAAkADwEJAI8ACQCPAQkATwAJAE8BCQDPAAkAzwEJAC8ACQAvAQkArwAJAK8BCQBvAAkAbwEJAO8ACQDvAQkAHwAJAB8BCQCfAAkAnwEJAF8ACQBfAQkA3wAJAN8BCQA/AAkAPwEJAL8ACQC/AQkAfwAJAH8BCQD/AAkA/wEJAAAABwBAAAcAIAAHAGAABwAQAAcAUAAHADAABwBwAAcACAAHAEgABwAoAAcAaAAHABgABwBYAAcAOAAHAHgABwAEAAcARAAHACQABwBkAAcAFAAHAFQABwA0AAcAdAAHAAMACACDAAgAQwAIAMMACAAjAAgAowAIAGMACADjAAgAAAAFABAABQAIAAUAGAAFAAQABQAUAAUADAAFABwABQACAAUAEgAFAAoABQAaAAUABgAFABYABQAOAAUAHgAFAAEABQARAAUACQAFABkABQAFAAUAFQAFAA0ABQAdAAUAAwAFABMABQALAAUAGwAFAAcABQAXAAUAQbDqAAtNAQAAAAEAAAABAAAAAQAAAAIAAAACAAAAAgAAAAIAAAADAAAAAwAAAAMAAAADAAAABAAAAAQAAAAEAAAABAAAAAUAAAAFAAAABQAAAAUAQaDrAAtlAQAAAAEAAAACAAAAAgAAAAMAAAADAAAABAAAAAQAAAAFAAAABQAAAAYAAAAGAAAABwAAAAcAAAAIAAAACAAAAAkAAAAJAAAACgAAAAoAAAALAAAACwAAAAwAAAAMAAAADQAAAA0AQdDsAAsjAgAAAAMAAAAHAAAAAAAAABAREgAIBwkGCgULBAwDDQIOAQ8AQYTtAAtpAQAAAAIAAAADAAAABAAAAAUAAAAGAAAABwAAAAgAAAAKAAAADAAAAA4AAAAQAAAAFAAAABgAAAAcAAAAIAAAACgAAAAwAAAAOAAAAEAAAABQAAAAYAAAAHAAAACAAAAAoAAAAMAAAADgAEGE7gALegEAAAACAAAAAwAAAAQAAAAGAAAACAAAAAwAAAAQAAAAGAAAACAAAAAwAAAAQAAAAGAAAACAAAAAwAAAAAABAACAAQAAAAIAAAADAAAABAAAAAYAAAAIAAAADAAAABAAAAAYAAAAIAAAADAAAABAAAAAYAAAMS4yLjExAEGI7wALbQcAAAAEAAQACAAEAAgAAAAEAAUAEAAIAAgAAAAEAAYAIAAgAAgAAAAEAAQAEAAQAAkAAAAIABAAIAAgAAkAAAAIABAAgACAAAkAAAAIACAAgAAAAQkAAAAgAIAAAgEABAkAAAAgAAIBAgEAEAkAQYDwAAulAgMABAAFAAYABwAIAAkACgALAA0ADwARABMAFwAbAB8AIwArADMAOwBDAFMAYwBzAIMAowDDAOMAAgEAAAAAAAAQABAAEAAQABAAEAAQABAAEQARABEAEQASABIAEgASABMAEwATABMAFAAUABQAFAAVABUAFQAVABAATQDKAAAAAQACAAMABAAFAAcACQANABEAGQAhADEAQQBhAIEAwQABAYEBAQIBAwEEAQYBCAEMARABGAEgATABQAFgAAAAABAAEAAQABAAEQARABIAEgATABMAFAAUABUAFQAWABYAFwAXABgAGAAZABkAGgAaABsAGwAcABwAHQAdAEAAQAAQABEAEgAAAAgABwAJAAYACgAFAAsABAAMAAMADQACAA4AAQAPAEGw8gALwRFgBwAAAAhQAAAIEAAUCHMAEgcfAAAIcAAACDAAAAnAABAHCgAACGAAAAggAAAJoAAACAAAAAiAAAAIQAAACeAAEAcGAAAIWAAACBgAAAmQABMHOwAACHgAAAg4AAAJ0AARBxEAAAhoAAAIKAAACbAAAAgIAAAIiAAACEgAAAnwABAHBAAACFQAAAgUABUI4wATBysAAAh0AAAINAAACcgAEQcNAAAIZAAACCQAAAmoAAAIBAAACIQAAAhEAAAJ6AAQBwgAAAhcAAAIHAAACZgAFAdTAAAIfAAACDwAAAnYABIHFwAACGwAAAgsAAAJuAAACAwAAAiMAAAITAAACfgAEAcDAAAIUgAACBIAFQijABMHIwAACHIAAAgyAAAJxAARBwsAAAhiAAAIIgAACaQAAAgCAAAIggAACEIAAAnkABAHBwAACFoAAAgaAAAJlAAUB0MAAAh6AAAIOgAACdQAEgcTAAAIagAACCoAAAm0AAAICgAACIoAAAhKAAAJ9AAQBwUAAAhWAAAIFgBACAAAEwczAAAIdgAACDYAAAnMABEHDwAACGYAAAgmAAAJrAAACAYAAAiGAAAIRgAACewAEAcJAAAIXgAACB4AAAmcABQHYwAACH4AAAg+AAAJ3AASBxsAAAhuAAAILgAACbwAAAgOAAAIjgAACE4AAAn8AGAHAAAACFEAAAgRABUIgwASBx8AAAhxAAAIMQAACcIAEAcKAAAIYQAACCEAAAmiAAAIAQAACIEAAAhBAAAJ4gAQBwYAAAhZAAAIGQAACZIAEwc7AAAIeQAACDkAAAnSABEHEQAACGkAAAgpAAAJsgAACAkAAAiJAAAISQAACfIAEAcEAAAIVQAACBUAEAgCARMHKwAACHUAAAg1AAAJygARBw0AAAhlAAAIJQAACaoAAAgFAAAIhQAACEUAAAnqABAHCAAACF0AAAgdAAAJmgAUB1MAAAh9AAAIPQAACdoAEgcXAAAIbQAACC0AAAm6AAAIDQAACI0AAAhNAAAJ+gAQBwMAAAhTAAAIEwAVCMMAEwcjAAAIcwAACDMAAAnGABEHCwAACGMAAAgjAAAJpgAACAMAAAiDAAAIQwAACeYAEAcHAAAIWwAACBsAAAmWABQHQwAACHsAAAg7AAAJ1gASBxMAAAhrAAAIKwAACbYAAAgLAAAIiwAACEsAAAn2ABAHBQAACFcAAAgXAEAIAAATBzMAAAh3AAAINwAACc4AEQcPAAAIZwAACCcAAAmuAAAIBwAACIcAAAhHAAAJ7gAQBwkAAAhfAAAIHwAACZ4AFAdjAAAIfwAACD8AAAneABIHGwAACG8AAAgvAAAJvgAACA8AAAiPAAAITwAACf4AYAcAAAAIUAAACBAAFAhzABIHHwAACHAAAAgwAAAJwQAQBwoAAAhgAAAIIAAACaEAAAgAAAAIgAAACEAAAAnhABAHBgAACFgAAAgYAAAJkQATBzsAAAh4AAAIOAAACdEAEQcRAAAIaAAACCgAAAmxAAAICAAACIgAAAhIAAAJ8QAQBwQAAAhUAAAIFAAVCOMAEwcrAAAIdAAACDQAAAnJABEHDQAACGQAAAgkAAAJqQAACAQAAAiEAAAIRAAACekAEAcIAAAIXAAACBwAAAmZABQHUwAACHwAAAg8AAAJ2QASBxcAAAhsAAAILAAACbkAAAgMAAAIjAAACEwAAAn5ABAHAwAACFIAAAgSABUIowATByMAAAhyAAAIMgAACcUAEQcLAAAIYgAACCIAAAmlAAAIAgAACIIAAAhCAAAJ5QAQBwcAAAhaAAAIGgAACZUAFAdDAAAIegAACDoAAAnVABIHEwAACGoAAAgqAAAJtQAACAoAAAiKAAAISgAACfUAEAcFAAAIVgAACBYAQAgAABMHMwAACHYAAAg2AAAJzQARBw8AAAhmAAAIJgAACa0AAAgGAAAIhgAACEYAAAntABAHCQAACF4AAAgeAAAJnQAUB2MAAAh+AAAIPgAACd0AEgcbAAAIbgAACC4AAAm9AAAIDgAACI4AAAhOAAAJ/QBgBwAAAAhRAAAIEQAVCIMAEgcfAAAIcQAACDEAAAnDABAHCgAACGEAAAghAAAJowAACAEAAAiBAAAIQQAACeMAEAcGAAAIWQAACBkAAAmTABMHOwAACHkAAAg5AAAJ0wARBxEAAAhpAAAIKQAACbMAAAgJAAAIiQAACEkAAAnzABAHBAAACFUAAAgVABAIAgETBysAAAh1AAAINQAACcsAEQcNAAAIZQAACCUAAAmrAAAIBQAACIUAAAhFAAAJ6wAQBwgAAAhdAAAIHQAACZsAFAdTAAAIfQAACD0AAAnbABIHFwAACG0AAAgtAAAJuwAACA0AAAiNAAAITQAACfsAEAcDAAAIUwAACBMAFQjDABMHIwAACHMAAAgzAAAJxwARBwsAAAhjAAAIIwAACacAAAgDAAAIgwAACEMAAAnnABAHBwAACFsAAAgbAAAJlwAUB0MAAAh7AAAIOwAACdcAEgcTAAAIawAACCsAAAm3AAAICwAACIsAAAhLAAAJ9wAQBwUAAAhXAAAIFwBACAAAEwczAAAIdwAACDcAAAnPABEHDwAACGcAAAgnAAAJrwAACAcAAAiHAAAIRwAACe8AEAcJAAAIXwAACB8AAAmfABQHYwAACH8AAAg/AAAJ3wASBxsAAAhvAAAILwAACb8AAAgPAAAIjwAACE8AAAn/ABAFAQAXBQEBEwURABsFARARBQUAGQUBBBUFQQAdBQFAEAUDABgFAQIUBSEAHAUBIBIFCQAaBQEIFgWBAEAFAAAQBQIAFwWBARMFGQAbBQEYEQUHABkFAQYVBWEAHQUBYBAFBAAYBQEDFAUxABwFATASBQ0AGgUBDBYFwQBABQAAEQAKABEREQAAAAAFAAAAAAAACQAAAAALAAAAAAAAAAARAA8KERERAwoHAAEACQsLAAAJBgsAAAsABhEAAAAREREAQYGEAQshCwAAAAAAAAAAEQAKChEREQAKAAACAAkLAAAACQALAAALAEG7hAELAQwAQceEAQsVDAAAAAAMAAAAAAkMAAAAAAAMAAAMAEH1hAELAQ4AQYGFAQsVDQAAAAQNAAAAAAkOAAAAAAAOAAAOAEGvhQELARAAQbuFAQseDwAAAAAPAAAAAAkQAAAAAAAQAAAQAAASAAAAEhISAEHyhQELDhIAAAASEhIAAAAAAAAJAEGjhgELAQsAQa+GAQsVCgAAAAAKAAAAAAkLAAAAAAALAAALAEHdhgELAQwAQemGAQsnDAAAAAAMAAAAAAkMAAAAAAAMAAAMAAAwMTIzNDU2Nzg5QUJDREVGAEG0hwELARkAQduHAQsF//////8AQaCIAQtXGRJEOwI/LEcUPTMwChsGRktFNw9JDo4XA0AdPGkrNh9KLRwBICUpIQgMFRYiLhA4Pgs0MRhkdHV2L0EJfzkRI0MyQomKiwUEJignDSoeNYwHGkiTE5SVAEGAiQELig5JbGxlZ2FsIGJ5dGUgc2VxdWVuY2UARG9tYWluIGVycm9yAFJlc3VsdCBub3QgcmVwcmVzZW50YWJsZQBOb3QgYSB0dHkAUGVybWlzc2lvbiBkZW5pZWQAT3BlcmF0aW9uIG5vdCBwZXJtaXR0ZWQATm8gc3VjaCBmaWxlIG9yIGRpcmVjdG9yeQBObyBzdWNoIHByb2Nlc3MARmlsZSBleGlzdHMAVmFsdWUgdG9vIGxhcmdlIGZvciBkYXRhIHR5cGUATm8gc3BhY2UgbGVmdCBvbiBkZXZpY2UAT3V0IG9mIG1lbW9yeQBSZXNvdXJjZSBidXN5AEludGVycnVwdGVkIHN5c3RlbSBjYWxsAFJlc291cmNlIHRlbXBvcmFyaWx5IHVuYXZhaWxhYmxlAEludmFsaWQgc2VlawBDcm9zcy1kZXZpY2UgbGluawBSZWFkLW9ubHkgZmlsZSBzeXN0ZW0ARGlyZWN0b3J5IG5vdCBlbXB0eQBDb25uZWN0aW9uIHJlc2V0IGJ5IHBlZXIAT3BlcmF0aW9uIHRpbWVkIG91dABDb25uZWN0aW9uIHJlZnVzZWQASG9zdCBpcyBkb3duAEhvc3QgaXMgdW5yZWFjaGFibGUAQWRkcmVzcyBpbiB1c2UAQnJva2VuIHBpcGUASS9PIGVycm9yAE5vIHN1Y2ggZGV2aWNlIG9yIGFkZHJlc3MAQmxvY2sgZGV2aWNlIHJlcXVpcmVkAE5vIHN1Y2ggZGV2aWNlAE5vdCBhIGRpcmVjdG9yeQBJcyBhIGRpcmVjdG9yeQBUZXh0IGZpbGUgYnVzeQBFeGVjIGZvcm1hdCBlcnJvcgBJbnZhbGlkIGFyZ3VtZW50AEFyZ3VtZW50IGxpc3QgdG9vIGxvbmcAU3ltYm9saWMgbGluayBsb29wAEZpbGVuYW1lIHRvbyBsb25nAFRvbyBtYW55IG9wZW4gZmlsZXMgaW4gc3lzdGVtAE5vIGZpbGUgZGVzY3JpcHRvcnMgYXZhaWxhYmxlAEJhZCBmaWxlIGRlc2NyaXB0b3IATm8gY2hpbGQgcHJvY2VzcwBCYWQgYWRkcmVzcwBGaWxlIHRvbyBsYXJnZQBUb28gbWFueSBsaW5rcwBObyBsb2NrcyBhdmFpbGFibGUAUmVzb3VyY2UgZGVhZGxvY2sgd291bGQgb2NjdXIAU3RhdGUgbm90IHJlY292ZXJhYmxlAFByZXZpb3VzIG93bmVyIGRpZWQAT3BlcmF0aW9uIGNhbmNlbGVkAEZ1bmN0aW9uIG5vdCBpbXBsZW1lbnRlZABObyBtZXNzYWdlIG9mIGRlc2lyZWQgdHlwZQBJZGVudGlmaWVyIHJlbW92ZWQARGV2aWNlIG5vdCBhIHN0cmVhbQBObyBkYXRhIGF2YWlsYWJsZQBEZXZpY2UgdGltZW91dABPdXQgb2Ygc3RyZWFtcyByZXNvdXJjZXMATGluayBoYXMgYmVlbiBzZXZlcmVkAFByb3RvY29sIGVycm9yAEJhZCBtZXNzYWdlAEZpbGUgZGVzY3JpcHRvciBpbiBiYWQgc3RhdGUATm90IGEgc29ja2V0AERlc3RpbmF0aW9uIGFkZHJlc3MgcmVxdWlyZWQATWVzc2FnZSB0b28gbGFyZ2UAUHJvdG9jb2wgd3JvbmcgdHlwZSBmb3Igc29ja2V0AFByb3RvY29sIG5vdCBhdmFpbGFibGUAUHJvdG9jb2wgbm90IHN1cHBvcnRlZABTb2NrZXQgdHlwZSBub3Qgc3VwcG9ydGVkAE5vdCBzdXBwb3J0ZWQAUHJvdG9jb2wgZmFtaWx5IG5vdCBzdXBwb3J0ZWQAQWRkcmVzcyBmYW1pbHkgbm90IHN1cHBvcnRlZCBieSBwcm90b2NvbABBZGRyZXNzIG5vdCBhdmFpbGFibGUATmV0d29yayBpcyBkb3duAE5ldHdvcmsgdW5yZWFjaGFibGUAQ29ubmVjdGlvbiByZXNldCBieSBuZXR3b3JrAENvbm5lY3Rpb24gYWJvcnRlZABObyBidWZmZXIgc3BhY2UgYXZhaWxhYmxlAFNvY2tldCBpcyBjb25uZWN0ZWQAU29ja2V0IG5vdCBjb25uZWN0ZWQAQ2Fubm90IHNlbmQgYWZ0ZXIgc29ja2V0IHNodXRkb3duAE9wZXJhdGlvbiBhbHJlYWR5IGluIHByb2dyZXNzAE9wZXJhdGlvbiBpbiBwcm9ncmVzcwBTdGFsZSBmaWxlIGhhbmRsZQBSZW1vdGUgSS9PIGVycm9yAFF1b3RhIGV4Y2VlZGVkAE5vIG1lZGl1bSBmb3VuZABXcm9uZyBtZWRpdW0gdHlwZQBObyBlcnJvciBpbmZvcm1hdGlvbgBBkJcBC1JQUFAACgAAAAsAAAAMAAAADQAAAA4AAAAPAAAAEAAAABEAAAASAAAACwAAAAwAAAANAAAADgAAAA8AAAAQAAAAEQAAAAEAAAAIAAAAlEsAALRLAEGQmQELAgxQAEHImQELCR8AAADkTAAAAwBB5JkBC4wBLfRRWM+MscBG9rXLKTEDxwRbcDC0Xf0geH+LmthZKVBoSImrp1YDbP+3zYg/1He0K6WjcPG65Kj8QYP92W/hinovLXSWBx8NCV4Ddixw90ClLKdvV0GoqnTfoFhkA0rHxDxTrq9fGAQVseNtKIarDKS/Q/DpUIE5VxZSN/////////////////////8="; - if (!isDataURI(wasmBinaryFile)) { - wasmBinaryFile = locateFile(wasmBinaryFile); - } - function getBinary(file) { - try { - if (file == wasmBinaryFile && wasmBinary) { - return new Uint8Array(wasmBinary); - } - var binary = tryParseAsDataURI(file); - if (binary) { - return binary; - } - if (readBinary) { - return readBinary(file); - } else { - 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 (err2) { - abort(err2); - } - } - function instantiateSync(file, info) { - var instance; - var module2; - var binary; - try { - binary = getBinary(file); - module2 = new WebAssembly.Module(binary); - instance = new WebAssembly.Instance(module2, info); - } catch (e) { - var str = e.toString(); - err("failed to compile wasm module: " + str); - if (str.includes("imported Memory") || str.includes("memory import")) { - err("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)."); - } - throw e; - } - return [instance, module2]; - } - function createWasm() { - var info = {a: asmLibraryArg}; - function receiveInstance(instance, module2) { - var exports3 = instance.exports; - Module["asm"] = exports3; - wasmMemory = Module["asm"]["u"]; - updateGlobalBufferAndViews(wasmMemory.buffer); - wasmTable = Module["asm"]["pa"]; - addOnInit(Module["asm"]["v"]); - removeRunDependency(); - } - addRunDependency(); - if (Module["instantiateWasm"]) { - try { - var exports2 = Module["instantiateWasm"](info, receiveInstance); - return exports2; - } catch (e) { - err("Module.instantiateWasm callback failed with error: " + e); - return false; - } - } - var result = instantiateSync(wasmBinaryFile, info); - receiveInstance(result[0]); - return Module["asm"]; - } - var tempDouble; - var tempI64; - function callRuntimeCallbacks(callbacks) { - while (callbacks.length > 0) { - var callback = callbacks.shift(); - if (typeof callback == "function") { - callback(Module); - continue; - } - var func = callback.func; - if (typeof func === "number") { - if (callback.arg === void 0) { - wasmTable.get(func)(); - } else { - wasmTable.get(func)(callback.arg); - } - } else { - func(callback.arg === void 0 ? null : callback.arg); - } - } - } - function _gmtime_r(time, tmPtr) { - var date = new Date(HEAP32[time >> 2] * 1e3); - HEAP32[tmPtr >> 2] = date.getUTCSeconds(); - HEAP32[tmPtr + 4 >> 2] = date.getUTCMinutes(); - HEAP32[tmPtr + 8 >> 2] = date.getUTCHours(); - HEAP32[tmPtr + 12 >> 2] = date.getUTCDate(); - HEAP32[tmPtr + 16 >> 2] = date.getUTCMonth(); - HEAP32[tmPtr + 20 >> 2] = date.getUTCFullYear() - 1900; - HEAP32[tmPtr + 24 >> 2] = date.getUTCDay(); - HEAP32[tmPtr + 36 >> 2] = 0; - HEAP32[tmPtr + 32 >> 2] = 0; - var start = Date.UTC(date.getUTCFullYear(), 0, 1, 0, 0, 0, 0); - var yday = (date.getTime() - start) / (1e3 * 60 * 60 * 24) | 0; - HEAP32[tmPtr + 28 >> 2] = yday; - if (!_gmtime_r.GMTString) - _gmtime_r.GMTString = allocateUTF8("GMT"); - HEAP32[tmPtr + 40 >> 2] = _gmtime_r.GMTString; - return tmPtr; - } - function ___gmtime_r(a0, a1) { - return _gmtime_r(a0, a1); - } - var PATH = { - splitPath: function(filename) { - var splitPathRe = /^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/; - return splitPathRe.exec(filename).slice(1); - }, - normalizeArray: function(parts, allowAboveRoot) { - var up = 0; - for (var i = parts.length - 1; i >= 0; i--) { - var last = parts[i]; - if (last === ".") { - parts.splice(i, 1); - } else if (last === "..") { - parts.splice(i, 1); - up++; - } else if (up) { - parts.splice(i, 1); - up--; - } - } - if (allowAboveRoot) { - for (; up; up--) { - parts.unshift(".."); - } - } - return parts; - }, - normalize: function(path) { - var isAbsolute = path.charAt(0) === "/", trailingSlash = path.substr(-1) === "/"; - path = PATH.normalizeArray(path.split("/").filter(function(p) { - return !!p; - }), !isAbsolute).join("/"); - if (!path && !isAbsolute) { - path = "."; - } - if (path && trailingSlash) { - path += "/"; - } - return (isAbsolute ? "/" : "") + path; - }, - dirname: function(path) { - var result = PATH.splitPath(path), root = result[0], dir = result[1]; - if (!root && !dir) { - return "."; - } - if (dir) { - dir = dir.substr(0, dir.length - 1); - } - return root + dir; - }, - basename: function(path) { - if (path === "/") - return "/"; - path = PATH.normalize(path); - path = path.replace(/\/$/, ""); - var lastSlash = path.lastIndexOf("/"); - if (lastSlash === -1) - return path; - return path.substr(lastSlash + 1); - }, - extname: function(path) { - return PATH.splitPath(path)[3]; - }, - join: function() { - var paths = Array.prototype.slice.call(arguments, 0); - return PATH.normalize(paths.join("/")); - }, - join2: function(l, r) { - return PATH.normalize(l + "/" + r); - } - }; - function getRandomDevice() { - { - try { - var crypto_module = require("crypto"); - return function() { - return crypto_module["randomBytes"](1)[0]; - }; - } catch (e) { - } - } - return function() { - abort("randomDevice"); - }; - } - var PATH_FS = { - resolve: function() { - var resolvedPath = "", resolvedAbsolute = false; - for (var i = arguments.length - 1; i >= -1 && !resolvedAbsolute; i--) { - var path = i >= 0 ? arguments[i] : FS.cwd(); - if (typeof path !== "string") { - throw new TypeError("Arguments to path.resolve must be strings"); - } else if (!path) { - return ""; - } - resolvedPath = path + "/" + resolvedPath; - resolvedAbsolute = path.charAt(0) === "/"; - } - resolvedPath = PATH.normalizeArray(resolvedPath.split("/").filter(function(p) { - return !!p; - }), !resolvedAbsolute).join("/"); - return (resolvedAbsolute ? "/" : "") + resolvedPath || "."; - }, - relative: function(from, to) { - from = PATH_FS.resolve(from).substr(1); - to = PATH_FS.resolve(to).substr(1); - function trim(arr) { - var start = 0; - for (; start < arr.length; start++) { - if (arr[start] !== "") - break; - } - var end = arr.length - 1; - for (; end >= 0; end--) { - if (arr[end] !== "") - break; - } - if (start > end) - return []; - return arr.slice(start, end - start + 1); - } - var fromParts = trim(from.split("/")); - var toParts = trim(to.split("/")); - var length = Math.min(fromParts.length, toParts.length); - var samePartsLength = length; - for (var i = 0; i < length; i++) { - if (fromParts[i] !== toParts[i]) { - samePartsLength = i; - break; - } - } - var outputParts = []; - for (var i = samePartsLength; i < fromParts.length; i++) { - outputParts.push(".."); - } - outputParts = outputParts.concat(toParts.slice(samePartsLength)); - return outputParts.join("/"); - } - }; - var TTY = { - ttys: [], - init: function() { - }, - shutdown: function() { - }, - register: function(dev, ops) { - TTY.ttys[dev] = {input: [], output: [], ops}; - FS.registerDevice(dev, TTY.stream_ops); - }, - stream_ops: { - open: function(stream) { - var tty = TTY.ttys[stream.node.rdev]; - if (!tty) { - throw new FS.ErrnoError(43); - } - stream.tty = tty; - stream.seekable = false; - }, - close: function(stream) { - stream.tty.ops.flush(stream.tty); - }, - flush: function(stream) { - stream.tty.ops.flush(stream.tty); - }, - read: function(stream, buffer2, offset, length, pos) { - if (!stream.tty || !stream.tty.ops.get_char) { - throw new FS.ErrnoError(60); - } - var bytesRead = 0; - for (var i = 0; i < length; i++) { - var result; - try { - result = stream.tty.ops.get_char(stream.tty); - } catch (e) { - throw new FS.ErrnoError(29); - } - if (result === void 0 && bytesRead === 0) { - throw new FS.ErrnoError(6); - } - if (result === null || result === void 0) - break; - bytesRead++; - buffer2[offset + i] = result; - } - if (bytesRead) { - stream.node.timestamp = Date.now(); - } - return bytesRead; - }, - write: function(stream, buffer2, offset, length, pos) { - if (!stream.tty || !stream.tty.ops.put_char) { - throw new FS.ErrnoError(60); - } - try { - for (var i = 0; i < length; i++) { - stream.tty.ops.put_char(stream.tty, buffer2[offset + i]); - } - } catch (e) { - throw new FS.ErrnoError(29); - } - if (length) { - stream.node.timestamp = Date.now(); - } - return i; - } - }, - default_tty_ops: { - get_char: function(tty) { - if (!tty.input.length) { - var result = null; - { - var BUFSIZE = 256; - var buf = Buffer.alloc ? Buffer.alloc(BUFSIZE) : new Buffer(BUFSIZE); - var bytesRead = 0; - try { - bytesRead = nodeFS.readSync(process.stdin.fd, buf, 0, BUFSIZE, null); - } catch (e) { - if (e.toString().includes("EOF")) - bytesRead = 0; - else - throw e; - } - if (bytesRead > 0) { - result = buf.slice(0, bytesRead).toString("utf-8"); - } else { - result = null; - } - } - if (!result) { - return null; - } - tty.input = intArrayFromString(result, true); - } - return tty.input.shift(); - }, - put_char: function(tty, val) { - if (val === null || val === 10) { - out(UTF8ArrayToString(tty.output, 0)); - tty.output = []; - } else { - if (val != 0) - tty.output.push(val); - } - }, - flush: function(tty) { - if (tty.output && tty.output.length > 0) { - out(UTF8ArrayToString(tty.output, 0)); - tty.output = []; - } - } - }, - default_tty1_ops: { - put_char: function(tty, val) { - if (val === null || val === 10) { - err(UTF8ArrayToString(tty.output, 0)); - tty.output = []; - } else { - if (val != 0) - tty.output.push(val); - } - }, - flush: function(tty) { - if (tty.output && tty.output.length > 0) { - err(UTF8ArrayToString(tty.output, 0)); - tty.output = []; - } - } - } - }; - function mmapAlloc(size) { - var alignedSize = alignMemory(size, 65536); - var ptr = _malloc(alignedSize); - while (size < alignedSize) - HEAP8[ptr + size++] = 0; - return ptr; - } - var MEMFS = { - ops_table: null, - mount: function(mount) { - return MEMFS.createNode(null, "/", 16384 | 511, 0); - }, - createNode: function(parent, name, mode, dev) { - if (FS.isBlkdev(mode) || FS.isFIFO(mode)) { - throw new FS.ErrnoError(63); - } - if (!MEMFS.ops_table) { - MEMFS.ops_table = { - dir: { - node: { - getattr: MEMFS.node_ops.getattr, - setattr: MEMFS.node_ops.setattr, - lookup: MEMFS.node_ops.lookup, - mknod: MEMFS.node_ops.mknod, - rename: MEMFS.node_ops.rename, - unlink: MEMFS.node_ops.unlink, - rmdir: MEMFS.node_ops.rmdir, - readdir: MEMFS.node_ops.readdir, - symlink: MEMFS.node_ops.symlink - }, - stream: {llseek: MEMFS.stream_ops.llseek} - }, - file: { - node: { - getattr: MEMFS.node_ops.getattr, - setattr: MEMFS.node_ops.setattr - }, - stream: { - llseek: MEMFS.stream_ops.llseek, - read: MEMFS.stream_ops.read, - write: MEMFS.stream_ops.write, - allocate: MEMFS.stream_ops.allocate, - mmap: MEMFS.stream_ops.mmap, - msync: MEMFS.stream_ops.msync - } - }, - link: { - node: { - getattr: MEMFS.node_ops.getattr, - setattr: MEMFS.node_ops.setattr, - readlink: MEMFS.node_ops.readlink - }, - stream: {} - }, - chrdev: { - node: { - getattr: MEMFS.node_ops.getattr, - setattr: MEMFS.node_ops.setattr - }, - stream: FS.chrdev_stream_ops - } - }; - } - var node = FS.createNode(parent, name, mode, dev); - if (FS.isDir(node.mode)) { - node.node_ops = MEMFS.ops_table.dir.node; - node.stream_ops = MEMFS.ops_table.dir.stream; - node.contents = {}; - } else if (FS.isFile(node.mode)) { - node.node_ops = MEMFS.ops_table.file.node; - node.stream_ops = MEMFS.ops_table.file.stream; - node.usedBytes = 0; - node.contents = null; - } else if (FS.isLink(node.mode)) { - node.node_ops = MEMFS.ops_table.link.node; - node.stream_ops = MEMFS.ops_table.link.stream; - } else if (FS.isChrdev(node.mode)) { - node.node_ops = MEMFS.ops_table.chrdev.node; - node.stream_ops = MEMFS.ops_table.chrdev.stream; - } - node.timestamp = Date.now(); - if (parent) { - parent.contents[name] = node; - parent.timestamp = node.timestamp; - } - return node; - }, - getFileDataAsTypedArray: function(node) { - if (!node.contents) - return new Uint8Array(0); - if (node.contents.subarray) - return node.contents.subarray(0, node.usedBytes); - return new Uint8Array(node.contents); - }, - expandFileStorage: function(node, newCapacity) { - var prevCapacity = node.contents ? node.contents.length : 0; - if (prevCapacity >= newCapacity) - return; - var CAPACITY_DOUBLING_MAX = 1024 * 1024; - newCapacity = Math.max(newCapacity, prevCapacity * (prevCapacity < CAPACITY_DOUBLING_MAX ? 2 : 1.125) >>> 0); - if (prevCapacity != 0) - newCapacity = Math.max(newCapacity, 256); - var oldContents = node.contents; - node.contents = new Uint8Array(newCapacity); - if (node.usedBytes > 0) - node.contents.set(oldContents.subarray(0, node.usedBytes), 0); - }, - resizeFileStorage: function(node, newSize) { - if (node.usedBytes == newSize) - return; - if (newSize == 0) { - node.contents = null; - node.usedBytes = 0; - } else { - var oldContents = node.contents; - node.contents = new Uint8Array(newSize); - if (oldContents) { - node.contents.set(oldContents.subarray(0, Math.min(newSize, node.usedBytes))); - } - node.usedBytes = newSize; - } - }, - node_ops: { - getattr: function(node) { - var attr = {}; - attr.dev = FS.isChrdev(node.mode) ? node.id : 1; - attr.ino = node.id; - attr.mode = node.mode; - attr.nlink = 1; - attr.uid = 0; - attr.gid = 0; - attr.rdev = node.rdev; - if (FS.isDir(node.mode)) { - attr.size = 4096; - } else if (FS.isFile(node.mode)) { - attr.size = node.usedBytes; - } else if (FS.isLink(node.mode)) { - attr.size = node.link.length; - } else { - attr.size = 0; - } - attr.atime = new Date(node.timestamp); - attr.mtime = new Date(node.timestamp); - attr.ctime = new Date(node.timestamp); - attr.blksize = 4096; - attr.blocks = Math.ceil(attr.size / attr.blksize); - return attr; - }, - setattr: function(node, attr) { - if (attr.mode !== void 0) { - node.mode = attr.mode; - } - if (attr.timestamp !== void 0) { - node.timestamp = attr.timestamp; - } - if (attr.size !== void 0) { - MEMFS.resizeFileStorage(node, attr.size); - } - }, - lookup: function(parent, name) { - throw FS.genericErrors[44]; - }, - mknod: function(parent, name, mode, dev) { - return MEMFS.createNode(parent, name, mode, dev); - }, - rename: function(old_node, new_dir, new_name) { - if (FS.isDir(old_node.mode)) { - var new_node; - try { - new_node = FS.lookupNode(new_dir, new_name); - } catch (e) { - } - if (new_node) { - for (var i in new_node.contents) { - throw new FS.ErrnoError(55); - } - } - } - delete old_node.parent.contents[old_node.name]; - old_node.parent.timestamp = Date.now(); - old_node.name = new_name; - new_dir.contents[new_name] = old_node; - new_dir.timestamp = old_node.parent.timestamp; - old_node.parent = new_dir; - }, - unlink: function(parent, name) { - delete parent.contents[name]; - parent.timestamp = Date.now(); - }, - rmdir: function(parent, name) { - var node = FS.lookupNode(parent, name); - for (var i in node.contents) { - throw new FS.ErrnoError(55); - } - delete parent.contents[name]; - parent.timestamp = Date.now(); - }, - readdir: function(node) { - var entries = [".", ".."]; - for (var key2 in node.contents) { - if (!node.contents.hasOwnProperty(key2)) { - continue; - } - entries.push(key2); - } - return entries; - }, - symlink: function(parent, newname, oldpath) { - var node = MEMFS.createNode(parent, newname, 511 | 40960, 0); - node.link = oldpath; - return node; - }, - readlink: function(node) { - if (!FS.isLink(node.mode)) { - throw new FS.ErrnoError(28); - } - return node.link; - } - }, - stream_ops: { - read: function(stream, buffer2, offset, length, position) { - var contents = stream.node.contents; - if (position >= stream.node.usedBytes) - return 0; - var size = Math.min(stream.node.usedBytes - position, length); - if (size > 8 && contents.subarray) { - buffer2.set(contents.subarray(position, position + size), offset); - } else { - for (var i = 0; i < size; i++) - buffer2[offset + i] = contents[position + i]; - } - return size; - }, - write: function(stream, buffer2, offset, length, position, canOwn) { - if (buffer2.buffer === HEAP8.buffer) { - canOwn = false; - } - if (!length) - return 0; - var node = stream.node; - node.timestamp = Date.now(); - if (buffer2.subarray && (!node.contents || node.contents.subarray)) { - if (canOwn) { - node.contents = buffer2.subarray(offset, offset + length); - node.usedBytes = length; - return length; - } else if (node.usedBytes === 0 && position === 0) { - node.contents = buffer2.slice(offset, offset + length); - node.usedBytes = length; - return length; - } else if (position + length <= node.usedBytes) { - node.contents.set(buffer2.subarray(offset, offset + length), position); - return length; - } - } - MEMFS.expandFileStorage(node, position + length); - if (node.contents.subarray && buffer2.subarray) { - node.contents.set(buffer2.subarray(offset, offset + length), position); - } else { - for (var i = 0; i < length; i++) { - node.contents[position + i] = buffer2[offset + i]; - } - } - node.usedBytes = Math.max(node.usedBytes, position + length); - return length; - }, - llseek: function(stream, offset, whence) { - var position = offset; - if (whence === 1) { - position += stream.position; - } else if (whence === 2) { - if (FS.isFile(stream.node.mode)) { - position += stream.node.usedBytes; - } - } - if (position < 0) { - throw new FS.ErrnoError(28); - } - return position; - }, - allocate: function(stream, offset, length) { - MEMFS.expandFileStorage(stream.node, offset + length); - stream.node.usedBytes = Math.max(stream.node.usedBytes, offset + length); - }, - mmap: function(stream, address, length, position, prot, flags) { - if (address !== 0) { - throw new FS.ErrnoError(28); - } - if (!FS.isFile(stream.node.mode)) { - throw new FS.ErrnoError(43); - } - var ptr; - var allocated; - var contents = stream.node.contents; - if (!(flags & 2) && contents.buffer === buffer) { - allocated = false; - ptr = contents.byteOffset; - } else { - if (position > 0 || position + length < contents.length) { - if (contents.subarray) { - contents = contents.subarray(position, position + length); - } else { - contents = Array.prototype.slice.call(contents, position, position + length); - } - } - allocated = true; - ptr = mmapAlloc(length); - if (!ptr) { - throw new FS.ErrnoError(48); - } - HEAP8.set(contents, ptr); - } - return {ptr, allocated}; - }, - msync: function(stream, buffer2, offset, length, mmapFlags) { - if (!FS.isFile(stream.node.mode)) { - throw new FS.ErrnoError(43); - } - if (mmapFlags & 2) { - return 0; - } - MEMFS.stream_ops.write(stream, buffer2, 0, length, offset, false); - return 0; - } - } - }; - var ERRNO_CODES = { - EPERM: 63, - ENOENT: 44, - ESRCH: 71, - EINTR: 27, - EIO: 29, - ENXIO: 60, - E2BIG: 1, - ENOEXEC: 45, - EBADF: 8, - ECHILD: 12, - EAGAIN: 6, - EWOULDBLOCK: 6, - ENOMEM: 48, - EACCES: 2, - EFAULT: 21, - ENOTBLK: 105, - EBUSY: 10, - EEXIST: 20, - EXDEV: 75, - ENODEV: 43, - ENOTDIR: 54, - EISDIR: 31, - EINVAL: 28, - ENFILE: 41, - EMFILE: 33, - ENOTTY: 59, - ETXTBSY: 74, - EFBIG: 22, - ENOSPC: 51, - ESPIPE: 70, - EROFS: 69, - EMLINK: 34, - EPIPE: 64, - EDOM: 18, - ERANGE: 68, - ENOMSG: 49, - EIDRM: 24, - ECHRNG: 106, - EL2NSYNC: 156, - EL3HLT: 107, - EL3RST: 108, - ELNRNG: 109, - EUNATCH: 110, - ENOCSI: 111, - EL2HLT: 112, - EDEADLK: 16, - ENOLCK: 46, - EBADE: 113, - EBADR: 114, - EXFULL: 115, - ENOANO: 104, - EBADRQC: 103, - EBADSLT: 102, - EDEADLOCK: 16, - EBFONT: 101, - ENOSTR: 100, - ENODATA: 116, - ETIME: 117, - ENOSR: 118, - ENONET: 119, - ENOPKG: 120, - EREMOTE: 121, - ENOLINK: 47, - EADV: 122, - ESRMNT: 123, - ECOMM: 124, - EPROTO: 65, - EMULTIHOP: 36, - EDOTDOT: 125, - EBADMSG: 9, - ENOTUNIQ: 126, - EBADFD: 127, - EREMCHG: 128, - ELIBACC: 129, - ELIBBAD: 130, - ELIBSCN: 131, - ELIBMAX: 132, - ELIBEXEC: 133, - ENOSYS: 52, - ENOTEMPTY: 55, - ENAMETOOLONG: 37, - ELOOP: 32, - EOPNOTSUPP: 138, - EPFNOSUPPORT: 139, - ECONNRESET: 15, - ENOBUFS: 42, - EAFNOSUPPORT: 5, - EPROTOTYPE: 67, - ENOTSOCK: 57, - ENOPROTOOPT: 50, - ESHUTDOWN: 140, - ECONNREFUSED: 14, - EADDRINUSE: 3, - ECONNABORTED: 13, - ENETUNREACH: 40, - ENETDOWN: 38, - ETIMEDOUT: 73, - EHOSTDOWN: 142, - EHOSTUNREACH: 23, - EINPROGRESS: 26, - EALREADY: 7, - EDESTADDRREQ: 17, - EMSGSIZE: 35, - EPROTONOSUPPORT: 66, - ESOCKTNOSUPPORT: 137, - EADDRNOTAVAIL: 4, - ENETRESET: 39, - EISCONN: 30, - ENOTCONN: 53, - ETOOMANYREFS: 141, - EUSERS: 136, - EDQUOT: 19, - ESTALE: 72, - ENOTSUP: 138, - ENOMEDIUM: 148, - EILSEQ: 25, - EOVERFLOW: 61, - ECANCELED: 11, - ENOTRECOVERABLE: 56, - EOWNERDEAD: 62, - ESTRPIPE: 135 - }; - var NODEFS = { - isWindows: false, - staticInit: function() { - NODEFS.isWindows = !!process.platform.match(/^win/); - var flags = {fs: fs.constants}; - if (flags["fs"]) { - flags = flags["fs"]; - } - NODEFS.flagsForNodeMap = { - 1024: flags["O_APPEND"], - 64: flags["O_CREAT"], - 128: flags["O_EXCL"], - 256: flags["O_NOCTTY"], - 0: flags["O_RDONLY"], - 2: flags["O_RDWR"], - 4096: flags["O_SYNC"], - 512: flags["O_TRUNC"], - 1: flags["O_WRONLY"] - }; - }, - bufferFrom: function(arrayBuffer) { - return Buffer["alloc"] ? Buffer.from(arrayBuffer) : new Buffer(arrayBuffer); - }, - convertNodeCode: function(e) { - var code = e.code; - return ERRNO_CODES[code]; - }, - mount: function(mount) { - return NODEFS.createNode(null, "/", NODEFS.getMode(mount.opts.root), 0); - }, - createNode: function(parent, name, mode, dev) { - if (!FS.isDir(mode) && !FS.isFile(mode) && !FS.isLink(mode)) { - throw new FS.ErrnoError(28); - } - var node = FS.createNode(parent, name, mode); - node.node_ops = NODEFS.node_ops; - node.stream_ops = NODEFS.stream_ops; - return node; - }, - getMode: function(path) { - var stat; - try { - stat = fs.lstatSync(path); - if (NODEFS.isWindows) { - stat.mode = stat.mode | (stat.mode & 292) >> 2; - } - } catch (e) { - if (!e.code) - throw e; - throw new FS.ErrnoError(NODEFS.convertNodeCode(e)); - } - return stat.mode; - }, - realPath: function(node) { - var parts = []; - while (node.parent !== node) { - parts.push(node.name); - node = node.parent; - } - parts.push(node.mount.opts.root); - parts.reverse(); - return PATH.join.apply(null, parts); - }, - flagsForNode: function(flags) { - flags &= ~2097152; - flags &= ~2048; - flags &= ~32768; - flags &= ~524288; - var newFlags = 0; - for (var k in NODEFS.flagsForNodeMap) { - if (flags & k) { - newFlags |= NODEFS.flagsForNodeMap[k]; - flags ^= k; - } - } - if (!flags) { - return newFlags; - } else { - throw new FS.ErrnoError(28); - } - }, - node_ops: { - getattr: function(node) { - var path = NODEFS.realPath(node); - var stat; - try { - stat = fs.lstatSync(path); - } catch (e) { - if (!e.code) - throw e; - throw new FS.ErrnoError(NODEFS.convertNodeCode(e)); - } - if (NODEFS.isWindows && !stat.blksize) { - stat.blksize = 4096; - } - if (NODEFS.isWindows && !stat.blocks) { - stat.blocks = (stat.size + stat.blksize - 1) / stat.blksize | 0; - } - return { - dev: stat.dev, - ino: stat.ino, - mode: stat.mode, - nlink: stat.nlink, - uid: stat.uid, - gid: stat.gid, - rdev: stat.rdev, - size: stat.size, - atime: stat.atime, - mtime: stat.mtime, - ctime: stat.ctime, - blksize: stat.blksize, - blocks: stat.blocks - }; - }, - setattr: function(node, attr) { - var path = NODEFS.realPath(node); - try { - if (attr.mode !== void 0) { - fs.chmodSync(path, attr.mode); - node.mode = attr.mode; - } - if (attr.timestamp !== void 0) { - var date = new Date(attr.timestamp); - fs.utimesSync(path, date, date); - } - if (attr.size !== void 0) { - fs.truncateSync(path, attr.size); - } - } catch (e) { - if (!e.code) - throw e; - throw new FS.ErrnoError(NODEFS.convertNodeCode(e)); - } - }, - lookup: function(parent, name) { - var path = PATH.join2(NODEFS.realPath(parent), name); - var mode = NODEFS.getMode(path); - return NODEFS.createNode(parent, name, mode); - }, - mknod: function(parent, name, mode, dev) { - var node = NODEFS.createNode(parent, name, mode, dev); - var path = NODEFS.realPath(node); - try { - if (FS.isDir(node.mode)) { - fs.mkdirSync(path, node.mode); - } else { - fs.writeFileSync(path, "", {mode: node.mode}); - } - } catch (e) { - if (!e.code) - throw e; - throw new FS.ErrnoError(NODEFS.convertNodeCode(e)); - } - return node; - }, - rename: function(oldNode, newDir, newName) { - var oldPath = NODEFS.realPath(oldNode); - var newPath = PATH.join2(NODEFS.realPath(newDir), newName); - try { - fs.renameSync(oldPath, newPath); - } catch (e) { - if (!e.code) - throw e; - throw new FS.ErrnoError(NODEFS.convertNodeCode(e)); - } - oldNode.name = newName; - }, - unlink: function(parent, name) { - var path = PATH.join2(NODEFS.realPath(parent), name); - try { - fs.unlinkSync(path); - } catch (e) { - if (!e.code) - throw e; - throw new FS.ErrnoError(NODEFS.convertNodeCode(e)); - } - }, - rmdir: function(parent, name) { - var path = PATH.join2(NODEFS.realPath(parent), name); - try { - fs.rmdirSync(path); - } catch (e) { - if (!e.code) - throw e; - throw new FS.ErrnoError(NODEFS.convertNodeCode(e)); - } - }, - readdir: function(node) { - var path = NODEFS.realPath(node); - try { - return fs.readdirSync(path); - } catch (e) { - if (!e.code) - throw e; - throw new FS.ErrnoError(NODEFS.convertNodeCode(e)); - } - }, - symlink: function(parent, newName, oldPath) { - var newPath = PATH.join2(NODEFS.realPath(parent), newName); - try { - fs.symlinkSync(oldPath, newPath); - } catch (e) { - if (!e.code) - throw e; - throw new FS.ErrnoError(NODEFS.convertNodeCode(e)); - } - }, - readlink: function(node) { - var path = NODEFS.realPath(node); - try { - path = fs.readlinkSync(path); - path = NODEJS_PATH.relative(NODEJS_PATH.resolve(node.mount.opts.root), path); - return path; - } catch (e) { - if (!e.code) - throw e; - throw new FS.ErrnoError(NODEFS.convertNodeCode(e)); - } - } - }, - stream_ops: { - open: function(stream) { - var path = NODEFS.realPath(stream.node); - try { - if (FS.isFile(stream.node.mode)) { - stream.nfd = fs.openSync(path, NODEFS.flagsForNode(stream.flags)); - } - } catch (e) { - if (!e.code) - throw e; - throw new FS.ErrnoError(NODEFS.convertNodeCode(e)); - } - }, - close: function(stream) { - try { - if (FS.isFile(stream.node.mode) && stream.nfd) { - fs.closeSync(stream.nfd); - } - } catch (e) { - if (!e.code) - throw e; - throw new FS.ErrnoError(NODEFS.convertNodeCode(e)); - } - }, - read: function(stream, buffer2, offset, length, position) { - if (length === 0) - return 0; - try { - return fs.readSync(stream.nfd, NODEFS.bufferFrom(buffer2.buffer), offset, length, position); - } catch (e) { - throw new FS.ErrnoError(NODEFS.convertNodeCode(e)); - } - }, - write: function(stream, buffer2, offset, length, position) { - try { - return fs.writeSync(stream.nfd, NODEFS.bufferFrom(buffer2.buffer), offset, length, position); - } catch (e) { - throw new FS.ErrnoError(NODEFS.convertNodeCode(e)); - } - }, - llseek: function(stream, offset, whence) { - var position = offset; - if (whence === 1) { - position += stream.position; - } else if (whence === 2) { - if (FS.isFile(stream.node.mode)) { - try { - var stat = fs.fstatSync(stream.nfd); - position += stat.size; - } catch (e) { - throw new FS.ErrnoError(NODEFS.convertNodeCode(e)); - } - } - } - if (position < 0) { - throw new FS.ErrnoError(28); - } - return position; - }, - mmap: function(stream, address, length, position, prot, flags) { - if (address !== 0) { - throw new FS.ErrnoError(28); - } - if (!FS.isFile(stream.node.mode)) { - throw new FS.ErrnoError(43); - } - var ptr = mmapAlloc(length); - NODEFS.stream_ops.read(stream, HEAP8, ptr, length, position); - return {ptr, allocated: true}; - }, - msync: function(stream, buffer2, offset, length, mmapFlags) { - if (!FS.isFile(stream.node.mode)) { - throw new FS.ErrnoError(43); - } - if (mmapFlags & 2) { - return 0; - } - NODEFS.stream_ops.write(stream, buffer2, 0, length, offset, false); - return 0; - } - } - }; - var NODERAWFS = { - lookupPath: function(path) { - return {path, node: {mode: NODEFS.getMode(path)}}; - }, - createStandardStreams: function() { - FS.streams[0] = { - fd: 0, - nfd: 0, - position: 0, - path: "", - flags: 0, - tty: true, - seekable: false - }; - for (var i = 1; i < 3; i++) { - FS.streams[i] = { - fd: i, - nfd: i, - position: 0, - path: "", - flags: 577, - tty: true, - seekable: false - }; - } - }, - cwd: function() { - return process.cwd(); - }, - chdir: function() { - process.chdir.apply(void 0, arguments); - }, - mknod: function(path, mode) { - if (FS.isDir(path)) { - fs.mkdirSync(path, mode); - } else { - fs.writeFileSync(path, "", {mode}); - } - }, - mkdir: function() { - fs.mkdirSync.apply(void 0, arguments); - }, - symlink: function() { - fs.symlinkSync.apply(void 0, arguments); - }, - rename: function() { - fs.renameSync.apply(void 0, arguments); - }, - rmdir: function() { - fs.rmdirSync.apply(void 0, arguments); - }, - readdir: function() { - fs.readdirSync.apply(void 0, arguments); - }, - unlink: function() { - fs.unlinkSync.apply(void 0, arguments); - }, - readlink: function() { - return fs.readlinkSync.apply(void 0, arguments); - }, - stat: function() { - return fs.statSync.apply(void 0, arguments); - }, - lstat: function() { - return fs.lstatSync.apply(void 0, arguments); - }, - chmod: function() { - fs.chmodSync.apply(void 0, arguments); - }, - fchmod: function() { - fs.fchmodSync.apply(void 0, arguments); - }, - chown: function() { - fs.chownSync.apply(void 0, arguments); - }, - fchown: function() { - fs.fchownSync.apply(void 0, arguments); - }, - truncate: function() { - fs.truncateSync.apply(void 0, arguments); - }, - ftruncate: function(fd, len) { - if (len < 0) { - throw new FS.ErrnoError(28); - } - fs.ftruncateSync.apply(void 0, arguments); - }, - utime: function() { - fs.utimesSync.apply(void 0, arguments); - }, - open: function(path, flags, mode, suggestFD) { - if (typeof flags === "string") { - flags = VFS.modeStringToFlags(flags); - } - var nfd = fs.openSync(path, NODEFS.flagsForNode(flags), mode); - var fd = suggestFD != null ? suggestFD : FS.nextfd(nfd); - var stream = { - fd, - nfd, - position: 0, - path, - flags, - seekable: true - }; - FS.streams[fd] = stream; - return stream; - }, - close: function(stream) { - if (!stream.stream_ops) { - fs.closeSync(stream.nfd); - } - FS.closeStream(stream.fd); - }, - llseek: function(stream, offset, whence) { - if (stream.stream_ops) { - return VFS.llseek(stream, offset, whence); - } - var position = offset; - if (whence === 1) { - position += stream.position; - } else if (whence === 2) { - position += fs.fstatSync(stream.nfd).size; - } else if (whence !== 0) { - throw new FS.ErrnoError(ERRNO_CODES.EINVAL); - } - if (position < 0) { - throw new FS.ErrnoError(ERRNO_CODES.EINVAL); - } - stream.position = position; - return position; - }, - read: function(stream, buffer2, offset, length, position) { - if (stream.stream_ops) { - return VFS.read(stream, buffer2, offset, length, position); - } - var seeking = typeof position !== "undefined"; - if (!seeking && stream.seekable) - position = stream.position; - var bytesRead = fs.readSync(stream.nfd, NODEFS.bufferFrom(buffer2.buffer), offset, length, position); - if (!seeking) - stream.position += bytesRead; - return bytesRead; - }, - write: function(stream, buffer2, offset, length, position) { - if (stream.stream_ops) { - return VFS.write(stream, buffer2, offset, length, position); - } - if (stream.flags & +"1024") { - FS.llseek(stream, 0, +"2"); - } - var seeking = typeof position !== "undefined"; - if (!seeking && stream.seekable) - position = stream.position; - var bytesWritten = fs.writeSync(stream.nfd, NODEFS.bufferFrom(buffer2.buffer), offset, length, position); - if (!seeking) - stream.position += bytesWritten; - return bytesWritten; - }, - allocate: function() { - throw new FS.ErrnoError(ERRNO_CODES.EOPNOTSUPP); - }, - mmap: function(stream, address, length, position, prot, flags) { - if (stream.stream_ops) { - return VFS.mmap(stream, address, length, position, prot, flags); - } - if (address !== 0) { - throw new FS.ErrnoError(28); - } - var ptr = mmapAlloc(length); - FS.read(stream, HEAP8, ptr, length, position); - return {ptr, allocated: true}; - }, - msync: function(stream, buffer2, offset, length, mmapFlags) { - if (stream.stream_ops) { - return VFS.msync(stream, buffer2, offset, length, mmapFlags); - } - if (mmapFlags & 2) { - return 0; - } - FS.write(stream, buffer2, 0, length, offset); - return 0; - }, - munmap: function() { - return 0; - }, - ioctl: function() { - throw new FS.ErrnoError(ERRNO_CODES.ENOTTY); - } - }; - var FS = { - root: null, - mounts: [], - devices: {}, - streams: [], - nextInode: 1, - nameTable: null, - currentPath: "/", - initialized: false, - ignorePermissions: true, - trackingDelegate: {}, - tracking: {openFlags: {READ: 1, WRITE: 2}}, - ErrnoError: null, - genericErrors: {}, - filesystems: null, - syncFSRequests: 0, - lookupPath: function(path, opts) { - path = PATH_FS.resolve(FS.cwd(), path); - opts = opts || {}; - if (!path) - return {path: "", node: null}; - var defaults = {follow_mount: true, recurse_count: 0}; - for (var key2 in defaults) { - if (opts[key2] === void 0) { - opts[key2] = defaults[key2]; - } - } - if (opts.recurse_count > 8) { - throw new FS.ErrnoError(32); - } - var parts = PATH.normalizeArray(path.split("/").filter(function(p) { - return !!p; - }), false); - var current = FS.root; - var current_path = "/"; - for (var i = 0; i < parts.length; i++) { - var islast = i === parts.length - 1; - if (islast && opts.parent) { - break; - } - current = FS.lookupNode(current, parts[i]); - current_path = PATH.join2(current_path, parts[i]); - if (FS.isMountpoint(current)) { - if (!islast || islast && opts.follow_mount) { - current = current.mounted.root; - } - } - if (!islast || opts.follow) { - var count = 0; - while (FS.isLink(current.mode)) { - var link = FS.readlink(current_path); - current_path = PATH_FS.resolve(PATH.dirname(current_path), link); - var lookup = FS.lookupPath(current_path, { - recurse_count: opts.recurse_count - }); - current = lookup.node; - if (count++ > 40) { - throw new FS.ErrnoError(32); - } - } - } - } - return {path: current_path, node: current}; - }, - getPath: function(node) { - var path; - while (true) { - if (FS.isRoot(node)) { - var mount = node.mount.mountpoint; - if (!path) - return mount; - return mount[mount.length - 1] !== "/" ? mount + "/" + path : mount + path; - } - path = path ? node.name + "/" + path : node.name; - node = node.parent; - } - }, - hashName: function(parentid, name) { - var hash = 0; - for (var i = 0; i < name.length; i++) { - hash = (hash << 5) - hash + name.charCodeAt(i) | 0; - } - return (parentid + hash >>> 0) % FS.nameTable.length; - }, - hashAddNode: function(node) { - var hash = FS.hashName(node.parent.id, node.name); - node.name_next = FS.nameTable[hash]; - FS.nameTable[hash] = node; - }, - hashRemoveNode: function(node) { - var hash = FS.hashName(node.parent.id, node.name); - if (FS.nameTable[hash] === node) { - FS.nameTable[hash] = node.name_next; - } else { - var current = FS.nameTable[hash]; - while (current) { - if (current.name_next === node) { - current.name_next = node.name_next; - break; - } - current = current.name_next; - } - } - }, - lookupNode: function(parent, name) { - var errCode = FS.mayLookup(parent); - if (errCode) { - throw new FS.ErrnoError(errCode, parent); - } - var hash = FS.hashName(parent.id, name); - for (var node = FS.nameTable[hash]; node; node = node.name_next) { - var nodeName = node.name; - if (node.parent.id === parent.id && nodeName === name) { - return node; - } - } - return FS.lookup(parent, name); - }, - createNode: function(parent, name, mode, rdev) { - var node = new FS.FSNode(parent, name, mode, rdev); - FS.hashAddNode(node); - return node; - }, - destroyNode: function(node) { - FS.hashRemoveNode(node); - }, - isRoot: function(node) { - return node === node.parent; - }, - isMountpoint: function(node) { - return !!node.mounted; - }, - isFile: function(mode) { - return (mode & 61440) === 32768; - }, - isDir: function(mode) { - return (mode & 61440) === 16384; - }, - isLink: function(mode) { - return (mode & 61440) === 40960; - }, - isChrdev: function(mode) { - return (mode & 61440) === 8192; - }, - isBlkdev: function(mode) { - return (mode & 61440) === 24576; - }, - isFIFO: function(mode) { - return (mode & 61440) === 4096; - }, - isSocket: function(mode) { - return (mode & 49152) === 49152; - }, - flagModes: {r: 0, "r+": 2, w: 577, "w+": 578, a: 1089, "a+": 1090}, - modeStringToFlags: function(str) { - var flags = FS.flagModes[str]; - if (typeof flags === "undefined") { - throw new Error("Unknown file open mode: " + str); - } - return flags; - }, - flagsToPermissionString: function(flag) { - var perms = ["r", "w", "rw"][flag & 3]; - if (flag & 512) { - perms += "w"; - } - return perms; - }, - nodePermissions: function(node, perms) { - if (FS.ignorePermissions) { - return 0; - } - if (perms.includes("r") && !(node.mode & 292)) { - return 2; - } else if (perms.includes("w") && !(node.mode & 146)) { - return 2; - } else if (perms.includes("x") && !(node.mode & 73)) { - return 2; - } - return 0; - }, - mayLookup: function(dir) { - var errCode = FS.nodePermissions(dir, "x"); - if (errCode) - return errCode; - if (!dir.node_ops.lookup) - return 2; - return 0; - }, - mayCreate: function(dir, name) { - try { - var node = FS.lookupNode(dir, name); - return 20; - } catch (e) { - } - return FS.nodePermissions(dir, "wx"); - }, - mayDelete: function(dir, name, isdir) { - var node; - try { - node = FS.lookupNode(dir, name); - } catch (e) { - return e.errno; - } - var errCode = FS.nodePermissions(dir, "wx"); - if (errCode) { - return errCode; - } - if (isdir) { - if (!FS.isDir(node.mode)) { - return 54; - } - if (FS.isRoot(node) || FS.getPath(node) === FS.cwd()) { - return 10; - } - } else { - if (FS.isDir(node.mode)) { - return 31; - } - } - return 0; - }, - mayOpen: function(node, flags) { - if (!node) { - return 44; - } - if (FS.isLink(node.mode)) { - return 32; - } else if (FS.isDir(node.mode)) { - if (FS.flagsToPermissionString(flags) !== "r" || flags & 512) { - return 31; - } - } - return FS.nodePermissions(node, FS.flagsToPermissionString(flags)); - }, - MAX_OPEN_FDS: 4096, - nextfd: function(fd_start, fd_end) { - fd_start = fd_start || 0; - fd_end = fd_end || FS.MAX_OPEN_FDS; - for (var fd = fd_start; fd <= fd_end; fd++) { - if (!FS.streams[fd]) { - return fd; - } - } - throw new FS.ErrnoError(33); - }, - getStream: function(fd) { - return FS.streams[fd]; - }, - createStream: function(stream, fd_start, fd_end) { - if (!FS.FSStream) { - FS.FSStream = function() { - }; - FS.FSStream.prototype = { - object: { - get: function() { - return this.node; - }, - set: function(val) { - this.node = val; - } - }, - isRead: { - get: function() { - return (this.flags & 2097155) !== 1; - } - }, - isWrite: { - get: function() { - return (this.flags & 2097155) !== 0; - } - }, - isAppend: { - get: function() { - return this.flags & 1024; - } - } - }; - } - var newStream = new FS.FSStream(); - for (var p in stream) { - newStream[p] = stream[p]; - } - stream = newStream; - var fd = FS.nextfd(fd_start, fd_end); - stream.fd = fd; - FS.streams[fd] = stream; - return stream; - }, - closeStream: function(fd) { - FS.streams[fd] = null; - }, - chrdev_stream_ops: { - open: function(stream) { - var device = FS.getDevice(stream.node.rdev); - stream.stream_ops = device.stream_ops; - if (stream.stream_ops.open) { - stream.stream_ops.open(stream); - } - }, - llseek: function() { - throw new FS.ErrnoError(70); - } - }, - major: function(dev) { - return dev >> 8; - }, - minor: function(dev) { - return dev & 255; - }, - makedev: function(ma, mi) { - return ma << 8 | mi; - }, - registerDevice: function(dev, ops) { - FS.devices[dev] = {stream_ops: ops}; - }, - getDevice: function(dev) { - return FS.devices[dev]; - }, - getMounts: function(mount) { - var mounts = []; - var check = [mount]; - while (check.length) { - var m = check.pop(); - mounts.push(m); - check.push.apply(check, m.mounts); - } - return mounts; - }, - syncfs: function(populate, callback) { - if (typeof populate === "function") { - callback = populate; - populate = false; - } - FS.syncFSRequests++; - if (FS.syncFSRequests > 1) { - err("warning: " + FS.syncFSRequests + " FS.syncfs operations in flight at once, probably just doing extra work"); - } - var mounts = FS.getMounts(FS.root.mount); - var completed = 0; - function doCallback(errCode) { - FS.syncFSRequests--; - return callback(errCode); - } - function done(errCode) { - if (errCode) { - if (!done.errored) { - done.errored = true; - return doCallback(errCode); - } - return; - } - if (++completed >= mounts.length) { - doCallback(null); - } - } - mounts.forEach(function(mount) { - if (!mount.type.syncfs) { - return done(null); - } - mount.type.syncfs(mount, populate, done); - }); - }, - mount: function(type, opts, mountpoint) { - var root = mountpoint === "/"; - var pseudo = !mountpoint; - var node; - if (root && FS.root) { - throw new FS.ErrnoError(10); - } else if (!root && !pseudo) { - var lookup = FS.lookupPath(mountpoint, {follow_mount: false}); - mountpoint = lookup.path; - node = lookup.node; - if (FS.isMountpoint(node)) { - throw new FS.ErrnoError(10); - } - if (!FS.isDir(node.mode)) { - throw new FS.ErrnoError(54); - } - } - var mount = { - type, - opts, - mountpoint, - mounts: [] - }; - var mountRoot = type.mount(mount); - mountRoot.mount = mount; - mount.root = mountRoot; - if (root) { - FS.root = mountRoot; - } else if (node) { - node.mounted = mount; - if (node.mount) { - node.mount.mounts.push(mount); - } - } - return mountRoot; - }, - unmount: function(mountpoint) { - var lookup = FS.lookupPath(mountpoint, {follow_mount: false}); - if (!FS.isMountpoint(lookup.node)) { - throw new FS.ErrnoError(28); - } - var node = lookup.node; - var mount = node.mounted; - var mounts = FS.getMounts(mount); - Object.keys(FS.nameTable).forEach(function(hash) { - var current = FS.nameTable[hash]; - while (current) { - var next = current.name_next; - if (mounts.includes(current.mount)) { - FS.destroyNode(current); - } - current = next; - } - }); - node.mounted = null; - var idx = node.mount.mounts.indexOf(mount); - node.mount.mounts.splice(idx, 1); - }, - lookup: function(parent, name) { - return parent.node_ops.lookup(parent, name); - }, - mknod: function(path, mode, dev) { - var lookup = FS.lookupPath(path, {parent: true}); - var parent = lookup.node; - var name = PATH.basename(path); - if (!name || name === "." || name === "..") { - throw new FS.ErrnoError(28); - } - var errCode = FS.mayCreate(parent, name); - if (errCode) { - throw new FS.ErrnoError(errCode); - } - if (!parent.node_ops.mknod) { - throw new FS.ErrnoError(63); - } - return parent.node_ops.mknod(parent, name, mode, dev); - }, - create: function(path, mode) { - mode = mode !== void 0 ? mode : 438; - mode &= 4095; - mode |= 32768; - return FS.mknod(path, mode, 0); - }, - mkdir: function(path, mode) { - mode = mode !== void 0 ? mode : 511; - mode &= 511 | 512; - mode |= 16384; - return FS.mknod(path, mode, 0); - }, - mkdirTree: function(path, mode) { - var dirs = path.split("/"); - var d = ""; - for (var i = 0; i < dirs.length; ++i) { - if (!dirs[i]) - continue; - d += "/" + dirs[i]; - try { - FS.mkdir(d, mode); - } catch (e) { - if (e.errno != 20) - throw e; - } - } - }, - mkdev: function(path, mode, dev) { - if (typeof dev === "undefined") { - dev = mode; - mode = 438; - } - mode |= 8192; - return FS.mknod(path, mode, dev); - }, - symlink: function(oldpath, newpath) { - if (!PATH_FS.resolve(oldpath)) { - throw new FS.ErrnoError(44); - } - var lookup = FS.lookupPath(newpath, {parent: true}); - var parent = lookup.node; - if (!parent) { - throw new FS.ErrnoError(44); - } - var newname = PATH.basename(newpath); - var errCode = FS.mayCreate(parent, newname); - if (errCode) { - throw new FS.ErrnoError(errCode); - } - if (!parent.node_ops.symlink) { - throw new FS.ErrnoError(63); - } - return parent.node_ops.symlink(parent, newname, oldpath); - }, - rename: function(old_path, new_path) { - var old_dirname = PATH.dirname(old_path); - var new_dirname = PATH.dirname(new_path); - var old_name = PATH.basename(old_path); - var new_name = PATH.basename(new_path); - var lookup, old_dir, new_dir; - lookup = FS.lookupPath(old_path, {parent: true}); - old_dir = lookup.node; - lookup = FS.lookupPath(new_path, {parent: true}); - new_dir = lookup.node; - if (!old_dir || !new_dir) - throw new FS.ErrnoError(44); - if (old_dir.mount !== new_dir.mount) { - throw new FS.ErrnoError(75); - } - var old_node = FS.lookupNode(old_dir, old_name); - var relative = PATH_FS.relative(old_path, new_dirname); - if (relative.charAt(0) !== ".") { - throw new FS.ErrnoError(28); - } - relative = PATH_FS.relative(new_path, old_dirname); - if (relative.charAt(0) !== ".") { - throw new FS.ErrnoError(55); - } - var new_node; - try { - new_node = FS.lookupNode(new_dir, new_name); - } catch (e) { - } - if (old_node === new_node) { - return; - } - var isdir = FS.isDir(old_node.mode); - var errCode = FS.mayDelete(old_dir, old_name, isdir); - if (errCode) { - throw new FS.ErrnoError(errCode); - } - errCode = new_node ? FS.mayDelete(new_dir, new_name, isdir) : FS.mayCreate(new_dir, new_name); - if (errCode) { - throw new FS.ErrnoError(errCode); - } - if (!old_dir.node_ops.rename) { - throw new FS.ErrnoError(63); - } - if (FS.isMountpoint(old_node) || new_node && FS.isMountpoint(new_node)) { - throw new FS.ErrnoError(10); - } - if (new_dir !== old_dir) { - errCode = FS.nodePermissions(old_dir, "w"); - if (errCode) { - throw new FS.ErrnoError(errCode); - } - } - try { - if (FS.trackingDelegate["willMovePath"]) { - FS.trackingDelegate["willMovePath"](old_path, new_path); - } - } catch (e) { - err("FS.trackingDelegate['willMovePath']('" + old_path + "', '" + new_path + "') threw an exception: " + e.message); - } - FS.hashRemoveNode(old_node); - try { - old_dir.node_ops.rename(old_node, new_dir, new_name); - } catch (e) { - throw e; - } finally { - FS.hashAddNode(old_node); - } - try { - if (FS.trackingDelegate["onMovePath"]) - FS.trackingDelegate["onMovePath"](old_path, new_path); - } catch (e) { - err("FS.trackingDelegate['onMovePath']('" + old_path + "', '" + new_path + "') threw an exception: " + e.message); - } - }, - rmdir: function(path) { - var lookup = FS.lookupPath(path, {parent: true}); - var parent = lookup.node; - var name = PATH.basename(path); - var node = FS.lookupNode(parent, name); - var errCode = FS.mayDelete(parent, name, true); - if (errCode) { - throw new FS.ErrnoError(errCode); - } - if (!parent.node_ops.rmdir) { - throw new FS.ErrnoError(63); - } - if (FS.isMountpoint(node)) { - throw new FS.ErrnoError(10); - } - try { - if (FS.trackingDelegate["willDeletePath"]) { - FS.trackingDelegate["willDeletePath"](path); - } - } catch (e) { - err("FS.trackingDelegate['willDeletePath']('" + path + "') threw an exception: " + e.message); - } - parent.node_ops.rmdir(parent, name); - FS.destroyNode(node); - try { - if (FS.trackingDelegate["onDeletePath"]) - FS.trackingDelegate["onDeletePath"](path); - } catch (e) { - err("FS.trackingDelegate['onDeletePath']('" + path + "') threw an exception: " + e.message); - } - }, - readdir: function(path) { - var lookup = FS.lookupPath(path, {follow: true}); - var node = lookup.node; - if (!node.node_ops.readdir) { - throw new FS.ErrnoError(54); - } - return node.node_ops.readdir(node); - }, - unlink: function(path) { - var lookup = FS.lookupPath(path, {parent: true}); - var parent = lookup.node; - var name = PATH.basename(path); - var node = FS.lookupNode(parent, name); - var errCode = FS.mayDelete(parent, name, false); - if (errCode) { - throw new FS.ErrnoError(errCode); - } - if (!parent.node_ops.unlink) { - throw new FS.ErrnoError(63); - } - if (FS.isMountpoint(node)) { - throw new FS.ErrnoError(10); - } - try { - if (FS.trackingDelegate["willDeletePath"]) { - FS.trackingDelegate["willDeletePath"](path); - } - } catch (e) { - err("FS.trackingDelegate['willDeletePath']('" + path + "') threw an exception: " + e.message); - } - parent.node_ops.unlink(parent, name); - FS.destroyNode(node); - try { - if (FS.trackingDelegate["onDeletePath"]) - FS.trackingDelegate["onDeletePath"](path); - } catch (e) { - err("FS.trackingDelegate['onDeletePath']('" + path + "') threw an exception: " + e.message); - } - }, - readlink: function(path) { - var lookup = FS.lookupPath(path); - var link = lookup.node; - if (!link) { - throw new FS.ErrnoError(44); - } - if (!link.node_ops.readlink) { - throw new FS.ErrnoError(28); - } - return PATH_FS.resolve(FS.getPath(link.parent), link.node_ops.readlink(link)); - }, - stat: function(path, dontFollow) { - var lookup = FS.lookupPath(path, {follow: !dontFollow}); - var node = lookup.node; - if (!node) { - throw new FS.ErrnoError(44); - } - if (!node.node_ops.getattr) { - throw new FS.ErrnoError(63); - } - return node.node_ops.getattr(node); - }, - lstat: function(path) { - return FS.stat(path, true); - }, - chmod: function(path, mode, dontFollow) { - var node; - if (typeof path === "string") { - var lookup = FS.lookupPath(path, {follow: !dontFollow}); - node = lookup.node; - } else { - node = path; - } - if (!node.node_ops.setattr) { - throw new FS.ErrnoError(63); - } - node.node_ops.setattr(node, { - mode: mode & 4095 | node.mode & ~4095, - timestamp: Date.now() - }); - }, - lchmod: function(path, mode) { - FS.chmod(path, mode, true); - }, - fchmod: function(fd, mode) { - var stream = FS.getStream(fd); - if (!stream) { - throw new FS.ErrnoError(8); - } - FS.chmod(stream.node, mode); - }, - chown: function(path, uid, gid, dontFollow) { - var node; - if (typeof path === "string") { - var lookup = FS.lookupPath(path, {follow: !dontFollow}); - node = lookup.node; - } else { - node = path; - } - if (!node.node_ops.setattr) { - throw new FS.ErrnoError(63); - } - node.node_ops.setattr(node, {timestamp: Date.now()}); - }, - lchown: function(path, uid, gid) { - FS.chown(path, uid, gid, true); - }, - fchown: function(fd, uid, gid) { - var stream = FS.getStream(fd); - if (!stream) { - throw new FS.ErrnoError(8); - } - FS.chown(stream.node, uid, gid); - }, - truncate: function(path, len) { - if (len < 0) { - throw new FS.ErrnoError(28); - } - var node; - if (typeof path === "string") { - var lookup = FS.lookupPath(path, {follow: true}); - node = lookup.node; - } else { - node = path; - } - if (!node.node_ops.setattr) { - throw new FS.ErrnoError(63); - } - if (FS.isDir(node.mode)) { - throw new FS.ErrnoError(31); - } - if (!FS.isFile(node.mode)) { - throw new FS.ErrnoError(28); - } - var errCode = FS.nodePermissions(node, "w"); - if (errCode) { - throw new FS.ErrnoError(errCode); - } - node.node_ops.setattr(node, {size: len, timestamp: Date.now()}); - }, - ftruncate: function(fd, len) { - var stream = FS.getStream(fd); - if (!stream) { - throw new FS.ErrnoError(8); - } - if ((stream.flags & 2097155) === 0) { - throw new FS.ErrnoError(28); - } - FS.truncate(stream.node, len); - }, - utime: function(path, atime, mtime) { - var lookup = FS.lookupPath(path, {follow: true}); - var node = lookup.node; - node.node_ops.setattr(node, {timestamp: Math.max(atime, mtime)}); - }, - open: function(path, flags, mode, fd_start, fd_end) { - if (path === "") { - throw new FS.ErrnoError(44); - } - flags = typeof flags === "string" ? FS.modeStringToFlags(flags) : flags; - mode = typeof mode === "undefined" ? 438 : mode; - if (flags & 64) { - mode = mode & 4095 | 32768; - } else { - mode = 0; - } - var node; - if (typeof path === "object") { - node = path; - } else { - path = PATH.normalize(path); - try { - var lookup = FS.lookupPath(path, {follow: !(flags & 131072)}); - node = lookup.node; - } catch (e) { - } - } - var created = false; - if (flags & 64) { - if (node) { - if (flags & 128) { - throw new FS.ErrnoError(20); - } - } else { - node = FS.mknod(path, mode, 0); - created = true; - } - } - if (!node) { - throw new FS.ErrnoError(44); - } - if (FS.isChrdev(node.mode)) { - flags &= ~512; - } - if (flags & 65536 && !FS.isDir(node.mode)) { - throw new FS.ErrnoError(54); - } - if (!created) { - var errCode = FS.mayOpen(node, flags); - if (errCode) { - throw new FS.ErrnoError(errCode); - } - } - if (flags & 512) { - FS.truncate(node, 0); - } - flags &= ~(128 | 512 | 131072); - var stream = FS.createStream({ - node, - path: FS.getPath(node), - flags, - seekable: true, - position: 0, - stream_ops: node.stream_ops, - ungotten: [], - error: false - }, fd_start, fd_end); - if (stream.stream_ops.open) { - stream.stream_ops.open(stream); - } - if (Module["logReadFiles"] && !(flags & 1)) { - if (!FS.readFiles) - FS.readFiles = {}; - if (!(path in FS.readFiles)) { - FS.readFiles[path] = 1; - err("FS.trackingDelegate error on read file: " + path); - } - } - try { - if (FS.trackingDelegate["onOpenFile"]) { - var trackingFlags = 0; - if ((flags & 2097155) !== 1) { - trackingFlags |= FS.tracking.openFlags.READ; - } - if ((flags & 2097155) !== 0) { - trackingFlags |= FS.tracking.openFlags.WRITE; - } - FS.trackingDelegate["onOpenFile"](path, trackingFlags); - } - } catch (e) { - err("FS.trackingDelegate['onOpenFile']('" + path + "', flags) threw an exception: " + e.message); - } - return stream; - }, - close: function(stream) { - if (FS.isClosed(stream)) { - throw new FS.ErrnoError(8); - } - if (stream.getdents) - stream.getdents = null; - try { - if (stream.stream_ops.close) { - stream.stream_ops.close(stream); - } - } catch (e) { - throw e; - } finally { - FS.closeStream(stream.fd); - } - stream.fd = null; - }, - isClosed: function(stream) { - return stream.fd === null; - }, - llseek: function(stream, offset, whence) { - if (FS.isClosed(stream)) { - throw new FS.ErrnoError(8); - } - if (!stream.seekable || !stream.stream_ops.llseek) { - throw new FS.ErrnoError(70); - } - if (whence != 0 && whence != 1 && whence != 2) { - throw new FS.ErrnoError(28); - } - stream.position = stream.stream_ops.llseek(stream, offset, whence); - stream.ungotten = []; - return stream.position; - }, - read: function(stream, buffer2, offset, length, position) { - if (length < 0 || position < 0) { - throw new FS.ErrnoError(28); - } - if (FS.isClosed(stream)) { - throw new FS.ErrnoError(8); - } - if ((stream.flags & 2097155) === 1) { - throw new FS.ErrnoError(8); - } - if (FS.isDir(stream.node.mode)) { - throw new FS.ErrnoError(31); - } - if (!stream.stream_ops.read) { - throw new FS.ErrnoError(28); - } - var seeking = typeof position !== "undefined"; - if (!seeking) { - position = stream.position; - } else if (!stream.seekable) { - throw new FS.ErrnoError(70); - } - var bytesRead = stream.stream_ops.read(stream, buffer2, offset, length, position); - if (!seeking) - stream.position += bytesRead; - return bytesRead; - }, - write: function(stream, buffer2, offset, length, position, canOwn) { - if (length < 0 || position < 0) { - throw new FS.ErrnoError(28); - } - if (FS.isClosed(stream)) { - throw new FS.ErrnoError(8); - } - if ((stream.flags & 2097155) === 0) { - throw new FS.ErrnoError(8); - } - if (FS.isDir(stream.node.mode)) { - throw new FS.ErrnoError(31); - } - if (!stream.stream_ops.write) { - throw new FS.ErrnoError(28); - } - if (stream.seekable && stream.flags & 1024) { - FS.llseek(stream, 0, 2); - } - var seeking = typeof position !== "undefined"; - if (!seeking) { - position = stream.position; - } else if (!stream.seekable) { - throw new FS.ErrnoError(70); - } - var bytesWritten = stream.stream_ops.write(stream, buffer2, offset, length, position, canOwn); - if (!seeking) - stream.position += bytesWritten; - try { - if (stream.path && FS.trackingDelegate["onWriteToFile"]) - FS.trackingDelegate["onWriteToFile"](stream.path); - } catch (e) { - err("FS.trackingDelegate['onWriteToFile']('" + stream.path + "') threw an exception: " + e.message); - } - return bytesWritten; - }, - allocate: function(stream, offset, length) { - if (FS.isClosed(stream)) { - throw new FS.ErrnoError(8); - } - if (offset < 0 || length <= 0) { - throw new FS.ErrnoError(28); - } - if ((stream.flags & 2097155) === 0) { - throw new FS.ErrnoError(8); - } - if (!FS.isFile(stream.node.mode) && !FS.isDir(stream.node.mode)) { - throw new FS.ErrnoError(43); - } - if (!stream.stream_ops.allocate) { - throw new FS.ErrnoError(138); - } - stream.stream_ops.allocate(stream, offset, length); - }, - mmap: function(stream, address, length, position, prot, flags) { - if ((prot & 2) !== 0 && (flags & 2) === 0 && (stream.flags & 2097155) !== 2) { - throw new FS.ErrnoError(2); - } - if ((stream.flags & 2097155) === 1) { - throw new FS.ErrnoError(2); - } - if (!stream.stream_ops.mmap) { - throw new FS.ErrnoError(43); - } - return stream.stream_ops.mmap(stream, address, length, position, prot, flags); - }, - msync: function(stream, buffer2, offset, length, mmapFlags) { - if (!stream || !stream.stream_ops.msync) { - return 0; - } - return stream.stream_ops.msync(stream, buffer2, offset, length, mmapFlags); - }, - munmap: function(stream) { - return 0; - }, - ioctl: function(stream, cmd, arg) { - if (!stream.stream_ops.ioctl) { - throw new FS.ErrnoError(59); - } - return stream.stream_ops.ioctl(stream, cmd, arg); - }, - readFile: function(path, opts) { - opts = opts || {}; - opts.flags = opts.flags || 0; - opts.encoding = opts.encoding || "binary"; - if (opts.encoding !== "utf8" && opts.encoding !== "binary") { - throw new Error('Invalid encoding type "' + opts.encoding + '"'); - } - var ret; - var stream = FS.open(path, opts.flags); - var stat = FS.stat(path); - var length = stat.size; - var buf = new Uint8Array(length); - FS.read(stream, buf, 0, length, 0); - if (opts.encoding === "utf8") { - ret = UTF8ArrayToString(buf, 0); - } else if (opts.encoding === "binary") { - ret = buf; - } - FS.close(stream); - return ret; - }, - writeFile: function(path, data, opts) { - opts = opts || {}; - opts.flags = opts.flags || 577; - var stream = FS.open(path, opts.flags, opts.mode); - if (typeof data === "string") { - var buf = new Uint8Array(lengthBytesUTF8(data) + 1); - var actualNumBytes = stringToUTF8Array(data, buf, 0, buf.length); - FS.write(stream, buf, 0, actualNumBytes, void 0, opts.canOwn); - } else if (ArrayBuffer.isView(data)) { - FS.write(stream, data, 0, data.byteLength, void 0, opts.canOwn); - } else { - throw new Error("Unsupported data type"); - } - FS.close(stream); - }, - cwd: function() { - return FS.currentPath; - }, - chdir: function(path) { - var lookup = FS.lookupPath(path, {follow: true}); - if (lookup.node === null) { - throw new FS.ErrnoError(44); - } - if (!FS.isDir(lookup.node.mode)) { - throw new FS.ErrnoError(54); - } - var errCode = FS.nodePermissions(lookup.node, "x"); - if (errCode) { - throw new FS.ErrnoError(errCode); - } - FS.currentPath = lookup.path; - }, - createDefaultDirectories: function() { - FS.mkdir("/tmp"); - FS.mkdir("/home"); - FS.mkdir("/home/web_user"); - }, - createDefaultDevices: function() { - FS.mkdir("/dev"); - FS.registerDevice(FS.makedev(1, 3), { - read: function() { - return 0; - }, - write: function(stream, buffer2, offset, length, pos) { - return length; - } - }); - FS.mkdev("/dev/null", FS.makedev(1, 3)); - TTY.register(FS.makedev(5, 0), TTY.default_tty_ops); - TTY.register(FS.makedev(6, 0), TTY.default_tty1_ops); - FS.mkdev("/dev/tty", FS.makedev(5, 0)); - FS.mkdev("/dev/tty1", FS.makedev(6, 0)); - var random_device = getRandomDevice(); - FS.createDevice("/dev", "random", random_device); - FS.createDevice("/dev", "urandom", random_device); - FS.mkdir("/dev/shm"); - FS.mkdir("/dev/shm/tmp"); - }, - createSpecialDirectories: function() { - FS.mkdir("/proc"); - var proc_self = FS.mkdir("/proc/self"); - FS.mkdir("/proc/self/fd"); - FS.mount({ - mount: function() { - var node = FS.createNode(proc_self, "fd", 16384 | 511, 73); - node.node_ops = { - lookup: function(parent, name) { - var fd = +name; - var stream = FS.getStream(fd); - if (!stream) - throw new FS.ErrnoError(8); - var ret = { - parent: null, - mount: {mountpoint: "fake"}, - node_ops: { - readlink: function() { - return stream.path; - } - } - }; - ret.parent = ret; - return ret; - } - }; - return node; - } - }, {}, "/proc/self/fd"); - }, - createStandardStreams: function() { - if (Module["stdin"]) { - FS.createDevice("/dev", "stdin", Module["stdin"]); - } else { - FS.symlink("/dev/tty", "/dev/stdin"); - } - if (Module["stdout"]) { - FS.createDevice("/dev", "stdout", null, Module["stdout"]); - } else { - FS.symlink("/dev/tty", "/dev/stdout"); - } - if (Module["stderr"]) { - FS.createDevice("/dev", "stderr", null, Module["stderr"]); - } else { - FS.symlink("/dev/tty1", "/dev/stderr"); - } - FS.open("/dev/stdin", 0); - FS.open("/dev/stdout", 1); - FS.open("/dev/stderr", 1); - }, - ensureErrnoError: function() { - if (FS.ErrnoError) - return; - FS.ErrnoError = function ErrnoError(errno, node) { - this.node = node; - this.setErrno = function(errno2) { - this.errno = errno2; - }; - this.setErrno(errno); - this.message = "FS error"; - }; - FS.ErrnoError.prototype = new Error(); - FS.ErrnoError.prototype.constructor = FS.ErrnoError; - [44].forEach(function(code) { - FS.genericErrors[code] = new FS.ErrnoError(code); - FS.genericErrors[code].stack = ""; - }); - }, - staticInit: function() { - FS.ensureErrnoError(); - FS.nameTable = new Array(4096); - FS.mount(MEMFS, {}, "/"); - FS.createDefaultDirectories(); - FS.createDefaultDevices(); - FS.createSpecialDirectories(); - FS.filesystems = {MEMFS, NODEFS}; - }, - init: function(input, output, error) { - FS.init.initialized = true; - FS.ensureErrnoError(); - Module["stdin"] = input || Module["stdin"]; - Module["stdout"] = output || Module["stdout"]; - Module["stderr"] = error || Module["stderr"]; - FS.createStandardStreams(); - }, - quit: function() { - FS.init.initialized = false; - var fflush = Module["_fflush"]; - if (fflush) - fflush(0); - for (var i = 0; i < FS.streams.length; i++) { - var stream = FS.streams[i]; - if (!stream) { - continue; - } - FS.close(stream); - } - }, - getMode: function(canRead, canWrite) { - var mode = 0; - if (canRead) - mode |= 292 | 73; - if (canWrite) - mode |= 146; - return mode; - }, - findObject: function(path, dontResolveLastLink) { - var ret = FS.analyzePath(path, dontResolveLastLink); - if (ret.exists) { - return ret.object; - } else { - return null; - } - }, - analyzePath: function(path, dontResolveLastLink) { - try { - var lookup = FS.lookupPath(path, {follow: !dontResolveLastLink}); - path = lookup.path; - } catch (e) { - } - var ret = { - isRoot: false, - exists: false, - error: 0, - name: null, - path: null, - object: null, - parentExists: false, - parentPath: null, - parentObject: null - }; - try { - var lookup = FS.lookupPath(path, {parent: true}); - ret.parentExists = true; - ret.parentPath = lookup.path; - ret.parentObject = lookup.node; - ret.name = PATH.basename(path); - lookup = FS.lookupPath(path, {follow: !dontResolveLastLink}); - ret.exists = true; - ret.path = lookup.path; - ret.object = lookup.node; - ret.name = lookup.node.name; - ret.isRoot = lookup.path === "/"; - } catch (e) { - ret.error = e.errno; - } - return ret; - }, - createPath: function(parent, path, canRead, canWrite) { - parent = typeof parent === "string" ? parent : FS.getPath(parent); - var parts = path.split("/").reverse(); - while (parts.length) { - var part = parts.pop(); - if (!part) - continue; - var current = PATH.join2(parent, part); - try { - FS.mkdir(current); - } catch (e) { - } - parent = current; - } - return current; - }, - createFile: function(parent, name, properties, canRead, canWrite) { - var path = PATH.join2(typeof parent === "string" ? parent : FS.getPath(parent), name); - var mode = FS.getMode(canRead, canWrite); - return FS.create(path, mode); - }, - createDataFile: function(parent, name, data, canRead, canWrite, canOwn) { - var path = name ? PATH.join2(typeof parent === "string" ? parent : FS.getPath(parent), name) : parent; - var mode = FS.getMode(canRead, canWrite); - var node = FS.create(path, mode); - if (data) { - if (typeof data === "string") { - var arr = new Array(data.length); - for (var i = 0, len = data.length; i < len; ++i) - arr[i] = data.charCodeAt(i); - data = arr; - } - FS.chmod(node, mode | 146); - var stream = FS.open(node, 577); - FS.write(stream, data, 0, data.length, 0, canOwn); - FS.close(stream); - FS.chmod(node, mode); - } - return node; - }, - createDevice: function(parent, name, input, output) { - var path = PATH.join2(typeof parent === "string" ? parent : FS.getPath(parent), name); - var mode = FS.getMode(!!input, !!output); - if (!FS.createDevice.major) - FS.createDevice.major = 64; - var dev = FS.makedev(FS.createDevice.major++, 0); - FS.registerDevice(dev, { - open: function(stream) { - stream.seekable = false; - }, - close: function(stream) { - if (output && output.buffer && output.buffer.length) { - output(10); - } - }, - read: function(stream, buffer2, offset, length, pos) { - var bytesRead = 0; - for (var i = 0; i < length; i++) { - var result; - try { - result = input(); - } catch (e) { - throw new FS.ErrnoError(29); - } - if (result === void 0 && bytesRead === 0) { - throw new FS.ErrnoError(6); - } - if (result === null || result === void 0) - break; - bytesRead++; - buffer2[offset + i] = result; - } - if (bytesRead) { - stream.node.timestamp = Date.now(); - } - return bytesRead; - }, - write: function(stream, buffer2, offset, length, pos) { - for (var i = 0; i < length; i++) { - try { - output(buffer2[offset + i]); - } catch (e) { - throw new FS.ErrnoError(29); - } - } - if (length) { - stream.node.timestamp = Date.now(); - } - return i; - } - }); - return FS.mkdev(path, mode, dev); - }, - forceLoadFile: function(obj) { - if (obj.isDevice || obj.isFolder || obj.link || obj.contents) - return true; - if (read_) { - try { - obj.contents = intArrayFromString(read_(obj.url), true); - obj.usedBytes = obj.contents.length; - } catch (e) { - throw new FS.ErrnoError(29); - } - } else { - throw new Error("Cannot load without read() or XMLHttpRequest."); - } - }, - createLazyFile: function(parent, name, url, canRead, canWrite) { - var properties; { - var properties = {isDevice: false, url}; - } - var node = FS.createFile(parent, name, properties, canRead, canWrite); - if (properties.contents) { - node.contents = properties.contents; - } else if (properties.url) { - node.contents = null; - node.url = properties.url; - } - Object.defineProperties(node, { - usedBytes: { - get: function() { - return this.contents.length; - } - } - }); - var stream_ops = {}; - var keys = Object.keys(node.stream_ops); - keys.forEach(function(key2) { - var fn = node.stream_ops[key2]; - stream_ops[key2] = function forceLoadLazyFile() { - FS.forceLoadFile(node); - return fn.apply(null, arguments); - }; - }); - stream_ops.read = function stream_ops_read(stream, buffer2, offset, length, position) { - FS.forceLoadFile(node); - var contents = stream.node.contents; - if (position >= contents.length) - return 0; - var size = Math.min(contents.length - position, length); - if (contents.slice) { - for (var i = 0; i < size; i++) { - buffer2[offset + i] = contents[position + i]; - } - } else { - for (var i = 0; i < size; i++) { - buffer2[offset + i] = contents.get(position + i); - } - } - return size; - }; - node.stream_ops = stream_ops; - return node; - }, - createPreloadedFile: function(parent, name, url, canRead, canWrite, onload, onerror, dontCreateFile, canOwn, preFinish) { - Browser.init(); - var fullname = name ? PATH_FS.resolve(PATH.join2(parent, name)) : parent; - function processData(byteArray) { - function finish(byteArray2) { - if (preFinish) - preFinish(); - if (!dontCreateFile) { - FS.createDataFile(parent, name, byteArray2, canRead, canWrite, canOwn); - } - if (onload) - onload(); - removeRunDependency(); - } - var handled = false; - Module["preloadPlugins"].forEach(function(plugin) { - if (handled) - return; - if (plugin["canHandle"](fullname)) { - plugin["handle"](byteArray, fullname, finish, function() { - if (onerror) - onerror(); - removeRunDependency(); - }); - handled = true; - } - }); - if (!handled) - finish(byteArray); - } - addRunDependency(); - if (typeof url == "string") { - Browser.asyncLoad(url, function(byteArray) { - processData(byteArray); - }, onerror); - } else { - processData(url); - } - }, - indexedDB: function() { - return window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB; - }, - DB_NAME: function() { - return "EM_FS_" + window.location.pathname; - }, - DB_VERSION: 20, - DB_STORE_NAME: "FILE_DATA", - saveFilesToDB: function(paths, onload, onerror) { - onload = onload || function() { - }; - onerror = onerror || function() { - }; - var indexedDB = FS.indexedDB(); - try { - var openRequest = indexedDB.open(FS.DB_NAME(), FS.DB_VERSION); - } catch (e) { - return onerror(e); - } - openRequest.onupgradeneeded = function openRequest_onupgradeneeded() { - out("creating db"); - var db = openRequest.result; - db.createObjectStore(FS.DB_STORE_NAME); - }; - openRequest.onsuccess = function openRequest_onsuccess() { - var db = openRequest.result; - var transaction = db.transaction([FS.DB_STORE_NAME], "readwrite"); - var files = transaction.objectStore(FS.DB_STORE_NAME); - var ok = 0, fail = 0, total = paths.length; - function finish() { - if (fail == 0) - onload(); - else - onerror(); - } - paths.forEach(function(path) { - var putRequest = files.put(FS.analyzePath(path).object.contents, path); - putRequest.onsuccess = function putRequest_onsuccess() { - ok++; - if (ok + fail == total) - finish(); - }; - putRequest.onerror = function putRequest_onerror() { - fail++; - if (ok + fail == total) - finish(); - }; - }); - transaction.onerror = onerror; - }; - openRequest.onerror = onerror; - }, - loadFilesFromDB: function(paths, onload, onerror) { - onload = onload || function() { - }; - onerror = onerror || function() { - }; - var indexedDB = FS.indexedDB(); - try { - var openRequest = indexedDB.open(FS.DB_NAME(), FS.DB_VERSION); - } catch (e) { - return onerror(e); - } - openRequest.onupgradeneeded = onerror; - openRequest.onsuccess = function openRequest_onsuccess() { - var db = openRequest.result; - try { - var transaction = db.transaction([FS.DB_STORE_NAME], "readonly"); - } catch (e) { - onerror(e); - return; - } - var files = transaction.objectStore(FS.DB_STORE_NAME); - var ok = 0, fail = 0, total = paths.length; - function finish() { - if (fail == 0) - onload(); - else - onerror(); - } - paths.forEach(function(path) { - var getRequest = files.get(path); - getRequest.onsuccess = function getRequest_onsuccess() { - if (FS.analyzePath(path).exists) { - FS.unlink(path); - } - FS.createDataFile(PATH.dirname(path), PATH.basename(path), getRequest.result, true, true, true); - ok++; - if (ok + fail == total) - finish(); - }; - getRequest.onerror = function getRequest_onerror() { - fail++; - if (ok + fail == total) - finish(); - }; - }); - transaction.onerror = onerror; - }; - openRequest.onerror = onerror; - } - }; - var SYSCALLS = { - mappings: {}, - DEFAULT_POLLMASK: 5, - umask: 511, - calculateAt: function(dirfd, path, allowEmpty) { - if (path[0] === "/") { - return path; - } - var dir; - if (dirfd === -100) { - dir = FS.cwd(); - } else { - var dirstream = FS.getStream(dirfd); - if (!dirstream) - throw new FS.ErrnoError(8); - dir = dirstream.path; - } - if (path.length == 0) { - if (!allowEmpty) { - throw new FS.ErrnoError(44); - } - return dir; - } - return PATH.join2(dir, path); - }, - doStat: function(func, path, buf) { - try { - var stat = func(path); - } catch (e) { - if (e && e.node && PATH.normalize(path) !== PATH.normalize(FS.getPath(e.node))) { - return -54; - } - throw e; - } - HEAP32[buf >> 2] = stat.dev; - HEAP32[buf + 4 >> 2] = 0; - HEAP32[buf + 8 >> 2] = stat.ino; - HEAP32[buf + 12 >> 2] = stat.mode; - HEAP32[buf + 16 >> 2] = stat.nlink; - HEAP32[buf + 20 >> 2] = stat.uid; - HEAP32[buf + 24 >> 2] = stat.gid; - HEAP32[buf + 28 >> 2] = stat.rdev; - HEAP32[buf + 32 >> 2] = 0; - tempI64 = [ - stat.size >>> 0, - (tempDouble = stat.size, +Math.abs(tempDouble) >= 1 ? tempDouble > 0 ? (Math.min(+Math.floor(tempDouble / 4294967296), 4294967295) | 0) >>> 0 : ~~+Math.ceil((tempDouble - +(~~tempDouble >>> 0)) / 4294967296) >>> 0 : 0) - ], HEAP32[buf + 40 >> 2] = tempI64[0], HEAP32[buf + 44 >> 2] = tempI64[1]; - HEAP32[buf + 48 >> 2] = 4096; - HEAP32[buf + 52 >> 2] = stat.blocks; - HEAP32[buf + 56 >> 2] = stat.atime.getTime() / 1e3 | 0; - HEAP32[buf + 60 >> 2] = 0; - HEAP32[buf + 64 >> 2] = stat.mtime.getTime() / 1e3 | 0; - HEAP32[buf + 68 >> 2] = 0; - HEAP32[buf + 72 >> 2] = stat.ctime.getTime() / 1e3 | 0; - HEAP32[buf + 76 >> 2] = 0; - tempI64 = [ - stat.ino >>> 0, - (tempDouble = stat.ino, +Math.abs(tempDouble) >= 1 ? tempDouble > 0 ? (Math.min(+Math.floor(tempDouble / 4294967296), 4294967295) | 0) >>> 0 : ~~+Math.ceil((tempDouble - +(~~tempDouble >>> 0)) / 4294967296) >>> 0 : 0) - ], HEAP32[buf + 80 >> 2] = tempI64[0], HEAP32[buf + 84 >> 2] = tempI64[1]; - return 0; - }, - doMsync: function(addr, stream, len, flags, offset) { - var buffer2 = HEAPU8.slice(addr, addr + len); - FS.msync(stream, buffer2, offset, len, flags); - }, - doMkdir: function(path, mode) { - path = PATH.normalize(path); - if (path[path.length - 1] === "/") - path = path.substr(0, path.length - 1); - FS.mkdir(path, mode, 0); - return 0; - }, - doMknod: function(path, mode, dev) { - switch (mode & 61440) { - case 32768: - case 8192: - case 24576: - case 4096: - case 49152: - break; - default: - return -28; - } - FS.mknod(path, mode, dev); - return 0; - }, - doReadlink: function(path, buf, bufsize) { - if (bufsize <= 0) - return -28; - var ret = FS.readlink(path); - var len = Math.min(bufsize, lengthBytesUTF8(ret)); - var endChar = HEAP8[buf + len]; - stringToUTF8(ret, buf, bufsize + 1); - HEAP8[buf + len] = endChar; - return len; - }, - doAccess: function(path, amode) { - if (amode & ~7) { - return -28; - } - var node; - var lookup = FS.lookupPath(path, {follow: true}); - node = lookup.node; - if (!node) { - return -44; - } - var perms = ""; - if (amode & 4) - perms += "r"; - if (amode & 2) - perms += "w"; - if (amode & 1) - perms += "x"; - if (perms && FS.nodePermissions(node, perms)) { - return -2; - } - return 0; - }, - doDup: function(path, flags, suggestFD) { - var suggest = FS.getStream(suggestFD); - if (suggest) - FS.close(suggest); - return FS.open(path, flags, 0, suggestFD, suggestFD).fd; - }, - doReadv: function(stream, iov, iovcnt, offset) { - var ret = 0; - for (var i = 0; i < iovcnt; i++) { - var ptr = HEAP32[iov + i * 8 >> 2]; - var len = HEAP32[iov + (i * 8 + 4) >> 2]; - var curr = FS.read(stream, HEAP8, ptr, len, offset); - if (curr < 0) - return -1; - ret += curr; - if (curr < len) - break; - } - return ret; - }, - doWritev: function(stream, iov, iovcnt, offset) { - var ret = 0; - for (var i = 0; i < iovcnt; i++) { - var ptr = HEAP32[iov + i * 8 >> 2]; - var len = HEAP32[iov + (i * 8 + 4) >> 2]; - var curr = FS.write(stream, HEAP8, ptr, len, offset); - if (curr < 0) - return -1; - ret += curr; - } - return ret; - }, - varargs: void 0, - get: function() { - SYSCALLS.varargs += 4; - var ret = HEAP32[SYSCALLS.varargs - 4 >> 2]; - return ret; - }, - getStr: function(ptr) { - var ret = UTF8ToString(ptr); - return ret; - }, - getStreamFromFD: function(fd) { - var stream = FS.getStream(fd); - if (!stream) - throw new FS.ErrnoError(8); - return stream; - }, - get64: function(low, high) { - return low; - } - }; - function ___sys_chmod(path, mode) { - try { - path = SYSCALLS.getStr(path); - FS.chmod(path, mode); - return 0; - } catch (e) { - if (typeof FS === "undefined" || !(e instanceof FS.ErrnoError)) - abort(e); - return -e.errno; - } - } - function setErrNo(value) { - HEAP32[___errno_location() >> 2] = value; - return value; - } - function ___sys_fcntl64(fd, cmd, varargs) { - SYSCALLS.varargs = varargs; - try { - var stream = SYSCALLS.getStreamFromFD(fd); - switch (cmd) { - case 0: { - var arg = SYSCALLS.get(); - if (arg < 0) { - return -28; - } - var newStream; - newStream = FS.open(stream.path, stream.flags, 0, arg); - return newStream.fd; - } - case 1: - case 2: - return 0; - case 3: - return stream.flags; - case 4: { - var arg = SYSCALLS.get(); - stream.flags |= arg; - return 0; - } - case 12: { - var arg = SYSCALLS.get(); - var offset = 0; - HEAP16[arg + offset >> 1] = 2; - return 0; - } - case 13: - case 14: - return 0; - case 16: - case 8: - return -28; - case 9: - setErrNo(28); - return -1; - default: { - return -28; - } - } - } catch (e) { - if (typeof FS === "undefined" || !(e instanceof FS.ErrnoError)) - abort(e); - return -e.errno; - } - } - function ___sys_fstat64(fd, buf) { - try { - var stream = SYSCALLS.getStreamFromFD(fd); - return SYSCALLS.doStat(FS.stat, stream.path, buf); - } catch (e) { - if (typeof FS === "undefined" || !(e instanceof FS.ErrnoError)) - abort(e); - return -e.errno; - } - } - function ___sys_ioctl(fd, op, varargs) { - SYSCALLS.varargs = varargs; - try { - var stream = SYSCALLS.getStreamFromFD(fd); - switch (op) { - case 21509: - case 21505: { - if (!stream.tty) - return -59; - return 0; - } - case 21510: - case 21511: - case 21512: - case 21506: - case 21507: - case 21508: { - if (!stream.tty) - return -59; - return 0; - } - case 21519: { - if (!stream.tty) - return -59; - var argp = SYSCALLS.get(); - HEAP32[argp >> 2] = 0; - return 0; - } - case 21520: { - if (!stream.tty) - return -59; - return -28; - } - case 21531: { - var argp = SYSCALLS.get(); - return FS.ioctl(stream, op, argp); - } - case 21523: { - if (!stream.tty) - return -59; - return 0; - } - case 21524: { - if (!stream.tty) - return -59; - return 0; - } - default: - abort("bad ioctl syscall " + op); - } - } catch (e) { - if (typeof FS === "undefined" || !(e instanceof FS.ErrnoError)) - abort(e); - return -e.errno; - } - } - function ___sys_open(path, flags, varargs) { - SYSCALLS.varargs = varargs; - try { - var pathname = SYSCALLS.getStr(path); - var mode = varargs ? SYSCALLS.get() : 0; - var stream = FS.open(pathname, flags, mode); - return stream.fd; - } catch (e) { - if (typeof FS === "undefined" || !(e instanceof FS.ErrnoError)) - abort(e); - return -e.errno; - } - } - function ___sys_rename(old_path, new_path) { - try { - old_path = SYSCALLS.getStr(old_path); - new_path = SYSCALLS.getStr(new_path); - FS.rename(old_path, new_path); - return 0; - } catch (e) { - if (typeof FS === "undefined" || !(e instanceof FS.ErrnoError)) - abort(e); - return -e.errno; - } - } - function ___sys_rmdir(path) { - try { - path = SYSCALLS.getStr(path); - FS.rmdir(path); - return 0; - } catch (e) { - if (typeof FS === "undefined" || !(e instanceof FS.ErrnoError)) - abort(e); - return -e.errno; - } - } - function ___sys_stat64(path, buf) { - try { - path = SYSCALLS.getStr(path); - return SYSCALLS.doStat(FS.stat, path, buf); - } catch (e) { - if (typeof FS === "undefined" || !(e instanceof FS.ErrnoError)) - abort(e); - return -e.errno; - } - } - function ___sys_unlink(path) { - try { - path = SYSCALLS.getStr(path); - FS.unlink(path); - return 0; - } catch (e) { - if (typeof FS === "undefined" || !(e instanceof FS.ErrnoError)) - abort(e); - return -e.errno; - } - } - function _emscripten_memcpy_big(dest, src, num) { - HEAPU8.copyWithin(dest, src, src + num); - } - function emscripten_realloc_buffer(size) { - try { - wasmMemory.grow(size - buffer.byteLength + 65535 >>> 16); - updateGlobalBufferAndViews(wasmMemory.buffer); - return 1; - } catch (e) { - } - } - function _emscripten_resize_heap(requestedSize) { - var oldSize = HEAPU8.length; - requestedSize = requestedSize >>> 0; - var maxHeapSize = 2147483648; - if (requestedSize > maxHeapSize) { - return false; - } - for (var cutDown = 1; cutDown <= 4; cutDown *= 2) { - var overGrownHeapSize = oldSize * (1 + 0.2 / cutDown); - overGrownHeapSize = Math.min(overGrownHeapSize, requestedSize + 100663296); - var newSize = Math.min(maxHeapSize, alignUp(Math.max(requestedSize, overGrownHeapSize), 65536)); - var replacement = emscripten_realloc_buffer(newSize); - if (replacement) { - return true; - } - } - return false; - } - function _fd_close(fd) { - try { - var stream = SYSCALLS.getStreamFromFD(fd); - FS.close(stream); - return 0; - } catch (e) { - if (typeof FS === "undefined" || !(e instanceof FS.ErrnoError)) - abort(e); - return e.errno; - } - } - function _fd_fdstat_get(fd, pbuf) { - try { - var stream = SYSCALLS.getStreamFromFD(fd); - var type = stream.tty ? 2 : FS.isDir(stream.mode) ? 3 : FS.isLink(stream.mode) ? 7 : 4; - HEAP8[pbuf >> 0] = type; - return 0; - } catch (e) { - if (typeof FS === "undefined" || !(e instanceof FS.ErrnoError)) - abort(e); - return e.errno; - } - } - function _fd_read(fd, iov, iovcnt, pnum) { - try { - var stream = SYSCALLS.getStreamFromFD(fd); - var num = SYSCALLS.doReadv(stream, iov, iovcnt); - HEAP32[pnum >> 2] = num; - return 0; - } catch (e) { - if (typeof FS === "undefined" || !(e instanceof FS.ErrnoError)) - abort(e); - return e.errno; - } - } - function _fd_seek(fd, offset_low, offset_high, whence, newOffset) { - try { - var stream = SYSCALLS.getStreamFromFD(fd); - var HIGH_OFFSET = 4294967296; - var offset = offset_high * HIGH_OFFSET + (offset_low >>> 0); - var DOUBLE_LIMIT = 9007199254740992; - if (offset <= -DOUBLE_LIMIT || offset >= DOUBLE_LIMIT) { - return -61; - } - FS.llseek(stream, offset, whence); - tempI64 = [ - stream.position >>> 0, - (tempDouble = stream.position, +Math.abs(tempDouble) >= 1 ? tempDouble > 0 ? (Math.min(+Math.floor(tempDouble / 4294967296), 4294967295) | 0) >>> 0 : ~~+Math.ceil((tempDouble - +(~~tempDouble >>> 0)) / 4294967296) >>> 0 : 0) - ], HEAP32[newOffset >> 2] = tempI64[0], HEAP32[newOffset + 4 >> 2] = tempI64[1]; - if (stream.getdents && offset === 0 && whence === 0) - stream.getdents = null; - return 0; - } catch (e) { - if (typeof FS === "undefined" || !(e instanceof FS.ErrnoError)) - abort(e); - return e.errno; - } - } - function _fd_write(fd, iov, iovcnt, pnum) { - try { - var stream = SYSCALLS.getStreamFromFD(fd); - var num = SYSCALLS.doWritev(stream, iov, iovcnt); - HEAP32[pnum >> 2] = num; - return 0; - } catch (e) { - if (typeof FS === "undefined" || !(e instanceof FS.ErrnoError)) - abort(e); - return e.errno; - } - } - function _setTempRet0(val) { - } - function _time(ptr) { - var ret = Date.now() / 1e3 | 0; - if (ptr) { - HEAP32[ptr >> 2] = ret; - } - return ret; - } - function _tzset() { - if (_tzset.called) - return; - _tzset.called = true; - var currentYear = new Date().getFullYear(); - var winter = new Date(currentYear, 0, 1); - var summer = new Date(currentYear, 6, 1); - var winterOffset = winter.getTimezoneOffset(); - var summerOffset = summer.getTimezoneOffset(); - var stdTimezoneOffset = Math.max(winterOffset, summerOffset); - HEAP32[__get_timezone() >> 2] = stdTimezoneOffset * 60; - HEAP32[__get_daylight() >> 2] = Number(winterOffset != summerOffset); - function extractZone(date) { - var match = date.toTimeString().match(/\(([A-Za-z ]+)\)$/); - return match ? match[1] : "GMT"; - } - var winterName = extractZone(winter); - var summerName = extractZone(summer); - var winterNamePtr = allocateUTF8(winterName); - var summerNamePtr = allocateUTF8(summerName); - if (summerOffset < winterOffset) { - HEAP32[__get_tzname() >> 2] = winterNamePtr; - HEAP32[__get_tzname() + 4 >> 2] = summerNamePtr; - } else { - HEAP32[__get_tzname() >> 2] = summerNamePtr; - HEAP32[__get_tzname() + 4 >> 2] = winterNamePtr; - } - } - function _timegm(tmPtr) { - _tzset(); - var time = Date.UTC(HEAP32[tmPtr + 20 >> 2] + 1900, HEAP32[tmPtr + 16 >> 2], HEAP32[tmPtr + 12 >> 2], HEAP32[tmPtr + 8 >> 2], HEAP32[tmPtr + 4 >> 2], HEAP32[tmPtr >> 2], 0); - var date = new Date(time); - HEAP32[tmPtr + 24 >> 2] = date.getUTCDay(); - var start = Date.UTC(date.getUTCFullYear(), 0, 1, 0, 0, 0, 0); - var yday = (date.getTime() - start) / (1e3 * 60 * 60 * 24) | 0; - HEAP32[tmPtr + 28 >> 2] = yday; - return date.getTime() / 1e3 | 0; - } - var FSNode = function(parent, name, mode, rdev) { - if (!parent) { - parent = this; - } - this.parent = parent; - this.mount = parent.mount; - this.mounted = null; - this.id = FS.nextInode++; - this.name = name; - this.mode = mode; - this.node_ops = {}; - this.stream_ops = {}; - this.rdev = rdev; - }; - var readMode = 292 | 73; - var writeMode = 146; - Object.defineProperties(FSNode.prototype, { - read: { - get: function() { - return (this.mode & readMode) === readMode; - }, - set: function(val) { - val ? this.mode |= readMode : this.mode &= ~readMode; - } - }, - write: { - get: function() { - return (this.mode & writeMode) === writeMode; - }, - set: function(val) { - val ? this.mode |= writeMode : this.mode &= ~writeMode; - } - }, - isFolder: { - get: function() { - return FS.isDir(this.mode); - } - }, - isDevice: { - get: function() { - return FS.isChrdev(this.mode); - } - } - }); - FS.FSNode = FSNode; - FS.staticInit(); - { - var fs = frozenFs; - var NODEJS_PATH = path__default.default; - NODEFS.staticInit(); - } - { - var _wrapNodeError = function(func) { - return function() { - try { - return func.apply(this, arguments); - } catch (e) { - if (!e.code) - throw e; - throw new FS.ErrnoError(ERRNO_CODES[e.code]); - } - }; - }; - var VFS = Object.assign({}, FS); - for (var _key in NODERAWFS) - FS[_key] = _wrapNodeError(NODERAWFS[_key]); - } - function intArrayFromString(stringy, dontAddNull, length) { - var len = length > 0 ? length : lengthBytesUTF8(stringy) + 1; - var u8array = new Array(len); - var numBytesWritten = stringToUTF8Array(stringy, u8array, 0, u8array.length); - if (dontAddNull) - u8array.length = numBytesWritten; - return u8array; - } - function intArrayFromBase64(s) { - { - var buf; - try { - buf = Buffer.from(s, "base64"); - } catch (_) { - buf = new Buffer(s, "base64"); - } - return new Uint8Array(buf["buffer"], buf["byteOffset"], buf["byteLength"]); - } - } - function tryParseAsDataURI(filename) { - if (!isDataURI(filename)) { - return; - } - return intArrayFromBase64(filename.slice(dataURIPrefix.length)); - } - var asmLibraryArg = { - s: ___gmtime_r, - p: ___sys_chmod, - e: ___sys_fcntl64, - k: ___sys_fstat64, - o: ___sys_ioctl, - q: ___sys_open, - i: ___sys_rename, - r: ___sys_rmdir, - c: ___sys_stat64, - h: ___sys_unlink, - l: _emscripten_memcpy_big, - m: _emscripten_resize_heap, - f: _fd_close, - j: _fd_fdstat_get, - g: _fd_read, - n: _fd_seek, - d: _fd_write, - a: _setTempRet0, - b: _time, - t: _timegm - }; - var asm = createWasm(); - Module["___wasm_call_ctors"] = asm["v"]; - Module["_zip_ext_count_symlinks"] = asm["w"]; - Module["_zip_file_get_external_attributes"] = asm["x"]; - Module["_zipstruct_stat"] = asm["y"]; - Module["_zipstruct_statS"] = asm["z"]; - Module["_zipstruct_stat_name"] = asm["A"]; - Module["_zipstruct_stat_index"] = asm["B"]; - Module["_zipstruct_stat_size"] = asm["C"]; - Module["_zipstruct_stat_mtime"] = asm["D"]; - Module["_zipstruct_stat_crc"] = asm["E"]; - Module["_zipstruct_error"] = asm["F"]; - Module["_zipstruct_errorS"] = asm["G"]; - Module["_zipstruct_error_code_zip"] = asm["H"]; - Module["_zipstruct_stat_comp_size"] = asm["I"]; - Module["_zipstruct_stat_comp_method"] = asm["J"]; - Module["_zip_close"] = asm["K"]; - Module["_zip_delete"] = asm["L"]; - Module["_zip_dir_add"] = asm["M"]; - Module["_zip_discard"] = asm["N"]; - Module["_zip_error_init_with_code"] = asm["O"]; - Module["_zip_get_error"] = asm["P"]; - Module["_zip_file_get_error"] = asm["Q"]; - Module["_zip_error_strerror"] = asm["R"]; - Module["_zip_fclose"] = asm["S"]; - Module["_zip_file_add"] = asm["T"]; - Module["_free"] = asm["U"]; - var _malloc = Module["_malloc"] = asm["V"]; - var ___errno_location = Module["___errno_location"] = asm["W"]; - Module["_zip_source_error"] = asm["X"]; - Module["_zip_source_seek"] = asm["Y"]; - Module["_zip_file_set_external_attributes"] = asm["Z"]; - Module["_zip_file_set_mtime"] = asm["_"]; - Module["_zip_fopen"] = asm["$"]; - Module["_zip_fopen_index"] = asm["aa"]; - Module["_zip_fread"] = asm["ba"]; - Module["_zip_get_name"] = asm["ca"]; - Module["_zip_get_num_entries"] = asm["da"]; - Module["_zip_source_read"] = asm["ea"]; - Module["_zip_name_locate"] = asm["fa"]; - Module["_zip_open"] = asm["ga"]; - Module["_zip_open_from_source"] = asm["ha"]; - Module["_zip_set_file_compression"] = asm["ia"]; - Module["_zip_source_buffer"] = asm["ja"]; - Module["_zip_source_buffer_create"] = asm["ka"]; - Module["_zip_source_close"] = asm["la"]; - Module["_zip_source_free"] = asm["ma"]; - Module["_zip_source_keep"] = asm["na"]; - Module["_zip_source_open"] = asm["oa"]; - Module["_zip_source_set_mtime"] = asm["qa"]; - Module["_zip_source_tell"] = asm["ra"]; - Module["_zip_stat"] = asm["sa"]; - Module["_zip_stat_index"] = asm["ta"]; - var __get_tzname = Module["__get_tzname"] = asm["ua"]; - var __get_daylight = Module["__get_daylight"] = asm["va"]; - var __get_timezone = Module["__get_timezone"] = asm["wa"]; - var stackSave = Module["stackSave"] = asm["xa"]; - var stackRestore = Module["stackRestore"] = asm["ya"]; - var stackAlloc = Module["stackAlloc"] = asm["za"]; - Module["cwrap"] = cwrap; - Module["getValue"] = getValue; - var calledRun; - dependenciesFulfilled = function runCaller() { - if (!calledRun) - run(); - if (!calledRun) - dependenciesFulfilled = runCaller; - }; - function run(args) { - if (runDependencies > 0) { - return; - } - preRun(); - if (runDependencies > 0) { - return; - } - function doRun() { - if (calledRun) - return; - calledRun = true; - Module["calledRun"] = true; - if (ABORT) - return; - initRuntime(); - readyPromiseResolve(Module); - if (Module["onRuntimeInitialized"]) - Module["onRuntimeInitialized"](); - postRun(); - } - if (Module["setStatus"]) { - Module["setStatus"]("Running..."); - setTimeout(function() { - setTimeout(function() { - Module["setStatus"](""); - }, 1); - doRun(); - }, 1); - } else { - doRun(); - } - } - Module["run"] = run; - if (Module["preInit"]) { - if (typeof Module["preInit"] == "function") - Module["preInit"] = [Module["preInit"]]; - while (Module["preInit"].length > 0) { - Module["preInit"].pop()(); - } - } - run(); - return createModule2; - }; -}(); -module.exports = createModule; -}(libzipSync)); - -const createModule = libzipSync.exports; - -const number64 = [ - `number`, - `number` -]; -var Errors; -(function(Errors2) { - Errors2[Errors2["ZIP_ER_OK"] = 0] = "ZIP_ER_OK"; - Errors2[Errors2["ZIP_ER_MULTIDISK"] = 1] = "ZIP_ER_MULTIDISK"; - Errors2[Errors2["ZIP_ER_RENAME"] = 2] = "ZIP_ER_RENAME"; - Errors2[Errors2["ZIP_ER_CLOSE"] = 3] = "ZIP_ER_CLOSE"; - Errors2[Errors2["ZIP_ER_SEEK"] = 4] = "ZIP_ER_SEEK"; - Errors2[Errors2["ZIP_ER_READ"] = 5] = "ZIP_ER_READ"; - Errors2[Errors2["ZIP_ER_WRITE"] = 6] = "ZIP_ER_WRITE"; - Errors2[Errors2["ZIP_ER_CRC"] = 7] = "ZIP_ER_CRC"; - Errors2[Errors2["ZIP_ER_ZIPCLOSED"] = 8] = "ZIP_ER_ZIPCLOSED"; - Errors2[Errors2["ZIP_ER_NOENT"] = 9] = "ZIP_ER_NOENT"; - Errors2[Errors2["ZIP_ER_EXISTS"] = 10] = "ZIP_ER_EXISTS"; - Errors2[Errors2["ZIP_ER_OPEN"] = 11] = "ZIP_ER_OPEN"; - Errors2[Errors2["ZIP_ER_TMPOPEN"] = 12] = "ZIP_ER_TMPOPEN"; - Errors2[Errors2["ZIP_ER_ZLIB"] = 13] = "ZIP_ER_ZLIB"; - Errors2[Errors2["ZIP_ER_MEMORY"] = 14] = "ZIP_ER_MEMORY"; - Errors2[Errors2["ZIP_ER_CHANGED"] = 15] = "ZIP_ER_CHANGED"; - Errors2[Errors2["ZIP_ER_COMPNOTSUPP"] = 16] = "ZIP_ER_COMPNOTSUPP"; - Errors2[Errors2["ZIP_ER_EOF"] = 17] = "ZIP_ER_EOF"; - Errors2[Errors2["ZIP_ER_INVAL"] = 18] = "ZIP_ER_INVAL"; - Errors2[Errors2["ZIP_ER_NOZIP"] = 19] = "ZIP_ER_NOZIP"; - Errors2[Errors2["ZIP_ER_INTERNAL"] = 20] = "ZIP_ER_INTERNAL"; - Errors2[Errors2["ZIP_ER_INCONS"] = 21] = "ZIP_ER_INCONS"; - Errors2[Errors2["ZIP_ER_REMOVE"] = 22] = "ZIP_ER_REMOVE"; - Errors2[Errors2["ZIP_ER_DELETED"] = 23] = "ZIP_ER_DELETED"; - Errors2[Errors2["ZIP_ER_ENCRNOTSUPP"] = 24] = "ZIP_ER_ENCRNOTSUPP"; - Errors2[Errors2["ZIP_ER_RDONLY"] = 25] = "ZIP_ER_RDONLY"; - Errors2[Errors2["ZIP_ER_NOPASSWD"] = 26] = "ZIP_ER_NOPASSWD"; - Errors2[Errors2["ZIP_ER_WRONGPASSWD"] = 27] = "ZIP_ER_WRONGPASSWD"; - Errors2[Errors2["ZIP_ER_OPNOTSUPP"] = 28] = "ZIP_ER_OPNOTSUPP"; - Errors2[Errors2["ZIP_ER_INUSE"] = 29] = "ZIP_ER_INUSE"; - Errors2[Errors2["ZIP_ER_TELL"] = 30] = "ZIP_ER_TELL"; - Errors2[Errors2["ZIP_ER_COMPRESSED_DATA"] = 31] = "ZIP_ER_COMPRESSED_DATA"; -})(Errors || (Errors = {})); -const makeInterface = (libzip) => ({ - get HEAP8() { - return libzip.HEAP8; - }, - get HEAPU8() { - return libzip.HEAPU8; - }, - errors: Errors, - 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: libzip._malloc(1), - uint16S: libzip._malloc(2), - uint32S: libzip._malloc(4), - uint64S: libzip._malloc(8), - malloc: libzip._malloc, - free: libzip._free, - getValue: libzip.getValue, - open: libzip.cwrap(`zip_open`, `number`, [`string`, `number`, `number`]), - openFromSource: libzip.cwrap(`zip_open_from_source`, `number`, [`number`, `number`, `number`]), - close: libzip.cwrap(`zip_close`, `number`, [`number`]), - discard: libzip.cwrap(`zip_discard`, null, [`number`]), - getError: libzip.cwrap(`zip_get_error`, `number`, [`number`]), - getName: libzip.cwrap(`zip_get_name`, `string`, [`number`, `number`, `number`]), - getNumEntries: libzip.cwrap(`zip_get_num_entries`, `number`, [`number`, `number`]), - delete: libzip.cwrap(`zip_delete`, `number`, [`number`, `number`]), - stat: libzip.cwrap(`zip_stat`, `number`, [`number`, `string`, `number`, `number`]), - statIndex: libzip.cwrap(`zip_stat_index`, `number`, [`number`, ...number64, `number`, `number`]), - fopen: libzip.cwrap(`zip_fopen`, `number`, [`number`, `string`, `number`]), - fopenIndex: libzip.cwrap(`zip_fopen_index`, `number`, [`number`, ...number64, `number`]), - fread: libzip.cwrap(`zip_fread`, `number`, [`number`, `number`, `number`, `number`]), - fclose: libzip.cwrap(`zip_fclose`, `number`, [`number`]), - dir: { - add: libzip.cwrap(`zip_dir_add`, `number`, [`number`, `string`]) - }, - file: { - add: libzip.cwrap(`zip_file_add`, `number`, [`number`, `string`, `number`, `number`]), - getError: libzip.cwrap(`zip_file_get_error`, `number`, [`number`]), - getExternalAttributes: libzip.cwrap(`zip_file_get_external_attributes`, `number`, [`number`, ...number64, `number`, `number`, `number`]), - setExternalAttributes: libzip.cwrap(`zip_file_set_external_attributes`, `number`, [`number`, ...number64, `number`, `number`, `number`]), - setMtime: libzip.cwrap(`zip_file_set_mtime`, `number`, [`number`, ...number64, `number`, `number`]), - setCompression: libzip.cwrap(`zip_set_file_compression`, `number`, [`number`, ...number64, `number`, `number`]) - }, - ext: { - countSymlinks: libzip.cwrap(`zip_ext_count_symlinks`, `number`, [`number`]) - }, - error: { - initWithCode: libzip.cwrap(`zip_error_init_with_code`, null, [`number`, `number`]), - strerror: libzip.cwrap(`zip_error_strerror`, `string`, [`number`]) - }, - name: { - locate: libzip.cwrap(`zip_name_locate`, `number`, [`number`, `string`, `number`]) - }, - source: { - fromUnattachedBuffer: libzip.cwrap(`zip_source_buffer_create`, `number`, [`number`, `number`, `number`, `number`]), - fromBuffer: libzip.cwrap(`zip_source_buffer`, `number`, [`number`, `number`, ...number64, `number`]), - free: libzip.cwrap(`zip_source_free`, null, [`number`]), - keep: libzip.cwrap(`zip_source_keep`, null, [`number`]), - open: libzip.cwrap(`zip_source_open`, `number`, [`number`]), - close: libzip.cwrap(`zip_source_close`, `number`, [`number`]), - seek: libzip.cwrap(`zip_source_seek`, `number`, [`number`, ...number64, `number`]), - tell: libzip.cwrap(`zip_source_tell`, `number`, [`number`]), - read: libzip.cwrap(`zip_source_read`, `number`, [`number`, `number`, `number`]), - error: libzip.cwrap(`zip_source_error`, `number`, [`number`]), - setMtime: libzip.cwrap(`zip_source_set_mtime`, `number`, [`number`, `number`]) - }, - struct: { - stat: libzip.cwrap(`zipstruct_stat`, `number`, []), - statS: libzip.cwrap(`zipstruct_statS`, `number`, []), - statName: libzip.cwrap(`zipstruct_stat_name`, `string`, [`number`]), - statIndex: libzip.cwrap(`zipstruct_stat_index`, `number`, [`number`]), - statSize: libzip.cwrap(`zipstruct_stat_size`, `number`, [`number`]), - statCompSize: libzip.cwrap(`zipstruct_stat_comp_size`, `number`, [`number`]), - statCompMethod: libzip.cwrap(`zipstruct_stat_comp_method`, `number`, [`number`]), - statMtime: libzip.cwrap(`zipstruct_stat_mtime`, `number`, [`number`]), - statCrc: libzip.cwrap(`zipstruct_stat_crc`, `number`, [`number`]), - error: libzip.cwrap(`zipstruct_error`, `number`, []), - errorS: libzip.cwrap(`zipstruct_errorS`, `number`, []), - errorCodeZip: libzip.cwrap(`zipstruct_error_code_zip`, `number`, [`number`]) - } -}); - -let mod = null; -function getLibzipSync() { - if (mod === null) - mod = makeInterface(createModule()); - return mod; -} - -var __defProp$2 = Object.defineProperty; -var __defProps$1 = Object.defineProperties; -var __getOwnPropDescs$1 = Object.getOwnPropertyDescriptors; -var __getOwnPropSymbols$3 = Object.getOwnPropertySymbols; -var __hasOwnProp$3 = Object.prototype.hasOwnProperty; -var __propIsEnum$3 = Object.prototype.propertyIsEnumerable; -var __defNormalProp$2 = (obj, key, value) => key in obj ? __defProp$2(obj, key, {enumerable: true, configurable: true, writable: true, value}) : obj[key] = value; -var __spreadValues$2 = (a, b) => { - for (var prop in b || (b = {})) - if (__hasOwnProp$3.call(b, prop)) - __defNormalProp$2(a, prop, b[prop]); - if (__getOwnPropSymbols$3) - for (var prop of __getOwnPropSymbols$3(b)) { - if (__propIsEnum$3.call(b, prop)) - __defNormalProp$2(a, prop, b[prop]); - } - return a; -}; -var __spreadProps$1 = (a, b) => __defProps$1(a, __getOwnPropDescs$1(b)); -var ErrorCode; -(function(ErrorCode2) { - ErrorCode2["API_ERROR"] = `API_ERROR`; - ErrorCode2["BUILTIN_NODE_RESOLUTION_FAILED"] = `BUILTIN_NODE_RESOLUTION_FAILED`; - ErrorCode2["EXPORTS_RESOLUTION_FAILED"] = `EXPORTS_RESOLUTION_FAILED`; - ErrorCode2["MISSING_DEPENDENCY"] = `MISSING_DEPENDENCY`; - ErrorCode2["MISSING_PEER_DEPENDENCY"] = `MISSING_PEER_DEPENDENCY`; - ErrorCode2["QUALIFIED_PATH_RESOLUTION_FAILED"] = `QUALIFIED_PATH_RESOLUTION_FAILED`; - ErrorCode2["INTERNAL"] = `INTERNAL`; - ErrorCode2["UNDECLARED_DEPENDENCY"] = `UNDECLARED_DEPENDENCY`; - ErrorCode2["UNSUPPORTED"] = `UNSUPPORTED`; -})(ErrorCode || (ErrorCode = {})); -const MODULE_NOT_FOUND_ERRORS = new Set([ - ErrorCode.BUILTIN_NODE_RESOLUTION_FAILED, - ErrorCode.MISSING_DEPENDENCY, - ErrorCode.MISSING_PEER_DEPENDENCY, - ErrorCode.QUALIFIED_PATH_RESOLUTION_FAILED, - ErrorCode.UNDECLARED_DEPENDENCY -]); -function makeError(pnpCode, message, data = {}, code) { - code != null ? code : code = MODULE_NOT_FOUND_ERRORS.has(pnpCode) ? `MODULE_NOT_FOUND` : pnpCode; - const propertySpec = { - configurable: true, - writable: true, - enumerable: false - }; - return Object.defineProperties(new Error(message), { - code: __spreadProps$1(__spreadValues$2({}, propertySpec), { - value: code - }), - pnpCode: __spreadProps$1(__spreadValues$2({}, propertySpec), { - value: pnpCode - }), - data: __spreadProps$1(__spreadValues$2({}, propertySpec), { - value: data - }) - }); -} -function getIssuerModule(parent) { - let issuer = parent; - while (issuer && (issuer.id === `[eval]` || issuer.id === `` || !issuer.filename)) - issuer = issuer.parent; - return issuer || null; -} -function getPathForDisplay(p) { - return npath.normalize(npath.fromPortablePath(p)); -} - -const builtinModules = new Set(require$$0.Module.builtinModules || Object.keys(process.binding(`natives`))); -const isBuiltinModule = (request) => request.startsWith(`node:`) || builtinModules.has(request); -function readPackageScope(checkPath) { - const rootSeparatorIndex = checkPath.indexOf(npath.sep); - let separatorIndex; - do { - separatorIndex = checkPath.lastIndexOf(npath.sep); - checkPath = checkPath.slice(0, separatorIndex); - if (checkPath.endsWith(`${npath.sep}node_modules`)) - return false; - const pjson = readPackage(checkPath + npath.sep); - if (pjson) { - return { - data: pjson, - path: checkPath - }; - } - } while (separatorIndex > rootSeparatorIndex); - return false; -} -function readPackage(requestPath) { - const jsonPath = npath.resolve(requestPath, `package.json`); - if (!fs__default.default.existsSync(jsonPath)) - return null; - return JSON.parse(fs__default.default.readFileSync(jsonPath, `utf8`)); -} -function ERR_REQUIRE_ESM(filename, parentPath = null) { - const basename = parentPath && path__default.default.basename(filename) === path__default.default.basename(parentPath) ? filename : path__default.default.basename(filename); - const msg = `require() of ES Module ${filename}${parentPath ? ` from ${parentPath}` : ``} not supported. -Instead change the require of ${basename} in ${parentPath} to a dynamic import() which is available in all CommonJS modules.`; - const err = new Error(msg); - err.code = `ERR_REQUIRE_ESM`; - return err; -} - -var __getOwnPropSymbols$2 = Object.getOwnPropertySymbols; -var __hasOwnProp$2 = Object.prototype.hasOwnProperty; -var __propIsEnum$2 = Object.prototype.propertyIsEnumerable; -var __objRest$1 = (source, exclude) => { - var target = {}; - for (var prop in source) - if (__hasOwnProp$2.call(source, prop) && exclude.indexOf(prop) < 0) - target[prop] = source[prop]; - if (source != null && __getOwnPropSymbols$2) - for (var prop of __getOwnPropSymbols$2(source)) { - if (exclude.indexOf(prop) < 0 && __propIsEnum$2.call(source, prop)) - target[prop] = source[prop]; - } - return target; -}; -function applyPatch(pnpapi, opts) { - const defaultCache = {}; - let enableNativeHooks = true; - process.versions.pnp = String(pnpapi.VERSIONS.std); - const moduleExports = require$$0__default.default; - moduleExports.findPnpApi = (lookupSource) => { - const lookupPath = lookupSource instanceof url.URL ? url.fileURLToPath(lookupSource) : lookupSource; - const apiPath = opts.manager.findApiPathFor(lookupPath); - if (apiPath === null) - return null; - const apiEntry = opts.manager.getApiEntry(apiPath, true); - return apiEntry.instance.findPackageLocator(lookupPath) ? apiEntry.instance : null; - }; - function getRequireStack(parent) { - const requireStack = []; - for (let cursor = parent; cursor; cursor = cursor.parent) - requireStack.push(cursor.filename || cursor.id); - return requireStack; - } - const originalModuleLoad = require$$0.Module._load; - require$$0.Module._load = function(request, parent, isMain) { - if (!enableNativeHooks) - return originalModuleLoad.call(require$$0.Module, request, parent, isMain); - if (isBuiltinModule(request)) { - try { - enableNativeHooks = false; - return originalModuleLoad.call(require$$0.Module, request, parent, isMain); - } finally { - enableNativeHooks = true; - } - } - const parentApiPath = opts.manager.getApiPathFromParent(parent); - const parentApi = parentApiPath !== null ? opts.manager.getApiEntry(parentApiPath, true).instance : null; - if (parentApi === null) - return originalModuleLoad(request, parent, isMain); - if (request === `pnpapi`) - return parentApi; - const modulePath = require$$0.Module._resolveFilename(request, parent, isMain); - const isOwnedByRuntime = parentApi !== null ? parentApi.findPackageLocator(modulePath) !== null : false; - const moduleApiPath = isOwnedByRuntime ? parentApiPath : opts.manager.findApiPathFor(npath.dirname(modulePath)); - const entry = moduleApiPath !== null ? opts.manager.getApiEntry(moduleApiPath) : {instance: null, cache: defaultCache}; - const cacheEntry = entry.cache[modulePath]; - if (cacheEntry) { - if (cacheEntry.loaded === false && cacheEntry.isLoading !== true) { - try { - cacheEntry.isLoading = true; - if (isMain) { - process.mainModule = cacheEntry; - cacheEntry.id = `.`; - } - cacheEntry.load(modulePath); - } finally { - cacheEntry.isLoading = false; - } - } - return cacheEntry.exports; - } - const module = new require$$0.Module(modulePath, parent != null ? parent : void 0); - module.pnpApiPath = moduleApiPath; - entry.cache[modulePath] = module; - if (isMain) { - process.mainModule = module; - module.id = `.`; - } - let hasThrown = true; - try { - module.isLoading = true; - module.load(modulePath); - hasThrown = false; - } finally { - module.isLoading = false; - if (hasThrown) { - delete require$$0.Module._cache[modulePath]; - } - } - return module.exports; - }; - function getIssuerSpecsFromPaths(paths) { - return paths.map((path) => ({ - apiPath: opts.manager.findApiPathFor(path), - path, - module: null - })); - } - function getIssuerSpecsFromModule(module) { - var _a; - if (module && module.id !== `` && module.id !== `internal/preload` && !module.parent && !module.filename && module.paths.length > 0) { - return [{ - apiPath: opts.manager.findApiPathFor(module.paths[0]), - path: module.paths[0], - module - }]; - } - const issuer = getIssuerModule(module); - if (issuer !== null) { - const path = npath.dirname(issuer.filename); - const apiPath = opts.manager.getApiPathFromParent(issuer); - return [{apiPath, path, module}]; - } else { - const path = process.cwd(); - const apiPath = (_a = opts.manager.findApiPathFor(npath.join(path, `[file]`))) != null ? _a : opts.manager.getApiPathFromParent(null); - return [{apiPath, path, module}]; - } - } - function makeFakeParent(path) { - const fakeParent = new require$$0.Module(``); - const fakeFilePath = npath.join(path, `[file]`); - fakeParent.paths = require$$0.Module._nodeModulePaths(fakeFilePath); - return fakeParent; - } - const pathRegExp = /^(?![a-zA-Z]:[\\/]|\\\\|\.{0,2}(?:\/|$))((?:@[^/]+\/)?[^/]+)\/*(.*|)$/; - const originalModuleResolveFilename = require$$0.Module._resolveFilename; - require$$0.Module._resolveFilename = function(request, parent, isMain, options) { - if (isBuiltinModule(request)) - return request; - if (!enableNativeHooks) - return originalModuleResolveFilename.call(require$$0.Module, request, parent, isMain, options); - if (options && options.plugnplay === false) { - const _a = options, rest = __objRest$1(_a, ["plugnplay"]); - const forwardedOptions = Object.keys(rest).length > 0 ? rest : void 0; - try { - enableNativeHooks = false; - return originalModuleResolveFilename.call(require$$0.Module, request, parent, isMain, forwardedOptions); - } finally { - enableNativeHooks = true; - } - } - if (options) { - const optionNames = new Set(Object.keys(options)); - optionNames.delete(`paths`); - optionNames.delete(`plugnplay`); - if (optionNames.size > 0) { - throw makeError(ErrorCode.UNSUPPORTED, `Some options passed to require() aren't supported by PnP yet (${Array.from(optionNames).join(`, `)})`); - } - } - const issuerSpecs = options && options.paths ? getIssuerSpecsFromPaths(options.paths) : getIssuerSpecsFromModule(parent); - if (request.match(pathRegExp) === null) { - const parentDirectory = (parent == null ? void 0 : parent.filename) != null ? npath.dirname(parent.filename) : null; - const absoluteRequest = npath.isAbsolute(request) ? request : parentDirectory !== null ? npath.resolve(parentDirectory, request) : null; - if (absoluteRequest !== null) { - const apiPath = parentDirectory === npath.dirname(absoluteRequest) && (parent == null ? void 0 : parent.pnpApiPath) ? parent.pnpApiPath : opts.manager.findApiPathFor(absoluteRequest); - if (apiPath !== null) { - issuerSpecs.unshift({ - apiPath, - path: parentDirectory, - module: null - }); - } - } - } - let firstError; - for (const {apiPath, path, module} of issuerSpecs) { - let resolution; - const issuerApi = apiPath !== null ? opts.manager.getApiEntry(apiPath, true).instance : null; - try { - if (issuerApi !== null) { - resolution = issuerApi.resolveRequest(request, path !== null ? `${path}/` : null); - } else { - if (path === null) - throw new Error(`Assertion failed: Expected the path to be set`); - resolution = originalModuleResolveFilename.call(require$$0.Module, request, module || makeFakeParent(path), isMain); - } - } catch (error) { - firstError = firstError || error; - continue; - } - if (resolution !== null) { - return resolution; - } - } - const requireStack = getRequireStack(parent); - Object.defineProperty(firstError, `requireStack`, { - configurable: true, - writable: true, - enumerable: false, - value: requireStack - }); - if (requireStack.length > 0) - firstError.message += ` -Require stack: -- ${requireStack.join(` -- `)}`; - if (typeof firstError.pnpCode === `string`) - Error.captureStackTrace(firstError); - throw firstError; - }; - const originalFindPath = require$$0.Module._findPath; - require$$0.Module._findPath = function(request, paths, isMain) { - if (request === `pnpapi`) - return false; - if (!enableNativeHooks) - return originalFindPath.call(require$$0.Module, request, paths, isMain); - const isAbsolute = npath.isAbsolute(request); - if (isAbsolute) - paths = [``]; - else if (!paths || paths.length === 0) - return false; - for (const path of paths) { - let resolution; - try { - const pnpApiPath = opts.manager.findApiPathFor(isAbsolute ? request : path); - if (pnpApiPath !== null) { - const api = opts.manager.getApiEntry(pnpApiPath, true).instance; - resolution = api.resolveRequest(request, path) || false; - } else { - resolution = originalFindPath.call(require$$0.Module, request, [path], isMain); - } - } catch (error) { - continue; - } - if (resolution) { - return resolution; - } - } - return false; - }; - const originalExtensionJSFunction = require$$0.Module._extensions[`.js`]; - require$$0.Module._extensions[`.js`] = function(module, filename) { - var _a, _b; - if (filename.endsWith(`.js`)) { - const pkg = readPackageScope(filename); - if (pkg && ((_a = pkg.data) == null ? void 0 : _a.type) === `module`) { - const err = ERR_REQUIRE_ESM(filename, (_b = module.parent) == null ? void 0 : _b.filename); - Error.captureStackTrace(err); - throw err; - } - } - originalExtensionJSFunction.call(this, module, filename); - }; - const originalDlopen = process.dlopen; - process.dlopen = function(...args) { - const [module, filename, ...rest] = args; - return originalDlopen.call(this, module, npath.fromPortablePath(VirtualFS.resolveVirtual(npath.toPortablePath(filename))), ...rest); - }; - const originalEmit = process.emit; - process.emit = function(name, data, ...args) { - if (name === `warning` && typeof data === `object` && data.name === `ExperimentalWarning` && (data.message.includes(`--experimental-loader`) || data.message.includes(`Custom ESM Loaders is an experimental feature`))) - return false; - return originalEmit.apply(process, arguments); - }; - patchFs(fs__default.default, new PosixFS(opts.fakeFs)); -} - -function hydrateRuntimeState(data, {basePath}) { - const portablePath = npath.toPortablePath(basePath); - const absolutePortablePath = ppath.resolve(portablePath); - const ignorePattern = data.ignorePatternData !== null ? new RegExp(data.ignorePatternData) : null; - const packageLocatorsByLocations = new Map(); - const packageRegistry = new Map(data.packageRegistryData.map(([packageName, packageStoreData]) => { - return [packageName, new Map(packageStoreData.map(([packageReference, packageInformationData]) => { - var _a; - if (packageName === null !== (packageReference === null)) - throw new Error(`Assertion failed: The name and reference should be null, or neither should`); - const discardFromLookup = (_a = packageInformationData.discardFromLookup) != null ? _a : false; - const packageLocator = {name: packageName, reference: packageReference}; - const entry = packageLocatorsByLocations.get(packageInformationData.packageLocation); - if (!entry) { - packageLocatorsByLocations.set(packageInformationData.packageLocation, {locator: packageLocator, discardFromLookup}); - } else { - entry.discardFromLookup = entry.discardFromLookup && discardFromLookup; - if (!discardFromLookup) { - entry.locator = packageLocator; - } - } - let resolvedPackageLocation = null; - return [packageReference, { - packageDependencies: new Map(packageInformationData.packageDependencies), - packagePeers: new Set(packageInformationData.packagePeers), - linkType: packageInformationData.linkType, - discardFromLookup, - get packageLocation() { - return resolvedPackageLocation || (resolvedPackageLocation = ppath.join(absolutePortablePath, packageInformationData.packageLocation)); - } - }]; - }))]; - })); - const fallbackExclusionList = new Map(data.fallbackExclusionList.map(([packageName, packageReferences]) => { - return [packageName, new Set(packageReferences)]; - })); - const fallbackPool = new Map(data.fallbackPool); - const dependencyTreeRoots = data.dependencyTreeRoots; - const enableTopLevelFallback = data.enableTopLevelFallback; - return { - basePath: portablePath, - dependencyTreeRoots, - enableTopLevelFallback, - fallbackExclusionList, - fallbackPool, - ignorePattern, - packageLocatorsByLocations, - packageRegistry - }; -} - -/** - * @param {object} exports - * @param {Set} keys - */ -function loop(exports, keys) { - if (typeof exports === 'string') { - return exports; - } - - if (exports) { - let idx, tmp; - if (Array.isArray(exports)) { - for (idx=0; idx < exports.length; idx++) { - if (tmp = loop(exports[idx], keys)) return tmp; - } - } else { - for (idx in exports) { - if (keys.has(idx)) { - return loop(exports[idx], keys); - } - } - } - } -} - -/** - * @param {string} name The package name - * @param {string} entry The target entry, eg "." - * @param {number} [condition] Unmatched condition? - */ -function bail(name, entry, condition) { - throw new Error( - condition - ? `No known conditions for "${entry}" entry in "${name}" package` - : `Missing "${entry}" export in "${name}" package` - ); -} - -/** - * @param {string} name the package name - * @param {string} entry the target path/import - */ -function toName(name, entry) { - return entry === name ? '.' - : entry[0] === '.' ? entry - : entry.replace(new RegExp('^' + name + '\/'), './'); -} - -/** - * @param {object} pkg package.json contents - * @param {string} [entry] entry name or import path - * @param {object} [options] - * @param {boolean} [options.browser] - * @param {boolean} [options.require] - * @param {string[]} [options.conditions] - * @param {boolean} [options.unsafe] - */ -function resolve(pkg, entry='.', options={}) { - let { name, exports } = pkg; - - if (exports) { - let { browser, require, unsafe, conditions=[] } = options; - - let target = toName(name, entry); - if (target[0] !== '.') target = './' + target; - - if (typeof exports === 'string') { - return target === '.' ? exports : bail(name, target); - } - - let allows = new Set(['default', ...conditions]); - unsafe || allows.add(require ? 'require' : 'import'); - unsafe || allows.add(browser ? 'browser' : 'node'); - - let key, tmp, isSingle=false; - - for (key in exports) { - isSingle = key[0] !== '.'; - break; - } - - if (isSingle) { - return target === '.' - ? loop(exports, allows) || bail(name, target, 1) - : bail(name, target); - } - - if (tmp = exports[target]) { - return loop(tmp, allows) || bail(name, target, 1); - } - - for (key in exports) { - tmp = key[key.length - 1]; - if (tmp === '/' && target.startsWith(key)) { - return (tmp = loop(exports[key], allows)) - ? (tmp + target.substring(key.length)) - : bail(name, target, 1); - } - if (tmp === '*' && target.startsWith(key.slice(0, -1))) { - // do not trigger if no *content* to inject - if (target.substring(key.length - 1).length > 0) { - return (tmp = loop(exports[key], allows)) - ? tmp.replace('*', target.substring(key.length - 1)) - : bail(name, target, 1); - } - } - } - - return bail(name, target); - } -} - -var __defProp$1 = Object.defineProperty; -var __defProps = Object.defineProperties; -var __getOwnPropDescs = Object.getOwnPropertyDescriptors; -var __getOwnPropSymbols$1 = Object.getOwnPropertySymbols; -var __hasOwnProp$1 = Object.prototype.hasOwnProperty; -var __propIsEnum$1 = Object.prototype.propertyIsEnumerable; -var __defNormalProp$1 = (obj, key, value) => key in obj ? __defProp$1(obj, key, {enumerable: true, configurable: true, writable: true, value}) : obj[key] = value; -var __spreadValues$1 = (a, b) => { - for (var prop in b || (b = {})) - if (__hasOwnProp$1.call(b, prop)) - __defNormalProp$1(a, prop, b[prop]); - if (__getOwnPropSymbols$1) - for (var prop of __getOwnPropSymbols$1(b)) { - if (__propIsEnum$1.call(b, prop)) - __defNormalProp$1(a, prop, b[prop]); - } - return a; -}; -var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b)); -function makeApi(runtimeState, opts) { - const alwaysWarnOnFallback = Number(process.env.PNP_ALWAYS_WARN_ON_FALLBACK) > 0; - const debugLevel = Number(process.env.PNP_DEBUG_LEVEL); - const pathRegExp = /^(?![a-zA-Z]:[\\/]|\\\\|\.{0,2}(?:\/|$))((?:node:)?(?:@[^/]+\/)?[^/]+)\/*(.*|)$/; - const isStrictRegExp = /^(\/|\.{1,2}(\/|$))/; - const isDirRegExp = /\/$/; - const isRelativeRegexp = /^\.{0,2}\//; - const topLevelLocator = {name: null, reference: null}; - const fallbackLocators = []; - const emittedWarnings = new Set(); - if (runtimeState.enableTopLevelFallback === true) - fallbackLocators.push(topLevelLocator); - if (opts.compatibilityMode !== false) { - for (const name of [`react-scripts`, `gatsby`]) { - const packageStore = runtimeState.packageRegistry.get(name); - if (packageStore) { - for (const reference of packageStore.keys()) { - if (reference === null) { - throw new Error(`Assertion failed: This reference shouldn't be null`); - } else { - fallbackLocators.push({name, reference}); - } - } - } - } - } - const { - ignorePattern, - packageRegistry, - packageLocatorsByLocations - } = runtimeState; - function makeLogEntry(name, args) { - return { - fn: name, - args, - error: null, - result: null - }; - } - function trace(entry) { - var _a, _b, _c, _d, _e, _f; - const colors = (_c = (_b = (_a = process.stderr) == null ? void 0 : _a.hasColors) == null ? void 0 : _b.call(_a)) != null ? _c : process.stdout.isTTY; - const c = (n, str) => `[${n}m${str}`; - const error = entry.error; - if (error) - console.error(c(`31;1`, `\u2716 ${(_d = entry.error) == null ? void 0 : _d.message.replace(/\n.*/s, ``)}`)); - else - console.error(c(`33;1`, `\u203C Resolution`)); - if (entry.args.length > 0) - console.error(); - for (const arg of entry.args) - console.error(` ${c(`37;1`, `In \u2190`)} ${nodeUtils.inspect(arg, {colors, compact: true})}`); - if (entry.result) { - console.error(); - console.error(` ${c(`37;1`, `Out \u2192`)} ${nodeUtils.inspect(entry.result, {colors, compact: true})}`); - } - const stack = (_f = (_e = new Error().stack.match(/(?<=^ +)at.*/gm)) == null ? void 0 : _e.slice(2)) != null ? _f : []; - if (stack.length > 0) { - console.error(); - for (const line of stack) { - console.error(` ${c(`38;5;244`, line)}`); - } - } - console.error(); - } - function maybeLog(name, fn) { - if (opts.allowDebug === false) - return fn; - if (Number.isFinite(debugLevel)) { - if (debugLevel >= 2) { - return (...args) => { - const logEntry = makeLogEntry(name, args); - try { - return logEntry.result = fn(...args); - } catch (error) { - throw logEntry.error = error; - } finally { - trace(logEntry); - } - }; - } else if (debugLevel >= 1) { - return (...args) => { - try { - return fn(...args); - } catch (error) { - const logEntry = makeLogEntry(name, args); - logEntry.error = error; - trace(logEntry); - throw error; - } - }; - } - } - return fn; - } - function getPackageInformationSafe(packageLocator) { - const packageInformation = getPackageInformation(packageLocator); - if (!packageInformation) { - throw makeError(ErrorCode.INTERNAL, `Couldn't find a matching entry in the dependency tree for the specified parent (this is probably an internal error)`); - } - return packageInformation; - } - function isDependencyTreeRoot(packageLocator) { - if (packageLocator.name === null) - return true; - for (const dependencyTreeRoot of runtimeState.dependencyTreeRoots) - if (dependencyTreeRoot.name === packageLocator.name && dependencyTreeRoot.reference === packageLocator.reference) - return true; - return false; - } - const defaultExportsConditions = new Set([`default`, `node`, `require`]); - function applyNodeExportsResolution(unqualifiedPath, conditions = defaultExportsConditions) { - const locator = findPackageLocator(ppath.join(unqualifiedPath, `internal.js`), { - resolveIgnored: true, - includeDiscardFromLookup: true - }); - if (locator === null) { - throw makeError(ErrorCode.INTERNAL, `The locator that owns the "${unqualifiedPath}" path can't be found inside the dependency tree (this is probably an internal error)`); - } - const {packageLocation} = getPackageInformationSafe(locator); - const manifestPath = ppath.join(packageLocation, Filename.manifest); - if (!opts.fakeFs.existsSync(manifestPath)) - return null; - const pkgJson = JSON.parse(opts.fakeFs.readFileSync(manifestPath, `utf8`)); - let subpath = ppath.contains(packageLocation, unqualifiedPath); - if (subpath === null) { - throw makeError(ErrorCode.INTERNAL, `unqualifiedPath doesn't contain the packageLocation (this is probably an internal error)`); - } - if (!isRelativeRegexp.test(subpath)) - subpath = `./${subpath}`; - let resolvedExport; - try { - resolvedExport = resolve(pkgJson, ppath.normalize(subpath), { - conditions, - unsafe: true - }); - } catch (error) { - throw makeError(ErrorCode.EXPORTS_RESOLUTION_FAILED, error.message, {unqualifiedPath: getPathForDisplay(unqualifiedPath), locator, pkgJson, subpath: getPathForDisplay(subpath), conditions}, `ERR_PACKAGE_PATH_NOT_EXPORTED`); - } - if (typeof resolvedExport === `string`) - return ppath.join(packageLocation, resolvedExport); - return null; - } - function applyNodeExtensionResolution(unqualifiedPath, candidates, {extensions}) { - let stat; - try { - candidates.push(unqualifiedPath); - stat = opts.fakeFs.statSync(unqualifiedPath); - } catch (error) { - } - if (stat && !stat.isDirectory()) - return opts.fakeFs.realpathSync(unqualifiedPath); - if (stat && stat.isDirectory()) { - let pkgJson; - try { - pkgJson = JSON.parse(opts.fakeFs.readFileSync(ppath.join(unqualifiedPath, Filename.manifest), `utf8`)); - } catch (error) { - } - let nextUnqualifiedPath; - if (pkgJson && pkgJson.main) - nextUnqualifiedPath = ppath.resolve(unqualifiedPath, pkgJson.main); - if (nextUnqualifiedPath && nextUnqualifiedPath !== unqualifiedPath) { - const resolution = applyNodeExtensionResolution(nextUnqualifiedPath, candidates, {extensions}); - if (resolution !== null) { - return resolution; - } - } - } - for (let i = 0, length = extensions.length; i < length; i++) { - const candidateFile = `${unqualifiedPath}${extensions[i]}`; - candidates.push(candidateFile); - if (opts.fakeFs.existsSync(candidateFile)) { - return candidateFile; - } - } - if (stat && stat.isDirectory()) { - for (let i = 0, length = extensions.length; i < length; i++) { - const candidateFile = ppath.format({dir: unqualifiedPath, name: `index`, ext: extensions[i]}); - candidates.push(candidateFile); - if (opts.fakeFs.existsSync(candidateFile)) { - return candidateFile; - } - } - } - return null; - } - function makeFakeModule(path) { - const fakeModule = new require$$0.Module(path, null); - fakeModule.filename = path; - fakeModule.paths = require$$0.Module._nodeModulePaths(path); - return fakeModule; - } - function callNativeResolution(request, issuer) { - if (issuer.endsWith(`/`)) - issuer = ppath.join(issuer, `internal.js`); - return require$$0.Module._resolveFilename(npath.fromPortablePath(request), makeFakeModule(npath.fromPortablePath(issuer)), false, {plugnplay: false}); - } - function isPathIgnored(path) { - if (ignorePattern === null) - return false; - const subPath = ppath.contains(runtimeState.basePath, path); - if (subPath === null) - return false; - if (ignorePattern.test(subPath.replace(/\/$/, ``))) { - return true; - } else { - return false; - } - } - const VERSIONS = {std: 3, resolveVirtual: 1, getAllLocators: 1}; - const topLevel = topLevelLocator; - function getPackageInformation({name, reference}) { - const packageInformationStore = packageRegistry.get(name); - if (!packageInformationStore) - return null; - const packageInformation = packageInformationStore.get(reference); - if (!packageInformation) - return null; - return packageInformation; - } - function findPackageDependents({name, reference}) { - const dependents = []; - for (const [dependentName, packageInformationStore] of packageRegistry) { - if (dependentName === null) - continue; - for (const [dependentReference, packageInformation] of packageInformationStore) { - if (dependentReference === null) - continue; - const dependencyReference = packageInformation.packageDependencies.get(name); - if (dependencyReference !== reference) - continue; - if (dependentName === name && dependentReference === reference) - continue; - dependents.push({ - name: dependentName, - reference: dependentReference - }); - } - } - return dependents; - } - function findBrokenPeerDependencies(dependency, initialPackage) { - const brokenPackages = new Map(); - const alreadyVisited = new Set(); - const traversal = (currentPackage) => { - const identifier = JSON.stringify(currentPackage.name); - if (alreadyVisited.has(identifier)) - return; - alreadyVisited.add(identifier); - const dependents = findPackageDependents(currentPackage); - for (const dependent of dependents) { - const dependentInformation = getPackageInformationSafe(dependent); - if (dependentInformation.packagePeers.has(dependency)) { - traversal(dependent); - } else { - let brokenSet = brokenPackages.get(dependent.name); - if (typeof brokenSet === `undefined`) - brokenPackages.set(dependent.name, brokenSet = new Set()); - brokenSet.add(dependent.reference); - } - } - }; - traversal(initialPackage); - const brokenList = []; - for (const name of [...brokenPackages.keys()].sort()) - for (const reference of [...brokenPackages.get(name)].sort()) - brokenList.push({name, reference}); - return brokenList; - } - function findPackageLocator(location, {resolveIgnored = false, includeDiscardFromLookup = false} = {}) { - if (isPathIgnored(location) && !resolveIgnored) - return null; - let relativeLocation = ppath.relative(runtimeState.basePath, location); - if (!relativeLocation.match(isStrictRegExp)) - relativeLocation = `./${relativeLocation}`; - if (!relativeLocation.endsWith(`/`)) - relativeLocation = `${relativeLocation}/`; - do { - const entry = packageLocatorsByLocations.get(relativeLocation); - if (typeof entry === `undefined` || entry.discardFromLookup && !includeDiscardFromLookup) { - relativeLocation = relativeLocation.substring(0, relativeLocation.lastIndexOf(`/`, relativeLocation.length - 2) + 1); - continue; - } - return entry.locator; - } while (relativeLocation !== ``); - return null; - } - function resolveToUnqualified(request, issuer, {considerBuiltins = true} = {}) { - if (request === `pnpapi`) - return npath.toPortablePath(opts.pnpapiResolution); - if (considerBuiltins && isBuiltinModule(request)) - return null; - const requestForDisplay = getPathForDisplay(request); - const issuerForDisplay = issuer && getPathForDisplay(issuer); - if (issuer && isPathIgnored(issuer)) { - if (!ppath.isAbsolute(request) || findPackageLocator(request) === null) { - const result = callNativeResolution(request, issuer); - if (result === false) { - throw makeError(ErrorCode.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: "${requestForDisplay}" -Required by: ${issuerForDisplay} -`, {request: requestForDisplay, issuer: issuerForDisplay}); - } - return npath.toPortablePath(result); - } - } - let unqualifiedPath; - const dependencyNameMatch = request.match(pathRegExp); - if (!dependencyNameMatch) { - if (ppath.isAbsolute(request)) { - unqualifiedPath = ppath.normalize(request); - } else { - if (!issuer) { - throw makeError(ErrorCode.API_ERROR, `The resolveToUnqualified function must be called with a valid issuer when the path isn't a builtin nor absolute`, {request: requestForDisplay, issuer: issuerForDisplay}); - } - const absoluteIssuer = ppath.resolve(issuer); - if (issuer.match(isDirRegExp)) { - unqualifiedPath = ppath.normalize(ppath.join(absoluteIssuer, request)); - } else { - unqualifiedPath = ppath.normalize(ppath.join(ppath.dirname(absoluteIssuer), request)); - } - } - } else { - if (!issuer) { - throw makeError(ErrorCode.API_ERROR, `The resolveToUnqualified function must be called with a valid issuer when the path isn't a builtin nor absolute`, {request: requestForDisplay, issuer: issuerForDisplay}); - } - const [, dependencyName, subPath] = dependencyNameMatch; - const issuerLocator = findPackageLocator(issuer); - if (!issuerLocator) { - const result = callNativeResolution(request, issuer); - if (result === false) { - throw makeError(ErrorCode.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: "${requestForDisplay}" -Required by: ${issuerForDisplay} -`, {request: requestForDisplay, issuer: issuerForDisplay}); - } - return npath.toPortablePath(result); - } - const issuerInformation = getPackageInformationSafe(issuerLocator); - let dependencyReference = issuerInformation.packageDependencies.get(dependencyName); - let fallbackReference = null; - if (dependencyReference == null) { - if (issuerLocator.name !== null) { - const exclusionEntry = runtimeState.fallbackExclusionList.get(issuerLocator.name); - const canUseFallbacks = !exclusionEntry || !exclusionEntry.has(issuerLocator.reference); - if (canUseFallbacks) { - for (let t = 0, T = fallbackLocators.length; t < T; ++t) { - const fallbackInformation = getPackageInformationSafe(fallbackLocators[t]); - const reference = fallbackInformation.packageDependencies.get(dependencyName); - if (reference == null) - continue; - if (alwaysWarnOnFallback) - fallbackReference = reference; - else - dependencyReference = reference; - break; - } - if (runtimeState.enableTopLevelFallback) { - if (dependencyReference == null && fallbackReference === null) { - const reference = runtimeState.fallbackPool.get(dependencyName); - if (reference != null) { - fallbackReference = reference; - } - } - } - } - } - } - let error = null; - if (dependencyReference === null) { - if (isDependencyTreeRoot(issuerLocator)) { - error = makeError(ErrorCode.MISSING_PEER_DEPENDENCY, `Your application tried to access ${dependencyName} (a peer dependency); this isn't allowed as there is no ancestor to satisfy the requirement. Use a devDependency if needed. - -Required package: ${dependencyName}${dependencyName !== requestForDisplay ? ` (via "${requestForDisplay}")` : ``} -Required by: ${issuerForDisplay} -`, {request: requestForDisplay, issuer: issuerForDisplay, dependencyName}); - } else { - const brokenAncestors = findBrokenPeerDependencies(dependencyName, issuerLocator); - if (brokenAncestors.every((ancestor) => isDependencyTreeRoot(ancestor))) { - error = makeError(ErrorCode.MISSING_PEER_DEPENDENCY, `${issuerLocator.name} tried to access ${dependencyName} (a peer dependency) but it isn't provided by your application; this makes the require call ambiguous and unsound. - -Required package: ${dependencyName}${dependencyName !== requestForDisplay ? ` (via "${requestForDisplay}")` : ``} -Required by: ${issuerLocator.name}@${issuerLocator.reference} (via ${issuerForDisplay}) -${brokenAncestors.map((ancestorLocator) => `Ancestor breaking the chain: ${ancestorLocator.name}@${ancestorLocator.reference} -`).join(``)} -`, {request: requestForDisplay, issuer: issuerForDisplay, issuerLocator: Object.assign({}, issuerLocator), dependencyName, brokenAncestors}); - } else { - error = makeError(ErrorCode.MISSING_PEER_DEPENDENCY, `${issuerLocator.name} tried to access ${dependencyName} (a peer dependency) but it isn't provided by its ancestors; this makes the require call ambiguous and unsound. - -Required package: ${dependencyName}${dependencyName !== requestForDisplay ? ` (via "${requestForDisplay}")` : ``} -Required by: ${issuerLocator.name}@${issuerLocator.reference} (via ${issuerForDisplay}) - -${brokenAncestors.map((ancestorLocator) => `Ancestor breaking the chain: ${ancestorLocator.name}@${ancestorLocator.reference} -`).join(``)} -`, {request: requestForDisplay, issuer: issuerForDisplay, issuerLocator: Object.assign({}, issuerLocator), dependencyName, brokenAncestors}); - } - } - } else if (dependencyReference === void 0) { - if (!considerBuiltins && isBuiltinModule(request)) { - if (isDependencyTreeRoot(issuerLocator)) { - error = makeError(ErrorCode.UNDECLARED_DEPENDENCY, `Your application tried to access ${dependencyName}. 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 ${dependencyName} isn't otherwise declared in your dependencies, this makes the require call ambiguous and unsound. - -Required package: ${dependencyName}${dependencyName !== requestForDisplay ? ` (via "${requestForDisplay}")` : ``} -Required by: ${issuerForDisplay} -`, {request: requestForDisplay, issuer: issuerForDisplay, dependencyName}); - } else { - error = makeError(ErrorCode.UNDECLARED_DEPENDENCY, `${issuerLocator.name} tried to access ${dependencyName}. 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 ${dependencyName} isn't otherwise declared in ${issuerLocator.name}'s dependencies, this makes the require call ambiguous and unsound. - -Required package: ${dependencyName}${dependencyName !== requestForDisplay ? ` (via "${requestForDisplay}")` : ``} -Required by: ${issuerForDisplay} -`, {request: requestForDisplay, issuer: issuerForDisplay, issuerLocator: Object.assign({}, issuerLocator), dependencyName}); - } - } else { - if (isDependencyTreeRoot(issuerLocator)) { - error = makeError(ErrorCode.UNDECLARED_DEPENDENCY, `Your application tried to access ${dependencyName}, but it isn't declared in your dependencies; this makes the require call ambiguous and unsound. - -Required package: ${dependencyName}${dependencyName !== requestForDisplay ? ` (via "${requestForDisplay}")` : ``} -Required by: ${issuerForDisplay} -`, {request: requestForDisplay, issuer: issuerForDisplay, dependencyName}); - } else { - error = makeError(ErrorCode.UNDECLARED_DEPENDENCY, `${issuerLocator.name} tried to access ${dependencyName}, but it isn't declared in its dependencies; this makes the require call ambiguous and unsound. - -Required package: ${dependencyName}${dependencyName !== requestForDisplay ? ` (via "${requestForDisplay}")` : ``} -Required by: ${issuerLocator.name}@${issuerLocator.reference} (via ${issuerForDisplay}) -`, {request: requestForDisplay, issuer: issuerForDisplay, issuerLocator: Object.assign({}, issuerLocator), dependencyName}); - } - } - } - if (dependencyReference == null) { - if (fallbackReference === null || error === null) - throw error || new Error(`Assertion failed: Expected an error to have been set`); - dependencyReference = fallbackReference; - const message = error.message.replace(/\n.*/g, ``); - error.message = message; - if (!emittedWarnings.has(message) && debugLevel !== 0) { - emittedWarnings.add(message); - process.emitWarning(error); - } - } - const dependencyLocator = Array.isArray(dependencyReference) ? {name: dependencyReference[0], reference: dependencyReference[1]} : {name: dependencyName, reference: dependencyReference}; - const dependencyInformation = getPackageInformationSafe(dependencyLocator); - if (!dependencyInformation.packageLocation) { - throw makeError(ErrorCode.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: ${dependencyLocator.name}@${dependencyLocator.reference}${dependencyLocator.name !== requestForDisplay ? ` (via "${requestForDisplay}")` : ``} -Required by: ${issuerLocator.name}@${issuerLocator.reference} (via ${issuerForDisplay}) -`, {request: requestForDisplay, issuer: issuerForDisplay, dependencyLocator: Object.assign({}, dependencyLocator)}); - } - const dependencyLocation = dependencyInformation.packageLocation; - if (subPath) { - unqualifiedPath = ppath.join(dependencyLocation, subPath); - } else { - unqualifiedPath = dependencyLocation; - } - } - return ppath.normalize(unqualifiedPath); - } - function resolveUnqualifiedExport(request, unqualifiedPath, conditions = defaultExportsConditions) { - if (isStrictRegExp.test(request)) - return unqualifiedPath; - const unqualifiedExportPath = applyNodeExportsResolution(unqualifiedPath, conditions); - if (unqualifiedExportPath) { - return ppath.normalize(unqualifiedExportPath); - } else { - return unqualifiedPath; - } - } - function resolveUnqualified(unqualifiedPath, {extensions = Object.keys(require$$0.Module._extensions)} = {}) { - var _a, _b; - const candidates = []; - const qualifiedPath = applyNodeExtensionResolution(unqualifiedPath, candidates, {extensions}); - if (qualifiedPath) { - return ppath.normalize(qualifiedPath); - } else { - const unqualifiedPathForDisplay = getPathForDisplay(unqualifiedPath); - const containingPackage = findPackageLocator(unqualifiedPath); - if (containingPackage) { - const {packageLocation} = getPackageInformationSafe(containingPackage); - let exists = true; - try { - opts.fakeFs.accessSync(packageLocation); - } catch (err) { - if ((err == null ? void 0 : err.code) === `ENOENT`) { - exists = false; - } else { - const readableError = ((_b = (_a = err == null ? void 0 : err.message) != null ? _a : err) != null ? _b : `empty exception thrown`).replace(/^[A-Z]/, ($0) => $0.toLowerCase()); - throw makeError(ErrorCode.QUALIFIED_PATH_RESOLUTION_FAILED, `Required package exists but could not be accessed (${readableError}). - -Missing package: ${containingPackage.name}@${containingPackage.reference} -Expected package location: ${getPathForDisplay(packageLocation)} -`, {unqualifiedPath: unqualifiedPathForDisplay, extensions}); - } - } - if (!exists) { - const errorMessage = packageLocation.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 makeError(ErrorCode.QUALIFIED_PATH_RESOLUTION_FAILED, `${errorMessage} - -Missing package: ${containingPackage.name}@${containingPackage.reference} -Expected package location: ${getPathForDisplay(packageLocation)} -`, {unqualifiedPath: unqualifiedPathForDisplay, extensions}); - } - } - throw makeError(ErrorCode.QUALIFIED_PATH_RESOLUTION_FAILED, `Qualified path resolution failed: we looked for the following paths, but none could be accessed. - -Source path: ${unqualifiedPathForDisplay} -${candidates.map((candidate) => `Not found: ${getPathForDisplay(candidate)} -`).join(``)}`, {unqualifiedPath: unqualifiedPathForDisplay, extensions}); - } - } - function resolveRequest(request, issuer, {considerBuiltins, extensions, conditions} = {}) { - try { - const unqualifiedPath = resolveToUnqualified(request, issuer, {considerBuiltins}); - if (request === `pnpapi`) - return unqualifiedPath; - if (unqualifiedPath === null) - return null; - const isIssuerIgnored = () => issuer !== null ? isPathIgnored(issuer) : false; - const remappedPath = (!considerBuiltins || !isBuiltinModule(request)) && !isIssuerIgnored() ? resolveUnqualifiedExport(request, unqualifiedPath, conditions) : unqualifiedPath; - return resolveUnqualified(remappedPath, {extensions}); - } catch (error) { - if (Object.prototype.hasOwnProperty.call(error, `pnpCode`)) - Object.assign(error.data, {request: getPathForDisplay(request), issuer: issuer && getPathForDisplay(issuer)}); - throw error; - } - } - function resolveVirtual(request) { - const normalized = ppath.normalize(request); - const resolved = VirtualFS.resolveVirtual(normalized); - return resolved !== normalized ? resolved : null; - } - return { - VERSIONS, - topLevel, - getLocator: (name, referencish) => { - if (Array.isArray(referencish)) { - return {name: referencish[0], reference: referencish[1]}; - } else { - return {name, reference: referencish}; - } - }, - getDependencyTreeRoots: () => { - return [...runtimeState.dependencyTreeRoots]; - }, - getAllLocators() { - const locators = []; - for (const [name, entry] of packageRegistry) - for (const reference of entry.keys()) - if (name !== null && reference !== null) - locators.push({name, reference}); - return locators; - }, - getPackageInformation: (locator) => { - const info = getPackageInformation(locator); - if (info === null) - return null; - const packageLocation = npath.fromPortablePath(info.packageLocation); - const nativeInfo = __spreadProps(__spreadValues$1({}, info), {packageLocation}); - return nativeInfo; - }, - findPackageLocator: (path) => { - return findPackageLocator(npath.toPortablePath(path)); - }, - resolveToUnqualified: maybeLog(`resolveToUnqualified`, (request, issuer, opts2) => { - const portableIssuer = issuer !== null ? npath.toPortablePath(issuer) : null; - const resolution = resolveToUnqualified(npath.toPortablePath(request), portableIssuer, opts2); - if (resolution === null) - return null; - return npath.fromPortablePath(resolution); - }), - resolveUnqualified: maybeLog(`resolveUnqualified`, (unqualifiedPath, opts2) => { - return npath.fromPortablePath(resolveUnqualified(npath.toPortablePath(unqualifiedPath), opts2)); - }), - resolveRequest: maybeLog(`resolveRequest`, (request, issuer, opts2) => { - const portableIssuer = issuer !== null ? npath.toPortablePath(issuer) : null; - const resolution = resolveRequest(npath.toPortablePath(request), portableIssuer, opts2); - if (resolution === null) - return null; - return npath.fromPortablePath(resolution); - }), - resolveVirtual: maybeLog(`resolveVirtual`, (path) => { - const result = resolveVirtual(npath.toPortablePath(path)); - if (result !== null) { - return npath.fromPortablePath(result); - } else { - return null; - } - }) - }; -} - -function makeManager(pnpapi, opts) { - const initialApiPath = npath.toPortablePath(pnpapi.resolveToUnqualified(`pnpapi`, null)); - const initialApiStats = opts.fakeFs.statSync(npath.toPortablePath(initialApiPath)); - const apiMetadata = new Map([ - [initialApiPath, { - cache: require$$0.Module._cache, - instance: pnpapi, - stats: initialApiStats, - lastRefreshCheck: Date.now() - }] - ]); - function loadApiInstance(pnpApiPath) { - const nativePath = npath.fromPortablePath(pnpApiPath); - const module = new require$$0.Module(nativePath, null); - module.load(nativePath); - return module.exports; - } - function refreshApiEntry(pnpApiPath, apiEntry) { - const timeNow = Date.now(); - if (timeNow - apiEntry.lastRefreshCheck < 500) - return; - apiEntry.lastRefreshCheck = timeNow; - const stats = opts.fakeFs.statSync(pnpApiPath); - if (stats.mtime > apiEntry.stats.mtime) { - process.emitWarning(`[Warning] The runtime detected new informations in a PnP file; reloading the API instance (${npath.fromPortablePath(pnpApiPath)})`); - apiEntry.stats = stats; - apiEntry.instance = loadApiInstance(pnpApiPath); - } - } - function getApiEntry(pnpApiPath, refresh = false) { - let apiEntry = apiMetadata.get(pnpApiPath); - if (typeof apiEntry !== `undefined`) { - if (refresh) { - refreshApiEntry(pnpApiPath, apiEntry); - } - } else { - apiMetadata.set(pnpApiPath, apiEntry = { - cache: {}, - instance: loadApiInstance(pnpApiPath), - stats: opts.fakeFs.statSync(pnpApiPath), - lastRefreshCheck: Date.now() - }); - } - return apiEntry; - } - const findApiPathCache = new Map(); - function addToCacheAndReturn(start, end, target) { - if (target !== null) - target = VirtualFS.resolveVirtual(target); - let curr; - let next = start; - do { - curr = next; - findApiPathCache.set(curr, target); - next = ppath.dirname(curr); - } while (curr !== end); - return target; - } - function findApiPathFor(modulePath) { - let bestCandidate = null; - for (const [apiPath, apiEntry] of apiMetadata) { - const locator = apiEntry.instance.findPackageLocator(modulePath); - if (!locator) - continue; - if (apiMetadata.size === 1) - return apiPath; - const packageInformation = apiEntry.instance.getPackageInformation(locator); - if (!packageInformation) - throw new Error(`Assertion failed: Couldn't get package information for '${modulePath}'`); - if (!bestCandidate) - bestCandidate = {packageLocation: packageInformation.packageLocation, apiPaths: []}; - if (packageInformation.packageLocation === bestCandidate.packageLocation) { - bestCandidate.apiPaths.push(apiPath); - } else if (packageInformation.packageLocation.length > bestCandidate.packageLocation.length) { - bestCandidate = {packageLocation: packageInformation.packageLocation, apiPaths: [apiPath]}; - } - } - if (bestCandidate) { - if (bestCandidate.apiPaths.length === 1) - return bestCandidate.apiPaths[0]; - const controlSegment = bestCandidate.apiPaths.map((apiPath) => ` ${npath.fromPortablePath(apiPath)}`).join(` -`); - throw new Error(`Unable to locate pnpapi, the module '${modulePath}' is controlled by multiple pnpapi instances. -This is usually caused by using the global cache (enableGlobalCache: true) - -Controlled by: -${controlSegment} -`); - } - const start = ppath.resolve(npath.toPortablePath(modulePath)); - let curr; - let next = start; - do { - curr = next; - const cached = findApiPathCache.get(curr); - if (cached !== void 0) - return addToCacheAndReturn(start, curr, cached); - const cjsCandidate = ppath.join(curr, Filename.pnpCjs); - if (opts.fakeFs.existsSync(cjsCandidate) && opts.fakeFs.statSync(cjsCandidate).isFile()) - return addToCacheAndReturn(start, curr, cjsCandidate); - const legacyCjsCandidate = ppath.join(curr, Filename.pnpJs); - if (opts.fakeFs.existsSync(legacyCjsCandidate) && opts.fakeFs.statSync(legacyCjsCandidate).isFile()) - return addToCacheAndReturn(start, curr, legacyCjsCandidate); - next = ppath.dirname(curr); - } while (curr !== PortablePath.root); - return addToCacheAndReturn(start, curr, null); - } - function getApiPathFromParent(parent) { - if (parent == null) - return initialApiPath; - if (typeof parent.pnpApiPath === `undefined`) { - if (parent.filename !== null) { - return parent.pnpApiPath = findApiPathFor(parent.filename); - } else { - return initialApiPath; - } - } - if (parent.pnpApiPath !== null) - return parent.pnpApiPath; - return null; - } - return { - getApiPathFromParent, - findApiPathFor, - getApiEntry - }; -} - -var __defProp = Object.defineProperty; -var __getOwnPropSymbols = Object.getOwnPropertySymbols; -var __hasOwnProp = Object.prototype.hasOwnProperty; -var __propIsEnum = Object.prototype.propertyIsEnumerable; -var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, {enumerable: true, configurable: true, writable: true, value}) : obj[key] = value; -var __spreadValues = (a, b) => { - for (var prop in b || (b = {})) - if (__hasOwnProp.call(b, prop)) - __defNormalProp(a, prop, b[prop]); - if (__getOwnPropSymbols) - for (var prop of __getOwnPropSymbols(b)) { - if (__propIsEnum.call(b, prop)) - __defNormalProp(a, prop, b[prop]); - } - return a; -}; -var __objRest = (source, exclude) => { - var target = {}; - for (var prop in source) - if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0) - target[prop] = source[prop]; - if (source != null && __getOwnPropSymbols) - for (var prop of __getOwnPropSymbols(source)) { - if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop)) - target[prop] = source[prop]; - } - return target; -}; -const localFs = __spreadValues({}, fs__default.default); -const nodeFs = new NodeFS(localFs); -const defaultRuntimeState = $$SETUP_STATE(hydrateRuntimeState); -const defaultPnpapiResolution = __filename; -const defaultFsLayer = new VirtualFS({ - baseFs: new ZipOpenFS({ - baseFs: nodeFs, - libzip: () => getLibzipSync(), - maxOpenFiles: 80, - readOnlyArchives: true - }) -}); -class DynamicFS extends ProxiedFS { - constructor() { - super(ppath); - this.baseFs = defaultFsLayer; - } - mapToBase(p) { - return p; - } - mapFromBase(p) { - return p; - } -} -const dynamicFsLayer = new DynamicFS(); -let manager; -const defaultApi = Object.assign(makeApi(defaultRuntimeState, { - fakeFs: dynamicFsLayer, - pnpapiResolution: defaultPnpapiResolution -}), { - makeApi: (_a) => { - var _b = _a, { - basePath = void 0, - fakeFs = dynamicFsLayer, - pnpapiResolution = defaultPnpapiResolution - } = _b, rest = __objRest(_b, [ - "basePath", - "fakeFs", - "pnpapiResolution" - ]); - const apiRuntimeState = typeof basePath !== `undefined` ? $$SETUP_STATE(hydrateRuntimeState, basePath) : defaultRuntimeState; - return makeApi(apiRuntimeState, __spreadValues({ - fakeFs, - pnpapiResolution - }, rest)); - }, - setup: (api) => { - applyPatch(api || defaultApi, { - fakeFs: defaultFsLayer, - manager - }); - dynamicFsLayer.baseFs = new NodeFS(fs__default.default); - } -}); -manager = makeManager(defaultApi, { - fakeFs: dynamicFsLayer -}); -if (module.parent && module.parent.id === `internal/preload`) { - defaultApi.setup(); - if (module.filename) { - delete require$$0__default.default._cache[module.filename]; - } -} -if (process.mainModule === module) { - const reportError = (code, message, data) => { - process.stdout.write(`${JSON.stringify([{code, message, data}, null])} -`); - }; - const reportSuccess = (resolution) => { - process.stdout.write(`${JSON.stringify([null, resolution])} -`); - }; - const processResolution = (request, issuer) => { - try { - reportSuccess(defaultApi.resolveRequest(request, issuer)); - } catch (error) { - reportError(error.code, error.message, error.data); - } - }; - const processRequest = (data) => { - try { - const [request, issuer] = JSON.parse(data); - processResolution(request, issuer); - } catch (error) { - reportError(`INVALID_JSON`, error.message, error.data); - } - }; - if (process.argv.length > 2) { - if (process.argv.length !== 4) { - process.stderr.write(`Usage: ${process.argv[0]} ${process.argv[1]} -`); - process.exitCode = 64; - } else { - processResolution(process.argv[2], process.argv[3]); - } - } else { - let buffer = ``; - const decoder = new StringDecoder__default.default.StringDecoder(); - process.stdin.on(`data`, (chunk) => { - buffer += decoder.write(chunk); - do { - const index = buffer.indexOf(` -`); - if (index === -1) - break; - const line = buffer.slice(0, index); - buffer = buffer.slice(index + 1); - processRequest(line); - } while (true); - }); - } -} - -module.exports = defaultApi; diff --git a/.pnp.loader.mjs b/.pnp.loader.mjs deleted file mode 100644 index 26efb974622..00000000000 --- a/.pnp.loader.mjs +++ /dev/null @@ -1,273 +0,0 @@ -import { URL, fileURLToPath, pathToFileURL } from 'url'; -import fs from 'fs'; -import path from 'path'; -import moduleExports, { Module } from 'module'; - -var PathType; -(function(PathType2) { - PathType2[PathType2["File"] = 0] = "File"; - PathType2[PathType2["Portable"] = 1] = "Portable"; - PathType2[PathType2["Native"] = 2] = "Native"; -})(PathType || (PathType = {})); -const npath = Object.create(path); -const ppath = Object.create(path.posix); -npath.cwd = () => process.cwd(); -ppath.cwd = () => toPortablePath(process.cwd()); -ppath.resolve = (...segments) => { - if (segments.length > 0 && ppath.isAbsolute(segments[0])) { - return path.posix.resolve(...segments); - } else { - return path.posix.resolve(ppath.cwd(), ...segments); - } -}; -const contains = function(pathUtils, from, to) { - from = pathUtils.normalize(from); - to = pathUtils.normalize(to); - if (from === to) - return `.`; - if (!from.endsWith(pathUtils.sep)) - from = from + pathUtils.sep; - if (to.startsWith(from)) { - return to.slice(from.length); - } else { - return null; - } -}; -npath.fromPortablePath = fromPortablePath; -npath.toPortablePath = toPortablePath; -npath.contains = (from, to) => contains(npath, from, to); -ppath.contains = (from, to) => contains(ppath, from, to); -const WINDOWS_PATH_REGEXP = /^([a-zA-Z]:.*)$/; -const UNC_WINDOWS_PATH_REGEXP = /^\/\/(\.\/)?(.*)$/; -const PORTABLE_PATH_REGEXP = /^\/([a-zA-Z]:.*)$/; -const UNC_PORTABLE_PATH_REGEXP = /^\/unc\/(\.dot\/)?(.*)$/; -function fromPortablePath(p) { - if (process.platform !== `win32`) - return p; - let portablePathMatch, uncPortablePathMatch; - if (portablePathMatch = p.match(PORTABLE_PATH_REGEXP)) - p = portablePathMatch[1]; - else if (uncPortablePathMatch = p.match(UNC_PORTABLE_PATH_REGEXP)) - p = `\\\\${uncPortablePathMatch[1] ? `.\\` : ``}${uncPortablePathMatch[2]}`; - else - return p; - return p.replace(/\//g, `\\`); -} -function toPortablePath(p) { - if (process.platform !== `win32`) - return p; - p = p.replace(/\\/g, `/`); - let windowsPathMatch, uncWindowsPathMatch; - if (windowsPathMatch = p.match(WINDOWS_PATH_REGEXP)) - p = `/${windowsPathMatch[1]}`; - else if (uncWindowsPathMatch = p.match(UNC_WINDOWS_PATH_REGEXP)) - p = `/unc/${uncWindowsPathMatch[1] ? `.dot/` : ``}${uncWindowsPathMatch[2]}`; - return p; -} - -const builtinModules = new Set(Module.builtinModules || Object.keys(process.binding(`natives`))); -const isBuiltinModule = (request) => request.startsWith(`node:`) || builtinModules.has(request); -function readPackageScope(checkPath) { - const rootSeparatorIndex = checkPath.indexOf(npath.sep); - let separatorIndex; - do { - separatorIndex = checkPath.lastIndexOf(npath.sep); - checkPath = checkPath.slice(0, separatorIndex); - if (checkPath.endsWith(`${npath.sep}node_modules`)) - return false; - const pjson = readPackage(checkPath + npath.sep); - if (pjson) { - return { - data: pjson, - path: checkPath - }; - } - } while (separatorIndex > rootSeparatorIndex); - return false; -} -function readPackage(requestPath) { - const jsonPath = npath.resolve(requestPath, `package.json`); - if (!fs.existsSync(jsonPath)) - return null; - return JSON.parse(fs.readFileSync(jsonPath, `utf8`)); -} - -async function tryReadFile(path2) { - try { - return await fs.promises.readFile(path2, `utf8`); - } catch (error) { - if (error.code === `ENOENT`) - return null; - throw error; - } -} -function tryParseURL(str, base) { - try { - return new URL(str, base); - } catch { - return null; - } -} -let entrypointPath = null; -function setEntrypointPath(file) { - entrypointPath = file; -} -function getFileFormat(filepath) { - var _a, _b; - const ext = path.extname(filepath); - switch (ext) { - case `.mjs`: { - return `module`; - } - case `.cjs`: { - return `commonjs`; - } - case `.wasm`: { - throw new Error(`Unknown file extension ".wasm" for ${filepath}`); - } - case `.json`: { - throw new Error(`Unknown file extension ".json" for ${filepath}`); - } - case `.js`: { - const pkg = readPackageScope(filepath); - if (!pkg) - return `commonjs`; - return (_a = pkg.data.type) != null ? _a : `commonjs`; - } - default: { - if (entrypointPath !== filepath) - return null; - const pkg = readPackageScope(filepath); - if (!pkg) - return `commonjs`; - if (pkg.data.type === `module`) - return null; - return (_b = pkg.data.type) != null ? _b : `commonjs`; - } - } -} - -async function getFormat$1(resolved, context, defaultGetFormat) { - const url = tryParseURL(resolved); - if ((url == null ? void 0 : url.protocol) !== `file:`) - return defaultGetFormat(resolved, context, defaultGetFormat); - const format = getFileFormat(fileURLToPath(url)); - if (format) { - return { - format - }; - } - return defaultGetFormat(resolved, context, defaultGetFormat); -} - -async function getSource$1(urlString, context, defaultGetSource) { - const url = tryParseURL(urlString); - if ((url == null ? void 0 : url.protocol) !== `file:`) - return defaultGetSource(urlString, context, defaultGetSource); - return { - source: await fs.promises.readFile(fileURLToPath(url), `utf8`) - }; -} - -async function load$1(urlString, context, nextLoad) { - const url = tryParseURL(urlString); - if ((url == null ? void 0 : url.protocol) !== `file:`) - return nextLoad(urlString, context, nextLoad); - const filePath = fileURLToPath(url); - const format = getFileFormat(filePath); - if (!format) - return nextLoad(urlString, context, nextLoad); - return { - format, - source: await fs.promises.readFile(filePath, `utf8`), - shortCircuit: true - }; -} - -const pathRegExp = /^(?![a-zA-Z]:[\\/]|\\\\|\.{0,2}(?:\/|$))((?:node:)?(?:@[^/]+\/)?[^/]+)\/*(.*|)$/; -const isRelativeRegexp = /^\.{0,2}\//; -async function resolve$1(originalSpecifier, context, nextResolve) { - var _a; - const {findPnpApi} = moduleExports; - if (!findPnpApi || isBuiltinModule(originalSpecifier)) - return nextResolve(originalSpecifier, context, nextResolve); - let specifier = originalSpecifier; - const url = tryParseURL(specifier, isRelativeRegexp.test(specifier) ? context.parentURL : void 0); - if (url) { - if (url.protocol !== `file:`) - return nextResolve(originalSpecifier, context, nextResolve); - specifier = fileURLToPath(url); - } - const {parentURL, conditions = []} = context; - const issuer = parentURL ? fileURLToPath(parentURL) : process.cwd(); - const pnpapi = (_a = findPnpApi(issuer)) != null ? _a : url ? findPnpApi(specifier) : null; - if (!pnpapi) - return nextResolve(originalSpecifier, context, nextResolve); - const dependencyNameMatch = specifier.match(pathRegExp); - let allowLegacyResolve = false; - if (dependencyNameMatch) { - const [, dependencyName, subPath] = dependencyNameMatch; - if (subPath === ``) { - const resolved = pnpapi.resolveToUnqualified(`${dependencyName}/package.json`, issuer); - if (resolved) { - const content = await tryReadFile(resolved); - if (content) { - const pkg = JSON.parse(content); - allowLegacyResolve = pkg.exports == null; - } - } - } - } - const result = pnpapi.resolveRequest(specifier, issuer, { - conditions: new Set(conditions), - extensions: allowLegacyResolve ? void 0 : [] - }); - if (!result) - throw new Error(`Resolving '${specifier}' from '${issuer}' failed`); - const resultURL = pathToFileURL(result); - if (url) { - resultURL.search = url.search; - resultURL.hash = url.hash; - } - if (!parentURL) - setEntrypointPath(fileURLToPath(resultURL)); - return { - url: resultURL.href, - shortCircuit: true - }; -} - -const binding = process.binding(`fs`); -const originalfstat = binding.fstat; -const ZIP_FD = 2147483648; -binding.fstat = function(...args) { - const [fd, useBigint, req] = args; - if ((fd & ZIP_FD) !== 0 && useBigint === false && req === void 0) { - try { - const stats = fs.fstatSync(fd); - return new Float64Array([ - stats.dev, - stats.mode, - stats.nlink, - stats.uid, - stats.gid, - stats.rdev, - stats.blksize, - stats.ino, - stats.size, - stats.blocks - ]); - } catch { - } - } - return originalfstat.apply(this, args); -}; - -const [major, minor] = process.versions.node.split(`.`).map((value) => parseInt(value, 10)); -const hasConsolidatedHooks = major > 16 || major === 16 && minor >= 12; -const resolve = resolve$1; -const getFormat = hasConsolidatedHooks ? void 0 : getFormat$1; -const getSource = hasConsolidatedHooks ? void 0 : getSource$1; -const load = hasConsolidatedHooks ? load$1 : void 0; - -export { getFormat, getSource, load, resolve }; diff --git a/.pylintrc b/.pylintrc index c9a33fcec2c..008f89e4547 100644 --- a/.pylintrc +++ b/.pylintrc @@ -405,4 +405,4 @@ analyse-fallback-blocks=no # Exceptions that will emit a warning when being caught. Defaults to # "Exception" -overgeneral-exceptions=Exception +overgeneral-exceptions=builtins.Exception diff --git a/.sassrc.json b/.sassrc.json new file mode 100644 index 00000000000..0dea8892cc4 --- /dev/null +++ b/.sassrc.json @@ -0,0 +1,3 @@ +{ + "silenceDeprecations": ["import", "if-function", "global-builtin", "color-functions"] +} diff --git a/.vscode/launch.json b/.vscode/launch.json index 8dfc1b9b7a3..227eb8f6155 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -12,7 +12,7 @@ "program": "${workspaceFolder}/ietf/manage.py", "args": [ "runserver", - "0.0.0.0:8000", + "0.0.0.0:8001", "--settings=settings_local" ], "django": true, @@ -30,7 +30,7 @@ "program": "${workspaceFolder}/ietf/manage.py", "args": [ "runserver", - "0.0.0.0:8000", + "0.0.0.0:8001", "--settings=settings_local_vite" ], "django": true, @@ -48,7 +48,7 @@ "program": "${workspaceFolder}/ietf/manage.py", "args": [ "runserver", - "0.0.0.0:8000", + "0.0.0.0:8001", "--settings=settings_local_debug" ], "django": true, diff --git a/.vscode/settings.json b/.vscode/settings.json index 6acc6412645..f15519dae81 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,55 +1,49 @@ { - "taskExplorer.exclude": [ - "**/.vscode-test/**", - "**/bin/**", - "**/build/**", - "**/CompiledOutput/**", - "**/dist/**", - "**/doc/**", - "**/ext/**", - "**/out/**", - "**/output/**", - "**/packages/**", - "**/release/**", - "**/releases/**", - "**/samples/**", - "**/sdks/**", - "**/static/**", - "**/target/**", - "**/test/**", - "**/third_party/**", - "**/vendor/**", - "**/work/**", - "/workspace/bootstrap/nuget/MyGet.ps1" - ], - "taskExplorer.enableAnt": false, - "taskExplorer.enableAppPublisher": false, - "taskExplorer.enablePipenv": false, - "taskExplorer.enableBash": false, - "taskExplorer.enableBatch": false, - "taskExplorer.enableGradle": false, - "taskExplorer.enableGrunt": false, - "taskExplorer.enableGulp": false, - "taskExplorer.enablePerl": false, - "taskExplorer.enableMake": false, - "taskExplorer.enableMaven": false, - "taskExplorer.enableNsis": false, - "taskExplorer.enableNpm": false, - "taskExplorer.enablePowershell": false, - "taskExplorer.enablePython": false, - "taskExplorer.enableRuby": false, - "taskExplorer.enableTsc": false, - "taskExplorer.enableWorkspace": true, - "taskExplorer.enableExplorerView": false, - "taskExplorer.enableSideBar": true, - "search.exclude": { - "**/.yarn": true, - "**/.pnp.*": true - }, - "eslint.nodePath": ".yarn/sdks", - "eslint.validate": [ - "javascript", - "javascriptreact", - "vue" - ] + "search.exclude": { + "**/.yarn": true, + "**/.pnp.*": true + }, + "python.linting.pylintArgs": ["--load-plugins", "pylint_django"], + "python.testing.pytestEnabled": false, + "python.testing.unittestEnabled": false, + "python.linting.enabled": true, + "python.terminal.shellIntegration.enabled": false, + "vs-kubernetes": { + "disable-linters": ["resource-limits"] + }, + "editor.codeActionsOnSave": { + "source.fixAll.oxc": "explicit" + }, + "[javascript]": { + "editor.defaultFormatter": "oxc.oxc-vscode", + "editor.formatOnSave": true + }, + "[vue]": { + "editor.defaultFormatter": "oxc.oxc-vscode", + "editor.formatOnSave": true + }, + "[scss]": { + "editor.defaultFormatter": "oxc.oxc-vscode", + "editor.formatOnSave": true + }, + "[css]": { + "editor.defaultFormatter": "oxc.oxc-vscode", + "editor.formatOnSave": true + }, + "[postcss]": { + "editor.defaultFormatter": "oxc.oxc-vscode", + "editor.formatOnSave": true + }, + "[json]": { + "editor.defaultFormatter": "oxc.oxc-vscode", + "editor.formatOnSave": true + }, + "[jsonc]": { + "editor.defaultFormatter": "oxc.oxc-vscode", + "editor.formatOnSave": true + }, + "[html]": { + "editor.defaultFormatter": "oxc.oxc-vscode", + "editor.formatOnSave": true + } } diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 5490af335c8..8b36b0e6ac9 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -48,7 +48,7 @@ "args": [ "${workspaceFolder}/ietf/manage.py", "test", - "--settings=settings_local_sqlitetest" + "--settings=settings_test" ], "group": "test", "presentation": { @@ -68,7 +68,7 @@ "args": [ "${workspaceFolder}/ietf/manage.py", "test", - "--settings=settings_local_sqlitetest", + "--settings=settings_test", "--pattern=tests_js.py" ], "group": "test", @@ -105,10 +105,11 @@ "command": "/usr/local/bin/python", "args": [ "-m", - "smtpd", + "aiosmtpd", "-n", "-c", - "DebuggingServer", + "ietf.utils.aiosmtpd.DevDebuggingHandler", + "-l", "localhost:2025" ], "presentation": { diff --git a/.yarn/cache/@babel-code-frame-npm-7.16.7-093eb9e124-db2f7faa31.zip b/.yarn/cache/@babel-code-frame-npm-7.16.7-093eb9e124-db2f7faa31.zip deleted file mode 100644 index 1c98cc9480c..00000000000 Binary files a/.yarn/cache/@babel-code-frame-npm-7.16.7-093eb9e124-db2f7faa31.zip and /dev/null differ diff --git a/.yarn/cache/@babel-helper-validator-identifier-npm-7.16.7-8599fb00fc-dbb3db9d18.zip b/.yarn/cache/@babel-helper-validator-identifier-npm-7.16.7-8599fb00fc-dbb3db9d18.zip deleted file mode 100644 index 0cde98edb13..00000000000 Binary files a/.yarn/cache/@babel-helper-validator-identifier-npm-7.16.7-8599fb00fc-dbb3db9d18.zip and /dev/null differ diff --git a/.yarn/cache/@babel-highlight-npm-7.17.12-73223b881e-841a11aa35.zip b/.yarn/cache/@babel-highlight-npm-7.17.12-73223b881e-841a11aa35.zip deleted file mode 100644 index ae9f45bc8d9..00000000000 Binary files a/.yarn/cache/@babel-highlight-npm-7.17.12-73223b881e-841a11aa35.zip and /dev/null differ diff --git a/.yarn/cache/@babel-parser-npm-7.18.4-63fd355e07-e05b2dc720.zip b/.yarn/cache/@babel-parser-npm-7.18.4-63fd355e07-e05b2dc720.zip deleted file mode 100644 index 492df2729c8..00000000000 Binary files a/.yarn/cache/@babel-parser-npm-7.18.4-63fd355e07-e05b2dc720.zip and /dev/null differ diff --git a/.yarn/cache/@babel-types-npm-7.18.4-758c2695f8-85df59beb9.zip b/.yarn/cache/@babel-types-npm-7.18.4-758c2695f8-85df59beb9.zip deleted file mode 100644 index f88d1e6fc3f..00000000000 Binary files a/.yarn/cache/@babel-types-npm-7.18.4-758c2695f8-85df59beb9.zip and /dev/null differ diff --git a/.yarn/cache/@bcoe-v8-coverage-npm-0.2.3-9e27b3c57e-850f930553.zip b/.yarn/cache/@bcoe-v8-coverage-npm-0.2.3-9e27b3c57e-850f930553.zip deleted file mode 100644 index 8725d33ac5b..00000000000 Binary files a/.yarn/cache/@bcoe-v8-coverage-npm-0.2.3-9e27b3c57e-850f930553.zip and /dev/null differ diff --git a/.yarn/cache/@colors-colors-npm-1.5.0-875af3a8b4-d64d5260be.zip b/.yarn/cache/@colors-colors-npm-1.5.0-875af3a8b4-d64d5260be.zip deleted file mode 100644 index c1edd324f68..00000000000 Binary files a/.yarn/cache/@colors-colors-npm-1.5.0-875af3a8b4-d64d5260be.zip and /dev/null differ diff --git a/.yarn/cache/@css-render-plugin-bem-npm-0.15.10-41ccecaa2f-cbab72a7b5.zip b/.yarn/cache/@css-render-plugin-bem-npm-0.15.10-41ccecaa2f-cbab72a7b5.zip deleted file mode 100644 index 7df7772871c..00000000000 Binary files a/.yarn/cache/@css-render-plugin-bem-npm-0.15.10-41ccecaa2f-cbab72a7b5.zip and /dev/null differ diff --git a/.yarn/cache/@css-render-vue3-ssr-npm-0.15.10-b8526cc313-7977e0c440.zip b/.yarn/cache/@css-render-vue3-ssr-npm-0.15.10-b8526cc313-7977e0c440.zip deleted file mode 100644 index 1ce346dd471..00000000000 Binary files a/.yarn/cache/@css-render-vue3-ssr-npm-0.15.10-b8526cc313-7977e0c440.zip and /dev/null differ diff --git a/.yarn/cache/@cypress-request-npm-2.88.10-44c588c8fc-69c3e3b332.zip b/.yarn/cache/@cypress-request-npm-2.88.10-44c588c8fc-69c3e3b332.zip deleted file mode 100644 index 981577f3f37..00000000000 Binary files a/.yarn/cache/@cypress-request-npm-2.88.10-44c588c8fc-69c3e3b332.zip and /dev/null differ diff --git a/.yarn/cache/@cypress-xvfb-npm-1.2.4-396a3691f7-7bdcdaeb1b.zip b/.yarn/cache/@cypress-xvfb-npm-1.2.4-396a3691f7-7bdcdaeb1b.zip deleted file mode 100644 index f5fc2cdbc11..00000000000 Binary files a/.yarn/cache/@cypress-xvfb-npm-1.2.4-396a3691f7-7bdcdaeb1b.zip and /dev/null differ diff --git a/.yarn/cache/@emotion-hash-npm-0.8.0-0104f4bbf3-4b35d88a97.zip b/.yarn/cache/@emotion-hash-npm-0.8.0-0104f4bbf3-4b35d88a97.zip deleted file mode 100644 index a857b732763..00000000000 Binary files a/.yarn/cache/@emotion-hash-npm-0.8.0-0104f4bbf3-4b35d88a97.zip and /dev/null differ diff --git a/.yarn/cache/@eslint-eslintrc-npm-1.3.0-1f3c51be25-a1e734ad31.zip b/.yarn/cache/@eslint-eslintrc-npm-1.3.0-1f3c51be25-a1e734ad31.zip deleted file mode 100644 index e9b7fa21a8b..00000000000 Binary files a/.yarn/cache/@eslint-eslintrc-npm-1.3.0-1f3c51be25-a1e734ad31.zip and /dev/null differ diff --git a/.yarn/cache/@fullcalendar-bootstrap5-npm-5.11.0-2c476fdabc-164120b931.zip b/.yarn/cache/@fullcalendar-bootstrap5-npm-5.11.0-2c476fdabc-164120b931.zip deleted file mode 100644 index 8526bef9864..00000000000 Binary files a/.yarn/cache/@fullcalendar-bootstrap5-npm-5.11.0-2c476fdabc-164120b931.zip and /dev/null differ diff --git a/.yarn/cache/@fullcalendar-common-npm-5.11.0-5c975d3481-1bda749a43.zip b/.yarn/cache/@fullcalendar-common-npm-5.11.0-5c975d3481-1bda749a43.zip deleted file mode 100644 index b6253dad9d2..00000000000 Binary files a/.yarn/cache/@fullcalendar-common-npm-5.11.0-5c975d3481-1bda749a43.zip and /dev/null differ diff --git a/.yarn/cache/@fullcalendar-core-npm-5.11.0-a3d247e75a-20e60c65af.zip b/.yarn/cache/@fullcalendar-core-npm-5.11.0-a3d247e75a-20e60c65af.zip deleted file mode 100644 index 367f87a2053..00000000000 Binary files a/.yarn/cache/@fullcalendar-core-npm-5.11.0-a3d247e75a-20e60c65af.zip and /dev/null differ diff --git a/.yarn/cache/@fullcalendar-daygrid-npm-5.11.0-4beb665944-d30105222f.zip b/.yarn/cache/@fullcalendar-daygrid-npm-5.11.0-4beb665944-d30105222f.zip deleted file mode 100644 index 24118d897ae..00000000000 Binary files a/.yarn/cache/@fullcalendar-daygrid-npm-5.11.0-4beb665944-d30105222f.zip and /dev/null differ diff --git a/.yarn/cache/@fullcalendar-interaction-npm-5.11.0-bdf2352cc1-625eb7ea33.zip b/.yarn/cache/@fullcalendar-interaction-npm-5.11.0-bdf2352cc1-625eb7ea33.zip deleted file mode 100644 index 3aded219e0d..00000000000 Binary files a/.yarn/cache/@fullcalendar-interaction-npm-5.11.0-bdf2352cc1-625eb7ea33.zip and /dev/null differ diff --git a/.yarn/cache/@fullcalendar-list-npm-5.11.0-f90ee50a26-08be90dbdf.zip b/.yarn/cache/@fullcalendar-list-npm-5.11.0-f90ee50a26-08be90dbdf.zip deleted file mode 100644 index 9cae54b1484..00000000000 Binary files a/.yarn/cache/@fullcalendar-list-npm-5.11.0-f90ee50a26-08be90dbdf.zip and /dev/null differ diff --git a/.yarn/cache/@fullcalendar-luxon2-npm-5.11.0-c598bea26b-7be523ce12.zip b/.yarn/cache/@fullcalendar-luxon2-npm-5.11.0-c598bea26b-7be523ce12.zip deleted file mode 100644 index 5674885a2a7..00000000000 Binary files a/.yarn/cache/@fullcalendar-luxon2-npm-5.11.0-c598bea26b-7be523ce12.zip and /dev/null differ diff --git a/.yarn/cache/@fullcalendar-timegrid-npm-5.11.0-13dce02247-4a7fb7fe3e.zip b/.yarn/cache/@fullcalendar-timegrid-npm-5.11.0-13dce02247-4a7fb7fe3e.zip deleted file mode 100644 index a45bb1ef3d1..00000000000 Binary files a/.yarn/cache/@fullcalendar-timegrid-npm-5.11.0-13dce02247-4a7fb7fe3e.zip and /dev/null differ diff --git a/.yarn/cache/@fullcalendar-vue3-npm-5.11.1-ec3de404fa-83ca9fecf5.zip b/.yarn/cache/@fullcalendar-vue3-npm-5.11.1-ec3de404fa-83ca9fecf5.zip deleted file mode 100644 index 7b3f1570cf1..00000000000 Binary files a/.yarn/cache/@fullcalendar-vue3-npm-5.11.1-ec3de404fa-83ca9fecf5.zip and /dev/null differ diff --git a/.yarn/cache/@gar-promisify-npm-1.1.3-ac1a325862-4059f790e2.zip b/.yarn/cache/@gar-promisify-npm-1.1.3-ac1a325862-4059f790e2.zip deleted file mode 100644 index 828b7817b08..00000000000 Binary files a/.yarn/cache/@gar-promisify-npm-1.1.3-ac1a325862-4059f790e2.zip and /dev/null differ diff --git a/.yarn/cache/@html-validate-stylish-npm-3.0.0-6d9dccafda-818efd25ac.zip b/.yarn/cache/@html-validate-stylish-npm-3.0.0-6d9dccafda-818efd25ac.zip deleted file mode 100644 index 5ed78286fb5..00000000000 Binary files a/.yarn/cache/@html-validate-stylish-npm-3.0.0-6d9dccafda-818efd25ac.zip and /dev/null differ diff --git a/.yarn/cache/@humanwhocodes-config-array-npm-0.9.5-030a025eae-8ba6281bc0.zip b/.yarn/cache/@humanwhocodes-config-array-npm-0.9.5-030a025eae-8ba6281bc0.zip deleted file mode 100644 index 63f5f5e83ff..00000000000 Binary files a/.yarn/cache/@humanwhocodes-config-array-npm-0.9.5-030a025eae-8ba6281bc0.zip and /dev/null differ diff --git a/.yarn/cache/@humanwhocodes-object-schema-npm-1.2.1-eb622b5d0e-a824a1ec31.zip b/.yarn/cache/@humanwhocodes-object-schema-npm-1.2.1-eb622b5d0e-a824a1ec31.zip deleted file mode 100644 index 2b79104af59..00000000000 Binary files a/.yarn/cache/@humanwhocodes-object-schema-npm-1.2.1-eb622b5d0e-a824a1ec31.zip and /dev/null differ diff --git a/.yarn/cache/@istanbuljs-schema-npm-0.1.3-466bd3eaaa-5282759d96.zip b/.yarn/cache/@istanbuljs-schema-npm-0.1.3-466bd3eaaa-5282759d96.zip deleted file mode 100644 index 5796f760161..00000000000 Binary files a/.yarn/cache/@istanbuljs-schema-npm-0.1.3-466bd3eaaa-5282759d96.zip and /dev/null differ diff --git a/.yarn/cache/@jridgewell-resolve-uri-npm-3.1.0-6ff2351e61-b5ceaaf9a1.zip b/.yarn/cache/@jridgewell-resolve-uri-npm-3.1.0-6ff2351e61-b5ceaaf9a1.zip deleted file mode 100644 index 97e857d7d22..00000000000 Binary files a/.yarn/cache/@jridgewell-resolve-uri-npm-3.1.0-6ff2351e61-b5ceaaf9a1.zip and /dev/null differ diff --git a/.yarn/cache/@jridgewell-sourcemap-codec-npm-1.4.14-f5f0630788-61100637b6.zip b/.yarn/cache/@jridgewell-sourcemap-codec-npm-1.4.14-f5f0630788-61100637b6.zip deleted file mode 100644 index d8703c89675..00000000000 Binary files a/.yarn/cache/@jridgewell-sourcemap-codec-npm-1.4.14-f5f0630788-61100637b6.zip and /dev/null differ diff --git a/.yarn/cache/@jridgewell-trace-mapping-npm-0.3.14-c78fcccfdf-b9537b9630.zip b/.yarn/cache/@jridgewell-trace-mapping-npm-0.3.14-c78fcccfdf-b9537b9630.zip deleted file mode 100644 index 95455c62eb2..00000000000 Binary files a/.yarn/cache/@jridgewell-trace-mapping-npm-0.3.14-c78fcccfdf-b9537b9630.zip and /dev/null differ diff --git a/.yarn/cache/@juggle-resize-observer-npm-3.3.1-f36d80a4f0-ddabc40442.zip b/.yarn/cache/@juggle-resize-observer-npm-3.3.1-f36d80a4f0-ddabc40442.zip deleted file mode 100644 index d6c7b40e829..00000000000 Binary files a/.yarn/cache/@juggle-resize-observer-npm-3.3.1-f36d80a4f0-ddabc40442.zip and /dev/null differ diff --git a/.yarn/cache/@lezer-common-npm-0.15.12-62017272b0-dae6581618.zip b/.yarn/cache/@lezer-common-npm-0.15.12-62017272b0-dae6581618.zip deleted file mode 100644 index 87f2f317bab..00000000000 Binary files a/.yarn/cache/@lezer-common-npm-0.15.12-62017272b0-dae6581618.zip and /dev/null differ diff --git a/.yarn/cache/@lezer-lr-npm-0.15.8-8c481c39cd-e741225d6a.zip b/.yarn/cache/@lezer-lr-npm-0.15.8-8c481c39cd-e741225d6a.zip deleted file mode 100644 index 9a56971a6d5..00000000000 Binary files a/.yarn/cache/@lezer-lr-npm-0.15.8-8c481c39cd-e741225d6a.zip and /dev/null differ diff --git a/.yarn/cache/@lmdb-lmdb-darwin-arm64-npm-2.5.2-ba0aa88b93-8.zip b/.yarn/cache/@lmdb-lmdb-darwin-arm64-npm-2.5.2-ba0aa88b93-8.zip deleted file mode 100644 index 1d582f1da74..00000000000 Binary files a/.yarn/cache/@lmdb-lmdb-darwin-arm64-npm-2.5.2-ba0aa88b93-8.zip and /dev/null differ diff --git a/.yarn/cache/@lmdb-lmdb-darwin-x64-npm-2.5.2-237e0d1098-8.zip b/.yarn/cache/@lmdb-lmdb-darwin-x64-npm-2.5.2-237e0d1098-8.zip deleted file mode 100644 index 9e99c17c099..00000000000 Binary files a/.yarn/cache/@lmdb-lmdb-darwin-x64-npm-2.5.2-237e0d1098-8.zip and /dev/null differ diff --git a/.yarn/cache/@lmdb-lmdb-linux-arm64-npm-2.5.2-29a971842e-8.zip b/.yarn/cache/@lmdb-lmdb-linux-arm64-npm-2.5.2-29a971842e-8.zip deleted file mode 100644 index 7ae79d5162f..00000000000 Binary files a/.yarn/cache/@lmdb-lmdb-linux-arm64-npm-2.5.2-29a971842e-8.zip and /dev/null differ diff --git a/.yarn/cache/@lmdb-lmdb-linux-x64-npm-2.5.2-ca846c82b3-8.zip b/.yarn/cache/@lmdb-lmdb-linux-x64-npm-2.5.2-ca846c82b3-8.zip deleted file mode 100644 index b9fb7c7824f..00000000000 Binary files a/.yarn/cache/@lmdb-lmdb-linux-x64-npm-2.5.2-ca846c82b3-8.zip and /dev/null differ diff --git a/.yarn/cache/@lmdb-lmdb-win32-x64-npm-2.5.2-b6c28f5123-8.zip b/.yarn/cache/@lmdb-lmdb-win32-x64-npm-2.5.2-b6c28f5123-8.zip deleted file mode 100644 index 60a2afc17dd..00000000000 Binary files a/.yarn/cache/@lmdb-lmdb-win32-x64-npm-2.5.2-b6c28f5123-8.zip and /dev/null differ diff --git a/.yarn/cache/@mischnic-json-sourcemap-npm-0.1.0-4b4af227b1-a30eda9eb0.zip b/.yarn/cache/@mischnic-json-sourcemap-npm-0.1.0-4b4af227b1-a30eda9eb0.zip deleted file mode 100644 index a456e201042..00000000000 Binary files a/.yarn/cache/@mischnic-json-sourcemap-npm-0.1.0-4b4af227b1-a30eda9eb0.zip and /dev/null differ diff --git a/.yarn/cache/@msgpackr-extract-msgpackr-extract-darwin-arm64-npm-2.0.2-be5249cbca-8.zip b/.yarn/cache/@msgpackr-extract-msgpackr-extract-darwin-arm64-npm-2.0.2-be5249cbca-8.zip deleted file mode 100644 index 146dc9d243c..00000000000 Binary files a/.yarn/cache/@msgpackr-extract-msgpackr-extract-darwin-arm64-npm-2.0.2-be5249cbca-8.zip and /dev/null differ diff --git a/.yarn/cache/@msgpackr-extract-msgpackr-extract-darwin-x64-npm-2.0.2-aaad2bbcdd-8.zip b/.yarn/cache/@msgpackr-extract-msgpackr-extract-darwin-x64-npm-2.0.2-aaad2bbcdd-8.zip deleted file mode 100644 index e727b219ead..00000000000 Binary files a/.yarn/cache/@msgpackr-extract-msgpackr-extract-darwin-x64-npm-2.0.2-aaad2bbcdd-8.zip and /dev/null differ diff --git a/.yarn/cache/@msgpackr-extract-msgpackr-extract-linux-arm64-npm-2.0.2-73fc5b0175-8.zip b/.yarn/cache/@msgpackr-extract-msgpackr-extract-linux-arm64-npm-2.0.2-73fc5b0175-8.zip deleted file mode 100644 index 125d8bca3ed..00000000000 Binary files a/.yarn/cache/@msgpackr-extract-msgpackr-extract-linux-arm64-npm-2.0.2-73fc5b0175-8.zip and /dev/null differ diff --git a/.yarn/cache/@msgpackr-extract-msgpackr-extract-linux-x64-npm-2.0.2-028869dc6b-8.zip b/.yarn/cache/@msgpackr-extract-msgpackr-extract-linux-x64-npm-2.0.2-028869dc6b-8.zip deleted file mode 100644 index 35d8ee2c6f0..00000000000 Binary files a/.yarn/cache/@msgpackr-extract-msgpackr-extract-linux-x64-npm-2.0.2-028869dc6b-8.zip and /dev/null differ diff --git a/.yarn/cache/@msgpackr-extract-msgpackr-extract-win32-x64-npm-2.0.2-c54981be26-8.zip b/.yarn/cache/@msgpackr-extract-msgpackr-extract-win32-x64-npm-2.0.2-c54981be26-8.zip deleted file mode 100644 index f21965c5b7f..00000000000 Binary files a/.yarn/cache/@msgpackr-extract-msgpackr-extract-win32-x64-npm-2.0.2-c54981be26-8.zip and /dev/null differ diff --git a/.yarn/cache/@npmcli-fs-npm-2.1.0-3b106d08bc-6ec6d678af.zip b/.yarn/cache/@npmcli-fs-npm-2.1.0-3b106d08bc-6ec6d678af.zip deleted file mode 100644 index 46e2dec6988..00000000000 Binary files a/.yarn/cache/@npmcli-fs-npm-2.1.0-3b106d08bc-6ec6d678af.zip and /dev/null differ diff --git a/.yarn/cache/@npmcli-move-file-npm-2.0.0-d8bd1d35d2-1388777b50.zip b/.yarn/cache/@npmcli-move-file-npm-2.0.0-d8bd1d35d2-1388777b50.zip deleted file mode 100644 index e896df6c3fc..00000000000 Binary files a/.yarn/cache/@npmcli-move-file-npm-2.0.0-d8bd1d35d2-1388777b50.zip and /dev/null differ diff --git a/.yarn/cache/@parcel-bundler-default-npm-2.6.2-99c549a93d-f99c2b673b.zip b/.yarn/cache/@parcel-bundler-default-npm-2.6.2-99c549a93d-f99c2b673b.zip deleted file mode 100644 index 5ac46774bf3..00000000000 Binary files a/.yarn/cache/@parcel-bundler-default-npm-2.6.2-99c549a93d-f99c2b673b.zip and /dev/null differ diff --git a/.yarn/cache/@parcel-cache-npm-2.6.2-7c97030a45-e7b540fe10.zip b/.yarn/cache/@parcel-cache-npm-2.6.2-7c97030a45-e7b540fe10.zip deleted file mode 100644 index 723629aa3d0..00000000000 Binary files a/.yarn/cache/@parcel-cache-npm-2.6.2-7c97030a45-e7b540fe10.zip and /dev/null differ diff --git a/.yarn/cache/@parcel-codeframe-npm-2.6.2-39f0ef1504-3253f42b90.zip b/.yarn/cache/@parcel-codeframe-npm-2.6.2-39f0ef1504-3253f42b90.zip deleted file mode 100644 index c4b1f0bb0b2..00000000000 Binary files a/.yarn/cache/@parcel-codeframe-npm-2.6.2-39f0ef1504-3253f42b90.zip and /dev/null differ diff --git a/.yarn/cache/@parcel-compressor-raw-npm-2.6.2-32d58189e9-fb147eb189.zip b/.yarn/cache/@parcel-compressor-raw-npm-2.6.2-32d58189e9-fb147eb189.zip deleted file mode 100644 index 8eeaf4d4817..00000000000 Binary files a/.yarn/cache/@parcel-compressor-raw-npm-2.6.2-32d58189e9-fb147eb189.zip and /dev/null differ diff --git a/.yarn/cache/@parcel-config-default-npm-2.6.2-fd9b2d7d94-08cf9d08bb.zip b/.yarn/cache/@parcel-config-default-npm-2.6.2-fd9b2d7d94-08cf9d08bb.zip deleted file mode 100644 index bdc0f3f1d15..00000000000 Binary files a/.yarn/cache/@parcel-config-default-npm-2.6.2-fd9b2d7d94-08cf9d08bb.zip and /dev/null differ diff --git a/.yarn/cache/@parcel-core-npm-2.6.2-f04091cfa7-f550cbbd5e.zip b/.yarn/cache/@parcel-core-npm-2.6.2-f04091cfa7-f550cbbd5e.zip deleted file mode 100644 index ff094e0f822..00000000000 Binary files a/.yarn/cache/@parcel-core-npm-2.6.2-f04091cfa7-f550cbbd5e.zip and /dev/null differ diff --git a/.yarn/cache/@parcel-css-darwin-arm64-npm-1.10.1-03e9bc5743-8.zip b/.yarn/cache/@parcel-css-darwin-arm64-npm-1.10.1-03e9bc5743-8.zip deleted file mode 100644 index a9fd8f13f34..00000000000 Binary files a/.yarn/cache/@parcel-css-darwin-arm64-npm-1.10.1-03e9bc5743-8.zip and /dev/null differ diff --git a/.yarn/cache/@parcel-css-darwin-x64-npm-1.10.1-9fe704042c-8.zip b/.yarn/cache/@parcel-css-darwin-x64-npm-1.10.1-9fe704042c-8.zip deleted file mode 100644 index c16692f1155..00000000000 Binary files a/.yarn/cache/@parcel-css-darwin-x64-npm-1.10.1-9fe704042c-8.zip and /dev/null differ diff --git a/.yarn/cache/@parcel-css-linux-arm64-gnu-npm-1.10.1-f794ca00bb-8.zip b/.yarn/cache/@parcel-css-linux-arm64-gnu-npm-1.10.1-f794ca00bb-8.zip deleted file mode 100644 index c1428eae4bf..00000000000 Binary files a/.yarn/cache/@parcel-css-linux-arm64-gnu-npm-1.10.1-f794ca00bb-8.zip and /dev/null differ diff --git a/.yarn/cache/@parcel-css-linux-x64-gnu-npm-1.10.1-a1033caa61-8.zip b/.yarn/cache/@parcel-css-linux-x64-gnu-npm-1.10.1-a1033caa61-8.zip deleted file mode 100644 index a06848768c3..00000000000 Binary files a/.yarn/cache/@parcel-css-linux-x64-gnu-npm-1.10.1-a1033caa61-8.zip and /dev/null differ diff --git a/.yarn/cache/@parcel-css-npm-1.10.1-708147cb8f-699752d6ec.zip b/.yarn/cache/@parcel-css-npm-1.10.1-708147cb8f-699752d6ec.zip deleted file mode 100644 index 75178589343..00000000000 Binary files a/.yarn/cache/@parcel-css-npm-1.10.1-708147cb8f-699752d6ec.zip and /dev/null differ diff --git a/.yarn/cache/@parcel-css-win32-x64-msvc-npm-1.10.1-38319dc193-8.zip b/.yarn/cache/@parcel-css-win32-x64-msvc-npm-1.10.1-38319dc193-8.zip deleted file mode 100644 index fa3df20ff57..00000000000 Binary files a/.yarn/cache/@parcel-css-win32-x64-msvc-npm-1.10.1-38319dc193-8.zip and /dev/null differ diff --git a/.yarn/cache/@parcel-diagnostic-npm-2.6.2-ad66c9d460-c20c7b12c4.zip b/.yarn/cache/@parcel-diagnostic-npm-2.6.2-ad66c9d460-c20c7b12c4.zip deleted file mode 100644 index c30ebf1a5b7..00000000000 Binary files a/.yarn/cache/@parcel-diagnostic-npm-2.6.2-ad66c9d460-c20c7b12c4.zip and /dev/null differ diff --git a/.yarn/cache/@parcel-events-npm-2.6.2-c1dc15633e-272898db0c.zip b/.yarn/cache/@parcel-events-npm-2.6.2-c1dc15633e-272898db0c.zip deleted file mode 100644 index 425c449a7bb..00000000000 Binary files a/.yarn/cache/@parcel-events-npm-2.6.2-c1dc15633e-272898db0c.zip and /dev/null differ diff --git a/.yarn/cache/@parcel-fs-npm-2.6.2-1670f601e3-b5e324d93b.zip b/.yarn/cache/@parcel-fs-npm-2.6.2-1670f601e3-b5e324d93b.zip deleted file mode 100644 index e120fbb10dc..00000000000 Binary files a/.yarn/cache/@parcel-fs-npm-2.6.2-1670f601e3-b5e324d93b.zip and /dev/null differ diff --git a/.yarn/cache/@parcel-fs-search-npm-2.6.2-babb086a28-99850b1fd8.zip b/.yarn/cache/@parcel-fs-search-npm-2.6.2-babb086a28-99850b1fd8.zip deleted file mode 100644 index 46866183853..00000000000 Binary files a/.yarn/cache/@parcel-fs-search-npm-2.6.2-babb086a28-99850b1fd8.zip and /dev/null differ diff --git a/.yarn/cache/@parcel-graph-npm-2.6.2-21a1647d01-74490009e8.zip b/.yarn/cache/@parcel-graph-npm-2.6.2-21a1647d01-74490009e8.zip deleted file mode 100644 index 077b75d5912..00000000000 Binary files a/.yarn/cache/@parcel-graph-npm-2.6.2-21a1647d01-74490009e8.zip and /dev/null differ diff --git a/.yarn/cache/@parcel-hash-npm-2.6.2-b2130ce130-212f34e439.zip b/.yarn/cache/@parcel-hash-npm-2.6.2-b2130ce130-212f34e439.zip deleted file mode 100644 index b538f06584c..00000000000 Binary files a/.yarn/cache/@parcel-hash-npm-2.6.2-b2130ce130-212f34e439.zip and /dev/null differ diff --git a/.yarn/cache/@parcel-logger-npm-2.6.2-d7fe563ebb-d3536408da.zip b/.yarn/cache/@parcel-logger-npm-2.6.2-d7fe563ebb-d3536408da.zip deleted file mode 100644 index 7be36aa0509..00000000000 Binary files a/.yarn/cache/@parcel-logger-npm-2.6.2-d7fe563ebb-d3536408da.zip and /dev/null differ diff --git a/.yarn/cache/@parcel-markdown-ansi-npm-2.6.2-16ce118d53-742c64c5db.zip b/.yarn/cache/@parcel-markdown-ansi-npm-2.6.2-16ce118d53-742c64c5db.zip deleted file mode 100644 index 122104d0ece..00000000000 Binary files a/.yarn/cache/@parcel-markdown-ansi-npm-2.6.2-16ce118d53-742c64c5db.zip and /dev/null differ diff --git a/.yarn/cache/@parcel-namer-default-npm-2.6.2-a284c84566-259053a59f.zip b/.yarn/cache/@parcel-namer-default-npm-2.6.2-a284c84566-259053a59f.zip deleted file mode 100644 index e0838646188..00000000000 Binary files a/.yarn/cache/@parcel-namer-default-npm-2.6.2-a284c84566-259053a59f.zip and /dev/null differ diff --git a/.yarn/cache/@parcel-node-resolver-core-npm-2.6.2-ddf86db312-7746b309fa.zip b/.yarn/cache/@parcel-node-resolver-core-npm-2.6.2-ddf86db312-7746b309fa.zip deleted file mode 100644 index 0beb09862cf..00000000000 Binary files a/.yarn/cache/@parcel-node-resolver-core-npm-2.6.2-ddf86db312-7746b309fa.zip and /dev/null differ diff --git a/.yarn/cache/@parcel-optimizer-css-npm-2.6.2-8806a46a86-d1179276f4.zip b/.yarn/cache/@parcel-optimizer-css-npm-2.6.2-8806a46a86-d1179276f4.zip deleted file mode 100644 index c9dbb65fa7e..00000000000 Binary files a/.yarn/cache/@parcel-optimizer-css-npm-2.6.2-8806a46a86-d1179276f4.zip and /dev/null differ diff --git a/.yarn/cache/@parcel-optimizer-htmlnano-npm-2.6.2-3a6cbfa587-3b86fb1b17.zip b/.yarn/cache/@parcel-optimizer-htmlnano-npm-2.6.2-3a6cbfa587-3b86fb1b17.zip deleted file mode 100644 index 087148911a1..00000000000 Binary files a/.yarn/cache/@parcel-optimizer-htmlnano-npm-2.6.2-3a6cbfa587-3b86fb1b17.zip and /dev/null differ diff --git a/.yarn/cache/@parcel-optimizer-image-npm-2.6.2-da334eea79-d36e3c4d80.zip b/.yarn/cache/@parcel-optimizer-image-npm-2.6.2-da334eea79-d36e3c4d80.zip deleted file mode 100644 index 4dc5700f7c2..00000000000 Binary files a/.yarn/cache/@parcel-optimizer-image-npm-2.6.2-da334eea79-d36e3c4d80.zip and /dev/null differ diff --git a/.yarn/cache/@parcel-optimizer-svgo-npm-2.6.2-48d274d3c4-00b6737805.zip b/.yarn/cache/@parcel-optimizer-svgo-npm-2.6.2-48d274d3c4-00b6737805.zip deleted file mode 100644 index 94642832d30..00000000000 Binary files a/.yarn/cache/@parcel-optimizer-svgo-npm-2.6.2-48d274d3c4-00b6737805.zip and /dev/null differ diff --git a/.yarn/cache/@parcel-optimizer-terser-npm-2.6.2-a5c22918d5-1b9cdee197.zip b/.yarn/cache/@parcel-optimizer-terser-npm-2.6.2-a5c22918d5-1b9cdee197.zip deleted file mode 100644 index b6674ffcc5b..00000000000 Binary files a/.yarn/cache/@parcel-optimizer-terser-npm-2.6.2-a5c22918d5-1b9cdee197.zip and /dev/null differ diff --git a/.yarn/cache/@parcel-package-manager-npm-2.6.2-41edbfb7da-0c7dfce953.zip b/.yarn/cache/@parcel-package-manager-npm-2.6.2-41edbfb7da-0c7dfce953.zip deleted file mode 100644 index 38a6a916eb5..00000000000 Binary files a/.yarn/cache/@parcel-package-manager-npm-2.6.2-41edbfb7da-0c7dfce953.zip and /dev/null differ diff --git a/.yarn/cache/@parcel-packager-css-npm-2.6.2-4c2ce40a16-70d0c5195f.zip b/.yarn/cache/@parcel-packager-css-npm-2.6.2-4c2ce40a16-70d0c5195f.zip deleted file mode 100644 index ee3cd5073ed..00000000000 Binary files a/.yarn/cache/@parcel-packager-css-npm-2.6.2-4c2ce40a16-70d0c5195f.zip and /dev/null differ diff --git a/.yarn/cache/@parcel-packager-html-npm-2.6.2-44f9c9a0af-5f0095111d.zip b/.yarn/cache/@parcel-packager-html-npm-2.6.2-44f9c9a0af-5f0095111d.zip deleted file mode 100644 index e90654d8e61..00000000000 Binary files a/.yarn/cache/@parcel-packager-html-npm-2.6.2-44f9c9a0af-5f0095111d.zip and /dev/null differ diff --git a/.yarn/cache/@parcel-packager-js-npm-2.6.2-fc8a4a80e6-b441a709c6.zip b/.yarn/cache/@parcel-packager-js-npm-2.6.2-fc8a4a80e6-b441a709c6.zip deleted file mode 100644 index a3a9092c445..00000000000 Binary files a/.yarn/cache/@parcel-packager-js-npm-2.6.2-fc8a4a80e6-b441a709c6.zip and /dev/null differ diff --git a/.yarn/cache/@parcel-packager-raw-npm-2.6.2-c2c82c87c4-c067a612c0.zip b/.yarn/cache/@parcel-packager-raw-npm-2.6.2-c2c82c87c4-c067a612c0.zip deleted file mode 100644 index f3f2866bca8..00000000000 Binary files a/.yarn/cache/@parcel-packager-raw-npm-2.6.2-c2c82c87c4-c067a612c0.zip and /dev/null differ diff --git a/.yarn/cache/@parcel-packager-svg-npm-2.6.2-91ca24db32-50468d382f.zip b/.yarn/cache/@parcel-packager-svg-npm-2.6.2-91ca24db32-50468d382f.zip deleted file mode 100644 index 3d77df3cb41..00000000000 Binary files a/.yarn/cache/@parcel-packager-svg-npm-2.6.2-91ca24db32-50468d382f.zip and /dev/null differ diff --git a/.yarn/cache/@parcel-plugin-npm-2.6.2-d1ea2dda44-23da0fa372.zip b/.yarn/cache/@parcel-plugin-npm-2.6.2-d1ea2dda44-23da0fa372.zip deleted file mode 100644 index 931ab4f5b1a..00000000000 Binary files a/.yarn/cache/@parcel-plugin-npm-2.6.2-d1ea2dda44-23da0fa372.zip and /dev/null differ diff --git a/.yarn/cache/@parcel-reporter-cli-npm-2.6.2-04e1d13b83-27486b9c5c.zip b/.yarn/cache/@parcel-reporter-cli-npm-2.6.2-04e1d13b83-27486b9c5c.zip deleted file mode 100644 index 953020a1053..00000000000 Binary files a/.yarn/cache/@parcel-reporter-cli-npm-2.6.2-04e1d13b83-27486b9c5c.zip and /dev/null differ diff --git a/.yarn/cache/@parcel-reporter-dev-server-npm-2.6.2-22ced32479-44007a3bce.zip b/.yarn/cache/@parcel-reporter-dev-server-npm-2.6.2-22ced32479-44007a3bce.zip deleted file mode 100644 index 72eed708af5..00000000000 Binary files a/.yarn/cache/@parcel-reporter-dev-server-npm-2.6.2-22ced32479-44007a3bce.zip and /dev/null differ diff --git a/.yarn/cache/@parcel-resolver-default-npm-2.6.2-0584e152a0-e0dfff6e62.zip b/.yarn/cache/@parcel-resolver-default-npm-2.6.2-0584e152a0-e0dfff6e62.zip deleted file mode 100644 index 23e5e7d94c9..00000000000 Binary files a/.yarn/cache/@parcel-resolver-default-npm-2.6.2-0584e152a0-e0dfff6e62.zip and /dev/null differ diff --git a/.yarn/cache/@parcel-runtime-browser-hmr-npm-2.6.2-abf052bd22-39a324c4ef.zip b/.yarn/cache/@parcel-runtime-browser-hmr-npm-2.6.2-abf052bd22-39a324c4ef.zip deleted file mode 100644 index 7d620f1b9ef..00000000000 Binary files a/.yarn/cache/@parcel-runtime-browser-hmr-npm-2.6.2-abf052bd22-39a324c4ef.zip and /dev/null differ diff --git a/.yarn/cache/@parcel-runtime-js-npm-2.6.2-64b723c929-861e89c536.zip b/.yarn/cache/@parcel-runtime-js-npm-2.6.2-64b723c929-861e89c536.zip deleted file mode 100644 index 073c8f8c24c..00000000000 Binary files a/.yarn/cache/@parcel-runtime-js-npm-2.6.2-64b723c929-861e89c536.zip and /dev/null differ diff --git a/.yarn/cache/@parcel-runtime-react-refresh-npm-2.6.2-0e47dcf17b-0c33a13dd4.zip b/.yarn/cache/@parcel-runtime-react-refresh-npm-2.6.2-0e47dcf17b-0c33a13dd4.zip deleted file mode 100644 index 10ad3c23e5c..00000000000 Binary files a/.yarn/cache/@parcel-runtime-react-refresh-npm-2.6.2-0e47dcf17b-0c33a13dd4.zip and /dev/null differ diff --git a/.yarn/cache/@parcel-runtime-service-worker-npm-2.6.2-b2e2082392-2a9790ad27.zip b/.yarn/cache/@parcel-runtime-service-worker-npm-2.6.2-b2e2082392-2a9790ad27.zip deleted file mode 100644 index 9f3360c8295..00000000000 Binary files a/.yarn/cache/@parcel-runtime-service-worker-npm-2.6.2-b2e2082392-2a9790ad27.zip and /dev/null differ diff --git a/.yarn/cache/@parcel-source-map-npm-2.0.5-2444d2c092-b5e677edeb.zip b/.yarn/cache/@parcel-source-map-npm-2.0.5-2444d2c092-b5e677edeb.zip deleted file mode 100644 index cc14f479365..00000000000 Binary files a/.yarn/cache/@parcel-source-map-npm-2.0.5-2444d2c092-b5e677edeb.zip and /dev/null differ diff --git a/.yarn/cache/@parcel-transformer-babel-npm-2.6.2-c5c9478ebe-c7f14b76bf.zip b/.yarn/cache/@parcel-transformer-babel-npm-2.6.2-c5c9478ebe-c7f14b76bf.zip deleted file mode 100644 index 851c707eda7..00000000000 Binary files a/.yarn/cache/@parcel-transformer-babel-npm-2.6.2-c5c9478ebe-c7f14b76bf.zip and /dev/null differ diff --git a/.yarn/cache/@parcel-transformer-css-npm-2.6.2-ab5a4c9465-2a8ac50457.zip b/.yarn/cache/@parcel-transformer-css-npm-2.6.2-ab5a4c9465-2a8ac50457.zip deleted file mode 100644 index 8a764bf8769..00000000000 Binary files a/.yarn/cache/@parcel-transformer-css-npm-2.6.2-ab5a4c9465-2a8ac50457.zip and /dev/null differ diff --git a/.yarn/cache/@parcel-transformer-html-npm-2.6.2-bf84827f26-6d37d556aa.zip b/.yarn/cache/@parcel-transformer-html-npm-2.6.2-bf84827f26-6d37d556aa.zip deleted file mode 100644 index 61d3ef506dd..00000000000 Binary files a/.yarn/cache/@parcel-transformer-html-npm-2.6.2-bf84827f26-6d37d556aa.zip and /dev/null differ diff --git a/.yarn/cache/@parcel-transformer-image-npm-2.6.2-28b8a807bd-2627a162b9.zip b/.yarn/cache/@parcel-transformer-image-npm-2.6.2-28b8a807bd-2627a162b9.zip deleted file mode 100644 index 3abdc57616a..00000000000 Binary files a/.yarn/cache/@parcel-transformer-image-npm-2.6.2-28b8a807bd-2627a162b9.zip and /dev/null differ diff --git a/.yarn/cache/@parcel-transformer-js-npm-2.6.2-1b820e17da-32a0480b29.zip b/.yarn/cache/@parcel-transformer-js-npm-2.6.2-1b820e17da-32a0480b29.zip deleted file mode 100644 index 0744c42b95f..00000000000 Binary files a/.yarn/cache/@parcel-transformer-js-npm-2.6.2-1b820e17da-32a0480b29.zip and /dev/null differ diff --git a/.yarn/cache/@parcel-transformer-json-npm-2.6.2-e55c433bcb-0b4162ba93.zip b/.yarn/cache/@parcel-transformer-json-npm-2.6.2-e55c433bcb-0b4162ba93.zip deleted file mode 100644 index 7ed03e5945c..00000000000 Binary files a/.yarn/cache/@parcel-transformer-json-npm-2.6.2-e55c433bcb-0b4162ba93.zip and /dev/null differ diff --git a/.yarn/cache/@parcel-transformer-postcss-npm-2.6.2-3da3a44a17-473d1e96f9.zip b/.yarn/cache/@parcel-transformer-postcss-npm-2.6.2-3da3a44a17-473d1e96f9.zip deleted file mode 100644 index 995280b71f5..00000000000 Binary files a/.yarn/cache/@parcel-transformer-postcss-npm-2.6.2-3da3a44a17-473d1e96f9.zip and /dev/null differ diff --git a/.yarn/cache/@parcel-transformer-posthtml-npm-2.6.2-7d4694cfa8-3ddb727aa2.zip b/.yarn/cache/@parcel-transformer-posthtml-npm-2.6.2-7d4694cfa8-3ddb727aa2.zip deleted file mode 100644 index 1f295093c29..00000000000 Binary files a/.yarn/cache/@parcel-transformer-posthtml-npm-2.6.2-7d4694cfa8-3ddb727aa2.zip and /dev/null differ diff --git a/.yarn/cache/@parcel-transformer-raw-npm-2.6.2-0f247428f1-aa8543194f.zip b/.yarn/cache/@parcel-transformer-raw-npm-2.6.2-0f247428f1-aa8543194f.zip deleted file mode 100644 index 0fa88a0c456..00000000000 Binary files a/.yarn/cache/@parcel-transformer-raw-npm-2.6.2-0f247428f1-aa8543194f.zip and /dev/null differ diff --git a/.yarn/cache/@parcel-transformer-react-refresh-wrap-npm-2.6.2-62385046b0-6655b93d5e.zip b/.yarn/cache/@parcel-transformer-react-refresh-wrap-npm-2.6.2-62385046b0-6655b93d5e.zip deleted file mode 100644 index 4ed9ecb0a33..00000000000 Binary files a/.yarn/cache/@parcel-transformer-react-refresh-wrap-npm-2.6.2-62385046b0-6655b93d5e.zip and /dev/null differ diff --git a/.yarn/cache/@parcel-transformer-sass-npm-2.6.2-b485ae126e-b35e8d272f.zip b/.yarn/cache/@parcel-transformer-sass-npm-2.6.2-b485ae126e-b35e8d272f.zip deleted file mode 100644 index 30033d24935..00000000000 Binary files a/.yarn/cache/@parcel-transformer-sass-npm-2.6.2-b485ae126e-b35e8d272f.zip and /dev/null differ diff --git a/.yarn/cache/@parcel-transformer-svg-npm-2.6.2-11420db70b-b768ecc0c6.zip b/.yarn/cache/@parcel-transformer-svg-npm-2.6.2-11420db70b-b768ecc0c6.zip deleted file mode 100644 index 0ea3743fd11..00000000000 Binary files a/.yarn/cache/@parcel-transformer-svg-npm-2.6.2-11420db70b-b768ecc0c6.zip and /dev/null differ diff --git a/.yarn/cache/@parcel-types-npm-2.6.2-aa1797faca-16f3c3ac36.zip b/.yarn/cache/@parcel-types-npm-2.6.2-aa1797faca-16f3c3ac36.zip deleted file mode 100644 index e253b54d319..00000000000 Binary files a/.yarn/cache/@parcel-types-npm-2.6.2-aa1797faca-16f3c3ac36.zip and /dev/null differ diff --git a/.yarn/cache/@parcel-utils-npm-2.6.2-cab87aed21-a74fdca966.zip b/.yarn/cache/@parcel-utils-npm-2.6.2-cab87aed21-a74fdca966.zip deleted file mode 100644 index 912047a77c6..00000000000 Binary files a/.yarn/cache/@parcel-utils-npm-2.6.2-cab87aed21-a74fdca966.zip and /dev/null differ diff --git a/.yarn/cache/@parcel-watcher-npm-2.0.5-bda35fb0f8-ddc5b073e8.zip b/.yarn/cache/@parcel-watcher-npm-2.0.5-bda35fb0f8-ddc5b073e8.zip deleted file mode 100644 index 1a7eee4a34f..00000000000 Binary files a/.yarn/cache/@parcel-watcher-npm-2.0.5-bda35fb0f8-ddc5b073e8.zip and /dev/null differ diff --git a/.yarn/cache/@parcel-workers-npm-2.6.2-a30e38db52-92b65cd3fd.zip b/.yarn/cache/@parcel-workers-npm-2.6.2-a30e38db52-92b65cd3fd.zip deleted file mode 100644 index bd89f95b92b..00000000000 Binary files a/.yarn/cache/@parcel-workers-npm-2.6.2-a30e38db52-92b65cd3fd.zip and /dev/null differ diff --git a/.yarn/cache/@popperjs-core-npm-2.11.5-a338f16bd4-fd7f9dca3f.zip b/.yarn/cache/@popperjs-core-npm-2.11.5-a338f16bd4-fd7f9dca3f.zip deleted file mode 100644 index e52b2d62eea..00000000000 Binary files a/.yarn/cache/@popperjs-core-npm-2.11.5-a338f16bd4-fd7f9dca3f.zip and /dev/null differ diff --git a/.yarn/cache/@sidvind-better-ajv-errors-npm-2.0.0-3531bddef9-12b0d87855.zip b/.yarn/cache/@sidvind-better-ajv-errors-npm-2.0.0-3531bddef9-12b0d87855.zip deleted file mode 100644 index 5990cc76044..00000000000 Binary files a/.yarn/cache/@sidvind-better-ajv-errors-npm-2.0.0-3531bddef9-12b0d87855.zip and /dev/null differ diff --git a/.yarn/cache/@swc-helpers-npm-0.4.3-5d4bea11d2-5c2f173e95.zip b/.yarn/cache/@swc-helpers-npm-0.4.3-5d4bea11d2-5c2f173e95.zip deleted file mode 100644 index a6e2cc58d43..00000000000 Binary files a/.yarn/cache/@swc-helpers-npm-0.4.3-5d4bea11d2-5c2f173e95.zip and /dev/null differ diff --git a/.yarn/cache/@tootallnate-once-npm-2.0.0-e36cf4f140-ad87447820.zip b/.yarn/cache/@tootallnate-once-npm-2.0.0-e36cf4f140-ad87447820.zip deleted file mode 100644 index d240a82ae2f..00000000000 Binary files a/.yarn/cache/@tootallnate-once-npm-2.0.0-e36cf4f140-ad87447820.zip and /dev/null differ diff --git a/.yarn/cache/@trysound-sax-npm-0.2.0-9f763d0295-11226c39b5.zip b/.yarn/cache/@trysound-sax-npm-0.2.0-9f763d0295-11226c39b5.zip deleted file mode 100644 index 97460317597..00000000000 Binary files a/.yarn/cache/@trysound-sax-npm-0.2.0-9f763d0295-11226c39b5.zip and /dev/null differ diff --git a/.yarn/cache/@types-chai-npm-4.3.1-dab3901c30-2ee246b76c.zip b/.yarn/cache/@types-chai-npm-4.3.1-dab3901c30-2ee246b76c.zip deleted file mode 100644 index 2b362280b75..00000000000 Binary files a/.yarn/cache/@types-chai-npm-4.3.1-dab3901c30-2ee246b76c.zip and /dev/null differ diff --git a/.yarn/cache/@types-chai-subset-npm-1.3.3-acf55b3b37-4481da7345.zip b/.yarn/cache/@types-chai-subset-npm-1.3.3-acf55b3b37-4481da7345.zip deleted file mode 100644 index 7f5de5f4789..00000000000 Binary files a/.yarn/cache/@types-chai-subset-npm-1.3.3-acf55b3b37-4481da7345.zip and /dev/null differ diff --git a/.yarn/cache/@types-istanbul-lib-coverage-npm-2.0.4-734954bb56-a25d7589ee.zip b/.yarn/cache/@types-istanbul-lib-coverage-npm-2.0.4-734954bb56-a25d7589ee.zip deleted file mode 100644 index 75f6652baac..00000000000 Binary files a/.yarn/cache/@types-istanbul-lib-coverage-npm-2.0.4-734954bb56-a25d7589ee.zip and /dev/null differ diff --git a/.yarn/cache/@types-jest-npm-27.4.1-31d07cd0d8-5184f3eef4.zip b/.yarn/cache/@types-jest-npm-27.4.1-31d07cd0d8-5184f3eef4.zip deleted file mode 100644 index 28e1c1b1249..00000000000 Binary files a/.yarn/cache/@types-jest-npm-27.4.1-31d07cd0d8-5184f3eef4.zip and /dev/null differ diff --git a/.yarn/cache/@types-json5-npm-0.0.29-f63a7916bd-e60b153664.zip b/.yarn/cache/@types-json5-npm-0.0.29-f63a7916bd-e60b153664.zip deleted file mode 100644 index 82bfbc82ae9..00000000000 Binary files a/.yarn/cache/@types-json5-npm-0.0.29-f63a7916bd-e60b153664.zip and /dev/null differ diff --git a/.yarn/cache/@types-lodash-es-npm-4.17.6-fd5abbdc74-9bd239dd52.zip b/.yarn/cache/@types-lodash-es-npm-4.17.6-fd5abbdc74-9bd239dd52.zip deleted file mode 100644 index 3bd29bcbad1..00000000000 Binary files a/.yarn/cache/@types-lodash-es-npm-4.17.6-fd5abbdc74-9bd239dd52.zip and /dev/null differ diff --git a/.yarn/cache/@types-lodash-npm-4.14.182-1073aac722-7dd137aa9d.zip b/.yarn/cache/@types-lodash-npm-4.14.182-1073aac722-7dd137aa9d.zip deleted file mode 100644 index 56f0da6f275..00000000000 Binary files a/.yarn/cache/@types-lodash-npm-4.14.182-1073aac722-7dd137aa9d.zip and /dev/null differ diff --git a/.yarn/cache/@types-node-npm-14.18.18-2f8f733938-a165225cd2.zip b/.yarn/cache/@types-node-npm-14.18.18-2f8f733938-a165225cd2.zip deleted file mode 100644 index ffdc271bf1e..00000000000 Binary files a/.yarn/cache/@types-node-npm-14.18.18-2f8f733938-a165225cd2.zip and /dev/null differ diff --git a/.yarn/cache/@types-node-npm-17.0.29-0de8e6d3d0-bb9d7bce9d.zip b/.yarn/cache/@types-node-npm-17.0.29-0de8e6d3d0-bb9d7bce9d.zip deleted file mode 100644 index 21a0e51f1ed..00000000000 Binary files a/.yarn/cache/@types-node-npm-17.0.29-0de8e6d3d0-bb9d7bce9d.zip and /dev/null differ diff --git a/.yarn/cache/@types-parse-json-npm-4.0.0-298522afa6-fd6bce2b67.zip b/.yarn/cache/@types-parse-json-npm-4.0.0-298522afa6-fd6bce2b67.zip deleted file mode 100644 index 6bd507a4cf7..00000000000 Binary files a/.yarn/cache/@types-parse-json-npm-4.0.0-298522afa6-fd6bce2b67.zip and /dev/null differ diff --git a/.yarn/cache/@types-sinonjs__fake-timers-npm-8.1.1-95ac9b59b5-ca09d54d47.zip b/.yarn/cache/@types-sinonjs__fake-timers-npm-8.1.1-95ac9b59b5-ca09d54d47.zip deleted file mode 100644 index f862c6baad2..00000000000 Binary files a/.yarn/cache/@types-sinonjs__fake-timers-npm-8.1.1-95ac9b59b5-ca09d54d47.zip and /dev/null differ diff --git a/.yarn/cache/@types-sizzle-npm-2.3.3-9403924950-586a9fb1f6.zip b/.yarn/cache/@types-sizzle-npm-2.3.3-9403924950-586a9fb1f6.zip deleted file mode 100644 index 52a4f8df233..00000000000 Binary files a/.yarn/cache/@types-sizzle-npm-2.3.3-9403924950-586a9fb1f6.zip and /dev/null differ diff --git a/.yarn/cache/@types-yauzl-npm-2.10.0-7b242343cb-55d27ae5d3.zip b/.yarn/cache/@types-yauzl-npm-2.10.0-7b242343cb-55d27ae5d3.zip deleted file mode 100644 index 0d3bbb8f9fb..00000000000 Binary files a/.yarn/cache/@types-yauzl-npm-2.10.0-7b242343cb-55d27ae5d3.zip and /dev/null differ diff --git a/.yarn/cache/@vitejs-plugin-vue-npm-2.3.3-89ac1da9f4-9303dcb9c8.zip b/.yarn/cache/@vitejs-plugin-vue-npm-2.3.3-89ac1da9f4-9303dcb9c8.zip deleted file mode 100644 index bfe4d70ebbb..00000000000 Binary files a/.yarn/cache/@vitejs-plugin-vue-npm-2.3.3-89ac1da9f4-9303dcb9c8.zip and /dev/null differ diff --git a/.yarn/cache/@vue-compiler-core-npm-3.2.37-1ed1423427-5642e20813.zip b/.yarn/cache/@vue-compiler-core-npm-3.2.37-1ed1423427-5642e20813.zip deleted file mode 100644 index 82b0f0af818..00000000000 Binary files a/.yarn/cache/@vue-compiler-core-npm-3.2.37-1ed1423427-5642e20813.zip and /dev/null differ diff --git a/.yarn/cache/@vue-compiler-dom-npm-3.2.37-b8cfefaa49-6cfa9d2ee1.zip b/.yarn/cache/@vue-compiler-dom-npm-3.2.37-b8cfefaa49-6cfa9d2ee1.zip deleted file mode 100644 index 4f39eb02b61..00000000000 Binary files a/.yarn/cache/@vue-compiler-dom-npm-3.2.37-b8cfefaa49-6cfa9d2ee1.zip and /dev/null differ diff --git a/.yarn/cache/@vue-compiler-sfc-npm-3.2.37-a6956912bb-9f9067d79f.zip b/.yarn/cache/@vue-compiler-sfc-npm-3.2.37-a6956912bb-9f9067d79f.zip deleted file mode 100644 index 71c8db8440a..00000000000 Binary files a/.yarn/cache/@vue-compiler-sfc-npm-3.2.37-a6956912bb-9f9067d79f.zip and /dev/null differ diff --git a/.yarn/cache/@vue-compiler-ssr-npm-3.2.37-30882c5f14-e137462340.zip b/.yarn/cache/@vue-compiler-ssr-npm-3.2.37-30882c5f14-e137462340.zip deleted file mode 100644 index 1c01e104840..00000000000 Binary files a/.yarn/cache/@vue-compiler-ssr-npm-3.2.37-30882c5f14-e137462340.zip and /dev/null differ diff --git a/.yarn/cache/@vue-devtools-api-npm-6.1.4-4ee2c9cc71-027bb138b0.zip b/.yarn/cache/@vue-devtools-api-npm-6.1.4-4ee2c9cc71-027bb138b0.zip deleted file mode 100644 index f958639b263..00000000000 Binary files a/.yarn/cache/@vue-devtools-api-npm-6.1.4-4ee2c9cc71-027bb138b0.zip and /dev/null differ diff --git a/.yarn/cache/@vue-reactivity-npm-3.2.37-b6bb8fbcbd-94e353f8b8.zip b/.yarn/cache/@vue-reactivity-npm-3.2.37-b6bb8fbcbd-94e353f8b8.zip deleted file mode 100644 index 4415c3eeb4d..00000000000 Binary files a/.yarn/cache/@vue-reactivity-npm-3.2.37-b6bb8fbcbd-94e353f8b8.zip and /dev/null differ diff --git a/.yarn/cache/@vue-reactivity-transform-npm-3.2.37-96d5a7d46e-d9e7c353e2.zip b/.yarn/cache/@vue-reactivity-transform-npm-3.2.37-96d5a7d46e-d9e7c353e2.zip deleted file mode 100644 index 9a30ec782eb..00000000000 Binary files a/.yarn/cache/@vue-reactivity-transform-npm-3.2.37-96d5a7d46e-d9e7c353e2.zip and /dev/null differ diff --git a/.yarn/cache/@vue-runtime-core-npm-3.2.37-4babb388df-8dbf4e1f97.zip b/.yarn/cache/@vue-runtime-core-npm-3.2.37-4babb388df-8dbf4e1f97.zip deleted file mode 100644 index 9779d93837e..00000000000 Binary files a/.yarn/cache/@vue-runtime-core-npm-3.2.37-4babb388df-8dbf4e1f97.zip and /dev/null differ diff --git a/.yarn/cache/@vue-runtime-dom-npm-3.2.37-6bd25ee477-36dddfd561.zip b/.yarn/cache/@vue-runtime-dom-npm-3.2.37-6bd25ee477-36dddfd561.zip deleted file mode 100644 index e891e1592a6..00000000000 Binary files a/.yarn/cache/@vue-runtime-dom-npm-3.2.37-6bd25ee477-36dddfd561.zip and /dev/null differ diff --git a/.yarn/cache/@vue-server-renderer-npm-3.2.37-93c5150576-634d43cd21.zip b/.yarn/cache/@vue-server-renderer-npm-3.2.37-93c5150576-634d43cd21.zip deleted file mode 100644 index 6ae0563a213..00000000000 Binary files a/.yarn/cache/@vue-server-renderer-npm-3.2.37-93c5150576-634d43cd21.zip and /dev/null differ diff --git a/.yarn/cache/@vue-shared-npm-3.2.37-60a8943fc6-999ab8baeb.zip b/.yarn/cache/@vue-shared-npm-3.2.37-60a8943fc6-999ab8baeb.zip deleted file mode 100644 index 8c5efaa452e..00000000000 Binary files a/.yarn/cache/@vue-shared-npm-3.2.37-60a8943fc6-999ab8baeb.zip and /dev/null differ diff --git a/.yarn/cache/@vue-test-utils-npm-2.0.2-8fecfc05d1-384bdd4231.zip b/.yarn/cache/@vue-test-utils-npm-2.0.2-8fecfc05d1-384bdd4231.zip deleted file mode 100644 index 57193c4ecde..00000000000 Binary files a/.yarn/cache/@vue-test-utils-npm-2.0.2-8fecfc05d1-384bdd4231.zip and /dev/null differ diff --git a/.yarn/cache/abbrev-npm-1.1.1-3659247eab-a4a97ec07d.zip b/.yarn/cache/abbrev-npm-1.1.1-3659247eab-a4a97ec07d.zip deleted file mode 100644 index a8b40a5f9dc..00000000000 Binary files a/.yarn/cache/abbrev-npm-1.1.1-3659247eab-a4a97ec07d.zip and /dev/null differ diff --git a/.yarn/cache/abortcontroller-polyfill-npm-1.7.3-3b01198b7a-55739d7f0c.zip b/.yarn/cache/abortcontroller-polyfill-npm-1.7.3-3b01198b7a-55739d7f0c.zip deleted file mode 100644 index 4172386d9b7..00000000000 Binary files a/.yarn/cache/abortcontroller-polyfill-npm-1.7.3-3b01198b7a-55739d7f0c.zip and /dev/null differ diff --git a/.yarn/cache/acorn-jsx-npm-5.3.2-d7594599ea-c3d3b2a89c.zip b/.yarn/cache/acorn-jsx-npm-5.3.2-d7594599ea-c3d3b2a89c.zip deleted file mode 100644 index 786b9ec4f1b..00000000000 Binary files a/.yarn/cache/acorn-jsx-npm-5.3.2-d7594599ea-c3d3b2a89c.zip and /dev/null differ diff --git a/.yarn/cache/acorn-npm-7.4.1-f450b4646c-1860f23c21.zip b/.yarn/cache/acorn-npm-7.4.1-f450b4646c-1860f23c21.zip deleted file mode 100644 index 9fdd0487b42..00000000000 Binary files a/.yarn/cache/acorn-npm-7.4.1-f450b4646c-1860f23c21.zip and /dev/null differ diff --git a/.yarn/cache/acorn-npm-8.7.1-7c7a019990-aca0aabf98.zip b/.yarn/cache/acorn-npm-8.7.1-7c7a019990-aca0aabf98.zip deleted file mode 100644 index 7cb7203ce3b..00000000000 Binary files a/.yarn/cache/acorn-npm-8.7.1-7c7a019990-aca0aabf98.zip and /dev/null differ diff --git a/.yarn/cache/acorn-walk-npm-8.2.0-2f2cac3177-1715e76c01.zip b/.yarn/cache/acorn-walk-npm-8.2.0-2f2cac3177-1715e76c01.zip deleted file mode 100644 index f140c4ab5c2..00000000000 Binary files a/.yarn/cache/acorn-walk-npm-8.2.0-2f2cac3177-1715e76c01.zip and /dev/null differ diff --git a/.yarn/cache/agent-base-npm-6.0.2-428f325a93-f52b6872cc.zip b/.yarn/cache/agent-base-npm-6.0.2-428f325a93-f52b6872cc.zip deleted file mode 100644 index c7d271af28b..00000000000 Binary files a/.yarn/cache/agent-base-npm-6.0.2-428f325a93-f52b6872cc.zip and /dev/null differ diff --git a/.yarn/cache/agentkeepalive-npm-4.2.1-b86a9fb343-39cb49ed8c.zip b/.yarn/cache/agentkeepalive-npm-4.2.1-b86a9fb343-39cb49ed8c.zip deleted file mode 100644 index 1814332a28a..00000000000 Binary files a/.yarn/cache/agentkeepalive-npm-4.2.1-b86a9fb343-39cb49ed8c.zip and /dev/null differ diff --git a/.yarn/cache/aggregate-error-npm-3.1.0-415a406f4e-1101a33f21.zip b/.yarn/cache/aggregate-error-npm-3.1.0-415a406f4e-1101a33f21.zip deleted file mode 100644 index 7db0127bfdb..00000000000 Binary files a/.yarn/cache/aggregate-error-npm-3.1.0-415a406f4e-1101a33f21.zip and /dev/null differ diff --git a/.yarn/cache/ajv-npm-6.12.6-4b5105e2b2-874972efe5.zip b/.yarn/cache/ajv-npm-6.12.6-4b5105e2b2-874972efe5.zip deleted file mode 100644 index 16973dd8c54..00000000000 Binary files a/.yarn/cache/ajv-npm-6.12.6-4b5105e2b2-874972efe5.zip and /dev/null differ diff --git a/.yarn/cache/ajv-npm-8.11.0-83d029789c-5e0ff22680.zip b/.yarn/cache/ajv-npm-8.11.0-83d029789c-5e0ff22680.zip deleted file mode 100644 index ef7be34bb33..00000000000 Binary files a/.yarn/cache/ajv-npm-8.11.0-83d029789c-5e0ff22680.zip and /dev/null differ diff --git a/.yarn/cache/ansi-colors-npm-4.1.3-8ffd0ae6c7-a9c2ec8420.zip b/.yarn/cache/ansi-colors-npm-4.1.3-8ffd0ae6c7-a9c2ec8420.zip deleted file mode 100644 index cad48c8f0e3..00000000000 Binary files a/.yarn/cache/ansi-colors-npm-4.1.3-8ffd0ae6c7-a9c2ec8420.zip and /dev/null differ diff --git a/.yarn/cache/ansi-escapes-npm-4.3.2-3ad173702f-93111c4218.zip b/.yarn/cache/ansi-escapes-npm-4.3.2-3ad173702f-93111c4218.zip deleted file mode 100644 index 6b90effb518..00000000000 Binary files a/.yarn/cache/ansi-escapes-npm-4.3.2-3ad173702f-93111c4218.zip and /dev/null differ diff --git a/.yarn/cache/ansi-regex-npm-5.0.1-c963a48615-2aa4bb54ca.zip b/.yarn/cache/ansi-regex-npm-5.0.1-c963a48615-2aa4bb54ca.zip deleted file mode 100644 index fffc17acac2..00000000000 Binary files a/.yarn/cache/ansi-regex-npm-5.0.1-c963a48615-2aa4bb54ca.zip and /dev/null differ diff --git a/.yarn/cache/ansi-styles-npm-3.2.1-8cb8107983-d85ade01c1.zip b/.yarn/cache/ansi-styles-npm-3.2.1-8cb8107983-d85ade01c1.zip deleted file mode 100644 index 4ffdcc49463..00000000000 Binary files a/.yarn/cache/ansi-styles-npm-3.2.1-8cb8107983-d85ade01c1.zip and /dev/null differ diff --git a/.yarn/cache/ansi-styles-npm-4.3.0-245c7d42c7-513b44c3b2.zip b/.yarn/cache/ansi-styles-npm-4.3.0-245c7d42c7-513b44c3b2.zip deleted file mode 100644 index a18e3e6439c..00000000000 Binary files a/.yarn/cache/ansi-styles-npm-4.3.0-245c7d42c7-513b44c3b2.zip and /dev/null differ diff --git a/.yarn/cache/ansi-styles-npm-5.2.0-72fc7003e3-d7f4e97ce0.zip b/.yarn/cache/ansi-styles-npm-5.2.0-72fc7003e3-d7f4e97ce0.zip deleted file mode 100644 index 62c09039bd1..00000000000 Binary files a/.yarn/cache/ansi-styles-npm-5.2.0-72fc7003e3-d7f4e97ce0.zip and /dev/null differ diff --git a/.yarn/cache/anymatch-npm-3.1.2-1d5471acfa-985163db22.zip b/.yarn/cache/anymatch-npm-3.1.2-1d5471acfa-985163db22.zip deleted file mode 100644 index b71280dc2a7..00000000000 Binary files a/.yarn/cache/anymatch-npm-3.1.2-1d5471acfa-985163db22.zip and /dev/null differ diff --git a/.yarn/cache/aproba-npm-2.0.0-8716bcfde6-5615cadcfb.zip b/.yarn/cache/aproba-npm-2.0.0-8716bcfde6-5615cadcfb.zip deleted file mode 100644 index 6b148888c0e..00000000000 Binary files a/.yarn/cache/aproba-npm-2.0.0-8716bcfde6-5615cadcfb.zip and /dev/null differ diff --git a/.yarn/cache/arch-npm-2.2.0-34797684d8-e21b763502.zip b/.yarn/cache/arch-npm-2.2.0-34797684d8-e21b763502.zip deleted file mode 100644 index e0f407e8c45..00000000000 Binary files a/.yarn/cache/arch-npm-2.2.0-34797684d8-e21b763502.zip and /dev/null differ diff --git a/.yarn/cache/are-we-there-yet-npm-3.0.0-1391430190-348edfdd93.zip b/.yarn/cache/are-we-there-yet-npm-3.0.0-1391430190-348edfdd93.zip deleted file mode 100644 index b4d0a71b828..00000000000 Binary files a/.yarn/cache/are-we-there-yet-npm-3.0.0-1391430190-348edfdd93.zip and /dev/null differ diff --git a/.yarn/cache/argparse-npm-2.0.1-faff7999e6-83644b5649.zip b/.yarn/cache/argparse-npm-2.0.1-faff7999e6-83644b5649.zip deleted file mode 100644 index 26a9ce4aca9..00000000000 Binary files a/.yarn/cache/argparse-npm-2.0.1-faff7999e6-83644b5649.zip and /dev/null differ diff --git a/.yarn/cache/array-includes-npm-3.1.4-79bb883109-69967c38c5.zip b/.yarn/cache/array-includes-npm-3.1.4-79bb883109-69967c38c5.zip deleted file mode 100644 index c88aec7c23b..00000000000 Binary files a/.yarn/cache/array-includes-npm-3.1.4-79bb883109-69967c38c5.zip and /dev/null differ diff --git a/.yarn/cache/array.prototype.flat-npm-1.3.0-6c5c4292bd-2a652b3e8d.zip b/.yarn/cache/array.prototype.flat-npm-1.3.0-6c5c4292bd-2a652b3e8d.zip deleted file mode 100644 index 66f81fb0ab7..00000000000 Binary files a/.yarn/cache/array.prototype.flat-npm-1.3.0-6c5c4292bd-2a652b3e8d.zip and /dev/null differ diff --git a/.yarn/cache/asap-npm-2.0.6-36714d439d-b296c92c4b.zip b/.yarn/cache/asap-npm-2.0.6-36714d439d-b296c92c4b.zip deleted file mode 100644 index ca3c4366bdd..00000000000 Binary files a/.yarn/cache/asap-npm-2.0.6-36714d439d-b296c92c4b.zip and /dev/null differ diff --git a/.yarn/cache/asn1-npm-0.2.6-bdd07356c4-39f2ae343b.zip b/.yarn/cache/asn1-npm-0.2.6-bdd07356c4-39f2ae343b.zip deleted file mode 100644 index a6463962d7b..00000000000 Binary files a/.yarn/cache/asn1-npm-0.2.6-bdd07356c4-39f2ae343b.zip and /dev/null differ diff --git a/.yarn/cache/assert-never-npm-1.2.1-d423b480cd-ea4f1756d9.zip b/.yarn/cache/assert-never-npm-1.2.1-d423b480cd-ea4f1756d9.zip deleted file mode 100644 index 8922d1d4e3a..00000000000 Binary files a/.yarn/cache/assert-never-npm-1.2.1-d423b480cd-ea4f1756d9.zip and /dev/null differ diff --git a/.yarn/cache/assert-plus-npm-1.0.0-cac95ef098-19b4340cb8.zip b/.yarn/cache/assert-plus-npm-1.0.0-cac95ef098-19b4340cb8.zip deleted file mode 100644 index 30c557d6878..00000000000 Binary files a/.yarn/cache/assert-plus-npm-1.0.0-cac95ef098-19b4340cb8.zip and /dev/null differ diff --git a/.yarn/cache/assertion-error-npm-1.1.0-66b893015e-fd9429d3a3.zip b/.yarn/cache/assertion-error-npm-1.1.0-66b893015e-fd9429d3a3.zip deleted file mode 100644 index e7b45eee3a5..00000000000 Binary files a/.yarn/cache/assertion-error-npm-1.1.0-66b893015e-fd9429d3a3.zip and /dev/null differ diff --git a/.yarn/cache/astral-regex-npm-2.0.0-f30d866aab-876231688c.zip b/.yarn/cache/astral-regex-npm-2.0.0-f30d866aab-876231688c.zip deleted file mode 100644 index 1af622c047d..00000000000 Binary files a/.yarn/cache/astral-regex-npm-2.0.0-f30d866aab-876231688c.zip and /dev/null differ diff --git a/.yarn/cache/async-npm-3.2.3-e9d6b79c88-c4bee57ab2.zip b/.yarn/cache/async-npm-3.2.3-e9d6b79c88-c4bee57ab2.zip deleted file mode 100644 index 21eb18386d5..00000000000 Binary files a/.yarn/cache/async-npm-3.2.3-e9d6b79c88-c4bee57ab2.zip and /dev/null differ diff --git a/.yarn/cache/async-validator-npm-4.1.1-470b8d5b59-88590ab8ad.zip b/.yarn/cache/async-validator-npm-4.1.1-470b8d5b59-88590ab8ad.zip deleted file mode 100644 index 71730f2e231..00000000000 Binary files a/.yarn/cache/async-validator-npm-4.1.1-470b8d5b59-88590ab8ad.zip and /dev/null differ diff --git a/.yarn/cache/asynckit-npm-0.4.0-c718858525-7b78c451df.zip b/.yarn/cache/asynckit-npm-0.4.0-c718858525-7b78c451df.zip deleted file mode 100644 index bb08c24f1bf..00000000000 Binary files a/.yarn/cache/asynckit-npm-0.4.0-c718858525-7b78c451df.zip and /dev/null differ diff --git a/.yarn/cache/at-least-node-npm-1.0.0-2b36e661fa-463e2f8e43.zip b/.yarn/cache/at-least-node-npm-1.0.0-2b36e661fa-463e2f8e43.zip deleted file mode 100644 index bc549750e64..00000000000 Binary files a/.yarn/cache/at-least-node-npm-1.0.0-2b36e661fa-463e2f8e43.zip and /dev/null differ diff --git a/.yarn/cache/aws-sign2-npm-0.7.0-656c6cb84d-b148b0bb07.zip b/.yarn/cache/aws-sign2-npm-0.7.0-656c6cb84d-b148b0bb07.zip deleted file mode 100644 index 6d41947851d..00000000000 Binary files a/.yarn/cache/aws-sign2-npm-0.7.0-656c6cb84d-b148b0bb07.zip and /dev/null differ diff --git a/.yarn/cache/aws4-npm-1.11.0-283476ad94-5a00d045fd.zip b/.yarn/cache/aws4-npm-1.11.0-283476ad94-5a00d045fd.zip deleted file mode 100644 index 41cb9dfbb63..00000000000 Binary files a/.yarn/cache/aws4-npm-1.11.0-283476ad94-5a00d045fd.zip and /dev/null differ diff --git a/.yarn/cache/babel-walk-npm-3.0.0-canary-5-61b07ed745-6fe7ee3889.zip b/.yarn/cache/babel-walk-npm-3.0.0-canary-5-61b07ed745-6fe7ee3889.zip deleted file mode 100644 index 9f0770f131b..00000000000 Binary files a/.yarn/cache/babel-walk-npm-3.0.0-canary-5-61b07ed745-6fe7ee3889.zip and /dev/null differ diff --git a/.yarn/cache/balanced-match-npm-1.0.2-a53c126459-9706c088a2.zip b/.yarn/cache/balanced-match-npm-1.0.2-a53c126459-9706c088a2.zip deleted file mode 100644 index 0693b6d7be2..00000000000 Binary files a/.yarn/cache/balanced-match-npm-1.0.2-a53c126459-9706c088a2.zip and /dev/null differ diff --git a/.yarn/cache/base-x-npm-3.0.9-7b2588e106-957101d6fd.zip b/.yarn/cache/base-x-npm-3.0.9-7b2588e106-957101d6fd.zip deleted file mode 100644 index 79bdd2c7052..00000000000 Binary files a/.yarn/cache/base-x-npm-3.0.9-7b2588e106-957101d6fd.zip and /dev/null differ diff --git a/.yarn/cache/base64-js-npm-1.5.1-b2f7275641-669632eb37.zip b/.yarn/cache/base64-js-npm-1.5.1-b2f7275641-669632eb37.zip deleted file mode 100644 index a49ec87ac2c..00000000000 Binary files a/.yarn/cache/base64-js-npm-1.5.1-b2f7275641-669632eb37.zip and /dev/null differ diff --git a/.yarn/cache/bcrypt-pbkdf-npm-1.0.2-80db8b16ed-4edfc9fe7d.zip b/.yarn/cache/bcrypt-pbkdf-npm-1.0.2-80db8b16ed-4edfc9fe7d.zip deleted file mode 100644 index 75152520d61..00000000000 Binary files a/.yarn/cache/bcrypt-pbkdf-npm-1.0.2-80db8b16ed-4edfc9fe7d.zip and /dev/null differ diff --git a/.yarn/cache/binary-extensions-npm-2.2.0-180c33fec7-ccd267956c.zip b/.yarn/cache/binary-extensions-npm-2.2.0-180c33fec7-ccd267956c.zip deleted file mode 100644 index 2ac750c15e1..00000000000 Binary files a/.yarn/cache/binary-extensions-npm-2.2.0-180c33fec7-ccd267956c.zip and /dev/null differ diff --git a/.yarn/cache/blob-util-npm-2.0.2-8026c830fe-d543e6b92e.zip b/.yarn/cache/blob-util-npm-2.0.2-8026c830fe-d543e6b92e.zip deleted file mode 100644 index a750b13446d..00000000000 Binary files a/.yarn/cache/blob-util-npm-2.0.2-8026c830fe-d543e6b92e.zip and /dev/null differ diff --git a/.yarn/cache/bluebird-npm-3.7.2-6a54136ee3-869417503c.zip b/.yarn/cache/bluebird-npm-3.7.2-6a54136ee3-869417503c.zip deleted file mode 100644 index f49f62c71b2..00000000000 Binary files a/.yarn/cache/bluebird-npm-3.7.2-6a54136ee3-869417503c.zip and /dev/null differ diff --git a/.yarn/cache/boolbase-npm-1.0.0-965fe9af6d-3e25c80ef6.zip b/.yarn/cache/boolbase-npm-1.0.0-965fe9af6d-3e25c80ef6.zip deleted file mode 100644 index 199099efa06..00000000000 Binary files a/.yarn/cache/boolbase-npm-1.0.0-965fe9af6d-3e25c80ef6.zip and /dev/null differ diff --git a/.yarn/cache/bootstrap-icons-npm-1.9.1-69d14bd4a0-b388264719.zip b/.yarn/cache/bootstrap-icons-npm-1.9.1-69d14bd4a0-b388264719.zip deleted file mode 100644 index 967f9533f6f..00000000000 Binary files a/.yarn/cache/bootstrap-icons-npm-1.9.1-69d14bd4a0-b388264719.zip and /dev/null differ diff --git a/.yarn/cache/bootstrap-npm-5.1.3-691fdc19a6-301b5ed872.zip b/.yarn/cache/bootstrap-npm-5.1.3-691fdc19a6-301b5ed872.zip deleted file mode 100644 index 91cbca041e1..00000000000 Binary files a/.yarn/cache/bootstrap-npm-5.1.3-691fdc19a6-301b5ed872.zip and /dev/null differ diff --git a/.yarn/cache/bootstrap-npm-5.2.0-e6c71ad969-9dbfb5d26b.zip b/.yarn/cache/bootstrap-npm-5.2.0-e6c71ad969-9dbfb5d26b.zip deleted file mode 100644 index f96548221c0..00000000000 Binary files a/.yarn/cache/bootstrap-npm-5.2.0-e6c71ad969-9dbfb5d26b.zip and /dev/null differ diff --git a/.yarn/cache/brace-expansion-npm-1.1.11-fb95eb05ad-faf34a7bb0.zip b/.yarn/cache/brace-expansion-npm-1.1.11-fb95eb05ad-faf34a7bb0.zip deleted file mode 100644 index 9deab64addc..00000000000 Binary files a/.yarn/cache/brace-expansion-npm-1.1.11-fb95eb05ad-faf34a7bb0.zip and /dev/null differ diff --git a/.yarn/cache/brace-expansion-npm-2.0.1-17aa2616f9-a61e7cd2e8.zip b/.yarn/cache/brace-expansion-npm-2.0.1-17aa2616f9-a61e7cd2e8.zip deleted file mode 100644 index 11d5bd0dbce..00000000000 Binary files a/.yarn/cache/brace-expansion-npm-2.0.1-17aa2616f9-a61e7cd2e8.zip and /dev/null differ diff --git a/.yarn/cache/braces-npm-3.0.2-782240b28a-e2a8e769a8.zip b/.yarn/cache/braces-npm-3.0.2-782240b28a-e2a8e769a8.zip deleted file mode 100644 index 92998e3cc76..00000000000 Binary files a/.yarn/cache/braces-npm-3.0.2-782240b28a-e2a8e769a8.zip and /dev/null differ diff --git a/.yarn/cache/browser-fs-access-npm-0.31.0-0e9a01c010-d1b6682415.zip b/.yarn/cache/browser-fs-access-npm-0.31.0-0e9a01c010-d1b6682415.zip deleted file mode 100644 index 02f11f9674b..00000000000 Binary files a/.yarn/cache/browser-fs-access-npm-0.31.0-0e9a01c010-d1b6682415.zip and /dev/null differ diff --git a/.yarn/cache/browserlist-npm-1.0.1-5c12c77f80-db4dc273b5.zip b/.yarn/cache/browserlist-npm-1.0.1-5c12c77f80-db4dc273b5.zip deleted file mode 100644 index 1f7525682c0..00000000000 Binary files a/.yarn/cache/browserlist-npm-1.0.1-5c12c77f80-db4dc273b5.zip and /dev/null differ diff --git a/.yarn/cache/browserslist-npm-4.20.3-d7ff9d00b4-1e4b719ac2.zip b/.yarn/cache/browserslist-npm-4.20.3-d7ff9d00b4-1e4b719ac2.zip deleted file mode 100644 index 06a6229a09e..00000000000 Binary files a/.yarn/cache/browserslist-npm-4.20.3-d7ff9d00b4-1e4b719ac2.zip and /dev/null differ diff --git a/.yarn/cache/buffer-crc32-npm-0.2.13-c4b6fceac1-06252347ae.zip b/.yarn/cache/buffer-crc32-npm-0.2.13-c4b6fceac1-06252347ae.zip deleted file mode 100644 index 96da9d8111c..00000000000 Binary files a/.yarn/cache/buffer-crc32-npm-0.2.13-c4b6fceac1-06252347ae.zip and /dev/null differ diff --git a/.yarn/cache/buffer-from-npm-1.1.2-03d2f20d7e-0448524a56.zip b/.yarn/cache/buffer-from-npm-1.1.2-03d2f20d7e-0448524a56.zip deleted file mode 100644 index efe1b763807..00000000000 Binary files a/.yarn/cache/buffer-from-npm-1.1.2-03d2f20d7e-0448524a56.zip and /dev/null differ diff --git a/.yarn/cache/buffer-npm-5.7.1-513ef8259e-e2cf8429e1.zip b/.yarn/cache/buffer-npm-5.7.1-513ef8259e-e2cf8429e1.zip deleted file mode 100644 index 15c7810bc9a..00000000000 Binary files a/.yarn/cache/buffer-npm-5.7.1-513ef8259e-e2cf8429e1.zip and /dev/null differ diff --git a/.yarn/cache/builtins-npm-4.1.0-b8969ccdfe-3524f5a589.zip b/.yarn/cache/builtins-npm-4.1.0-b8969ccdfe-3524f5a589.zip deleted file mode 100644 index 15b386e4517..00000000000 Binary files a/.yarn/cache/builtins-npm-4.1.0-b8969ccdfe-3524f5a589.zip and /dev/null differ diff --git a/.yarn/cache/c8-npm-7.12.0-c808cac509-3b7fa9ad7c.zip b/.yarn/cache/c8-npm-7.12.0-c808cac509-3b7fa9ad7c.zip deleted file mode 100644 index 4558e5b9f9a..00000000000 Binary files a/.yarn/cache/c8-npm-7.12.0-c808cac509-3b7fa9ad7c.zip and /dev/null differ diff --git a/.yarn/cache/cacache-npm-16.1.0-e24d9a7d5b-ddfcf92f07.zip b/.yarn/cache/cacache-npm-16.1.0-e24d9a7d5b-ddfcf92f07.zip deleted file mode 100644 index eab7684e198..00000000000 Binary files a/.yarn/cache/cacache-npm-16.1.0-e24d9a7d5b-ddfcf92f07.zip and /dev/null differ diff --git a/.yarn/cache/cachedir-npm-2.3.0-640dc16bbb-ec90cb0f2e.zip b/.yarn/cache/cachedir-npm-2.3.0-640dc16bbb-ec90cb0f2e.zip deleted file mode 100644 index 016740008c7..00000000000 Binary files a/.yarn/cache/cachedir-npm-2.3.0-640dc16bbb-ec90cb0f2e.zip and /dev/null differ diff --git a/.yarn/cache/call-bind-npm-1.0.2-c957124861-f8e31de9d1.zip b/.yarn/cache/call-bind-npm-1.0.2-c957124861-f8e31de9d1.zip deleted file mode 100644 index bff7528d404..00000000000 Binary files a/.yarn/cache/call-bind-npm-1.0.2-c957124861-f8e31de9d1.zip and /dev/null differ diff --git a/.yarn/cache/callsites-npm-3.1.0-268f989910-072d17b6ab.zip b/.yarn/cache/callsites-npm-3.1.0-268f989910-072d17b6ab.zip deleted file mode 100644 index be6414c5472..00000000000 Binary files a/.yarn/cache/callsites-npm-3.1.0-268f989910-072d17b6ab.zip and /dev/null differ diff --git a/.yarn/cache/caniuse-lite-npm-1.0.30001340-5ba8569de6-5b419c93cb.zip b/.yarn/cache/caniuse-lite-npm-1.0.30001340-5ba8569de6-5b419c93cb.zip deleted file mode 100644 index a2d4de44494..00000000000 Binary files a/.yarn/cache/caniuse-lite-npm-1.0.30001340-5ba8569de6-5b419c93cb.zip and /dev/null differ diff --git a/.yarn/cache/caniuse-lite-npm-1.0.30001368-82766437b8-e2a763e7bc.zip b/.yarn/cache/caniuse-lite-npm-1.0.30001368-82766437b8-e2a763e7bc.zip deleted file mode 100644 index 626fbb14d18..00000000000 Binary files a/.yarn/cache/caniuse-lite-npm-1.0.30001368-82766437b8-e2a763e7bc.zip and /dev/null differ diff --git a/.yarn/cache/caseless-npm-0.12.0-e83bc5df83-b43bd4c440.zip b/.yarn/cache/caseless-npm-0.12.0-e83bc5df83-b43bd4c440.zip deleted file mode 100644 index a12be75cdb5..00000000000 Binary files a/.yarn/cache/caseless-npm-0.12.0-e83bc5df83-b43bd4c440.zip and /dev/null differ diff --git a/.yarn/cache/chai-npm-4.3.6-dba90e4b0b-acff93fd53.zip b/.yarn/cache/chai-npm-4.3.6-dba90e4b0b-acff93fd53.zip deleted file mode 100644 index 1a0d17d02fa..00000000000 Binary files a/.yarn/cache/chai-npm-4.3.6-dba90e4b0b-acff93fd53.zip and /dev/null differ diff --git a/.yarn/cache/chalk-npm-2.4.2-3ea16dd91e-ec3661d38f.zip b/.yarn/cache/chalk-npm-2.4.2-3ea16dd91e-ec3661d38f.zip deleted file mode 100644 index 3f58a7b2333..00000000000 Binary files a/.yarn/cache/chalk-npm-2.4.2-3ea16dd91e-ec3661d38f.zip and /dev/null differ diff --git a/.yarn/cache/chalk-npm-4.1.2-ba8b67ab80-fe75c9d5c7.zip b/.yarn/cache/chalk-npm-4.1.2-ba8b67ab80-fe75c9d5c7.zip deleted file mode 100644 index 03d46b8646f..00000000000 Binary files a/.yarn/cache/chalk-npm-4.1.2-ba8b67ab80-fe75c9d5c7.zip and /dev/null differ diff --git a/.yarn/cache/character-parser-npm-2.2.0-a5df9fb883-71826fae50.zip b/.yarn/cache/character-parser-npm-2.2.0-a5df9fb883-71826fae50.zip deleted file mode 100644 index dd15601fd9e..00000000000 Binary files a/.yarn/cache/character-parser-npm-2.2.0-a5df9fb883-71826fae50.zip and /dev/null differ diff --git a/.yarn/cache/check-error-npm-1.0.2-00c540c6e9-d9d1065044.zip b/.yarn/cache/check-error-npm-1.0.2-00c540c6e9-d9d1065044.zip deleted file mode 100644 index 23753533b3f..00000000000 Binary files a/.yarn/cache/check-error-npm-1.0.2-00c540c6e9-d9d1065044.zip and /dev/null differ diff --git a/.yarn/cache/check-more-types-npm-2.24.0-fa2e491b27-b09080ec34.zip b/.yarn/cache/check-more-types-npm-2.24.0-fa2e491b27-b09080ec34.zip deleted file mode 100644 index 6f5e29aaa87..00000000000 Binary files a/.yarn/cache/check-more-types-npm-2.24.0-fa2e491b27-b09080ec34.zip and /dev/null differ diff --git a/.yarn/cache/chokidar-npm-3.5.3-c5f9b0a56a-b49fcde401.zip b/.yarn/cache/chokidar-npm-3.5.3-c5f9b0a56a-b49fcde401.zip deleted file mode 100644 index f5261bc278d..00000000000 Binary files a/.yarn/cache/chokidar-npm-3.5.3-c5f9b0a56a-b49fcde401.zip and /dev/null differ diff --git a/.yarn/cache/chownr-npm-2.0.0-638f1c9c61-c57cf9dd07.zip b/.yarn/cache/chownr-npm-2.0.0-638f1c9c61-c57cf9dd07.zip deleted file mode 100644 index e074b2f4c78..00000000000 Binary files a/.yarn/cache/chownr-npm-2.0.0-638f1c9c61-c57cf9dd07.zip and /dev/null differ diff --git a/.yarn/cache/chrome-trace-event-npm-1.0.3-e0ae3dcd60-cb8b1fc7e8.zip b/.yarn/cache/chrome-trace-event-npm-1.0.3-e0ae3dcd60-cb8b1fc7e8.zip deleted file mode 100644 index b1b2134d5f0..00000000000 Binary files a/.yarn/cache/chrome-trace-event-npm-1.0.3-e0ae3dcd60-cb8b1fc7e8.zip and /dev/null differ diff --git a/.yarn/cache/ci-info-npm-3.3.1-c80845db6d-244546317c.zip b/.yarn/cache/ci-info-npm-3.3.1-c80845db6d-244546317c.zip deleted file mode 100644 index a4232b35f92..00000000000 Binary files a/.yarn/cache/ci-info-npm-3.3.1-c80845db6d-244546317c.zip and /dev/null differ diff --git a/.yarn/cache/clean-stack-npm-2.2.0-a8ce435a5c-2ac8cd2b2f.zip b/.yarn/cache/clean-stack-npm-2.2.0-a8ce435a5c-2ac8cd2b2f.zip deleted file mode 100644 index c510995715e..00000000000 Binary files a/.yarn/cache/clean-stack-npm-2.2.0-a8ce435a5c-2ac8cd2b2f.zip and /dev/null differ diff --git a/.yarn/cache/cli-cursor-npm-3.1.0-fee1e46b5e-2692784c6c.zip b/.yarn/cache/cli-cursor-npm-3.1.0-fee1e46b5e-2692784c6c.zip deleted file mode 100644 index 2a8723c64ee..00000000000 Binary files a/.yarn/cache/cli-cursor-npm-3.1.0-fee1e46b5e-2692784c6c.zip and /dev/null differ diff --git a/.yarn/cache/cli-table3-npm-0.6.2-dff919b99d-2f82391698.zip b/.yarn/cache/cli-table3-npm-0.6.2-dff919b99d-2f82391698.zip deleted file mode 100644 index d6059a7bfad..00000000000 Binary files a/.yarn/cache/cli-table3-npm-0.6.2-dff919b99d-2f82391698.zip and /dev/null differ diff --git a/.yarn/cache/cli-truncate-npm-2.1.0-72184d3467-bf1e4e6195.zip b/.yarn/cache/cli-truncate-npm-2.1.0-72184d3467-bf1e4e6195.zip deleted file mode 100644 index f8c20f36514..00000000000 Binary files a/.yarn/cache/cli-truncate-npm-2.1.0-72184d3467-bf1e4e6195.zip and /dev/null differ diff --git a/.yarn/cache/cliui-npm-7.0.4-d6b8a9edb6-ce2e8f578a.zip b/.yarn/cache/cliui-npm-7.0.4-d6b8a9edb6-ce2e8f578a.zip deleted file mode 100644 index 24f58564e46..00000000000 Binary files a/.yarn/cache/cliui-npm-7.0.4-d6b8a9edb6-ce2e8f578a.zip and /dev/null differ diff --git a/.yarn/cache/clone-npm-2.1.2-1d491c6629-aaf106e9bc.zip b/.yarn/cache/clone-npm-2.1.2-1d491c6629-aaf106e9bc.zip deleted file mode 100644 index 6ae29b32e57..00000000000 Binary files a/.yarn/cache/clone-npm-2.1.2-1d491c6629-aaf106e9bc.zip and /dev/null differ diff --git a/.yarn/cache/color-convert-npm-1.9.3-1fe690075e-fd7a64a17c.zip b/.yarn/cache/color-convert-npm-1.9.3-1fe690075e-fd7a64a17c.zip deleted file mode 100644 index 1b4c9391ea3..00000000000 Binary files a/.yarn/cache/color-convert-npm-1.9.3-1fe690075e-fd7a64a17c.zip and /dev/null differ diff --git a/.yarn/cache/color-convert-npm-2.0.1-79730e935b-79e6bdb9fd.zip b/.yarn/cache/color-convert-npm-2.0.1-79730e935b-79e6bdb9fd.zip deleted file mode 100644 index b3499adbb84..00000000000 Binary files a/.yarn/cache/color-convert-npm-2.0.1-79730e935b-79e6bdb9fd.zip and /dev/null differ diff --git a/.yarn/cache/color-name-npm-1.1.3-728b7b5d39-09c5d3e33d.zip b/.yarn/cache/color-name-npm-1.1.3-728b7b5d39-09c5d3e33d.zip deleted file mode 100644 index f158de9e2eb..00000000000 Binary files a/.yarn/cache/color-name-npm-1.1.3-728b7b5d39-09c5d3e33d.zip and /dev/null differ diff --git a/.yarn/cache/color-name-npm-1.1.4-025792b0ea-b044585952.zip b/.yarn/cache/color-name-npm-1.1.4-025792b0ea-b044585952.zip deleted file mode 100644 index ce1ffc4bf31..00000000000 Binary files a/.yarn/cache/color-name-npm-1.1.4-025792b0ea-b044585952.zip and /dev/null differ diff --git a/.yarn/cache/color-support-npm-1.1.3-3be5c53455-9b73568176.zip b/.yarn/cache/color-support-npm-1.1.3-3be5c53455-9b73568176.zip deleted file mode 100644 index 625a79f1779..00000000000 Binary files a/.yarn/cache/color-support-npm-1.1.3-3be5c53455-9b73568176.zip and /dev/null differ diff --git a/.yarn/cache/colorette-npm-2.0.16-7b996485d7-cd55596a3a.zip b/.yarn/cache/colorette-npm-2.0.16-7b996485d7-cd55596a3a.zip deleted file mode 100644 index 0d086dd3784..00000000000 Binary files a/.yarn/cache/colorette-npm-2.0.16-7b996485d7-cd55596a3a.zip and /dev/null differ diff --git a/.yarn/cache/combined-stream-npm-1.0.8-dc14d4a63a-49fa4aeb49.zip b/.yarn/cache/combined-stream-npm-1.0.8-dc14d4a63a-49fa4aeb49.zip deleted file mode 100644 index 89c8caa0fdc..00000000000 Binary files a/.yarn/cache/combined-stream-npm-1.0.8-dc14d4a63a-49fa4aeb49.zip and /dev/null differ diff --git a/.yarn/cache/commander-npm-2.20.3-d8dcbaa39b-ab8c07884e.zip b/.yarn/cache/commander-npm-2.20.3-d8dcbaa39b-ab8c07884e.zip deleted file mode 100644 index 6a14adf507d..00000000000 Binary files a/.yarn/cache/commander-npm-2.20.3-d8dcbaa39b-ab8c07884e.zip and /dev/null differ diff --git a/.yarn/cache/commander-npm-5.1.0-7e939e7832-0b7fec1712.zip b/.yarn/cache/commander-npm-5.1.0-7e939e7832-0b7fec1712.zip deleted file mode 100644 index ceec307a3d7..00000000000 Binary files a/.yarn/cache/commander-npm-5.1.0-7e939e7832-0b7fec1712.zip and /dev/null differ diff --git a/.yarn/cache/commander-npm-7.2.0-19178180f8-53501cbeee.zip b/.yarn/cache/commander-npm-7.2.0-19178180f8-53501cbeee.zip deleted file mode 100644 index 1c86bf71813..00000000000 Binary files a/.yarn/cache/commander-npm-7.2.0-19178180f8-53501cbeee.zip and /dev/null differ diff --git a/.yarn/cache/common-tags-npm-1.8.2-2c30ba69b3-767a6255a8.zip b/.yarn/cache/common-tags-npm-1.8.2-2c30ba69b3-767a6255a8.zip deleted file mode 100644 index 3b1eefb4c39..00000000000 Binary files a/.yarn/cache/common-tags-npm-1.8.2-2c30ba69b3-767a6255a8.zip and /dev/null differ diff --git a/.yarn/cache/concat-map-npm-0.0.1-85a921b7ee-902a9f5d89.zip b/.yarn/cache/concat-map-npm-0.0.1-85a921b7ee-902a9f5d89.zip deleted file mode 100644 index 66b4c329f86..00000000000 Binary files a/.yarn/cache/concat-map-npm-0.0.1-85a921b7ee-902a9f5d89.zip and /dev/null differ diff --git a/.yarn/cache/console-control-strings-npm-1.1.0-e3160e5275-8755d76787.zip b/.yarn/cache/console-control-strings-npm-1.1.0-e3160e5275-8755d76787.zip deleted file mode 100644 index a1f2fe661be..00000000000 Binary files a/.yarn/cache/console-control-strings-npm-1.1.0-e3160e5275-8755d76787.zip and /dev/null differ diff --git a/.yarn/cache/constantinople-npm-4.0.1-925d9c26ce-8f70f16ddf.zip b/.yarn/cache/constantinople-npm-4.0.1-925d9c26ce-8f70f16ddf.zip deleted file mode 100644 index 9a9f752f831..00000000000 Binary files a/.yarn/cache/constantinople-npm-4.0.1-925d9c26ce-8f70f16ddf.zip and /dev/null differ diff --git a/.yarn/cache/convert-source-map-npm-1.8.0-037f671dde-985d974a2d.zip b/.yarn/cache/convert-source-map-npm-1.8.0-037f671dde-985d974a2d.zip deleted file mode 100644 index 00cffe534e4..00000000000 Binary files a/.yarn/cache/convert-source-map-npm-1.8.0-037f671dde-985d974a2d.zip and /dev/null differ diff --git a/.yarn/cache/core-util-is-npm-1.0.2-9fc2b94dc3-7a4c925b49.zip b/.yarn/cache/core-util-is-npm-1.0.2-9fc2b94dc3-7a4c925b49.zip deleted file mode 100644 index 00b0792a3b9..00000000000 Binary files a/.yarn/cache/core-util-is-npm-1.0.2-9fc2b94dc3-7a4c925b49.zip and /dev/null differ diff --git a/.yarn/cache/cosmiconfig-npm-7.0.1-dd19ae2403-4be63e7117.zip b/.yarn/cache/cosmiconfig-npm-7.0.1-dd19ae2403-4be63e7117.zip deleted file mode 100644 index 6cb92f2fb78..00000000000 Binary files a/.yarn/cache/cosmiconfig-npm-7.0.1-dd19ae2403-4be63e7117.zip and /dev/null differ diff --git a/.yarn/cache/cross-spawn-npm-7.0.3-e4ff3e65b3-671cc7c728.zip b/.yarn/cache/cross-spawn-npm-7.0.3-e4ff3e65b3-671cc7c728.zip deleted file mode 100644 index 9613e383d10..00000000000 Binary files a/.yarn/cache/cross-spawn-npm-7.0.3-e4ff3e65b3-671cc7c728.zip and /dev/null differ diff --git a/.yarn/cache/css-render-npm-0.15.10-57cf7c0959-051ebb6a56.zip b/.yarn/cache/css-render-npm-0.15.10-57cf7c0959-051ebb6a56.zip deleted file mode 100644 index 55f8c949717..00000000000 Binary files a/.yarn/cache/css-render-npm-0.15.10-57cf7c0959-051ebb6a56.zip and /dev/null differ diff --git a/.yarn/cache/css-select-npm-4.3.0-72f53028ec-d620273683.zip b/.yarn/cache/css-select-npm-4.3.0-72f53028ec-d620273683.zip deleted file mode 100644 index cc75afed1ca..00000000000 Binary files a/.yarn/cache/css-select-npm-4.3.0-72f53028ec-d620273683.zip and /dev/null differ diff --git a/.yarn/cache/css-tree-npm-1.1.3-9c46f35513-79f9b81803.zip b/.yarn/cache/css-tree-npm-1.1.3-9c46f35513-79f9b81803.zip deleted file mode 100644 index 13920c8991c..00000000000 Binary files a/.yarn/cache/css-tree-npm-1.1.3-9c46f35513-79f9b81803.zip and /dev/null differ diff --git a/.yarn/cache/css-what-npm-6.1.0-57f751efbb-b975e547e1.zip b/.yarn/cache/css-what-npm-6.1.0-57f751efbb-b975e547e1.zip deleted file mode 100644 index 7ae813a3909..00000000000 Binary files a/.yarn/cache/css-what-npm-6.1.0-57f751efbb-b975e547e1.zip and /dev/null differ diff --git a/.yarn/cache/cssesc-npm-3.0.0-15ec56f86f-f8c4ababff.zip b/.yarn/cache/cssesc-npm-3.0.0-15ec56f86f-f8c4ababff.zip deleted file mode 100644 index ba053ede3a4..00000000000 Binary files a/.yarn/cache/cssesc-npm-3.0.0-15ec56f86f-f8c4ababff.zip and /dev/null differ diff --git a/.yarn/cache/csso-npm-4.2.0-b277db8d71-380ba9663d.zip b/.yarn/cache/csso-npm-4.2.0-b277db8d71-380ba9663d.zip deleted file mode 100644 index fd347a7db00..00000000000 Binary files a/.yarn/cache/csso-npm-4.2.0-b277db8d71-380ba9663d.zip and /dev/null differ diff --git a/.yarn/cache/csstype-npm-2.6.20-7c929732a1-cb5d5ded49.zip b/.yarn/cache/csstype-npm-2.6.20-7c929732a1-cb5d5ded49.zip deleted file mode 100644 index 59ddf4f69fc..00000000000 Binary files a/.yarn/cache/csstype-npm-2.6.20-7c929732a1-cb5d5ded49.zip and /dev/null differ diff --git a/.yarn/cache/csstype-npm-3.0.11-b49897178d-95e56abfe9.zip b/.yarn/cache/csstype-npm-3.0.11-b49897178d-95e56abfe9.zip deleted file mode 100644 index 41dbc2f772b..00000000000 Binary files a/.yarn/cache/csstype-npm-3.0.11-b49897178d-95e56abfe9.zip and /dev/null differ diff --git a/.yarn/cache/cypress-npm-10.3.1-b9950af2d1-7c76157195.zip b/.yarn/cache/cypress-npm-10.3.1-b9950af2d1-7c76157195.zip deleted file mode 100644 index cfd7990c50e..00000000000 Binary files a/.yarn/cache/cypress-npm-10.3.1-b9950af2d1-7c76157195.zip and /dev/null differ diff --git a/.yarn/cache/cypress-real-events-npm-1.7.1-6d5a866c0e-b31c2facfa.zip b/.yarn/cache/cypress-real-events-npm-1.7.1-6d5a866c0e-b31c2facfa.zip deleted file mode 100644 index 3f5f4271605..00000000000 Binary files a/.yarn/cache/cypress-real-events-npm-1.7.1-6d5a866c0e-b31c2facfa.zip and /dev/null differ diff --git a/.yarn/cache/d3-array-npm-3.1.6-fa4f0bcb75-32f515bd25.zip b/.yarn/cache/d3-array-npm-3.1.6-fa4f0bcb75-32f515bd25.zip deleted file mode 100644 index 441797e7945..00000000000 Binary files a/.yarn/cache/d3-array-npm-3.1.6-fa4f0bcb75-32f515bd25.zip and /dev/null differ diff --git a/.yarn/cache/d3-array-npm-3.2.0-c3a38fe288-e236f6670b.zip b/.yarn/cache/d3-array-npm-3.2.0-c3a38fe288-e236f6670b.zip deleted file mode 100644 index dd64b2955bc..00000000000 Binary files a/.yarn/cache/d3-array-npm-3.2.0-c3a38fe288-e236f6670b.zip and /dev/null differ diff --git a/.yarn/cache/d3-axis-npm-3.0.0-81ef16a9a5-227ddaa6d4.zip b/.yarn/cache/d3-axis-npm-3.0.0-81ef16a9a5-227ddaa6d4.zip deleted file mode 100644 index c5050dc37d4..00000000000 Binary files a/.yarn/cache/d3-axis-npm-3.0.0-81ef16a9a5-227ddaa6d4.zip and /dev/null differ diff --git a/.yarn/cache/d3-brush-npm-3.0.0-0f86c8ad35-1d04216776.zip b/.yarn/cache/d3-brush-npm-3.0.0-0f86c8ad35-1d04216776.zip deleted file mode 100644 index a051672128d..00000000000 Binary files a/.yarn/cache/d3-brush-npm-3.0.0-0f86c8ad35-1d04216776.zip and /dev/null differ diff --git a/.yarn/cache/d3-chord-npm-3.0.1-3fcb345658-ddf35d4167.zip b/.yarn/cache/d3-chord-npm-3.0.1-3fcb345658-ddf35d4167.zip deleted file mode 100644 index 21b3092a4a0..00000000000 Binary files a/.yarn/cache/d3-chord-npm-3.0.1-3fcb345658-ddf35d4167.zip and /dev/null differ diff --git a/.yarn/cache/d3-color-npm-3.1.0-fc73fe3b15-4931fbfda5.zip b/.yarn/cache/d3-color-npm-3.1.0-fc73fe3b15-4931fbfda5.zip deleted file mode 100644 index e065048e8d0..00000000000 Binary files a/.yarn/cache/d3-color-npm-3.1.0-fc73fe3b15-4931fbfda5.zip and /dev/null differ diff --git a/.yarn/cache/d3-contour-npm-4.0.0-9b98ab4af2-1f9b9e56d0.zip b/.yarn/cache/d3-contour-npm-4.0.0-9b98ab4af2-1f9b9e56d0.zip deleted file mode 100644 index ad2b7574559..00000000000 Binary files a/.yarn/cache/d3-contour-npm-4.0.0-9b98ab4af2-1f9b9e56d0.zip and /dev/null differ diff --git a/.yarn/cache/d3-delaunay-npm-6.0.2-23823819ce-80b18686dd.zip b/.yarn/cache/d3-delaunay-npm-6.0.2-23823819ce-80b18686dd.zip deleted file mode 100644 index e5e73df653a..00000000000 Binary files a/.yarn/cache/d3-delaunay-npm-6.0.2-23823819ce-80b18686dd.zip and /dev/null differ diff --git a/.yarn/cache/d3-dispatch-npm-3.0.1-5f44c3166f-fdfd4a230f.zip b/.yarn/cache/d3-dispatch-npm-3.0.1-5f44c3166f-fdfd4a230f.zip deleted file mode 100644 index 44204fac3bd..00000000000 Binary files a/.yarn/cache/d3-dispatch-npm-3.0.1-5f44c3166f-fdfd4a230f.zip and /dev/null differ diff --git a/.yarn/cache/d3-drag-npm-3.0.0-cf7b48417f-d297231e60.zip b/.yarn/cache/d3-drag-npm-3.0.0-cf7b48417f-d297231e60.zip deleted file mode 100644 index 912ab766f53..00000000000 Binary files a/.yarn/cache/d3-drag-npm-3.0.0-cf7b48417f-d297231e60.zip and /dev/null differ diff --git a/.yarn/cache/d3-dsv-npm-3.0.1-5d88fb8a85-5fc0723647.zip b/.yarn/cache/d3-dsv-npm-3.0.1-5d88fb8a85-5fc0723647.zip deleted file mode 100644 index 4ddf527989b..00000000000 Binary files a/.yarn/cache/d3-dsv-npm-3.0.1-5d88fb8a85-5fc0723647.zip and /dev/null differ diff --git a/.yarn/cache/d3-ease-npm-3.0.1-f8f3709dc7-06e2ee5326.zip b/.yarn/cache/d3-ease-npm-3.0.1-f8f3709dc7-06e2ee5326.zip deleted file mode 100644 index 36827333ae8..00000000000 Binary files a/.yarn/cache/d3-ease-npm-3.0.1-f8f3709dc7-06e2ee5326.zip and /dev/null differ diff --git a/.yarn/cache/d3-fetch-npm-3.0.1-ad9ce3dc3e-382dcea065.zip b/.yarn/cache/d3-fetch-npm-3.0.1-ad9ce3dc3e-382dcea065.zip deleted file mode 100644 index 1324ceb9db5..00000000000 Binary files a/.yarn/cache/d3-fetch-npm-3.0.1-ad9ce3dc3e-382dcea065.zip and /dev/null differ diff --git a/.yarn/cache/d3-force-npm-3.0.0-462e87e63b-6c7e96438c.zip b/.yarn/cache/d3-force-npm-3.0.0-462e87e63b-6c7e96438c.zip deleted file mode 100644 index 368a4b3111c..00000000000 Binary files a/.yarn/cache/d3-force-npm-3.0.0-462e87e63b-6c7e96438c.zip and /dev/null differ diff --git a/.yarn/cache/d3-format-npm-3.1.0-dfc19924ca-f345ec3b8a.zip b/.yarn/cache/d3-format-npm-3.1.0-dfc19924ca-f345ec3b8a.zip deleted file mode 100644 index ce557b956a0..00000000000 Binary files a/.yarn/cache/d3-format-npm-3.1.0-dfc19924ca-f345ec3b8a.zip and /dev/null differ diff --git a/.yarn/cache/d3-geo-npm-3.0.1-2aabdbb750-e0f7e6a2f0.zip b/.yarn/cache/d3-geo-npm-3.0.1-2aabdbb750-e0f7e6a2f0.zip deleted file mode 100644 index dd9236c02a9..00000000000 Binary files a/.yarn/cache/d3-geo-npm-3.0.1-2aabdbb750-e0f7e6a2f0.zip and /dev/null differ diff --git a/.yarn/cache/d3-hierarchy-npm-3.1.2-1ac1bae7e3-0fd946a8c5.zip b/.yarn/cache/d3-hierarchy-npm-3.1.2-1ac1bae7e3-0fd946a8c5.zip deleted file mode 100644 index b70ca95b598..00000000000 Binary files a/.yarn/cache/d3-hierarchy-npm-3.1.2-1ac1bae7e3-0fd946a8c5.zip and /dev/null differ diff --git a/.yarn/cache/d3-interpolate-npm-3.0.1-77ddca7977-a42ba314e2.zip b/.yarn/cache/d3-interpolate-npm-3.0.1-77ddca7977-a42ba314e2.zip deleted file mode 100644 index 06512aad4c6..00000000000 Binary files a/.yarn/cache/d3-interpolate-npm-3.0.1-77ddca7977-a42ba314e2.zip and /dev/null differ diff --git a/.yarn/cache/d3-npm-7.6.1-9545deaa85-af883cfeaf.zip b/.yarn/cache/d3-npm-7.6.1-9545deaa85-af883cfeaf.zip deleted file mode 100644 index e42149bd4f4..00000000000 Binary files a/.yarn/cache/d3-npm-7.6.1-9545deaa85-af883cfeaf.zip and /dev/null differ diff --git a/.yarn/cache/d3-path-npm-3.0.1-c8a313bdd3-6347c7055e.zip b/.yarn/cache/d3-path-npm-3.0.1-c8a313bdd3-6347c7055e.zip deleted file mode 100644 index 087e9507a6b..00000000000 Binary files a/.yarn/cache/d3-path-npm-3.0.1-c8a313bdd3-6347c7055e.zip and /dev/null differ diff --git a/.yarn/cache/d3-polygon-npm-3.0.1-ccec77a8d4-0b85c53251.zip b/.yarn/cache/d3-polygon-npm-3.0.1-ccec77a8d4-0b85c53251.zip deleted file mode 100644 index fda7026b752..00000000000 Binary files a/.yarn/cache/d3-polygon-npm-3.0.1-ccec77a8d4-0b85c53251.zip and /dev/null differ diff --git a/.yarn/cache/d3-quadtree-npm-3.0.1-6f0eae8c83-5469d46276.zip b/.yarn/cache/d3-quadtree-npm-3.0.1-6f0eae8c83-5469d46276.zip deleted file mode 100644 index b2ecee4624d..00000000000 Binary files a/.yarn/cache/d3-quadtree-npm-3.0.1-6f0eae8c83-5469d46276.zip and /dev/null differ diff --git a/.yarn/cache/d3-random-npm-3.0.1-4fabe65eda-a70ad8d1ca.zip b/.yarn/cache/d3-random-npm-3.0.1-4fabe65eda-a70ad8d1ca.zip deleted file mode 100644 index 13b359a7f42..00000000000 Binary files a/.yarn/cache/d3-random-npm-3.0.1-4fabe65eda-a70ad8d1ca.zip and /dev/null differ diff --git a/.yarn/cache/d3-scale-chromatic-npm-3.0.0-ca3b48a3cb-a8ce4cb026.zip b/.yarn/cache/d3-scale-chromatic-npm-3.0.0-ca3b48a3cb-a8ce4cb026.zip deleted file mode 100644 index 538f62de184..00000000000 Binary files a/.yarn/cache/d3-scale-chromatic-npm-3.0.0-ca3b48a3cb-a8ce4cb026.zip and /dev/null differ diff --git a/.yarn/cache/d3-scale-npm-4.0.2-d17a53447b-a9c770d283.zip b/.yarn/cache/d3-scale-npm-4.0.2-d17a53447b-a9c770d283.zip deleted file mode 100644 index dab858adf70..00000000000 Binary files a/.yarn/cache/d3-scale-npm-4.0.2-d17a53447b-a9c770d283.zip and /dev/null differ diff --git a/.yarn/cache/d3-selection-npm-3.0.0-39a42b4ca9-f4e60e1333.zip b/.yarn/cache/d3-selection-npm-3.0.0-39a42b4ca9-f4e60e1333.zip deleted file mode 100644 index 9a72f33c4b1..00000000000 Binary files a/.yarn/cache/d3-selection-npm-3.0.0-39a42b4ca9-f4e60e1333.zip and /dev/null differ diff --git a/.yarn/cache/d3-shape-npm-3.1.0-a298c27eca-3dffe31b56.zip b/.yarn/cache/d3-shape-npm-3.1.0-a298c27eca-3dffe31b56.zip deleted file mode 100644 index aa3f2ef4607..00000000000 Binary files a/.yarn/cache/d3-shape-npm-3.1.0-a298c27eca-3dffe31b56.zip and /dev/null differ diff --git a/.yarn/cache/d3-time-format-npm-4.1.0-7f352c4634-7342bce283.zip b/.yarn/cache/d3-time-format-npm-4.1.0-7f352c4634-7342bce283.zip deleted file mode 100644 index b7354e588e6..00000000000 Binary files a/.yarn/cache/d3-time-format-npm-4.1.0-7f352c4634-7342bce283.zip and /dev/null differ diff --git a/.yarn/cache/d3-time-npm-3.0.0-a4963e64c8-01646568ef.zip b/.yarn/cache/d3-time-npm-3.0.0-a4963e64c8-01646568ef.zip deleted file mode 100644 index 5fb8d1d71f6..00000000000 Binary files a/.yarn/cache/d3-time-npm-3.0.0-a4963e64c8-01646568ef.zip and /dev/null differ diff --git a/.yarn/cache/d3-timer-npm-3.0.1-45083f465d-1cfddf86d7.zip b/.yarn/cache/d3-timer-npm-3.0.1-45083f465d-1cfddf86d7.zip deleted file mode 100644 index 8724902dafc..00000000000 Binary files a/.yarn/cache/d3-timer-npm-3.0.1-45083f465d-1cfddf86d7.zip and /dev/null differ diff --git a/.yarn/cache/d3-transition-npm-3.0.1-9191e0faaa-cb1e6e018c.zip b/.yarn/cache/d3-transition-npm-3.0.1-9191e0faaa-cb1e6e018c.zip deleted file mode 100644 index 8ccda883508..00000000000 Binary files a/.yarn/cache/d3-transition-npm-3.0.1-9191e0faaa-cb1e6e018c.zip and /dev/null differ diff --git a/.yarn/cache/d3-zoom-npm-3.0.0-18f706a421-8056e35272.zip b/.yarn/cache/d3-zoom-npm-3.0.0-18f706a421-8056e35272.zip deleted file mode 100644 index 37d72bf7d99..00000000000 Binary files a/.yarn/cache/d3-zoom-npm-3.0.0-18f706a421-8056e35272.zip and /dev/null differ diff --git a/.yarn/cache/dashdash-npm-1.14.1-be8f10a286-3634c24957.zip b/.yarn/cache/dashdash-npm-1.14.1-be8f10a286-3634c24957.zip deleted file mode 100644 index 108f90531ad..00000000000 Binary files a/.yarn/cache/dashdash-npm-1.14.1-be8f10a286-3634c24957.zip and /dev/null differ diff --git a/.yarn/cache/date-fns-npm-2.28.0-c19c5add1b-a0516b2e4f.zip b/.yarn/cache/date-fns-npm-2.28.0-c19c5add1b-a0516b2e4f.zip deleted file mode 100644 index 1e88493b725..00000000000 Binary files a/.yarn/cache/date-fns-npm-2.28.0-c19c5add1b-a0516b2e4f.zip and /dev/null differ diff --git a/.yarn/cache/date-fns-tz-npm-1.3.3-4b42de3dcf-52111dffb4.zip b/.yarn/cache/date-fns-tz-npm-1.3.3-4b42de3dcf-52111dffb4.zip deleted file mode 100644 index 856e44240d0..00000000000 Binary files a/.yarn/cache/date-fns-tz-npm-1.3.3-4b42de3dcf-52111dffb4.zip and /dev/null differ diff --git a/.yarn/cache/dayjs-npm-1.11.2-644b12fe04-78f8bd04a9.zip b/.yarn/cache/dayjs-npm-1.11.2-644b12fe04-78f8bd04a9.zip deleted file mode 100644 index 9e092055103..00000000000 Binary files a/.yarn/cache/dayjs-npm-1.11.2-644b12fe04-78f8bd04a9.zip and /dev/null differ diff --git a/.yarn/cache/debug-npm-2.6.9-7d4cb597dc-d2f51589ca.zip b/.yarn/cache/debug-npm-2.6.9-7d4cb597dc-d2f51589ca.zip deleted file mode 100644 index 5a112760762..00000000000 Binary files a/.yarn/cache/debug-npm-2.6.9-7d4cb597dc-d2f51589ca.zip and /dev/null differ diff --git a/.yarn/cache/debug-npm-3.2.7-754e818c7a-b3d8c59407.zip b/.yarn/cache/debug-npm-3.2.7-754e818c7a-b3d8c59407.zip deleted file mode 100644 index b9eb5a9e889..00000000000 Binary files a/.yarn/cache/debug-npm-3.2.7-754e818c7a-b3d8c59407.zip and /dev/null differ diff --git a/.yarn/cache/debug-npm-4.3.4-4513954577-3dbad3f94e.zip b/.yarn/cache/debug-npm-4.3.4-4513954577-3dbad3f94e.zip deleted file mode 100644 index d3a11d8e2a7..00000000000 Binary files a/.yarn/cache/debug-npm-4.3.4-4513954577-3dbad3f94e.zip and /dev/null differ diff --git a/.yarn/cache/deep-eql-npm-3.0.1-9a66c09c65-4f4c9fb79e.zip b/.yarn/cache/deep-eql-npm-3.0.1-9a66c09c65-4f4c9fb79e.zip deleted file mode 100644 index 0c632a27ef0..00000000000 Binary files a/.yarn/cache/deep-eql-npm-3.0.1-9a66c09c65-4f4c9fb79e.zip and /dev/null differ diff --git a/.yarn/cache/deep-is-npm-0.1.4-88938b5a67-edb65dd0d7.zip b/.yarn/cache/deep-is-npm-0.1.4-88938b5a67-edb65dd0d7.zip deleted file mode 100644 index 2078a471f04..00000000000 Binary files a/.yarn/cache/deep-is-npm-0.1.4-88938b5a67-edb65dd0d7.zip and /dev/null differ diff --git a/.yarn/cache/deepmerge-npm-4.2.2-112165ced2-a8c43a1ed8.zip b/.yarn/cache/deepmerge-npm-4.2.2-112165ced2-a8c43a1ed8.zip deleted file mode 100644 index 3e07a61c478..00000000000 Binary files a/.yarn/cache/deepmerge-npm-4.2.2-112165ced2-a8c43a1ed8.zip and /dev/null differ diff --git a/.yarn/cache/define-properties-npm-1.1.4-85ee575655-ce0aef3f9e.zip b/.yarn/cache/define-properties-npm-1.1.4-85ee575655-ce0aef3f9e.zip deleted file mode 100644 index afc995a3c77..00000000000 Binary files a/.yarn/cache/define-properties-npm-1.1.4-85ee575655-ce0aef3f9e.zip and /dev/null differ diff --git a/.yarn/cache/delaunator-npm-5.0.0-9540390d61-d676418844.zip b/.yarn/cache/delaunator-npm-5.0.0-9540390d61-d676418844.zip deleted file mode 100644 index c1c27784424..00000000000 Binary files a/.yarn/cache/delaunator-npm-5.0.0-9540390d61-d676418844.zip and /dev/null differ diff --git a/.yarn/cache/delayed-stream-npm-1.0.0-c5a4c4cc02-46fe6e83e2.zip b/.yarn/cache/delayed-stream-npm-1.0.0-c5a4c4cc02-46fe6e83e2.zip deleted file mode 100644 index 71514340e4e..00000000000 Binary files a/.yarn/cache/delayed-stream-npm-1.0.0-c5a4c4cc02-46fe6e83e2.zip and /dev/null differ diff --git a/.yarn/cache/delegates-npm-1.0.0-9b1942d75f-a51744d9b5.zip b/.yarn/cache/delegates-npm-1.0.0-9b1942d75f-a51744d9b5.zip deleted file mode 100644 index 9921e5ec103..00000000000 Binary files a/.yarn/cache/delegates-npm-1.0.0-9b1942d75f-a51744d9b5.zip and /dev/null differ diff --git a/.yarn/cache/depd-npm-1.1.2-b0c8414da7-6b406620d2.zip b/.yarn/cache/depd-npm-1.1.2-b0c8414da7-6b406620d2.zip deleted file mode 100644 index 082e9254835..00000000000 Binary files a/.yarn/cache/depd-npm-1.1.2-b0c8414da7-6b406620d2.zip and /dev/null differ diff --git a/.yarn/cache/detect-libc-npm-1.0.3-c30ac344d4-daaaed925f.zip b/.yarn/cache/detect-libc-npm-1.0.3-c30ac344d4-daaaed925f.zip deleted file mode 100644 index 9c78505ea46..00000000000 Binary files a/.yarn/cache/detect-libc-npm-1.0.3-c30ac344d4-daaaed925f.zip and /dev/null differ diff --git a/.yarn/cache/diff-sequences-npm-27.5.1-29338362fa-a00db5554c.zip b/.yarn/cache/diff-sequences-npm-27.5.1-29338362fa-a00db5554c.zip deleted file mode 100644 index ddfadea4583..00000000000 Binary files a/.yarn/cache/diff-sequences-npm-27.5.1-29338362fa-a00db5554c.zip and /dev/null differ diff --git a/.yarn/cache/doctrine-npm-2.1.0-ac15d049b7-a45e277f7f.zip b/.yarn/cache/doctrine-npm-2.1.0-ac15d049b7-a45e277f7f.zip deleted file mode 100644 index b85eaafa1d7..00000000000 Binary files a/.yarn/cache/doctrine-npm-2.1.0-ac15d049b7-a45e277f7f.zip and /dev/null differ diff --git a/.yarn/cache/doctrine-npm-3.0.0-c6f1615f04-fd7673ca77.zip b/.yarn/cache/doctrine-npm-3.0.0-c6f1615f04-fd7673ca77.zip deleted file mode 100644 index 25e0903144c..00000000000 Binary files a/.yarn/cache/doctrine-npm-3.0.0-c6f1615f04-fd7673ca77.zip and /dev/null differ diff --git a/.yarn/cache/doctypes-npm-1.1.0-cb4fdda595-6e6c2d1a80.zip b/.yarn/cache/doctypes-npm-1.1.0-cb4fdda595-6e6c2d1a80.zip deleted file mode 100644 index 9bf826b3fc2..00000000000 Binary files a/.yarn/cache/doctypes-npm-1.1.0-cb4fdda595-6e6c2d1a80.zip and /dev/null differ diff --git a/.yarn/cache/dom-serializer-npm-1.4.1-ebb24349c1-fbb0b01f87.zip b/.yarn/cache/dom-serializer-npm-1.4.1-ebb24349c1-fbb0b01f87.zip deleted file mode 100644 index d59f3d3fe8f..00000000000 Binary files a/.yarn/cache/dom-serializer-npm-1.4.1-ebb24349c1-fbb0b01f87.zip and /dev/null differ diff --git a/.yarn/cache/domelementtype-npm-2.3.0-02de7cbfba-ee837a318f.zip b/.yarn/cache/domelementtype-npm-2.3.0-02de7cbfba-ee837a318f.zip deleted file mode 100644 index cab8bb79ac3..00000000000 Binary files a/.yarn/cache/domelementtype-npm-2.3.0-02de7cbfba-ee837a318f.zip and /dev/null differ diff --git a/.yarn/cache/domhandler-npm-4.3.1-493539c1ca-4c665ceed0.zip b/.yarn/cache/domhandler-npm-4.3.1-493539c1ca-4c665ceed0.zip deleted file mode 100644 index 6532c54da30..00000000000 Binary files a/.yarn/cache/domhandler-npm-4.3.1-493539c1ca-4c665ceed0.zip and /dev/null differ diff --git a/.yarn/cache/domutils-npm-2.8.0-0325139e5c-abf7434315.zip b/.yarn/cache/domutils-npm-2.8.0-0325139e5c-abf7434315.zip deleted file mode 100644 index ff5aa736dd7..00000000000 Binary files a/.yarn/cache/domutils-npm-2.8.0-0325139e5c-abf7434315.zip and /dev/null differ diff --git a/.yarn/cache/dotenv-expand-npm-5.1.0-c3fff50eb5-8017675b7f.zip b/.yarn/cache/dotenv-expand-npm-5.1.0-c3fff50eb5-8017675b7f.zip deleted file mode 100644 index 6eba7a7e7a9..00000000000 Binary files a/.yarn/cache/dotenv-expand-npm-5.1.0-c3fff50eb5-8017675b7f.zip and /dev/null differ diff --git a/.yarn/cache/dotenv-npm-7.0.0-9fbf3b4fd8-18a7b3ef0e.zip b/.yarn/cache/dotenv-npm-7.0.0-9fbf3b4fd8-18a7b3ef0e.zip deleted file mode 100644 index e5a4e458b68..00000000000 Binary files a/.yarn/cache/dotenv-npm-7.0.0-9fbf3b4fd8-18a7b3ef0e.zip and /dev/null differ diff --git a/.yarn/cache/ecc-jsbn-npm-0.1.2-85b7a7be89-22fef4b620.zip b/.yarn/cache/ecc-jsbn-npm-0.1.2-85b7a7be89-22fef4b620.zip deleted file mode 100644 index 80e362ad73d..00000000000 Binary files a/.yarn/cache/ecc-jsbn-npm-0.1.2-85b7a7be89-22fef4b620.zip and /dev/null differ diff --git a/.yarn/cache/electron-to-chromium-npm-1.4.137-35182e6efc-639d7b9490.zip b/.yarn/cache/electron-to-chromium-npm-1.4.137-35182e6efc-639d7b9490.zip deleted file mode 100644 index c180a38e90d..00000000000 Binary files a/.yarn/cache/electron-to-chromium-npm-1.4.137-35182e6efc-639d7b9490.zip and /dev/null differ diff --git a/.yarn/cache/emoji-regex-npm-8.0.0-213764015c-d4c5c39d5a.zip b/.yarn/cache/emoji-regex-npm-8.0.0-213764015c-d4c5c39d5a.zip deleted file mode 100644 index d02d8879711..00000000000 Binary files a/.yarn/cache/emoji-regex-npm-8.0.0-213764015c-d4c5c39d5a.zip and /dev/null differ diff --git a/.yarn/cache/encoding-npm-0.1.13-82a1837d30-bb98632f8f.zip b/.yarn/cache/encoding-npm-0.1.13-82a1837d30-bb98632f8f.zip deleted file mode 100644 index 202e93181a5..00000000000 Binary files a/.yarn/cache/encoding-npm-0.1.13-82a1837d30-bb98632f8f.zip and /dev/null differ diff --git a/.yarn/cache/end-of-stream-npm-1.4.4-497fc6dee1-530a5a5a1e.zip b/.yarn/cache/end-of-stream-npm-1.4.4-497fc6dee1-530a5a5a1e.zip deleted file mode 100644 index fecd2286f20..00000000000 Binary files a/.yarn/cache/end-of-stream-npm-1.4.4-497fc6dee1-530a5a5a1e.zip and /dev/null differ diff --git a/.yarn/cache/enquirer-npm-2.3.6-7899175762-1c0911e14a.zip b/.yarn/cache/enquirer-npm-2.3.6-7899175762-1c0911e14a.zip deleted file mode 100644 index 22c981f2bc0..00000000000 Binary files a/.yarn/cache/enquirer-npm-2.3.6-7899175762-1c0911e14a.zip and /dev/null differ diff --git a/.yarn/cache/entities-npm-2.2.0-0fc8d5b2f7-19010dacaf.zip b/.yarn/cache/entities-npm-2.2.0-0fc8d5b2f7-19010dacaf.zip deleted file mode 100644 index b0c0f76a595..00000000000 Binary files a/.yarn/cache/entities-npm-2.2.0-0fc8d5b2f7-19010dacaf.zip and /dev/null differ diff --git a/.yarn/cache/entities-npm-3.0.1-21eeb201ba-aaf7f12033.zip b/.yarn/cache/entities-npm-3.0.1-21eeb201ba-aaf7f12033.zip deleted file mode 100644 index 78991fcd204..00000000000 Binary files a/.yarn/cache/entities-npm-3.0.1-21eeb201ba-aaf7f12033.zip and /dev/null differ diff --git a/.yarn/cache/env-paths-npm-2.2.1-7c7577428c-65b5df55a8.zip b/.yarn/cache/env-paths-npm-2.2.1-7c7577428c-65b5df55a8.zip deleted file mode 100644 index 5fecf17a478..00000000000 Binary files a/.yarn/cache/env-paths-npm-2.2.1-7c7577428c-65b5df55a8.zip and /dev/null differ diff --git a/.yarn/cache/err-code-npm-2.0.3-082e0ff9a7-8b7b1be20d.zip b/.yarn/cache/err-code-npm-2.0.3-082e0ff9a7-8b7b1be20d.zip deleted file mode 100644 index 30585845686..00000000000 Binary files a/.yarn/cache/err-code-npm-2.0.3-082e0ff9a7-8b7b1be20d.zip and /dev/null differ diff --git a/.yarn/cache/error-ex-npm-1.3.2-5654f80c0f-c1c2b8b65f.zip b/.yarn/cache/error-ex-npm-1.3.2-5654f80c0f-c1c2b8b65f.zip deleted file mode 100644 index 9577ccee8de..00000000000 Binary files a/.yarn/cache/error-ex-npm-1.3.2-5654f80c0f-c1c2b8b65f.zip and /dev/null differ diff --git a/.yarn/cache/es-abstract-npm-1.19.5-524a87d262-55199b0f17.zip b/.yarn/cache/es-abstract-npm-1.19.5-524a87d262-55199b0f17.zip deleted file mode 100644 index 9c6cf6749b8..00000000000 Binary files a/.yarn/cache/es-abstract-npm-1.19.5-524a87d262-55199b0f17.zip and /dev/null differ diff --git a/.yarn/cache/es-shim-unscopables-npm-1.0.0-06186593f1-83e95cadbb.zip b/.yarn/cache/es-shim-unscopables-npm-1.0.0-06186593f1-83e95cadbb.zip deleted file mode 100644 index 87e87a9ea9b..00000000000 Binary files a/.yarn/cache/es-shim-unscopables-npm-1.0.0-06186593f1-83e95cadbb.zip and /dev/null differ diff --git a/.yarn/cache/es-to-primitive-npm-1.2.1-b7a7eac6c5-4ead6671a2.zip b/.yarn/cache/es-to-primitive-npm-1.2.1-b7a7eac6c5-4ead6671a2.zip deleted file mode 100644 index c0bb5b0c69a..00000000000 Binary files a/.yarn/cache/es-to-primitive-npm-1.2.1-b7a7eac6c5-4ead6671a2.zip and /dev/null differ diff --git a/.yarn/cache/esbuild-darwin-64-npm-0.14.38-fee9a60d9b-8.zip b/.yarn/cache/esbuild-darwin-64-npm-0.14.38-fee9a60d9b-8.zip deleted file mode 100644 index 41fc558ae2f..00000000000 Binary files a/.yarn/cache/esbuild-darwin-64-npm-0.14.38-fee9a60d9b-8.zip and /dev/null differ diff --git a/.yarn/cache/esbuild-darwin-64-npm-0.14.49-55333913ef-8.zip b/.yarn/cache/esbuild-darwin-64-npm-0.14.49-55333913ef-8.zip deleted file mode 100644 index cb177261d81..00000000000 Binary files a/.yarn/cache/esbuild-darwin-64-npm-0.14.49-55333913ef-8.zip and /dev/null differ diff --git a/.yarn/cache/esbuild-darwin-arm64-npm-0.14.38-b37de966bb-8.zip b/.yarn/cache/esbuild-darwin-arm64-npm-0.14.38-b37de966bb-8.zip deleted file mode 100644 index d991ac38580..00000000000 Binary files a/.yarn/cache/esbuild-darwin-arm64-npm-0.14.38-b37de966bb-8.zip and /dev/null differ diff --git a/.yarn/cache/esbuild-darwin-arm64-npm-0.14.49-3434761197-8.zip b/.yarn/cache/esbuild-darwin-arm64-npm-0.14.49-3434761197-8.zip deleted file mode 100644 index 62a9524db42..00000000000 Binary files a/.yarn/cache/esbuild-darwin-arm64-npm-0.14.49-3434761197-8.zip and /dev/null differ diff --git a/.yarn/cache/esbuild-linux-64-npm-0.14.38-c39b94428f-8.zip b/.yarn/cache/esbuild-linux-64-npm-0.14.38-c39b94428f-8.zip deleted file mode 100644 index 17f433ffb1d..00000000000 Binary files a/.yarn/cache/esbuild-linux-64-npm-0.14.38-c39b94428f-8.zip and /dev/null differ diff --git a/.yarn/cache/esbuild-linux-64-npm-0.14.49-96241737d6-8.zip b/.yarn/cache/esbuild-linux-64-npm-0.14.49-96241737d6-8.zip deleted file mode 100644 index f0c71d3c797..00000000000 Binary files a/.yarn/cache/esbuild-linux-64-npm-0.14.49-96241737d6-8.zip and /dev/null differ diff --git a/.yarn/cache/esbuild-linux-arm64-npm-0.14.38-cef31fba53-8.zip b/.yarn/cache/esbuild-linux-arm64-npm-0.14.38-cef31fba53-8.zip deleted file mode 100644 index 16e3d339688..00000000000 Binary files a/.yarn/cache/esbuild-linux-arm64-npm-0.14.38-cef31fba53-8.zip and /dev/null differ diff --git a/.yarn/cache/esbuild-linux-arm64-npm-0.14.49-54281525ae-8.zip b/.yarn/cache/esbuild-linux-arm64-npm-0.14.49-54281525ae-8.zip deleted file mode 100644 index 3fa33882a80..00000000000 Binary files a/.yarn/cache/esbuild-linux-arm64-npm-0.14.49-54281525ae-8.zip and /dev/null differ diff --git a/.yarn/cache/esbuild-npm-0.14.38-04b78ffe2b-d7523a36bd.zip b/.yarn/cache/esbuild-npm-0.14.38-04b78ffe2b-d7523a36bd.zip deleted file mode 100644 index 9487a6d5c50..00000000000 Binary files a/.yarn/cache/esbuild-npm-0.14.38-04b78ffe2b-d7523a36bd.zip and /dev/null differ diff --git a/.yarn/cache/esbuild-npm-0.14.49-8ea32c7f59-b718f4c9ea.zip b/.yarn/cache/esbuild-npm-0.14.49-8ea32c7f59-b718f4c9ea.zip deleted file mode 100644 index 1533a361b95..00000000000 Binary files a/.yarn/cache/esbuild-npm-0.14.49-8ea32c7f59-b718f4c9ea.zip and /dev/null differ diff --git a/.yarn/cache/esbuild-windows-64-npm-0.14.38-67094dd963-8.zip b/.yarn/cache/esbuild-windows-64-npm-0.14.38-67094dd963-8.zip deleted file mode 100644 index 84dfc50bbbc..00000000000 Binary files a/.yarn/cache/esbuild-windows-64-npm-0.14.38-67094dd963-8.zip and /dev/null differ diff --git a/.yarn/cache/esbuild-windows-64-npm-0.14.49-72426d3535-8.zip b/.yarn/cache/esbuild-windows-64-npm-0.14.49-72426d3535-8.zip deleted file mode 100644 index f3655daa64b..00000000000 Binary files a/.yarn/cache/esbuild-windows-64-npm-0.14.49-72426d3535-8.zip and /dev/null differ diff --git a/.yarn/cache/esbuild-windows-arm64-npm-0.14.38-9693d16298-8.zip b/.yarn/cache/esbuild-windows-arm64-npm-0.14.38-9693d16298-8.zip deleted file mode 100644 index 9ad725f42e6..00000000000 Binary files a/.yarn/cache/esbuild-windows-arm64-npm-0.14.38-9693d16298-8.zip and /dev/null differ diff --git a/.yarn/cache/esbuild-windows-arm64-npm-0.14.49-88d3b995f3-8.zip b/.yarn/cache/esbuild-windows-arm64-npm-0.14.49-88d3b995f3-8.zip deleted file mode 100644 index ca844d58da8..00000000000 Binary files a/.yarn/cache/esbuild-windows-arm64-npm-0.14.49-88d3b995f3-8.zip and /dev/null differ diff --git a/.yarn/cache/escalade-npm-3.1.1-e02da076aa-a3e2a99f07.zip b/.yarn/cache/escalade-npm-3.1.1-e02da076aa-a3e2a99f07.zip deleted file mode 100644 index 88c57af4b86..00000000000 Binary files a/.yarn/cache/escalade-npm-3.1.1-e02da076aa-a3e2a99f07.zip and /dev/null differ diff --git a/.yarn/cache/escape-string-regexp-npm-1.0.5-3284de402f-6092fda75c.zip b/.yarn/cache/escape-string-regexp-npm-1.0.5-3284de402f-6092fda75c.zip deleted file mode 100644 index b7ea3be1478..00000000000 Binary files a/.yarn/cache/escape-string-regexp-npm-1.0.5-3284de402f-6092fda75c.zip and /dev/null differ diff --git a/.yarn/cache/escape-string-regexp-npm-4.0.0-4b531d8d59-98b48897d9.zip b/.yarn/cache/escape-string-regexp-npm-4.0.0-4b531d8d59-98b48897d9.zip deleted file mode 100644 index c23e416b5a7..00000000000 Binary files a/.yarn/cache/escape-string-regexp-npm-4.0.0-4b531d8d59-98b48897d9.zip and /dev/null differ diff --git a/.yarn/cache/eslint-config-standard-npm-17.0.0-2803f6a79a-dc0ed51e18.zip b/.yarn/cache/eslint-config-standard-npm-17.0.0-2803f6a79a-dc0ed51e18.zip deleted file mode 100644 index 0cb3ae760a3..00000000000 Binary files a/.yarn/cache/eslint-config-standard-npm-17.0.0-2803f6a79a-dc0ed51e18.zip and /dev/null differ diff --git a/.yarn/cache/eslint-import-resolver-node-npm-0.3.6-d9426786c6-6266733af1.zip b/.yarn/cache/eslint-import-resolver-node-npm-0.3.6-d9426786c6-6266733af1.zip deleted file mode 100644 index a4588dad43f..00000000000 Binary files a/.yarn/cache/eslint-import-resolver-node-npm-0.3.6-d9426786c6-6266733af1.zip and /dev/null differ diff --git a/.yarn/cache/eslint-module-utils-npm-2.7.3-ccd32fe6fd-77048263f3.zip b/.yarn/cache/eslint-module-utils-npm-2.7.3-ccd32fe6fd-77048263f3.zip deleted file mode 100644 index 647dc496000..00000000000 Binary files a/.yarn/cache/eslint-module-utils-npm-2.7.3-ccd32fe6fd-77048263f3.zip and /dev/null differ diff --git a/.yarn/cache/eslint-npm-8.20.0-6bbc377ff7-a31adf390d.zip b/.yarn/cache/eslint-npm-8.20.0-6bbc377ff7-a31adf390d.zip deleted file mode 100644 index d85f41d25a6..00000000000 Binary files a/.yarn/cache/eslint-npm-8.20.0-6bbc377ff7-a31adf390d.zip and /dev/null differ diff --git a/.yarn/cache/eslint-plugin-cypress-npm-2.12.1-6681f582fa-1f1c36e149.zip b/.yarn/cache/eslint-plugin-cypress-npm-2.12.1-6681f582fa-1f1c36e149.zip deleted file mode 100644 index 53d6f880de4..00000000000 Binary files a/.yarn/cache/eslint-plugin-cypress-npm-2.12.1-6681f582fa-1f1c36e149.zip and /dev/null differ diff --git a/.yarn/cache/eslint-plugin-es-npm-3.0.1-95e8015220-e57592c523.zip b/.yarn/cache/eslint-plugin-es-npm-3.0.1-95e8015220-e57592c523.zip deleted file mode 100644 index a63c083d9b0..00000000000 Binary files a/.yarn/cache/eslint-plugin-es-npm-3.0.1-95e8015220-e57592c523.zip and /dev/null differ diff --git a/.yarn/cache/eslint-plugin-es-npm-4.1.0-a4cf26d3cd-26b87a216d.zip b/.yarn/cache/eslint-plugin-es-npm-4.1.0-a4cf26d3cd-26b87a216d.zip deleted file mode 100644 index e42ed00d8e8..00000000000 Binary files a/.yarn/cache/eslint-plugin-es-npm-4.1.0-a4cf26d3cd-26b87a216d.zip and /dev/null differ diff --git a/.yarn/cache/eslint-plugin-import-npm-2.26.0-959fe14a01-0bf77ad803.zip b/.yarn/cache/eslint-plugin-import-npm-2.26.0-959fe14a01-0bf77ad803.zip deleted file mode 100644 index 62c5e22fd65..00000000000 Binary files a/.yarn/cache/eslint-plugin-import-npm-2.26.0-959fe14a01-0bf77ad803.zip and /dev/null differ diff --git a/.yarn/cache/eslint-plugin-n-npm-15.2.0-669e8b723e-4303dea35a.zip b/.yarn/cache/eslint-plugin-n-npm-15.2.0-669e8b723e-4303dea35a.zip deleted file mode 100644 index b02ddcd680c..00000000000 Binary files a/.yarn/cache/eslint-plugin-n-npm-15.2.0-669e8b723e-4303dea35a.zip and /dev/null differ diff --git a/.yarn/cache/eslint-plugin-node-npm-11.1.0-913abe06f4-5804c4f8a6.zip b/.yarn/cache/eslint-plugin-node-npm-11.1.0-913abe06f4-5804c4f8a6.zip deleted file mode 100644 index b322a2ccdc2..00000000000 Binary files a/.yarn/cache/eslint-plugin-node-npm-11.1.0-913abe06f4-5804c4f8a6.zip and /dev/null differ diff --git a/.yarn/cache/eslint-plugin-promise-npm-6.0.0-5a0de876d5-7e761507c5.zip b/.yarn/cache/eslint-plugin-promise-npm-6.0.0-5a0de876d5-7e761507c5.zip deleted file mode 100644 index 48b2de5c4a0..00000000000 Binary files a/.yarn/cache/eslint-plugin-promise-npm-6.0.0-5a0de876d5-7e761507c5.zip and /dev/null differ diff --git a/.yarn/cache/eslint-plugin-vue-npm-9.2.0-eb1ca66b56-008819b12a.zip b/.yarn/cache/eslint-plugin-vue-npm-9.2.0-eb1ca66b56-008819b12a.zip deleted file mode 100644 index 0b2127d21d0..00000000000 Binary files a/.yarn/cache/eslint-plugin-vue-npm-9.2.0-eb1ca66b56-008819b12a.zip and /dev/null differ diff --git a/.yarn/cache/eslint-scope-npm-7.1.1-23935eb377-9f6e974ab2.zip b/.yarn/cache/eslint-scope-npm-7.1.1-23935eb377-9f6e974ab2.zip deleted file mode 100644 index fcad723df34..00000000000 Binary files a/.yarn/cache/eslint-scope-npm-7.1.1-23935eb377-9f6e974ab2.zip and /dev/null differ diff --git a/.yarn/cache/eslint-utils-npm-2.1.0-a3a7ebf4fa-27500938f3.zip b/.yarn/cache/eslint-utils-npm-2.1.0-a3a7ebf4fa-27500938f3.zip deleted file mode 100644 index 1dadeb5d09b..00000000000 Binary files a/.yarn/cache/eslint-utils-npm-2.1.0-a3a7ebf4fa-27500938f3.zip and /dev/null differ diff --git a/.yarn/cache/eslint-utils-npm-3.0.0-630b3a4013-0668fe02f5.zip b/.yarn/cache/eslint-utils-npm-3.0.0-630b3a4013-0668fe02f5.zip deleted file mode 100644 index 1ece43c644b..00000000000 Binary files a/.yarn/cache/eslint-utils-npm-3.0.0-630b3a4013-0668fe02f5.zip and /dev/null differ diff --git a/.yarn/cache/eslint-visitor-keys-npm-1.3.0-c07780a0fb-37a19b712f.zip b/.yarn/cache/eslint-visitor-keys-npm-1.3.0-c07780a0fb-37a19b712f.zip deleted file mode 100644 index 070b3cb7884..00000000000 Binary files a/.yarn/cache/eslint-visitor-keys-npm-1.3.0-c07780a0fb-37a19b712f.zip and /dev/null differ diff --git a/.yarn/cache/eslint-visitor-keys-npm-2.1.0-c31806b6b9-e3081d7dd2.zip b/.yarn/cache/eslint-visitor-keys-npm-2.1.0-c31806b6b9-e3081d7dd2.zip deleted file mode 100644 index a99eddbc6a3..00000000000 Binary files a/.yarn/cache/eslint-visitor-keys-npm-2.1.0-c31806b6b9-e3081d7dd2.zip and /dev/null differ diff --git a/.yarn/cache/eslint-visitor-keys-npm-3.3.0-d329af7c8c-d59e68a7c5.zip b/.yarn/cache/eslint-visitor-keys-npm-3.3.0-d329af7c8c-d59e68a7c5.zip deleted file mode 100644 index a46738b25f1..00000000000 Binary files a/.yarn/cache/eslint-visitor-keys-npm-3.3.0-d329af7c8c-d59e68a7c5.zip and /dev/null differ diff --git a/.yarn/cache/espree-npm-9.3.2-c70fa2a91d-9a790d6779.zip b/.yarn/cache/espree-npm-9.3.2-c70fa2a91d-9a790d6779.zip deleted file mode 100644 index 4b4bfe1f4df..00000000000 Binary files a/.yarn/cache/espree-npm-9.3.2-c70fa2a91d-9a790d6779.zip and /dev/null differ diff --git a/.yarn/cache/esquery-npm-1.4.0-f39408b1a7-a0807e17ab.zip b/.yarn/cache/esquery-npm-1.4.0-f39408b1a7-a0807e17ab.zip deleted file mode 100644 index abf91d4c4fa..00000000000 Binary files a/.yarn/cache/esquery-npm-1.4.0-f39408b1a7-a0807e17ab.zip and /dev/null differ diff --git a/.yarn/cache/esrecurse-npm-4.3.0-10b86a887a-ebc17b1a33.zip b/.yarn/cache/esrecurse-npm-4.3.0-10b86a887a-ebc17b1a33.zip deleted file mode 100644 index 97e67b46e5d..00000000000 Binary files a/.yarn/cache/esrecurse-npm-4.3.0-10b86a887a-ebc17b1a33.zip and /dev/null differ diff --git a/.yarn/cache/estraverse-npm-5.3.0-03284f8f63-072780882d.zip b/.yarn/cache/estraverse-npm-5.3.0-03284f8f63-072780882d.zip deleted file mode 100644 index eb7c3ccbcd9..00000000000 Binary files a/.yarn/cache/estraverse-npm-5.3.0-03284f8f63-072780882d.zip and /dev/null differ diff --git a/.yarn/cache/estree-walker-npm-2.0.2-dfab42f65c-6151e6f982.zip b/.yarn/cache/estree-walker-npm-2.0.2-dfab42f65c-6151e6f982.zip deleted file mode 100644 index 71b90a2f2c5..00000000000 Binary files a/.yarn/cache/estree-walker-npm-2.0.2-dfab42f65c-6151e6f982.zip and /dev/null differ diff --git a/.yarn/cache/esutils-npm-2.0.3-f865beafd5-22b5b08f74.zip b/.yarn/cache/esutils-npm-2.0.3-f865beafd5-22b5b08f74.zip deleted file mode 100644 index c163c32a0e8..00000000000 Binary files a/.yarn/cache/esutils-npm-2.0.3-f865beafd5-22b5b08f74.zip and /dev/null differ diff --git a/.yarn/cache/eventemitter2-npm-6.4.5-6862f231f1-84504f9cf0.zip b/.yarn/cache/eventemitter2-npm-6.4.5-6862f231f1-84504f9cf0.zip deleted file mode 100644 index 78ed2083e05..00000000000 Binary files a/.yarn/cache/eventemitter2-npm-6.4.5-6862f231f1-84504f9cf0.zip and /dev/null differ diff --git a/.yarn/cache/evtd-npm-0.2.3-51a4edcda1-5ddded6263.zip b/.yarn/cache/evtd-npm-0.2.3-51a4edcda1-5ddded6263.zip deleted file mode 100644 index 3e341b96ef8..00000000000 Binary files a/.yarn/cache/evtd-npm-0.2.3-51a4edcda1-5ddded6263.zip and /dev/null differ diff --git a/.yarn/cache/execa-npm-4.1.0-cc675b4189-e30d298934.zip b/.yarn/cache/execa-npm-4.1.0-cc675b4189-e30d298934.zip deleted file mode 100644 index bffd898183d..00000000000 Binary files a/.yarn/cache/execa-npm-4.1.0-cc675b4189-e30d298934.zip and /dev/null differ diff --git a/.yarn/cache/executable-npm-4.1.1-c06d32cd1b-f01927ce59.zip b/.yarn/cache/executable-npm-4.1.1-c06d32cd1b-f01927ce59.zip deleted file mode 100644 index 63ff61c87ca..00000000000 Binary files a/.yarn/cache/executable-npm-4.1.1-c06d32cd1b-f01927ce59.zip and /dev/null differ diff --git a/.yarn/cache/extend-npm-3.0.2-e1ca07ac54-a50a8309ca.zip b/.yarn/cache/extend-npm-3.0.2-e1ca07ac54-a50a8309ca.zip deleted file mode 100644 index a33fb285f42..00000000000 Binary files a/.yarn/cache/extend-npm-3.0.2-e1ca07ac54-a50a8309ca.zip and /dev/null differ diff --git a/.yarn/cache/extract-zip-npm-2.0.1-92a28e392b-8cbda9debd.zip b/.yarn/cache/extract-zip-npm-2.0.1-92a28e392b-8cbda9debd.zip deleted file mode 100644 index 2169ae49126..00000000000 Binary files a/.yarn/cache/extract-zip-npm-2.0.1-92a28e392b-8cbda9debd.zip and /dev/null differ diff --git a/.yarn/cache/extsprintf-npm-1.3.0-61a92b324c-cee7a4a1e3.zip b/.yarn/cache/extsprintf-npm-1.3.0-61a92b324c-cee7a4a1e3.zip deleted file mode 100644 index e72ea1cf447..00000000000 Binary files a/.yarn/cache/extsprintf-npm-1.3.0-61a92b324c-cee7a4a1e3.zip and /dev/null differ diff --git a/.yarn/cache/fast-deep-equal-npm-3.1.3-790edcfcf5-e21a9d8d84.zip b/.yarn/cache/fast-deep-equal-npm-3.1.3-790edcfcf5-e21a9d8d84.zip deleted file mode 100644 index c06008992c9..00000000000 Binary files a/.yarn/cache/fast-deep-equal-npm-3.1.3-790edcfcf5-e21a9d8d84.zip and /dev/null differ diff --git a/.yarn/cache/fast-json-stable-stringify-npm-2.1.0-02e8905fda-b191531e36.zip b/.yarn/cache/fast-json-stable-stringify-npm-2.1.0-02e8905fda-b191531e36.zip deleted file mode 100644 index 737d4761f35..00000000000 Binary files a/.yarn/cache/fast-json-stable-stringify-npm-2.1.0-02e8905fda-b191531e36.zip and /dev/null differ diff --git a/.yarn/cache/fast-levenshtein-npm-2.0.6-fcd74b8df5-92cfec0a8d.zip b/.yarn/cache/fast-levenshtein-npm-2.0.6-fcd74b8df5-92cfec0a8d.zip deleted file mode 100644 index ffb76eb13cd..00000000000 Binary files a/.yarn/cache/fast-levenshtein-npm-2.0.6-fcd74b8df5-92cfec0a8d.zip and /dev/null differ diff --git a/.yarn/cache/fd-slicer-npm-1.1.0-3cade0050a-c8585fd571.zip b/.yarn/cache/fd-slicer-npm-1.1.0-3cade0050a-c8585fd571.zip deleted file mode 100644 index 13159628cb5..00000000000 Binary files a/.yarn/cache/fd-slicer-npm-1.1.0-3cade0050a-c8585fd571.zip and /dev/null differ diff --git a/.yarn/cache/figures-npm-3.2.0-85d357e955-85a6ad29e9.zip b/.yarn/cache/figures-npm-3.2.0-85d357e955-85a6ad29e9.zip deleted file mode 100644 index eac0ef72262..00000000000 Binary files a/.yarn/cache/figures-npm-3.2.0-85d357e955-85a6ad29e9.zip and /dev/null differ diff --git a/.yarn/cache/file-entry-cache-npm-6.0.1-31965cf0af-f49701feaa.zip b/.yarn/cache/file-entry-cache-npm-6.0.1-31965cf0af-f49701feaa.zip deleted file mode 100644 index 3748d0b2d21..00000000000 Binary files a/.yarn/cache/file-entry-cache-npm-6.0.1-31965cf0af-f49701feaa.zip and /dev/null differ diff --git a/.yarn/cache/file-saver-npm-2.0.5-2c3bc40d53-c62d96e5ce.zip b/.yarn/cache/file-saver-npm-2.0.5-2c3bc40d53-c62d96e5ce.zip deleted file mode 100644 index deabe2a689a..00000000000 Binary files a/.yarn/cache/file-saver-npm-2.0.5-2c3bc40d53-c62d96e5ce.zip and /dev/null differ diff --git a/.yarn/cache/fill-range-npm-7.0.1-b8b1817caa-cc283f4e65.zip b/.yarn/cache/fill-range-npm-7.0.1-b8b1817caa-cc283f4e65.zip deleted file mode 100644 index 1da4a361d87..00000000000 Binary files a/.yarn/cache/fill-range-npm-7.0.1-b8b1817caa-cc283f4e65.zip and /dev/null differ diff --git a/.yarn/cache/find-up-npm-2.1.0-9f6cb1765c-43284fe4da.zip b/.yarn/cache/find-up-npm-2.1.0-9f6cb1765c-43284fe4da.zip deleted file mode 100644 index 6b2c2d9da4e..00000000000 Binary files a/.yarn/cache/find-up-npm-2.1.0-9f6cb1765c-43284fe4da.zip and /dev/null differ diff --git a/.yarn/cache/find-up-npm-5.0.0-e03e9b796d-07955e3573.zip b/.yarn/cache/find-up-npm-5.0.0-e03e9b796d-07955e3573.zip deleted file mode 100644 index 034f3a07ef6..00000000000 Binary files a/.yarn/cache/find-up-npm-5.0.0-e03e9b796d-07955e3573.zip and /dev/null differ diff --git a/.yarn/cache/flat-cache-npm-3.0.4-ee77e5911e-4fdd10ecbc.zip b/.yarn/cache/flat-cache-npm-3.0.4-ee77e5911e-4fdd10ecbc.zip deleted file mode 100644 index adabb73b05d..00000000000 Binary files a/.yarn/cache/flat-cache-npm-3.0.4-ee77e5911e-4fdd10ecbc.zip and /dev/null differ diff --git a/.yarn/cache/flatted-npm-3.2.5-0ee5a8875f-3c436e9695.zip b/.yarn/cache/flatted-npm-3.2.5-0ee5a8875f-3c436e9695.zip deleted file mode 100644 index 0a71b59ca50..00000000000 Binary files a/.yarn/cache/flatted-npm-3.2.5-0ee5a8875f-3c436e9695.zip and /dev/null differ diff --git a/.yarn/cache/foreground-child-npm-2.0.0-80c976b61e-f77ec9aff6.zip b/.yarn/cache/foreground-child-npm-2.0.0-80c976b61e-f77ec9aff6.zip deleted file mode 100644 index d947311d1e9..00000000000 Binary files a/.yarn/cache/foreground-child-npm-2.0.0-80c976b61e-f77ec9aff6.zip and /dev/null differ diff --git a/.yarn/cache/forever-agent-npm-0.6.1-01dae53bf9-766ae6e220.zip b/.yarn/cache/forever-agent-npm-0.6.1-01dae53bf9-766ae6e220.zip deleted file mode 100644 index 8250de6b49d..00000000000 Binary files a/.yarn/cache/forever-agent-npm-0.6.1-01dae53bf9-766ae6e220.zip and /dev/null differ diff --git a/.yarn/cache/form-data-npm-2.3.3-c016cc11c0-10c1780fa1.zip b/.yarn/cache/form-data-npm-2.3.3-c016cc11c0-10c1780fa1.zip deleted file mode 100644 index 9e2c84d8441..00000000000 Binary files a/.yarn/cache/form-data-npm-2.3.3-c016cc11c0-10c1780fa1.zip and /dev/null differ diff --git a/.yarn/cache/fs-extra-npm-9.1.0-983c2ddb4c-ba71ba32e0.zip b/.yarn/cache/fs-extra-npm-9.1.0-983c2ddb4c-ba71ba32e0.zip deleted file mode 100644 index 4a760ba0f6d..00000000000 Binary files a/.yarn/cache/fs-extra-npm-9.1.0-983c2ddb4c-ba71ba32e0.zip and /dev/null differ diff --git a/.yarn/cache/fs-minipass-npm-2.1.0-501ef87306-1b8d128dae.zip b/.yarn/cache/fs-minipass-npm-2.1.0-501ef87306-1b8d128dae.zip deleted file mode 100644 index 21a91aac75a..00000000000 Binary files a/.yarn/cache/fs-minipass-npm-2.1.0-501ef87306-1b8d128dae.zip and /dev/null differ diff --git a/.yarn/cache/fs.realpath-npm-1.0.0-c8f05d8126-99ddea01a7.zip b/.yarn/cache/fs.realpath-npm-1.0.0-c8f05d8126-99ddea01a7.zip deleted file mode 100644 index 920c4caedca..00000000000 Binary files a/.yarn/cache/fs.realpath-npm-1.0.0-c8f05d8126-99ddea01a7.zip and /dev/null differ diff --git a/.yarn/cache/fsevents-npm-2.3.2-a881d6ac9f-97ade64e75.zip b/.yarn/cache/fsevents-npm-2.3.2-a881d6ac9f-97ade64e75.zip deleted file mode 100644 index 204c8e4846b..00000000000 Binary files a/.yarn/cache/fsevents-npm-2.3.2-a881d6ac9f-97ade64e75.zip and /dev/null differ diff --git a/.yarn/cache/fsevents-patch-3340e2eb10-8.zip b/.yarn/cache/fsevents-patch-3340e2eb10-8.zip deleted file mode 100644 index c4511f19bda..00000000000 Binary files a/.yarn/cache/fsevents-patch-3340e2eb10-8.zip and /dev/null differ diff --git a/.yarn/cache/function-bind-npm-1.1.1-b56b322ae9-b32fbaebb3.zip b/.yarn/cache/function-bind-npm-1.1.1-b56b322ae9-b32fbaebb3.zip deleted file mode 100644 index c22a184eba2..00000000000 Binary files a/.yarn/cache/function-bind-npm-1.1.1-b56b322ae9-b32fbaebb3.zip and /dev/null differ diff --git a/.yarn/cache/functional-red-black-tree-npm-1.0.1-ccfe924dcd-ca6c170f37.zip b/.yarn/cache/functional-red-black-tree-npm-1.0.1-ccfe924dcd-ca6c170f37.zip deleted file mode 100644 index 3478d021dae..00000000000 Binary files a/.yarn/cache/functional-red-black-tree-npm-1.0.1-ccfe924dcd-ca6c170f37.zip and /dev/null differ diff --git a/.yarn/cache/gauge-npm-4.0.4-8f878385e9-788b6bfe52.zip b/.yarn/cache/gauge-npm-4.0.4-8f878385e9-788b6bfe52.zip deleted file mode 100644 index ef82b8737a3..00000000000 Binary files a/.yarn/cache/gauge-npm-4.0.4-8f878385e9-788b6bfe52.zip and /dev/null differ diff --git a/.yarn/cache/get-caller-file-npm-2.0.5-80e8a86305-b9769a836d.zip b/.yarn/cache/get-caller-file-npm-2.0.5-80e8a86305-b9769a836d.zip deleted file mode 100644 index 0aa2c9cd03d..00000000000 Binary files a/.yarn/cache/get-caller-file-npm-2.0.5-80e8a86305-b9769a836d.zip and /dev/null differ diff --git a/.yarn/cache/get-func-name-npm-2.0.0-afbf363765-8d82e69f3e.zip b/.yarn/cache/get-func-name-npm-2.0.0-afbf363765-8d82e69f3e.zip deleted file mode 100644 index 7374eae53be..00000000000 Binary files a/.yarn/cache/get-func-name-npm-2.0.0-afbf363765-8d82e69f3e.zip and /dev/null differ diff --git a/.yarn/cache/get-intrinsic-npm-1.1.1-7e868745da-a9fe2ca8fa.zip b/.yarn/cache/get-intrinsic-npm-1.1.1-7e868745da-a9fe2ca8fa.zip deleted file mode 100644 index a33f35fae33..00000000000 Binary files a/.yarn/cache/get-intrinsic-npm-1.1.1-7e868745da-a9fe2ca8fa.zip and /dev/null differ diff --git a/.yarn/cache/get-port-npm-4.2.0-07a1c5d34e-6c9a452b2d.zip b/.yarn/cache/get-port-npm-4.2.0-07a1c5d34e-6c9a452b2d.zip deleted file mode 100644 index e83d6e1feb7..00000000000 Binary files a/.yarn/cache/get-port-npm-4.2.0-07a1c5d34e-6c9a452b2d.zip and /dev/null differ diff --git a/.yarn/cache/get-stream-npm-5.2.0-2cfd3b452b-8bc1a23174.zip b/.yarn/cache/get-stream-npm-5.2.0-2cfd3b452b-8bc1a23174.zip deleted file mode 100644 index f5e0b29aa20..00000000000 Binary files a/.yarn/cache/get-stream-npm-5.2.0-2cfd3b452b-8bc1a23174.zip and /dev/null differ diff --git a/.yarn/cache/get-symbol-description-npm-1.0.0-9c95a4bc1f-9ceff8fe96.zip b/.yarn/cache/get-symbol-description-npm-1.0.0-9c95a4bc1f-9ceff8fe96.zip deleted file mode 100644 index 5cdbc26f258..00000000000 Binary files a/.yarn/cache/get-symbol-description-npm-1.0.0-9c95a4bc1f-9ceff8fe96.zip and /dev/null differ diff --git a/.yarn/cache/getos-npm-3.2.1-620c03aa34-42fd78a66d.zip b/.yarn/cache/getos-npm-3.2.1-620c03aa34-42fd78a66d.zip deleted file mode 100644 index ff87b0c5d2d..00000000000 Binary files a/.yarn/cache/getos-npm-3.2.1-620c03aa34-42fd78a66d.zip and /dev/null differ diff --git a/.yarn/cache/getpass-npm-0.1.7-519164a3be-ab18d55661.zip b/.yarn/cache/getpass-npm-0.1.7-519164a3be-ab18d55661.zip deleted file mode 100644 index c0a0abf62c4..00000000000 Binary files a/.yarn/cache/getpass-npm-0.1.7-519164a3be-ab18d55661.zip and /dev/null differ diff --git a/.yarn/cache/glob-npm-7.2.3-2d866d17a5-29452e97b3.zip b/.yarn/cache/glob-npm-7.2.3-2d866d17a5-29452e97b3.zip deleted file mode 100644 index b2fa0ac329c..00000000000 Binary files a/.yarn/cache/glob-npm-7.2.3-2d866d17a5-29452e97b3.zip and /dev/null differ diff --git a/.yarn/cache/glob-npm-8.0.3-750f909025-50bcdea19d.zip b/.yarn/cache/glob-npm-8.0.3-750f909025-50bcdea19d.zip deleted file mode 100644 index 4b8d24d33ee..00000000000 Binary files a/.yarn/cache/glob-npm-8.0.3-750f909025-50bcdea19d.zip and /dev/null differ diff --git a/.yarn/cache/glob-parent-npm-5.1.2-021ab32634-f4f2bfe242.zip b/.yarn/cache/glob-parent-npm-5.1.2-021ab32634-f4f2bfe242.zip deleted file mode 100644 index 8a94317ecb6..00000000000 Binary files a/.yarn/cache/glob-parent-npm-5.1.2-021ab32634-f4f2bfe242.zip and /dev/null differ diff --git a/.yarn/cache/glob-parent-npm-6.0.2-2cbef12738-c13ee97978.zip b/.yarn/cache/glob-parent-npm-6.0.2-2cbef12738-c13ee97978.zip deleted file mode 100644 index 2a4d60d7260..00000000000 Binary files a/.yarn/cache/glob-parent-npm-6.0.2-2cbef12738-c13ee97978.zip and /dev/null differ diff --git a/.yarn/cache/global-dirs-npm-3.0.0-45faebeb68-953c17cf14.zip b/.yarn/cache/global-dirs-npm-3.0.0-45faebeb68-953c17cf14.zip deleted file mode 100644 index 3f2995afe67..00000000000 Binary files a/.yarn/cache/global-dirs-npm-3.0.0-45faebeb68-953c17cf14.zip and /dev/null differ diff --git a/.yarn/cache/globals-npm-11.12.0-1fa7f41a6c-67051a45ec.zip b/.yarn/cache/globals-npm-11.12.0-1fa7f41a6c-67051a45ec.zip deleted file mode 100644 index 306b5aacad3..00000000000 Binary files a/.yarn/cache/globals-npm-11.12.0-1fa7f41a6c-67051a45ec.zip and /dev/null differ diff --git a/.yarn/cache/globals-npm-13.15.0-c0b0c83a7a-383ade0873.zip b/.yarn/cache/globals-npm-13.15.0-c0b0c83a7a-383ade0873.zip deleted file mode 100644 index b74e2b3511d..00000000000 Binary files a/.yarn/cache/globals-npm-13.15.0-c0b0c83a7a-383ade0873.zip and /dev/null differ diff --git a/.yarn/cache/graceful-fs-npm-4.2.10-79c70989ca-3f109d70ae.zip b/.yarn/cache/graceful-fs-npm-4.2.10-79c70989ca-3f109d70ae.zip deleted file mode 100644 index 2d04255c12e..00000000000 Binary files a/.yarn/cache/graceful-fs-npm-4.2.10-79c70989ca-3f109d70ae.zip and /dev/null differ diff --git a/.yarn/cache/has-bigints-npm-1.0.2-52732e614d-390e31e7be.zip b/.yarn/cache/has-bigints-npm-1.0.2-52732e614d-390e31e7be.zip deleted file mode 100644 index bc0b5ffd549..00000000000 Binary files a/.yarn/cache/has-bigints-npm-1.0.2-52732e614d-390e31e7be.zip and /dev/null differ diff --git a/.yarn/cache/has-flag-npm-3.0.0-16ac11fe05-4a15638b45.zip b/.yarn/cache/has-flag-npm-3.0.0-16ac11fe05-4a15638b45.zip deleted file mode 100644 index 60eafa65f5d..00000000000 Binary files a/.yarn/cache/has-flag-npm-3.0.0-16ac11fe05-4a15638b45.zip and /dev/null differ diff --git a/.yarn/cache/has-flag-npm-4.0.0-32af9f0536-261a135703.zip b/.yarn/cache/has-flag-npm-4.0.0-32af9f0536-261a135703.zip deleted file mode 100644 index 6f5845da2f6..00000000000 Binary files a/.yarn/cache/has-flag-npm-4.0.0-32af9f0536-261a135703.zip and /dev/null differ diff --git a/.yarn/cache/has-npm-1.0.3-b7f00631c1-b9ad53d53b.zip b/.yarn/cache/has-npm-1.0.3-b7f00631c1-b9ad53d53b.zip deleted file mode 100644 index f0731c951d2..00000000000 Binary files a/.yarn/cache/has-npm-1.0.3-b7f00631c1-b9ad53d53b.zip and /dev/null differ diff --git a/.yarn/cache/has-property-descriptors-npm-1.0.0-56289b918d-a6d3f0a266.zip b/.yarn/cache/has-property-descriptors-npm-1.0.0-56289b918d-a6d3f0a266.zip deleted file mode 100644 index 46eaa4fd050..00000000000 Binary files a/.yarn/cache/has-property-descriptors-npm-1.0.0-56289b918d-a6d3f0a266.zip and /dev/null differ diff --git a/.yarn/cache/has-symbols-npm-1.0.3-1986bff2c4-a054c40c63.zip b/.yarn/cache/has-symbols-npm-1.0.3-1986bff2c4-a054c40c63.zip deleted file mode 100644 index d07bbd4967b..00000000000 Binary files a/.yarn/cache/has-symbols-npm-1.0.3-1986bff2c4-a054c40c63.zip and /dev/null differ diff --git a/.yarn/cache/has-tostringtag-npm-1.0.0-b1fcf3ab55-cc12eb28cb.zip b/.yarn/cache/has-tostringtag-npm-1.0.0-b1fcf3ab55-cc12eb28cb.zip deleted file mode 100644 index 7718fc28f64..00000000000 Binary files a/.yarn/cache/has-tostringtag-npm-1.0.0-b1fcf3ab55-cc12eb28cb.zip and /dev/null differ diff --git a/.yarn/cache/has-unicode-npm-2.0.1-893adb4747-1eab07a743.zip b/.yarn/cache/has-unicode-npm-2.0.1-893adb4747-1eab07a743.zip deleted file mode 100644 index 5988a7e8aa9..00000000000 Binary files a/.yarn/cache/has-unicode-npm-2.0.1-893adb4747-1eab07a743.zip and /dev/null differ diff --git a/.yarn/cache/highcharts-npm-10.2.0-5422304a58-b9e16b9fc4.zip b/.yarn/cache/highcharts-npm-10.2.0-5422304a58-b9e16b9fc4.zip deleted file mode 100644 index b7b83ef2849..00000000000 Binary files a/.yarn/cache/highcharts-npm-10.2.0-5422304a58-b9e16b9fc4.zip and /dev/null differ diff --git a/.yarn/cache/highlight.js-npm-11.5.1-0fb1167640-bff556101d.zip b/.yarn/cache/highlight.js-npm-11.5.1-0fb1167640-bff556101d.zip deleted file mode 100644 index efbd98ed5de..00000000000 Binary files a/.yarn/cache/highlight.js-npm-11.5.1-0fb1167640-bff556101d.zip and /dev/null differ diff --git a/.yarn/cache/html-escaper-npm-2.0.2-38e51ef294-d2df2da3ad.zip b/.yarn/cache/html-escaper-npm-2.0.2-38e51ef294-d2df2da3ad.zip deleted file mode 100644 index cf5e7a07742..00000000000 Binary files a/.yarn/cache/html-escaper-npm-2.0.2-38e51ef294-d2df2da3ad.zip and /dev/null differ diff --git a/.yarn/cache/html-validate-npm-7.1.2-66108a0686-616c859647.zip b/.yarn/cache/html-validate-npm-7.1.2-66108a0686-616c859647.zip deleted file mode 100644 index f11b95ccf22..00000000000 Binary files a/.yarn/cache/html-validate-npm-7.1.2-66108a0686-616c859647.zip and /dev/null differ diff --git a/.yarn/cache/htmlnano-npm-2.0.2-a89803bfeb-41f9e0c0e5.zip b/.yarn/cache/htmlnano-npm-2.0.2-a89803bfeb-41f9e0c0e5.zip deleted file mode 100644 index a0b15302fde..00000000000 Binary files a/.yarn/cache/htmlnano-npm-2.0.2-a89803bfeb-41f9e0c0e5.zip and /dev/null differ diff --git a/.yarn/cache/htmlparser2-npm-7.2.0-ec7c96986f-96563d9965.zip b/.yarn/cache/htmlparser2-npm-7.2.0-ec7c96986f-96563d9965.zip deleted file mode 100644 index 28ff65de4e6..00000000000 Binary files a/.yarn/cache/htmlparser2-npm-7.2.0-ec7c96986f-96563d9965.zip and /dev/null differ diff --git a/.yarn/cache/http-cache-semantics-npm-4.1.0-860520a31f-974de94a81.zip b/.yarn/cache/http-cache-semantics-npm-4.1.0-860520a31f-974de94a81.zip deleted file mode 100644 index ed85c1c4c78..00000000000 Binary files a/.yarn/cache/http-cache-semantics-npm-4.1.0-860520a31f-974de94a81.zip and /dev/null differ diff --git a/.yarn/cache/http-proxy-agent-npm-5.0.0-7f1f121b83-e2ee1ff165.zip b/.yarn/cache/http-proxy-agent-npm-5.0.0-7f1f121b83-e2ee1ff165.zip deleted file mode 100644 index a999ab7d5a9..00000000000 Binary files a/.yarn/cache/http-proxy-agent-npm-5.0.0-7f1f121b83-e2ee1ff165.zip and /dev/null differ diff --git a/.yarn/cache/http-signature-npm-1.3.6-5b2eff4373-10be2af476.zip b/.yarn/cache/http-signature-npm-1.3.6-5b2eff4373-10be2af476.zip deleted file mode 100644 index 44966300c24..00000000000 Binary files a/.yarn/cache/http-signature-npm-1.3.6-5b2eff4373-10be2af476.zip and /dev/null differ diff --git a/.yarn/cache/https-proxy-agent-npm-5.0.1-42d65f358e-571fccdf38.zip b/.yarn/cache/https-proxy-agent-npm-5.0.1-42d65f358e-571fccdf38.zip deleted file mode 100644 index b8bc9949c64..00000000000 Binary files a/.yarn/cache/https-proxy-agent-npm-5.0.1-42d65f358e-571fccdf38.zip and /dev/null differ diff --git a/.yarn/cache/human-signals-npm-1.1.1-616b2586c2-d587647c9e.zip b/.yarn/cache/human-signals-npm-1.1.1-616b2586c2-d587647c9e.zip deleted file mode 100644 index 1dcc5877fe1..00000000000 Binary files a/.yarn/cache/human-signals-npm-1.1.1-616b2586c2-d587647c9e.zip and /dev/null differ diff --git a/.yarn/cache/humanize-ms-npm-1.2.1-e942bd7329-9c7a74a282.zip b/.yarn/cache/humanize-ms-npm-1.2.1-e942bd7329-9c7a74a282.zip deleted file mode 100644 index c09856b3348..00000000000 Binary files a/.yarn/cache/humanize-ms-npm-1.2.1-e942bd7329-9c7a74a282.zip and /dev/null differ diff --git a/.yarn/cache/iconv-lite-npm-0.6.3-24b8aae27e-3f60d47a5c.zip b/.yarn/cache/iconv-lite-npm-0.6.3-24b8aae27e-3f60d47a5c.zip deleted file mode 100644 index f3f767a22d7..00000000000 Binary files a/.yarn/cache/iconv-lite-npm-0.6.3-24b8aae27e-3f60d47a5c.zip and /dev/null differ diff --git a/.yarn/cache/ieee754-npm-1.2.1-fb63b3caeb-5144c0c981.zip b/.yarn/cache/ieee754-npm-1.2.1-fb63b3caeb-5144c0c981.zip deleted file mode 100644 index 74128ad8f26..00000000000 Binary files a/.yarn/cache/ieee754-npm-1.2.1-fb63b3caeb-5144c0c981.zip and /dev/null differ diff --git a/.yarn/cache/ignore-npm-5.2.0-fc4b58a4f3-6b1f926792.zip b/.yarn/cache/ignore-npm-5.2.0-fc4b58a4f3-6b1f926792.zip deleted file mode 100644 index 68895e2edcb..00000000000 Binary files a/.yarn/cache/ignore-npm-5.2.0-fc4b58a4f3-6b1f926792.zip and /dev/null differ diff --git a/.yarn/cache/immutable-npm-4.0.0-74b844f82e-4b5e9181e4.zip b/.yarn/cache/immutable-npm-4.0.0-74b844f82e-4b5e9181e4.zip deleted file mode 100644 index 9f957eadceb..00000000000 Binary files a/.yarn/cache/immutable-npm-4.0.0-74b844f82e-4b5e9181e4.zip and /dev/null differ diff --git a/.yarn/cache/import-fresh-npm-3.3.0-3e34265ca9-2cacfad06e.zip b/.yarn/cache/import-fresh-npm-3.3.0-3e34265ca9-2cacfad06e.zip deleted file mode 100644 index 318d7b8460d..00000000000 Binary files a/.yarn/cache/import-fresh-npm-3.3.0-3e34265ca9-2cacfad06e.zip and /dev/null differ diff --git a/.yarn/cache/imurmurhash-npm-0.1.4-610c5068a0-7cae75c8cd.zip b/.yarn/cache/imurmurhash-npm-0.1.4-610c5068a0-7cae75c8cd.zip deleted file mode 100644 index 9ddf4f880fb..00000000000 Binary files a/.yarn/cache/imurmurhash-npm-0.1.4-610c5068a0-7cae75c8cd.zip and /dev/null differ diff --git a/.yarn/cache/indent-string-npm-4.0.0-7b717435b2-824cfb9929.zip b/.yarn/cache/indent-string-npm-4.0.0-7b717435b2-824cfb9929.zip deleted file mode 100644 index eedfdb0f37a..00000000000 Binary files a/.yarn/cache/indent-string-npm-4.0.0-7b717435b2-824cfb9929.zip and /dev/null differ diff --git a/.yarn/cache/infer-owner-npm-1.0.4-685ac3d2af-181e732764.zip b/.yarn/cache/infer-owner-npm-1.0.4-685ac3d2af-181e732764.zip deleted file mode 100644 index bdc705082a7..00000000000 Binary files a/.yarn/cache/infer-owner-npm-1.0.4-685ac3d2af-181e732764.zip and /dev/null differ diff --git a/.yarn/cache/inflight-npm-1.0.6-ccedb4b908-f4f76aa072.zip b/.yarn/cache/inflight-npm-1.0.6-ccedb4b908-f4f76aa072.zip deleted file mode 100644 index c5a4bb07259..00000000000 Binary files a/.yarn/cache/inflight-npm-1.0.6-ccedb4b908-f4f76aa072.zip and /dev/null differ diff --git a/.yarn/cache/inherits-npm-2.0.4-c66b3957a0-4a48a73384.zip b/.yarn/cache/inherits-npm-2.0.4-c66b3957a0-4a48a73384.zip deleted file mode 100644 index 62c31cb78bb..00000000000 Binary files a/.yarn/cache/inherits-npm-2.0.4-c66b3957a0-4a48a73384.zip and /dev/null differ diff --git a/.yarn/cache/ini-npm-2.0.0-28f7426761-e7aadc5fb2.zip b/.yarn/cache/ini-npm-2.0.0-28f7426761-e7aadc5fb2.zip deleted file mode 100644 index 377051d248b..00000000000 Binary files a/.yarn/cache/ini-npm-2.0.0-28f7426761-e7aadc5fb2.zip and /dev/null differ diff --git a/.yarn/cache/internal-slot-npm-1.0.3-9e05eea002-1944f92e98.zip b/.yarn/cache/internal-slot-npm-1.0.3-9e05eea002-1944f92e98.zip deleted file mode 100644 index 18c6edaa912..00000000000 Binary files a/.yarn/cache/internal-slot-npm-1.0.3-9e05eea002-1944f92e98.zip and /dev/null differ diff --git a/.yarn/cache/internmap-npm-2.0.3-d74f5c9998-7ca41ec6ab.zip b/.yarn/cache/internmap-npm-2.0.3-d74f5c9998-7ca41ec6ab.zip deleted file mode 100644 index 0ee1ec327bc..00000000000 Binary files a/.yarn/cache/internmap-npm-2.0.3-d74f5c9998-7ca41ec6ab.zip and /dev/null differ diff --git a/.yarn/cache/ip-npm-1.1.8-abea558b72-a2ade53eb3.zip b/.yarn/cache/ip-npm-1.1.8-abea558b72-a2ade53eb3.zip deleted file mode 100644 index 6349789baa9..00000000000 Binary files a/.yarn/cache/ip-npm-1.1.8-abea558b72-a2ade53eb3.zip and /dev/null differ diff --git a/.yarn/cache/is-arrayish-npm-0.2.1-23927dfb15-eef4417e3c.zip b/.yarn/cache/is-arrayish-npm-0.2.1-23927dfb15-eef4417e3c.zip deleted file mode 100644 index 8d3275c2113..00000000000 Binary files a/.yarn/cache/is-arrayish-npm-0.2.1-23927dfb15-eef4417e3c.zip and /dev/null differ diff --git a/.yarn/cache/is-bigint-npm-1.0.4-31c2eecbc9-c56edfe09b.zip b/.yarn/cache/is-bigint-npm-1.0.4-31c2eecbc9-c56edfe09b.zip deleted file mode 100644 index 5282dfa9189..00000000000 Binary files a/.yarn/cache/is-bigint-npm-1.0.4-31c2eecbc9-c56edfe09b.zip and /dev/null differ diff --git a/.yarn/cache/is-binary-path-npm-2.1.0-e61d46f557-84192eb88c.zip b/.yarn/cache/is-binary-path-npm-2.1.0-e61d46f557-84192eb88c.zip deleted file mode 100644 index b509d00f589..00000000000 Binary files a/.yarn/cache/is-binary-path-npm-2.1.0-e61d46f557-84192eb88c.zip and /dev/null differ diff --git a/.yarn/cache/is-boolean-object-npm-1.1.2-ecbd575e6a-c03b23dbaa.zip b/.yarn/cache/is-boolean-object-npm-1.1.2-ecbd575e6a-c03b23dbaa.zip deleted file mode 100644 index 7a1ae53d09d..00000000000 Binary files a/.yarn/cache/is-boolean-object-npm-1.1.2-ecbd575e6a-c03b23dbaa.zip and /dev/null differ diff --git a/.yarn/cache/is-callable-npm-1.2.4-03fc17459c-1a28d57dc4.zip b/.yarn/cache/is-callable-npm-1.2.4-03fc17459c-1a28d57dc4.zip deleted file mode 100644 index a5b40696917..00000000000 Binary files a/.yarn/cache/is-callable-npm-1.2.4-03fc17459c-1a28d57dc4.zip and /dev/null differ diff --git a/.yarn/cache/is-ci-npm-3.0.1-d9aea361e1-192c66dc78.zip b/.yarn/cache/is-ci-npm-3.0.1-d9aea361e1-192c66dc78.zip deleted file mode 100644 index 6e9e3af3642..00000000000 Binary files a/.yarn/cache/is-ci-npm-3.0.1-d9aea361e1-192c66dc78.zip and /dev/null differ diff --git a/.yarn/cache/is-core-module-npm-2.9.0-5ba77c35ae-b27034318b.zip b/.yarn/cache/is-core-module-npm-2.9.0-5ba77c35ae-b27034318b.zip deleted file mode 100644 index b7f03ef99ad..00000000000 Binary files a/.yarn/cache/is-core-module-npm-2.9.0-5ba77c35ae-b27034318b.zip and /dev/null differ diff --git a/.yarn/cache/is-date-object-npm-1.0.5-88f3d08b5e-baa9077cdf.zip b/.yarn/cache/is-date-object-npm-1.0.5-88f3d08b5e-baa9077cdf.zip deleted file mode 100644 index 3dbce36af99..00000000000 Binary files a/.yarn/cache/is-date-object-npm-1.0.5-88f3d08b5e-baa9077cdf.zip and /dev/null differ diff --git a/.yarn/cache/is-expression-npm-4.0.0-44cc07c8aa-0f01d0ff53.zip b/.yarn/cache/is-expression-npm-4.0.0-44cc07c8aa-0f01d0ff53.zip deleted file mode 100644 index 6fa6af94f5a..00000000000 Binary files a/.yarn/cache/is-expression-npm-4.0.0-44cc07c8aa-0f01d0ff53.zip and /dev/null differ diff --git a/.yarn/cache/is-extglob-npm-2.1.1-0870ea68b5-df033653d0.zip b/.yarn/cache/is-extglob-npm-2.1.1-0870ea68b5-df033653d0.zip deleted file mode 100644 index 0acbc56e225..00000000000 Binary files a/.yarn/cache/is-extglob-npm-2.1.1-0870ea68b5-df033653d0.zip and /dev/null differ diff --git a/.yarn/cache/is-fullwidth-code-point-npm-3.0.0-1ecf4ebee5-44a30c2945.zip b/.yarn/cache/is-fullwidth-code-point-npm-3.0.0-1ecf4ebee5-44a30c2945.zip deleted file mode 100644 index dccc80a970b..00000000000 Binary files a/.yarn/cache/is-fullwidth-code-point-npm-3.0.0-1ecf4ebee5-44a30c2945.zip and /dev/null differ diff --git a/.yarn/cache/is-glob-npm-4.0.3-cb87bf1bdb-d381c1319f.zip b/.yarn/cache/is-glob-npm-4.0.3-cb87bf1bdb-d381c1319f.zip deleted file mode 100644 index 52274ed2541..00000000000 Binary files a/.yarn/cache/is-glob-npm-4.0.3-cb87bf1bdb-d381c1319f.zip and /dev/null differ diff --git a/.yarn/cache/is-installed-globally-npm-0.4.0-a30dd056c7-3359840d59.zip b/.yarn/cache/is-installed-globally-npm-0.4.0-a30dd056c7-3359840d59.zip deleted file mode 100644 index f94dbc064b9..00000000000 Binary files a/.yarn/cache/is-installed-globally-npm-0.4.0-a30dd056c7-3359840d59.zip and /dev/null differ diff --git a/.yarn/cache/is-json-npm-2.0.1-a385cacc72-29efc4f82e.zip b/.yarn/cache/is-json-npm-2.0.1-a385cacc72-29efc4f82e.zip deleted file mode 100644 index 98db5f85d1a..00000000000 Binary files a/.yarn/cache/is-json-npm-2.0.1-a385cacc72-29efc4f82e.zip and /dev/null differ diff --git a/.yarn/cache/is-lambda-npm-1.0.1-7ab55bc8a8-93a32f0194.zip b/.yarn/cache/is-lambda-npm-1.0.1-7ab55bc8a8-93a32f0194.zip deleted file mode 100644 index f981b1bea6c..00000000000 Binary files a/.yarn/cache/is-lambda-npm-1.0.1-7ab55bc8a8-93a32f0194.zip and /dev/null differ diff --git a/.yarn/cache/is-negative-zero-npm-2.0.2-0adac91f15-f3232194c4.zip b/.yarn/cache/is-negative-zero-npm-2.0.2-0adac91f15-f3232194c4.zip deleted file mode 100644 index 06b47fde5a0..00000000000 Binary files a/.yarn/cache/is-negative-zero-npm-2.0.2-0adac91f15-f3232194c4.zip and /dev/null differ diff --git a/.yarn/cache/is-number-npm-7.0.0-060086935c-456ac6f8e0.zip b/.yarn/cache/is-number-npm-7.0.0-060086935c-456ac6f8e0.zip deleted file mode 100644 index e4ae0485760..00000000000 Binary files a/.yarn/cache/is-number-npm-7.0.0-060086935c-456ac6f8e0.zip and /dev/null differ diff --git a/.yarn/cache/is-number-object-npm-1.0.7-539d0e274d-d1e8d01bb0.zip b/.yarn/cache/is-number-object-npm-1.0.7-539d0e274d-d1e8d01bb0.zip deleted file mode 100644 index fac0d675add..00000000000 Binary files a/.yarn/cache/is-number-object-npm-1.0.7-539d0e274d-d1e8d01bb0.zip and /dev/null differ diff --git a/.yarn/cache/is-path-inside-npm-3.0.3-2ea0ef44fd-abd50f0618.zip b/.yarn/cache/is-path-inside-npm-3.0.3-2ea0ef44fd-abd50f0618.zip deleted file mode 100644 index 27f29d70bee..00000000000 Binary files a/.yarn/cache/is-path-inside-npm-3.0.3-2ea0ef44fd-abd50f0618.zip and /dev/null differ diff --git a/.yarn/cache/is-promise-npm-2.2.2-afbf94db67-18bf7d1c59.zip b/.yarn/cache/is-promise-npm-2.2.2-afbf94db67-18bf7d1c59.zip deleted file mode 100644 index c47eb5f909a..00000000000 Binary files a/.yarn/cache/is-promise-npm-2.2.2-afbf94db67-18bf7d1c59.zip and /dev/null differ diff --git a/.yarn/cache/is-regex-npm-1.1.4-cca193ef11-362399b335.zip b/.yarn/cache/is-regex-npm-1.1.4-cca193ef11-362399b335.zip deleted file mode 100644 index 41d26b8c736..00000000000 Binary files a/.yarn/cache/is-regex-npm-1.1.4-cca193ef11-362399b335.zip and /dev/null differ diff --git a/.yarn/cache/is-shared-array-buffer-npm-1.0.2-32e4181fcd-9508929cf1.zip b/.yarn/cache/is-shared-array-buffer-npm-1.0.2-32e4181fcd-9508929cf1.zip deleted file mode 100644 index af3ad4f0000..00000000000 Binary files a/.yarn/cache/is-shared-array-buffer-npm-1.0.2-32e4181fcd-9508929cf1.zip and /dev/null differ diff --git a/.yarn/cache/is-stream-npm-2.0.1-c802db55e7-b8e05ccdf9.zip b/.yarn/cache/is-stream-npm-2.0.1-c802db55e7-b8e05ccdf9.zip deleted file mode 100644 index c5699a4eeb7..00000000000 Binary files a/.yarn/cache/is-stream-npm-2.0.1-c802db55e7-b8e05ccdf9.zip and /dev/null differ diff --git a/.yarn/cache/is-string-npm-1.0.7-9f7066daed-323b3d0462.zip b/.yarn/cache/is-string-npm-1.0.7-9f7066daed-323b3d0462.zip deleted file mode 100644 index 21039f90178..00000000000 Binary files a/.yarn/cache/is-string-npm-1.0.7-9f7066daed-323b3d0462.zip and /dev/null differ diff --git a/.yarn/cache/is-symbol-npm-1.0.4-eb9baac703-92805812ef.zip b/.yarn/cache/is-symbol-npm-1.0.4-eb9baac703-92805812ef.zip deleted file mode 100644 index aa6f763ead9..00000000000 Binary files a/.yarn/cache/is-symbol-npm-1.0.4-eb9baac703-92805812ef.zip and /dev/null differ diff --git a/.yarn/cache/is-typedarray-npm-1.0.0-bbd99de5b6-3508c6cd0a.zip b/.yarn/cache/is-typedarray-npm-1.0.0-bbd99de5b6-3508c6cd0a.zip deleted file mode 100644 index 09d0014a470..00000000000 Binary files a/.yarn/cache/is-typedarray-npm-1.0.0-bbd99de5b6-3508c6cd0a.zip and /dev/null differ diff --git a/.yarn/cache/is-unicode-supported-npm-0.1.0-0833e1bbfb-a2aab86ee7.zip b/.yarn/cache/is-unicode-supported-npm-0.1.0-0833e1bbfb-a2aab86ee7.zip deleted file mode 100644 index 7425daa3669..00000000000 Binary files a/.yarn/cache/is-unicode-supported-npm-0.1.0-0833e1bbfb-a2aab86ee7.zip and /dev/null differ diff --git a/.yarn/cache/is-weakref-npm-1.0.2-ff80e8c314-95bd9a57cd.zip b/.yarn/cache/is-weakref-npm-1.0.2-ff80e8c314-95bd9a57cd.zip deleted file mode 100644 index a798b0183b2..00000000000 Binary files a/.yarn/cache/is-weakref-npm-1.0.2-ff80e8c314-95bd9a57cd.zip and /dev/null differ diff --git a/.yarn/cache/isexe-npm-2.0.0-b58870bd2e-26bf6c5480.zip b/.yarn/cache/isexe-npm-2.0.0-b58870bd2e-26bf6c5480.zip deleted file mode 100644 index 077597d686e..00000000000 Binary files a/.yarn/cache/isexe-npm-2.0.0-b58870bd2e-26bf6c5480.zip and /dev/null differ diff --git a/.yarn/cache/isstream-npm-0.1.2-8581c75385-1eb2fe63a7.zip b/.yarn/cache/isstream-npm-0.1.2-8581c75385-1eb2fe63a7.zip deleted file mode 100644 index 7c1a1e17180..00000000000 Binary files a/.yarn/cache/isstream-npm-0.1.2-8581c75385-1eb2fe63a7.zip and /dev/null differ diff --git a/.yarn/cache/istanbul-lib-coverage-npm-3.2.0-93f84b2c8c-a2a545033b.zip b/.yarn/cache/istanbul-lib-coverage-npm-3.2.0-93f84b2c8c-a2a545033b.zip deleted file mode 100644 index 89e143d50e2..00000000000 Binary files a/.yarn/cache/istanbul-lib-coverage-npm-3.2.0-93f84b2c8c-a2a545033b.zip and /dev/null differ diff --git a/.yarn/cache/istanbul-lib-report-npm-3.0.0-660f97340a-3f29eb3f53.zip b/.yarn/cache/istanbul-lib-report-npm-3.0.0-660f97340a-3f29eb3f53.zip deleted file mode 100644 index 90bcd0adf54..00000000000 Binary files a/.yarn/cache/istanbul-lib-report-npm-3.0.0-660f97340a-3f29eb3f53.zip and /dev/null differ diff --git a/.yarn/cache/istanbul-reports-npm-3.1.4-5faaa9636c-2132983355.zip b/.yarn/cache/istanbul-reports-npm-3.1.4-5faaa9636c-2132983355.zip deleted file mode 100644 index c9a9a9c9496..00000000000 Binary files a/.yarn/cache/istanbul-reports-npm-3.1.4-5faaa9636c-2132983355.zip and /dev/null differ diff --git a/.yarn/cache/jest-diff-npm-27.5.1-818e549196-8be27c1e1e.zip b/.yarn/cache/jest-diff-npm-27.5.1-818e549196-8be27c1e1e.zip deleted file mode 100644 index de55e34a9cf..00000000000 Binary files a/.yarn/cache/jest-diff-npm-27.5.1-818e549196-8be27c1e1e.zip and /dev/null differ diff --git a/.yarn/cache/jest-get-type-npm-27.5.1-980fbf7a43-63064ab701.zip b/.yarn/cache/jest-get-type-npm-27.5.1-980fbf7a43-63064ab701.zip deleted file mode 100644 index 50167f4d8d1..00000000000 Binary files a/.yarn/cache/jest-get-type-npm-27.5.1-980fbf7a43-63064ab701.zip and /dev/null differ diff --git a/.yarn/cache/jest-matcher-utils-npm-27.5.1-0c47b071fb-bb2135fc48.zip b/.yarn/cache/jest-matcher-utils-npm-27.5.1-0c47b071fb-bb2135fc48.zip deleted file mode 100644 index f4bc56be0ff..00000000000 Binary files a/.yarn/cache/jest-matcher-utils-npm-27.5.1-0c47b071fb-bb2135fc48.zip and /dev/null differ diff --git a/.yarn/cache/jquery-migrate-npm-3.4.0-88c209e61f-7431685c56.zip b/.yarn/cache/jquery-migrate-npm-3.4.0-88c209e61f-7431685c56.zip deleted file mode 100644 index 04eb1cbaab8..00000000000 Binary files a/.yarn/cache/jquery-migrate-npm-3.4.0-88c209e61f-7431685c56.zip and /dev/null differ diff --git a/.yarn/cache/jquery-npm-3.6.0-ca7872bdbb-8fd5fef4aa.zip b/.yarn/cache/jquery-npm-3.6.0-ca7872bdbb-8fd5fef4aa.zip deleted file mode 100644 index 2c23cc857b5..00000000000 Binary files a/.yarn/cache/jquery-npm-3.6.0-ca7872bdbb-8fd5fef4aa.zip and /dev/null differ diff --git a/.yarn/cache/jquery-ui-dist-npm-1.13.1-fe4cdb19d6-9a19f520b8.zip b/.yarn/cache/jquery-ui-dist-npm-1.13.1-fe4cdb19d6-9a19f520b8.zip deleted file mode 100644 index b424df27014..00000000000 Binary files a/.yarn/cache/jquery-ui-dist-npm-1.13.1-fe4cdb19d6-9a19f520b8.zip and /dev/null differ diff --git a/.yarn/cache/js-cookie-npm-3.0.1-04c7177de1-bb48de67e2.zip b/.yarn/cache/js-cookie-npm-3.0.1-04c7177de1-bb48de67e2.zip deleted file mode 100644 index 3c0bf5db17d..00000000000 Binary files a/.yarn/cache/js-cookie-npm-3.0.1-04c7177de1-bb48de67e2.zip and /dev/null differ diff --git a/.yarn/cache/js-stringify-npm-1.0.2-898ffeac57-f9701d9e53.zip b/.yarn/cache/js-stringify-npm-1.0.2-898ffeac57-f9701d9e53.zip deleted file mode 100644 index 0baf0a7b23a..00000000000 Binary files a/.yarn/cache/js-stringify-npm-1.0.2-898ffeac57-f9701d9e53.zip and /dev/null differ diff --git a/.yarn/cache/js-tokens-npm-4.0.0-0ac852e9e2-8a95213a5a.zip b/.yarn/cache/js-tokens-npm-4.0.0-0ac852e9e2-8a95213a5a.zip deleted file mode 100644 index 8ffd9d48a5c..00000000000 Binary files a/.yarn/cache/js-tokens-npm-4.0.0-0ac852e9e2-8a95213a5a.zip and /dev/null differ diff --git a/.yarn/cache/js-yaml-npm-4.1.0-3606f32312-c7830dfd45.zip b/.yarn/cache/js-yaml-npm-4.1.0-3606f32312-c7830dfd45.zip deleted file mode 100644 index 659c85d097f..00000000000 Binary files a/.yarn/cache/js-yaml-npm-4.1.0-3606f32312-c7830dfd45.zip and /dev/null differ diff --git a/.yarn/cache/jsbn-npm-0.1.1-0eb7132404-e5ff29c1b8.zip b/.yarn/cache/jsbn-npm-0.1.1-0eb7132404-e5ff29c1b8.zip deleted file mode 100644 index 8ec54a26c59..00000000000 Binary files a/.yarn/cache/jsbn-npm-0.1.1-0eb7132404-e5ff29c1b8.zip and /dev/null differ diff --git a/.yarn/cache/json-parse-even-better-errors-npm-2.3.1-144d62256e-798ed4cf33.zip b/.yarn/cache/json-parse-even-better-errors-npm-2.3.1-144d62256e-798ed4cf33.zip deleted file mode 100644 index 96a83fe3c51..00000000000 Binary files a/.yarn/cache/json-parse-even-better-errors-npm-2.3.1-144d62256e-798ed4cf33.zip and /dev/null differ diff --git a/.yarn/cache/json-schema-npm-0.4.0-e776313070-66389434c3.zip b/.yarn/cache/json-schema-npm-0.4.0-e776313070-66389434c3.zip deleted file mode 100644 index 1946e3075a8..00000000000 Binary files a/.yarn/cache/json-schema-npm-0.4.0-e776313070-66389434c3.zip and /dev/null differ diff --git a/.yarn/cache/json-schema-traverse-npm-0.4.1-4759091693-7486074d3b.zip b/.yarn/cache/json-schema-traverse-npm-0.4.1-4759091693-7486074d3b.zip deleted file mode 100644 index 54f0a7acb67..00000000000 Binary files a/.yarn/cache/json-schema-traverse-npm-0.4.1-4759091693-7486074d3b.zip and /dev/null differ diff --git a/.yarn/cache/json-schema-traverse-npm-1.0.0-fb3684f4f0-02f2f466cd.zip b/.yarn/cache/json-schema-traverse-npm-1.0.0-fb3684f4f0-02f2f466cd.zip deleted file mode 100644 index bfd6fdcd8ae..00000000000 Binary files a/.yarn/cache/json-schema-traverse-npm-1.0.0-fb3684f4f0-02f2f466cd.zip and /dev/null differ diff --git a/.yarn/cache/json-stable-stringify-without-jsonify-npm-1.0.1-b65772b28b-cff44156dd.zip b/.yarn/cache/json-stable-stringify-without-jsonify-npm-1.0.1-b65772b28b-cff44156dd.zip deleted file mode 100644 index 47d58522043..00000000000 Binary files a/.yarn/cache/json-stable-stringify-without-jsonify-npm-1.0.1-b65772b28b-cff44156dd.zip and /dev/null differ diff --git a/.yarn/cache/json-stringify-safe-npm-5.0.1-064ddd6ab4-48ec0adad5.zip b/.yarn/cache/json-stringify-safe-npm-5.0.1-064ddd6ab4-48ec0adad5.zip deleted file mode 100644 index bda01edf7c4..00000000000 Binary files a/.yarn/cache/json-stringify-safe-npm-5.0.1-064ddd6ab4-48ec0adad5.zip and /dev/null differ diff --git a/.yarn/cache/json5-npm-1.0.1-647fc8794b-e76ea23dbb.zip b/.yarn/cache/json5-npm-1.0.1-647fc8794b-e76ea23dbb.zip deleted file mode 100644 index cc70df52204..00000000000 Binary files a/.yarn/cache/json5-npm-1.0.1-647fc8794b-e76ea23dbb.zip and /dev/null differ diff --git a/.yarn/cache/json5-npm-2.2.1-44675c859c-74b8a23b10.zip b/.yarn/cache/json5-npm-2.2.1-44675c859c-74b8a23b10.zip deleted file mode 100644 index 99c2b0de704..00000000000 Binary files a/.yarn/cache/json5-npm-2.2.1-44675c859c-74b8a23b10.zip and /dev/null differ diff --git a/.yarn/cache/jsonfile-npm-6.1.0-20a4796cee-7af3b8e1ac.zip b/.yarn/cache/jsonfile-npm-6.1.0-20a4796cee-7af3b8e1ac.zip deleted file mode 100644 index eaf6e09e673..00000000000 Binary files a/.yarn/cache/jsonfile-npm-6.1.0-20a4796cee-7af3b8e1ac.zip and /dev/null differ diff --git a/.yarn/cache/jsprim-npm-2.0.2-8c40f3719c-d175f6b199.zip b/.yarn/cache/jsprim-npm-2.0.2-8c40f3719c-d175f6b199.zip deleted file mode 100644 index 6a0140011ff..00000000000 Binary files a/.yarn/cache/jsprim-npm-2.0.2-8c40f3719c-d175f6b199.zip and /dev/null differ diff --git a/.yarn/cache/jstransformer-npm-1.0.0-41a47d180a-1e019fde17.zip b/.yarn/cache/jstransformer-npm-1.0.0-41a47d180a-1e019fde17.zip deleted file mode 100644 index 9a7a6b2bbc1..00000000000 Binary files a/.yarn/cache/jstransformer-npm-1.0.0-41a47d180a-1e019fde17.zip and /dev/null differ diff --git a/.yarn/cache/kleur-npm-3.0.3-f6f53649a4-df82cd1e17.zip b/.yarn/cache/kleur-npm-3.0.3-f6f53649a4-df82cd1e17.zip deleted file mode 100644 index 7d710afab95..00000000000 Binary files a/.yarn/cache/kleur-npm-3.0.3-f6f53649a4-df82cd1e17.zip and /dev/null differ diff --git a/.yarn/cache/kleur-npm-4.1.4-7a73ff57c6-7f6db36e37.zip b/.yarn/cache/kleur-npm-4.1.4-7a73ff57c6-7f6db36e37.zip deleted file mode 100644 index 18f47b1ab57..00000000000 Binary files a/.yarn/cache/kleur-npm-4.1.4-7a73ff57c6-7f6db36e37.zip and /dev/null differ diff --git a/.yarn/cache/lazy-ass-npm-1.6.0-5cda93b8cb-5a3ebb1791.zip b/.yarn/cache/lazy-ass-npm-1.6.0-5cda93b8cb-5a3ebb1791.zip deleted file mode 100644 index 8c28def5d30..00000000000 Binary files a/.yarn/cache/lazy-ass-npm-1.6.0-5cda93b8cb-5a3ebb1791.zip and /dev/null differ diff --git a/.yarn/cache/levn-npm-0.4.1-d183b2d7bb-12c5021c85.zip b/.yarn/cache/levn-npm-0.4.1-d183b2d7bb-12c5021c85.zip deleted file mode 100644 index dda4d01a391..00000000000 Binary files a/.yarn/cache/levn-npm-0.4.1-d183b2d7bb-12c5021c85.zip and /dev/null differ diff --git a/.yarn/cache/lines-and-columns-npm-1.2.4-d6c7cc5799-0c37f9f7fa.zip b/.yarn/cache/lines-and-columns-npm-1.2.4-d6c7cc5799-0c37f9f7fa.zip deleted file mode 100644 index 273106a73c2..00000000000 Binary files a/.yarn/cache/lines-and-columns-npm-1.2.4-d6c7cc5799-0c37f9f7fa.zip and /dev/null differ diff --git a/.yarn/cache/list.js-npm-2.3.1-31415fcbbd-3bb4e9035b.zip b/.yarn/cache/list.js-npm-2.3.1-31415fcbbd-3bb4e9035b.zip deleted file mode 100644 index 27656b3f876..00000000000 Binary files a/.yarn/cache/list.js-npm-2.3.1-31415fcbbd-3bb4e9035b.zip and /dev/null differ diff --git a/.yarn/cache/listr2-npm-3.14.0-446f504112-fdb8b2d6bd.zip b/.yarn/cache/listr2-npm-3.14.0-446f504112-fdb8b2d6bd.zip deleted file mode 100644 index b78302771ad..00000000000 Binary files a/.yarn/cache/listr2-npm-3.14.0-446f504112-fdb8b2d6bd.zip and /dev/null differ diff --git a/.yarn/cache/lmdb-npm-2.5.2-76ec56235a-3362dc2b03.zip b/.yarn/cache/lmdb-npm-2.5.2-76ec56235a-3362dc2b03.zip deleted file mode 100644 index e7056cac355..00000000000 Binary files a/.yarn/cache/lmdb-npm-2.5.2-76ec56235a-3362dc2b03.zip and /dev/null differ diff --git a/.yarn/cache/local-pkg-npm-0.4.2-534016519b-22be451353.zip b/.yarn/cache/local-pkg-npm-0.4.2-534016519b-22be451353.zip deleted file mode 100644 index 2c18a7927bd..00000000000 Binary files a/.yarn/cache/local-pkg-npm-0.4.2-534016519b-22be451353.zip and /dev/null differ diff --git a/.yarn/cache/locate-path-npm-2.0.0-673d28b0ea-02d581edbb.zip b/.yarn/cache/locate-path-npm-2.0.0-673d28b0ea-02d581edbb.zip deleted file mode 100644 index 0841fd1c173..00000000000 Binary files a/.yarn/cache/locate-path-npm-2.0.0-673d28b0ea-02d581edbb.zip and /dev/null differ diff --git a/.yarn/cache/locate-path-npm-6.0.0-06a1e4c528-72eb661788.zip b/.yarn/cache/locate-path-npm-6.0.0-06a1e4c528-72eb661788.zip deleted file mode 100644 index b67b77440bb..00000000000 Binary files a/.yarn/cache/locate-path-npm-6.0.0-06a1e4c528-72eb661788.zip and /dev/null differ diff --git a/.yarn/cache/lodash-es-npm-4.17.21-b45832dfce-05cbffad6e.zip b/.yarn/cache/lodash-es-npm-4.17.21-b45832dfce-05cbffad6e.zip deleted file mode 100644 index c95a052eebb..00000000000 Binary files a/.yarn/cache/lodash-es-npm-4.17.21-b45832dfce-05cbffad6e.zip and /dev/null differ diff --git a/.yarn/cache/lodash-npm-4.17.21-6382451519-eb835a2e51.zip b/.yarn/cache/lodash-npm-4.17.21-6382451519-eb835a2e51.zip deleted file mode 100644 index 22ac44c4efb..00000000000 Binary files a/.yarn/cache/lodash-npm-4.17.21-6382451519-eb835a2e51.zip and /dev/null differ diff --git a/.yarn/cache/lodash.merge-npm-4.6.2-77cb4416bf-ad580b4bdb.zip b/.yarn/cache/lodash.merge-npm-4.6.2-77cb4416bf-ad580b4bdb.zip deleted file mode 100644 index f6bc72b461e..00000000000 Binary files a/.yarn/cache/lodash.merge-npm-4.6.2-77cb4416bf-ad580b4bdb.zip and /dev/null differ diff --git a/.yarn/cache/lodash.once-npm-4.1.1-d8ba329ead-d768fa9f9b.zip b/.yarn/cache/lodash.once-npm-4.1.1-d8ba329ead-d768fa9f9b.zip deleted file mode 100644 index 8d6432ca314..00000000000 Binary files a/.yarn/cache/lodash.once-npm-4.1.1-d8ba329ead-d768fa9f9b.zip and /dev/null differ diff --git a/.yarn/cache/lodash.sortby-npm-4.7.0-fda8ab950d-db170c9396.zip b/.yarn/cache/lodash.sortby-npm-4.7.0-fda8ab950d-db170c9396.zip deleted file mode 100644 index 915d1f2fcc2..00000000000 Binary files a/.yarn/cache/lodash.sortby-npm-4.7.0-fda8ab950d-db170c9396.zip and /dev/null differ diff --git a/.yarn/cache/log-symbols-npm-4.1.0-0a13492d8b-fce1497b31.zip b/.yarn/cache/log-symbols-npm-4.1.0-0a13492d8b-fce1497b31.zip deleted file mode 100644 index 6a7e0761597..00000000000 Binary files a/.yarn/cache/log-symbols-npm-4.1.0-0a13492d8b-fce1497b31.zip and /dev/null differ diff --git a/.yarn/cache/log-update-npm-4.0.0-9d0554261c-ae2f85bbab.zip b/.yarn/cache/log-update-npm-4.0.0-9d0554261c-ae2f85bbab.zip deleted file mode 100644 index 66a2c50de73..00000000000 Binary files a/.yarn/cache/log-update-npm-4.0.0-9d0554261c-ae2f85bbab.zip and /dev/null differ diff --git a/.yarn/cache/loupe-npm-2.3.4-2067703c8d-5af91db61a.zip b/.yarn/cache/loupe-npm-2.3.4-2067703c8d-5af91db61a.zip deleted file mode 100644 index e778f0b6e0a..00000000000 Binary files a/.yarn/cache/loupe-npm-2.3.4-2067703c8d-5af91db61a.zip and /dev/null differ diff --git a/.yarn/cache/lru-cache-npm-6.0.0-b4c8668fe1-f97f499f89.zip b/.yarn/cache/lru-cache-npm-6.0.0-b4c8668fe1-f97f499f89.zip deleted file mode 100644 index 1635dac9b28..00000000000 Binary files a/.yarn/cache/lru-cache-npm-6.0.0-b4c8668fe1-f97f499f89.zip and /dev/null differ diff --git a/.yarn/cache/lru-cache-npm-7.10.1-5af910d0ed-e8b190d71e.zip b/.yarn/cache/lru-cache-npm-7.10.1-5af910d0ed-e8b190d71e.zip deleted file mode 100644 index 5a73fd5843c..00000000000 Binary files a/.yarn/cache/lru-cache-npm-7.10.1-5af910d0ed-e8b190d71e.zip and /dev/null differ diff --git a/.yarn/cache/luxon-npm-3.0.1-c6377bcf9a-aa966eb919.zip b/.yarn/cache/luxon-npm-3.0.1-c6377bcf9a-aa966eb919.zip deleted file mode 100644 index ad85d83e685..00000000000 Binary files a/.yarn/cache/luxon-npm-3.0.1-c6377bcf9a-aa966eb919.zip and /dev/null differ diff --git a/.yarn/cache/magic-string-npm-0.25.9-0b51c0ea50-9a0e55a15c.zip b/.yarn/cache/magic-string-npm-0.25.9-0b51c0ea50-9a0e55a15c.zip deleted file mode 100644 index caa6d6b49e8..00000000000 Binary files a/.yarn/cache/magic-string-npm-0.25.9-0b51c0ea50-9a0e55a15c.zip and /dev/null differ diff --git a/.yarn/cache/make-dir-npm-3.1.0-d1d7505142-484200020a.zip b/.yarn/cache/make-dir-npm-3.1.0-d1d7505142-484200020a.zip deleted file mode 100644 index e466cd8a165..00000000000 Binary files a/.yarn/cache/make-dir-npm-3.1.0-d1d7505142-484200020a.zip and /dev/null differ diff --git a/.yarn/cache/make-fetch-happen-npm-10.1.5-d805393723-b0b42a1ccd.zip b/.yarn/cache/make-fetch-happen-npm-10.1.5-d805393723-b0b42a1ccd.zip deleted file mode 100644 index 246675902ce..00000000000 Binary files a/.yarn/cache/make-fetch-happen-npm-10.1.5-d805393723-b0b42a1ccd.zip and /dev/null differ diff --git a/.yarn/cache/mdn-data-npm-2.0.14-0acd669f0d-9d0128ed42.zip b/.yarn/cache/mdn-data-npm-2.0.14-0acd669f0d-9d0128ed42.zip deleted file mode 100644 index bbdfbb8fd10..00000000000 Binary files a/.yarn/cache/mdn-data-npm-2.0.14-0acd669f0d-9d0128ed42.zip and /dev/null differ diff --git a/.yarn/cache/merge-stream-npm-2.0.0-2ac83efea5-6fa4dcc8d8.zip b/.yarn/cache/merge-stream-npm-2.0.0-2ac83efea5-6fa4dcc8d8.zip deleted file mode 100644 index 1cf9d57dce0..00000000000 Binary files a/.yarn/cache/merge-stream-npm-2.0.0-2ac83efea5-6fa4dcc8d8.zip and /dev/null differ diff --git a/.yarn/cache/mime-db-npm-1.52.0-b5371d6fd2-0d99a03585.zip b/.yarn/cache/mime-db-npm-1.52.0-b5371d6fd2-0d99a03585.zip deleted file mode 100644 index 8db72635742..00000000000 Binary files a/.yarn/cache/mime-db-npm-1.52.0-b5371d6fd2-0d99a03585.zip and /dev/null differ diff --git a/.yarn/cache/mime-types-npm-2.1.35-dd9ea9f3e2-89a5b7f1de.zip b/.yarn/cache/mime-types-npm-2.1.35-dd9ea9f3e2-89a5b7f1de.zip deleted file mode 100644 index 166d33254d3..00000000000 Binary files a/.yarn/cache/mime-types-npm-2.1.35-dd9ea9f3e2-89a5b7f1de.zip and /dev/null differ diff --git a/.yarn/cache/mimic-fn-npm-2.1.0-4fbeb3abb4-d2421a3444.zip b/.yarn/cache/mimic-fn-npm-2.1.0-4fbeb3abb4-d2421a3444.zip deleted file mode 100644 index 1cc2414f46c..00000000000 Binary files a/.yarn/cache/mimic-fn-npm-2.1.0-4fbeb3abb4-d2421a3444.zip and /dev/null differ diff --git a/.yarn/cache/minimatch-npm-3.1.2-9405269906-c154e56640.zip b/.yarn/cache/minimatch-npm-3.1.2-9405269906-c154e56640.zip deleted file mode 100644 index ba0c510402f..00000000000 Binary files a/.yarn/cache/minimatch-npm-3.1.2-9405269906-c154e56640.zip and /dev/null differ diff --git a/.yarn/cache/minimatch-npm-5.1.0-34f6240621-15ce53d31a.zip b/.yarn/cache/minimatch-npm-5.1.0-34f6240621-15ce53d31a.zip deleted file mode 100644 index 2a360f54205..00000000000 Binary files a/.yarn/cache/minimatch-npm-5.1.0-34f6240621-15ce53d31a.zip and /dev/null differ diff --git a/.yarn/cache/minimist-npm-1.2.6-f4cee4b4af-d15428cd1e.zip b/.yarn/cache/minimist-npm-1.2.6-f4cee4b4af-d15428cd1e.zip deleted file mode 100644 index e7466c584ee..00000000000 Binary files a/.yarn/cache/minimist-npm-1.2.6-f4cee4b4af-d15428cd1e.zip and /dev/null differ diff --git a/.yarn/cache/minipass-collect-npm-1.0.2-3b4676eab5-14df761028.zip b/.yarn/cache/minipass-collect-npm-1.0.2-3b4676eab5-14df761028.zip deleted file mode 100644 index 582f61ca2a8..00000000000 Binary files a/.yarn/cache/minipass-collect-npm-1.0.2-3b4676eab5-14df761028.zip and /dev/null differ diff --git a/.yarn/cache/minipass-fetch-npm-2.1.0-300ce55188-1334732859.zip b/.yarn/cache/minipass-fetch-npm-2.1.0-300ce55188-1334732859.zip deleted file mode 100644 index 389d884dc99..00000000000 Binary files a/.yarn/cache/minipass-fetch-npm-2.1.0-300ce55188-1334732859.zip and /dev/null differ diff --git a/.yarn/cache/minipass-flush-npm-1.0.5-efe79d9826-56269a0b22.zip b/.yarn/cache/minipass-flush-npm-1.0.5-efe79d9826-56269a0b22.zip deleted file mode 100644 index 913b687a4d7..00000000000 Binary files a/.yarn/cache/minipass-flush-npm-1.0.5-efe79d9826-56269a0b22.zip and /dev/null differ diff --git a/.yarn/cache/minipass-npm-3.1.6-f032df1661-57a0404141.zip b/.yarn/cache/minipass-npm-3.1.6-f032df1661-57a0404141.zip deleted file mode 100644 index 0f2d4ae31f9..00000000000 Binary files a/.yarn/cache/minipass-npm-3.1.6-f032df1661-57a0404141.zip and /dev/null differ diff --git a/.yarn/cache/minipass-pipeline-npm-1.2.4-5924cb077f-b14240dac0.zip b/.yarn/cache/minipass-pipeline-npm-1.2.4-5924cb077f-b14240dac0.zip deleted file mode 100644 index 4deae416db7..00000000000 Binary files a/.yarn/cache/minipass-pipeline-npm-1.2.4-5924cb077f-b14240dac0.zip and /dev/null differ diff --git a/.yarn/cache/minipass-sized-npm-1.0.3-306d86f432-79076749fc.zip b/.yarn/cache/minipass-sized-npm-1.0.3-306d86f432-79076749fc.zip deleted file mode 100644 index b6f4644f623..00000000000 Binary files a/.yarn/cache/minipass-sized-npm-1.0.3-306d86f432-79076749fc.zip and /dev/null differ diff --git a/.yarn/cache/minizlib-npm-2.1.2-ea89cd0cfb-f1fdeac0b0.zip b/.yarn/cache/minizlib-npm-2.1.2-ea89cd0cfb-f1fdeac0b0.zip deleted file mode 100644 index efb1b7f6b69..00000000000 Binary files a/.yarn/cache/minizlib-npm-2.1.2-ea89cd0cfb-f1fdeac0b0.zip and /dev/null differ diff --git a/.yarn/cache/mkdirp-npm-1.0.4-37f6ef56b9-a96865108c.zip b/.yarn/cache/mkdirp-npm-1.0.4-37f6ef56b9-a96865108c.zip deleted file mode 100644 index 4625e914a4a..00000000000 Binary files a/.yarn/cache/mkdirp-npm-1.0.4-37f6ef56b9-a96865108c.zip and /dev/null differ diff --git a/.yarn/cache/moment-npm-2.29.3-fe4ba99bae-2e780e36d9.zip b/.yarn/cache/moment-npm-2.29.3-fe4ba99bae-2e780e36d9.zip deleted file mode 100644 index 8db6d8b80b5..00000000000 Binary files a/.yarn/cache/moment-npm-2.29.3-fe4ba99bae-2e780e36d9.zip and /dev/null differ diff --git a/.yarn/cache/moment-npm-2.29.4-902943305d-0ec3f9c2bc.zip b/.yarn/cache/moment-npm-2.29.4-902943305d-0ec3f9c2bc.zip deleted file mode 100644 index 78acd14bed8..00000000000 Binary files a/.yarn/cache/moment-npm-2.29.4-902943305d-0ec3f9c2bc.zip and /dev/null differ diff --git a/.yarn/cache/moment-timezone-npm-0.5.34-e4fe2d01f6-12a1d3d52e.zip b/.yarn/cache/moment-timezone-npm-0.5.34-e4fe2d01f6-12a1d3d52e.zip deleted file mode 100644 index d6584641e4c..00000000000 Binary files a/.yarn/cache/moment-timezone-npm-0.5.34-e4fe2d01f6-12a1d3d52e.zip and /dev/null differ diff --git a/.yarn/cache/ms-npm-2.0.0-9e1101a471-0e6a22b8b7.zip b/.yarn/cache/ms-npm-2.0.0-9e1101a471-0e6a22b8b7.zip deleted file mode 100644 index 1cb6ffa5d58..00000000000 Binary files a/.yarn/cache/ms-npm-2.0.0-9e1101a471-0e6a22b8b7.zip and /dev/null differ diff --git a/.yarn/cache/ms-npm-2.1.2-ec0c1512ff-673cdb2c31.zip b/.yarn/cache/ms-npm-2.1.2-ec0c1512ff-673cdb2c31.zip deleted file mode 100644 index 725e9b8c176..00000000000 Binary files a/.yarn/cache/ms-npm-2.1.2-ec0c1512ff-673cdb2c31.zip and /dev/null differ diff --git a/.yarn/cache/ms-npm-2.1.3-81ff3cfac1-aa92de6080.zip b/.yarn/cache/ms-npm-2.1.3-81ff3cfac1-aa92de6080.zip deleted file mode 100644 index 2b635f28eba..00000000000 Binary files a/.yarn/cache/ms-npm-2.1.3-81ff3cfac1-aa92de6080.zip and /dev/null differ diff --git a/.yarn/cache/msgpackr-extract-npm-2.0.2-27402474ca-6b24c0e89e.zip b/.yarn/cache/msgpackr-extract-npm-2.0.2-27402474ca-6b24c0e89e.zip deleted file mode 100644 index c2c4c7fc8e9..00000000000 Binary files a/.yarn/cache/msgpackr-extract-npm-2.0.2-27402474ca-6b24c0e89e.zip and /dev/null differ diff --git a/.yarn/cache/msgpackr-npm-1.6.0-de9303a46e-7f94acbe93.zip b/.yarn/cache/msgpackr-npm-1.6.0-de9303a46e-7f94acbe93.zip deleted file mode 100644 index bdc06ee09ac..00000000000 Binary files a/.yarn/cache/msgpackr-npm-1.6.0-de9303a46e-7f94acbe93.zip and /dev/null differ diff --git a/.yarn/cache/murmurhash-js-npm-1.0.0-b1fa804bc0-083cea92a1.zip b/.yarn/cache/murmurhash-js-npm-1.0.0-b1fa804bc0-083cea92a1.zip deleted file mode 100644 index c4a3adfd319..00000000000 Binary files a/.yarn/cache/murmurhash-js-npm-1.0.0-b1fa804bc0-083cea92a1.zip and /dev/null differ diff --git a/.yarn/cache/naive-ui-npm-2.31.0-99dec18d2b-7194b4a814.zip b/.yarn/cache/naive-ui-npm-2.31.0-99dec18d2b-7194b4a814.zip deleted file mode 100644 index cf1c8b105c0..00000000000 Binary files a/.yarn/cache/naive-ui-npm-2.31.0-99dec18d2b-7194b4a814.zip and /dev/null differ diff --git a/.yarn/cache/nanoid-npm-3.3.3-25d865be84-ada019402a.zip b/.yarn/cache/nanoid-npm-3.3.3-25d865be84-ada019402a.zip deleted file mode 100644 index d28e91f1ff3..00000000000 Binary files a/.yarn/cache/nanoid-npm-3.3.3-25d865be84-ada019402a.zip and /dev/null differ diff --git a/.yarn/cache/nanoid-npm-3.3.4-3d250377d6-2fddd6dee9.zip b/.yarn/cache/nanoid-npm-3.3.4-3d250377d6-2fddd6dee9.zip deleted file mode 100644 index 740fd4c3362..00000000000 Binary files a/.yarn/cache/nanoid-npm-3.3.4-3d250377d6-2fddd6dee9.zip and /dev/null differ diff --git a/.yarn/cache/natural-compare-npm-1.4.0-97b75b362d-23ad088b08.zip b/.yarn/cache/natural-compare-npm-1.4.0-97b75b362d-23ad088b08.zip deleted file mode 100644 index db454c31c56..00000000000 Binary files a/.yarn/cache/natural-compare-npm-1.4.0-97b75b362d-23ad088b08.zip and /dev/null differ diff --git a/.yarn/cache/negotiator-npm-0.6.3-9d50e36171-b8ffeb1e26.zip b/.yarn/cache/negotiator-npm-0.6.3-9d50e36171-b8ffeb1e26.zip deleted file mode 100644 index e8c5cf48996..00000000000 Binary files a/.yarn/cache/negotiator-npm-0.6.3-9d50e36171-b8ffeb1e26.zip and /dev/null differ diff --git a/.yarn/cache/node-addon-api-npm-3.2.1-a29528f81d-2369986bb0.zip b/.yarn/cache/node-addon-api-npm-3.2.1-a29528f81d-2369986bb0.zip deleted file mode 100644 index 038beb4ad14..00000000000 Binary files a/.yarn/cache/node-addon-api-npm-3.2.1-a29528f81d-2369986bb0.zip and /dev/null differ diff --git a/.yarn/cache/node-addon-api-npm-4.3.0-a07a1232df-3de396e23c.zip b/.yarn/cache/node-addon-api-npm-4.3.0-a07a1232df-3de396e23c.zip deleted file mode 100644 index 36e334fcc29..00000000000 Binary files a/.yarn/cache/node-addon-api-npm-4.3.0-a07a1232df-3de396e23c.zip and /dev/null differ diff --git a/.yarn/cache/node-gyp-build-npm-4.4.0-d95e1857d1-972a059f96.zip b/.yarn/cache/node-gyp-build-npm-4.4.0-d95e1857d1-972a059f96.zip deleted file mode 100644 index 2f443472af8..00000000000 Binary files a/.yarn/cache/node-gyp-build-npm-4.4.0-d95e1857d1-972a059f96.zip and /dev/null differ diff --git a/.yarn/cache/node-gyp-build-optional-packages-npm-5.0.2-2917525a31-6fca33cd1e.zip b/.yarn/cache/node-gyp-build-optional-packages-npm-5.0.2-2917525a31-6fca33cd1e.zip deleted file mode 100644 index fe61c8f0035..00000000000 Binary files a/.yarn/cache/node-gyp-build-optional-packages-npm-5.0.2-2917525a31-6fca33cd1e.zip and /dev/null differ diff --git a/.yarn/cache/node-gyp-build-optional-packages-npm-5.0.3-50b9c76481-be3f023592.zip b/.yarn/cache/node-gyp-build-optional-packages-npm-5.0.3-50b9c76481-be3f023592.zip deleted file mode 100644 index b7d288db9b4..00000000000 Binary files a/.yarn/cache/node-gyp-build-optional-packages-npm-5.0.3-50b9c76481-be3f023592.zip and /dev/null differ diff --git a/.yarn/cache/node-gyp-npm-9.0.0-0eccfca4d1-4d8ef8860f.zip b/.yarn/cache/node-gyp-npm-9.0.0-0eccfca4d1-4d8ef8860f.zip deleted file mode 100644 index 417b1c24f2a..00000000000 Binary files a/.yarn/cache/node-gyp-npm-9.0.0-0eccfca4d1-4d8ef8860f.zip and /dev/null differ diff --git a/.yarn/cache/node-releases-npm-2.0.4-7d25d174cd-b32d6c2032.zip b/.yarn/cache/node-releases-npm-2.0.4-7d25d174cd-b32d6c2032.zip deleted file mode 100644 index fa5ea2b7097..00000000000 Binary files a/.yarn/cache/node-releases-npm-2.0.4-7d25d174cd-b32d6c2032.zip and /dev/null differ diff --git a/.yarn/cache/nopt-npm-5.0.0-304b40fbfe-d35fdec187.zip b/.yarn/cache/nopt-npm-5.0.0-304b40fbfe-d35fdec187.zip deleted file mode 100644 index 163bffbb60d..00000000000 Binary files a/.yarn/cache/nopt-npm-5.0.0-304b40fbfe-d35fdec187.zip and /dev/null differ diff --git a/.yarn/cache/normalize-path-npm-3.0.0-658ba7d77f-88eeb4da89.zip b/.yarn/cache/normalize-path-npm-3.0.0-658ba7d77f-88eeb4da89.zip deleted file mode 100644 index 855af70e63b..00000000000 Binary files a/.yarn/cache/normalize-path-npm-3.0.0-658ba7d77f-88eeb4da89.zip and /dev/null differ diff --git a/.yarn/cache/npm-run-path-npm-4.0.1-7aebd8bab3-5374c0cea4.zip b/.yarn/cache/npm-run-path-npm-4.0.1-7aebd8bab3-5374c0cea4.zip deleted file mode 100644 index 18ef7040d5c..00000000000 Binary files a/.yarn/cache/npm-run-path-npm-4.0.1-7aebd8bab3-5374c0cea4.zip and /dev/null differ diff --git a/.yarn/cache/npmlog-npm-6.0.2-e0e69455c7-ae238cd264.zip b/.yarn/cache/npmlog-npm-6.0.2-e0e69455c7-ae238cd264.zip deleted file mode 100644 index a7bb4a7dfcf..00000000000 Binary files a/.yarn/cache/npmlog-npm-6.0.2-e0e69455c7-ae238cd264.zip and /dev/null differ diff --git a/.yarn/cache/nth-check-npm-2.1.1-f97afc8169-5afc3dafcd.zip b/.yarn/cache/nth-check-npm-2.1.1-f97afc8169-5afc3dafcd.zip deleted file mode 100644 index dc825e50b87..00000000000 Binary files a/.yarn/cache/nth-check-npm-2.1.1-f97afc8169-5afc3dafcd.zip and /dev/null differ diff --git a/.yarn/cache/nullthrows-npm-1.1.1-3d1f817134-10806b9212.zip b/.yarn/cache/nullthrows-npm-1.1.1-3d1f817134-10806b9212.zip deleted file mode 100644 index 225c91a89cc..00000000000 Binary files a/.yarn/cache/nullthrows-npm-1.1.1-3d1f817134-10806b9212.zip and /dev/null differ diff --git a/.yarn/cache/object-assign-npm-4.1.1-1004ad6dec-fcc6e4ea8c.zip b/.yarn/cache/object-assign-npm-4.1.1-1004ad6dec-fcc6e4ea8c.zip deleted file mode 100644 index 8c8ab03b1b7..00000000000 Binary files a/.yarn/cache/object-assign-npm-4.1.1-1004ad6dec-fcc6e4ea8c.zip and /dev/null differ diff --git a/.yarn/cache/object-inspect-npm-1.12.0-d064fa559a-2b36d4001a.zip b/.yarn/cache/object-inspect-npm-1.12.0-d064fa559a-2b36d4001a.zip deleted file mode 100644 index 012894f367e..00000000000 Binary files a/.yarn/cache/object-inspect-npm-1.12.0-d064fa559a-2b36d4001a.zip and /dev/null differ diff --git a/.yarn/cache/object-keys-npm-1.1.1-1bf2f1be93-b363c5e764.zip b/.yarn/cache/object-keys-npm-1.1.1-1bf2f1be93-b363c5e764.zip deleted file mode 100644 index 34022827ec9..00000000000 Binary files a/.yarn/cache/object-keys-npm-1.1.1-1bf2f1be93-b363c5e764.zip and /dev/null differ diff --git a/.yarn/cache/object.assign-npm-4.1.2-d52edada1c-d621d832ed.zip b/.yarn/cache/object.assign-npm-4.1.2-d52edada1c-d621d832ed.zip deleted file mode 100644 index 0031b978160..00000000000 Binary files a/.yarn/cache/object.assign-npm-4.1.2-d52edada1c-d621d832ed.zip and /dev/null differ diff --git a/.yarn/cache/object.values-npm-1.1.5-f1de7f3742-0f17e99741.zip b/.yarn/cache/object.values-npm-1.1.5-f1de7f3742-0f17e99741.zip deleted file mode 100644 index e03d02d7ddd..00000000000 Binary files a/.yarn/cache/object.values-npm-1.1.5-f1de7f3742-0f17e99741.zip and /dev/null differ diff --git a/.yarn/cache/once-npm-1.4.0-ccf03ef07a-cd0a885013.zip b/.yarn/cache/once-npm-1.4.0-ccf03ef07a-cd0a885013.zip deleted file mode 100644 index 1b943eec95a..00000000000 Binary files a/.yarn/cache/once-npm-1.4.0-ccf03ef07a-cd0a885013.zip and /dev/null differ diff --git a/.yarn/cache/onetime-npm-5.1.2-3ed148fa42-2478859ef8.zip b/.yarn/cache/onetime-npm-5.1.2-3ed148fa42-2478859ef8.zip deleted file mode 100644 index 958e05b7dd9..00000000000 Binary files a/.yarn/cache/onetime-npm-5.1.2-3ed148fa42-2478859ef8.zip and /dev/null differ diff --git a/.yarn/cache/optionator-npm-0.9.1-577e397aae-dbc6fa0656.zip b/.yarn/cache/optionator-npm-0.9.1-577e397aae-dbc6fa0656.zip deleted file mode 100644 index 6e6efe345ba..00000000000 Binary files a/.yarn/cache/optionator-npm-0.9.1-577e397aae-dbc6fa0656.zip and /dev/null differ diff --git a/.yarn/cache/ordered-binary-npm-1.2.5-c6ab9248f9-fd0f1322a6.zip b/.yarn/cache/ordered-binary-npm-1.2.5-c6ab9248f9-fd0f1322a6.zip deleted file mode 100644 index 6a9dd5272e2..00000000000 Binary files a/.yarn/cache/ordered-binary-npm-1.2.5-c6ab9248f9-fd0f1322a6.zip and /dev/null differ diff --git a/.yarn/cache/ospath-npm-1.2.2-c8f45523a8-505f48a4f4.zip b/.yarn/cache/ospath-npm-1.2.2-c8f45523a8-505f48a4f4.zip deleted file mode 100644 index 0c1524ce411..00000000000 Binary files a/.yarn/cache/ospath-npm-1.2.2-c8f45523a8-505f48a4f4.zip and /dev/null differ diff --git a/.yarn/cache/p-limit-npm-1.3.0-fdb471d864-281c1c0b8c.zip b/.yarn/cache/p-limit-npm-1.3.0-fdb471d864-281c1c0b8c.zip deleted file mode 100644 index 96906babdc5..00000000000 Binary files a/.yarn/cache/p-limit-npm-1.3.0-fdb471d864-281c1c0b8c.zip and /dev/null differ diff --git a/.yarn/cache/p-limit-npm-3.1.0-05d2ede37f-7c3690c4db.zip b/.yarn/cache/p-limit-npm-3.1.0-05d2ede37f-7c3690c4db.zip deleted file mode 100644 index b87d97ccf80..00000000000 Binary files a/.yarn/cache/p-limit-npm-3.1.0-05d2ede37f-7c3690c4db.zip and /dev/null differ diff --git a/.yarn/cache/p-locate-npm-2.0.0-3a2ee263dd-e2dceb9b49.zip b/.yarn/cache/p-locate-npm-2.0.0-3a2ee263dd-e2dceb9b49.zip deleted file mode 100644 index f6f9f09b9ea..00000000000 Binary files a/.yarn/cache/p-locate-npm-2.0.0-3a2ee263dd-e2dceb9b49.zip and /dev/null differ diff --git a/.yarn/cache/p-locate-npm-5.0.0-92cc7c7a3e-1623088f36.zip b/.yarn/cache/p-locate-npm-5.0.0-92cc7c7a3e-1623088f36.zip deleted file mode 100644 index 077f1c6eeba..00000000000 Binary files a/.yarn/cache/p-locate-npm-5.0.0-92cc7c7a3e-1623088f36.zip and /dev/null differ diff --git a/.yarn/cache/p-map-npm-4.0.0-4677ae07c7-cb0ab21ec0.zip b/.yarn/cache/p-map-npm-4.0.0-4677ae07c7-cb0ab21ec0.zip deleted file mode 100644 index 092fe42ff79..00000000000 Binary files a/.yarn/cache/p-map-npm-4.0.0-4677ae07c7-cb0ab21ec0.zip and /dev/null differ diff --git a/.yarn/cache/p-try-npm-1.0.0-7373139e40-3b5303f77e.zip b/.yarn/cache/p-try-npm-1.0.0-7373139e40-3b5303f77e.zip deleted file mode 100644 index e12bd247e1a..00000000000 Binary files a/.yarn/cache/p-try-npm-1.0.0-7373139e40-3b5303f77e.zip and /dev/null differ diff --git a/.yarn/cache/parcel-npm-2.6.2-91cd9ac49d-4c0de2d27a.zip b/.yarn/cache/parcel-npm-2.6.2-91cd9ac49d-4c0de2d27a.zip deleted file mode 100644 index 9e729d85278..00000000000 Binary files a/.yarn/cache/parcel-npm-2.6.2-91cd9ac49d-4c0de2d27a.zip and /dev/null differ diff --git a/.yarn/cache/parent-module-npm-1.0.1-1fae11b095-6ba8b25514.zip b/.yarn/cache/parent-module-npm-1.0.1-1fae11b095-6ba8b25514.zip deleted file mode 100644 index 5b900e17fba..00000000000 Binary files a/.yarn/cache/parent-module-npm-1.0.1-1fae11b095-6ba8b25514.zip and /dev/null differ diff --git a/.yarn/cache/parse-json-npm-5.2.0-00a63b1199-62085b17d6.zip b/.yarn/cache/parse-json-npm-5.2.0-00a63b1199-62085b17d6.zip deleted file mode 100644 index 141b5217132..00000000000 Binary files a/.yarn/cache/parse-json-npm-5.2.0-00a63b1199-62085b17d6.zip and /dev/null differ diff --git a/.yarn/cache/path-exists-npm-3.0.0-e80371aa68-96e92643aa.zip b/.yarn/cache/path-exists-npm-3.0.0-e80371aa68-96e92643aa.zip deleted file mode 100644 index bdaa46fd30e..00000000000 Binary files a/.yarn/cache/path-exists-npm-3.0.0-e80371aa68-96e92643aa.zip and /dev/null differ diff --git a/.yarn/cache/path-exists-npm-4.0.0-e9e4f63eb0-505807199d.zip b/.yarn/cache/path-exists-npm-4.0.0-e9e4f63eb0-505807199d.zip deleted file mode 100644 index b5048416993..00000000000 Binary files a/.yarn/cache/path-exists-npm-4.0.0-e9e4f63eb0-505807199d.zip and /dev/null differ diff --git a/.yarn/cache/path-is-absolute-npm-1.0.1-31bc695ffd-060840f92c.zip b/.yarn/cache/path-is-absolute-npm-1.0.1-31bc695ffd-060840f92c.zip deleted file mode 100644 index ce195de7058..00000000000 Binary files a/.yarn/cache/path-is-absolute-npm-1.0.1-31bc695ffd-060840f92c.zip and /dev/null differ diff --git a/.yarn/cache/path-key-npm-3.1.1-0e66ea8321-55cd7a9dd4.zip b/.yarn/cache/path-key-npm-3.1.1-0e66ea8321-55cd7a9dd4.zip deleted file mode 100644 index dd7212e2cd4..00000000000 Binary files a/.yarn/cache/path-key-npm-3.1.1-0e66ea8321-55cd7a9dd4.zip and /dev/null differ diff --git a/.yarn/cache/path-parse-npm-1.0.7-09564527b7-49abf3d811.zip b/.yarn/cache/path-parse-npm-1.0.7-09564527b7-49abf3d811.zip deleted file mode 100644 index 30362e2c384..00000000000 Binary files a/.yarn/cache/path-parse-npm-1.0.7-09564527b7-49abf3d811.zip and /dev/null differ diff --git a/.yarn/cache/path-type-npm-4.0.0-10d47fc86a-5b1e2daa24.zip b/.yarn/cache/path-type-npm-4.0.0-10d47fc86a-5b1e2daa24.zip deleted file mode 100644 index f37ca5bcc1a..00000000000 Binary files a/.yarn/cache/path-type-npm-4.0.0-10d47fc86a-5b1e2daa24.zip and /dev/null differ diff --git a/.yarn/cache/pathval-npm-1.1.1-ce0311d7e0-090e314771.zip b/.yarn/cache/pathval-npm-1.1.1-ce0311d7e0-090e314771.zip deleted file mode 100644 index b5cdc46250e..00000000000 Binary files a/.yarn/cache/pathval-npm-1.1.1-ce0311d7e0-090e314771.zip and /dev/null differ diff --git a/.yarn/cache/pend-npm-1.2.0-7a13d93266-6c72f52433.zip b/.yarn/cache/pend-npm-1.2.0-7a13d93266-6c72f52433.zip deleted file mode 100644 index 03b6b6dec0d..00000000000 Binary files a/.yarn/cache/pend-npm-1.2.0-7a13d93266-6c72f52433.zip and /dev/null differ diff --git a/.yarn/cache/performance-now-npm-2.1.0-45e3ce7e49-534e641aa8.zip b/.yarn/cache/performance-now-npm-2.1.0-45e3ce7e49-534e641aa8.zip deleted file mode 100644 index fa9ee04fea4..00000000000 Binary files a/.yarn/cache/performance-now-npm-2.1.0-45e3ce7e49-534e641aa8.zip and /dev/null differ diff --git a/.yarn/cache/picocolors-npm-1.0.0-d81e0b1927-a2e8092dd8.zip b/.yarn/cache/picocolors-npm-1.0.0-d81e0b1927-a2e8092dd8.zip deleted file mode 100644 index 2d7c3d573a5..00000000000 Binary files a/.yarn/cache/picocolors-npm-1.0.0-d81e0b1927-a2e8092dd8.zip and /dev/null differ diff --git a/.yarn/cache/picomatch-npm-2.3.1-c782cfd986-050c865ce8.zip b/.yarn/cache/picomatch-npm-2.3.1-c782cfd986-050c865ce8.zip deleted file mode 100644 index 33846984276..00000000000 Binary files a/.yarn/cache/picomatch-npm-2.3.1-c782cfd986-050c865ce8.zip and /dev/null differ diff --git a/.yarn/cache/pify-npm-2.3.0-8b63310934-9503aaeaf4.zip b/.yarn/cache/pify-npm-2.3.0-8b63310934-9503aaeaf4.zip deleted file mode 100644 index 4cbc70a0abe..00000000000 Binary files a/.yarn/cache/pify-npm-2.3.0-8b63310934-9503aaeaf4.zip and /dev/null differ diff --git a/.yarn/cache/pinia-npm-2.0.16-5cedac4949-226aaf57a8.zip b/.yarn/cache/pinia-npm-2.0.16-5cedac4949-226aaf57a8.zip deleted file mode 100644 index ed5d857dd41..00000000000 Binary files a/.yarn/cache/pinia-npm-2.0.16-5cedac4949-226aaf57a8.zip and /dev/null differ diff --git a/.yarn/cache/pinia-plugin-persist-npm-1.0.0-b6b3a94cc9-49335d7207.zip b/.yarn/cache/pinia-plugin-persist-npm-1.0.0-b6b3a94cc9-49335d7207.zip deleted file mode 100644 index ef5d8106609..00000000000 Binary files a/.yarn/cache/pinia-plugin-persist-npm-1.0.0-b6b3a94cc9-49335d7207.zip and /dev/null differ diff --git a/.yarn/cache/postcss-npm-8.4.12-e941d78a98-248e3d0f9b.zip b/.yarn/cache/postcss-npm-8.4.12-e941d78a98-248e3d0f9b.zip deleted file mode 100644 index 4f940728b96..00000000000 Binary files a/.yarn/cache/postcss-npm-8.4.12-e941d78a98-248e3d0f9b.zip and /dev/null differ diff --git a/.yarn/cache/postcss-npm-8.4.14-c0d448b728-fe58766ff3.zip b/.yarn/cache/postcss-npm-8.4.14-c0d448b728-fe58766ff3.zip deleted file mode 100644 index 63ace659e33..00000000000 Binary files a/.yarn/cache/postcss-npm-8.4.14-c0d448b728-fe58766ff3.zip and /dev/null differ diff --git a/.yarn/cache/postcss-selector-parser-npm-6.0.10-a4d7aaa270-46afaa60e3.zip b/.yarn/cache/postcss-selector-parser-npm-6.0.10-a4d7aaa270-46afaa60e3.zip deleted file mode 100644 index 496c72f70c2..00000000000 Binary files a/.yarn/cache/postcss-selector-parser-npm-6.0.10-a4d7aaa270-46afaa60e3.zip and /dev/null differ diff --git a/.yarn/cache/postcss-value-parser-npm-4.2.0-3cef602a6a-819ffab0c9.zip b/.yarn/cache/postcss-value-parser-npm-4.2.0-3cef602a6a-819ffab0c9.zip deleted file mode 100644 index 8f7cb96c0a9..00000000000 Binary files a/.yarn/cache/postcss-value-parser-npm-4.2.0-3cef602a6a-819ffab0c9.zip and /dev/null differ diff --git a/.yarn/cache/posthtml-npm-0.16.6-c3387f43c9-8b9b9d27bd.zip b/.yarn/cache/posthtml-npm-0.16.6-c3387f43c9-8b9b9d27bd.zip deleted file mode 100644 index 01f7cf83c4c..00000000000 Binary files a/.yarn/cache/posthtml-npm-0.16.6-c3387f43c9-8b9b9d27bd.zip and /dev/null differ diff --git a/.yarn/cache/posthtml-parser-npm-0.10.2-f553bc0146-63ec8e8631.zip b/.yarn/cache/posthtml-parser-npm-0.10.2-f553bc0146-63ec8e8631.zip deleted file mode 100644 index a2e4b0e351c..00000000000 Binary files a/.yarn/cache/posthtml-parser-npm-0.10.2-f553bc0146-63ec8e8631.zip and /dev/null differ diff --git a/.yarn/cache/posthtml-parser-npm-0.11.0-88a39d3d19-37dca546a0.zip b/.yarn/cache/posthtml-parser-npm-0.11.0-88a39d3d19-37dca546a0.zip deleted file mode 100644 index 316798a5adb..00000000000 Binary files a/.yarn/cache/posthtml-parser-npm-0.11.0-88a39d3d19-37dca546a0.zip and /dev/null differ diff --git a/.yarn/cache/posthtml-render-npm-3.0.0-7d46185567-5ed2d6e881.zip b/.yarn/cache/posthtml-render-npm-3.0.0-7d46185567-5ed2d6e881.zip deleted file mode 100644 index aeb19515b90..00000000000 Binary files a/.yarn/cache/posthtml-render-npm-3.0.0-7d46185567-5ed2d6e881.zip and /dev/null differ diff --git a/.yarn/cache/preact-npm-10.7.2-dffb68bd4b-2f0655e043.zip b/.yarn/cache/preact-npm-10.7.2-dffb68bd4b-2f0655e043.zip deleted file mode 100644 index 40a53d7f1c2..00000000000 Binary files a/.yarn/cache/preact-npm-10.7.2-dffb68bd4b-2f0655e043.zip and /dev/null differ diff --git a/.yarn/cache/prelude-ls-npm-1.2.1-3e4d272a55-cd192ec0d0.zip b/.yarn/cache/prelude-ls-npm-1.2.1-3e4d272a55-cd192ec0d0.zip deleted file mode 100644 index 38e7969199e..00000000000 Binary files a/.yarn/cache/prelude-ls-npm-1.2.1-3e4d272a55-cd192ec0d0.zip and /dev/null differ diff --git a/.yarn/cache/pretty-bytes-npm-5.6.0-0061079c9f-9c082500d1.zip b/.yarn/cache/pretty-bytes-npm-5.6.0-0061079c9f-9c082500d1.zip deleted file mode 100644 index 767e74fc050..00000000000 Binary files a/.yarn/cache/pretty-bytes-npm-5.6.0-0061079c9f-9c082500d1.zip and /dev/null differ diff --git a/.yarn/cache/pretty-format-npm-27.5.1-cd7d49696f-cf610cffcb.zip b/.yarn/cache/pretty-format-npm-27.5.1-cd7d49696f-cf610cffcb.zip deleted file mode 100644 index 8d28efe3e1f..00000000000 Binary files a/.yarn/cache/pretty-format-npm-27.5.1-cd7d49696f-cf610cffcb.zip and /dev/null differ diff --git a/.yarn/cache/promise-inflight-npm-1.0.1-5bb925afac-2274948309.zip b/.yarn/cache/promise-inflight-npm-1.0.1-5bb925afac-2274948309.zip deleted file mode 100644 index fa2a77c45bf..00000000000 Binary files a/.yarn/cache/promise-inflight-npm-1.0.1-5bb925afac-2274948309.zip and /dev/null differ diff --git a/.yarn/cache/promise-npm-7.3.1-5d81d474c0-475bb06913.zip b/.yarn/cache/promise-npm-7.3.1-5d81d474c0-475bb06913.zip deleted file mode 100644 index 8cdeb99bf6e..00000000000 Binary files a/.yarn/cache/promise-npm-7.3.1-5d81d474c0-475bb06913.zip and /dev/null differ diff --git a/.yarn/cache/promise-retry-npm-2.0.1-871f0b01b7-f96a3f6d90.zip b/.yarn/cache/promise-retry-npm-2.0.1-871f0b01b7-f96a3f6d90.zip deleted file mode 100644 index 9cefe07769b..00000000000 Binary files a/.yarn/cache/promise-retry-npm-2.0.1-871f0b01b7-f96a3f6d90.zip and /dev/null differ diff --git a/.yarn/cache/prompts-npm-2.4.2-f5d25d5eea-d8fd1fe638.zip b/.yarn/cache/prompts-npm-2.4.2-f5d25d5eea-d8fd1fe638.zip deleted file mode 100644 index ec51fd38428..00000000000 Binary files a/.yarn/cache/prompts-npm-2.4.2-f5d25d5eea-d8fd1fe638.zip and /dev/null differ diff --git a/.yarn/cache/proxy-from-env-npm-1.0.0-679b82b4ec-292e28d1de.zip b/.yarn/cache/proxy-from-env-npm-1.0.0-679b82b4ec-292e28d1de.zip deleted file mode 100644 index 8015209887a..00000000000 Binary files a/.yarn/cache/proxy-from-env-npm-1.0.0-679b82b4ec-292e28d1de.zip and /dev/null differ diff --git a/.yarn/cache/psl-npm-1.8.0-226099d70e-6150048ed2.zip b/.yarn/cache/psl-npm-1.8.0-226099d70e-6150048ed2.zip deleted file mode 100644 index 1611ec10a31..00000000000 Binary files a/.yarn/cache/psl-npm-1.8.0-226099d70e-6150048ed2.zip and /dev/null differ diff --git a/.yarn/cache/pug-attrs-npm-3.0.0-31b331fe79-2ca2d34de3.zip b/.yarn/cache/pug-attrs-npm-3.0.0-31b331fe79-2ca2d34de3.zip deleted file mode 100644 index 2de44655ff5..00000000000 Binary files a/.yarn/cache/pug-attrs-npm-3.0.0-31b331fe79-2ca2d34de3.zip and /dev/null differ diff --git a/.yarn/cache/pug-code-gen-npm-3.0.2-1cc7d40723-1644d3a4d6.zip b/.yarn/cache/pug-code-gen-npm-3.0.2-1cc7d40723-1644d3a4d6.zip deleted file mode 100644 index d27259746e1..00000000000 Binary files a/.yarn/cache/pug-code-gen-npm-3.0.2-1cc7d40723-1644d3a4d6.zip and /dev/null differ diff --git a/.yarn/cache/pug-error-npm-2.0.0-13b776f97b-c5372d018c.zip b/.yarn/cache/pug-error-npm-2.0.0-13b776f97b-c5372d018c.zip deleted file mode 100644 index 77a74d496e2..00000000000 Binary files a/.yarn/cache/pug-error-npm-2.0.0-13b776f97b-c5372d018c.zip and /dev/null differ diff --git a/.yarn/cache/pug-filters-npm-4.0.0-d2cf0196e7-44eb327319.zip b/.yarn/cache/pug-filters-npm-4.0.0-d2cf0196e7-44eb327319.zip deleted file mode 100644 index 8f54c88cb84..00000000000 Binary files a/.yarn/cache/pug-filters-npm-4.0.0-d2cf0196e7-44eb327319.zip and /dev/null differ diff --git a/.yarn/cache/pug-lexer-npm-5.0.1-3bdff5fe60-afdd2f43f2.zip b/.yarn/cache/pug-lexer-npm-5.0.1-3bdff5fe60-afdd2f43f2.zip deleted file mode 100644 index b3cdc8c582a..00000000000 Binary files a/.yarn/cache/pug-lexer-npm-5.0.1-3bdff5fe60-afdd2f43f2.zip and /dev/null differ diff --git a/.yarn/cache/pug-linker-npm-4.0.0-b140c7e607-7433aa6518.zip b/.yarn/cache/pug-linker-npm-4.0.0-b140c7e607-7433aa6518.zip deleted file mode 100644 index adea222016a..00000000000 Binary files a/.yarn/cache/pug-linker-npm-4.0.0-b140c7e607-7433aa6518.zip and /dev/null differ diff --git a/.yarn/cache/pug-load-npm-3.0.0-dc9f2273d3-1800ec5199.zip b/.yarn/cache/pug-load-npm-3.0.0-dc9f2273d3-1800ec5199.zip deleted file mode 100644 index 7995c53be8c..00000000000 Binary files a/.yarn/cache/pug-load-npm-3.0.0-dc9f2273d3-1800ec5199.zip and /dev/null differ diff --git a/.yarn/cache/pug-npm-3.0.2-a900d45f03-3e1a3d4889.zip b/.yarn/cache/pug-npm-3.0.2-a900d45f03-3e1a3d4889.zip deleted file mode 100644 index c35c2972b56..00000000000 Binary files a/.yarn/cache/pug-npm-3.0.2-a900d45f03-3e1a3d4889.zip and /dev/null differ diff --git a/.yarn/cache/pug-parser-npm-6.0.0-87b7dc8a83-a6954d1383.zip b/.yarn/cache/pug-parser-npm-6.0.0-87b7dc8a83-a6954d1383.zip deleted file mode 100644 index 38850483520..00000000000 Binary files a/.yarn/cache/pug-parser-npm-6.0.0-87b7dc8a83-a6954d1383.zip and /dev/null differ diff --git a/.yarn/cache/pug-runtime-npm-3.0.1-13038c62ae-48a71b587c.zip b/.yarn/cache/pug-runtime-npm-3.0.1-13038c62ae-48a71b587c.zip deleted file mode 100644 index 9473bee29f7..00000000000 Binary files a/.yarn/cache/pug-runtime-npm-3.0.1-13038c62ae-48a71b587c.zip and /dev/null differ diff --git a/.yarn/cache/pug-strip-comments-npm-2.0.0-7baa7bca2f-2cfcbf506c.zip b/.yarn/cache/pug-strip-comments-npm-2.0.0-7baa7bca2f-2cfcbf506c.zip deleted file mode 100644 index db4d78e3da5..00000000000 Binary files a/.yarn/cache/pug-strip-comments-npm-2.0.0-7baa7bca2f-2cfcbf506c.zip and /dev/null differ diff --git a/.yarn/cache/pug-walk-npm-2.0.0-a8a11880fc-bee64e133b.zip b/.yarn/cache/pug-walk-npm-2.0.0-a8a11880fc-bee64e133b.zip deleted file mode 100644 index a1a134b0dc8..00000000000 Binary files a/.yarn/cache/pug-walk-npm-2.0.0-a8a11880fc-bee64e133b.zip and /dev/null differ diff --git a/.yarn/cache/pump-npm-3.0.0-0080bf6a7a-e42e9229fb.zip b/.yarn/cache/pump-npm-3.0.0-0080bf6a7a-e42e9229fb.zip deleted file mode 100644 index 05856836216..00000000000 Binary files a/.yarn/cache/pump-npm-3.0.0-0080bf6a7a-e42e9229fb.zip and /dev/null differ diff --git a/.yarn/cache/punycode-npm-2.1.1-26eb3e15cf-823bf443c6.zip b/.yarn/cache/punycode-npm-2.1.1-26eb3e15cf-823bf443c6.zip deleted file mode 100644 index 4946f0581f5..00000000000 Binary files a/.yarn/cache/punycode-npm-2.1.1-26eb3e15cf-823bf443c6.zip and /dev/null differ diff --git a/.yarn/cache/qs-npm-6.5.3-90b2635484-6f20bf08ca.zip b/.yarn/cache/qs-npm-6.5.3-90b2635484-6f20bf08ca.zip deleted file mode 100644 index 6714c3cff96..00000000000 Binary files a/.yarn/cache/qs-npm-6.5.3-90b2635484-6f20bf08ca.zip and /dev/null differ diff --git a/.yarn/cache/react-error-overlay-npm-6.0.9-96e7e1e53a-695853bc88.zip b/.yarn/cache/react-error-overlay-npm-6.0.9-96e7e1e53a-695853bc88.zip deleted file mode 100644 index 5f9512c2457..00000000000 Binary files a/.yarn/cache/react-error-overlay-npm-6.0.9-96e7e1e53a-695853bc88.zip and /dev/null differ diff --git a/.yarn/cache/react-is-npm-17.0.2-091bbb8db6-9d6d111d89.zip b/.yarn/cache/react-is-npm-17.0.2-091bbb8db6-9d6d111d89.zip deleted file mode 100644 index 8b0c3e54609..00000000000 Binary files a/.yarn/cache/react-is-npm-17.0.2-091bbb8db6-9d6d111d89.zip and /dev/null differ diff --git a/.yarn/cache/react-refresh-npm-0.9.0-02c61ee045-6440146176.zip b/.yarn/cache/react-refresh-npm-0.9.0-02c61ee045-6440146176.zip deleted file mode 100644 index 911231e1072..00000000000 Binary files a/.yarn/cache/react-refresh-npm-0.9.0-02c61ee045-6440146176.zip and /dev/null differ diff --git a/.yarn/cache/readable-stream-npm-3.6.0-23a4a5eb56-d4ea81502d.zip b/.yarn/cache/readable-stream-npm-3.6.0-23a4a5eb56-d4ea81502d.zip deleted file mode 100644 index ede5b314bfd..00000000000 Binary files a/.yarn/cache/readable-stream-npm-3.6.0-23a4a5eb56-d4ea81502d.zip and /dev/null differ diff --git a/.yarn/cache/readdirp-npm-3.6.0-f950cc74ab-1ced032e6e.zip b/.yarn/cache/readdirp-npm-3.6.0-f950cc74ab-1ced032e6e.zip deleted file mode 100644 index f3687812b2c..00000000000 Binary files a/.yarn/cache/readdirp-npm-3.6.0-f950cc74ab-1ced032e6e.zip and /dev/null differ diff --git a/.yarn/cache/regenerator-runtime-npm-0.13.9-6d02340eec-65ed455fe5.zip b/.yarn/cache/regenerator-runtime-npm-0.13.9-6d02340eec-65ed455fe5.zip deleted file mode 100644 index 29291038f14..00000000000 Binary files a/.yarn/cache/regenerator-runtime-npm-0.13.9-6d02340eec-65ed455fe5.zip and /dev/null differ diff --git a/.yarn/cache/regexpp-npm-3.2.0-2513f32cfc-a78dc5c715.zip b/.yarn/cache/regexpp-npm-3.2.0-2513f32cfc-a78dc5c715.zip deleted file mode 100644 index 9dac209df2f..00000000000 Binary files a/.yarn/cache/regexpp-npm-3.2.0-2513f32cfc-a78dc5c715.zip and /dev/null differ diff --git a/.yarn/cache/request-progress-npm-3.0.0-f79f1c9e67-6ea1761dcc.zip b/.yarn/cache/request-progress-npm-3.0.0-f79f1c9e67-6ea1761dcc.zip deleted file mode 100644 index 422169abe66..00000000000 Binary files a/.yarn/cache/request-progress-npm-3.0.0-f79f1c9e67-6ea1761dcc.zip and /dev/null differ diff --git a/.yarn/cache/require-directory-npm-2.1.1-8608aee50b-fb47e70bf0.zip b/.yarn/cache/require-directory-npm-2.1.1-8608aee50b-fb47e70bf0.zip deleted file mode 100644 index 5af5579b18e..00000000000 Binary files a/.yarn/cache/require-directory-npm-2.1.1-8608aee50b-fb47e70bf0.zip and /dev/null differ diff --git a/.yarn/cache/require-from-string-npm-2.0.2-8557e0db12-a03ef68954.zip b/.yarn/cache/require-from-string-npm-2.0.2-8557e0db12-a03ef68954.zip deleted file mode 100644 index a91f2d57b23..00000000000 Binary files a/.yarn/cache/require-from-string-npm-2.0.2-8557e0db12-a03ef68954.zip and /dev/null differ diff --git a/.yarn/cache/resolve-from-npm-4.0.0-f758ec21bf-f4ba0b8494.zip b/.yarn/cache/resolve-from-npm-4.0.0-f758ec21bf-f4ba0b8494.zip deleted file mode 100644 index 86f591e3e89..00000000000 Binary files a/.yarn/cache/resolve-from-npm-4.0.0-f758ec21bf-f4ba0b8494.zip and /dev/null differ diff --git a/.yarn/cache/resolve-npm-1.22.0-f641ddcc95-a2d14cc437.zip b/.yarn/cache/resolve-npm-1.22.0-f641ddcc95-a2d14cc437.zip deleted file mode 100644 index 1804da23d5e..00000000000 Binary files a/.yarn/cache/resolve-npm-1.22.0-f641ddcc95-a2d14cc437.zip and /dev/null differ diff --git a/.yarn/cache/resolve-npm-1.22.1-3980488690-07af5fc1e8.zip b/.yarn/cache/resolve-npm-1.22.1-3980488690-07af5fc1e8.zip deleted file mode 100644 index d41402c877c..00000000000 Binary files a/.yarn/cache/resolve-npm-1.22.1-3980488690-07af5fc1e8.zip and /dev/null differ diff --git a/.yarn/cache/resolve-patch-46f9469d0d-5656f4d0be.zip b/.yarn/cache/resolve-patch-46f9469d0d-5656f4d0be.zip deleted file mode 100644 index c3066c3608a..00000000000 Binary files a/.yarn/cache/resolve-patch-46f9469d0d-5656f4d0be.zip and /dev/null differ diff --git a/.yarn/cache/resolve-patch-bad885c6ea-c79ecaea36.zip b/.yarn/cache/resolve-patch-bad885c6ea-c79ecaea36.zip deleted file mode 100644 index b7e8b9abf59..00000000000 Binary files a/.yarn/cache/resolve-patch-bad885c6ea-c79ecaea36.zip and /dev/null differ diff --git a/.yarn/cache/restore-cursor-npm-3.1.0-52c5a4c98f-f877dd8741.zip b/.yarn/cache/restore-cursor-npm-3.1.0-52c5a4c98f-f877dd8741.zip deleted file mode 100644 index f11afe99bba..00000000000 Binary files a/.yarn/cache/restore-cursor-npm-3.1.0-52c5a4c98f-f877dd8741.zip and /dev/null differ diff --git a/.yarn/cache/retry-npm-0.12.0-72ac7fb4cc-623bd7d2e5.zip b/.yarn/cache/retry-npm-0.12.0-72ac7fb4cc-623bd7d2e5.zip deleted file mode 100644 index 12e25fcd41c..00000000000 Binary files a/.yarn/cache/retry-npm-0.12.0-72ac7fb4cc-623bd7d2e5.zip and /dev/null differ diff --git a/.yarn/cache/rfdc-npm-1.3.0-272f288ad8-fb2ba8512e.zip b/.yarn/cache/rfdc-npm-1.3.0-272f288ad8-fb2ba8512e.zip deleted file mode 100644 index c6d5d0c9448..00000000000 Binary files a/.yarn/cache/rfdc-npm-1.3.0-272f288ad8-fb2ba8512e.zip and /dev/null differ diff --git a/.yarn/cache/rimraf-npm-3.0.2-2cb7dac69a-87f4164e39.zip b/.yarn/cache/rimraf-npm-3.0.2-2cb7dac69a-87f4164e39.zip deleted file mode 100644 index 6d2f54108a1..00000000000 Binary files a/.yarn/cache/rimraf-npm-3.0.2-2cb7dac69a-87f4164e39.zip and /dev/null differ diff --git a/.yarn/cache/robust-predicates-npm-3.0.1-550da1ca46-45e9de2df4.zip b/.yarn/cache/robust-predicates-npm-3.0.1-550da1ca46-45e9de2df4.zip deleted file mode 100644 index 19af9000ded..00000000000 Binary files a/.yarn/cache/robust-predicates-npm-3.0.1-550da1ca46-45e9de2df4.zip and /dev/null differ diff --git a/.yarn/cache/rollup-npm-2.75.3-7efa4583e0-ac33a2336d.zip b/.yarn/cache/rollup-npm-2.75.3-7efa4583e0-ac33a2336d.zip deleted file mode 100644 index b0261829fe4..00000000000 Binary files a/.yarn/cache/rollup-npm-2.75.3-7efa4583e0-ac33a2336d.zip and /dev/null differ diff --git a/.yarn/cache/rollup-npm-2.76.0-50edb80f3c-58293e1c63.zip b/.yarn/cache/rollup-npm-2.76.0-50edb80f3c-58293e1c63.zip deleted file mode 100644 index 05cce5d19ee..00000000000 Binary files a/.yarn/cache/rollup-npm-2.76.0-50edb80f3c-58293e1c63.zip and /dev/null differ diff --git a/.yarn/cache/rw-npm-1.3.3-2197930a8d-c20d82421f.zip b/.yarn/cache/rw-npm-1.3.3-2197930a8d-c20d82421f.zip deleted file mode 100644 index a1362e00bb9..00000000000 Binary files a/.yarn/cache/rw-npm-1.3.3-2197930a8d-c20d82421f.zip and /dev/null differ diff --git a/.yarn/cache/rxjs-npm-7.5.5-d0546b1ccb-e034f60805.zip b/.yarn/cache/rxjs-npm-7.5.5-d0546b1ccb-e034f60805.zip deleted file mode 100644 index c7a67f47145..00000000000 Binary files a/.yarn/cache/rxjs-npm-7.5.5-d0546b1ccb-e034f60805.zip and /dev/null differ diff --git a/.yarn/cache/safe-buffer-npm-5.1.2-c27fedf6c4-f2f1f7943c.zip b/.yarn/cache/safe-buffer-npm-5.1.2-c27fedf6c4-f2f1f7943c.zip deleted file mode 100644 index 53c2813c6fe..00000000000 Binary files a/.yarn/cache/safe-buffer-npm-5.1.2-c27fedf6c4-f2f1f7943c.zip and /dev/null differ diff --git a/.yarn/cache/safe-buffer-npm-5.2.1-3481c8aa9b-b99c4b41fd.zip b/.yarn/cache/safe-buffer-npm-5.2.1-3481c8aa9b-b99c4b41fd.zip deleted file mode 100644 index c80798aecd8..00000000000 Binary files a/.yarn/cache/safe-buffer-npm-5.2.1-3481c8aa9b-b99c4b41fd.zip and /dev/null differ diff --git a/.yarn/cache/safer-buffer-npm-2.1.2-8d5c0b705e-cab8f25ae6.zip b/.yarn/cache/safer-buffer-npm-2.1.2-8d5c0b705e-cab8f25ae6.zip deleted file mode 100644 index 1a93be64235..00000000000 Binary files a/.yarn/cache/safer-buffer-npm-2.1.2-8d5c0b705e-cab8f25ae6.zip and /dev/null differ diff --git a/.yarn/cache/sass-npm-1.52.1-7f0eb7e72c-a0508c88b1.zip b/.yarn/cache/sass-npm-1.52.1-7f0eb7e72c-a0508c88b1.zip deleted file mode 100644 index fd36b484979..00000000000 Binary files a/.yarn/cache/sass-npm-1.52.1-7f0eb7e72c-a0508c88b1.zip and /dev/null differ diff --git a/.yarn/cache/sass-npm-1.53.0-84886439f0-4bcb0617d6.zip b/.yarn/cache/sass-npm-1.53.0-84886439f0-4bcb0617d6.zip deleted file mode 100644 index 8a8d2a94b7b..00000000000 Binary files a/.yarn/cache/sass-npm-1.53.0-84886439f0-4bcb0617d6.zip and /dev/null differ diff --git a/.yarn/cache/seemly-npm-0.3.3-1df3254399-b6445553f8.zip b/.yarn/cache/seemly-npm-0.3.3-1df3254399-b6445553f8.zip deleted file mode 100644 index 5265b570838..00000000000 Binary files a/.yarn/cache/seemly-npm-0.3.3-1df3254399-b6445553f8.zip and /dev/null differ diff --git a/.yarn/cache/seemly-npm-0.3.4-2c676840e8-7b422b0d51.zip b/.yarn/cache/seemly-npm-0.3.4-2c676840e8-7b422b0d51.zip deleted file mode 100644 index d0d2f8ca394..00000000000 Binary files a/.yarn/cache/seemly-npm-0.3.4-2c676840e8-7b422b0d51.zip and /dev/null differ diff --git a/.yarn/cache/select2-bootstrap-5-theme-npm-1.3.0-10122bfbcb-248a869835.zip b/.yarn/cache/select2-bootstrap-5-theme-npm-1.3.0-10122bfbcb-248a869835.zip deleted file mode 100644 index 4e891ed7249..00000000000 Binary files a/.yarn/cache/select2-bootstrap-5-theme-npm-1.3.0-10122bfbcb-248a869835.zip and /dev/null differ diff --git a/.yarn/cache/select2-npm-4.1.0-rc.0-4f6f223d12-c27cefc396.zip b/.yarn/cache/select2-npm-4.1.0-rc.0-4f6f223d12-c27cefc396.zip deleted file mode 100644 index b4061a9e097..00000000000 Binary files a/.yarn/cache/select2-npm-4.1.0-rc.0-4f6f223d12-c27cefc396.zip and /dev/null differ diff --git a/.yarn/cache/semver-npm-5.7.1-40bcea106b-57fd0acfd0.zip b/.yarn/cache/semver-npm-5.7.1-40bcea106b-57fd0acfd0.zip deleted file mode 100644 index 68795d87761..00000000000 Binary files a/.yarn/cache/semver-npm-5.7.1-40bcea106b-57fd0acfd0.zip and /dev/null differ diff --git a/.yarn/cache/semver-npm-6.3.0-b3eace8bfd-1b26ecf6db.zip b/.yarn/cache/semver-npm-6.3.0-b3eace8bfd-1b26ecf6db.zip deleted file mode 100644 index 6320ec2b1bf..00000000000 Binary files a/.yarn/cache/semver-npm-6.3.0-b3eace8bfd-1b26ecf6db.zip and /dev/null differ diff --git a/.yarn/cache/semver-npm-7.3.7-3bfe704194-2fa3e87756.zip b/.yarn/cache/semver-npm-7.3.7-3bfe704194-2fa3e87756.zip deleted file mode 100644 index 38aca8db9d2..00000000000 Binary files a/.yarn/cache/semver-npm-7.3.7-3bfe704194-2fa3e87756.zip and /dev/null differ diff --git a/.yarn/cache/set-blocking-npm-2.0.0-49e2cffa24-6e65a05f7c.zip b/.yarn/cache/set-blocking-npm-2.0.0-49e2cffa24-6e65a05f7c.zip deleted file mode 100644 index fe99c6f42ca..00000000000 Binary files a/.yarn/cache/set-blocking-npm-2.0.0-49e2cffa24-6e65a05f7c.zip and /dev/null differ diff --git a/.yarn/cache/shebang-command-npm-2.0.0-eb2b01921d-6b52fe8727.zip b/.yarn/cache/shebang-command-npm-2.0.0-eb2b01921d-6b52fe8727.zip deleted file mode 100644 index 727c5471e2c..00000000000 Binary files a/.yarn/cache/shebang-command-npm-2.0.0-eb2b01921d-6b52fe8727.zip and /dev/null differ diff --git a/.yarn/cache/shebang-regex-npm-3.0.0-899a0cd65e-1a2bcae50d.zip b/.yarn/cache/shebang-regex-npm-3.0.0-899a0cd65e-1a2bcae50d.zip deleted file mode 100644 index 3e891cda952..00000000000 Binary files a/.yarn/cache/shebang-regex-npm-3.0.0-899a0cd65e-1a2bcae50d.zip and /dev/null differ diff --git a/.yarn/cache/side-channel-npm-1.0.4-e1f38b9e06-351e41b947.zip b/.yarn/cache/side-channel-npm-1.0.4-e1f38b9e06-351e41b947.zip deleted file mode 100644 index 3761d612205..00000000000 Binary files a/.yarn/cache/side-channel-npm-1.0.4-e1f38b9e06-351e41b947.zip and /dev/null differ diff --git a/.yarn/cache/signal-exit-npm-3.0.7-bd270458a3-a2f098f247.zip b/.yarn/cache/signal-exit-npm-3.0.7-bd270458a3-a2f098f247.zip deleted file mode 100644 index 98720bd8c76..00000000000 Binary files a/.yarn/cache/signal-exit-npm-3.0.7-bd270458a3-a2f098f247.zip and /dev/null differ diff --git a/.yarn/cache/sisteransi-npm-1.0.5-af60cc0cfa-aba6438f46.zip b/.yarn/cache/sisteransi-npm-1.0.5-af60cc0cfa-aba6438f46.zip deleted file mode 100644 index 606f0db3b78..00000000000 Binary files a/.yarn/cache/sisteransi-npm-1.0.5-af60cc0cfa-aba6438f46.zip and /dev/null differ diff --git a/.yarn/cache/slice-ansi-npm-3.0.0-d9999864af-5ec6d022d1.zip b/.yarn/cache/slice-ansi-npm-3.0.0-d9999864af-5ec6d022d1.zip deleted file mode 100644 index 0129e70bff8..00000000000 Binary files a/.yarn/cache/slice-ansi-npm-3.0.0-d9999864af-5ec6d022d1.zip and /dev/null differ diff --git a/.yarn/cache/slice-ansi-npm-4.0.0-6eeca1d10e-4a82d7f085.zip b/.yarn/cache/slice-ansi-npm-4.0.0-6eeca1d10e-4a82d7f085.zip deleted file mode 100644 index ef2012f3731..00000000000 Binary files a/.yarn/cache/slice-ansi-npm-4.0.0-6eeca1d10e-4a82d7f085.zip and /dev/null differ diff --git a/.yarn/cache/slugify-npm-1.6.5-6db25d7016-a955a1b600.zip b/.yarn/cache/slugify-npm-1.6.5-6db25d7016-a955a1b600.zip deleted file mode 100644 index 3cea733dfac..00000000000 Binary files a/.yarn/cache/slugify-npm-1.6.5-6db25d7016-a955a1b600.zip and /dev/null differ diff --git a/.yarn/cache/smart-buffer-npm-4.2.0-5ac3f668bb-b5167a7142.zip b/.yarn/cache/smart-buffer-npm-4.2.0-5ac3f668bb-b5167a7142.zip deleted file mode 100644 index d587b3db7ad..00000000000 Binary files a/.yarn/cache/smart-buffer-npm-4.2.0-5ac3f668bb-b5167a7142.zip and /dev/null differ diff --git a/.yarn/cache/socks-npm-2.6.2-94c1dcb8b8-dd91942930.zip b/.yarn/cache/socks-npm-2.6.2-94c1dcb8b8-dd91942930.zip deleted file mode 100644 index bec5d0ca378..00000000000 Binary files a/.yarn/cache/socks-npm-2.6.2-94c1dcb8b8-dd91942930.zip and /dev/null differ diff --git a/.yarn/cache/socks-proxy-agent-npm-6.2.0-9c332b84bc-6723fd64fb.zip b/.yarn/cache/socks-proxy-agent-npm-6.2.0-9c332b84bc-6723fd64fb.zip deleted file mode 100644 index 69f6d0d1835..00000000000 Binary files a/.yarn/cache/socks-proxy-agent-npm-6.2.0-9c332b84bc-6723fd64fb.zip and /dev/null differ diff --git a/.yarn/cache/sortablejs-npm-1.15.0-f3a393abcc-bb82223a66.zip b/.yarn/cache/sortablejs-npm-1.15.0-f3a393abcc-bb82223a66.zip deleted file mode 100644 index 9028b71d1c6..00000000000 Binary files a/.yarn/cache/sortablejs-npm-1.15.0-f3a393abcc-bb82223a66.zip and /dev/null differ diff --git a/.yarn/cache/source-map-js-npm-1.0.2-ee4f9f9b30-c049a7fc4d.zip b/.yarn/cache/source-map-js-npm-1.0.2-ee4f9f9b30-c049a7fc4d.zip deleted file mode 100644 index 061ccc63c48..00000000000 Binary files a/.yarn/cache/source-map-js-npm-1.0.2-ee4f9f9b30-c049a7fc4d.zip and /dev/null differ diff --git a/.yarn/cache/source-map-npm-0.6.1-1a3621db16-59ce8640cf.zip b/.yarn/cache/source-map-npm-0.6.1-1a3621db16-59ce8640cf.zip deleted file mode 100644 index 5f6c0e46b75..00000000000 Binary files a/.yarn/cache/source-map-npm-0.6.1-1a3621db16-59ce8640cf.zip and /dev/null differ diff --git a/.yarn/cache/source-map-npm-0.8.0-beta.0-688a309e94-e94169be64.zip b/.yarn/cache/source-map-npm-0.8.0-beta.0-688a309e94-e94169be64.zip deleted file mode 100644 index 877220ab43e..00000000000 Binary files a/.yarn/cache/source-map-npm-0.8.0-beta.0-688a309e94-e94169be64.zip and /dev/null differ diff --git a/.yarn/cache/source-map-support-npm-0.5.21-09ca99e250-43e98d700d.zip b/.yarn/cache/source-map-support-npm-0.5.21-09ca99e250-43e98d700d.zip deleted file mode 100644 index 5fc27c8438d..00000000000 Binary files a/.yarn/cache/source-map-support-npm-0.5.21-09ca99e250-43e98d700d.zip and /dev/null differ diff --git a/.yarn/cache/sourcemap-codec-npm-1.4.8-3a1a9e60b1-b57981c056.zip b/.yarn/cache/sourcemap-codec-npm-1.4.8-3a1a9e60b1-b57981c056.zip deleted file mode 100644 index de84f79779c..00000000000 Binary files a/.yarn/cache/sourcemap-codec-npm-1.4.8-3a1a9e60b1-b57981c056.zip and /dev/null differ diff --git a/.yarn/cache/sshpk-npm-1.17.0-95f17f597f-ba109f65c8.zip b/.yarn/cache/sshpk-npm-1.17.0-95f17f597f-ba109f65c8.zip deleted file mode 100644 index f3b155f79aa..00000000000 Binary files a/.yarn/cache/sshpk-npm-1.17.0-95f17f597f-ba109f65c8.zip and /dev/null differ diff --git a/.yarn/cache/ssri-npm-9.0.1-33ce27f4f8-fb58f5e46b.zip b/.yarn/cache/ssri-npm-9.0.1-33ce27f4f8-fb58f5e46b.zip deleted file mode 100644 index 4af584ce2c5..00000000000 Binary files a/.yarn/cache/ssri-npm-9.0.1-33ce27f4f8-fb58f5e46b.zip and /dev/null differ diff --git a/.yarn/cache/stable-npm-0.1.8-feb4e06de8-2ff482bb10.zip b/.yarn/cache/stable-npm-0.1.8-feb4e06de8-2ff482bb10.zip deleted file mode 100644 index 3ca4e22615d..00000000000 Binary files a/.yarn/cache/stable-npm-0.1.8-feb4e06de8-2ff482bb10.zip and /dev/null differ diff --git a/.yarn/cache/string-natural-compare-npm-2.0.3-9ad7314e5b-e0f22bb0de.zip b/.yarn/cache/string-natural-compare-npm-2.0.3-9ad7314e5b-e0f22bb0de.zip deleted file mode 100644 index 435dd4b433f..00000000000 Binary files a/.yarn/cache/string-natural-compare-npm-2.0.3-9ad7314e5b-e0f22bb0de.zip and /dev/null differ diff --git a/.yarn/cache/string-width-npm-4.2.3-2c27177bae-e52c10dc3f.zip b/.yarn/cache/string-width-npm-4.2.3-2c27177bae-e52c10dc3f.zip deleted file mode 100644 index 9b4c088118f..00000000000 Binary files a/.yarn/cache/string-width-npm-4.2.3-2c27177bae-e52c10dc3f.zip and /dev/null differ diff --git a/.yarn/cache/string.prototype.trimend-npm-1.0.4-a656b8fe24-17e5aa45c3.zip b/.yarn/cache/string.prototype.trimend-npm-1.0.4-a656b8fe24-17e5aa45c3.zip deleted file mode 100644 index 3a6cb8db614..00000000000 Binary files a/.yarn/cache/string.prototype.trimend-npm-1.0.4-a656b8fe24-17e5aa45c3.zip and /dev/null differ diff --git a/.yarn/cache/string.prototype.trimstart-npm-1.0.4-b31f5e7c85-3fb06818d3.zip b/.yarn/cache/string.prototype.trimstart-npm-1.0.4-b31f5e7c85-3fb06818d3.zip deleted file mode 100644 index 477439a7209..00000000000 Binary files a/.yarn/cache/string.prototype.trimstart-npm-1.0.4-b31f5e7c85-3fb06818d3.zip and /dev/null differ diff --git a/.yarn/cache/string_decoder-npm-1.3.0-2422117fd0-8417646695.zip b/.yarn/cache/string_decoder-npm-1.3.0-2422117fd0-8417646695.zip deleted file mode 100644 index e12cf759105..00000000000 Binary files a/.yarn/cache/string_decoder-npm-1.3.0-2422117fd0-8417646695.zip and /dev/null differ diff --git a/.yarn/cache/strip-ansi-npm-6.0.1-caddc7cb40-f3cd25890a.zip b/.yarn/cache/strip-ansi-npm-6.0.1-caddc7cb40-f3cd25890a.zip deleted file mode 100644 index 1a63f3baa20..00000000000 Binary files a/.yarn/cache/strip-ansi-npm-6.0.1-caddc7cb40-f3cd25890a.zip and /dev/null differ diff --git a/.yarn/cache/strip-bom-npm-3.0.0-71e8f81ff9-8d50ff27b7.zip b/.yarn/cache/strip-bom-npm-3.0.0-71e8f81ff9-8d50ff27b7.zip deleted file mode 100644 index e6e88c61081..00000000000 Binary files a/.yarn/cache/strip-bom-npm-3.0.0-71e8f81ff9-8d50ff27b7.zip and /dev/null differ diff --git a/.yarn/cache/strip-final-newline-npm-2.0.0-340c4f7c66-69412b5e25.zip b/.yarn/cache/strip-final-newline-npm-2.0.0-340c4f7c66-69412b5e25.zip deleted file mode 100644 index 92534423478..00000000000 Binary files a/.yarn/cache/strip-final-newline-npm-2.0.0-340c4f7c66-69412b5e25.zip and /dev/null differ diff --git a/.yarn/cache/strip-json-comments-npm-3.1.1-dcb2324823-492f73e272.zip b/.yarn/cache/strip-json-comments-npm-3.1.1-dcb2324823-492f73e272.zip deleted file mode 100644 index e74ed10a6fa..00000000000 Binary files a/.yarn/cache/strip-json-comments-npm-3.1.1-dcb2324823-492f73e272.zip and /dev/null differ diff --git a/.yarn/cache/supports-color-npm-5.5.0-183ac537bc-95f6f4ba5a.zip b/.yarn/cache/supports-color-npm-5.5.0-183ac537bc-95f6f4ba5a.zip deleted file mode 100644 index aa46b9881db..00000000000 Binary files a/.yarn/cache/supports-color-npm-5.5.0-183ac537bc-95f6f4ba5a.zip and /dev/null differ diff --git a/.yarn/cache/supports-color-npm-7.2.0-606bfcf7da-3dda818de0.zip b/.yarn/cache/supports-color-npm-7.2.0-606bfcf7da-3dda818de0.zip deleted file mode 100644 index 1fd9e12d4ec..00000000000 Binary files a/.yarn/cache/supports-color-npm-7.2.0-606bfcf7da-3dda818de0.zip and /dev/null differ diff --git a/.yarn/cache/supports-color-npm-8.1.1-289e937149-c052193a7e.zip b/.yarn/cache/supports-color-npm-8.1.1-289e937149-c052193a7e.zip deleted file mode 100644 index 3fd0d6c6a42..00000000000 Binary files a/.yarn/cache/supports-color-npm-8.1.1-289e937149-c052193a7e.zip and /dev/null differ diff --git a/.yarn/cache/supports-preserve-symlinks-flag-npm-1.0.0-f17c4d0028-53b1e247e6.zip b/.yarn/cache/supports-preserve-symlinks-flag-npm-1.0.0-f17c4d0028-53b1e247e6.zip deleted file mode 100644 index 07a2c831552..00000000000 Binary files a/.yarn/cache/supports-preserve-symlinks-flag-npm-1.0.0-f17c4d0028-53b1e247e6.zip and /dev/null differ diff --git a/.yarn/cache/svgo-npm-2.8.0-43b4f3debe-b92f71a854.zip b/.yarn/cache/svgo-npm-2.8.0-43b4f3debe-b92f71a854.zip deleted file mode 100644 index b22a605fa59..00000000000 Binary files a/.yarn/cache/svgo-npm-2.8.0-43b4f3debe-b92f71a854.zip and /dev/null differ diff --git a/.yarn/cache/tar-npm-6.1.11-e6ac3cba9c-a04c07bb9e.zip b/.yarn/cache/tar-npm-6.1.11-e6ac3cba9c-a04c07bb9e.zip deleted file mode 100644 index d4e5d8f310b..00000000000 Binary files a/.yarn/cache/tar-npm-6.1.11-e6ac3cba9c-a04c07bb9e.zip and /dev/null differ diff --git a/.yarn/cache/term-size-npm-2.2.1-77ce7141d0-1ed9813354.zip b/.yarn/cache/term-size-npm-2.2.1-77ce7141d0-1ed9813354.zip deleted file mode 100644 index 062b405ad7a..00000000000 Binary files a/.yarn/cache/term-size-npm-2.2.1-77ce7141d0-1ed9813354.zip and /dev/null differ diff --git a/.yarn/cache/terser-npm-5.13.1-c7df10bd07-0b1f5043cf.zip b/.yarn/cache/terser-npm-5.13.1-c7df10bd07-0b1f5043cf.zip deleted file mode 100644 index b8f30c7effb..00000000000 Binary files a/.yarn/cache/terser-npm-5.13.1-c7df10bd07-0b1f5043cf.zip and /dev/null differ diff --git a/.yarn/cache/test-exclude-npm-6.0.0-3fb03d69df-3b34a3d771.zip b/.yarn/cache/test-exclude-npm-6.0.0-3fb03d69df-3b34a3d771.zip deleted file mode 100644 index 00b9c4c041c..00000000000 Binary files a/.yarn/cache/test-exclude-npm-6.0.0-3fb03d69df-3b34a3d771.zip and /dev/null differ diff --git a/.yarn/cache/text-table-npm-0.2.0-d92a778b59-b6937a38c8.zip b/.yarn/cache/text-table-npm-0.2.0-d92a778b59-b6937a38c8.zip deleted file mode 100644 index 08df4834d08..00000000000 Binary files a/.yarn/cache/text-table-npm-0.2.0-d92a778b59-b6937a38c8.zip and /dev/null differ diff --git a/.yarn/cache/throttleit-npm-1.0.0-6cbcfe7b7b-1b2db4d245.zip b/.yarn/cache/throttleit-npm-1.0.0-6cbcfe7b7b-1b2db4d245.zip deleted file mode 100644 index f020328c0c4..00000000000 Binary files a/.yarn/cache/throttleit-npm-1.0.0-6cbcfe7b7b-1b2db4d245.zip and /dev/null differ diff --git a/.yarn/cache/through-npm-2.3.8-df5f72a16e-a38c3e0598.zip b/.yarn/cache/through-npm-2.3.8-df5f72a16e-a38c3e0598.zip deleted file mode 100644 index 425b87ec87d..00000000000 Binary files a/.yarn/cache/through-npm-2.3.8-df5f72a16e-a38c3e0598.zip and /dev/null differ diff --git a/.yarn/cache/timsort-npm-0.3.0-868a28166c-1a66cb897d.zip b/.yarn/cache/timsort-npm-0.3.0-868a28166c-1a66cb897d.zip deleted file mode 100644 index 638b46bd1bb..00000000000 Binary files a/.yarn/cache/timsort-npm-0.3.0-868a28166c-1a66cb897d.zip and /dev/null differ diff --git a/.yarn/cache/tinypool-npm-0.2.4-1940a28d43-f050bd36c8.zip b/.yarn/cache/tinypool-npm-0.2.4-1940a28d43-f050bd36c8.zip deleted file mode 100644 index 1adf2233ef8..00000000000 Binary files a/.yarn/cache/tinypool-npm-0.2.4-1940a28d43-f050bd36c8.zip and /dev/null differ diff --git a/.yarn/cache/tinyspy-npm-1.0.0-6b0cbea3cc-f9a7cea406.zip b/.yarn/cache/tinyspy-npm-1.0.0-6b0cbea3cc-f9a7cea406.zip deleted file mode 100644 index 0c7877e2e3e..00000000000 Binary files a/.yarn/cache/tinyspy-npm-1.0.0-6b0cbea3cc-f9a7cea406.zip and /dev/null differ diff --git a/.yarn/cache/tmp-npm-0.2.1-a9c8d9c0ca-8b12146541.zip b/.yarn/cache/tmp-npm-0.2.1-a9c8d9c0ca-8b12146541.zip deleted file mode 100644 index d47a2298adf..00000000000 Binary files a/.yarn/cache/tmp-npm-0.2.1-a9c8d9c0ca-8b12146541.zip and /dev/null differ diff --git a/.yarn/cache/to-fast-properties-npm-2.0.0-0dc60cc481-be2de62fe5.zip b/.yarn/cache/to-fast-properties-npm-2.0.0-0dc60cc481-be2de62fe5.zip deleted file mode 100644 index bed5e126bb7..00000000000 Binary files a/.yarn/cache/to-fast-properties-npm-2.0.0-0dc60cc481-be2de62fe5.zip and /dev/null differ diff --git a/.yarn/cache/to-regex-range-npm-5.0.1-f1e8263b00-f76fa01b3d.zip b/.yarn/cache/to-regex-range-npm-5.0.1-f1e8263b00-f76fa01b3d.zip deleted file mode 100644 index acdc9630b7f..00000000000 Binary files a/.yarn/cache/to-regex-range-npm-5.0.1-f1e8263b00-f76fa01b3d.zip and /dev/null differ diff --git a/.yarn/cache/token-stream-npm-1.0.0-b6bc01bff8-e8adb56f31.zip b/.yarn/cache/token-stream-npm-1.0.0-b6bc01bff8-e8adb56f31.zip deleted file mode 100644 index cd25a4da1ea..00000000000 Binary files a/.yarn/cache/token-stream-npm-1.0.0-b6bc01bff8-e8adb56f31.zip and /dev/null differ diff --git a/.yarn/cache/tough-cookie-npm-2.5.0-79a2fe43fe-16a8cd0902.zip b/.yarn/cache/tough-cookie-npm-2.5.0-79a2fe43fe-16a8cd0902.zip deleted file mode 100644 index 74e27e7464c..00000000000 Binary files a/.yarn/cache/tough-cookie-npm-2.5.0-79a2fe43fe-16a8cd0902.zip and /dev/null differ diff --git a/.yarn/cache/tr46-npm-1.0.1-9547f343a4-96d4ed46bc.zip b/.yarn/cache/tr46-npm-1.0.1-9547f343a4-96d4ed46bc.zip deleted file mode 100644 index 3130815a0d1..00000000000 Binary files a/.yarn/cache/tr46-npm-1.0.1-9547f343a4-96d4ed46bc.zip and /dev/null differ diff --git a/.yarn/cache/treemate-npm-0.3.11-7be66c23fc-0c6ccbc6c5.zip b/.yarn/cache/treemate-npm-0.3.11-7be66c23fc-0c6ccbc6c5.zip deleted file mode 100644 index 1722c4669b7..00000000000 Binary files a/.yarn/cache/treemate-npm-0.3.11-7be66c23fc-0c6ccbc6c5.zip and /dev/null differ diff --git a/.yarn/cache/tsconfig-paths-npm-3.14.1-17a815b5c5-8afa01c673.zip b/.yarn/cache/tsconfig-paths-npm-3.14.1-17a815b5c5-8afa01c673.zip deleted file mode 100644 index 98a7ab1f879..00000000000 Binary files a/.yarn/cache/tsconfig-paths-npm-3.14.1-17a815b5c5-8afa01c673.zip and /dev/null differ diff --git a/.yarn/cache/tslib-npm-2.4.0-9cb6dc5030-8c4aa6a3c5.zip b/.yarn/cache/tslib-npm-2.4.0-9cb6dc5030-8c4aa6a3c5.zip deleted file mode 100644 index cf5fce16fdc..00000000000 Binary files a/.yarn/cache/tslib-npm-2.4.0-9cb6dc5030-8c4aa6a3c5.zip and /dev/null differ diff --git a/.yarn/cache/tunnel-agent-npm-0.6.0-64345ab7eb-05f6510358.zip b/.yarn/cache/tunnel-agent-npm-0.6.0-64345ab7eb-05f6510358.zip deleted file mode 100644 index 5256e200850..00000000000 Binary files a/.yarn/cache/tunnel-agent-npm-0.6.0-64345ab7eb-05f6510358.zip and /dev/null differ diff --git a/.yarn/cache/tweetnacl-npm-0.14.5-a3f766c0d1-6061daba17.zip b/.yarn/cache/tweetnacl-npm-0.14.5-a3f766c0d1-6061daba17.zip deleted file mode 100644 index 2811987dbb0..00000000000 Binary files a/.yarn/cache/tweetnacl-npm-0.14.5-a3f766c0d1-6061daba17.zip and /dev/null differ diff --git a/.yarn/cache/type-check-npm-0.4.0-60565800ce-ec688ebfc9.zip b/.yarn/cache/type-check-npm-0.4.0-60565800ce-ec688ebfc9.zip deleted file mode 100644 index 85a029590ea..00000000000 Binary files a/.yarn/cache/type-check-npm-0.4.0-60565800ce-ec688ebfc9.zip and /dev/null differ diff --git a/.yarn/cache/type-detect-npm-4.0.8-8d8127b901-62b5628bff.zip b/.yarn/cache/type-detect-npm-4.0.8-8d8127b901-62b5628bff.zip deleted file mode 100644 index a3c01d86ab4..00000000000 Binary files a/.yarn/cache/type-detect-npm-4.0.8-8d8127b901-62b5628bff.zip and /dev/null differ diff --git a/.yarn/cache/type-fest-npm-0.20.2-b36432617f-4fb3272df2.zip b/.yarn/cache/type-fest-npm-0.20.2-b36432617f-4fb3272df2.zip deleted file mode 100644 index 8222fdcc36f..00000000000 Binary files a/.yarn/cache/type-fest-npm-0.20.2-b36432617f-4fb3272df2.zip and /dev/null differ diff --git a/.yarn/cache/type-fest-npm-0.21.3-5ff2a9c6fd-e6b32a3b38.zip b/.yarn/cache/type-fest-npm-0.21.3-5ff2a9c6fd-e6b32a3b38.zip deleted file mode 100644 index 89f3fd57a9e..00000000000 Binary files a/.yarn/cache/type-fest-npm-0.21.3-5ff2a9c6fd-e6b32a3b38.zip and /dev/null differ diff --git a/.yarn/cache/unbox-primitive-npm-1.0.2-cb56a05066-b7a1cf5862.zip b/.yarn/cache/unbox-primitive-npm-1.0.2-cb56a05066-b7a1cf5862.zip deleted file mode 100644 index 7230bc69278..00000000000 Binary files a/.yarn/cache/unbox-primitive-npm-1.0.2-cb56a05066-b7a1cf5862.zip and /dev/null differ diff --git a/.yarn/cache/unique-filename-npm-1.1.1-c885c5095b-cf4998c922.zip b/.yarn/cache/unique-filename-npm-1.1.1-c885c5095b-cf4998c922.zip deleted file mode 100644 index 3187d5eba7e..00000000000 Binary files a/.yarn/cache/unique-filename-npm-1.1.1-c885c5095b-cf4998c922.zip and /dev/null differ diff --git a/.yarn/cache/unique-slug-npm-2.0.2-f6ba1ddeb7-5b6876a645.zip b/.yarn/cache/unique-slug-npm-2.0.2-f6ba1ddeb7-5b6876a645.zip deleted file mode 100644 index 060fb64cf94..00000000000 Binary files a/.yarn/cache/unique-slug-npm-2.0.2-f6ba1ddeb7-5b6876a645.zip and /dev/null differ diff --git a/.yarn/cache/universalify-npm-2.0.0-03b8b418a8-2406a4edf4.zip b/.yarn/cache/universalify-npm-2.0.0-03b8b418a8-2406a4edf4.zip deleted file mode 100644 index fa6b36b077a..00000000000 Binary files a/.yarn/cache/universalify-npm-2.0.0-03b8b418a8-2406a4edf4.zip and /dev/null differ diff --git a/.yarn/cache/untildify-npm-4.0.0-4a8b569825-39ced9c418.zip b/.yarn/cache/untildify-npm-4.0.0-4a8b569825-39ced9c418.zip deleted file mode 100644 index a88f9ac1d5c..00000000000 Binary files a/.yarn/cache/untildify-npm-4.0.0-4a8b569825-39ced9c418.zip and /dev/null differ diff --git a/.yarn/cache/uri-js-npm-4.4.1-66d11cbcaf-7167432de6.zip b/.yarn/cache/uri-js-npm-4.4.1-66d11cbcaf-7167432de6.zip deleted file mode 100644 index bd21deb73d1..00000000000 Binary files a/.yarn/cache/uri-js-npm-4.4.1-66d11cbcaf-7167432de6.zip and /dev/null differ diff --git a/.yarn/cache/util-deprecate-npm-1.0.2-e3fe1a219c-474acf1146.zip b/.yarn/cache/util-deprecate-npm-1.0.2-e3fe1a219c-474acf1146.zip deleted file mode 100644 index c2309cfe4d1..00000000000 Binary files a/.yarn/cache/util-deprecate-npm-1.0.2-e3fe1a219c-474acf1146.zip and /dev/null differ diff --git a/.yarn/cache/utility-types-npm-3.10.0-747e7c6549-8f274415c6.zip b/.yarn/cache/utility-types-npm-3.10.0-747e7c6549-8f274415c6.zip deleted file mode 100644 index 3fec72e0795..00000000000 Binary files a/.yarn/cache/utility-types-npm-3.10.0-747e7c6549-8f274415c6.zip and /dev/null differ diff --git a/.yarn/cache/uuid-npm-8.3.2-eca0baba53-5575a8a75c.zip b/.yarn/cache/uuid-npm-8.3.2-eca0baba53-5575a8a75c.zip deleted file mode 100644 index 9b583288f22..00000000000 Binary files a/.yarn/cache/uuid-npm-8.3.2-eca0baba53-5575a8a75c.zip and /dev/null differ diff --git a/.yarn/cache/v8-compile-cache-npm-2.3.0-961375f150-adb0a271ea.zip b/.yarn/cache/v8-compile-cache-npm-2.3.0-961375f150-adb0a271ea.zip deleted file mode 100644 index 0e04423cd8d..00000000000 Binary files a/.yarn/cache/v8-compile-cache-npm-2.3.0-961375f150-adb0a271ea.zip and /dev/null differ diff --git a/.yarn/cache/v8-to-istanbul-npm-9.0.1-58bbce7857-a49c34bf0a.zip b/.yarn/cache/v8-to-istanbul-npm-9.0.1-58bbce7857-a49c34bf0a.zip deleted file mode 100644 index 460a70b28f1..00000000000 Binary files a/.yarn/cache/v8-to-istanbul-npm-9.0.1-58bbce7857-a49c34bf0a.zip and /dev/null differ diff --git a/.yarn/cache/vdirs-npm-0.1.8-59a32a98d6-a7be8ccad3.zip b/.yarn/cache/vdirs-npm-0.1.8-59a32a98d6-a7be8ccad3.zip deleted file mode 100644 index db845417c20..00000000000 Binary files a/.yarn/cache/vdirs-npm-0.1.8-59a32a98d6-a7be8ccad3.zip and /dev/null differ diff --git a/.yarn/cache/verror-npm-1.10.0-c3f839c579-c431df0bed.zip b/.yarn/cache/verror-npm-1.10.0-c3f839c579-c431df0bed.zip deleted file mode 100644 index e81972bdea8..00000000000 Binary files a/.yarn/cache/verror-npm-1.10.0-c3f839c579-c431df0bed.zip and /dev/null differ diff --git a/.yarn/cache/vite-npm-2.9.14-6654defddb-f78b54f584.zip b/.yarn/cache/vite-npm-2.9.14-6654defddb-f78b54f584.zip deleted file mode 100644 index 62849512c4f..00000000000 Binary files a/.yarn/cache/vite-npm-2.9.14-6654defddb-f78b54f584.zip and /dev/null differ diff --git a/.yarn/cache/vite-npm-3.0.0-beta.10-1e22aa4d4f-2b27107dac.zip b/.yarn/cache/vite-npm-3.0.0-beta.10-1e22aa4d4f-2b27107dac.zip deleted file mode 100644 index 1db61067e93..00000000000 Binary files a/.yarn/cache/vite-npm-3.0.0-beta.10-1e22aa4d4f-2b27107dac.zip and /dev/null differ diff --git a/.yarn/cache/vitest-npm-0.18.1-e5f5447995-0d3a77625e.zip b/.yarn/cache/vitest-npm-0.18.1-e5f5447995-0d3a77625e.zip deleted file mode 100644 index cf42cd3ef12..00000000000 Binary files a/.yarn/cache/vitest-npm-0.18.1-e5f5447995-0d3a77625e.zip and /dev/null differ diff --git a/.yarn/cache/void-elements-npm-3.1.0-4f43780839-0390f81810.zip b/.yarn/cache/void-elements-npm-3.1.0-4f43780839-0390f81810.zip deleted file mode 100644 index afbaf50fe84..00000000000 Binary files a/.yarn/cache/void-elements-npm-3.1.0-4f43780839-0390f81810.zip and /dev/null differ diff --git a/.yarn/cache/vooks-npm-0.2.12-0d1a2d856b-e6841ec5b6.zip b/.yarn/cache/vooks-npm-0.2.12-0d1a2d856b-e6841ec5b6.zip deleted file mode 100644 index b1f3cc55e0a..00000000000 Binary files a/.yarn/cache/vooks-npm-0.2.12-0d1a2d856b-e6841ec5b6.zip and /dev/null differ diff --git a/.yarn/cache/vue-demi-npm-0.12.5-01b6b9fe36-40a0470cae.zip b/.yarn/cache/vue-demi-npm-0.12.5-01b6b9fe36-40a0470cae.zip deleted file mode 100644 index d6afb8a0ed6..00000000000 Binary files a/.yarn/cache/vue-demi-npm-0.12.5-01b6b9fe36-40a0470cae.zip and /dev/null differ diff --git a/.yarn/cache/vue-demi-npm-0.13.1-a467bc3a9a-d26b060258.zip b/.yarn/cache/vue-demi-npm-0.13.1-a467bc3a9a-d26b060258.zip deleted file mode 100644 index 570ed5bd38c..00000000000 Binary files a/.yarn/cache/vue-demi-npm-0.13.1-a467bc3a9a-d26b060258.zip and /dev/null differ diff --git a/.yarn/cache/vue-eslint-parser-npm-9.0.3-1d52721799-61248eb504.zip b/.yarn/cache/vue-eslint-parser-npm-9.0.3-1d52721799-61248eb504.zip deleted file mode 100644 index 175f3e88467..00000000000 Binary files a/.yarn/cache/vue-eslint-parser-npm-9.0.3-1d52721799-61248eb504.zip and /dev/null differ diff --git a/.yarn/cache/vue-npm-3.2.37-c15242c7af-cd20069c31.zip b/.yarn/cache/vue-npm-3.2.37-c15242c7af-cd20069c31.zip deleted file mode 100644 index c87566ca2a7..00000000000 Binary files a/.yarn/cache/vue-npm-3.2.37-c15242c7af-cd20069c31.zip and /dev/null differ diff --git a/.yarn/cache/vue-router-npm-4.1.2-fb1ea78cc7-f4b900f0db.zip b/.yarn/cache/vue-router-npm-4.1.2-fb1ea78cc7-f4b900f0db.zip deleted file mode 100644 index 7cb1233a728..00000000000 Binary files a/.yarn/cache/vue-router-npm-4.1.2-fb1ea78cc7-f4b900f0db.zip and /dev/null differ diff --git a/.yarn/cache/vueuc-npm-0.4.47-ad081ddd15-b82b77a882.zip b/.yarn/cache/vueuc-npm-0.4.47-ad081ddd15-b82b77a882.zip deleted file mode 100644 index 0a267b628a7..00000000000 Binary files a/.yarn/cache/vueuc-npm-0.4.47-ad081ddd15-b82b77a882.zip and /dev/null differ diff --git a/.yarn/cache/weak-lru-cache-npm-1.2.2-0dc8dfa322-0fbe16839d.zip b/.yarn/cache/weak-lru-cache-npm-1.2.2-0dc8dfa322-0fbe16839d.zip deleted file mode 100644 index 244c23edc97..00000000000 Binary files a/.yarn/cache/weak-lru-cache-npm-1.2.2-0dc8dfa322-0fbe16839d.zip and /dev/null differ diff --git a/.yarn/cache/webidl-conversions-npm-4.0.2-1d159e6409-c93d8dfe90.zip b/.yarn/cache/webidl-conversions-npm-4.0.2-1d159e6409-c93d8dfe90.zip deleted file mode 100644 index a75f5ee65fc..00000000000 Binary files a/.yarn/cache/webidl-conversions-npm-4.0.2-1d159e6409-c93d8dfe90.zip and /dev/null differ diff --git a/.yarn/cache/whatwg-url-npm-7.1.0-d6cae01571-fecb07c872.zip b/.yarn/cache/whatwg-url-npm-7.1.0-d6cae01571-fecb07c872.zip deleted file mode 100644 index 9f21814850a..00000000000 Binary files a/.yarn/cache/whatwg-url-npm-7.1.0-d6cae01571-fecb07c872.zip and /dev/null differ diff --git a/.yarn/cache/which-boxed-primitive-npm-1.0.2-e214f9ae5a-53ce774c73.zip b/.yarn/cache/which-boxed-primitive-npm-1.0.2-e214f9ae5a-53ce774c73.zip deleted file mode 100644 index fef0ce42437..00000000000 Binary files a/.yarn/cache/which-boxed-primitive-npm-1.0.2-e214f9ae5a-53ce774c73.zip and /dev/null differ diff --git a/.yarn/cache/which-npm-2.0.2-320ddf72f7-1a5c563d3c.zip b/.yarn/cache/which-npm-2.0.2-320ddf72f7-1a5c563d3c.zip deleted file mode 100644 index 389ec5e25ec..00000000000 Binary files a/.yarn/cache/which-npm-2.0.2-320ddf72f7-1a5c563d3c.zip and /dev/null differ diff --git a/.yarn/cache/wide-align-npm-1.1.5-889d77e592-d5fc37cd56.zip b/.yarn/cache/wide-align-npm-1.1.5-889d77e592-d5fc37cd56.zip deleted file mode 100644 index 4dc7fcc67a0..00000000000 Binary files a/.yarn/cache/wide-align-npm-1.1.5-889d77e592-d5fc37cd56.zip and /dev/null differ diff --git a/.yarn/cache/with-npm-7.0.2-135a242adb-a00fe87b73.zip b/.yarn/cache/with-npm-7.0.2-135a242adb-a00fe87b73.zip deleted file mode 100644 index c96481262e8..00000000000 Binary files a/.yarn/cache/with-npm-7.0.2-135a242adb-a00fe87b73.zip and /dev/null differ diff --git a/.yarn/cache/word-wrap-npm-1.2.3-7fb15ab002-30b48f91fc.zip b/.yarn/cache/word-wrap-npm-1.2.3-7fb15ab002-30b48f91fc.zip deleted file mode 100644 index 518977eb886..00000000000 Binary files a/.yarn/cache/word-wrap-npm-1.2.3-7fb15ab002-30b48f91fc.zip and /dev/null differ diff --git a/.yarn/cache/wrap-ansi-npm-6.2.0-439a7246d8-6cd96a4101.zip b/.yarn/cache/wrap-ansi-npm-6.2.0-439a7246d8-6cd96a4101.zip deleted file mode 100644 index aa06055f0b7..00000000000 Binary files a/.yarn/cache/wrap-ansi-npm-6.2.0-439a7246d8-6cd96a4101.zip and /dev/null differ diff --git a/.yarn/cache/wrap-ansi-npm-7.0.0-ad6e1a0554-a790b846fd.zip b/.yarn/cache/wrap-ansi-npm-7.0.0-ad6e1a0554-a790b846fd.zip deleted file mode 100644 index ab6ea6e871e..00000000000 Binary files a/.yarn/cache/wrap-ansi-npm-7.0.0-ad6e1a0554-a790b846fd.zip and /dev/null differ diff --git a/.yarn/cache/wrappy-npm-1.0.2-916de4d4b3-159da4805f.zip b/.yarn/cache/wrappy-npm-1.0.2-916de4d4b3-159da4805f.zip deleted file mode 100644 index 6072a9f2e72..00000000000 Binary files a/.yarn/cache/wrappy-npm-1.0.2-916de4d4b3-159da4805f.zip and /dev/null differ diff --git a/.yarn/cache/xml-name-validator-npm-4.0.0-0857c21729-af100b79c2.zip b/.yarn/cache/xml-name-validator-npm-4.0.0-0857c21729-af100b79c2.zip deleted file mode 100644 index abb3efef257..00000000000 Binary files a/.yarn/cache/xml-name-validator-npm-4.0.0-0857c21729-af100b79c2.zip and /dev/null differ diff --git a/.yarn/cache/xxhash-wasm-npm-0.4.2-afa0b23648-747b32fcfe.zip b/.yarn/cache/xxhash-wasm-npm-0.4.2-afa0b23648-747b32fcfe.zip deleted file mode 100644 index a90fbb34f70..00000000000 Binary files a/.yarn/cache/xxhash-wasm-npm-0.4.2-afa0b23648-747b32fcfe.zip and /dev/null differ diff --git a/.yarn/cache/y18n-npm-5.0.8-5f3a0a7e62-54f0fb9562.zip b/.yarn/cache/y18n-npm-5.0.8-5f3a0a7e62-54f0fb9562.zip deleted file mode 100644 index bf39a466ce0..00000000000 Binary files a/.yarn/cache/y18n-npm-5.0.8-5f3a0a7e62-54f0fb9562.zip and /dev/null differ diff --git a/.yarn/cache/yallist-npm-4.0.0-b493d9e907-343617202a.zip b/.yarn/cache/yallist-npm-4.0.0-b493d9e907-343617202a.zip deleted file mode 100644 index f2d3306fed7..00000000000 Binary files a/.yarn/cache/yallist-npm-4.0.0-b493d9e907-343617202a.zip and /dev/null differ diff --git a/.yarn/cache/yaml-npm-1.10.2-0e780aebdf-ce4ada136e.zip b/.yarn/cache/yaml-npm-1.10.2-0e780aebdf-ce4ada136e.zip deleted file mode 100644 index bb28507cd0f..00000000000 Binary files a/.yarn/cache/yaml-npm-1.10.2-0e780aebdf-ce4ada136e.zip and /dev/null differ diff --git a/.yarn/cache/yargs-npm-16.2.0-547873d425-b14afbb51e.zip b/.yarn/cache/yargs-npm-16.2.0-547873d425-b14afbb51e.zip deleted file mode 100644 index d11c27d5104..00000000000 Binary files a/.yarn/cache/yargs-npm-16.2.0-547873d425-b14afbb51e.zip and /dev/null differ diff --git a/.yarn/cache/yargs-parser-npm-20.2.9-a1d19e598d-8bb69015f2.zip b/.yarn/cache/yargs-parser-npm-20.2.9-a1d19e598d-8bb69015f2.zip deleted file mode 100644 index f230038cfc2..00000000000 Binary files a/.yarn/cache/yargs-parser-npm-20.2.9-a1d19e598d-8bb69015f2.zip and /dev/null differ diff --git a/.yarn/cache/yauzl-npm-2.10.0-72e70ea021-7f21fe0bba.zip b/.yarn/cache/yauzl-npm-2.10.0-72e70ea021-7f21fe0bba.zip deleted file mode 100644 index 7a5f10caf5d..00000000000 Binary files a/.yarn/cache/yauzl-npm-2.10.0-72e70ea021-7f21fe0bba.zip and /dev/null differ diff --git a/.yarn/cache/yocto-queue-npm-0.1.0-c6c9a7db29-f77b3d8d00.zip b/.yarn/cache/yocto-queue-npm-0.1.0-c6c9a7db29-f77b3d8d00.zip deleted file mode 100644 index f56730df001..00000000000 Binary files a/.yarn/cache/yocto-queue-npm-0.1.0-c6c9a7db29-f77b3d8d00.zip and /dev/null differ diff --git a/.yarn/cache/zxcvbn-npm-4.4.2-6527983856-76ab32c066.zip b/.yarn/cache/zxcvbn-npm-4.4.2-6527983856-76ab32c066.zip deleted file mode 100644 index 6147b3b3308..00000000000 Binary files a/.yarn/cache/zxcvbn-npm-4.4.2-6527983856-76ab32c066.zip and /dev/null differ diff --git a/.yarn/plugins/@yarnpkg/plugin-interactive-tools.cjs b/.yarn/plugins/@yarnpkg/plugin-interactive-tools.cjs deleted file mode 100644 index 8d3e2a39b7a..00000000000 --- a/.yarn/plugins/@yarnpkg/plugin-interactive-tools.cjs +++ /dev/null @@ -1,546 +0,0 @@ -/* eslint-disable */ -//prettier-ignore -module.exports = { -name: "@yarnpkg/plugin-interactive-tools", -factory: function (require) { -var plugin=(()=>{var $P=Object.create,Py=Object.defineProperty,eI=Object.defineProperties,tI=Object.getOwnPropertyDescriptor,nI=Object.getOwnPropertyDescriptors,rI=Object.getOwnPropertyNames,L_=Object.getOwnPropertySymbols,iI=Object.getPrototypeOf,rD=Object.prototype.hasOwnProperty,sS=Object.prototype.propertyIsEnumerable;var aS=(i,o,a)=>o in i?Py(i,o,{enumerable:!0,configurable:!0,writable:!0,value:a}):i[o]=a,qt=(i,o)=>{for(var a in o||(o={}))rD.call(o,a)&&aS(i,a,o[a]);if(L_)for(var a of L_(o))sS.call(o,a)&&aS(i,a,o[a]);return i},Zr=(i,o)=>eI(i,nI(o)),uI=i=>Py(i,"__esModule",{value:!0});var wl=(i,o)=>{var a={};for(var c in i)rD.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&&sS.call(i,c)&&(a[c]=i[c]);return a};var Ke=(i,o)=>()=>(o||i((o={exports:{}}).exports,o),o.exports),oI=(i,o)=>{for(var a in o)Py(i,a,{get:o[a],enumerable:!0})},lI=(i,o,a)=>{if(o&&typeof o=="object"||typeof o=="function")for(let c of rI(o))!rD.call(i,c)&&c!=="default"&&Py(i,c,{get:()=>o[c],enumerable:!(a=tI(o,c))||a.enumerable});return i},ou=i=>lI(uI(Py(i!=null?$P(iI(i)):{},"default",i&&i.__esModule&&"default"in i?{get:()=>i.default,enumerable:!0}:{value:i,enumerable:!0})),i);var Iy=Ke((mW,fS)=>{"use strict";var cS=Object.getOwnPropertySymbols,sI=Object.prototype.hasOwnProperty,aI=Object.prototype.propertyIsEnumerable;function fI(i){if(i==null)throw new TypeError("Object.assign cannot be called with null or undefined");return Object(i)}function cI(){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}}fS.exports=cI()?Object.assign:function(i,o){for(var a,c=fI(i),_,t=1;t{"use strict";var iD=Iy(),$f=typeof Symbol=="function"&&Symbol.for,by=$f?Symbol.for("react.element"):60103,dI=$f?Symbol.for("react.portal"):60106,pI=$f?Symbol.for("react.fragment"):60107,hI=$f?Symbol.for("react.strict_mode"):60108,vI=$f?Symbol.for("react.profiler"):60114,mI=$f?Symbol.for("react.provider"):60109,yI=$f?Symbol.for("react.context"):60110,gI=$f?Symbol.for("react.forward_ref"):60112,_I=$f?Symbol.for("react.suspense"):60113,EI=$f?Symbol.for("react.memo"):60115,DI=$f?Symbol.for("react.lazy"):60116,dS=typeof Symbol=="function"&&Symbol.iterator;function By(i){for(var o="https://reactjs.org/docs/error-decoder.html?invariant="+i,a=1;aN_.length&&N_.push(i)}function aD(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 by:case dI:t=!0}}if(t)return a(c,i,o===""?"."+fD(i,0):o),1;if(t=0,o=o===""?".":o+":",Array.isArray(i))for(var M=0;M{"use strict";var RI="SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED";TS.exports=RI});var hD=Ke((_W,xS)=>{"use strict";var pD=function(){};process.env.NODE_ENV!=="production"&&(RS=CS(),F_={},AS=Function.call.bind(Object.prototype.hasOwnProperty),pD=function(i){var o="Warning: "+i;typeof console!="undefined"&&console.error(o);try{throw new Error(o)}catch(a){}});var RS,F_,AS;function OS(i,o,a,c,_){if(process.env.NODE_ENV!=="production"){for(var t in i)if(AS(i,t)){var M;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}M=i[t](o,t,c,a,null,RS)}catch(T){M=T}if(M&&!(M instanceof Error)&&pD((c||"React class")+": type specification of "+a+" `"+t+"` is invalid; the type checker function must return `null` or an `Error` but returned a "+typeof M+". You may have forgotten to pass an argument to the type checker creator (arrayOf, instanceOf, objectOf, oneOf, oneOfType, and shape all require an argument)."),M instanceof Error&&!(M.message in F_)){F_[M.message]=!0;var O=_?_():"";pD("Failed "+a+" type: "+M.message+(O!=null?O:""))}}}}OS.resetWarningCache=function(){process.env.NODE_ENV!=="production"&&(F_={})};xS.exports=OS});var MS=Ke(Eu=>{"use strict";process.env.NODE_ENV!=="production"&&function(){"use strict";var i=Iy(),o=hD(),a="16.13.1",c=typeof Symbol=="function"&&Symbol.for,_=c?Symbol.for("react.element"):60103,t=c?Symbol.for("react.portal"):60106,M=c?Symbol.for("react.fragment"):60107,N=c?Symbol.for("react.strict_mode"):60108,O=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,pe=c?Symbol.for("react.memo"):60115,ge=c?Symbol.for("react.lazy"):60116,ve=c?Symbol.for("react.block"):60121,ue=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,re="@@iterator";function we(Q){if(Q===null||typeof Q!="object")return null;var Se=me&&Q[me]||Q[re];return typeof Se=="function"?Se:null}var Ie={current:null},je={suspense:null},ct={current:null},pt=/^(.*)[\\\/]/;function Xe(Q,Se,Ne){var Le="";if(Se){var ht=Se.fileName,Yn=ht.replace(pt,"");if(/^index\./.test(Yn)){var Cn=ht.match(pt);if(Cn){var cr=Cn[1];if(cr){var Si=cr.replace(pt,"");Yn=Si+"/"+Yn}}}Le=" (at "+Yn+":"+Se.lineNumber+")"}else Ne&&(Le=" (created by "+Ne+")");return` - in `+(Q||"Unknown")+Le}var tt=1;function He(Q){return Q._status===tt?Q._result:null}function kt(Q,Se,Ne){var Le=Se.displayName||Se.name||"";return Q.displayName||(Le!==""?Ne+"("+Le+")":Ne)}function zt(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 M:return"Fragment";case t:return"Portal";case O: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 kt(Q,Q.render,"ForwardRef");case pe:return zt(Q.type);case ve:return zt(Q.render);case ge:{var Se=Q,Ne=He(Se);if(Ne)return zt(Ne);break}}return null}var nt={},X=null;function fe(Q){X=Q}nt.getCurrentStack=null,nt.getStackAddendum=function(){var Q="";if(X){var Se=zt(X.type),Ne=X._owner;Q+=Xe(Se,X._source,Ne&&zt(Ne.type))}var Le=nt.getCurrentStack;return Le&&(Q+=Le()||""),Q};var xe={current:!1},le={ReactCurrentDispatcher:Ie,ReactCurrentBatchConfig:je,ReactCurrentOwner:ct,IsSomeRendererActing:xe,assign:i};i(le,{ReactDebugCurrentFrame:nt,ReactComponentTreeHook:{}});function qe(Q){{for(var Se=arguments.length,Ne=new Array(Se>1?Se-1:0),Le=1;Le1?Se-1:0),Le=1;Le0&&typeof Ne[Ne.length-1]=="string"&&Ne[Ne.length-1].indexOf(` - in`)===0;if(!Le){var ht=le.ReactDebugCurrentFrame,Yn=ht.getStackAddendum();Yn!==""&&(Se+="%s",Ne=Ne.concat([Yn]))}var Cn=Ne.map(function(Mu){return""+Mu});Cn.unshift("Warning: "+Se),Function.prototype.apply.call(console[Q],console,Cn);try{var cr=0,Si="Warning: "+Se.replace(/%s/g,function(){return Ne[cr++]});throw new Error(Si)}catch(Mu){}}}var nn={};function an(Q,Se){{var Ne=Q.constructor,Le=Ne&&(Ne.displayName||Ne.name)||"ReactClass",ht=Le+"."+Se;if(nn[ht])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.",Se,Le),nn[ht]=!0}}var Mn={isMounted:function(Q){return!1},enqueueForceUpdate:function(Q,Se,Ne){an(Q,"forceUpdate")},enqueueReplaceState:function(Q,Se,Ne,Le){an(Q,"replaceState")},enqueueSetState:function(Q,Se,Ne,Le){an(Q,"setState")}},lr={};Object.freeze(lr);function ln(Q,Se,Ne){this.props=Q,this.context=Se,this.refs=lr,this.updater=Ne||Mn}ln.prototype.isReactComponent={},ln.prototype.setState=function(Q,Se){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,Se,"setState")},ln.prototype.forceUpdate=function(Q){this.updater.enqueueForceUpdate(this,Q,"forceUpdate")};{var Gt={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)."]},Er=function(Q,Se){Object.defineProperty(ln.prototype,Q,{get:function(){qe("%s(...) is deprecated in plain JavaScript React classes. %s",Se[0],Se[1])}})};for(var w in Gt)Gt.hasOwnProperty(w)&&Er(w,Gt[w])}function jt(){}jt.prototype=ln.prototype;function Xn(Q,Se,Ne){this.props=Q,this.context=Se,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,po;po={};function A0(Q){if(fr.call(Q,"ref")){var Se=Object.getOwnPropertyDescriptor(Q,"ref").get;if(Se&&Se.isReactWarning)return!1}return Q.ref!==void 0}function J0(Q){if(fr.call(Q,"key")){var Se=Object.getOwnPropertyDescriptor(Q,"key").get;if(Se&&Se.isReactWarning)return!1}return Q.key!==void 0}function Ps(Q,Se){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)",Se))};Ne.isReactWarning=!0,Object.defineProperty(Q,"key",{get:Ne,configurable:!0})}function Z0(Q,Se){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)",Se))};Ne.isReactWarning=!0,Object.defineProperty(Q,"ref",{get:Ne,configurable:!0})}function $0(Q){if(typeof Q.ref=="string"&&ct.current&&Q.__self&&ct.current.stateNode!==Q.__self){var Se=zt(ct.current.type);po[Se]||(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',zt(ct.current.type),Q.ref),po[Se]=!0)}}var Wt=function(Q,Se,Ne,Le,ht,Yn,Cn){var cr={$$typeof:_,type:Q,key:Se,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:ht}),Object.freeze&&(Object.freeze(cr.props),Object.freeze(cr)),cr};function xi(Q,Se,Ne){var Le,ht={},Yn=null,Cn=null,cr=null,Si=null;if(Se!=null){A0(Se)&&(Cn=Se.ref,$0(Se)),J0(Se)&&(Yn=""+Se.key),cr=Se.__self===void 0?null:Se.__self,Si=Se.__source===void 0?null:Se.__source;for(Le in Se)fr.call(Se,Le)&&!zr.hasOwnProperty(Le)&&(ht[Le]=Se[Le])}var Mu=arguments.length-2;if(Mu===1)ht.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 Vt(Q){var Se={$$typeof:ge,_ctor:Q,_status:-1,_result:null};{var Ne,Le;Object.defineProperties(Se,{defaultProps:{configurable:!0,get:function(){return Ne},set:function(ht){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=ht,Object.defineProperty(Se,"defaultProps",{enumerable:!0})}},propTypes:{configurable:!0,get:function(){return Le},set:function(ht){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=ht,Object.defineProperty(Se,"propTypes",{enumerable:!0})}}})}return Se}function Au(Q){return Q!=null&&Q.$$typeof===pe?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===M||Q===H||Q===O||Q===N||Q===ne||Q===m||typeof Q=="object"&&Q!==null&&(Q.$$typeof===ge||Q.$$typeof===pe||Q.$$typeof===T||Q.$$typeof===B||Q.$$typeof===q||Q.$$typeof===ue||Q.$$typeof===_e||Q.$$typeof===ce||Q.$$typeof===ve)}function Jo(Q,Se){return eu(Q)||dt("memo: The first argument must be a component. Instead received: %s",Q===null?"null":typeof Q),{$$typeof:pe,type:Q,compare:Se===void 0?null:Se}}function Yi(){var Q=Ie.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,Se){var Ne=Yi();if(Se!==void 0&&dt("useContext() second argument is reserved for future use in React. Passing it is not supported. You passed: %s.%s",Se,typeof Se=="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,Se)}function k0(Q){var Se=Yi();return Se.useState(Q)}function ai(Q,Se,Ne){var Le=Yi();return Le.useReducer(Q,Se,Ne)}function f0(Q){var Se=Yi();return Se.useRef(Q)}function Jl(Q,Se){var Ne=Yi();return Ne.useEffect(Q,Se)}function L0(Q,Se){var Ne=Yi();return Ne.useLayoutEffect(Q,Se)}function bs(Q,Se){var Ne=Yi();return Ne.useCallback(Q,Se)}function $n(Q,Se){var Ne=Yi();return Ne.useMemo(Q,Se)}function tl(Q,Se,Ne){var Le=Yi();return Le.useImperativeHandle(Q,Se,Ne)}function c0(Q,Se){{var Ne=Yi();return Ne.useDebugValue(Q,Se)}}var bo;bo=!1;function Sl(){if(ct.current){var Q=zt(ct.current.type);if(Q)return` - -Check the render method of \``+Q+"`."}return""}function N0(Q){if(Q!==void 0){var Se=Q.fileName.replace(/^.*[\\\/]/,""),Ne=Q.lineNumber;return` - -Check your code at `+Se+":"+Ne+"."}return""}function wt(Q){return Q!=null?N0(Q.__source):""}var bt={};function Hn(Q){var Se=Sl();if(!Se){var Ne=typeof Q=="string"?Q:Q.displayName||Q.name;Ne&&(Se=` - -Check the top-level render call using <`+Ne+">.")}return Se}function qr(Q,Se){if(!(!Q._store||Q._store.validated||Q.key!=null)){Q._store.validated=!0;var Ne=Hn(Se);if(!bt[Ne]){bt[Ne]=!0;var Le="";Q&&Q._owner&&Q._owner!==ct.current&&(Le=" It was passed a child from "+zt(Q._owner.type)+"."),fe(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),fe(null)}}}function Ki(Q,Se){if(typeof Q=="object"){if(Array.isArray(Q))for(var Ne=0;Ne",ht=" 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,ht)}var cr=xi.apply(this,arguments);if(cr==null)return cr;if(Le)for(var Si=2;Si{"use strict";process.env.NODE_ENV==="production"?vD.exports=SS():vD.exports=MS()});var kS=Ke((Wv,Uy)=>{(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`",M="__lodash_hash_undefined__",N=500,O="__lodash_placeholder__",T=1,B=2,H=4,q=1,ne=2,m=1,pe=2,ge=4,ve=8,ue=16,_e=32,ce=64,me=128,re=256,we=512,Ie=30,je="...",ct=800,pt=16,Xe=1,tt=2,He=3,kt=1/0,zt=9007199254740991,nt=17976931348623157e292,X=0/0,fe=4294967295,xe=fe-1,le=fe>>>1,qe=[["ary",me],["bind",m],["bindKey",pe],["curry",ve],["curryRight",ue],["flip",we],["partial",_e],["partialRight",ce],["rearg",re]],dt="[object Arguments]",Rt="[object Array]",nn="[object AsyncFunction]",an="[object Boolean]",Mn="[object Date]",lr="[object DOMException]",ln="[object Error]",Gt="[object Function]",Er="[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]",po="[object Symbol]",A0="[object Undefined]",J0="[object WeakMap]",Ps="[object WeakSet]",Z0="[object ArrayBuffer]",$0="[object DataView]",Wt="[object Float32Array]",xi="[object Float64Array]",su="[object Int8Array]",mi="[object Int16Array]",Dr="[object Int32Array]",el="[object Uint8Array]",Ko="[object Uint8ClampedArray]",Uu="[object Uint16Array]",Xo="[object Uint32Array]",Xr=/\b__p \+= '';/g,O0=/\b(__p \+=) '' \+/g,M0=/(__e\(.*?\)|\b__t\)) \+\n'';/g,Po=/&(?:amp|lt|gt|quot|#39);/g,au=/[&<>"']/g,ki=RegExp(Po.source),Is=RegExp(au.source),Xl=/<%-([\s\S]+?)%>/g,Io=/<%([\s\S]+?)%>/g,ho=/<%=([\s\S]+?)%>/g,Hr=/\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,Ri=/^\w*$/,Qo=/[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g,yi=/[\\^$.*+?()[\]{}|]/g,en=RegExp(yi.source),bn=/^\s+/,Ai=/\s/,gi=/\{(?:\n\/\* \[wrapped with .+\] \*\/)?\n?/,Vt=/\{\n\/\* \[wrapped with (.+)\] \*/,Au=/,? & /,eu=/[^\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f]+/g,Jo=/[()=,{}\[\]\/\s]/,Yi=/\\(\\)?/g,Ql=/\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g,k0=/\w*$/,ai=/^[-+]0x[0-9a-f]+$/i,f0=/^0b[01]+$/i,Jl=/^\[object .+?Constructor\]$/,L0=/^0o[0-7]+$/i,bs=/^(?:0|[1-9]\d*)$/,$n=/[\xc0-\xd6\xd8-\xf6\xf8-\xff\u0100-\u017f]/g,tl=/($^)/,c0=/['\n\r\u2028\u2029\\]/g,bo="\\ud800-\\udfff",Sl="\\u0300-\\u036f",N0="\\ufe20-\\ufe2f",wt="\\u20d0-\\u20ff",bt=Sl+N0+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",vo=" \\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",Li="A-Z\\xc0-\\xd6\\xd8-\\xde",mo="\\ufe0e\\ufe0f",vs=Ki+Qr+Ou+vo,Tt="['\u2019]",d0="["+bo+"]",nl="["+vs+"]",Zl="["+bt+"]",ju="\\d+",ms="["+Hn+"]",Bo="["+qr+"]",Q="[^"+bo+vs+ju+Hn+qr+Li+"]",Se="\\ud83c[\\udffb-\\udfff]",Ne="(?:"+Zl+"|"+Se+")",Le="[^"+bo+"]",ht="(?:\\ud83c[\\udde6-\\uddff]){2}",Yn="[\\ud800-\\udbff][\\udc00-\\udfff]",Cn="["+Li+"]",cr="\\u200d",Si="(?:"+Bo+"|"+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="["+mo+"]?",F0="(?:"+cr+"(?:"+[Le,ht,Yn].join("|")+")"+Ti+Su+")*",ku="\\d*(?:1st|2nd|3rd|(?![123])\\dth)(?=\\b|[A-Z_])",p0="\\d*(?:1ST|2ND|3RD|(?![123])\\dTH)(?=\\b|[a-z_])",qu=Ti+Su+F0,Ia="(?:"+[ms,ht,Yn].join("|")+")"+qu,yo="(?:"+[Le+Zl+"?",Zl,ht,Yn,d0].join("|")+")",ua=RegExp(Tt,"g"),Zo=RegExp(Zl,"g"),oa=RegExp(Se+"(?="+Se+")|"+yo+qu,"g"),ba=RegExp([Cn+"?"+Bo+"+"+zu+"(?="+[nl,Cn,"$"].join("|")+")",Mu+"+"+Hu+"(?="+[nl,Cn+Si,"$"].join("|")+")",Cn+"?"+Si+"+"+zu,Cn+"+"+Hu,p0,ku,ju,Ia].join("|"),"g"),ys=RegExp("["+cr+bo+bt+mo+"]"),To=/[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[Wt]=fi[xi]=fi[su]=fi[mi]=fi[Dr]=fi[el]=fi[Ko]=fi[Uu]=fi[Xo]=!0,fi[dt]=fi[Rt]=fi[Z0]=fi[an]=fi[$0]=fi[Mn]=fi[ln]=fi[Gt]=fi[w]=fi[jt]=fi[vr]=fi[zr]=fi[Qt]=fi[wu]=fi[J0]=!1;var $r={};$r[dt]=$r[Rt]=$r[Z0]=$r[$0]=$r[an]=$r[Mn]=$r[Wt]=$r[xi]=$r[su]=$r[mi]=$r[Dr]=$r[w]=$r[jt]=$r[vr]=$r[zr]=$r[Qt]=$r[wu]=$r[po]=$r[el]=$r[Ko]=$r[Uu]=$r[Xo]=!0,$r[ln]=$r[Gt]=$r[J0]=!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,go=typeof global=="object"&&global&&global.Object===Object&&global,js=typeof self=="object"&&self&&self.Object===Object&&self,ji=go||js||Function("return this")(),U=typeof Wv=="object"&&Wv&&!Wv.nodeType&&Wv,z=U&&typeof Uy=="object"&&Uy&&!Uy.nodeType&&Uy,G=z&&z.exports===U,$=G&&go.process,Ce=function(){try{var Re=z&&z.require&&z.require("util").types;return Re||$&&$.binding&&$.binding("util")}catch(rt){}}(),Ee=Ce&&Ce.isArrayBuffer,Ae=Ce&&Ce.isDate,Z=Ce&&Ce.isMap,ke=Ce&&Ce.isRegExp,Je=Ce&&Ce.isSet,mt=Ce&&Ce.isTypedArray;function oe(Re,rt,Ye){switch(Ye.length){case 0:return Re.call(rt);case 1:return Re.call(rt,Ye[0]);case 2:return Re.call(rt,Ye[0],Ye[1]);case 3:return Re.call(rt,Ye[0],Ye[1],Ye[2])}return Re.apply(rt,Ye)}function We(Re,rt,Ye,Kt){for(var Xt=-1,pr=Re==null?0:Re.length;++Xt-1}function rn(Re,rt,Ye){for(var Kt=-1,Xt=Re==null?0:Re.length;++Kt-1;);return Ye}function Tl(Re,rt){for(var Ye=Re.length;Ye--&&Dt(rt,Re[Ye],0)>-1;);return Ye}function mf(Re,rt){for(var Ye=Re.length,Kt=0;Ye--;)Re[Ye]===rt&&++Kt;return Kt}var I0=Jn($l),gs=Jn(la);function zs(Re){return"\\"+Bs[Re]}function b0(Re,rt){return Re==null?i:Re[rt]}function B0(Re){return ys.test(Re)}function _s(Re){return To.test(Re)}function Qu(Re){for(var rt,Ye=[];!(rt=Re.next()).done;)Ye.push(rt.value);return Ye}function Tu(Re){var rt=-1,Ye=Array(Re.size);return Re.forEach(function(Kt,Xt){Ye[++rt]=[Xt,Kt]}),Ye}function Ei(Re,rt){return function(Ye){return Re(rt(Ye))}}function xo(Re,rt){for(var Ye=-1,Kt=Re.length,Xt=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}u0.prototype.clear=Ua,u0.prototype.delete=Ef,u0.prototype.get=cc,u0.prototype.has=ws,u0.prototype.set=ca;function jo(p){var v=-1,x=p==null?0:p.length;for(this.clear();++v=v?p:v)),p}function zo(p,v,x,P,W,ee){var he,De=v&T,be=v&B,Et=v&H;if(x&&(he=W?x(p,P,W,ee):x(p)),he!==i)return he;if(!bu(p))return p;var St=tr(p);if(St){if(he=xs(p),!De)return iu(p,he)}else{var At=Iu(p),on=At==Gt||At==Er;if(Zs(p))return mc(p,De);if(At==vr||At==dt||on&&!W){if(he=be||on?{}:Dc(p),!De)return be?rs(p,ol(he,p)):oo(p,Df(he,p))}else{if(!$r[At])return W?p:{};he=Th(p,At,De)}}ee||(ee=new ul);var kn=ee.get(p);if(kn)return kn;ee.set(p,he),bd(p)?p.forEach(function(ar){he.add(zo(ar,v,x,ar,p,ee))}):Dp(p)&&p.forEach(function(ar,ui){he.set(ui,zo(ar,v,x,ui,p,ee))});var rr=Et?be?sr:r1:be?dn:No,br=St?i:rr(p);return it(br||p,function(ar,ui){br&&(ui=ar,ar=p[ui]),Ts(he,ui,zo(ar,v,x,ui,p,ee))}),he}function wf(p){var v=No(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],he=p[W];if(he===i&&!(W in p)||!ee(he))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,he=!0,De=p.length,be=[],Et=v.length;if(!De)return be;x&&(v=Ft(v,_i(x))),P?(ee=rn,he=!1):v.length>=a&&(ee=rl,he=!1,v=new y0(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(De)?v>1?qi(De,v-1,x,P,W):Dn(W,De):P||(W[W.length]=De)}return W}var g=gc(),y=gc(!0);function R(p,v){return p&&g(p,v,No)}function F(p,v){return p&&y(p,v,No)}function b(p,v){return It(v,function(x){return Ra(p[x])})}function J(p,v){v=Vs(v,p);for(var x=0,P=v.length;p!=null&&xv}function Lt(p,v){return p!=null&&li.call(p,v)}function xr(p,v){return p!=null&&v in xn(p)}function io(p,v,x){return p>=Kn(v,x)&&p=120&&St.length>=120)?new y0(he&&St):i}St=p[0];var At=-1,on=De[0];e:for(;++At-1;)De!==p&&Mo.call(De,be,1),Mo.call(p,be,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;D0(W)?Mo.call(p,W,1):A2(p,W)}}return p}function fd(p,v){return p+Ds(Do()*(v-p+1))}function C2(p,v,x,P){for(var W=-1,ee=ni($u((v-p)/(x||1)),0),he=Ye(ee);ee--;)he[P?ee:++W]=p,p+=x;return he}function Yc(p,v){var x="";if(!p||v<1||v>zt)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,so),p+"")}function cd(p){return Ha(Nc(p))}function dd(p,v){var x=Nc(p);return Sc(x,ro(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,he=ee-1,De=p;De!=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,he=p[ee];he!==null&&!Bl(he)&&(x?he<=v:he=a){var Et=v?null:fm(p);if(Et)return e0(Et);he=!1,W=rl,be=new y0}else be=v?[]:De;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 yc(p){var v=new p.constructor(p.byteLength);return new Oo(v).set(new Oo(p)),v}function hd(p,v){var x=v?yc(p.buffer):p.buffer;return new p.constructor(x,p.byteOffset,p.byteLength)}function Eh(p){var v=new p.constructor(p.source,k0.exec(p));return v.lastIndex=p.lastIndex,v}function Cf(p){return Ar?xn(Ar.call(p)):{}}function $c(p,v){var x=v?yc(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),he=v!==i,De=v===null,be=v===v,Et=Bl(v);if(!De&&!Et&&!ee&&p>v||ee&&he&&be&&!De&&!Et||P&&he&&be||!x&&be||!W)return 1;if(!P&&!ee&&!Et&&p=De)return be;var Et=x[P];return be*(Et=="desc"?-1:1)}}return p.index-v.index}function Gs(p,v,x,P){for(var W=-1,ee=p.length,he=x.length,De=-1,be=v.length,Et=ni(ee-he,0),St=Ye(be+Et),At=!P;++De1?x[W-1]:i,he=W>2?x[2]:i;for(ee=p.length>3&&typeof ee=="function"?(W--,ee):i,he&&s0(x[0],x[1],he)&&(ee=W<3?i:ee,W=1),v=xn(v);++P-1?W[ee?v[he]:he]: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&&!he&&q0(ee)=="wrapper")var he=new Vr([],!0)}for(P=he?P:x;++P1&&di.reverse(),St&&beDe))return!1;var Et=ee.get(p),St=ee.get(v);if(Et&&St)return Et==v&&St==p;var At=-1,on=!0,kn=x&ne?new y0:i;for(ee.set(p,v),ee.set(v,p);++At1?"& ":"")+v[P],v=v.join(x>2?", ":" "),p.replace(gi,`{ -/* [wrapped with `+v+`] */ -`)}function us(p){return tr(p)||pl(p)||!!(v0&&p&&p[v0])}function D0(p,v){var x=typeof p;return v=v==null?zt:v,!!v&&(x=="number"||x!="symbol"&&bs.test(p))&&p>-1&&p%1==0&&p0){if(++v>=ct)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 g1(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 at)||!D0(x)?this.thru(W):(P=P.slice(x,+x+(v?1:0)),P.__actions__.push({func:g1,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 at){var v=p;return this.__actions__.length&&(v=new at(this)),v=v.reverse(),v.__actions__.push({func:g1,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&&s0(p,v,x)&&(v=i),P(p,Vn(v,3))}function tp(p,v){var x=tr(p)?It: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),kt)}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)?it: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&&Dt(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(he){ee[++P]=W?oe(v,he,x):Ml(he,v,x)}),ee}),Kh=Ka(function(p,v,x){Gu(p,x,v)});function _1(p,v){var x=tr(p)?Ft: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]),g0(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:wr,W=arguments.length<3;return P(p,Vn(v,4),x,W,Cs)}function xm(p,v,x){var P=tr(p)?er:wr,W=arguments.length<3;return P(p,Vn(v,4),x,W,pa)}function Rm(p,v){var x=tr(p)?It:Vc;return x(p,Od(Vn(v,3)))}function Xh(p){var v=tr(p)?Ha:cd;return v(p)}function Am(p,v,x){(x?s0(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:yh;return x&&s0(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&&s0(p,v[0],v[1])?v=[]:x>2&&s0(v[0],v[1],v[2])&&(v=[v[0]]),g0(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 Rd(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=xo(x,yr(D1));P|=_e}return hn(p,P,v,x,W)}),Jh=Ir(function(p,v,x){var P=m|pe;if(x.length){var W=xo(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,ve,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,ue,i,i,i,i,i,v);return P.placeholder=Zh.placeholder,P}function cp(p,v,x){var P,W,ee,he,De,be,Et=0,St=!1,At=!1,on=!0;if(typeof p!="function")throw new ti(_);v=vl(v)||0,bu(x)&&(St=!!x.leading,At="maxWait"in x,ee=At?ni(vl(x.maxWait)||0,v):ee,on="trailing"in x?!!x.trailing:on);function kn(ao){var Ms=P,C0=W;return P=W=i,Et=ao,he=p.apply(C0,Ms),he}function rr(ao){return Et=ao,De=Ja(ui,v),St?kn(ao):he}function br(ao){var Ms=ao-be,C0=ao-Et,kv=v-Ms;return At?Kn(kv,ee-C0):kv}function ar(ao){var Ms=ao-be,C0=ao-Et;return be===i||Ms>=v||Ms<0||At&&C0>=ee}function ui(){var ao=E1();if(ar(ao))return di(ao);De=Ja(ui,br(ao))}function di(ao){return De=i,on&&P?kn(ao):(P=W=i,he)}function zl(){De!==i&&Zc(De),Et=0,P=be=W=De=i}function Zi(){return De===i?he:di(E1())}function a0(){var ao=E1(),Ms=ar(ao);if(P=arguments,W=this,be=ao,Ms){if(De===i)return rr(be);if(At)return Zc(De),De=Ja(ui,v),kn(be)}return De===i&&(De=Ja(ui,v)),he}return a0.cancel=zl,a0.flush=Zi,a0}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,we)}function Ad(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 he=p.apply(this,P);return x.cache=ee.set(W,he)||ee,he};return x.cache=new(Ad.Cache||jo),x}Ad.Cache=jo;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 qo(p){return Rd(2,p)}var Md=k2(function(p,v){v=v.length==1&&tr(v[0])?Ft(v[0],_i(Vn())):Ft(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=uo(function(){return arguments}())?uo:function(p){return Yu(p)&&li.call(p,"callee")&&!Uo.call(p,"callee")},tr=Ye.isArray,Js=Ee?_i(Ee):Ve;function hl(p){return p!=null&&Pd(p.length)&&!Ra(p)}function lo(p){return Yu(p)&&hl(p)}function rv(p){return p===!0||p===!1||Yu(p)&>(p)==an}var Zs=r0||jp,yp=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)||Aa(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 gp(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 Ra(p){if(!bu(p))return!1;var v=gt(p);return v==Gt||v==Er||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<=zt}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 Xt(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>=-zt&&p<=zt}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)==po}var Aa=mt?_i(mt):Gr;function lv(p){return p===i}function jm(p){return Yu(p)&&Iu(p)==J0}function sv(p){return Yu(p)&>(p)==Ps}var av=yd(ld),zm=yd(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?e0:Nc;return x(p)}function Oa(p){if(!p)return p===0?p:0;if(p=vl(p),p===kt||p===-kt){var v=p<0?-1:1;return v*nt}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?ro(Mr(p),0,fe):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=f0.test(p);return x||L0.test(p)?Us(p.slice(2),x?2:8):ai.test(p)?X:+p}function gu(p){return ko(p,dn(p))}function T1(p){return p?ro(Mr(p),-zt,zt):p===0?p:0}function Ui(p){return p==null?"":al(p)}var Tp=o0(function(p,v){if(Nf(v)||hl(v)){ko(v,No(v),p);return}for(var x in v)li.call(v,x)&&Ts(p,x,v[x])}),Bd=o0(function(p,v){ko(v,dn(v),p)}),T0=o0(function(p,v,x,P){ko(v,dn(v),p,P)}),Os=o0(function(p,v,x,P){ko(v,No(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&&s0(v[0],v[1],W)&&(P=1);++x1),ee}),ko(p,sr(p),x),P&&(x=zo(x,T|B|H,cm));for(var W=v.length;W--;)A2(x,v[W]);return x});function A1(p,v){return tf(p,Od(Vn(v)))}var Ap=cl(function(p,v){return p==null?{}:vh(p,v)});function tf(p,v){if(p==null)return{};var x=Ft(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=Do();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?W0(v):v)});function W0(p){return kp(Ui(p).toLowerCase())}function Yd(p){return p=Ui(p),p&&p.replace($n,I0).replace(Zo,"")}function Wm(p,v,x){p=Ui(p),v=al(v);var P=p.length;x=x===i?P:ro(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,gs):p}function Vm(p){return p=Ui(p),p&&en.test(p)?p.replace(yi,"\\$&"):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&&B0(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:ro(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&&s0(p,v,x)&&(v=i),p=Ui(p),v=T0({},v,P,Af);var W=T0({},v.imports,P.imports,Af),ee=No(W),he=P0(W,ee),De,be,Et=0,St=v.interpolate||tl,At="__p += '",on=yu((v.escape||tl).source+"|"+St.source+"|"+(St===ho?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,a0){return di||(di=zl),At+=p.slice(Et,a0).replace(c0,zs),ui&&(De=!0,At+=`' + -__e(`+ui+`) + -'`),Zi&&(be=!0,At+=`'; -`+Zi+`; -__p += '`),di&&(At+=`' + -((__t = (`+di+`)) == null ? '' : __t) + -'`),Et=a0+ar.length,ar}),At+=`'; -`;var rr=li.call(v,"variable")&&v.variable;if(!rr)At=`with (obj) { -`+At+` -} -`;else if(Jo.test(rr))throw new Xt(t);At=(be?At.replace(Xr,""):At).replace(O0,"$1").replace(M0,"$1;"),At="function("+(rr||"obj")+`) { -`+(rr?"":`obj || (obj = {}); -`)+"var __t, __p = ''"+(De?", __e = _.escape":"")+(be?`, __j = Array.prototype.join; -function print() { __p += __j.call(arguments, '') } -`:`; -`)+At+`return __p -}`;var br=wv(function(){return pr(ee,kn+"return "+At).apply(i,he)});if(br.source=At,_p(br))throw br;return br}function yv(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),he=Tl(P,W)+1;return ma(P,ee,he).join("")}function Mp(p,v,x){if(p=Ui(p),p&&(x||v===i))return p.slice(0,h0(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 gv(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=Ie,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(B0(p)){var he=ei(p);ee=he.length}if(x>=ee)return p;var De=x-tu(P);if(De<1)return P;var be=he?ma(he,0,De).join(""):p.slice(0,De);if(W===i)return be+P;if(he&&(De+=be.length-De),w1(W)){if(p.slice(De).search(W)){var Et,St=be;for(W.global||(W=yu(W.source,Ui(k0.exec(W))+"g")),W.lastIndex=0;Et=W.exec(St);)var At=Et.index;be=be.slice(0,At===i?De:At)}}else if(p.indexOf(al(W),De)!=De){var on=be.lastIndexOf(W);on>-1&&(be=be.slice(0,on))}return be+P}function _v(p){return p=Ui(p),p&&ki.test(p)?p.replace(Po,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)?gf(p):_o(p):p.match(v)||[]}var wv=Ir(function(p,v){try{return oe(p,i,v)}catch(x){return _p(x)?x:new Xt(x)}}),$m=cl(function(p,v){return it(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?Ft(p,function(P){if(typeof P[1]!="function")throw new ti(_);return[x(P[0]),P[1]]}):[],Ir(function(P){for(var W=-1;++Wzt)return[];var x=fe,P=Kn(p,fe);v=Vn(v),p-=fe;for(var W=Co(P,v);++x0||v<0)?new at(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)},at.prototype.takeRightWhile=function(p){return this.reverse().takeWhile(p).reverse()},at.prototype.toArray=function(){return this.take(fe)},R(at.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 he=this.__wrapped__,De=P?[1]:arguments,be=he instanceof at,Et=De[0],St=be||tr(he),At=function(ui){var di=W.apply(Y,Dn([ui],De));return P&&on?di[0]:di};St&&x&&typeof Et=="function"&&Et.length!=1&&(be=St=!1);var on=this.__chain__,kn=!!this.__actions__.length,rr=ee&&!on,br=be&&!kn;if(!ee&&St){he=br?he:new at(this);var ar=p.apply(he,De);return ar.__actions__.push({func:g1,args:[At],thisArg:i}),new Vr(ar,on)}return rr&&br?p.apply(this,De):(ar=this.thru(At),rr?P?ar.value()[0]:ar.value():ar)})}),it(["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(he){return v.apply(tr(he)?he:[],W)})}}),R(at.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[ga(i,pe).name]=[{name:"wrapper",func:i}],at.prototype.clone=Di,at.prototype.reverse=ru,at.prototype.value=wo,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},n0=t0();typeof define=="function"&&typeof define.amd=="object"&&define.amd?(ji._=n0,define(function(){return n0})):z?((z.exports=n0)._=n0,U._=n0):ji._=n0}).call(Wv)});var yD=Ke((wW,mD)=>{"use strict";var Pi=mD.exports;mD.exports.default=Pi;var Du="[",jy="]",Vv="\x07",P_=";",LS=process.env.TERM_PROGRAM==="Apple_Terminal";Pi.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"};Pi.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};Pi.cursorUp=(i=1)=>Du+i+"A";Pi.cursorDown=(i=1)=>Du+i+"B";Pi.cursorForward=(i=1)=>Du+i+"C";Pi.cursorBackward=(i=1)=>Du+i+"D";Pi.cursorLeft=Du+"G";Pi.cursorSavePosition=LS?"7":Du+"s";Pi.cursorRestorePosition=LS?"8":Du+"u";Pi.cursorGetPosition=Du+"6n";Pi.cursorNextLine=Du+"E";Pi.cursorPrevLine=Du+"F";Pi.cursorHide=Du+"?25l";Pi.cursorShow=Du+"?25h";Pi.eraseLines=i=>{let o="";for(let a=0;a[jy,"8",P_,P_,o,Vv,i,jy,"8",P_,P_,Vv].join("");Pi.image=(i,o={})=>{let a=`${jy}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};Pi.iTerm={setCwd:(i=process.cwd())=>`${jy}50;CurrentDir=${i}${Vv}`,annotation:(i,o={})=>{let a=`${jy}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 PS=Ke((SW,gD)=>{"use strict";var NS=(i,o)=>{for(let a of Reflect.ownKeys(o))Object.defineProperty(i,a,Object.getOwnPropertyDescriptor(o,a));return i};gD.exports=NS;gD.exports.default=NS});var bS=Ke((TW,I_)=>{"use strict";var AI=PS(),b_=new WeakMap,IS=(i,o={})=>{if(typeof i!="function")throw new TypeError("Expected a function");let a,c=0,_=i.displayName||i.name||"",t=function(...M){if(b_.set(t,++c),c===1)a=i.apply(this,M),i=null;else if(o.throw===!0)throw new Error(`Function \`${_}\` can only be called once`);return a};return AI(t,i),b_.set(t,c),t};I_.exports=IS;I_.exports.default=IS;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 wD=Ke((xW,zy)=>{var OI=require("assert"),Hy=BS(),MI=/^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);zy.exports=function(i,o){OI.equal(typeof i,"function","a callback must be provided for exit handler"),qy===!1&&US();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&&_D()};return Yl.on(a,i),c};zy.exports.unload=_D;function _D(){!qy||(qy=!1,Hy.forEach(function(i){try{process.removeListener(i,ED[i])}catch(o){}}),process.emit=DD,process.reallyExit=jS,Yl.count-=1)}function Gv(i,o,a){Yl.emitted[i]||(Yl.emitted[i]=!0,Yl.emit(i,o,a))}var ED={};Hy.forEach(function(i){ED[i]=function(){var a=process.listeners(i);a.length===Yl.count&&(_D(),Gv("exit",null,i),Gv("afterexit",null,i),MI&&i==="SIGHUP"&&(i="SIGINT"),process.kill(process.pid,i))}});zy.exports.signals=function(){return Hy};zy.exports.load=US;var qy=!1;function US(){qy||(qy=!0,Yl.count+=1,Hy=Hy.filter(function(i){try{return process.on(i,ED[i]),!0}catch(o){return!1}}),process.emit=LI,process.reallyExit=kI)}var jS=process.reallyExit;function kI(i){process.exitCode=i||0,Gv("exit",process.exitCode,null),Gv("afterexit",process.exitCode,null),jS.call(process,process.exitCode)}var DD=process.emit;function LI(i,o){if(i==="exit"){o!==void 0&&(process.exitCode=o);var a=DD.apply(this,arguments);return Gv("exit",process.exitCode,null),Gv("afterexit",process.exitCode,null),a}else return DD.apply(this,arguments)}});var HS=Ke((RW,zS)=>{"use strict";var NI=bS(),FI=wD();zS.exports=NI(()=>{FI(()=>{process.stderr.write("[?25h")},{alwaysLast:!0})})});var SD=Ke(Yv=>{"use strict";var PI=HS(),j_=!1;Yv.show=(i=process.stderr)=>{!i.isTTY||(j_=!1,i.write("[?25h"))};Yv.hide=(i=process.stderr)=>{!i.isTTY||(PI(),j_=!0,i.write("[?25l"))};Yv.toggle=(i,o)=>{i!==void 0&&(j_=i),j_?Yv.show(o):Yv.hide(o)}});var GS=Ke(Wy=>{"use strict";var qS=Wy&&Wy.__importDefault||function(i){return i&&i.__esModule?i:{default:i}};Object.defineProperty(Wy,"__esModule",{value:!0});var WS=qS(yD()),VS=qS(SD()),II=(i,{showCursor:o=!1}={})=>{let a=0,c="",_=!1,t=M=>{!o&&!_&&(VS.default.hide(),_=!0);let N=M+` -`;N!==c&&(c=N,i.write(WS.default.eraseLines(a)+N),a=N.split(` -`).length)};return t.clear=()=>{i.write(WS.default.eraseLines(a)),c="",a=0},t.done=()=>{c="",a=0,o||(VS.default.show(),_=!1)},t};Wy.default={create:II}});var KS=Ke((MW,YS)=>{YS.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 JS=Ke(Pa=>{"use strict";var XS=KS(),jc=process.env;Object.defineProperty(Pa,"_vendors",{value:XS.map(function(i){return i.constant})});Pa.name=null;Pa.isPR=null;XS.forEach(function(i){var o=Array.isArray(i.env)?i.env:[i.env],a=o.every(function(c){return QS(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=QS(i.pr);break;default:Pa.isPR=null}});Pa.isCI=!!(jc.CI||jc.CONTINUOUS_INTEGRATION||jc.BUILD_NUMBER||jc.RUN_ID||Pa.name);function QS(i){return typeof i=="string"?!!jc[i]:Object.keys(i).every(function(o){return jc[o]===i[o]})}});var $S=Ke((LW,ZS)=>{"use strict";ZS.exports=JS().isCI});var tT=Ke((NW,eT)=>{"use strict";var bI=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};eT.exports=(i,{include:o,exclude:a}={})=>{let c=_=>{let t=M=>typeof M=="string"?_===M:M.test(_);return o?o.some(t):a?!a.some(t):!0};for(let[_,t]of bI(i.constructor.prototype)){if(t==="constructor"||!c(t))continue;let M=Reflect.getOwnPropertyDescriptor(_,t);M&&typeof M.value=="function"&&(i[t]=i[t].bind(i))}return i}});var sT=Ke(lu=>{"use strict";Object.defineProperty(lu,"__esModule",{value:!0});var Kv,Vy,z_,H_,TD;typeof window=="undefined"||typeof MessageChannel!="function"?(Xv=null,CD=null,xD=function(){if(Xv!==null)try{var i=lu.unstable_now();Xv(!0,i),Xv=null}catch(o){throw setTimeout(xD,0),o}},nT=Date.now(),lu.unstable_now=function(){return Date.now()-nT},Kv=function(i){Xv!==null?setTimeout(Kv,0,i):(Xv=i,setTimeout(xD,0))},Vy=function(i,o){CD=setTimeout(i,o)},z_=function(){clearTimeout(CD)},H_=function(){return!1},TD=lu.unstable_forceFrameRate=function(){}):(q_=window.performance,RD=window.Date,rT=window.setTimeout,iT=window.clearTimeout,typeof console!="undefined"&&(uT=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 uT!="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()}:(oT=RD.now(),lu.unstable_now=function(){return RD.now()-oT}),Gy=!1,Yy=null,W_=-1,AD=5,OD=0,H_=function(){return lu.unstable_now()>=OD},TD=function(){},lu.unstable_forceFrameRate=function(i){0>i||125G_(M,a))O!==void 0&&0>G_(O,M)?(i[c]=O,i[N]=a,c=N):(i[c]=M,i[t]=a,c=t);else if(O!==void 0&&0>G_(O,a))i[c]=O,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,Ky=!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,kD(ec,o);else break;o=df(d2)}}function LD(i){if(Ky=!1,X_(i),!$p)if(df(ec)!==null)$p=!0,Kv(ND);else{var o=df(d2);o!==null&&Vy(LD,o.startTime-i)}}function ND(i,o){$p=!1,Ky&&(Ky=!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 M=df(d2);M!==null&&Vy(LD,M.startTime-o),t=!1}return t}finally{Fs=null,ps=a,K_=!1}}function lT(i){switch(i){case 1:return-1;case 2:return 250;case 5:return 1073741823;case 4:return 1e4;default:return 5e3}}var UI=TD;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:lT(i)}else a=lT(i),_=c;return a=_+a,i={id:BI++,callback:o,priorityLevel:i,startTime:_,expirationTime:a,sortIndex:-1},_>c?(i.sortIndex=_,kD(d2,i),df(ec)===null&&i===df(d2)&&(Ky?z_():Ky=!0,Vy(LD,_-c))):(i.sortIndex=a,kD(ec,i),$p||K_||($p=!0,Kv(ND))),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(Ii,"__esModule",{value:!0});var i=!1,o=!1,a=!0,c,_,t,M,N;if(typeof window=="undefined"||typeof MessageChannel!="function"){var O=null,T=null,B=function(){if(O!==null)try{var wt=Ii.unstable_now(),bt=!0;O(bt,wt),O=null}catch(Hn){throw setTimeout(B,0),Hn}},H=Date.now();Ii.unstable_now=function(){return Date.now()-H},c=function(wt){O!==null?setTimeout(c,0,wt):(O=wt,setTimeout(B,0))},_=function(wt,bt){T=setTimeout(wt,bt)},t=function(){clearTimeout(T)},M=function(){return!1},N=Ii.unstable_forceFrameRate=function(){}}else{var q=window.performance,ne=window.Date,m=window.setTimeout,pe=window.clearTimeout;if(typeof console!="undefined"){var ge=window.requestAnimationFrame,ve=window.cancelAnimationFrame;typeof ge!="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 ve!="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")Ii.unstable_now=function(){return q.now()};else{var ue=ne.now();Ii.unstable_now=function(){return ne.now()-ue}}var _e=!1,ce=null,me=-1,re=5,we=0,Ie=300,je=!1;if(o&&navigator!==void 0&&navigator.scheduling!==void 0&&navigator.scheduling.isInputPending!==void 0){var ct=navigator.scheduling;M=function(){var wt=Ii.unstable_now();return wt>=we?je||ct.isInputPending()?!0:wt>=Ie:!1},N=function(){je=!0}}else M=function(){return Ii.unstable_now()>=we},N=function(){};Ii.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?re=Math.floor(1e3/wt):re=5};var pt=function(){if(ce!==null){var wt=Ii.unstable_now();we=wt+re;var bt=!0;try{var Hn=ce(bt,wt);Hn?tt.postMessage(null):(_e=!1,ce=null)}catch(qr){throw tt.postMessage(null),qr}}else _e=!1;je=!1},Xe=new MessageChannel,tt=Xe.port2;Xe.port1.onmessage=pt,c=function(wt){ce=wt,_e||(_e=!0,tt.postMessage(null))},_=function(wt,bt){me=m(function(){wt(Ii.unstable_now())},bt)},t=function(){pe(me),me=-1}}function He(wt,bt){var Hn=wt.length;wt.push(bt),nt(wt,bt,Hn)}function kt(wt){var bt=wt[0];return bt===void 0?null:bt}function zt(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 nt(wt,bt,Hn){for(var qr=Hn;;){var Ki=Math.floor((qr-1)/2),Qr=wt[Ki];if(Qr!==void 0&&fe(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()`."),Dr();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 Dr(){var wt=zr;return fr=0,zr=null,Qt=null,wu=0,wt}function el(wt,bt){a&&(Gt[Xn]++,Qt!==null&&su([po,bt*1e3,wt.id,wt.priorityLevel]))}function Ko(wt,bt){a&&(Gt[Er]=xe,Gt[w]=0,Gt[Xn]--,Qt!==null&&su([A0,bt*1e3,wt.id]))}function Uu(wt,bt){a&&(Gt[Xn]--,Qt!==null&&su([Ps,bt*1e3,wt.id]))}function Xo(wt,bt){a&&(Gt[Er]=xe,Gt[w]=0,Gt[Xn]--,Qt!==null&&su([J0,bt*1e3,wt.id]))}function Xr(wt,bt){a&&(an++,Gt[Er]=wt.priorityLevel,Gt[w]=wt.id,Gt[jt]=an,Qt!==null&&su([Z0,bt*1e3,wt.id,an]))}function O0(wt,bt){a&&(Gt[Er]=xe,Gt[w]=0,Gt[jt]=0,Qt!==null&&su([$0,bt*1e3,wt.id,an]))}function M0(wt){a&&(Mn++,Qt!==null&&su([Wt,wt*1e3,Mn]))}function Po(wt){a&&Qt!==null&&su([xi,wt*1e3,Mn])}var au=1073741823,ki=-1,Is=250,Xl=5e3,Io=1e4,ho=au,Hr=[],Ri=[],Qo=1,yi=!1,en=null,bn=dt,Ai=!1,gi=!1,Vt=!1;function Au(wt){for(var bt=kt(Ri);bt!==null;){if(bt.callback===null)zt(Ri);else if(bt.startTime<=wt)zt(Ri),bt.sortIndex=bt.expirationTime,He(Hr,bt),a&&(el(bt,wt),bt.isQueued=!0);else return;bt=kt(Ri)}}function eu(wt){if(Vt=!1,Au(wt),!gi)if(kt(Hr)!==null)gi=!0,c(Jo);else{var bt=kt(Ri);bt!==null&&_(eu,bt.startTime-wt)}}function Jo(wt,bt){a&&Po(bt),gi=!1,Vt&&(Vt=!1,t()),Ai=!0;var Hn=bn;try{if(a)try{return Yi(wt,bt)}catch(Qr){if(en!==null){var qr=Ii.unstable_now();Xo(en,qr),en.isQueued=!1}throw Qr}else return Yi(wt,bt)}finally{if(en=null,bn=Hn,Ai=!1,a){var Ki=Ii.unstable_now();M0(Ki)}}}function Yi(wt,bt){var Hn=bt;for(Au(Hn),en=kt(Hr);en!==null&&!(i&&yi)&&!(en.expirationTime>Hn&&(!wt||M()));){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=Ii.unstable_now(),typeof Qr=="function"?(en.callback=Qr,O0(en,Hn)):(a&&(Ko(en,Hn),en.isQueued=!1),en===kt(Hr)&&zt(Hr)),Au(Hn)}else zt(Hr);en=kt(Hr)}if(en!==null)return!0;var Ou=kt(Ri);return Ou!==null&&_(eu,Ou.startTime-Hn),!1}function Ql(wt,bt){switch(wt){case le:case qe:case dt:case Rt:case nn:break;default:wt=dt}var Hn=bn;bn=wt;try{return bt()}finally{bn=Hn}}function k0(wt){var bt;switch(bn){case le:case qe: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 f0(wt){switch(wt){case le:return ki;case qe:return Is;case nn:return ho;case Rt:return Io;case dt:default:return Xl}}function Jl(wt,bt,Hn){var qr=Ii.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:f0(wt)}else Qr=f0(wt),Ki=qr;var vo=Ki+Qr,Li={id:Qo++,callback:bt,priorityLevel:wt,startTime:Ki,expirationTime:vo,sortIndex:-1};return a&&(Li.isQueued=!1),Ki>qr?(Li.sortIndex=Ki,He(Ri,Li),kt(Hr)===null&&Li===kt(Ri)&&(Vt?t():Vt=!0,_(eu,Ki-qr))):(Li.sortIndex=vo,He(Hr,Li),a&&(el(Li,qr),Li.isQueued=!0),!gi&&!Ai&&(gi=!0,c(Jo))),Li}function L0(){yi=!0}function bs(){yi=!1,!gi&&!Ai&&(gi=!0,c(Jo))}function $n(){return kt(Hr)}function tl(wt){if(a&&wt.isQueued){var bt=Ii.unstable_now();Uu(wt,bt),wt.isQueued=!1}wt.callback=null}function c0(){return bn}function bo(){var wt=Ii.unstable_now();Au(wt);var bt=kt(Hr);return bt!==en&&en!==null&&bt!==null&&bt.callback!==null&&bt.startTime<=wt&&bt.expirationTime{"use strict";process.env.NODE_ENV==="production"?FD.exports=sT():FD.exports=aT()});var fT=Ke((bW,Xy)=>{Xy.exports=function i(o){"use strict";var a=Iy(),c=Mi(),_=Q_();function t(g){for(var y="https://reactjs.org/docs/error-decoder.html?invariant="+g,R=1;RQo||(g.current=Ri[Qo],Ri[Qo]=null,Qo--)}function en(g,y){Qo++,Ri[Qo]=g.current,g.current=y}var bn={},Ai={current:bn},gi={current:!1},Vt=bn;function Au(g,y){var R=g.type.contextTypes;if(!R)return bn;var F=g.stateNode;if(F&&F.__reactInternalMemoizedUnmaskedChildContext===y)return F.__reactInternalMemoizedMaskedChildContext;var b={},J;for(J in R)b[J]=y[J];return F&&(g=g.stateNode,g.__reactInternalMemoizedUnmaskedChildContext=y,g.__reactInternalMemoizedMaskedChildContext=b),b}function eu(g){return g=g.childContextTypes,g!=null}function Jo(g){yi(gi,g),yi(Ai,g)}function Yi(g){yi(gi,g),yi(Ai,g)}function Ql(g,y,R){if(Ai.current!==bn)throw Error(t(168));en(Ai,y,g),en(gi,R,g)}function k0(g,y,R){var F=g.stateNode;if(g=y.childContextTypes,typeof F.getChildContext!="function")return R;F=F.getChildContext();for(var b in F)if(!(b in g))throw Error(t(108,Ie(y)||"Unknown",b));return a({},R,{},F)}function ai(g){var y=g.stateNode;return y=y&&y.__reactInternalMemoizedMergedChildContext||bn,Vt=Ai.current,en(Ai,y,g),en(gi,gi.current,g),!0}function f0(g,y,R){var F=g.stateNode;if(!F)throw Error(t(169));R?(y=k0(g,y,Vt),F.__reactInternalMemoizedMergedChildContext=y,yi(gi,g),yi(Ai,g),en(Ai,y,g)):yi(gi,g),en(gi,R,g)}var Jl=_.unstable_runWithPriority,L0=_.unstable_scheduleCallback,bs=_.unstable_cancelCallback,$n=_.unstable_shouldYield,tl=_.unstable_requestPaint,c0=_.unstable_now,bo=_.unstable_getCurrentPriorityLevel,Sl=_.unstable_ImmediatePriority,N0=_.unstable_UserBlockingPriority,wt=_.unstable_NormalPriority,bt=_.unstable_LowPriority,Hn=_.unstable_IdlePriority,qr={},Ki=tl!==void 0?tl:function(){},Qr=null,Ou=null,vo=!1,Li=c0(),mo=1e4>Li?c0:function(){return c0()-Li};function vs(){switch(bo()){case Sl:return 99;case N0:return 98;case wt:return 97;case bt:return 96;case Hn:return 95;default:throw Error(t(332))}}function Tt(g){switch(g){case 99:return Sl;case 98:return N0;case 97:return wt;case 96:return bt;case 95:return Hn;default:throw Error(t(332))}}function d0(g,y){return g=Tt(g),Jl(g,y)}function nl(g,y,R){return g=Tt(g),L0(g,y,R)}function Zl(g){return Qr===null?(Qr=[g],Ou=L0(Sl,ms)):Qr.push(g),qr}function ju(){if(Ou!==null){var g=Ou;Ou=null,bs(g)}ms()}function ms(){if(!vo&&Qr!==null){vo=!0;var g=0;try{var y=Qr;d0(99,function(){for(;g=y&&(h0=!0),g.firstContext=null)}function ku(g,y){if(Mu!==g&&y!==!1&&y!==0)if((typeof y!="number"||y===1073741823)&&(Mu=g,y=1073741823),y={context:g,observedBits:y,next:null},Si===null){if(cr===null)throw Error(t(308));Si=y,cr.dependencies={expirationTime:0,firstContext:y,responders:null}}else Si=Si.next=y;return ln?g._currentValue:g._currentValue2}var p0=!1;function qu(g){return{baseState:g,firstUpdate:null,lastUpdate:null,firstCapturedUpdate:null,lastCapturedUpdate:null,firstEffect:null,lastEffect:null,firstCapturedEffect:null,lastCapturedEffect:null}}function Ia(g){return{baseState:g.baseState,firstUpdate:g.firstUpdate,lastUpdate:g.lastUpdate,firstCapturedUpdate:null,lastCapturedUpdate:null,firstEffect:null,lastEffect:null,firstCapturedEffect:null,lastCapturedEffect:null}}function yo(g,y){return{expirationTime:g,suspenseConfig:y,tag:0,payload:null,callback:null,next:null,nextEffect:null}}function ua(g,y){g.lastUpdate===null?g.firstUpdate=g.lastUpdate=y:(g.lastUpdate.next=y,g.lastUpdate=y)}function Zo(g,y){var R=g.alternate;if(R===null){var F=g.updateQueue,b=null;F===null&&(F=g.updateQueue=qu(g.memoizedState))}else F=g.updateQueue,b=R.updateQueue,F===null?b===null?(F=g.updateQueue=qu(g.memoizedState),b=R.updateQueue=qu(R.memoizedState)):F=g.updateQueue=Ia(b):b===null&&(b=R.updateQueue=Ia(F));b===null||F===b?ua(F,y):F.lastUpdate===null||b.lastUpdate===null?(ua(F,y),ua(b,y)):(ua(F,y),b.lastUpdate=y)}function oa(g,y){var R=g.updateQueue;R=R===null?g.updateQueue=qu(g.memoizedState):ba(g,R),R.lastCapturedUpdate===null?R.firstCapturedUpdate=R.lastCapturedUpdate=y:(R.lastCapturedUpdate.next=y,R.lastCapturedUpdate=y)}function ba(g,y){var R=g.alternate;return R!==null&&y===R.updateQueue&&(y=g.updateQueue=Ia(y)),y}function ys(g,y,R,F,b,J){switch(R.tag){case 1:return g=R.payload,typeof g=="function"?g.call(J,F,b):g;case 3:g.effectTag=g.effectTag&-4097|64;case 0:if(g=R.payload,b=typeof g=="function"?g.call(J,F,b):g,b==null)break;return a({},F,b);case 2:p0=!0}return F}function To(g,y,R,F,b){p0=!1,y=ba(g,y);for(var J=y.baseState,de=null,gt=0,xt=y.firstUpdate,Lt=J;xt!==null;){var xr=xt.expirationTime;xrci?(Qi=ur,ur=null):Qi=ur.sibling;var Gr=du(Ve,ur,lt[ci],$t);if(Gr===null){ur===null&&(ur=Qi);break}g&&ur&&Gr.alternate===null&&y(Ve,ur),ze=J(Gr,ze,ci),si===null?Wn=Gr:si.sibling=Gr,si=Gr,ur=Qi}if(ci===lt.length)return R(Ve,ur),Wn;if(ur===null){for(;cici?(Qi=ur,ur=null):Qi=ur.sibling;var Cu=du(Ve,ur,Gr.value,$t);if(Cu===null){ur===null&&(ur=Qi);break}g&&ur&&Cu.alternate===null&&y(Ve,ur),ze=J(Cu,ze,ci),si===null?Wn=Cu:si.sibling=Cu,si=Cu,ur=Qi}if(Gr.done)return R(Ve,ur),Wn;if(ur===null){for(;!Gr.done;ci++,Gr=lt.next())Gr=io(Ve,Gr.value,$t),Gr!==null&&(ze=J(Gr,ze,ci),si===null?Wn=Gr:si.sibling=Gr,si=Gr);return Wn}for(ur=F(Ve,ur);!Gr.done;ci++,Gr=lt.next())Gr=Ho(ur,Ve,ci,Gr.value,$t),Gr!==null&&(g&&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 g&&ur.forEach(function(Va){return y(Ve,Va)}),Wn}return function(Ve,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 O:e:{for(si=lt.key,Wn=ze;Wn!==null;){if(Wn.key===si)if(Wn.tag===7?lt.type===B:Wn.elementType===lt.type){R(Ve,Wn.sibling),ze=b(Wn,lt.type===B?lt.props.children:lt.props,$t),ze.ref=js(Ve,Wn,lt),ze.return=Ve,Ve=ze;break e}else{R(Ve,Wn);break}else y(Ve,Wn);Wn=Wn.sibling}lt.type===B?(ze=ro(lt.props.children,Ve.mode,$t,lt.key),ze.return=Ve,Ve=ze):($t=Wa(lt.type,lt.key,lt.props,null,Ve.mode,$t),$t.ref=js(Ve,ze,lt),$t.return=Ve,Ve=$t)}return de(Ve);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){R(Ve,ze.sibling),ze=b(ze,lt.children||[],$t),ze.return=Ve,Ve=ze;break e}else{R(Ve,ze);break}else y(Ve,ze);ze=ze.sibling}ze=wf(lt,Ve.mode,$t),ze.return=Ve,Ve=ze}return de(Ve)}if(typeof lt=="string"||typeof lt=="number")return lt=""+lt,ze!==null&&ze.tag===6?(R(Ve,ze.sibling),ze=b(ze,lt,$t),ze.return=Ve,Ve=ze):(R(Ve,ze),ze=zo(lt,Ve.mode,$t),ze.return=Ve,Ve=ze),de(Ve);if(go(lt))return Ml(Ve,ze,lt,$t);if(re(lt))return uo(Ve,ze,lt,$t);if(si&&ji(Ve,lt),typeof lt=="undefined"&&!Wn)switch(Ve.tag){case 1:case 0:throw Ve=Ve.type,Error(t(152,Ve.displayName||Ve.name||"Component"))}return R(Ve,ze)}}var z=U(!0),G=U(!1),$={},Ce={current:$},Ee={current:$},Ae={current:$};function Z(g){if(g===$)throw Error(t(174));return g}function ke(g,y){en(Ae,y,g),en(Ee,g,g),en(Ce,$,g),y=kt(y),yi(Ce,g),en(Ce,y,g)}function Je(g){yi(Ce,g),yi(Ee,g),yi(Ae,g)}function mt(g){var y=Z(Ae.current),R=Z(Ce.current);y=zt(R,g.type,y),R!==y&&(en(Ee,g,g),en(Ce,y,g))}function oe(g){Ee.current===g&&(yi(Ce,g),yi(Ee,g))}var We={current:0};function it(g){for(var y=g;y!==null;){if(y.tag===13){var R=y.memoizedState;if(R!==null&&(R=R.dehydrated,R===null||Xr(R)||O0(R)))return y}else if(y.tag===19&&y.memoizedProps.revealOrder!==void 0){if((y.effectTag&64)!=0)return y}else if(y.child!==null){y.child.return=y,y=y.child;continue}if(y===g)break;for(;y.sibling===null;){if(y.return===null||y.return===g)return null;y=y.return}y.sibling.return=y.return,y=y.sibling}return null}function Ct(g,y){return{responder:g,props:y}}var Mt=M.ReactCurrentDispatcher,It=M.ReactCurrentBatchConfig,sn=0,rn=null,Ft=null,Dn=null,dr=null,er=null,Cr=null,An=0,Lr=null,_o=0,Nr=!1,ut=null,Dt=0;function et(){throw Error(t(321))}function Pt(g,y){if(y===null)return!1;for(var R=0;RAn&&(An=xr,ja(An))):(dc(xr,xt.suspenseConfig),J=xt.eagerReducer===g?xt.eagerState:g(J,xt.action)),de=xt,xt=xt.next}while(xt!==null&&xt!==F);Lt||(gt=de,b=J),Ne(J,y.memoizedState)||(h0=!0),y.memoizedState=J,y.baseUpdate=gt,y.baseState=b,R.lastRenderedState=J}return[y.memoizedState,R.dispatch]}function Co(g){var y=Jn();return typeof g=="function"&&(g=g()),y.memoizedState=y.baseState=g,g=y.queue={last:null,dispatch:null,lastRenderedReducer:fu,lastRenderedState:g},g=g.dispatch=zs.bind(null,rn,g),[y.memoizedState,g]}function $o(g){return Lu(fu,g)}function Nu(g,y,R,F){return g={tag:g,create:y,destroy:R,deps:F,next:null},Lr===null?(Lr={lastEffect:null},Lr.lastEffect=g.next=g):(y=Lr.lastEffect,y===null?Lr.lastEffect=g.next=g:(R=y.next,y.next=g,g.next=R,Lr.lastEffect=g)),g}function _i(g,y,R,F){var b=Jn();_o|=g,b.memoizedState=Nu(y,R,void 0,F===void 0?null:F)}function P0(g,y,R,F){var b=wr();F=F===void 0?null:F;var J=void 0;if(Ft!==null){var de=Ft.memoizedState;if(J=de.destroy,F!==null&&Pt(F,de.deps)){Nu(0,R,J,F);return}}_o|=g,b.memoizedState=Nu(y,R,J,F)}function rl(g,y){return _i(516,192,g,y)}function vf(g,y){return P0(516,192,g,y)}function Tl(g,y){if(typeof y=="function")return g=g(),y(g),function(){y(null)};if(y!=null)return g=g(),y.current=g,function(){y.current=null}}function mf(){}function I0(g,y){return Jn().memoizedState=[g,y===void 0?null:y],g}function gs(g,y){var R=wr();y=y===void 0?null:y;var F=R.memoizedState;return F!==null&&y!==null&&Pt(y,F[1])?F[0]:(R.memoizedState=[g,y],g)}function zs(g,y,R){if(!(25>Dt))throw Error(t(301));var F=g.alternate;if(g===rn||F!==null&&F===rn)if(Nr=!0,g={expirationTime:sn,suspenseConfig:null,action:R,eagerReducer:null,eagerState:null,next:null},ut===null&&(ut=new Map),R=ut.get(y),R===void 0)ut.set(y,g);else{for(y=R;y.next!==null;)y=y.next;y.next=g}else{var b=wo(),J=fi.suspense;b=Un(b,g,J),J={expirationTime:b,suspenseConfig:J,action:R,eagerReducer:null,eagerState:null,next:null};var de=y.last;if(de===null)J.next=J;else{var gt=de.next;gt!==null&&(J.next=gt),de.next=J}if(y.last=J,g.expirationTime===0&&(F===null||F.expirationTime===0)&&(F=y.lastRenderedReducer,F!==null))try{var xt=y.lastRenderedState,Lt=F(xt,R);if(J.eagerReducer=F,J.eagerState=Lt,Ne(Lt,xt))return}catch(xr){}finally{}to(g,b)}}var b0={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},B0={readContext:ku,useCallback:I0,useContext:ku,useEffect:rl,useImperativeHandle:function(g,y,R){return R=R!=null?R.concat([g]):null,_i(4,36,Tl.bind(null,y,g),R)},useLayoutEffect:function(g,y){return _i(4,36,g,y)},useMemo:function(g,y){var R=Jn();return y=y===void 0?null:y,g=g(),R.memoizedState=[g,y],g},useReducer:function(g,y,R){var F=Jn();return y=R!==void 0?R(y):y,F.memoizedState=F.baseState=y,g=F.queue={last:null,dispatch:null,lastRenderedReducer:g,lastRenderedState:y},g=g.dispatch=zs.bind(null,rn,g),[F.memoizedState,g]},useRef:function(g){var y=Jn();return g={current:g},y.memoizedState=g},useState:Co,useDebugValue:mf,useResponder:Ct,useDeferredValue:function(g,y){var R=Co(g),F=R[0],b=R[1];return rl(function(){_.unstable_next(function(){var J=It.suspense;It.suspense=y===void 0?null:y;try{b(g)}finally{It.suspense=J}})},[g,y]),F},useTransition:function(g){var y=Co(!1),R=y[0],F=y[1];return[I0(function(b){F(!0),_.unstable_next(function(){var J=It.suspense;It.suspense=g===void 0?null:g;try{F(!1),b()}finally{It.suspense=J}})},[g,R]),R]}},_s={readContext:ku,useCallback:gs,useContext:ku,useEffect:vf,useImperativeHandle:function(g,y,R){return R=R!=null?R.concat([g]):null,P0(4,36,Tl.bind(null,y,g),R)},useLayoutEffect:function(g,y){return P0(4,36,g,y)},useMemo:function(g,y){var R=wr();y=y===void 0?null:y;var F=R.memoizedState;return F!==null&&y!==null&&Pt(y,F[1])?F[0]:(g=g(),R.memoizedState=[g,y],g)},useReducer:Lu,useRef:function(){return wr().memoizedState},useState:$o,useDebugValue:mf,useResponder:Ct,useDeferredValue:function(g,y){var R=$o(g),F=R[0],b=R[1];return vf(function(){_.unstable_next(function(){var J=It.suspense;It.suspense=y===void 0?null:y;try{b(g)}finally{It.suspense=J}})},[g,y]),F},useTransition:function(g){var y=$o(!1),R=y[0],F=y[1];return[gs(function(b){F(!0),_.unstable_next(function(){var J=It.suspense;It.suspense=g===void 0?null:g;try{F(!1),b()}finally{It.suspense=J}})},[g,R]),R]}},Qu=null,Tu=null,Ei=!1;function xo(g,y){var R=H0(5,null,null,0);R.elementType="DELETED",R.type="DELETED",R.stateNode=y,R.return=g,R.effectTag=8,g.lastEffect!==null?(g.lastEffect.nextEffect=R,g.lastEffect=R):g.firstEffect=g.lastEffect=R}function e0(g,y){switch(g.tag){case 5:return y=Uu(y,g.type,g.pendingProps),y!==null?(g.stateNode=y,!0):!1;case 6:return y=Xo(y,g.pendingProps),y!==null?(g.stateNode=y,!0):!1;case 13:return!1;default:return!1}}function U0(g){if(Ei){var y=Tu;if(y){var R=y;if(!e0(g,y)){if(y=M0(R),!y||!e0(g,y)){g.effectTag=g.effectTag&-1025|2,Ei=!1,Qu=g;return}xo(Qu,R)}Qu=g,Tu=Po(y)}else g.effectTag=g.effectTag&-1025|2,Ei=!1,Qu=g}}function sa(g){for(g=g.return;g!==null&&g.tag!==5&&g.tag!==3&&g.tag!==13;)g=g.return;Qu=g}function es(g){if(!w||g!==Qu)return!1;if(!Ei)return sa(g),Ei=!0,!1;var y=g.type;if(g.tag!==5||y!=="head"&&y!=="body"&&!dt(y,g.memoizedProps))for(y=Tu;y;)xo(g,y),y=M0(y);if(sa(g),g.tag===13){if(!w)throw Error(t(316));if(g=g.memoizedState,g=g!==null?g.dehydrated:null,!g)throw Error(t(317));Tu=Is(g)}else Tu=Qu?M0(g.stateNode):null;return!0}function tu(){w&&(Tu=Qu=null,Ei=!1)}var ei=M.ReactCurrentOwner,h0=!1;function Bi(g,y,R,F){y.child=g===null?G(y,null,R,F):z(y,g.child,R,F)}function Ci(g,y,R,F,b){R=R.render;var J=y.ref;return F0(y,b),F=un(g,y,R,F,J,b),g!==null&&!h0?(y.updateQueue=g.updateQueue,y.effectTag&=-517,g.expirationTime<=b&&(g.expirationTime=0),yu(g,y,b)):(y.effectTag|=1,Bi(g,y,F,b),y.child)}function yf(g,y,R,F,b,J){if(g===null){var de=R.type;return typeof de=="function"&&!Df(de)&&de.defaultProps===void 0&&R.compare===null&&R.defaultProps===void 0?(y.tag=15,y.type=de,gf(g,y,de,F,b,J)):(g=Wa(R.type,null,F,null,y.mode,J),g.ref=y.ref,g.return=y,y.child=g)}return de=g.child,by)&&Vr.set(g,y)))}}function i0(g,y){g.expirationTimeg?y:g)}function no(g){if(g.lastExpiredTime!==0)g.callbackExpirationTime=1073741823,g.callbackPriority=99,g.callbackNode=Zl(u0.bind(null,g));else{var y=m0(g),R=g.callbackNode;if(y===0)R!==null&&(g.callbackNode=null,g.callbackExpirationTime=0,g.callbackPriority=90);else{var F=wo();if(y===1073741823?F=99:y===1||y===2?F=95:(F=10*(1073741821-y)-10*(1073741821-F),F=0>=F?99:250>=F?98:5250>=F?97:95),R!==null){var b=g.callbackPriority;if(g.callbackExpirationTime===y&&b>=F)return;R!==qr&&bs(R)}g.callbackExpirationTime=y,g.callbackPriority=F,y=y===1073741823?Zl(u0.bind(null,g)):nl(F,j0.bind(null,g),{timeout:10*(1073741821-y)-mo()}),g.callbackNode=y}}}function j0(g,y){if(ru=0,y)return y=wo(),pa(g,y),no(g),null;var R=m0(g);if(R!==0){if(y=g.callbackNode,(Fn&(nu|cu))!==Rr)throw Error(t(327));if(Ws(),g===ae&&R===Fe||ws(g,R),ie!==null){var F=Fn;Fn|=nu;var b=jo(g);do try{rd();break}catch(gt){ca(g,gt)}while(1);if(zu(),Fn=F,$u.current=b,Oe===ni)throw y=st,ws(g,R),Ol(g,R),no(g),y;if(ie===null)switch(b=g.finishedWork=g.current.alternate,g.finishedExpirationTime=R,F=Oe,ae=null,F){case Ni:case ni:throw Error(t(345));case Kn:pa(g,2=R){g.lastPingedTime=R,ws(g,R);break}}if(J=m0(g),J!==0&&J!==R)break;if(F!==0&&F!==R){g.lastPingedTime=F;break}g.timeoutHandle=an(Rl.bind(null,g),b);break}Rl(g);break;case Eo:if(Ol(g,R),F=g.lastSuspendedTime,R===F&&(g.nextKnownPendingLevel=qc(b)),_n&&(b=g.lastPingedTime,b===0||b>=R)){g.lastPingedTime=R,ws(g,R);break}if(b=m0(g),b!==0&&b!==R)break;if(F!==0&&F!==R){g.lastPingedTime=F;break}if(Jt!==1073741823?F=10*(1073741821-Jt)-mo():yt===1073741823?F=0:(F=10*(1073741821-yt)-5e3,b=mo(),R=10*(1073741821-R)-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,R=F?F=0:(b=de.busyDelayMs|0,J=mo()-(10*(1073741821-J)-(de.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))}Oe!==Do&&(Oe=Kn),J=Cl(J,b),xt=F;do{switch(xt.tag){case 3:de=J,xt.effectTag|=4096,xt.expirationTime=y;var ze=Es(xt,de,y);oa(xt,ze);break e;case 1:de=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=y;var Wn=fa(xt,de,y);oa(xt,Wn);break e}}xt=xt.return}while(xt!==null)}ie=y0(ie)}catch(si){y=si;continue}break}while(1)}function jo(){var g=$u.current;return $u.current=b0,g===null?b0:g}function dc(g,y){gSn&&(Sn=g)}function D2(){for(;ie!==null;)ie=id(ie)}function rd(){for(;ie!==null&&!$n();)ie=id(ie)}function id(g){var y=qa(g.alternate,g,Fe);return g.memoizedProps=g.pendingProps,y===null&&(y=y0(g)),Ds.current=null,y}function y0(g){ie=g;do{var y=ie.alternate;if(g=ie.return,(ie.effectTag&2048)==0){e:{var R=y;y=ie;var F=Fe,b=y.pendingProps;switch(y.tag){case 2:break;case 16:break;case 15:case 0:break;case 1:eu(y.type)&&Jo(y);break;case 3:Je(y),Yi(y),b=y.stateNode,b.pendingContext&&(b.context=b.pendingContext,b.pendingContext=null),(R===null||R.child===null)&&es(y)&&Ju(y),Jr(y);break;case 5:oe(y);var J=Z(Ae.current);if(F=y.type,R!==null&&y.stateNode!=null)Wu(R,y,F,b,J),R.ref!==y.ref&&(y.effectTag|=128);else if(b){if(R=Z(Ce.current),es(y)){if(b=y,!w)throw Error(t(175));R=au(b.stateNode,b.type,b.memoizedProps,J,R,b),b.updateQueue=R,R=R!==null,R&&Ju(y)}else{var de=fe(F,b,J,R,y);ti(de,y,!1,!1),y.stateNode=de,le(de,F,b,J,R)&&Ju(y)}y.ref!==null&&(y.effectTag|=128)}else if(y.stateNode===null)throw Error(t(166));break;case 6:if(R&&y.stateNode!=null)Rn(R,y,R.memoizedProps,b);else{if(typeof b!="string"&&y.stateNode===null)throw Error(t(166));if(R=Z(Ae.current),J=Z(Ce.current),es(y)){if(R=y,!w)throw Error(t(176));(R=ki(R.stateNode,R.memoizedProps,R))&&Ju(y)}else y.stateNode=nn(b,R,J,y)}break;case 11:break;case 13:if(yi(We,y),b=y.memoizedState,(y.effectTag&64)!=0){y.expirationTime=F;break e}b=b!==null,J=!1,R===null?y.memoizedProps.fallback!==void 0&&es(y):(F=R.memoizedState,J=F!==null,b||F===null||(F=R.child.sibling,F!==null&&(de=y.firstEffect,de!==null?(y.firstEffect=F,F.nextEffect=de):(y.firstEffect=y.lastEffect=F,F.nextEffect=null),F.effectTag=8))),b&&!J&&(y.mode&2)!=0&&(R===null&&y.memoizedProps.unstable_avoidThisFallback!==!0||(We.current&1)!=0?Oe===Ni&&(Oe=eo):((Oe===Ni||Oe===eo)&&(Oe=Eo),Sn!==0&&ae!==null&&(Ol(ae,Fe),Cs(ae,Sn)))),Er&&b&&(y.effectTag|=4),Gt&&(b||J)&&(y.effectTag|=4);break;case 7:break;case 8:break;case 12:break;case 4:Je(y),Jr(y);break;case 10:Su(y);break;case 9:break;case 14:break;case 17:eu(y.type)&&Jo(y);break;case 19:if(yi(We,y),b=y.memoizedState,b===null)break;if(J=(y.effectTag&64)!=0,de=b.rendering,de===null){if(J)Fu(b,!1);else if(Oe!==Ni||R!==null&&(R.effectTag&64)!=0)for(R=y.child;R!==null;){if(de=it(R),de!==null){for(y.effectTag|=64,Fu(b,!1),R=de.updateQueue,R!==null&&(y.updateQueue=R,y.effectTag|=4),b.lastEffect===null&&(y.firstEffect=null),y.lastEffect=b.lastEffect,R=F,b=y.child;b!==null;)J=b,F=R,J.effectTag&=2,J.nextEffect=null,J.firstEffect=null,J.lastEffect=null,de=J.alternate,de===null?(J.childExpirationTime=0,J.expirationTime=F,J.child=null,J.memoizedProps=null,J.memoizedState=null,J.updateQueue=null,J.dependencies=null):(J.childExpirationTime=de.childExpirationTime,J.expirationTime=de.expirationTime,J.child=de.child,J.memoizedProps=de.memoizedProps,J.memoizedState=de.memoizedState,J.updateQueue=de.updateQueue,F=de.dependencies,J.dependencies=F===null?null:{expirationTime:F.expirationTime,firstContext:F.firstContext,responders:F.responders}),b=b.sibling;en(We,We.current&1|2,y),y=y.child;break e}R=R.sibling}}else{if(!J)if(R=it(de),R!==null){if(y.effectTag|=64,J=!0,R=R.updateQueue,R!==null&&(y.updateQueue=R,y.effectTag|=4),Fu(b,!0),b.tail===null&&b.tailMode==="hidden"&&!de.alternate){y=y.lastEffect=b.lastEffect,y!==null&&(y.nextEffect=null);break}}else mo()>b.tailExpiration&&1b&&(b=F),de>b&&(b=de),J=J.sibling;R.childExpirationTime=b}if(y!==null)return y;g!==null&&(g.effectTag&2048)==0&&(g.firstEffect===null&&(g.firstEffect=ie.firstEffect),ie.lastEffect!==null&&(g.lastEffect!==null&&(g.lastEffect.nextEffect=ie.firstEffect),g.lastEffect=ie.lastEffect),1g?y:g}function Rl(g){var y=vs();return d0(99,ul.bind(null,g,y)),null}function ul(g,y){do Ws();while(ri!==null);if((Fn&(nu|cu))!==Rr)throw Error(t(327));var R=g.finishedWork,F=g.finishedExpirationTime;if(R===null)return null;if(g.finishedWork=null,g.finishedExpirationTime=0,R===g.current)throw Error(t(177));g.callbackNode=null,g.callbackExpirationTime=0,g.callbackPriority=90,g.nextKnownPendingLevel=0;var b=qc(R);if(g.firstPendingTime=b,F<=g.lastSuspendedTime?g.firstSuspendedTime=g.lastSuspendedTime=g.nextKnownPendingLevel=0:F<=g.firstSuspendedTime&&(g.firstSuspendedTime=F-1),F<=g.lastPingedTime&&(g.lastPingedTime=0),F<=g.lastExpiredTime&&(g.lastExpiredTime=0),g===ae&&(ie=ae=null,Fe=0),1=R?Xt(g,y,R):(en(We,We.current&1,y),y=yu(g,y,R),y!==null?y.sibling:null);en(We,We.current&1,y);break;case 19:if(F=y.childExpirationTime>=R,(g.effectTag&64)!=0){if(F)return xn(g,y,R);y.effectTag|=64}if(b=y.memoizedState,b!==null&&(b.rendering=null,b.tail=null),en(We,We.current,y),!F)return null}return yu(g,y,R)}h0=!1}}else h0=!1;switch(y.expirationTime=0,y.tag){case 2:if(F=y.type,g!==null&&(g.alternate=null,y.alternate=null,y.effectTag|=2),g=y.pendingProps,b=Au(y,Ai.current),F0(y,R),b=un(null,y,F,g,b,R),y.effectTag|=1,typeof b=="object"&&b!==null&&typeof b.render=="function"&&b.$$typeof===void 0){if(y.tag=1,fn(),eu(F)){var J=!0;ai(y)}else J=!1;y.memoizedState=b.state!==null&&b.state!==void 0?b.state:null;var de=F.getDerivedStateFromProps;typeof de=="function"&&$l(y,F,de,g),b.updater=la,y.stateNode=b,b._reactInternalFiber=y,Us(y,F,g,R),y=rt(null,y,F,!0,J,R)}else y.tag=0,Bi(null,y,b,R),y=y.child;return y;case 16:if(b=y.elementType,g!==null&&(g.alternate=null,y.alternate=null,y.effectTag|=2),g=y.pendingProps,we(b),b._status!==1)throw b._result;switch(b=b._result,y.type=b,J=y.tag=ol(b),g=Yn(b,g),J){case 0:y=n0(null,y,b,g,R);break;case 1:y=Re(null,y,b,g,R);break;case 11:y=Ci(null,y,b,g,R);break;case 14:y=yf(null,y,b,Yn(b.type,g),F,R);break;default:throw Error(t(306,b,""))}return y;case 0:return F=y.type,b=y.pendingProps,b=y.elementType===F?b:Yn(F,b),n0(g,y,F,b,R);case 1:return F=y.type,b=y.pendingProps,b=y.elementType===F?b:Yn(F,b),Re(g,y,F,b,R);case 3:if(Ye(y),F=y.updateQueue,F===null)throw Error(t(282));if(b=y.memoizedState,b=b!==null?b.element:null,To(y,F,y.pendingProps,null,R),F=y.memoizedState.element,F===b)tu(),y=yu(g,y,R);else{if((b=y.stateNode.hydrate)&&(w?(Tu=Po(y.stateNode.containerInfo),Qu=y,b=Ei=!0):b=!1),b)for(R=G(y,null,F,R),y.child=R;R;)R.effectTag=R.effectTag&-3|1024,R=R.sibling;else Bi(g,y,F,R),tu();y=y.child}return y;case 5:return mt(y),g===null&&U0(y),F=y.type,b=y.pendingProps,J=g!==null?g.memoizedProps:null,de=b.children,dt(F,b)?de=null:J!==null&&dt(F,J)&&(y.effectTag|=16),t0(g,y),y.mode&4&&R!==1&&Rt(F,b)?(y.expirationTime=y.childExpirationTime=1,y=null):(Bi(g,y,de,R),y=y.child),y;case 6:return g===null&&U0(y),null;case 13:return Xt(g,y,R);case 4:return ke(y,y.stateNode.containerInfo),F=y.pendingProps,g===null?y.child=z(y,null,F,R):Bi(g,y,F,R),y.child;case 11:return F=y.type,b=y.pendingProps,b=y.elementType===F?b:Yn(F,b),Ci(g,y,F,b,R);case 7:return Bi(g,y,y.pendingProps,R),y.child;case 8:return Bi(g,y,y.pendingProps.children,R),y.child;case 12:return Bi(g,y,y.pendingProps.children,R),y.child;case 10:e:{if(F=y.type._context,b=y.pendingProps,de=y.memoizedProps,J=b.value,Hu(y,J),de!==null){var gt=de.value;if(J=Ne(gt,J)?0:(typeof F._calculateChangedBits=="function"?F._calculateChangedBits(gt,J):1073741823)|0,J===0){if(de.children===b.children&&!gi.current){y=yu(g,y,R);break e}}else for(gt=y.child,gt!==null&&(gt.return=y);gt!==null;){var xt=gt.dependencies;if(xt!==null){de=gt.child;for(var Lt=xt.firstContext;Lt!==null;){if(Lt.context===F&&(Lt.observedBits&J)!=0){gt.tag===1&&(Lt=yo(R,null),Lt.tag=2,Zo(gt,Lt)),gt.expirationTime=y&&g<=y}function Ol(g,y){var R=g.firstSuspendedTime,F=g.lastSuspendedTime;Ry||R===0)&&(g.lastSuspendedTime=y),y<=g.lastPingedTime&&(g.lastPingedTime=0),y<=g.lastExpiredTime&&(g.lastExpiredTime=0)}function Cs(g,y){y>g.firstPendingTime&&(g.firstPendingTime=y);var R=g.firstSuspendedTime;R!==0&&(y>=R?g.firstSuspendedTime=g.lastSuspendedTime=g.nextKnownPendingLevel=0:y>=g.lastSuspendedTime&&(g.lastSuspendedTime=y+1),y>g.nextKnownPendingLevel&&(g.nextKnownPendingLevel=y))}function pa(g,y){var R=g.lastExpiredTime;(R===0||R>y)&&(g.lastExpiredTime=y)}function od(g){var y=g._reactInternalFiber;if(y===void 0)throw typeof g.render=="function"?Error(t(188)):Error(t(268,Object.keys(g)));return g=Xe(y),g===null?null:g.stateNode}function ha(g,y){g=g.memoizedState,g!==null&&g.dehydrated!==null&&g.retryTime{"use strict";Object.defineProperty(tc,"__esModule",{value:!0});var jI=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++jI};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 dT=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 _(ue){if(!i)return ue();var _e=mu.__interactionsRef.current;mu.__interactionsRef.current=new Set;try{return ue()}finally{mu.__interactionsRef.current=_e}}function t(){return i?mu.__interactionsRef.current:null}function M(){return++c}function N(ue,_e,ce){var me=arguments.length>3&&arguments[3]!==void 0?arguments[3]:o;if(!i)return ce();var re={__count:1,id:a++,name:ue,timestamp:_e},we=mu.__interactionsRef.current,Ie=new Set(we);Ie.add(re),mu.__interactionsRef.current=Ie;var je=mu.__subscriberRef.current,ct;try{je!==null&&je.onInteractionTraced(re)}finally{try{je!==null&&je.onWorkStarted(Ie,me)}finally{try{ct=ce()}finally{mu.__interactionsRef.current=we;try{je!==null&&je.onWorkStopped(Ie,me)}finally{re.__count--,je!==null&&re.__count===0&&je.onInteractionScheduledWorkCompleted(re)}}}}return ct}function O(ue){var _e=arguments.length>1&&arguments[1]!==void 0?arguments[1]:o;if(!i)return ue;var ce=mu.__interactionsRef.current,me=mu.__subscriberRef.current;me!==null&&me.onWorkScheduled(ce,_e),ce.forEach(function(Ie){Ie.__count++});var re=!1;function we(){var Ie=mu.__interactionsRef.current;mu.__interactionsRef.current=ce,me=mu.__subscriberRef.current;try{var je;try{me!==null&&me.onWorkStarted(ce,_e)}finally{try{je=ue.apply(void 0,arguments)}finally{mu.__interactionsRef.current=Ie,me!==null&&me.onWorkStopped(ce,_e)}}return je}finally{re||(re=!0,ce.forEach(function(ct){ct.__count--,me!==null&&ct.__count===0&&me.onInteractionScheduledWorkCompleted(ct)}))}}return we.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)})}},we}var T=null;i&&(T=new Set);function B(ue){i&&(T.add(ue),T.size===1&&(mu.__subscriberRef.current={onInteractionScheduledWorkCompleted:ne,onInteractionTraced:q,onWorkCanceled:ve,onWorkScheduled:m,onWorkStarted:pe,onWorkStopped:ge}))}function H(ue){i&&(T.delete(ue),T.size===0&&(mu.__subscriberRef.current=null))}function q(ue){var _e=!1,ce=null;if(T.forEach(function(me){try{me.onInteractionTraced(ue)}catch(re){_e||(_e=!0,ce=re)}}),_e)throw ce}function ne(ue){var _e=!1,ce=null;if(T.forEach(function(me){try{me.onInteractionScheduledWorkCompleted(ue)}catch(re){_e||(_e=!0,ce=re)}}),_e)throw ce}function m(ue,_e){var ce=!1,me=null;if(T.forEach(function(re){try{re.onWorkScheduled(ue,_e)}catch(we){ce||(ce=!0,me=we)}}),ce)throw me}function pe(ue,_e){var ce=!1,me=null;if(T.forEach(function(re){try{re.onWorkStarted(ue,_e)}catch(we){ce||(ce=!0,me=we)}}),ce)throw me}function ge(ue,_e){var ce=!1,me=null;if(T.forEach(function(re){try{re.onWorkStopped(ue,_e)}catch(we){ce||(ce=!0,me=we)}}),ce)throw me}function ve(ue,_e){var ce=!1,me=null;if(T.forEach(function(re){try{re.onWorkCanceled(ue,_e)}catch(we){ce||(ce=!0,me=we)}}),ce)throw me}mu.unstable_clear=_,mu.unstable_getCurrent=t,mu.unstable_getThreadID=M,mu.unstable_trace=N,mu.unstable_wrap=O,mu.unstable_subscribe=B,mu.unstable_unsubscribe=H}()});var pT=Ke((jW,PD)=>{"use strict";process.env.NODE_ENV==="production"?PD.exports=cT():PD.exports=dT()});var hT=Ke((zW,Qy)=>{"use strict";process.env.NODE_ENV!=="production"&&(Qy.exports=function i(o){"use strict";var a=Iy(),c=Mi(),_=hD(),t=Q_(),M=pT(),N=0,O=1,T=2,B=3,H=4,q=5,ne=6,m=7,pe=8,ge=9,ve=10,ue=11,_e=12,ce=13,me=14,re=15,we=16,Ie=17,je=18,ct=19,pt=20,Xe=21,tt=function(){};tt=function(f,d){for(var E=arguments.length,C=new Array(E>2?E-2:0),A=2;A8)throw new Error("warningWithoutStack() currently supports at most 8 arguments.");if(!f){if(typeof console!="undefined"){var j=C.map(function(se){return""+se});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(se){}}};var He=tt;function kt(f){return f._reactInternalFiber}function zt(f,d){f._reactInternalFiber=d}var nt=c.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;nt.hasOwnProperty("ReactCurrentDispatcher")||(nt.ReactCurrentDispatcher={current:null}),nt.hasOwnProperty("ReactCurrentBatchConfig")||(nt.ReactCurrentBatchConfig={suspense:null});var X=typeof Symbol=="function"&&Symbol.for,fe=X?Symbol.for("react.element"):60103,xe=X?Symbol.for("react.portal"):60106,le=X?Symbol.for("react.fragment"):60107,qe=X?Symbol.for("react.strict_mode"):60108,dt=X?Symbol.for("react.profiler"):60114,Rt=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,Gt=X?Symbol.for("react.memo"):60115,Er=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=He;zr=function(f,d){if(!f){for(var E=nt.ReactDebugCurrentFrame,C=E.getStackAddendum(),A=arguments.length,j=new Array(A>2?A-2:0),V=2;V import('./MyComponent'))`,C),f._status=A0,f._result=A}},function(C){f._status===po&&(f._status=J0,f._result=C)})}}function $0(f,d,E){var C=d.displayName||d.name||"";return f.displayName||(C!==""?E+"("+C+")":E)}function Wt(f){if(f==null)return null;if(typeof f.tag=="number"&&He(!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 le:return"Fragment";case xe:return"Portal";case dt:return"Profiler";case qe:return"StrictMode";case lr:return"Suspense";case ln:return"SuspenseList"}if(typeof f=="object")switch(f.$$typeof){case nn:return"Context.Consumer";case Rt:return"Context.Provider";case Mn:return $0(f,f.render,"ForwardRef");case Gt:return Wt(f.type);case Er:{var d=f,E=Ps(d);if(E)return Wt(E);break}}return null}var xi=0,su=1,mi=2,Dr=4,el=6,Ko=8,Uu=16,Xo=32,Xr=64,O0=128,M0=256,Po=512,au=1024,ki=1028,Is=932,Xl=2047,Io=2048,ho=4096,Hr=!0,Ri=!0,Qo=!0,yi=!0,en=!0,bn=!0,Ai=!1,gi=!1,Vt=!1,Au=!1,eu=!1,Jo=!0,Yi=!1,Ql=!1,k0=!1,ai=!1,f0=!1,Jl=nt.ReactCurrentOwner;function L0(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))!==xi&&(E=d.return),C=d.return;while(C)}return d.tag===B?E:null}function bs(f){return L0(f)===f}function $n(f){{var d=Jl.current;if(d!==null&&d.tag===O){var E=d,C=E.stateNode;C._warnedAboutRefsInRender||He(!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.",Wt(E.type)||"A component"),C._warnedAboutRefsInRender=!0}}var A=kt(f);return A?L0(A)===A:!1}function tl(f){if(L0(f)!==f)throw Error("Unable to find node on an unmounted component.")}function c0(f){var d=f.alternate;if(!d){var E=L0(f);if(E===null)throw Error("Unable to find node on an unmounted component.");return E!==f?null:f}for(var C=f,A=d;;){var j=C.return;if(j===null)break;var V=j.alternate;if(V===null){var te=j.return;if(te!==null){C=A=te;continue}break}if(j.child===V.child){for(var se=j.child;se;){if(se===C)return tl(j),f;if(se===A)return tl(j),d;se=se.sibling}throw Error("Unable to find node on an unmounted component.")}if(C.return!==A.return)C=j,A=V;else{for(var Ue=!1,Qe=j.child;Qe;){if(Qe===C){Ue=!0,C=j,A=V;break}if(Qe===A){Ue=!0,A=j,C=V;break}Qe=Qe.sibling}if(!Ue){for(Qe=V.child;Qe;){if(Qe===C){Ue=!0,C=V,A=j;break}if(Qe===A){Ue=!0,A=V,C=j;break}Qe=Qe.sibling}if(!Ue)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!==A)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 bo(f){var d=c0(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=c0(f);if(!d)return null;for(var E=d;;){if(E.tag===q||E.tag===ne||Vt&&E.tag===pt)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 N0=o.getPublicInstance,wt=o.getRootHostContext,bt=o.getChildHostContext,Hn=o.prepareForCommit,qr=o.resetAfterCommit,Ki=o.createInstance,Qr=o.appendInitialChild,Ou=o.finalizeInitialChildren,vo=o.prepareUpdate,Li=o.shouldSetTextContent,mo=o.shouldDeprioritizeSubtree,vs=o.createTextInstance,Tt=o.setTimeout,d0=o.clearTimeout,nl=o.noTimeout,Zl=o.now,ju=o.isPrimaryRenderer,ms=o.warnsIfNotActing,Bo=o.supportsMutation,Q=o.supportsPersistence,Se=o.supportsHydration,Ne=o.mountResponderInstance,Le=o.unmountResponderInstance,ht=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,F0=o.insertInContainerBefore,ku=o.removeChild,p0=o.removeChildFromContainer,qu=o.resetTextContent,Ia=o.hideInstance,yo=o.hideTextInstance,ua=o.unhideInstance,Zo=o.unhideTextInstance,oa=o.updateFundamentalComponent,ba=o.unmountFundamentalComponent,ys=o.cloneInstance,To=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,go=o.isSuspenseInstanceFallback,js=o.registerSuspenseInstanceRetry,ji=o.getNextHydratableSibling,U=o.getFirstHydratableChild,z=o.hydrateInstance,G=o.hydrateTextInstance,$=o.hydrateSuspenseInstance,Ce=o.getNextHydratableInstanceAfterSuspenseInstance,Ee=o.commitHydratedContainer,Ae=o.commitHydratedSuspenseInstance,Z=o.clearSuspenseBoundary,ke=o.clearSuspenseBoundaryFromContainer,Je=o.didNotMatchHydratedContainerTextInstance,mt=o.didNotMatchHydratedTextInstance,oe=o.didNotHydrateContainerInstance,We=o.didNotHydrateInstance,it=o.didNotFindHydratableContainerInstance,Ct=o.didNotFindHydratableContainerTextInstance,Mt=o.didNotFindHydratableContainerSuspenseInstance,It=o.didNotFindHydratableInstance,sn=o.didNotFindHydratableTextInstance,rn=o.didNotFindHydratableSuspenseInstance,Ft=/^(.*)[\\\/]/,Dn=function(f,d,E){var C="";if(d){var A=d.fileName,j=A.replace(Ft,"");if(/^index\./.test(j)){var V=A.match(Ft);if(V){var te=V[1];if(te){var se=te.replace(Ft,"");j=se+"/"+j}}}C=" (at "+j+":"+d.lineNumber+")"}else E&&(C=" (created by "+E+")");return` - in `+(f||"Unknown")+C},dr=nt.ReactDebugCurrentFrame;function er(f){switch(f.tag){case B:case H:case ne:case m:case ve:case ge:return"";default:var d=f._debugOwner,E=f._debugSource,C=Wt(f.type),A=null;return d&&(A=Wt(d.type)),Dn(C,E,A)}}function Cr(f){var d="",E=f;do d+=er(E),E=E.return;while(E);return d}var An=null,Lr=null;function _o(){{if(An===null)return null;var f=An._debugOwner;if(f!==null&&typeof f!="undefined")return Wt(f.type)}return null}function Nr(){return An===null?"":Cr(An)}function ut(){dr.getCurrentStack=null,An=null,Lr=null}function Dt(f){dr.getCurrentStack=Nr,An=f,Lr=null}function et(f){Lr=f}var Pt="\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,wr=null,fu=null,Lu=!1,Co=!1,$o=!1,Nu=0,_i=0,P0=new Set,rl=function(f){return Pt+" "+f},vf=function(f,d){var E=d?un+" ":Pt+" ",C=d?" Warning: "+d:"";return""+E+f+C},Tl=function(f){performance.mark(rl(f))},mf=function(f){performance.clearMarks(rl(f))},I0=function(f,d,E){var C=rl(d),A=vf(f,E);try{performance.measure(A,C)}catch(j){}performance.clearMarks(C),performance.clearMeasures(A)},gs=function(f,d){return f+" (#"+d+")"},zs=function(f,d,E){return E===null?f+" ["+(d?"update":"mount")+"]":f+"."+E},b0=function(f,d){var E=Wt(f.type)||"Unknown",C=f._debugID,A=f.alternate!==null,j=zs(E,A,d);if(Lu&&P0.has(j))return!1;P0.add(j);var V=gs(j,C);return Tl(V),!0},B0=function(f,d){var E=Wt(f.type)||"Unknown",C=f._debugID,A=f.alternate!==null,j=zs(E,A,d),V=gs(j,C);mf(V)},_s=function(f,d,E){var C=Wt(f.type)||"Unknown",A=f._debugID,j=f.alternate!==null,V=zs(C,j,d),te=gs(V,A);I0(V,te,E)},Qu=function(f){switch(f.tag){case B:case q:case ne:case H:case m:case ve:case ge:case pe:return!0;default:return!1}},Tu=function(){wr!==null&&fu!==null&&B0(fu,wr),fu=null,wr=null,$o=!1},Ei=function(){for(var f=Jn;f;)f._debugIsCurrentlyTiming&&_s(f,null,null),f=f.return},xo=function(f){f.return!==null&&xo(f.return),f._debugIsCurrentlyTiming&&b0(f,null)},e0=function(){Jn!==null&&xo(Jn)};function U0(){Hr&&_i++}function sa(){Hr&&(Lu&&(Co=!0),wr!==null&&wr!=="componentWillMount"&&wr!=="componentWillReceiveProps"&&($o=!0))}function es(f){if(Hr){if(!fn||Qu(f)||(Jn=f,!b0(f,null)))return;f._debugIsCurrentlyTiming=!0}}function tu(f){if(Hr){if(!fn||Qu(f))return;f._debugIsCurrentlyTiming=!1,B0(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 h0(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(),!b0(f,d)))return;fu=f,wr=d}}function Ci(){if(Hr){if(!fn)return;if(wr!==null&&fu!==null){var f=$o?"Scheduled a cascading update":null;_s(fu,wr,f)}wr=null,fu=null}}function yf(f){if(Hr){if(Jn=f,!fn)return;Nu=0,Tl("(React Tree Reconciliation)"),e0()}}function gf(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=Wt(f.type)||"Unknown";E="An update to "+C+" interrupted the previous render"}else Nu>1&&(E="There were cascading updates");Nu=0;var A=d?"(React Tree Reconciliation: Completed Root)":"(React Tree Reconciliation: Yielded)";Ei(),I0(A,"(React Tree Reconciliation)",E)}}function t0(){if(Hr){if(!fn)return;Lu=!0,Co=!1,P0.clear(),Tl("(Committing Changes)")}}function n0(){if(Hr){if(!fn)return;var f=null;Co?f="Lifecycle hook scheduled a cascading update":Nu>0&&(f="Caused by a cascading update in earlier commit"),Co=!1,Nu++,Lu=!1,P0.clear(),I0("(Committing Changes)","(Committing Changes)",f)}}function Re(){if(Hr){if(!fn)return;_i=0,Tl("(Committing Snapshot Effects)")}}function rt(){if(Hr){if(!fn)return;var f=_i;_i=0,I0("(Committing Snapshot Effects: "+f+" Total)","(Committing Snapshot Effects)",null)}}function Ye(){if(Hr){if(!fn)return;_i=0,Tl("(Committing Host Effects)")}}function Kt(){if(Hr){if(!fn)return;var f=_i;_i=0,I0("(Committing Host Effects: "+f+" Total)","(Committing Host Effects)",null)}}function Xt(){if(Hr){if(!fn)return;_i=0,Tl("(Calling Lifecycle Methods)")}}function pr(){if(Hr){if(!fn)return;var f=_i;_i=0,I0("(Calling Lifecycle Methods: "+f+" Total)","(Calling Lifecycle Methods)",null)}}var Wr=[],xn;xn=[];var yu=-1;function Ju(f){return{current:f}}function ti(f,d){if(yu<0){He(!1,"Unexpected pop.");return}d!==xn[yu]&&He(!1,"Unexpected Fiber popped."),f.current=Wr[yu],Wr[yu]=null,xn[yu]=null,yu--}function Jr(f,d,E){yu++,Wr[yu]=f.current,xn[yu]=E,f.current=d}var Wu;Wu={};var Rn={};Object.freeze(Rn);var Ro=Ju(Rn),Fu=Ju(!1),li=Rn;function Cl(f,d,E){return ai?Rn:E&&Xi(d)?li:Ro.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 Rn;var E=f.type,C=E.contextTypes;if(!C)return Rn;var A=f.stateNode;if(A&&A.__reactInternalMemoizedUnmaskedChildContext===d)return A.__reactInternalMemoizedMaskedChildContext;var j={};for(var V in C)j[V]=d[V];{var te=Wt(E)||"Unknown";_(C,j,"context",te,Nr)}return A&&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(Ro,f))}function Ao(f){ai||(ti(Fu,f),ti(Ro,f))}function zi(f,d,E){if(!ai){if(Ro.current!==Rn)throw Error("Unexpected context found on stack. This error is likely caused by a bug in React. Please file an issue.");Jr(Ro,d,f),Jr(Fu,E,f)}}function Oo(f,d,E){if(ai)return E;var C=f.stateNode,A=d.childContextTypes;if(typeof C.getChildContext!="function"){{var j=Wt(d)||"Unknown";Wu[j]||(Wu[j]=!0,He(!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 A))throw Error((Wt(d)||"Unknown")+'.getChildContext(): key "'+te+'" is not defined in childContextTypes.');{var se=Wt(d)||"Unknown";_(A,V,"child context",se,Nr)}return a({},E,{},V)}function Hi(f){if(ai)return!1;var d=f.stateNode,E=d&&d.__reactInternalMemoizedMergedChildContext||Rn;return li=Ro.current,Jr(Ro,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 A=Oo(f,d,li);C.__reactInternalMemoizedMergedChildContext=A,ti(Fu,f),ti(Ro,f),Jr(Ro,A,f),Jr(Fu,E,f)}else ti(Fu,f),Jr(Fu,E,f)}}function xl(f){if(ai)return Rn;if(!(bs(f)&&f.tag===O))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 O:{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 Uo=1,Mo=2,v0=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,Rr=t.unstable_NormalPriority,r0=t.unstable_LowPriority,nu=t.unstable_IdlePriority;if(bn&&!(M.__interactionsRef!=null&&M.__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={},Ni=99,ni=98,Kn=97,eo=96,Eo=95,Do=90,Fn=ts,ae=Es!==void 0?Es:function(){},ie=null,Fe=null,Oe=!1,st=fa(),yt=st<1e4?fa:function(){return fa()-st};function Jt(){switch(_f()){case $u:return Ni;case Ds:return ni;case Rr:return Kn;case r0:return eo;case nu:return Eo;default:throw Error("Unknown priority level.")}}function On(f){switch(f){case Ni:return $u;case ni:return Ds;case Kn:return Rr;case eo:return r0;case Eo:return nu;default:throw Error("Unknown priority level.")}}function Sn(f,d){var E=On(f);return v0(E,d)}function _n(f,d,E){var C=On(f);return Pu(C,d,E)}function Tn(f){return ie===null?(ie=[f],Fe=Pu($u,Fi)):ie.push(f),cu}function ir(f){f!==cu&&Zu(f)}function Bt(){if(Fe!==null){var f=Fe;Fe=null,Zu(f)}Fi()}function Fi(){if(!Oe&&ie!==null){Oe=!0;var f=0;try{var d=!0,E=ie;Sn(Ni,function(){for(;f1?d-1:0),C=1;C2?E-2:0),A=2;A0&&(za.forEach(function(Nt){f.add(Wt(Nt.type)||"Component"),ns.add(Nt.type)}),za=[]);var d=new Set;Ha.length>0&&(Ha.forEach(function(Nt){d.add(Wt(Nt.type)||"Component"),ns.add(Nt.type)}),Ha=[]);var E=new Set;qa.length>0&&(qa.forEach(function(Nt){E.add(Wt(Nt.type)||"Component"),ns.add(Nt.type)}),qa=[]);var C=new Set;da.length>0&&(da.forEach(function(Nt){C.add(Wt(Nt.type)||"Component"),ns.add(Nt.type)}),da=[]);var A=new Set;Ss.length>0&&(Ss.forEach(function(Nt){A.add(Wt(Nt.type)||"Component"),ns.add(Nt.type)}),Ss=[]);var j=new Set;if(Ts.length>0&&(Ts.forEach(function(Nt){j.add(Wt(Nt.type)||"Component"),ns.add(Nt.type)}),Ts=[]),d.size>0){var V=z0(d);He(!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=z0(C);He(!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 se=z0(j);He(!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`,se)}if(f.size>0){var Ue=z0(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`,Ue)}if(E.size>0){var Qe=z0(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`,Qe)}if(A.size>0){var vt=z0(A);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`,vt)}};var H0=new Map,Df=new Set;Al.recordLegacyContextWarning=function(f,d){var E=ud(f);if(E===null){He(!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=H0.get(E);(f.type.contextTypes!=null||f.type.childContextTypes!=null||d!==null&&typeof d.getChildContext=="function")&&(C===void 0&&(C=[],H0.set(E,C)),C.push(f))}},Al.flushLegacyContextWarning=function(){H0.forEach(function(f,d){var E=new Set;f.forEach(function(j){E.add(Wt(j.type)||"Component"),Df.add(j.type)});var C=z0(E),A=Cr(d);He(!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,A)})},Al.discardPendingWarnings=function(){za=[],Ha=[],qa=[],da=[],Ss=[],Ts=[],H0=new Map}}var ol=null,Gu=null,Wa=function(f){ol=f};function ro(f){{if(ol===null)return f;var d=ol(f);return d===void 0?f:d.current}}function zo(f){return ro(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=ro(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,A=!1,j=typeof C=="object"&&C!==null?C.$$typeof:null;switch(f.tag){case O:{typeof C=="function"&&(A=!0);break}case N:{(typeof C=="function"||j===Er)&&(A=!0);break}case ue:{(j===Mn||j===Er)&&(A=!0);break}case me:case re:{(j===Gt||j===Er)&&(A=!0);break}default:return!1}if(A){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!==Rn)return;nf(),pv(function(){o_(d,f,null,null)})}};function pa(f,d,E){{var C=f.alternate,A=f.child,j=f.sibling,V=f.tag,te=f.type,se=null;switch(V){case N:case re:case O:se=te;break;case ue:se=te.render;break;default:break}if(ol===null)throw new Error("Expected resolveFamily to be set during hot reload.");var Ue=!1,Qe=!1;if(se!==null){var vt=ol(se);vt!==void 0&&(E.has(vt)?Qe=!0:d.has(vt)&&(V===O?Qe=!0:Ue=!0))}Gu!==null&&(Gu.has(f)||C!==null&&Gu.has(C))&&(Qe=!0),Qe&&(f._debugNeedsRemount=!0),(Qe||Ue)&&yl(f,Un),A!==null&&!Qe&&pa(A,d,E),j!==null&&pa(j,d,E)}}var od=function(f,d){{var E=new Set,C=new Set(d.map(function(A){return A.current}));return ha(f.current,C,E),E}};function ha(f,d,E){{var C=f.child,A=f.sibling,j=f.tag,V=f.type,te=null;switch(j){case N:case re:case O:te=V;break;case ue:te=V.render;break;default:break}var se=!1;te!==null&&d.has(te)&&(se=!0),se?hc(f,E):C!==null&&ha(C,d,E),A!==null&&ha(A,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 A in C)E[A]===void 0&&(E[A]=C[A]);return E}return d}function g(f){if(Z0(f),f._status!==A0)throw f._result;return f._result}var y=Ju(null),R;R={};var F=null,b=null,J=null,de=!1;function gt(){F=null,b=null,J=null,de=!1}function xt(){de=!0}function Lt(){de=!1}function xr(f,d){var E=f.type._context;ju?(Jr(y,E._currentValue,f),E._currentValue=d,E._currentRenderer===void 0||E._currentRenderer===null||E._currentRenderer===R||He(!1,"Detected multiple renderers concurrently rendering the same context provider. This is currently unsupported."),E._currentRenderer=R):(Jr(y,E._currentValue2,f),E._currentValue2=d,E._currentRenderer2===void 0||E._currentRenderer2===null||E._currentRenderer2===R||He(!1,"Detected multiple renderers concurrently rendering the same context provider. This is currently unsupported."),E._currentRenderer2=R)}function io(f){var d=y.current;ti(y,f);var E=f.type._context;ju?E._currentValue=d:E._currentValue2=d}function du(f,d,E){if(y0(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 Ho(f,d){for(var E=f;E!==null;){var C=E.alternate;if(E.childExpirationTime=d&&sp(),E.firstContext=null)}}function Ve(f,d){if(de&&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:at,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,A;E===null?(C=f.updateQueue,A=null,C===null&&(C=f.updateQueue=Qi(f.memoizedState))):(C=f.updateQueue,A=E.updateQueue,C===null?A===null?(C=f.updateQueue=Qi(f.memoizedState),A=E.updateQueue=Qi(E.memoizedState)):C=f.updateQueue=Gr(A):A===null&&(A=E.updateQueue=Gr(C))),A===null||C===A?Va(C,d):C.lastUpdate===null||A.lastUpdate===null?(Va(C,d),Va(A,d)):(Va(C,d),A.lastUpdate=d),f.tag===O&&(ci===C||A!==null&&ci===A)&&!ur&&(He(!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,A,j){switch(E.tag){case lt:{var V=E.payload;if(typeof V=="function"){xt(),Ri&&f.mode&mr&&V.call(j,C,A);var te=V.call(j,C,A);return Lt(),te}return V}case Wn:f.effectTag=f.effectTag&~ho|Xr;case ze:{var se=E.payload,Ue;return typeof se=="function"?(xt(),Ri&&f.mode&mr&&se.call(j,C,A),Ue=se.call(j,C,A),Lt()):Ue=se,Ue==null?C:a({},C,Ue)}case $t:return si=!0,C}return C}function Sf(f,d,E,C,A){si=!1,d=S2(f,d),ci=d;for(var j=d.baseState,V=null,te=at,se=d.firstUpdate,Ue=j;se!==null;){var Qe=se.expirationTime;if(Qe 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=Ko}}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 A(ot,Ot,$e){var Ut=C0(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 So=Nt(ot,hr,$e[Kr],Ut);if(So===null){hr===null&&(hr=xu);break}f&&hr&&So.alternate===null&&d(ot,hr),hu=j(So,hu,Kr),Ku===null?pi=So:Ku.sibling=So,Ku=So,hr=xu}if(Kr===$e.length)return E(ot,hr),pi;if(hr===null){for(;Kr<$e.length;Kr++){var Vo=vt(ot,$e[Kr],Ut);Vo!==null&&(hu=j(Vo,hu,Kr),Ku===null?pi=Vo:Ku.sibling=Vo,Ku=Vo)}return pi}for(var ks=C(ot,hr);Kr<$e.length;Kr++){var Xu=Yt(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(gl){return d(ot,gl)}),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=Ht(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,So=0,Vo=0,ks=null,Xu=hr.next();xu!==null&&!Xu.done;Vo++,Xu=hr.next()){xu.index>Vo?(ks=xu,xu=null):ks=xu.sibling;var gl=Nt(ot,xu,Xu.value,Ut);if(gl===null){xu===null&&(xu=ks);break}f&&xu&&gl.alternate===null&&d(ot,xu),So=j(gl,So,Vo),Kr===null?hu=gl:Kr.sibling=gl,Kr=gl,xu=ks}if(Xu.done)return E(ot,xu),hu;if(xu===null){for(;!Xu.done;Vo++,Xu=hr.next()){var uf=vt(ot,Xu.value,Ut);uf!==null&&(So=j(uf,So,Vo),Kr===null?hu=uf:Kr.sibling=uf,Kr=uf)}return hu}for(var V0=C(ot,xu);!Xu.done;Vo++,Xu=hr.next()){var Ls=Yt(V0,ot,Vo,Xu.value,Ut);Ls!==null&&(f&&Ls.alternate!==null&&V0.delete(Ls.key===null?Vo:Ls.key),So=j(Ls,So,Vo),Kr===null?hu=Ls:Kr.sibling=Ls,Kr=Ls)}return f&&V0.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=A(Ot,$e,Ut);return Pn.return=ot,Pn}E(ot,Ot);var vn=_y($e,ot.mode,Ut);return vn.return=ot,vn}function Oi(ot,Ot,$e,Ut){for(var Pn=$e.key,vn=Ot;vn!==null;){if(vn.key===Pn)if(vn.tag===m?$e.type===le:vn.elementType===$e.type||Wc(vn,$e)){E(ot,vn.sibling);var Wi=A(vn,$e.type===le?$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===le){var pi=rf($e.props.children,ot.mode,Ut,$e.key);return pi.return=ot,pi}else{var Ku=gy($e,ot.mode,Ut);return Ku.ref=mc(ot,Ot,$e),Ku.return=ot,Ku}}function Fo(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=A(vn,$e.children||[],Ut);return Wi.return=ot,Wi}else{E(ot,vn);break}else d(ot,vn);vn=vn.sibling}var pi=Ey($e,ot.mode,Ut);return pi.return=ot,pi}function $i(ot,Ot,$e,Ut){var Pn=typeof $e=="object"&&$e!==null&&$e.type===le&&$e.key===null;Pn&&($e=$e.props.children);var vn=typeof $e=="object"&&$e!==null;if(vn)switch($e.$$typeof){case fe:return V(Oi(ot,Ot,$e,Ut));case xe:return V(Fo(ot,Ot,$e,Ut))}if(typeof $e=="string"||typeof $e=="number")return V(oi(ot,Ot,""+$e,Ut));if(Zc($e))return yn(ot,Ot,$e,Ut);if(fr($e))return kr(ot,Ot,$e,Ut);if(vn&&yc(ot,$e),typeof $e=="function"&&hd(),typeof $e=="undefined"&&!Pn)switch(ot.tag){case O:{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=C0(E,E.pendingProps,E.expirationTime);for(d.child=C,C.return=d;E.sibling!==null;)E=E.sibling,C=C.sibling=C0(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={},ya=Ju(Gs),iu=Ju(Gs),ko=Ju(Gs);function oo(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=oo(ko.current);return f}function Ka(f,d){Jr(ko,d,f),Jr(iu,f,f),Jr(ya,Gs,f);var E=wt(d);ti(ya,f),Jr(ya,E,f)}function o0(f){ti(ya,f),ti(iu,f),ti(ko,f)}function fl(){var f=oo(ya.current);return f}function gc(f){var d=oo(ko.current),E=oo(ya.current),C=bt(E,f.type,d);E!==C&&(Jr(iu,f,f),Jr(ya,C,f))}function L2(f){iu.current===f&&(ti(ya,f),ti(iu,f))}var wh=0,xf=1,Rf=1,e1=2,Ll=Ju(wh);function t1(f,d){return(f&d)!=0}function ga(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)||go(C))return d}}else if(d.tag===ct&&d.memoizedProps.revealOrder!==void 0){var A=(d.effectTag&Xr)!==xi;if(A)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 yd={},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,A){var j=yd,V=f.getInitialState;V!==null&&(j=V(d));var te=F2(f,d,j,E);if(!A)for(var se=E;se!==null;){var Ue=se.tag;if(Ue===q){A=se.stateNode;break}else if(Ue===B){A=se.stateNode.containerInfo;break}se=se.return}Ne(f,te,d,j,A),C.set(f,te)}function gd(f,d,E,C,A){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 se=C.get(j);se===void 0?fm(j,te,d,C,A):(se.props=te,se.fiber=d)}function hn(f,d,E){var C=new Set,A=d.dependencies;if(f!=null){A===null&&(A=d.dependencies={expirationTime:at,firstContext:null,responders:new Map});var j=A.responders;if(j===null&&(j=new Map),wi(f))for(var V=0,te=f.length;V0){var j=A.dispatch;if(xs!==null){var V=xs.get(A);if(V!==void 0){xs.delete(A);var te=C.memoizedState,se=V;do{var Ue=se.action;te=f(te,Ue),se=se.next}while(se!==null);return y0(te,C.memoizedState)||sp(),C.memoizedState=te,C.baseUpdate===A.last&&(C.baseState=te),A.lastRenderedState=te,[te,j]}}return[C.memoizedState,j]}var Qe=A.last,vt=C.baseUpdate,Nt=C.baseState,Yt;if(vt!==null?(Qe!==null&&(Qe.next=null),Yt=vt.next):Yt=Qe!==null?Qe.next:null,Yt!==null){var Ht=Nt,yn=null,kr=null,oi=vt,Oi=Yt,Fo=!1;do{var $i=Oi.expirationTime;if($iIu&&(Iu=$i,Qd(Iu));else if(gv($i,Oi.suspenseConfig),Oi.eagerReducer===f)Ht=Oi.eagerState;else{var ot=Oi.action;Ht=f(Ht,ot)}oi=Oi,Oi=Oi.next}while(Oi!==null&&Oi!==Yt);Fo||(kr=oi,yn=Ht),y0(Ht,C.memoizedState)||sp(),C.memoizedState=Ht,C.baseUpdate=kr,C.baseState=yn,A.lastRenderedState=Ht}var Ot=A.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 A={tag:f,create:d,destroy:E,deps:C,next:null};if(is===null)is=Qa(),is.lastEffect=A.next=A;else{var j=is.lastEffect;if(j===null)is.lastEffect=A.next=A;else{var V=j.next;j.next=A,A.next=V,is.lastEffect=A}}return A}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 A=wc(),j=C===void 0?null:C;kf|=f,A.memoizedState=Ja(d,E,void 0,j)}function Sc(f,d,E,C){var A=i1(),j=C===void 0?null:C,V=void 0;if(jn!==null){var te=jn.memoizedState;if(V=te.destroy,j!==null){var se=te.deps;if(Nf(j,se)){Ja(Of,E,V,j);return}}}kf|=f,A.memoizedState=Ja(d,E,V,j)}function s1(f,d){return typeof jest!="undefined"&&Mv(dl),wd(Dr|Po,sr|r1,f,d)}function Fl(f,d){return typeof jest!="undefined"&&Mv(dl),Sc(Dr|Po,sr|r1,f,d)}function Da(f,d){return wd(Dr,Mf|cl,f,d)}function Ch(f,d){return Sc(Dr,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 A=d;A.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(A).join(", ")+"}");var j=f();return A.current=j,function(){A.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(Dr,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(Dr,Mf|cl,b2.bind(null,d,f),C)}function Sd(f,d){}var Rh=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,A=E.memoizedState;if(A!==null&&C!==null){var j=A[1];if(Nf(C,j))return A[0]}return E.memoizedState=[f,C],f}function Rs(f,d){var E=wc(),C=d===void 0?null:d,A=f();return E.memoizedState=[A,C],A}function Ys(f,d){var E=i1(),C=d===void 0?null:d,A=E.memoizedState;if(A!==null&&C!==null){var j=A[1];if(Nf(C,j))return A[0]}var V=f();return E.memoizedState=[V,C],V}function U2(f,d){var E=Pf(f),C=E[0],A=E[1];return s1(function(){t.unstable_next(function(){var j=q0.suspense;q0.suspense=d===void 0?null:d;try{A(f)}finally{q0.suspense=j}})},[f,d]),C}function Ah(f,d){var E=o1(f),C=E[0],A=E[1];return Fl(function(){t.unstable_next(function(){var j=q0.suspense;q0.suspense=d===void 0?null:d;try{A(f)}finally{q0.suspense=j}})},[f,d]),C}function j2(f){var d=Pf(!1),E=d[0],C=d[1],A=Pl(function(j){C(!0),t.unstable_next(function(){var V=q0.suspense;q0.suspense=f===void 0?null:f;try{C(!1),j()}finally{q0.suspense=V}})},[f,E]);return[A,E]}function z2(f){var d=o1(!1),E=d[0],C=d[1],A=os(function(j){C(!0),t.unstable_next(function(){var V=q0.suspense;q0.suspense=f===void 0?null:f;try{C(!1),j()}finally{q0.suspense=V}})},[f,E]);return[A,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(!Se)return!1;var d=f.stateNode.containerInfo;return $a=U(d),bl=f,wa=!0,!0}function hm(f,d){return Se?($a=ji(d),X2(f),wa=!0,!0):!1}function Y2(f,d){switch(f.tag){case B:oe(f.stateNode.containerInfo,d);break;case q:We(f.type,f.memoizedProps,f.stateNode,d);break}var E=rE();E.stateNode=d,E.return=f,E.effectTag=Ko,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,A=d.pendingProps;it(E,C,A);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,se=f.stateNode;switch(d.tag){case q:var Ue=d.type,Qe=d.pendingProps;It(V,te,se,Ue,Qe);break;case ne:var vt=d.pendingProps;sn(V,te,se,vt);break;case ce:rn(V,te,se);break}break}default:return}}function Ph(f,d){switch(f.tag){case q:{var E=f.type,C=f.pendingProps,A=hf(d,E,C);return A!==null?(f.stateNode=A,!0):!1}case ne:{var j=f.pendingProps,V=Bs(d,j);return V!==null?(f.stateNode=V,!0):!1}case ce:{if(Ai){var te=Ba(d);if(te!==null){var se={dehydrated:te,retryTime:Di};f.memoizedState=se;var Ue=iE(te);return Ue.return=f,f.child=Ue,!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(!Se)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,A=z(C,f.type,f.memoizedProps,d,E,f);return f.updateQueue=A,A!==null}function mm(f){if(!Se)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 A=bl;if(A!==null)switch(A.tag){case B:{var j=A.stateNode.containerInfo;Je(j,d,E);break}case q:{var V=A.type,te=A.memoizedProps,se=A.stateNode;mt(V,te,se,d,E);break}}}return C}function Ih(f){if(!Se)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 ym(f){if(!Se)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 Ce(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(!Se||f!==bl)return!1;if(!wa)return X2(f),wa=!0,!1;var d=f.type;if(f.tag!==q||d!=="head"&&d!=="body"&&!Li(d,f.memoizedProps))for(var E=$a;E;)Y2(f,E),E=ji(E);return X2(f),f.tag===ce?$a=ym(f):$a=bl?ji(f.stateNode):null,!0}function v1(){!Se||(bl=null,$a=null,wa=!1)}var m1=nt.ReactCurrentOwner,Sa=!1,Q2,Ks,Xs,Qs,J2,Ta,y1,Td,Tc,Z2;Q2={},Ks={},Xs={},Qs={},J2={},Ta=!1,y1=!1,Td={},Tc={},Z2={};function w0(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,A){if(d.type!==d.elementType){var j=E.propTypes;j&&_(j,C,"prop",Wt(E),Nr)}var V=E.render,te=d.ref,se;return uo(d,A),m1.current=d,et("render"),se=Ff(f,d,V,C,te,A),Ri&&d.mode&mr&&d.memoizedState!==null&&(se=Ff(f,d,V,C,te,A)),et(null),f!==null&&!Sa?(_d(f,d,A),Ca(f,d,A)):(d.effectTag|=su,w0(f,d,se,A),d.child)}function Uh(f,d,E,C,A,j){if(f===null){var V=E.type;if(ao(V)&&E.compare===null&&E.defaultProps===void 0){var te=V;return te=ro(V),d.tag=re,d.type=te,tp(d,V),jh(f,d,te,C,A,j)}{var se=V.propTypes;se&&_(se,C,"prop",Wt(V),Nr)}var Ue=yy(E.type,null,C,null,d.mode,j);return Ue.ref=d.ref,Ue.return=d,d.child=Ue,Ue}{var Qe=E.type,vt=Qe.propTypes;vt&&_(vt,C,"prop",Wt(Qe),Nr)}var Nt=f.child;if(A 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.",se,se),Q2[se]=!0)}d.mode&mr&&Al.recordLegacyContextWarning(d,null),m1.current=d,te=Ff(null,d,E,A,j,C)}if(d.effectTag|=su,typeof te=="object"&&te!==null&&typeof te.render=="function"&&te.$$typeof===void 0){{var Ue=Wt(E)||"Unknown";Ks[Ue]||(He(!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.",Ue,Ue,Ue),Ks[Ue]=!0)}d.tag=O,Ed();var Qe=!1;Xi(E)?(Qe=!0,Hi(d)):Qe=!1,d.memoizedState=te.state!==null&&te.state!==void 0?te.state:null;var vt=E.getDerivedStateFromProps;return typeof vt=="function"&&Tf(d,E,vt,A),al(d,te),vc(d,E,A,C),ep(null,d,E,!0,Qe,C)}else return d.tag=N,ai&&E.contextTypes&&He(!1,"%s uses the legacy contextTypes API which is no longer supported. Use React.createContext() with React.useContext() instead.",Wt(E)||"Unknown"),Ri&&d.mode&mr&&d.memoizedState!==null&&(te=Ff(null,d,E,A,j,C)),w0(null,d,te,C),tp(d,E),d.child}function tp(f,d){if(d&&d.childContextTypes&&He(!1,"%s(...): childContextTypes cannot be defined on a function component.",d.displayName||d.name||"Component"),f.ref!==null){var E="",C=_o();C&&(E+=` - -Check the render method of \``+C+"`.");var A=C||f._debugID||"",j=f._debugSource;j&&(A=j.fileName+":"+j.lineNumber),J2[A]||(J2[A]=!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=Wt(d)||"Unknown";Z2[V]||(He(!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=Wt(d)||"Unknown";Qs[te]||(He(!1,"%s: Function components do not support getDerivedStateFromProps.",te),Qs[te]=!0)}if(typeof d.contextType=="object"&&d.contextType!==null){var se=Wt(d)||"Unknown";Xs[se]||(He(!1,"%s: Function components do not support contextType.",se),Xs[se]=!0)}}var xd={dehydrated:null,retryTime:at};function np(f,d,E){return t1(f,e1)&&(d===null||d.memoizedState!==null)}function Vh(f,d,E){var C=d.mode,A=d.pendingProps;s_(d)&&(d.effectTag|=Xr);var j=Ll.current,V=!1,te=(d.effectTag&Xr)!==xi;if(te||np(j,f,d)?(V=!0,d.effectTag&=~Xr):(f===null||f.memoizedState!==null)&&A.fallback!==void 0&&A.unstable_avoidThisFallback!==!0&&(j=md(j,Rf)),j=ga(j),Fr(d,j),"maxDuration"in A&&(y1||(y1=!0,Qt(!1,"maxDuration has been removed from React. Remove the maxDuration prop."))),f===null){if(A.fallback!==void 0&&(K2(d),Ai)){var se=d.memoizedState;if(se!==null){var Ue=se.dehydrated;if(Ue!==null)return Gh(d,Ue,E)}}if(V){var Qe=A.fallback,vt=rf(null,C,at,null);if(vt.return=d,(d.mode&Y)===Ar){var Nt=d.memoizedState,Yt=Nt!==null?d.child.child:d.child;vt.child=Yt;for(var Ht=Yt;Ht!==null;)Ht.return=vt,Ht=Ht.sibling}var yn=rf(Qe,C,E,null);return yn.return=d,vt.sibling=yn,d.memoizedState=xd,d.child=vt,yn}else{var kr=A.children;return d.memoizedState=null,d.child=$c(d,null,kr,E)}}else{var oi=f.memoizedState;if(oi!==null){if(Ai){var Oi=oi.dehydrated;if(Oi!==null)if(te){if(d.memoizedState!==null)return d.child=f.child,d.effectTag|=Xr,null;var Fo=A.fallback,$i=rf(null,C,at,null);if($i.return=d,$i.child=null,(d.mode&Y)===Ar)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(Fo,C,E,null);return Ut.return=d,$i.sibling=Ut,Ut.effectTag|=mi,$i.childExpirationTime=at,d.memoizedState=xd,d.child=$i,Ut}else return Yh(f,d,Oi,oi,E)}var Pn=f.child,vn=Pn.sibling;if(V){var Wi=A.fallback,pi=C0(Pn,Pn.pendingProps,at);if(pi.return=d,(d.mode&Y)===Ar){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 So=C0(vn,Wi,vn.expirationTime);return So.return=d,pi.sibling=So,pi.childExpirationTime=at,d.memoizedState=xd,d.child=pi,So}else{var Vo=A.children,ks=Pn.child,Xu=Cf(d,ks,Vo,E);return d.memoizedState=null,d.child=Xu}}else{var gl=f.child;if(V){var uf=A.fallback,V0=rf(null,C,at,null);if(V0.return=d,V0.child=gl,gl!==null&&(gl.return=V0),(d.mode&Y)===Ar){var Ls=d.memoizedState,$d=Ls!==null?d.child.child:d.child;V0.child=$d;for(var Gf=$d;Gf!==null;)Gf.return=V0,Gf=Gf.sibling}if(en&&d.mode&ii){for(var Fc=0,Hl=V0.child;Hl!==null;)Fc+=Hl.treeBaseDuration,Hl=Hl.sibling;V0.treeBaseDuration=Fc}var G0=rf(uf,C,E,null);return G0.return=d,V0.sibling=G0,G0.effectTag|=mi,V0.childExpirationTime=at,d.memoizedState=xd,d.child=V0,G0}else{d.memoizedState=null;var N1=A.children;return d.child=Cf(d,gl,N1,E)}}}}function rp(f,d,E){d.memoizedState=null;var C=d.pendingProps,A=C.children;return w0(f,d,A,E),d.child}function Gh(f,d,E){if((f.mode&Y)===Ar)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(go(d)){var C=jl(),A=ws(C);bn&&x(A),f.expirationTime=A}else f.expirationTime=Di,bn&&x(Di);return null}function Yh(f,d,E,C,A){if(V2(),(d.mode&Y)===Ar||go(E))return rp(f,d,A);var j=f.childExpirationTime>=A;if(Sa||j){if(A. 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 A=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} ... ",A,d,A),!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,A,j){var V=f.memoizedState;V===null?f.memoizedState={isBackwards:d,rendering:null,last:C,tail:E,tailExpiration:0,tailMode:A,lastEffect:j}:(V.isBackwards=d,V.rendering=null,V.last=C,V.tail=E,V.tailExpiration=0,V.tailMode=A,V.lastEffect=j)}function op(f,d,E){var C=d.pendingProps,A=C.revealOrder,j=C.tail,V=C.children;Tm(A),Kh(j,A),Cm(V,A),w0(f,d,V,E);var te=Ll.current,se=t1(te,e1);if(se)te=vd(te,e1),d.effectTag|=Xr;else{var Ue=f!==null&&(f.effectTag&Xr)!==xi;Ue&&wm(d,d.child,E),te=ga(te)}if(Fr(d,te),(d.mode&Y)===Ar)d.memoizedState=null;else switch(A){case"forwards":{var Qe=Sm(d.child),vt;Qe===null?(vt=d.child,d.child=null):(vt=Qe.sibling,Qe.sibling=null),up(d,!1,vt,Qe,j,d.lastEffect);break}case"backwards":{var Nt=null,Yt=d.child;for(d.child=null;Yt!==null;){var Ht=Yt.alternate;if(Ht!==null&&n1(Ht)===null){d.child=Yt;break}var yn=Yt.sibling;Yt.sibling=Nt,Nt=Yt,Yt=yn}up(d,!0,Nt,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):w0(f,d,C,E),d.child}function Rm(f,d,E){var C=d.type,A=C._context,j=d.pendingProps,V=d.memoizedProps,te=j.value;{var se=d.type.propTypes;se&&_(se,j,"prop","Context.Provider",Nr)}if(xr(d,te),V!==null){var Ue=V.value,Qe=du(A,te,Ue);if(Qe===0){if(V.children===j.children&&!aa())return Ca(f,d,E)}else Ml(d,A,Qe,E)}var vt=j.children;return w0(f,d,vt,E),d.child}var Xh=!1;function Am(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 A=d.pendingProps,j=A.children;typeof j!="function"&&He(!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."),uo(d,E);var V=Ve(C,A.unstable_observedBits),te;return m1.current=d,et("render"),te=j(V),et(null),d.effectTag|=su,w0(f,d,te,E),d.child}function Om(f,d,E){var C=d.type.impl;if(C.reconcileChildren===!1)return null;var A=d.pendingProps,j=A.children;return w0(f,d,j,E),d.child}function lp(f,d,E){var C=d.pendingProps,A=C.children;return w0(f,d,A,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!==at&&Qd(C);var A=d.childExpirationTime;return A=E;se&&(d.effectTag|=Dr)}break;case ce:{var Ue=d.memoizedState;if(Ue!==null){if(Ai&&Ue.dehydrated!==null){Fr(d,ga(Ll.current)),d.effectTag|=Xr;break}var Qe=d.child,vt=Qe.childExpirationTime;if(vt!==at&&vt>=E)return Vh(f,d,E);Fr(d,ga(Ll.current));var Nt=Ca(f,d,E);return Nt!==null?Nt.sibling:null}else Fr(d,ga(Ll.current));break}case ct:{var Yt=(f.effectTag&Xr)!==xi,Ht=d.childExpirationTime>=E;if(Yt){if(Ht)return op(f,d,E);d.effectTag|=Xr}var yn=d.memoizedState;if(yn!==null&&(yn.rendering=null,yn.tail=null),Fr(d,Ll.current),Ht)break;return null}}return Ca(f,d,E)}else Sa=!1}else Sa=!1;switch(d.expirationTime=at,d.tag){case T:return Dm(f,d,d.type,E);case we:{var kr=d.elementType;return bf(f,d,kr,C,E)}case N:{var oi=d.type,Oi=d.pendingProps,Fo=d.elementType===oi?Oi:qi(oi,Oi);return $2(f,d,oi,Fo,E)}case O:{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 ue:{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 gm(f,d,E);case pe:return zh(f,d,E);case _e:return Hh(f,d,E);case ve:return Rm(f,d,E);case ge:return Am(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",Wt(vn),Nr)}return pi=qi(vn.type,pi),Uh(f,d,vn,pi,C,E)}case re:return jh(f,d,d.type,d.pendingProps,C,E);case Ie:{var hr=d.type,hu=d.pendingProps,Kr=d.elementType===hr?hu:qi(hr,hu);return Cd(f,d,hr,Kr,E)}case ct:return op(f,d,E);case pt:{if(Vt)return Om(f,d,E);break}case Xe:{if(Au)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 Rd(f){return f.tag===ce&&f.memoizedState!==null}function D1(f){return f.child.sibling.child}var Jh={};function fp(f,d,E){if(Au){if(f.tag===q){var C=f.type,A=f.memoizedProps,j=f.stateNode,V=N0(j);V!==null&&d(C,A||Jh,V)===!0&&E.push(V)}var te=f.child;Rd(f)&&(te=D1(f)),te!==null&&cp(te,d,E)}}function Zh(f,d){if(Au){if(f.tag===q){var E=f.type,C=f.memoizedProps,A=f.stateNode,j=N0(A);if(j!==null&&d(E,C,j)===!0)return j}var V=f.child;if(Rd(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(Ad(f,d))E.push(f.stateNode.methods);else{var C=f.child;Rd(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 Ad(f,d){return f.tag===Xe&&f.type===d&&f.stateNode!==null}function Od(f,d){return{getChildren:function(){var E=d.fiber,C=E.child,A=[];return C!==null&&dp(C,f,A),A.length===0?null:A},getChildrenFromRoot:function(){for(var E=d.fiber,C=E;C!==null;){var A=C.return;if(A===null||(C=A,C.tag===Xe&&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===Xe&&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,A=C.child,j=[];return A!==null&&cp(A,E,j),j.length===0?null:j},queryFirstNode:function(E){var C=d.fiber,A=C.child;return A!==null?$h(A,E):null},containsNode:function(E){for(var C=cr(E);C!==null;){if(C.tag===Xe&&C.type===f&&C.stateNode===d)return!0;C=C.return}return!1}}}function qo(f){f.effectTag|=Dr}function Md(f){f.effectTag|=O0}var xa,ef,kd,Ld;if(Bo)xa=function(f,d,E,C){for(var A=d.child;A!==null;){if(A.tag===q||A.tag===ne)Qr(f,A.stateNode);else if(Vt&&A.tag===pt)Qr(f,A.stateNode.instance);else if(A.tag!==H){if(A.child!==null){A.child.return=A,A=A.child;continue}}if(A===d)return;for(;A.sibling===null;){if(A.return===null||A.return===d)return;A=A.return}A.sibling.return=A.return,A=A.sibling}},ef=function(f){},kd=function(f,d,E,C,A){var j=f.memoizedProps;if(j!==C){var V=d.stateNode,te=fl(),se=vo(V,E,j,C,A,te);d.updateQueue=se,se&&qo(d)}},Ld=function(f,d,E,C){E!==C&&qo(d)};else if(Q){xa=function(f,d,E,C){for(var A=d.child;A!==null;){e:if(A.tag===q){var j=A.stateNode;if(E&&C){var V=A.memoizedProps,te=A.type;j=$r(j,te,V,A)}Qr(f,j)}else if(A.tag===ne){var se=A.stateNode;if(E&&C){var Ue=A.memoizedProps;se=$l(se,Ue,A)}Qr(f,se)}else if(Vt&&A.tag===pt){var Qe=A.stateNode.instance;if(E&&C){var vt=A.memoizedProps,Nt=A.type;Qe=$r(Qe,Nt,vt,A)}Qr(f,Qe)}else if(A.tag!==H){if(A.tag===ce){if((A.effectTag&Dr)!==xi){var Yt=A.memoizedState!==null;if(Yt){var Ht=A.child;if(Ht!==null){Ht.child!==null&&(Ht.child.return=Ht,xa(f,Ht,!0,Yt));var yn=Ht.sibling;if(yn!==null){yn.return=A,A=yn;continue}}}}if(A.child!==null){A.child.return=A,A=A.child;continue}}else if(A.child!==null){A.child.return=A,A=A.child;continue}}if(A=A,A===d)return;for(;A.sibling===null;){if(A.return===null||A.return===d)return;A=A.return}A.sibling.return=A.return,A=A.sibling}};var pp=function(f,d,E,C){for(var A=d.child;A!==null;){e:if(A.tag===q){var j=A.stateNode;if(E&&C){var V=A.memoizedProps,te=A.type;j=$r(j,te,V,A)}Qn(f,j)}else if(A.tag===ne){var se=A.stateNode;if(E&&C){var Ue=A.memoizedProps;se=$l(se,Ue,A)}Qn(f,se)}else if(Vt&&A.tag===pt){var Qe=A.stateNode.instance;if(E&&C){var vt=A.memoizedProps,Nt=A.type;Qe=$r(Qe,Nt,vt,A)}Qn(f,Qe)}else if(A.tag!==H){if(A.tag===ce){if((A.effectTag&Dr)!==xi){var Yt=A.memoizedState!==null;if(Yt){var Ht=A.child;if(Ht!==null){Ht.child!==null&&(Ht.child.return=Ht,pp(f,Ht,!0,Yt));var yn=Ht.sibling;if(yn!==null){yn.return=A,A=yn;continue}}}}if(A.child!==null){A.child.return=A,A=A.child;continue}}else if(A.child!==null){A.child.return=A,A=A.child;continue}}if(A=A,A===d)return;for(;A.sibling===null;){if(A.return===null||A.return===d)return;A=A.return}A.sibling.return=A.return,A=A.sibling}};ef=function(f){var d=f.stateNode,E=f.firstEffect===null;if(!E){var C=d.containerInfo,A=To(C);pp(A,f,!1,!1),d.pendingChildren=A,qo(f),fc(C,A)}},kd=function(f,d,E,C,A){var j=f.stateNode,V=f.memoizedProps,te=d.firstEffect===null;if(te&&V===C){d.stateNode=j;return}var se=d.stateNode,Ue=fl(),Qe=null;if(V!==C&&(Qe=vo(se,E,V,C,A,Ue)),te&&Qe===null){d.stateNode=j;return}var vt=ys(j,Qe,E,V,C,d,te,se);Ou(vt,E,C,A,Ue)&&qo(d),d.stateNode=vt,te?qo(d):xa(vt,d,!1,!1)},Ld=function(f,d,E,C){if(E!==C){var A=rs(),j=fl();d.stateNode=vs(C,A,j,d),qo(d)}}}else ef=function(f){},kd=function(f,d,E,C,A){},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 A=f.tail,j=null;A!==null;)A.alternate!==null&&(j=A),A=A.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 we:break;case re:case N:break;case O:{var A=d.type;Xi(A)&&qs(d);break}case B:{o0(d),Ao(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&&qo(d)}ef(d);break}case q:{L2(d);var te=rs(),se=d.type;if(f!==null&&d.stateNode!=null){if(kd(f,d,se,C,te),gi){var Ue=f.memoizedProps.listeners,Qe=C.listeners;Ue!==Qe&&qo(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 vt=fl(),Nt=h1(d);if(Nt){if(vm(d,te,vt)&&qo(d),gi){var Yt=C.listeners;Yt!=null&&hn(Yt,d,te)}}else{var Ht=Ki(se,C,te,vt,d);if(xa(Ht,d,!1,!1),d.stateNode=Ht,gi){var yn=C.listeners;yn!=null&&hn(yn,d,te)}Ou(Ht,se,C,te,vt)&&qo(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 Oi=rs(),Fo=fl(),$i=h1(d);$i?mm(d)&&qo(d):d.stateNode=vs(kr,Oi,Fo,d)}break}case ue:break;case ce:{Ea(d);var ot=d.memoizedState;if(Ai&&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)===xi&&(d.memoizedState=null),d.effectTag|=Dr,null;if((d.effectTag&Xr)!==xi)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=Ko}}}if($e&&!Ut&&(d.mode&Y)!==Ar){var pi=f===null&&d.memoizedProps.unstable_avoidThisFallback!==!0;pi||t1(Ll.current,Rf)?_v():Ev()}Q&&$e&&(d.effectTag|=Dr),Bo&&($e||Ut)&&(d.effectTag|=Dr),Yi&&d.updateQueue!==null&&d.memoizedProps.suspenseCallback!=null&&(d.effectTag|=Dr);break}case m:break;case pe:break;case _e:break;case H:o0(d),ef(d);break;case ve:io(d);break;case ge:break;case me:break;case Ie:{var Ku=d.type;Xi(Ku)&&qs(d);break}case ct:{Ea(d);var hr=d.memoizedState;if(hr===null)break;var hu=(d.effectTag&Xr)!==xi,Kr=hr.rendering;if(Kr===null)if(hu)Nd(hr,!1);else{var xu=Dv()&&(f===null||(f.effectTag&Xr)===xi);if(!xu)for(var So=d.child;So!==null;){var Vo=n1(So);if(Vo!==null){hu=!0,d.effectTag|=Xr,Nd(hr,!1);var ks=Vo.updateQueue;return ks!==null&&(d.updateQueue=ks,d.effectTag|=Dr),hr.lastEffect===null&&(d.firstEffect=null),d.lastEffect=hr.lastEffect,am(d,E),Fr(d,vd(Ll.current,e1)),d.child}So=So.sibling}}else{if(!hu){var Xu=n1(Kr);if(Xu!==null){d.effectTag|=Xr,hu=!0;var gl=Xu.updateQueue;if(gl!==null&&(d.updateQueue=gl,d.effectTag|=Dr),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(yt()>hr.tailExpiration&&E>Di){d.effectTag|=Xr,hu=!0,Nd(hr,!1);var V0=E-1;d.expirationTime=d.childExpirationTime=V0,bn&&x(V0)}}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=yt()+$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=ga(Fc),Fr(d,Fc),Gf}break}case pt:{if(Vt){var Hl=d.type.impl,G0=d.stateNode;if(G0===null){var N1=Hl.getInitialState,v_;N1!==void 0&&(v_=N1(C)),G0=d.stateNode=Qh(d,C,Hl,v_||{});var m_=ht(G0);if(G0.instance=m_,Hl.reconcileChildren===!1)return null;xa(m_,d,!1,!1),Yn(G0)}else{var EE=G0.props;if(G0.prevProps=EE,G0.props=C,G0.currentFiber=d,Q){var y_=la(G0);G0.instance=y_,xa(y_,d,!1,!1)}var DE=Cn(G0);DE&&qo(d)}}break}case Xe:{if(Au)if(f===null){var wE=d.type,Ry={fiber:d,methods:null};if(d.stateNode=Ry,Ry.methods=Od(wE,Ry),gi){var g_=C.listeners;if(g_!=null){var SE=rs();hn(g_,d,SE)}}d.ref!==null&&(Md(d),qo(d))}else{if(gi){var TE=f.memoizedProps.listeners,CE=C.listeners;(TE!==CE||d.ref!==null)&&qo(d)}else d.ref!==null&&qo(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 O:{var E=f.type;Xi(E)&&qs(f);var C=f.effectTag;return C&ho?(f.effectTag=C&~ho|Xr,f):null}case B:{o0(f),Ao(f);var A=f.effectTag;if((A&Xr)!==xi)throw Error("The root failed to unmount after an error. This is likely a bug in React. Please file an issue.");return f.effectTag=A&~ho|Xr,f}case q:return L2(f),null;case ce:{if(Ea(f),Ai){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&ho?(f.effectTag=V&~ho|Xr,f):null}case ct:return Ea(f),null;case H:return o0(f),null;case ve:return io(f),null;default:return null}}function nv(f){switch(f.tag){case O:{var d=f.type.childContextTypes;d!=null&&qs(f);break}case B:{o0(f),Ao(f);break}case q:{L2(f);break}case H:o0(f);break;case ce:Ea(f);break;case ct:Ea(f);break;case ve:io(f);break;default:break}}function hp(f,d){return{value:f,source:d,stack:Cr(d)}}var vp=function(f,d,E,C,A,j,V,te,se){var Ue=Array.prototype.slice.call(arguments,3);try{d.apply(E,Ue)}catch(Qe){this.onError(Qe)}};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,A,j,V,te,se){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 Ue=document.createEvent("Event"),Qe=!0,vt=window.event,Nt=Object.getOwnPropertyDescriptor(window,"event"),Yt=Array.prototype.slice.call(arguments,3);function Ht(){mp.removeEventListener(Fo,Ht,!1),typeof window.event!="undefined"&&window.hasOwnProperty("event")&&(window.event=vt),d.apply(E,Yt),Qe=!1}var yn,kr=!1,oi=!1;function Oi($i){if(yn=$i.error,kr=!0,yn===null&&$i.colno===0&&$i.lineno===0&&(oi=!0),$i.defaultPrevented&&yn!=null&&typeof yn=="object")try{yn._suppressLogging=!0}catch(ot){}}var Fo="react-"+(f||"invokeguardedcallback");window.addEventListener("error",Oi),mp.addEventListener(Fo,Ht,!1),Ue.initEvent(Fo,!1,!1),mp.dispatchEvent(Ue),Nt&&Object.defineProperty(window,"event",Nt),Qe&&(kr?oi&&(yn=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.")):yn=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(yn)),window.removeEventListener("error",Oi)};vp=km}var Lm=vp,S0=!1,Fd=null,Nm={onError:function(f){S0=!0,Fd=f}};function pl(f,d,E,C,A,j,V,te,se){S0=!1,Fd=null,Lm.apply(Nm,arguments)}function tr(){return S0}function Js(){if(S0){var f=Fd;return S0=!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 lo(f){var d=hl(f);if(d!==!1){var E=f.error;{var C=f.componentName,A=f.componentStack,j=f.errorBoundaryName,V=f.errorBoundaryFound,te=f.willRetry;if(E!=null&&E._suppressLogging){if(V&&te)return;console.error(E)}var se=C?"The above error occurred in the <"+C+"> component:":"The above error occurred in one of your React components:",Ue;V&&j?te?Ue="React will try to recreate this component tree from scratch "+("using the error boundary you provided, "+j+"."):Ue="This error was initially handled by the error boundary "+j+`. -Recreating the tree from scratch failed so React will unmount the tree.`:Ue=`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 Qe=""+se+A+` - -`+(""+Ue);console.error(Qe)}}}var rv=null;rv=new Set;var Zs=typeof WeakSet=="function"?WeakSet:Set;function yp(f,d){var E=d.source,C=d.stack;C===null&&E!==null&&(C=Cr(E));var A={componentName:E!==null?Wt(E.type):null,componentStack:C!==null?C:"",error:d.value,errorBoundary:null,errorBoundaryName:null,errorBoundaryFound:!1,willRetry:!1};f!==null&&f.tag===O&&(A.errorBoundary=f.stateNode,A.errorBoundaryName=Wt(f.type),A.errorBoundaryFound=!0,A.willRetry=!0);try{lo(A)}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 gp(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 ue:case re:{Cc(cm,Of,d);return}case O:{if(d.effectTag&M0&&f!==null){var E=f.memoizedProps,C=f.memoizedState;Bi(d,"getSnapshotBeforeUpdate");var A=d.stateNode;d.type===d.elementType&&!Ta&&(A.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.",Wt(d.type)||"instance"),A.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.",Wt(d.type)||"instance"));var j=A.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),He(!1,"%s.getSnapshotBeforeUpdate(): A snapshot value (or null) must be returned. You have returned undefined.",Wt(d.type)))}A.__reactInternalSnapshotBeforeUpdate=j,Ci()}return}case B:case q:case ne:case H:case Ie: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,A=C!==null?C.lastEffect:null;if(A!==null){var j=A.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 se=V.create;V.destroy=se();{var Ue=V.destroy;if(Ue!==void 0&&typeof Ue!="function"){var Qe=void 0;Ue===null?Qe=" You returned null. If your effect does not require clean up, return undefined (or nothing).":typeof Ue.then=="function"?Qe=` - -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`:Qe=" You returned: "+Ue,He(!1,"An effect function must not return anything besides a function, which is used for clean-up.%s%s",Qe,Cr(E))}}}V=V.next}while(V!==j)}}function Ra(f){if((f.effectTag&Po)!==xi)switch(f.tag){case N:case ue:case re:{Cc(sr,Of,f),Cc(Of,r1,f);break}default:break}}function Ep(f,d,E,C){switch(E.tag){case N:case ue:case re:{Cc(dm,cl,E);break}case O:{var A=E.stateNode;if(E.effectTag&Dr)if(d===null)Bi(E,"componentDidMount"),E.type===E.elementType&&!Ta&&(A.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.",Wt(E.type)||"instance"),A.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.",Wt(E.type)||"instance")),A.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&&(A.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.",Wt(E.type)||"instance"),A.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.",Wt(E.type)||"instance")),A.componentDidUpdate(j,V,A.__reactInternalSnapshotBeforeUpdate),Ci()}var te=E.updateQueue;te!==null&&(E.type===E.elementType&&!Ta&&(A.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.",Wt(E.type)||"instance"),A.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.",Wt(E.type)||"instance")),g0(E,te,A,C));return}case B:{var se=E.updateQueue;if(se!==null){var Ue=null;if(E.child!==null)switch(E.child.tag){case q:Ue=N0(E.child.stateNode);break;case O:Ue=E.child.stateNode;break}g0(E,se,Ue,C)}return}case q:{var Qe=E.stateNode;if(d===null&&E.effectTag&Dr){var vt=E.type,Nt=E.memoizedProps;Hu(Qe,vt,Nt,E)}return}case ne:return;case H:return;case _e:{if(en){var Yt=E.memoizedProps.onRender;typeof Yt=="function"&&(bn?Yt(E.memoizedProps.id,d===null?"mount":"update",E.actualDuration,E.treeBaseDuration,E.actualStartTime,Il(),f.memoizedInteractions):Yt(E.memoizedProps.id,d===null?"mount":"update",E.actualDuration,E.treeBaseDuration,E.actualStartTime,Il()))}return}case ce:{Bl(f,E);return}case ct:case Ie:case pt:case Xe: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(Bo)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 A=E.stateNode;d?yo(A):Zo(A,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=N0(E);break;default:C=E}Au&&f.tag===Xe&&(C=E.methods),typeof d=="function"?d(C):(d.hasOwnProperty("current")||He(!1,"Unexpected ref object provided for %s. Use either a ref-setter function or React.createRef().%s",Wt(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 ue:case me:case re:{var C=d.updateQueue;if(C!==null){var A=C.lastEffect;if(A!==null){var j=A.next,V=E>Kn?Kn:E;Sn(V,function(){var oi=j;do{var Oi=oi.destroy;Oi!==void 0&&Pm(d,Oi),oi=oi.next}while(oi!==j)})}}break}case O:{gp(d);var te=d.stateNode;typeof te.componentWillUnmount=="function"&&iv(d,te);return}case q:{if(gi){var se=d.dependencies;if(se!==null){var Ue=se.responders;if(Ue!==null){for(var Qe=Array.from(Ue.values()),vt=0,Nt=Qe.length;vt component higher in the tree to provide a loading indicator or placeholder to display.`+Cr(E))}kp(),C=hp(C,E);var Nt=d;do{switch(Nt.tag){case B:{var Yt=C;Nt.effectTag|=ho,Nt.expirationTime=A;var Ht=sv(Nt,Yt,A);ld(Nt,Ht);return}case O:var yn=C,kr=Nt.type,oi=Nt.stateNode;if((Nt.effectTag&Xr)===xi&&(typeof kr.getDerivedStateFromError=="function"||oi!==null&&typeof oi.componentDidCatch=="function"&&!Ip(oi))){Nt.effectTag|=ho,Nt.expirationTime=A;var Oi=av(Nt,yn,A);ld(Nt,Oi);return}break;default:break}Nt=Nt.return}while(Nt!==null)}var Oa=Math.ceil,Mr=nt.ReactCurrentDispatcher,Sp=nt.ReactCurrentOwner,vl=nt.IsSomeRendererActing,gu=0,T1=1,Ui=2,Tp=4,Bd=8,T0=16,Os=32,Bf=0,Ud=1,Cp=2,C1=3,x1=4,xp=5,nr=gu,ml=null,Gn=null,Wo=at,Lo=Bf,jd=null,Ul=Un,R1=Un,Rc=null,Ac=at,zd=!1,Rp=0,No=500,dn=null,Hd=!1,qd=null,Oc=null,Mc=!1,kc=null,A1=Do,Ap=at,tf=null,Hm=50,Lc=0,Wd=null,cv=50,O1=0,Uf=null,jf=null,M1=at;function jl(){return(nr&(T0|Os))!==gu?no(yt()):(M1!==at||(M1=no(yt())),M1)}function Nc(){return no(yt())}function zf(f,d,E){var C=d.mode;if((C&Y)===Ar)return Un;var A=Jt();if((C&ri)===Ar)return A===Ni?Un:to;if((nr&T0)!==gu)return Wo;var j;if(E!==null)j=ca(f,E.timeoutMs|0||Ef);else switch(A){case Ni:j=Un;break;case ni:j=ja(f);break;case Kn:case eo:j=ws(f);break;case Eo:j=ru;break;default:throw Error("Expected a valid priority level")}return ml!==null&&j===Wo&&(j-=1),j}function qm(f,d){sy(),dy(f);var E=Vd(f,d);if(E===null){fy(f);return}Hp(f,d),sa();var C=Jt();if(d===Un?(nr&Bd)!==gu&&(nr&(T0|Os))===gu?(W(E,d),k1(E)):(W0(E),W(E,d),nr===gu&&Bt()):(W0(E),W(E,d)),(nr&Tp)!==gu&&(C===ni||C===Ni))if(tf===null)tf=new Map([[E,d]]);else{var A=tf.get(E);(A===void 0||A>d)&&tf.set(E,d)}}var yl=qm;function Vd(f,d){f.expirationTimeA?C:A}function W0(f){var d=f.lastExpiredTime;if(d!==at){f.callbackExpirationTime=Un,f.callbackPriority=Ni,f.callbackNode=Tn(k1.bind(null,f));return}var E=Gd(f),C=f.callbackNode;if(E===at){C!==null&&(f.callbackNode=null,f.callbackExpirationTime=at,f.callbackPriority=Do);return}var A=jl(),j=rd(A,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 se;E===Un?se=Tn(k1.bind(null,f)):f0?se=_n(j,Yd.bind(null,f)):se=_n(j,Yd.bind(null,f),{timeout:j0(E)-yt()}),f.callbackNode=se}function Yd(f,d){if(M1=at,d){var E=jl();return Vp(f,E),W0(f),null}var C=Gd(f);if(C!==at){var A=f.callbackNode;if((nr&(T0|Os))!==gu)throw Error("Should not already be working.");if(nf(),(f!==ml||C!==Wo)&&(Hf(f,C),ee(f,C)),Gn!==null){var j=nr;nr|=T0;var V=mv(f),te=Kd(f);yf(Gn);do try{ey();break}catch(Qe){vv(f,Qe)}while(!0);if(gt(),nr=j,yv(V),bn&&Xd(te),Lo===Ud){var se=jd;throw zp(),Hf(f,C),Vf(f,C),W0(f),se}if(Gn!==null)zp();else{Rv();var Ue=f.finishedWork=f.current.alternate;f.finishedExpirationTime=C,Wm(f,Ue,Lo,C)}if(W0(f),f.callbackNode===A)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 A=f.lastSuspendedTime;C===A&&(f.nextKnownPendingLevel=Lp(d)),p();var j=Ul===Un;if(j&&!(Jo&&Wf.current)){var V=Rp+No-yt();if(V>10){if(zd){var te=f.lastPingedTime;if(te===at||te>=C){f.lastPingedTime=C,Hf(f,C);break}}var se=Gd(f);if(se!==at&&se!==C)break;if(A!==at&&A!==C){f.lastPingedTime=A;break}f.timeoutHandle=Tt(so.bind(null,f),V);break}}so(f);break}case x1:{Vf(f,C);var Ue=f.lastSuspendedTime;if(C===Ue&&(f.nextKnownPendingLevel=Lp(d)),p(),!(Jo&&Wf.current)){if(zd){var Qe=f.lastPingedTime;if(Qe===at||Qe>=C){f.lastPingedTime=C,Hf(f,C);break}}var vt=Gd(f);if(vt!==at&&vt!==C)break;if(Ue!==at&&Ue!==C){f.lastPingedTime=Ue;break}var Nt;if(R1!==Un)Nt=j0(R1)-yt();else if(Ul===Un)Nt=0;else{var Yt=wv(Ul),Ht=yt(),yn=j0(C)-Ht,kr=Ht-Yt;kr<0&&(kr=0),Nt=Up(kr)-kr,yn10){f.timeoutHandle=Tt(so.bind(null,f),Nt);break}}so(f);break}case xp:{if(!(Jo&&Wf.current)&&Ul!==Un&&Rc!==null){var oi=jp(Ul,C,Rc);if(oi>10){Vf(f,C),f.timeoutHandle=Tt(so.bind(null,f),oi);break}}so(f);break}default:throw Error("Unknown root exit status.")}}function k1(f){var d=f.lastExpiredTime,E=d!==at?d:Un;if(f.finishedExpirationTime===E)so(f);else{if((nr&(T0|Os))!==gu)throw Error("Should not already be working.");if(nf(),(f!==ml||E!==Wo)&&(Hf(f,E),ee(f,E)),Gn!==null){var C=nr;nr|=T0;var A=mv(f),j=Kd(f);yf(Gn);do try{Sv();break}catch(te){vv(f,te)}while(!0);if(gt(),nr=C,yv(A),bn&&Xd(j),Lo===Ud){var V=jd;throw zp(),Hf(f,E),Vf(f,E),W0(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.");Rv(),f.finishedWork=f.current.alternate,f.finishedExpirationTime=E,Vm(f,Lo,E),W0(f)}}return null}function Vm(f,d,E){ml=null,(d===C1||d===x1)&&p(),so(f)}function Gm(f,d){Vp(f,d),W0(f),(nr&(T0|Os))===gu&&Bt()}function dv(){if((nr&(T1|T0|Os))!==gu){(nr&T0)!==gu&&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(Ni,f.bind(null,d,E,C))}function Km(){if(tf!==null){var f=tf;tf=null,f.forEach(function(d,E){Vp(E,d),W0(E)}),Bt()}}function Xm(f,d){var E=nr;nr|=T1;try{return f(d)}finally{nr=E,nr===gu&&Bt()}}function Qm(f,d){var E=nr;nr|=Ui;try{return f(d)}finally{nr=E,nr===gu&&Bt()}}function hv(f,d,E,C){var A=nr;nr|=Tp;try{return Sn(ni,f.bind(null,d,E,C))}finally{nr=A,nr===gu&&Bt()}}function Jm(f,d){var E=nr;nr&=~T1,nr|=Bd;try{return f(d)}finally{nr=E,nr===gu&&Bt()}}function Op(f,d){if((nr&(T0|Os))!==gu)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(Ni,f.bind(null,d))}finally{nr=E,Bt()}}function Zm(f){var d=nr;nr|=T1;try{Sn(Ni,f)}finally{nr=d,nr===gu&&Bt()}}function Hf(f,d){f.finishedWork=null,f.finishedExpirationTime=at;var E=f.timeoutHandle;if(E!==nl&&(f.timeoutHandle=nl,d0(E)),Gn!==null)for(var C=Gn.return;C!==null;)nv(C),C=C.return;ml=f,Gn=C0(f.current,null,d),Wo=d,Lo=Bf,jd=null,Ul=Un,R1=Un,Rc=null,Ac=at,zd=!1,bn&&(jf=null),Al.discardPendingWarnings(),$s=null}function vv(f,d){do{try{if(gt(),Ed(),ut(),Gn===null||Gn.return===null)return Lo=Ud,jd=d,null;en&&Gn.mode&ii&&p1(Gn,!0),fv(f,Gn.return,Gn,d,Wo),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 yv(f){Mr.current=f}function Kd(f){if(bn){var d=M.__interactionsRef.current;return M.__interactionsRef.current=f.memoizedInteractions,d}return null}function Xd(f){bn&&(M.__interactionsRef.current=f)}function Mp(){Rp=yt()}function gv(f,d){fru&&(Ul=f),d!==null&&fru&&(R1=f,Rc=d)}function Qd(f){f>Ac&&(Ac=f)}function _v(){Lo===Bf&&(Lo=C1)}function Ev(){(Lo===Bf||Lo===C1)&&(Lo=x1),Ac!==at&&ml!==null&&(Vf(ml,Wo),u_(ml,Ac))}function kp(){Lo!==xp&&(Lo=Cp)}function Dv(){return Lo===Bf}function wv(f){var d=j0(f);return d-Ef}function $m(f,d){var E=j0(f);return E-(d.timeoutMs|0||Ef)}function Sv(){for(;Gn!==null;)Gn=Jd(Gn)}function ey(){for(;Gn!==null&&!Fn();)Gn=Jd(Gn)}function Jd(f){var d=f.alternate;es(f),Dt(f);var E;return en&&(f.mode&ii)!==Ar?(W2(f),E=L1(d,f,Wo),p1(f,!0)):E=L1(d,f,Wo),ut(),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&Io)===xi){Dt(Gn);var C=void 0;if(!en||(Gn.mode&ii)===Ar?C=tv(d,Gn,Wo):(W2(Gn),C=tv(d,Gn,Wo),p1(Gn,!1)),ei(Gn),ut(),ty(Gn),C!==null)return C;if(E!==null&&(E.effectTag&Io)===xi){E.firstEffect===null&&(E.firstEffect=Gn.firstEffect),Gn.lastEffect!==null&&(E.lastEffect!==null&&(E.lastEffect.nextEffect=Gn.firstEffect),E.lastEffect=Gn.lastEffect);var A=Gn.effectTag;A>su&&(E.lastEffect!==null?E.lastEffect.nextEffect=Gn:E.firstEffect=Gn,E.lastEffect=Gn)}}else{var j=Mm(Gn,Wo);if(en&&(Gn.mode&ii)!==Ar){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 h0(Gn),j.effectTag&=Xl,j;ei(Gn),E!==null&&(E.firstEffect=E.lastEffect=null,E.effectTag|=Io)}var se=Gn.sibling;if(se!==null)return se;Gn=E}while(Gn!==null);return Lo===Bf&&(Lo=xp),null}function Lp(f){var d=f.expirationTime,E=f.childExpirationTime;return d>E?d:E}function ty(f){if(!(Wo!==Di&&f.childExpirationTime===Di)){var d=at;if(en&&(f.mode&ii)!==Ar){for(var E=f.actualDuration,C=f.selfBaseDuration,A=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),A&&(E+=j.actualDuration),C+=j.treeBaseDuration,j=j.sibling}f.actualDuration=E,f.treeBaseDuration=C}else for(var se=f.child;se!==null;){var Ue=se.expirationTime,Qe=se.childExpirationTime;Ue>d&&(d=Ue),Qe>d&&(d=Qe),se=se.sibling}f.childExpirationTime=d}}function so(f){var d=Jt();return Sn(Ni,Np.bind(null,f,d)),null}function Np(f,d){do nf();while(kc!==null);if(ay(),(nr&(T0|Os))!==gu)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=at,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=at,f.callbackPriority=Do,f.nextKnownPendingLevel=at,t0();var A=Lp(E);lE(f,C,A),f===ml&&(ml=null,Gn=null,Wo=at);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,Re(),Hn(f.containerInfo),dn=j;do if(pl(null,ny,null),tr()){if(dn===null)throw Error("Should be working on an effect.");var se=Js();qf(dn,se),dn=dn.nextEffect}while(dn!==null);rt(),en&&Lh(),Ye(),dn=j;do if(pl(null,ry,null,f,d),tr()){if(dn===null)throw Error("Should be working on an effect.");var Ue=Js();qf(dn,Ue),dn=dn.nextEffect}while(dn!==null);Kt(),qr(f.containerInfo),f.current=E,Xt(),dn=j;do if(pl(null,Fp,null,f,C),tr()){if(dn===null)throw Error("Should be working on an effect.");var Qe=Js();qf(dn,Qe),dn=dn.nextEffect}while(dn!==null);pr(),dn=null,ae(),bn&&Xd(te),nr=V}else f.current=E,Re(),rt(),en&&Lh(),Ye(),Kt(),Xt(),pr();n0();var vt=Mc;if(Mc)Mc=!1,kc=f,Ap=C,A1=d;else for(dn=j;dn!==null;){var Nt=dn.nextEffect;dn.nextEffect=null,dn=Nt}var Yt=f.firstPendingTime;if(Yt!==at){if(bn){if(jf!==null){var Ht=jf;jf=null;for(var yn=0;ynKn?Kn:A1;return A1=Do,Sn(f,Pp)}}function Pp(){if(kc===null)return!1;var f=kc,d=Ap;if(kc=null,Ap=at,(nr&(T0|Os))!==gu)throw Error("Cannot flush passive effects while already rendering.");var E=nr;nr|=Os;for(var C=Kd(f),A=f.current.firstEffect;A!==null;){{if(Dt(A),pl(null,Ra,null,A),tr()){if(A===null)throw Error("Should be working on an effect.");var j=Js();qf(A,j)}ut()}var V=A.nextEffect;A.nextEffect=null,A=V}return bn&&(Xd(C),he(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 iy(f){Hd||(Hd=!0,qd=f)}var uy=iy;function Cv(f,d,E){var C=hp(E,d),A=sv(f,C,Un);Ga(f,A);var j=Vd(f,Un);j!==null&&(W0(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===O){var C=E.type,A=E.stateNode;if(typeof C.getDerivedStateFromError=="function"||typeof A.componentDidCatch=="function"&&!Ip(A)){var j=hp(d,f),V=av(E,j,Un);Ga(E,V);var te=Vd(E,Un);te!==null&&(W0(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&&Wo===E){Lo===x1||Lo===C1&&Ul===Un&&yt()-RpHm)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 ay(){Al.flushLegacyContextWarning(),yi&&Al.flushPendingUnsafeLifecycleWarnings()}function Rv(){var f=!0;gf(Uf,f),Uf=null}function zp(){var f=!1;gf(Uf,f),Uf=null}function Hp(f,d){Hr&&ml!==null&&d>Wo&&(Uf=f)}var Zd=null;function fy(f){{var d=f.tag;if(d!==B&&d!==O&&d!==N&&d!==ue&&d!==me&&d!==re)return;var E=Wt(f.type)||"ReactComponent";if(Zd!==null){if(Zd.has(E))return;Zd.add(E)}else Zd=new Set([E]);He(!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===O?"the componentWillUnmount method":"a useEffect cleanup function",Cr(f))}}var L1;if(Qo){var cy=null;L1=function(f,d,E){var C=r_(cy,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 A=Js();throw A}else throw j}}}else L1=ap;var Av=!1,Ov=!1;function dy(f){if(f.tag===O)switch(Lr){case"getChildContext":if(Ov)return;He(!1,"setState(...): Cannot call setState() inside getChildContext()"),Ov=!0;break;case"render":if(Av)return;He(!1,"Cannot update during an existing state transition (such as within `render`). Render methods should be a pure function of props and state."),Av=!0;break}}var Wf={current:!1};function qp(f){ms===!0&&vl.current===!0&&Wf.current!==!0&&He(!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)!==Ar&&vl.current===!1&&Wf.current===!1&&He(!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`,Wt(f.type),Cr(f))}function py(f){ms===!0&&nr===gu&&vl.current===!1&&Wf.current===!1&&He(!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`,Wt(f.type),Cr(f))}var hy=py,Wp=!1;function vy(f){Wp===!1&&t.unstable_flushAllWithoutAsserting===void 0&&(f.mode&Y||f.mode&ri?(Wp=!0,He(!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,He(!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 my(f){{var d=Jt();if((f.mode&ri)!==xi&&(d===ni||d===Ni))for(var E=f;E!==null;){var C=E.alternate;if(C!==null)switch(E.tag){case O:var A=C.updateQueue;if(A!==null)for(var j=A.firstUpdate;j!==null;){var V=j.priority;if(V===ni||V===Ni){$s===null?$s=new Set([Wt(E.type)]):$s.add(Wt(E.type));break}j=j.next}break;case N:case ue:case re:if(E.memoizedState!==null&&E.memoizedState.baseUpdate!==null)for(var te=E.memoizedState.baseUpdate;te!==null;){var se=te.priority;if(se===ni||se===Ni){$s===null?$s=new Set([Wt(E.type)]):$s.add(Wt(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&&He(!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,A=C.get(d);A!=null?E.forEach(function(te){A.has(te)||te.__count++,A.add(te)}):(C.set(d,new Set(E)),E.forEach(function(te){te.__count++}));var j=M.__subscriberRef.current;if(j!==null){var V=v(f,d);j.onWorkScheduled(E,V)}}}function W(f,d){!bn||P(f,d,M.__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=M.__subscriberRef.current;if(C!==null){var A=v(f,d);try{C.onWorkStarted(E,A)}catch(j){_n(Ni,function(){throw j})}}}}}function he(f,d){if(!!bn){var E=f.firstPendingTime,C;try{if(C=M.__subscriberRef.current,C!==null&&f.memoizedInteractions.size>0){var A=v(f,d);C.onWorkStopped(f.memoizedInteractions,A)}}catch(V){_n(Ni,function(){throw V})}finally{var j=f.pendingInteractionMap;j.forEach(function(V,te){te>E&&(j.delete(te),V.forEach(function(se){if(se.__count--,C!==null&&se.__count===0)try{C.onInteractionScheduledWorkCompleted(se)}catch(Ue){_n(Ni,function(){throw Ue})}}))})}}}var De=null,be=null,Et=!1,St=typeof __REACT_DEVTOOLS_GLOBAL_HOOK__!="undefined";function At(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 He(!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);De=function(C,A){try{var j=(C.current.effectTag&Xr)===Xr;if(en){var V=Nc(),te=rd(V,A);d.onCommitFiberRoot(E,C,te,j)}else d.onCommitFiberRoot(E,C,void 0,j)}catch(se){Et||(Et=!0,He(!1,"React DevTools encountered an error: %s",se))}},be=function(C){try{d.onCommitFiberUnmount(E,C)}catch(A){Et||(Et=!0,He(!1,"React DevTools encountered an error: %s",A))}}}catch(C){He(!1,"React DevTools encountered an error: %s.",C)}return!0}function on(f,d){typeof De=="function"&&De(f,d)}function kn(f){typeof be=="function"&&be(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=xi,this.nextEffect=null,this.firstEffect=null,this.lastEffect=null,this.expirationTime=at,this.childExpirationTime=at,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 a0(f){var d=f.prototype;return!!(d&&d.isReactComponent)}function ao(f){return typeof f=="function"&&!a0(f)&&f.defaultProps===void 0}function Ms(f){if(typeof f=="function")return a0(f)?O:N;if(f!=null){var d=f.$$typeof;if(d===Mn)return ue;if(d===Gt)return me}return T}function C0(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=xi,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 A=f.dependencies;switch(C.dependencies=A===null?null:{expirationTime:A.expirationTime,firstContext:A.firstContext,responders:A.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 re:C.type=ro(f.type);break;case O:C.type=zo(f.type);break;case ue: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=at,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 Z4(f){var d;return f===Mo?d=ri|Y|mr:f===Uo?d=Y|mr:d=Ar,en&&St&&(d|=ii),Zi(B,null,null,d)}function yy(f,d,E,C,A,j){var V,te=T,se=f;if(typeof f=="function")a0(f)?(te=O,se=zo(se)):se=ro(se);else if(typeof f=="string")te=q;else{e:switch(f){case le:return rf(E.children,A,j,d);case an:te=pe,A|=ri|Y|mr;break;case qe:te=pe,A|=mr;break;case dt:return eE(E,A,j,d);case lr:return tE(E,A,j,d);case ln:return nE(E,A,j,d);default:{if(typeof f=="object"&&f!==null)switch(f.$$typeof){case Rt:te=ve;break e;case nn:te=ge;break e;case Mn:te=ue,se=wf(se);break e;case Gt:te=me;break e;case Er:te=we,se=null;break e;case w:if(Vt)return n_(f,E,A,j,d);break;case Xn:if(Au)return $4(f,E,A,j,d)}var Ue="";{(f===void 0||typeof f=="object"&&f!==null&&Object.keys(f).length===0)&&(Ue+=" 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 Qe=C?Wt(C.type):null;Qe&&(Ue+=` - -Check the render method of \``+Qe+"`.")}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)+"."+Ue)}}}return V=Zi(te,E,d,A),V.elementType=f,V.type=se,V.expirationTime=j,V}function gy(f,d,E){var C=null;C=f._owner;var A=f.type,j=f.key,V=f.props,te=yy(A,j,V,C,d,E);return te._debugSource=f._source,te._debugOwner=f._owner,te}function rf(f,d,E,C){var A=Zi(m,f,C,d);return A.expirationTime=E,A}function n_(f,d,E,C,A){var j=Zi(pt,d,A,E);return j.elementType=f,j.type=f,j.expirationTime=C,j}function $4(f,d,E,C,A){var j=Zi(Xe,d,A,E);return j.type=f,j.elementType=f,j.expirationTime=C,j}function eE(f,d,E,C){(typeof f.id!="string"||typeof f.onRender!="function")&&He(!1,'Profiler must specify an "id" string and "onRender" function as props');var A=Zi(_e,f,C,d|ii);return A.elementType=dt,A.type=dt,A.expirationTime=E,A}function tE(f,d,E,C){var A=Zi(ce,f,C,d);return A.type=lr,A.elementType=lr,A.expirationTime=E,A}function nE(f,d,E,C){var A=Zi(ct,f,C,d);return A.type=ln,A.elementType=ln,A.expirationTime=E,A}function _y(f,d,E){var C=Zi(ne,f,null,d);return C.expirationTime=E,C}function rE(){var f=Zi(q,null,null,Ar);return f.elementType="DELETED",f.type="DELETED",f}function iE(f){var d=Zi(je,null,null,Ar);return d.stateNode=f,d}function Ey(f,d,E){var C=f.children!==null?f.children:[],A=Zi(H,C,f.key,d);return A.expirationTime=E,A.stateNode={containerInfo:f.containerInfo,pendingChildren:null,implementation:f.implementation},A}function r_(f,d){return f===null&&(f=Zi(T,null,null,Ar)),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 uE(f,d,E){this.tag=d,this.current=null,this.containerInfo=f,this.pendingChildren=null,this.pingCache=null,this.finishedExpirationTime=at,this.finishedWork=null,this.timeoutHandle=nl,this.context=null,this.pendingContext=null,this.hydrate=E,this.callbackNode=null,this.callbackPriority=Do,this.firstPendingTime=at,this.firstSuspendedTime=at,this.lastSuspendedTime=at,this.nextKnownPendingLevel=at,this.lastPingedTime=at,this.lastExpiredTime=at,bn&&(this.interactionThreadID=M.unstable_getThreadID(),this.memoizedInteractions=new Set,this.pendingInteractionMap=new Map),Yi&&(this.hydrationCallbacks=null)}function oE(f,d,E,C){var A=new uE(f,d,E);Yi&&(A.hydrationCallbacks=C);var j=Z4(d);return A.current=j,j.stateNode=A,A}function i_(f,d){var E=f.firstSuspendedTime,C=f.lastSuspendedTime;return E!==at&&E>=d&&C<=d}function Vf(f,d){var E=f.firstSuspendedTime,C=f.lastSuspendedTime;Ed||E===at)&&(f.lastSuspendedTime=d),d<=f.lastPingedTime&&(f.lastPingedTime=at),d<=f.lastExpiredTime&&(f.lastExpiredTime=at)}function u_(f,d){var E=f.firstPendingTime;d>E&&(f.firstPendingTime=d);var C=f.firstSuspendedTime;C!==at&&(d>=C?f.firstSuspendedTime=f.lastSuspendedTime=f.nextKnownPendingLevel=at:d>=f.lastSuspendedTime&&(f.lastSuspendedTime=d+1),d>f.nextKnownPendingLevel&&(f.nextKnownPendingLevel=d))}function lE(f,d,E){f.firstPendingTime=E,d<=f.lastSuspendedTime?f.firstSuspendedTime=f.lastSuspendedTime=f.nextKnownPendingLevel=at:d<=f.firstSuspendedTime&&(f.firstSuspendedTime=d-1),d<=f.lastPingedTime&&(f.lastPingedTime=at),d<=f.lastExpiredTime&&(f.lastExpiredTime=at)}function Vp(f,d){var E=f.lastExpiredTime;(E===at||E>d)&&(f.lastExpiredTime=d)}var sE={debugTool:null},Lv=sE,Dy,wy;Dy=!1,wy={};function aE(f){if(!f)return Rn;var d=kt(f),E=xl(d);if(d.tag===O){var C=d.type;if(Xi(C))return Oo(d,C,E)}return E}function Sy(f){var d=kt(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=bo(d);return E===null?null:E.stateNode}function fE(f,d){{var E=kt(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=bo(E);if(C===null)return null;if(C.mode&mr){var A=Wt(E.type)||"Component";wy[A]||(wy[A]=!0,E.mode&mr?He(!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,A,Cr(C)):He(!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,A,Cr(C)))}return C.stateNode}return Sy(f)}function cE(f,d,E,C){return oE(f,d,E,C)}function o_(f,d,E,C){var A=d.current,j=jl();typeof jest!="undefined"&&(vy(A),qp(A));var V=_0(),te=zf(j,A,V);Lv.debugTool&&(A.alternate===null?Lv.debugTool.onMountContainer(d):f===null?Lv.debugTool.onUnmountContainer(d):Lv.debugTool.onUpdateContainer(d));var se=aE(E);d.context===null?d.context=se:d.pendingContext=se,Lr==="render"&&An!==null&&!Dy&&(Dy=!0,He(!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.`,Wt(An.type)||"Unknown"));var Ue=Cu(te,V);return Ue.payload={element:f},C=C===void 0?null:C,C!==null&&(typeof C!="function"&&He(!1,"render(...): Expected the last optional `callback` argument to be a function. Instead received: %s.",C),Ue.callback=C),Ga(A,Ue),yl(A,te),te}function dE(f){var d=f.current;if(!d.child)return null;switch(d.child.tag){case q:return N0(d.child.stateNode);default:return d.child.stateNode}}function pE(f){switch(f.tag){case B:var d=f.stateNode;d.hydrate&&Gm(d,d.firstPendingTime);break;case ce:Op(function(){return yl(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 A=d[E],j=Array.isArray(f)?f.slice():a({},f);return j[A]=xy(f[A],d,E+1,C),j},p_=function(f,d,E){return xy(f,d,0,E)};a_=function(f,d,E,C){for(var A=f.memoizedState;A!==null&&d>0;)A=A.next,d--;if(A!==null){var j=p_(A.memoizedState,E,C);A.memoizedState=j,A.baseState=j,f.memoizedProps=a({},f.memoizedProps),yl(f,Un)}},f_=function(f,d,E){f.pendingProps=p_(f.memoizedProps,d,E),f.alternate&&(f.alternate.pendingProps=f.pendingProps),yl(f,Un)},c_=function(f){yl(f,Un)},d_=function(f){Cy=f}}function yE(f){var d=f.findFiberByHostInstance,E=nt.ReactCurrentDispatcher;return At(a({},f,{overrideHookState:a_,overrideProps:f_,setSuspenseHandler:d_,scheduleUpdate:c_,currentDispatcherRef:E,findHostInstanceByFiber:function(C){var A=bo(C);return A===null?null:A.stateNode},findFiberByHostInstance:function(C){return d?d(C):null},findHostInstancesForRefresh:od,scheduleRefresh:Ol,scheduleRoot:Cs,setRefreshHandler:Wa,getCurrentFiber:function(){return An}}))}var h_=Object.freeze({createContainer:cE,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:dE,attemptSynchronousHydration:pE,attemptUserBlockingHydration:hE,attemptContinuousHydration:Ty,attemptHydrationAtCurrentPriority:vE,findHostInstance:Sy,findHostInstanceWithWarning:fE,findHostInstanceWithNoPortals:mE,shouldSuspend:s_,injectIntoDevTools:yE}),gE=h_.default||h_;Qy.exports=gE;var _E=Qy.exports;return Qy.exports=i,_E})});var vT=Ke((HW,ID)=>{"use strict";process.env.NODE_ENV==="production"?ID.exports=fT():ID.exports=hT()});var yT=Ke((qW,mT)=>{"use strict";var zI={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};mT.exports=zI});var DT=Ke((WW,gT)=>{"use strict";var HI=Object.assign||function(i){for(var o=1;o"}}]),i}(),_T=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}(),ET=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(M,N,O){var T=M[N];M[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,O=arguments.length>2&&arguments[2]!==void 0?arguments[2]:NaN,T=arguments.length>3&&arguments[3]!==void 0?arguments[3]:nc.DIRECTION_LTR;return M.call(this,N,O,T)}),HI({Config:o.Config,Node:o.Node,Layout:i("Layout",qI),Size:i("Size",_T),Value:i("Value",ET),getInstanceCount:function(){return o.getInstanceCount.apply(o,arguments)}},nc)}});var wT=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 M=getCFunc(o),N=[],O=0;if(_)for(var T=0;T<_.length;T++){var B=toC[c[T]];B?(O===0&&(O=Runtime.stackSave()),N[T]=B(_[T])):N[T]=_[T]}var H=M.apply(null,N);if(a==="string"&&(H=Pointer_stringify(H)),O!==0){if(t&&t.async){EmterpreterAsync.asyncFinalizers.push(function(){Runtime.stackRestore(O)});return}Runtime.stackRestore(O)}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 M=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,M?1:o.length)),_){var c=N,O;for(assert((N&3)==0),O=N+(t&~3);c>2]=0;for(O=N+t;c>0]=0;return N}if(M==="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 M=1024,N;o>0;)N=String.fromCharCode.apply(String,HEAPU8.subarray(i,i+Math.min(o,M))),t=t?t+N:N,i+=M,o-=M;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,M,N,O,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:(M=i[o++]&63,(c&248)==240?c=(c&7)<<18|_<<12|t<<6|M:(N=i[o++]&63,(c&252)==248?c=(c&3)<<24|_<<18|t<<12|M<<6|N:(O=i[o++]&63,c=(c&1)<<30|_<<24|t<<18|M<<12|N<<6|O))),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,M=0;M=55296&&N<=57343&&(N=65536+((N&1023)<<10)|i.charCodeAt(++M)&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),M=o(_,0,0,t);if(getValue(t,"i32")===0&&M)return Pointer_stringify(M)}catch(N){}finally{_&&_free(_),t&&_free(t),M&&_free(M)}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,M=a&65535;return _*M+(c*M+_*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,M,N){return _nbind.callbackSignatureList[i].apply(this,arguments)}];function _emscripten_asm_const_iiiiiiii(i,o,a,c,_,t,M,N){return ASM_CONSTS[i](o,a,c,_,t,M,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,M,N,O){return ASM_CONSTS[i](o,a,c,_,t,M,N,O)}function _emscripten_asm_const_iiididi(i,o,a,c,_,t,M){return ASM_CONSTS[i](o,a,c,_,t,M)}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,M;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--)(M=i[N])&&(t=(_<3?M(t):_>3?M(o,a,t):M(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 M=Math.max(0,Browser.mainLoop.tickStartTime+o-_emscripten_get_now())|0;setTimeout(Browser.mainLoop.runner,M)},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(M){M.source===window&&M.data===c&&(M.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 M=Browser.mainLoop.currentlyRunningMainloop;if(Browser.mainLoop.runner=function(){if(!ABORT){if(Browser.mainLoop.queue.length>0){var O=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()-O)+" ms"),Browser.mainLoop.updateStatus(),M1&&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),!(M0?_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=re>>we-6&63;we-=6,me+=_e[je]}return we==2?(me+=_e[(re&3)<<4],me+=ce+ce):we==4&&(me+=_e[(re&15)<<2],me+=ce),me}m.src="data:audio/x-"+M.substr(-3)+";base64,"+ve(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 M={antialias:!1,alpha:!1};if(c)for(var N in c)M[N]=c[N];t=GL.createContext(i,M),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(O){O()}),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 M=c.parentNode;(document.fullscreenElement||document.mozFullScreenElement||document.msFullscreenElement||document.webkitFullscreenElement||document.webkitCurrentFullScreenElement)===M?(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()):(M.parentNode.insertBefore(c,M),M.parentNode.removeChild(M),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 M=i.touch;if(M===void 0)return;var N=M.pageX-(_+o.left),O=M.pageY-(t+o.top);N=N*(a/o.width),O=O*(c/o.height);var T={x:N,y:O};if(i.type==="touchstart")Browser.lastTouches[M.identifier]=T,Browser.touches[M.identifier]=T;else if(i.type==="touchend"||i.type==="touchmove"){var B=Browser.touches[M.identifier];B||(B=T),Browser.lastTouches[M.identifier]=B,Browser.touches[M.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(O,T,B,H,q,ne){if(T==1){var m=H&896;(m==128||m==256||m==384)&&(O="X const")}var pe;return ne?pe=B.replace("X",O).replace("Y",q):pe=O.replace("X",B).replace("Y",q),pe.replace(/([*&]) (?=[*&])/g,"$1")}function c(O,T,B,H,q){throw new Error(O+" type "+B.replace("X",T+"?")+(H?" with flag "+H:"")+" in "+q)}function _(O,T,B,H,q,ne,m,pe){ne===void 0&&(ne="X"),pe===void 0&&(pe=1);var ge=B(O);if(ge)return ge;var ve=H(O),ue=ve.placeholderFlag,_e=o[ue];m&&_e&&(ne=a(m[2],m[0],ne,_e[0],"?",!0));var ce;ue==0&&(ce="Unbound"),ue>=10&&(ce="Corrupt"),pe>20&&(ce="Deeply nested"),ce&&c(ce,O,ne,ue,q||"?");var me=ve.paramList[0],re=_(me,T,B,H,q,ne,_e,pe+1),we,Ie={flags:_e[0],id:O,name:"",paramList:[re]},je=[],ct="?";switch(ve.placeholderFlag){case 1:we=re.spec;break;case 2:if((re.flags&15360)==1024&&re.spec.ptrSize==1){Ie.flags=7168;break}case 3:case 6:case 5:we=re.spec,(re.flags&15360)!=2048;break;case 8:ct=""+ve.paramList[1],Ie.paramList.push(ve.paramList[1]);break;case 9:for(var pt=0,Xe=ve.paramList[1];pt>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(),M=SYSCALLS.get(),N=_;return FS.llseek(a,N,M),HEAP32[t>>2]=a.position,a.getdents&&N===0&&M===0&&(a.getdents=null),0}catch(O){return(typeof FS=="undefined"||!(O instanceof FS.ErrnoError))&&abort(O),-O.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 M=0;M<_;M++){for(var N=HEAP32[c+M*8>>2],O=HEAP32[c+(M*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,M,N,O){var T=c.call(this)||this;if(!(T instanceof _))return new(Function.prototype.bind.apply(_,Array.prototype.concat.apply([null],arguments)));var B=M,H=N,q=O;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},pe={__nbindFlags:B,__nbindPtr:H};q&&(pe.__nbindShared=q,_nbind.mark(T));for(var ge=0,ve=Object.keys(pe);ge>=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?M=Buffer.from(t):M=new Buffer(t),M.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(M){if(typeof M!="number"&&M!=="longjmp")throw M;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(M){if(typeof M!="number"&&M!=="longjmp")throw M;Module.setThrew(1,0)}}function invoke_viiiiii(i,o,a,c,_,t,M){try{Module.dynCall_viiiiii(i,o,a,c,_,t,M)}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(M){if(typeof M!="number"&&M!=="longjmp")throw M;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,M){try{Module.dynCall_viififi(i,o,a,c,_,t,M)}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),M=new i.Uint8Array(a),N=new i.Uint16Array(a),O=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,pe=o.STACK_MAX|0,ge=o.cttz_i8|0,ve=o.___dso_handle|0,ue=0,_e=0,ce=0,me=0,re=i.NaN,we=i.Infinity,Ie=0,je=0,ct=0,pt=0,Xe=0,tt=0,He=i.Math.floor,kt=i.Math.abs,zt=i.Math.sqrt,nt=i.Math.pow,X=i.Math.cos,fe=i.Math.sin,xe=i.Math.tan,le=i.Math.acos,qe=i.Math.asin,dt=i.Math.atan,Rt=i.Math.atan2,nn=i.Math.exp,an=i.Math.log,Mn=i.Math.ceil,lr=i.Math.imul,ln=i.Math.min,Gt=i.Math.max,Er=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,po=o.invoke_fiff,A0=o.invoke_vi,J0=o.invoke_vii,Ps=o.invoke_ii,Z0=o.invoke_viddi,$0=o.invoke_vidd,Wt=o.invoke_iiii,xi=o.invoke_diii,su=o.invoke_di,mi=o.invoke_iid,Dr=o.invoke_iii,el=o.invoke_viiddi,Ko=o.invoke_viiiiii,Uu=o.invoke_dii,Xo=o.invoke_i,Xr=o.invoke_iiiiii,O0=o.invoke_viiid,M0=o.invoke_viififi,Po=o.invoke_viii,au=o.invoke_v,ki=o.invoke_viid,Is=o.invoke_idd,Xl=o.invoke_viiii,Io=o._emscripten_asm_const_iiiii,ho=o._emscripten_asm_const_iiidddddd,Hr=o._emscripten_asm_const_iiiid,Ri=o.__nbind_reference_external,Qo=o._emscripten_asm_const_iiiiiiii,yi=o._removeAccessorPrefix,en=o._typeModule,bn=o.__nbind_register_pool,Ai=o.__decorate,gi=o._llvm_stackrestore,Vt=o.___cxa_atexit,Au=o.__extends,eu=o.__nbind_get_value_object,Jo=o.__ZN8facebook4yoga14YGNodeToStringEPNSt3__212basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEP6YGNode14YGPrintOptionsj,Yi=o._emscripten_set_main_loop_timing,Ql=o.__nbind_register_primitive,k0=o.__nbind_register_type,ai=o._emscripten_memcpy_big,f0=o.__nbind_register_function,Jl=o.___setErrNo,L0=o.__nbind_register_class,bs=o.__nbind_finish,$n=o._abort,tl=o._nbind_value,c0=o._llvm_stacksave,bo=o.___syscall54,Sl=o._defineHidden,N0=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,vo=o._atexit,Li=o.___syscall140,mo=o.___syscall146,vs=w(0);let Tt=w(0);function d0(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,pe=n}function ms(e,n){e=e|0,n=n|0,ue||(ue=e,_e=n)}function Bo(e){e=e|0,tt=e}function Q(){return tt|0}function Se(){var e=0,n=0;gr(8104,8,400)|0,gr(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,Vt(17,8104,ve|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 ht(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,gr(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;gr(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)),F0(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&&(ky(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 F0(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;gr(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||nD[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&&(ky(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 p0(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)),F0(n),n=e+976|0,r=t[n>>2]|0,gr(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 yo(){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 Zo(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),ys(e),n=e+948|0,t[h>>2]=(t[n>>2]|0)+(r<<2),t[s>>2]=t[h>>2],To(n,s,l)|0,t[(t[l>>2]|0)+944>>2]=e,Qn(e),m=u}function ys(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||nD[u&15](h,D,e,n),n=n+1|0;while((n|0)!=(r|0))}}function To(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,Te=0,ye=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,Te=Ze+20|0,ye=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=Ao(e)|0,l>>>0>>0&&hi(e),k=t[e>>2]|0,L=(t[h>>2]|0)-k|0,s=L>>1,Y(ye,L>>2>>>0>>1>>>0?s>>>0>>0?u:s:l,n-k>>2,e+8|0),k=ye+8|0,u=t[k>>2]|0,s=ye+12|0,L=t[s>>2]|0,h=L,S=u;do if((u|0)==(L|0)){if(L=ye+4|0,u=t[L>>2]|0,Ge=t[ye>>2]|0,l=Ge,u>>>0<=Ge>>>0){u=h-l>>1,u=(u|0)==0?1:u,Y(K,u,u>>>2,t[ye+16>>2]|0),t[Be>>2]=t[L>>2],t[Te>>2]=t[k>>2],t[D>>2]=t[Be>>2],t[I>>2]=t[Te>>2],Di(K,D,I),u=t[ye>>2]|0,t[ye>>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&&(ky(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=at(e,ye,n)|0,ii(ye)}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(re),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)),_t(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,LF(e,n,400)|0&&(gr(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 go(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 Ce(e){return e=e|0,t[e+16>>2]|0}function Ee(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 mt(e){return e=e|0,t[e+28>>2]|0}function oe(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 We(e){return e=e|0,t[e+32>>2]|0}function it(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 It(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 Ft(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 An(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 _o(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(re),t[r>>2]=3,Qn(e))}function ut(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 Dt(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 Pt(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 wr(e){e=e|0;var n=0;n=e+352|0,(t[n>>2]|0)!=3&&(T[e+348>>2]=w(re),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 Co(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 $o(e){e=e|0;var n=0;n=e+360|0,(t[n>>2]|0)!=3&&(T[e+356>>2]=w(re),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 P0(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 I0(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 gs(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 b0(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 B0(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 xo(e){return e=e|0,w(T[e+404>>2])}function e0(e){return e=e|0,w(T[e+408>>2])}function U0(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 h0(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(kt(w(u-w(T[n>>2]))))>2]=0,t[u+4>>2]=0,t[u+8>>2]=0,Jo(u|0,e|0,n|0,0),pr(e,3,(c[u+11>>0]|0)<0?t[u>>2]|0:u,r),tP(u),m=r}function t0(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(QE(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 n0(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,Te=Tt,ye=Tt,Ze=Tt,Ge=Tt,ft=Tt,Me=Tt;return S>2]),Te!=w(0)):0)?(Ze=w(t0(n,Te,0,0)),Ge=w(t0(u,Te,0,0)),ye=w(t0(s,Te,0,0)),Te=w(t0(D,Te,0,0))):(ye=s,Ze=n,Te=D,Ge=u),(l|0)==(e|0)?Be=Ci(ye,Ze)|0:Be=0,(h|0)==(r|0)?K=Ci(Te,Ge)|0:K=0,((Be?0:(ft=w(n-k),!(Re(e,ft,S)|0)))?!(rt(e,ft,l,S)|0):0)?Be=Ye(e,ft,l,s,S)|0:Be=1,((K?0:(Me=w(u-I),!(Re(r,Me,L)|0)))?!(rt(r,Me,h,L)|0):0)?K=Ye(r,Me,h,D,L)|0:K=1,K=Be&K),K|0}function Re(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 rt(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 Kt(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,Te=0,ye=Tt,Ze=Tt,Ge=0,ft=0,Me=0,Pe=0,Zt=0,Br=0,In=0,gn=0,_r=0,Pr=0,Ln=0,uu=Tt,ls=Tt,ss=Tt,as=0,ta=0;Ln=m,m=m+160|0,gn=Ln+152|0,In=Ln+120|0,Br=Ln+104|0,Me=Ln+72|0,Te=Ln+56|0,Zt=Ln+8|0,ft=Ln,Pe=(t[2279]|0)+1|0,t[2279]=Pe,_r=e+984|0,((c[_r>>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(ye=w(Xt(e,2,h)),Ze=w(Xt(e,0,h)),I=e+916|0,ss=w(T[I>>2]),ls=w(T[e+920>>2]),uu=w(T[e+932>>2]),n0(l,n,s,r,t[e+924>>2]|0,ss,t[e+928>>2]|0,ls,uu,w(T[e+936>>2]),ye,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]),n0(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]),ye,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}Te=I+16|0,t[e+908>>2]=t[Te>>2],Be=I+20|0,t[e+912>>2]=t[Be>>2],(c[11698]|0)==0|K^1||(t[ft>>2]=Wr(Pe)|0,t[ft+4>>2]=Pe,pr(e,4,2972,ft),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[Te>>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[Te>>2]=K,t[Te+4>>2]=Pe,t[Te+8>>2]=Pr?3047:11699,pr(e,4,3038,Te),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&&(yu(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,gn),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[_r>>0]=0),t[2279]=(t[2279]|0)+-1,t[e+512>>2]=t[2278],m=Ln,Pr|(I|0)==0|0}function Xt(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(Oo(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 yu(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,Te=Tt,ye=Tt,Ze=Tt,Ge=Tt,ft=Tt,Me=Tt,Pe=Tt,Zt=0,Br=0,In=0,gn=Tt,_r=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,Sr=Tt,Bu=0,Dl=0,ds=0,Gl=0,Or=0,Bn=0,cf=0,mn=Tt,Y1=0,fo=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=Uo(2,Dl)|0,Bn=Uo(0,Dl)|0,T[e+440>>2]=w(zi(e,Or,h)),T[e+444>>2]=w(Oo(e,Or,h)),T[e+428>>2]=w(zi(e,Bn,h)),T[e+436>>2]=w(Oo(e,Bn,h)),T[e+464>>2]=w(Mo(e,Or)),T[e+468>>2]=w(v0(e,Or)),T[e+452>>2]=w(Mo(e,Bn)),T[e+460>>2]=w(v0(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;ys(e),lf=e+508|0,c[lf>>0]=0,Or=Uo(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)),Te=w($u(e,Bn,h)),Jf=w(Rr(e,Or,h)),Vl=w(Rr(e,Bn,h)),In=Bu?l:s,ff=Bu?s:l,Sr=Bu?Jf:Vl,ft=Bu?Vl:Jf,Qf=w(Xt(e,2,h)),Ge=w(Xt(e,0,h)),ye=w(w(Rn(e+364|0,h))-Sr),Ze=w(w(Rn(e+380|0,h))-Sr),Me=w(w(Rn(e+372|0,D))-ft),Pe=w(w(Rn(e+388|0,D))-ft),bc=Bu?ye:Me,Bc=Bu?Ze:Pe,Qf=w(n-Qf),n=w(Qf-Sr),Le(n)|0?Sr=n:Sr=w(Ru(w(Qp(n,Ze)),ye)),z1=w(r-Ge),n=w(z1-ft),Le(n)|0?fs=n:fs=w(Ru(w(Qp(n,Pe)),Me)),ye=Bu?Sr:fs,vu=Bu?fs:Sr;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(r0(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)Ni(I),c[I+985>>0]=1,c[I+984>>0]=0;else{Jr(I),S&&Ro(I,xl(I,Dl)|0,ye,vu,Sr);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,Sr,l,fs,Sr,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(Xt(I,Or,Sr))))}K=K+1|0}while((K|0)!=(Gl|0));for(ss=n>ye,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=ye,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),ye=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(Xt(Zt,Or,Sr)),vi=t[of>>2]|0,r=w(Rn(Zt+380+(vi<<3)|0,cs)),ft=w(T[Zt+504>>2]),r=w(Qp(r,ft)),r=w(Ru(w(Rn(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),r0(Zt)|0&&(Ze=w(Ze+w(nu(Zt))),ye=w(ye-w(ft*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),ye=w(0),I=0,In=Pr;while(0);vi=Ze>w(0)&Zew(0)&yeBc&((Le(Bc)|0)^1))n=Bc,vi=51;else if(c[(t[ls>>2]|0)+3>>0]|0)vi=51;else{if(gn!=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:(_r=w(n-Ge),Ln=n)),(vi|0)==53&&(vi=0,Ge>2]|0,Be=_rw(0),Me=w(_r/gn),Ze=w(0),Ge=w(0),n=w(0),k=I;do r=w(Rn(k+380+(K<<3)|0,cs)),ye=w(Rn(k+364+(K<<3)|0,cs)),ye=w(Qp(r,w(Ru(ye,w(T[k+504>>2]))))),Be?(r=w(ye*w(cu(k))),(r!=w(-0)?(mn=w(ye-w(ft*r)),B1=w(Kn(k,Or,mn,Ln,Sr)),mn!=B1):0)&&(Ze=w(Ze-w(B1-ye)),n=w(n+r))):((Zt?(Uc=w(nu(k)),Uc!=w(0)):0)?(mn=w(ye+w(Me*Uc)),U1=w(Kn(k,Or,mn,Ln,Sr)),mn!=U1):0)&&(Ze=w(Ze-w(U1-ye)),Ge=w(Ge-Uc)),k=t[k+960>>2]|0;while((k|0)!=0);if(n=w(Pe+n),ye=w(_r+Ze),b1)n=w(0);else{ft=w(gn+Ge),Be=t[of>>2]|0,Zt=yew(0),ft=w(ye/ft),n=w(0);do{mn=w(Rn(I+380+(Be<<3)|0,cs)),Ze=w(Rn(I+364+(Be<<3)|0,cs)),Ze=w(Qp(mn,w(Ru(Ze,w(T[I+504>>2]))))),Zt?(mn=w(Ze*w(cu(I))),ye=w(-mn),mn!=w(-0)?(mn=w(Me*ye),ye=w(Kn(I,Or,w(Ze+(Br?ye:mn)),Ln,Sr))):ye=Ze):(K?(j1=w(nu(I)),j1!=w(0)):0)?ye=w(Kn(I,Or,w(Ze+w(ft*j1)),Ln,Sr)):ye=Ze,n=w(n-w(ye-Ze)),Ge=w(Xt(I,Or,Sr)),r=w(Xt(I,Bn,Sr)),ye=w(ye+Ge),T[Fa>>2]=ye,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)||(eo(e,I)|0)!=4||(t[(Eo(I,Bn)|0)+4>>2]|0)==3||(t[(Do(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(Rn(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(ye-Ge),gn=w(mn/Ze),mn=w(Ze*mn),t[Ns>>2]=1,T[ql>>2]=w(r+(Bu?gn:mn));while(0);Fn(I,Or,Ln,Sr,sf,Fa),Fn(I,Bn,vu,Sr,Ns,ql);do if(Wu(I,Bn,vu)|0?0:(eo(e,I)|0)==4){if((t[(Eo(I,Bn)|0)+4>>2]|0)==3){k=0;break}k=(t[(Do(I,Bn)|0)+4>>2]|0)!=3}else k=0;while(0);mn=w(T[Fa>>2]),gn=w(T[ql>>2]),Y1=t[sf>>2]|0,fo=t[Ns>>2]|0,Kt(I,Bu?mn:gn,Bu?gn:mn,Dl,Bu?Y1:fo,Bu?fo:Y1,Sr,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(_r+n),fo=n>0]=fo|M[lf>>0],i2&n>w(0)?(k=t[of>>2]|0,((t[e+364+(k<<3)+4>>2]|0)!=0?(Wl=w(Rn(e+364+(k<<3)|0,cs)),Wl>=w(0)):0)?ye=w(Ru(w(0),w(Wl-w(Ln-n)))):ye=w(0)):ye=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[(Eo(I,Or)|0)+4>>2]|0)==3&1)+k|0,k=k+((t[(Do(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(ye*w(.5)),r=w(0);break e}case 2:{k=0,Ge=ye,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(Ru(ye,w(0)))/r);break e}case 5:{r=w(ye/w((s+1|0)>>>0)),k=0,Ge=r;break e}case 4:{r=w(ye/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(ye/w(k|0)),K=t[ds>>2]|0,I=Pr,ye=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(ie(k,Or,Ln)),mn=w(mn+w(Mo(e,Or))),mn=w(mn+w(zi(k,Or,Sr))),T[k+400+(t[Ic>>2]<<2)>>2]=mn;break e}break}case 0:if(fo=(t[(Eo(k,Or)|0)+4>>2]|0)==3,mn=w(Ze+n),n=fo?mn:n,S&&(fo=k+400+(t[Ic>>2]<<2)|0,T[fo>>2]=w(n+w(T[fo>>2]))),fo=(t[(Do(k,Or)|0)+4>>2]|0)==3,mn=w(Ze+n),n=fo?mn:n,ta){mn=w(r+w(Xt(k,Or,Sr))),ye=vu,n=w(n+w(mn+w(T[k+504>>2])));break e}else{n=w(n+w(r+w(Fe(k,Or,Sr)))),ye=w(Ru(ye,w(Fe(k,Bn,Sr))));break e}default:}S&&(mn=w(Ge+w(Mo(e,Or))),fo=k+400+(t[Ic>>2]<<2)|0,T[fo>>2]=w(mn+w(T[fo>>2])))}while(0);I=I+1|0}while((I|0)!=(In|0))}else ye=w(0);if(r=w(c2+n),u2?Ge=w(w(Kn(e,Bn,w(Vl+ye),Zf,h))-Vl):Ge=vu,Ze=w(w(Kn(e,Bn,w(Vl+(s2?vu:ye)),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(ie(K,Bn,vu)),mn=w(mn+w(Mo(e,Bn))),mn=w(mn+w(zi(K,Bn,Sr))),k=t[Pc>>2]|0,T[K+400+(k<<2)>>2]=mn,!(Le(mn)|0))break}else k=t[Pc>>2]|0;mn=w(Mo(e,Bn)),T[K+400+(k<<2)>>2]=w(mn+w(zi(K,Bn,Sr)));break}k=eo(e,K)|0;do if((k|0)==4){if((t[(Eo(K,Bn)|0)+4>>2]|0)==3){vi=139;break}if((t[(Do(K,Bn)|0)+4>>2]|0)==3){vi=139;break}if(Wu(K,Bn,vu)|0){n=Te;break}Y1=t[K+908+(t[of>>2]<<2)>>2]|0,t[ql>>2]=Y1,n=w(T[K+396>>2]),fo=Le(n)|0,ye=(t[q>>2]=Y1,w(T[q>>2])),fo?n=Ze:(_r=w(Xt(K,Bn,Sr)),mn=w(ye/n),n=w(n*ye),n=w(_r+(Bu?mn:n))),T[Fa>>2]=n,T[ql>>2]=w(w(Xt(K,Or,Sr))+ye),t[Ns>>2]=1,t[sf>>2]=1,Fn(K,Or,Ln,Sr,Ns,ql),Fn(K,Bn,vu,Sr,sf,Fa),n=w(T[ql>>2]),_r=w(T[Fa>>2]),mn=Bu?n:_r,n=Bu?_r:n,fo=((Le(mn)|0)^1)&1,Kt(K,mn,n,Dl,fo,((Le(n)|0)^1)&1,Sr,fs,1,3493,L)|0,n=Te}else vi=139;while(0);e:do if((vi|0)==139){vi=0,n=w(Ge-w(Fe(K,Bn,Sr)));do if((t[(Eo(K,Bn)|0)+4>>2]|0)==3){if((t[(Do(K,Bn)|0)+4>>2]|0)!=3)break;n=w(Te+w(Ru(w(0),w(n*w(.5)))));break e}while(0);if((t[(Do(K,Bn)|0)+4>>2]|0)==3){n=Te;break}if((t[(Eo(K,Bn)|0)+4>>2]|0)==3){n=w(Te+w(Ru(w(0),n)));break}switch(k|0){case 1:{n=Te;break e}case 2:{n=w(Te+w(n*w(.5)));break e}default:{n=w(Te+n);break e}}}while(0);mn=w(El+n),fo=K+400+(t[Pc>>2]<<2)|0,T[fo>>2]=w(mn+w(T[fo>>2]))}while(0);I=I+1|0}while((I|0)!=(In|0))}if(El=w(El+Ze),Xf=w(Ru(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:!(Oe(e)|0))break;if(!(Le(vu)|0)){n=w(vu-El);e:do switch(t[e+12>>2]|0){case 3:{Te=w(Te+n),Me=w(0);break}case 2:{Te=w(Te+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){Te=w(Te+w(n/w(s<<1>>>0))),Me=w(n/w(s>>>0)),Me=k?Me:w(0);break e}else{Te=w(Te+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(ye=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(Ru(n,w(mn+w(Xt(k,Bn,Sr)))))),(eo(e,k)|0)!=5)break;Wl=w(yt(k)),Wl=w(Wl+w(zi(k,0,Sr))),mn=w(T[k+912>>2]),mn=w(w(mn+w(Xt(k,0,Sr)))-Wl),Wl=w(Ru(Ze,Wl)),mn=w(Ru(ye,mn)),ye=mn,Ze=Wl,n=w(Ru(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(ft=w(Me+n),r=Te,Te=w(Te+ft),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(eo(e,I)|0){case 1:{mn=w(r+w(zi(I,Bn,Sr))),T[I+400+(t[Zt>>2]<<2)>>2]=mn;break e}case 3:{mn=w(w(Te-w(Oo(I,Bn,Sr)))-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(ft-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,Sr))),T[I+400+(t[Zt>>2]<<2)>>2]=mn,Wu(I,Bn,vu)|0||(Bu?(ye=w(T[I+908>>2]),n=w(ye+w(Xt(I,Or,Sr))),Ze=ft):(Ze=w(T[I+912>>2]),Ze=w(Ze+w(Xt(I,Bn,Sr))),n=ft,ye=w(T[I+908>>2])),Ci(n,ye)|0?Ci(Ze,w(T[I+912>>2]))|0:0))break e;Kt(I,n,Ze,Dl,1,1,Sr,fs,1,3501,L)|0;break e}case 5:{T[I+404>>2]=w(w(Ge-w(yt(I)))+w(ie(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(Ru(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(Ru(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]),fo=Be+400+(t[K>>2]<<2)|0,mn=w(mn-w(T[fo>>2])),T[fo>>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,Sr,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(Rn(t[e+992>>2]|0,n)),S=1,l=w(l+w(Xt(e,2,n)))):(l=w(Rn(e+380|0,n)),l>=w(0)?S=2:(S=((Le(n)|0)^1)&1,l=n)),Wu(e,0,r)|0?(s=w(Rn(t[e+996>>2]|0,r)),D=1,s=w(s+w(Xt(e,0,n)))):(s=w(Rn(e+388|0,r)),s>=w(0)?D=2:(D=((Le(r)|0)^1)&1,s=r)),h=e+976|0,(Kt(e,l,s,u,S,D,n,r,1,3189,t[h>>2]|0)|0?(Ro(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)&&yf(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(re)}return w(n)}function Ro(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=Uo(t[e+4>>2]|0,n)|0,n=_f(s,n)|0,r=w(Ar(e,s,r)),u=w(Ar(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(Oo(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(Oo(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,Te=Tt,ye=Tt;if(n!=w(0)&&(l=e+400|0,ye=w(T[l>>2]),s=e+404|0,Te=w(T[s>>2]),I=e+416|0,Be=w(T[I>>2]),L=e+420|0,h=w(T[L>>2]),K=w(ye+r),k=w(Te+u),u=w(K+Be),D=w(k+h),S=(t[e+988>>2]|0)==1,T[l>>2]=w(t0(ye,n,0,S)),T[s>>2]=w(t0(Te,n,0,S)),r=w(QE(w(Be*n),w(1))),Ci(r,w(0))|0?s=0:s=(Ci(r,w(1))|0)^1,r=w(QE(w(h*n),w(1))),Ci(r,w(0))|0?l=0:l=(Ci(r,w(1))|0)^1,ye=w(t0(u,n,S&s,S&(s^1))),T[I>>2]=w(ye-w(t0(K,n,0,S))),ye=w(t0(D,n,S&l,S&(l^1))),T[L>>2]=w(ye-w(t0(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=b8(t[489]|0,u,l)|0;break}default:e=JF(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,iS[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((Ao(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&&(gr(t[u>>2]|0,n|0,e|0)|0,t[u>>2]=(t[u>>2]|0)+(e>>>2<<2))}function Ao(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=ht(e+60|0,t[1040+(n<<2)>>2]|0,992)|0,w(il(e,r))}function Oo(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=ht(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(Rn(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 Uo(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 Mo(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(Ru(w(T[(ht(e+276|0,t[1040+(n<<2)>>2]|0,992)|0)>>2]),w(0)))),w(r)}function v0(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(Ru(w(T[(ht(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(Rn(e+236|0,r)),u>=w(0)):0)||(u=w(Ru(w(Rn(ht(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(Rn(e+244|0,r)),u>=w(0)):0)||(u=w(Ru(w(Rn(ht(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,Te=0,ye=0;ye=m,m=m+16|0,Be=ye,Te=e+964|0,qu(e,(t[Te>>2]|0)!=0,3519),D=w(Rr(e,2,n)),S=w(Rr(e,0,n)),L=w(Xt(e,2,n)),k=w(Xt(e,0,n)),Le(n)|0?I=n:I=w(Ru(w(0),w(w(n-L)-D))),Le(r)|0?K=r:K=w(Ru(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))):(uS[t[Te>>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=ye}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(Rr(e,2,s)),D=w(Rr(e,0,s)),k=w(Xt(e,2,s)),S=w(Xt(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(Xt(e,0,s)),L=w(Xt(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=Uo(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(Mo(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(v0(e,n)))}function Rr(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 r0(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 Ni(e){e=e|0;var n=0,r=0;if(jv(e+400|0,0,540)|0,c[e+985>>0]=1,ys(e),r=Su(e)|0,r|0){n=e+948|0,e=0;do Ni(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,Te=Tt,ye=Tt,Ze=0,Ge=Tt,ft=0,Me=Tt,Pe=0,Zt=0,Br=0,In=0,gn=0,_r=0,Pr=0,Ln=0,uu=0,ls=0;uu=m,m=m+16|0,Br=uu+12|0,In=uu+8|0,gn=uu+4|0,_r=uu,Ln=Uo(t[e+4>>2]|0,S)|0,Pe=Hi(Ln)|0,I=w(Rn(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(Ru(I,w(Rr(n,Ln,s))))}else K=7;while(0);do if((K|0)==7){if(ft=Pe^1,!(ft|Zt^1)){h=w(Rn(t[n+992>>2]|0,s)),T[n+504>>2]=w(Ru(h,w(Rr(n,2,s))));break}if(!(Pe|Pr^1)){h=w(Rn(t[n+996>>2]|0,h)),T[n+504>>2]=w(Ru(h,w(Rr(n,0,s))));break}T[Br>>2]=w(re),T[In>>2]=w(re),t[gn>>2]=0,t[_r>>2]=0,Ge=w(Xt(n,2,s)),Me=w(Xt(n,0,s)),Zt?(Te=w(Ge+w(Rn(t[n+992>>2]|0,s))),T[Br>>2]=Te,t[gn>>2]=1,Be=1):(Be=0,Te=w(re)),Pr?(I=w(Me+w(Rn(t[n+996>>2]|0,h))),T[In>>2]=I,t[_r>>2]=1,k=1):(k=0,I=w(re)),K=t[e+32>>2]|0,Pe&(K|0)==2?K=2:(Le(Te)|0?!(Le(r)|0):0)&&(T[Br>>2]=r,t[gn>>2]=2,Be=2,Te=r),(((K|0)==2&ft?0:Le(I)|0)?!(Le(l)|0):0)&&(T[In>>2]=l,t[_r>>2]=2,k=2,I=l),ye=w(T[n+396>>2]),Ze=Le(ye)|0;do if(Ze)K=Be;else{if((Be|0)==1&ft){T[In>>2]=w(w(Te-Ge)/ye),t[_r>>2]=1,k=1,K=1;break}Pe&(k|0)==1?(T[Br>>2]=w(ye*w(I-Me)),t[gn>>2]=1,k=1,K=1):K=Be}while(0);ls=Le(r)|0,Be=(eo(e,n)|0)!=4,(Pe|Zt|((u|0)!=1|ls)|(Be|(K|0)==1)?0:(T[Br>>2]=r,t[gn>>2]=1,!Ze))&&(T[In>>2]=w(w(r-Ge)/ye),t[_r>>2]=1,k=1),(Pr|ft|((D|0)!=1|(Le(l)|0))|(Be|(k|0)==1)?0:(T[In>>2]=l,t[_r>>2]=1,!Ze))&&(T[Br>>2]=w(ye*w(l-Me)),t[gn>>2]=1),Fn(n,2,s,s,gn,Br),Fn(n,0,h,s,_r,In),r=w(T[Br>>2]),l=w(T[In>>2]),Kt(n,r,l,S,t[gn>>2]|0,t[_r>>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(Ru(h,w(Rr(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(Ru(u,w(Rr(e,n,l))))}function eo(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 Eo(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 Do(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(Rn(e+380+(t[976+(n<<2)>>2]<<3)|0,r)),r=w(r+w(Xt(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[(ht(e,4,948)|0)+4>>2]|0)!=0:0)?e=1:e=(t[(ht(e,t[1040+(n<<2)>>2]|0,948)|0)+4>>2]|0)!=0,e|0}function ie(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=ht(e,4,948)|0,(t[u+4>>2]|0)!=0):0)?l=4:(u=ht(e,t[1040+(n<<2)>>2]|0,948)|0,t[u+4>>2]|0?l=4:r=w(0)),(l|0)==4&&(r=w(Rn(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(Oo(e,n,r)))}function Oe(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 yt(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(eS[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=(eo(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(yt(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(re),l=w(re)),(s|0)==3&&(l=w(Rn(e+364+(n<<3)|0,u)),u=w(Rn(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,Te=_f(Ze,s)|0,ye=Hi(Ze)|0,I=w(Xt(n,2,r)),K=w(Xt(n,0,r)),Wu(n,2,r)|0?D=w(I+w(Rn(t[n+992>>2]|0,r))):(ae(n,2)|0?Bt(n,2)|0:0)?(D=w(T[e+908>>2]),S=w(Mo(e,2)),S=w(D-w(S+w(v0(e,2)))),D=w(ie(n,2,r)),D=w(Kn(n,2,w(S-w(D+w(Fi(n,2,r)))),r,r))):D=w(re),Wu(n,0,l)|0?S=w(K+w(Rn(t[n+996>>2]|0,l))):(ae(n,0)|0?Bt(n,0)|0:0)?(S=w(T[e+912>>2]),ft=w(Mo(e,0)),ft=w(S-w(ft+w(v0(e,0)))),S=w(ie(n,0,l)),S=w(Kn(n,0,w(ft-w(S+w(Fi(n,0,l)))),l,r))):S=w(re),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{ft=w(K+w(w(D-I)/Be)),S=k?ft: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=ye?D:u?r:D,Kt(n,D,S,s,ye?Me:u?2:Me,k&(L^1)&1,D,S,0,3623,h)|0,D=w(T[n+908>>2]),D=w(D+w(Xt(n,2,r))),S=w(T[n+912>>2]),S=w(S+w(Xt(n,0,r)))),Kt(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,ft=w(T[e+908+(Me<<2)>>2]),ft=w(ft-w(T[n+908+(Me<<2)>>2])),ft=w(ft-w(v0(e,Ze))),ft=w(ft-w(Oo(n,Ze,r))),ft=w(ft-w(Fi(n,Ze,ye?r:l))),T[n+400+(t[1040+(Ze<<2)>>2]<<2)>>2]=ft):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,ft=w(T[e+908+(Me<<2)>>2]),ft=w(w(ft-w(T[n+908+(Me<<2)>>2]))*w(.5)),T[n+400+(t[1040+(Ze<<2)>>2]<<2)>>2]=ft;break}(ae(n,Ze)|0?0:(t[e+8>>2]|0)==2)&&(Me=t[976+(Ze<<2)>>2]|0,ft=w(T[e+908+(Me<<2)>>2]),ft=w(ft-w(T[n+908+(Me<<2)>>2])),T[n+400+(t[1040+(Ze<<2)>>2]<<2)>>2]=ft)}while(0);(Bt(n,Te)|0?!(ae(n,Te)|0):0)?(Me=t[976+(Te<<2)>>2]|0,ft=w(T[e+908+(Me<<2)>>2]),ft=w(ft-w(T[n+908+(Me<<2)>>2])),ft=w(ft-w(v0(e,Te))),ft=w(ft-w(Oo(n,Te,r))),ft=w(ft-w(Fi(n,Te,ye?l:r))),T[n+400+(t[1040+(Te<<2)>>2]<<2)>>2]=ft):Ge=30;do if((Ge|0)==30?!(ae(n,Te)|0):0){if((eo(e,n)|0)==2){Me=t[976+(Te<<2)>>2]|0,ft=w(T[e+908+(Me<<2)>>2]),ft=w(w(ft-w(T[n+908+(Me<<2)>>2]))*w(.5)),T[n+400+(t[1040+(Te<<2)>>2]<<2)>>2]=ft;break}Me=(eo(e,n)|0)==3,Me^(t[e+28>>2]|0)==2&&(Me=t[976+(Te<<2)>>2]|0,ft=w(T[e+908+(Me<<2)>>2]),ft=w(ft-w(T[n+908+(Me<<2)>>2])),T[n+400+(t[1040+(Te<<2)>>2]<<2)>>2]=ft)}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[(ht(e,5,948)|0)+4>>2]|0)!=0:0)?e=1:e=(t[(ht(e,t[1e3+(n<<2)>>2]|0,948)|0)+4>>2]|0)!=0,e|0}function Fi(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=ht(e,5,948)|0,(t[u+4>>2]|0)!=0):0)?l=4:(u=ht(e,t[1e3+(n<<2)>>2]|0,948)|0,t[u+4>>2]|0?l=4:r=w(0)),(l|0)==4&&(r=w(Rn(u,r))),w(r)}function Ar(e,n,r){return e=e|0,n=n|0,r=w(r),ae(e,n)|0?r=w(ie(e,n,r)):r=w(-w(Fi(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?(gr(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&&_t(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&&ky(D+(0-s<<2)|0,n|0,l|0)|0}function at(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&&gr(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&&(gr(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(){Se()}function wo(){var e=0;return e=pn(4)|0,Un(e),e|0}function Un(e){e=e|0,t[e>>2]=yo()|0}function to(e){e=e|0,e|0&&(i0(e),_t(e))}function i0(e){e=e|0,Zo(t[e>>2]|0)}function m0(e,n,r){e=e|0,n=n|0,r=r|0,Vu(t[e>>2]|0,n,r)}function no(e,n){e=e|0,n=w(n),Ju(t[e>>2]|0,n)}function j0(e,n){return e=e|0,n=n|0,ir(t[e>>2]|0,n)|0}function u0(){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),_t(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),_t(e))}function ca(e){e=e|0,jo(e)}function jo(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),_t(n)),p0(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 y0(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 Rl(e,n){e=e|0,n=n|0,$(t[e>>2]|0,n)}function ul(e,n){e=e|0,n=n|0,Ee(t[e>>2]|0,n)}function w2(e,n){e=e|0,n=n|0,go(t[e>>2]|0,n)}function Ws(e,n){e=e|0,n=n|0,Je(t[e>>2]|0,n)}function Al(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,An(t[e>>2]|0,n,w(r))}function z0(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,oe(t[e>>2]|0,n)}function qa(e,n){e=e|0,n=n|0,it(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,Ft(t[e>>2]|0,w(n))}function ns(e,n){e=e|0,n=+n,It(t[e>>2]|0,w(n))}function H0(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,wr(t[e>>2]|0)}function Wa(e,n){e=e|0,n=+n,Lu(t[e>>2]|0,w(n))}function ro(e,n){e=e|0,n=+n,Co(t[e>>2]|0,w(n))}function zo(e){e=e|0,$o(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,P0(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,I0(t[e>>2]|0,w(n))}function pa(e,n){e=e|0,n=+n,gs(t[e>>2]|0,w(n))}function od(e,n){e=e|0,n=+n,b0(t[e>>2]|0,w(n))}function ha(e,n){e=e|0,n=+n,B0(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,Pt(t[e>>2]|0,n,w(r))}function qi(e,n,r){e=e|0,n=n|0,r=+r,ut(t[e>>2]|0,n,w(r))}function g(e,n,r){e=e|0,n=n|0,r=+r,Dt(t[e>>2]|0,n,w(r))}function y(e){return e=e|0,ke(t[e>>2]|0)|0}function R(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 de(e){return e=e|0,Ce(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 Lt(e){return e=e|0,mt(t[e>>2]|0)|0}function xr(e){return e=e|0,U(t[e>>2]|0)|0}function io(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,_o(l,t[n>>2]|0,r),F(e,l),m=u}function du(e){return e=e|0,We(t[e>>2]|0)|0}function Ho(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 uo(e){return e=e|0,+ +w(hf(t[e>>2]|0))}function Ve(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),_t(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=g0(n)|0,vh(e,n,+B[r>>3],t[u>>2]|0,+B[l>>3],t[s>>2]|0),La(D),m=h}function g0(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=_0(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 _0(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 yh(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),_t(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 R2(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 gh(e){return e=e|0,+ +w(Ei(t[e>>2]|0))}function al(e){return e=e|0,+ +w(e0(t[e>>2]|0))}function va(e){return e=e|0,+ +w(xo(t[e>>2]|0))}function A2(e){return e=e|0,+ +w(U0(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(e0(t[n>>2]|0)),B[e+16>>3]=+w(xo(t[n>>2]|0)),B[e+24>>3]=+w(U0(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(h0(t[e>>2]|0,n))}function Jc(){return Ia()|0}function Vs(){k2(),ma(),Zc(),mc(),yc(),hd()}function k2(){IO(11713,4938,1)}function ma(){tO(10448)}function Zc(){I7(10408)}function mc(){u7(10324)}function yc(){EE(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,Te=0,ye=0,Ze=0,Ge=0,ft=0,Me=0,Pe=0,Zt=0,Br=0,In=0,gn=0,_r=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,Sr=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,Sr=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,_r=n+176|0,gn=n+168|0,In=n+160|0,Br=n+152|0,Zt=n+144|0,Pe=n+136|0,Me=n+128|0,ft=n+120|0,Ge=n+112|0,Ze=n+104|0,ye=n+96|0,Te=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],ya(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],ko(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],ko(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[Sr>>2]=5,t[Sr+4>>2]=0,t[r>>2]=t[Sr>>2],t[r+4>>2]=t[Sr+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],ko(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],ko(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],oo(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],oo(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],oo(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],oo(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],oo(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],oo(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],oo(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],oo(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],oo(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],oo(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],oo(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],oo(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],oo(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],oo(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],oo(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],oo(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],oo(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],oo(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],ko(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],ko(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],ko(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],o0(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],o0(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],o0(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],o0(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],o0(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],o0(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],o0(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],gc(e,4486,r)|0,t[_r>>2]=10,t[_r+4>>2]=0,t[r>>2]=t[_r>>2],t[r+4>>2]=t[_r+4>>2],rs(e,4496,r)|0,t[gn>>2]=11,t[gn+4>>2]=0,t[r>>2]=t[gn>>2],t[r+4>>2]=t[gn+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],Rf(e,4568,r)|0,t[ft>>2]=2,t[ft+4>>2]=0,t[r>>2]=t[ft>>2],t[r+4>>2]=t[ft+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[ye>>2]=23,t[ye+4>>2]=0,t[r>>2]=t[ye>>2],t[r+4>>2]=t[ye+4>>2],Gs(e,4619,r)|0,t[Te>>2]=14,t[Te+4>>2]=0,t[r>>2]=t[Te>>2],t[r+4>>2]=t[Te+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],ga(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],gc(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],gc(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],gc(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,V0(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,hE(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],oE(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],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 ko(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],Rv(e,n,l),m=u,e|0}function oo(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],ny(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 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],Lo(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 gc(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],lo(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],Am(e,n,l),m=u,e|0}function Rf(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],y1(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 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],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,yd(s,u)|0,u),m=l}function N2(){var e=0,n=0;if(c[7616]|0||(cl(9136),Vt(24,9136,ve|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 yd(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],Af(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,gd(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 gd(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 Af(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],Af(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?(gr(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&&_t(e)}function cl(e){e=e|0,q0(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)),_t(r))}function q0(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=E0(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 E0(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=l0(u)|0,m=l,u|0}function l0(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),Vt(25,9184,ve|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,s0(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),_t(e)}function us(e){e=e|0,e=t[e+12>>2]|0,e|0&&_t(e)}function D0(e){e=e|0,_t(e)}function s0(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=g0(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=_0(Lf()|0)|0,n=+kl(n),r=+kl(r),u=+kl(u),l=+kl(l),s=+kl(s),ho(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,_t(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,_t(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),Vt(26,9232,ve|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?(gr(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&&_t(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)),_t(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],Rh(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 Rh(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),Rs(S,l),S=Ys(S,l)|0,tS[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,+ +Ah(n)}function Rs(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 Ah(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),Vt(27,9268,ve|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=As(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 As(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?(gr(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&&_t(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)),_t(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),Vt(28,9304,ve|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?(gr(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&&_t(e)}function Ih(e){e=e|0,h1(e)}function ym(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)),_t(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 y1(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,w0(s,u)|0,u),m=l}function Tc(){var e=0,n=0;if(c[7664]|0||(Hh(9340),Vt(29,9340,ve|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 w0(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,gm(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 gm(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?(gr(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&&_t(e)}function Hh(e){e=e|0,qh(e)}function g1(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)),_t(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(tD[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),Vt(30,9376,ve|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?(gr(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&&_t(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)),_t(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=Rm(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 Rm(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 Am(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),Vt(31,9412,ve|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,Rd(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 Rd(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?(gr(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&&_t(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)),_t(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=Ad(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 Ad(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),qo(Zp[r&31](e)|0)|0}function qo(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),Vt(32,9448,ve|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?(gr(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&&_t(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)),_t(r))}function Lm(e){e=e|0;var n=0;n=yr()|0,jn(e,2,6,n,S0()|0,1),t[e+24>>2]=0,t[e+28>>2]=0,t[e+32>>2]=0}function S0(){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 lo(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=yp(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),Vt(33,9484,ve|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 yp(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):(gp(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 gp(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),Ra(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?(gr(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&&_t(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)),_t(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,Fy[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),Vt(34,9520,ve|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),Aa(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?(gr(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&&_t(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)),_t(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),Rs(l,r),l=Ys(l,r)|0,h=+Ya(+rS[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=gu()|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 gu(){var e=0,n=0;if(c[7712]|0||(Cp(9556),Vt(35,9556,ve|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=gu()|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=T0(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 T0(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?(gr(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&&_t(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)),_t(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=+Wo(n,l),m=u,+r}function Gn(e){return e=e|0,(t[(gu()|0)+24>>2]|0)+(e*12|0)|0}function Wo(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(+nS[r&15](e))}function Lo(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=R1(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,Rc(s,u)|0,u),m=l}function Ul(){var e=0,n=0;if(c[7720]|0||(qd(9592),Vt(36,9592,ve|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 R1(e){return e=e|0,0}function Rc(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],Ac(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 Ac(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=Rp(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,No(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],Ac(s,u,r),t[S>>2]=(t[S>>2]|0)+12,dn(e,D),Hd(D),m=L;return}}function Rp(e){return e=e|0,357913941}function No(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?(gr(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&&_t(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)),_t(r))}function kc(e){e=e|0;var n=0;n=yr()|0,jn(e,2,7,n,A1()|0,0),t[e+24>>2]=0,t[e+28>>2]=0,t[e+32>>2]=0}function A1(){return 1276}function Ap(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||(W0(9640),Vt(25,9640,ve|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),_t(e)}function M1(e){e=e|0,e=t[e+12>>2]|0,e|0&&_t(e)}function jl(e){e=e|0,_t(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=g0(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=_0(yl()|0)|0,n=ad(n)|0,Hr(0,u|0,e|0,n|0,+ +kl(r))|0}function yl(){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 W0(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),Vt(37,9684,ve|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?(gr(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&&_t(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)),_t(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=yv(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 yv(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),Rs(s,r),s=Ys(s,r)|0,Fy[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=gv(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),Vt(38,9720,ve|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 gv(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?(gr(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&&_t(e)}function Sv(e){e=e|0,Tv(e)}function ey(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)),_t(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 ty(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=so(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 so(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 ny(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],ry(e,r,l,0),m=u}function ry(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),Vt(39,9756,ve|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=iy(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,uy(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 iy(e){return e=e|0,357913941}function uy(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?(gr(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&&_t(e)}function Bp(e){e=e|0,ly(e)}function xv(e){e=e|0,oy(e+24|0)}function oy(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)),_t(r))}function ly(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=sy(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],ay(n,l,r),m=u}function sy(e){return e=e|0,(t[(Fp()|0)+24>>2]|0)+(e*12|0)|0}function ay(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),$8[u&31](e,r),m=s}function Rv(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,fy(s,u)|0,u),m=l}function Hp(){var e=0,n=0;if(c[7768]|0||(qp(9792),Vt(40,9792,ve|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 fy(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):(cy(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 cy(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=Av(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,dy(e,D),Wf(D),m=L;return}}function Av(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 dy(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?(gr(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&&_t(e)}function qp(e){e=e|0,hy(e)}function Mv(e){e=e|0,py(e+24|0)}function py(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)),_t(r))}function hy(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 vy(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],my(n,s,r,u),m=l}function $s(e){return e=e|0,(t[(Hp()|0)+24>>2]|0)+(e*12|0)|0}function my(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),Rs(s,r),s=Ys(s,r)|0,Pl(h,u),u=+os(h,u),lS[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||(At(9828),Vt(41,9828,ve|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));At(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):(he(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 he(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=De(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,be(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,Et(e,D),St(D),m=L;return}}function De(e){return e=e|0,357913941}function be(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 Et(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?(gr(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&&_t(e)}function At(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)),_t(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),Rs(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=a0()|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=ao(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 a0(){var e=0,n=0;if(c[7784]|0||(n_(9864),Vt(42,9864,ve|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 ao(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=a0()|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],C0(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 C0(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=Z4(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,yy(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],C0(s,u,r),t[S>>2]=(t[S>>2]|0)+12,gy(e,D),rf(D),m=L;return}}function Z4(e){return e=e|0,357913941}function yy(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 gy(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?(gr(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&&_t(e)}function n_(e){e=e|0,tE(e)}function $4(e){e=e|0,eE(e+24|0)}function eE(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)),_t(r))}function tE(e){e=e|0;var n=0;n=yr()|0,jn(e,2,8,n,nE()|0,1),t[e+24>>2]=0,t[e+28>>2]=0,t[e+32>>2]=0}function nE(){return 1320}function _y(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=rE(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],iE(n,l,r),m=u}function rE(e){return e=e|0,(t[(a0()|0)+24>>2]|0)+(e*12|0)|0}function iE(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),Ey(l,r),l=r_(l,r)|0,I1[u&31](e,l),m=s}function Ey(e,n){e=e|0,n=n|0}function r_(e,n){return e=e|0,n=n|0,uE(n)|0}function uE(e){return e=e|0,e|0}function oE(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,lE(s,u)|0,u),m=l}function Vf(){var e=0,n=0;if(c[7792]|0||(Sy(9900),Vt(43,9900,ve|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));Sy(9900)}return 9900}function u_(e){return e=e|0,0}function lE(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):(sE(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 sE(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,Dy(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,wy(e,D),aE(D),m=L;return}}function Lv(e){return e=e|0,357913941}function Dy(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 wy(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?(gr(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 aE(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&&_t(e)}function Sy(e){e=e|0,o_(e)}function fE(e){e=e|0,cE(e+24|0)}function cE(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)),_t(r))}function o_(e){e=e|0;var n=0;n=yr()|0,jn(e,2,22,n,dE()|0,0),t[e+24>>2]=0,t[e+28>>2]=0,t[e+32>>2]=0}function dE(){return 1344}function pE(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 hE(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=Ty()|0,e=vE(r)|0,wi(s,n,l,e,mE(r,u)|0,u)}function Ty(){var e=0,n=0;if(c[7800]|0||(xy(9936),Vt(44,9936,ve|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));xy(9936)}return 9936}function vE(e){return e=e|0,e|0}function mE(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=Ty()|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?(Cy(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 Cy(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,Cy(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?(gr(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&&_t(e)}function xy(e){e=e|0,h_(e)}function p_(e){e=e|0,yE(e+24|0)}function yE(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)),_t(r))}function h_(e){e=e|0;var n=0;n=yr()|0,jn(e,1,23,n,S0()|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[(_E(e)|0)>>2]|0,n)}function _E(e){return e=e|0,(t[(Ty()|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,A(r,u)|0,u)}function E(){var e=0,n=0;if(c[7808]|0||(vt(9972),Vt(45,9972,ve|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));vt(9972)}return 9972}function C(e){return e=e|0,e|0}function A(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,se(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,Ue(e,l),Qe(l),m=D;return}}function te(e){return e=e|0,536870911}function se(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 Ue(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?(gr(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 Qe(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&&_t(e)}function vt(e){e=e|0,Ht(e)}function Nt(e){e=e|0,Yt(e+24|0)}function Yt(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)),_t(r))}function Ht(e){e=e|0;var n=0;n=yr()|0,jn(e,1,9,n,yn()|0,1),t[e+24>>2]=0,t[e+28>>2]=0,t[e+32>>2]=0}function yn(){return 1348}function kr(e,n){return e=e|0,n=n|0,Oi(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 Oi(e,n){e=e|0,n=n|0;var r=0,u=0;return r=m,m=m+16|0,u=r,Fo(u,n),n=$i(u,n)|0,n=Cd(Zp[e&31](n)|0)|0,m=r,n|0}function Fo(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),Vt(46,10008,ve|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?(gr(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&&_t(e)}function Kr(e){e=e|0,Vo(e)}function xu(e){e=e|0,So(e+24|0)}function So(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)),_t(r))}function Vo(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,gl(t[(Xu(e)|0)>>2]|0)|0}function Xu(e){return e=e|0,(t[($e()|0)+24>>2]|0)+(e<<3)|0}function gl(e){return e=e|0,Cd(k_[e&7]()|0)|0}function uf(){var e=0;return c[7832]|0||(m_(10052),Vt(25,10052,ve|0)|0,e=7832,t[e>>2]=1,t[e+4>>2]=0),10052}function V0(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&&(G0(r),_t(r)):n|0&&(ws(n),_t(n))}function Hl(e,n){return e=e|0,n=n|0,n&e|0}function G0(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 EE(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,y_(e,4827),DE(e,4834,3)|0,wE(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],Ry(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],g_(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],SE(e,4891,r)|0,m=n}function y_(e,n){e=e|0,n=n|0;var r=0;r=JA()|0,t[e>>2]=r,ZA(r,n),e2(t[e>>2]|0)}function DE(e,n,r){return e=e|0,n=n|0,r=r|0,PA(e,Fr(n)|0,r,0),e|0}function wE(e,n,r){return e=e|0,n=n|0,r=r|0,EA(e,Fr(n)|0,r,0),e|0}function Ry(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],tA(e,n,l),m=u,e|0}function g_(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],IR(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;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],TE(e,n,l),m=u,e|0}function TE(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],CE(e,r,l,1),m=u}function CE(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=wR(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,SR(s,u)|0,u),m=l}function xE(){var e=0,n=0;if(c[7840]|0||(I3(10100),Vt(48,10100,ve|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));I3(10100)}return 10100}function wR(e){return e=e|0,0}function SR(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],P3(r,l,e),e=(t[n>>2]|0)+12|0,t[n>>2]=e):(TR(L,D,S),e=t[n>>2]|0),m=k,((e-(t[L>>2]|0)|0)/12|0)+-1|0}function P3(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 TR(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=CR(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,xR(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],P3(s,u,r),t[S>>2]=(t[S>>2]|0)+12,RR(e,D),AR(D),m=L;return}}function CR(e){return e=e|0,357913941}function xR(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 RR(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?(gr(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 AR(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&&_t(e)}function I3(e){e=e|0,kR(e)}function OR(e){e=e|0,MR(e+24|0)}function MR(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)),_t(r))}function kR(e){e=e|0;var n=0;n=yr()|0,jn(e,2,6,n,LR()|0,1),t[e+24>>2]=0,t[e+28>>2]=0,t[e+32>>2]=0}function LR(){return 1364}function NR(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=FR(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=PR(n,l,r)|0,m=u,r|0}function FR(e){return e=e|0,(t[(xE()|0)+24>>2]|0)+(e*12|0)|0}function PR(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),Rs(l,r),l=Ys(l,r)|0,l=bl(tD[u&15](e,l)|0)|0,m=s,l|0}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;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],bR(e,r,l,0),m=u}function bR(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=RE()|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=BR(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,UR(s,u)|0,u),m=l}function RE(){var e=0,n=0;if(c[7848]|0||(B3(10136),Vt(49,10136,ve|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));B3(10136)}return 10136}function BR(e){return e=e|0,0}function UR(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=RE()|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],b3(r,l,e),e=(t[n>>2]|0)+12|0,t[n>>2]=e):(jR(L,D,S),e=t[n>>2]|0),m=k,((e-(t[L>>2]|0)|0)/12|0)+-1|0}function b3(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 jR(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=zR(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,HR(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],b3(s,u,r),t[S>>2]=(t[S>>2]|0)+12,qR(e,D),WR(D),m=L;return}}function zR(e){return e=e|0,357913941}function HR(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 qR(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?(gr(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 WR(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&&_t(e)}function B3(e){e=e|0,YR(e)}function VR(e){e=e|0,GR(e+24|0)}function GR(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)),_t(r))}function YR(e){e=e|0;var n=0;n=yr()|0,jn(e,2,9,n,KR()|0,1),t[e+24>>2]=0,t[e+28>>2]=0,t[e+32>>2]=0}function KR(){return 1372}function XR(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=QR(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],JR(n,l,r),m=u}function QR(e){return e=e|0,(t[(RE()|0)+24>>2]|0)+(e*12|0)|0}function JR(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),ZR(l,r),h=w($R(l,r)),Z8[u&1](e,h),m=s}function ZR(e,n){e=e|0,n=+n}function $R(e,n){return e=e|0,n=+n,w(eA(n))}function eA(e){return e=+e,w(e)}function tA(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],nA(e,r,l,0),m=u}function nA(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=rA(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,iA(s,u)|0,u),m=l}function AE(){var e=0,n=0;if(c[7856]|0||(j3(10172),Vt(50,10172,ve|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));j3(10172)}return 10172}function rA(e){return e=e|0,0}function iA(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],U3(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 U3(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=oA(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,lA(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],U3(s,u,r),t[S>>2]=(t[S>>2]|0)+12,sA(e,D),aA(D),m=L;return}}function oA(e){return e=e|0,357913941}function lA(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 sA(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?(gr(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&&_t(e)}function j3(e){e=e|0,dA(e)}function fA(e){e=e|0,cA(e+24|0)}function cA(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)),_t(r))}function dA(e){e=e|0;var n=0;n=yr()|0,jn(e,2,3,n,pA()|0,2),t[e+24>>2]=0,t[e+28>>2]=0,t[e+32>>2]=0}function pA(){return 1380}function hA(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=vA(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],mA(n,s,r,u),m=l}function vA(e){return e=e|0,(t[(AE()|0)+24>>2]|0)+(e*12|0)|0}function mA(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),Rs(s,r),s=Ys(s,r)|0,yA(h,u),h=gA(h,u)|0,Fy[l&15](e,s,h),m=D}function yA(e,n){e=e|0,n=n|0}function gA(e,n){return e=e|0,n=n|0,_A(n)|0}function _A(e){return e=e|0,(e|0)!=0|0}function EA(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=DA(r)|0,wi(s,n,l,e,wA(r,u)|0,u)}function OE(){var e=0,n=0;if(c[7864]|0||(H3(10208),Vt(51,10208,ve|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));H3(10208)}return 10208}function DA(e){return e=e|0,e|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;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?(z3(u,e,n),n=(t[r>>2]|0)+8|0,t[r>>2]=n):(SA(h,l,s),n=t[r>>2]|0),m=D,(n-(t[h>>2]|0)>>3)+-1|0}function z3(e,n,r){e=e|0,n=n|0,r=r|0,t[e>>2]=n,t[e+4>>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;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=TA(e)|0,u>>>0>>0)hi(e);else{S=t[e>>2]|0,k=(t[e+8>>2]|0)-S|0,L=k>>2,CA(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,z3(t[h>>2]|0,t[n>>2]|0,t[r>>2]|0),t[h>>2]=(t[h>>2]|0)+8,xA(e,l),RA(l),m=D;return}}function TA(e){return e=e|0,536870911}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>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 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)+(0-(l>>3)<<3)|0,t[s>>2]=r,(l|0)>0?(gr(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+-8-n|0)>>>3)<<3)),e=t[e>>2]|0,e|0&&_t(e)}function H3(e){e=e|0,MA(e)}function AA(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+-8-u|0)>>>3)<<3)),_t(r))}function MA(e){e=e|0;var n=0;n=yr()|0,jn(e,1,24,n,kA()|0,1),t[e+24>>2]=0,t[e+28>>2]=0,t[e+32>>2]=0}function kA(){return 1392}function LA(e,n){e=e|0,n=n|0,FA(t[(NA(e)|0)>>2]|0,n)}function NA(e){return e=e|0,(t[(OE()|0)+24>>2]|0)+(e<<3)|0}function FA(e,n){e=e|0,n=n|0;var r=0,u=0;r=m,m=m+16|0,u=r,Fo(u,n),n=$i(u,n)|0,P1[e&127](n),m=r}function PA(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=ME()|0,e=IA(r)|0,wi(s,n,l,e,bA(r,u)|0,u)}function ME(){var e=0,n=0;if(c[7872]|0||(W3(10244),Vt(52,10244,ve|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));W3(10244)}return 10244}function IA(e){return e=e|0,e|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;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?(q3(u,e,n),n=(t[r>>2]|0)+8|0,t[r>>2]=n):(BA(h,l,s),n=t[r>>2]|0),m=D,(n-(t[h>>2]|0)>>3)+-1|0}function q3(e,n,r){e=e|0,n=n|0,r=r|0,t[e>>2]=n,t[e+4>>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,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=UA(e)|0,u>>>0>>0)hi(e);else{S=t[e>>2]|0,k=(t[e+8>>2]|0)-S|0,L=k>>2,jA(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,q3(t[h>>2]|0,t[n>>2]|0,t[r>>2]|0),t[h>>2]=(t[h>>2]|0)+8,zA(e,l),HA(l),m=D;return}}function UA(e){return e=e|0,536870911}function jA(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 zA(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?(gr(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 HA(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&&_t(e)}function W3(e){e=e|0,VA(e)}function qA(e){e=e|0,WA(e+24|0)}function WA(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)),_t(r))}function VA(e){e=e|0;var n=0;n=yr()|0,jn(e,1,16,n,GA()|0,0),t[e+24>>2]=0,t[e+28>>2]=0,t[e+32>>2]=0}function GA(){return 1400}function YA(e){return e=e|0,XA(t[(KA(e)|0)>>2]|0)|0}function KA(e){return e=e|0,(t[(ME()|0)+24>>2]|0)+(e<<3)|0}function XA(e){return e=e|0,QA(k_[e&7]()|0)|0}function QA(e){return e=e|0,e|0}function JA(){var e=0;return c[7880]|0||(i7(10280),Vt(25,10280,ve|0)|0,e=7880,t[e>>2]=1,t[e+4>>2]=0),10280}function ZA(e,n){e=e|0,n=n|0,t[e>>2]=$A()|0,t[e+4>>2]=e7()|0,t[e+12>>2]=n,t[e+8>>2]=t7()|0,t[e+32>>2]=4}function $A(){return 11711}function e7(){return 1356}function t7(){return N1()|0}function n7(e,n,r,u){e=e|0,n=n|0,r=r|0,u=u|0,(Hl(u,896)|0)==512?r|0&&(r7(r),_t(r)):n|0&&(i0(n),_t(n))}function r7(e){e=e|0,e=t[e+4>>2]|0,e|0&&t2(e)}function i7(e){e=e|0,Qa(e)}function u7(e){e=e|0,o7(e,4920),l7(e)|0,s7(e)|0}function o7(e,n){e=e|0,n=n|0;var r=0;r=Wd()|0,t[e>>2]=r,O7(r,n),e2(t[e>>2]|0)}function l7(e){e=e|0;var n=0;return n=t[e>>2]|0,Gp(n,_7()|0),e|0}function s7(e){e=e|0;var n=0;return n=t[e>>2]|0,Gp(n,a7()|0),e|0}function a7(){var e=0;return c[7888]|0||(V3(10328),Vt(53,10328,ve|0)|0,e=7888,t[e>>2]=1,t[e+4>>2]=0),sr(10328)|0||V3(10328),10328}function Gp(e,n){e=e|0,n=n|0,wi(e,0,n,0,0,0)}function V3(e){e=e|0,d7(e),Yp(e,10)}function f7(e){e=e|0,c7(e+24|0)}function c7(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)),_t(r))}function d7(e){e=e|0;var n=0;n=yr()|0,jn(e,5,1,n,m7()|0,2),t[e+24>>2]=0,t[e+28>>2]=0,t[e+32>>2]=0}function p7(e,n,r){e=e|0,n=n|0,r=+r,h7(e,n,r)}function Yp(e,n){e=e|0,n=n|0,t[e+20>>2]=n}function h7(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,Rs(D,n),t[s>>2]=Ys(D,n)|0,Pl(h,r),B[l>>3]=+os(h,r),v7(e,s,l),m=u}function v7(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 m7(){return 1404}function y7(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,Rs(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 _7(){var e=0;return c[7896]|0||(G3(10364),Vt(54,10364,ve|0)|0,e=7896,t[e>>2]=1,t[e+4>>2]=0),sr(10364)|0||G3(10364),10364}function G3(e){e=e|0,w7(e),Yp(e,55)}function E7(e){e=e|0,D7(e+24|0)}function D7(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)),_t(r))}function w7(e){e=e|0;var n=0;n=yr()|0,jn(e,5,4,n,x7()|0,0),t[e+24>>2]=0,t[e+28>>2]=0,t[e+32>>2]=0}function S7(e){e=e|0,T7(e)}function T7(e){e=e|0,C7(e)}function C7(e){e=e|0,Y3(e+8|0),c[e+24>>0]=1}function Y3(e){e=e|0,t[e>>2]=0,B[e+8>>3]=0}function x7(){return 1424}function R7(){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,Y3(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 O7(e,n){e=e|0,n=n|0,t[e>>2]=M7()|0,t[e+4>>2]=k7()|0,t[e+12>>2]=n,t[e+8>>2]=L7()|0,t[e+32>>2]=5}function M7(){return 11710}function k7(){return 1416}function L7(){return __()|0}function N7(e,n,r,u){e=e|0,n=n|0,r=r|0,u=u|0,(Hl(u,896)|0)==512?r|0&&(F7(r),_t(r)):n|0&&_t(n)}function F7(e){e=e|0,e=t[e+4>>2]|0,e|0&&t2(e)}function __(){var e=0;return c[7904]|0||(t[2600]=P7()|0,t[2601]=0,e=7904,t[e>>2]=1,t[e+4>>2]=0),10400}function P7(){return t[357]|0}function I7(e){e=e|0,b7(e,4926),B7(e)|0}function b7(e,n){e=e|0,n=n|0;var r=0;r=Xa()|0,t[e>>2]=r,X7(r,n),e2(t[e>>2]|0)}function B7(e){e=e|0;var n=0;return n=t[e>>2]|0,Gp(n,U7()|0),e|0}function U7(){var e=0;return c[7912]|0||(K3(10412),Vt(56,10412,ve|0)|0,e=7912,t[e>>2]=1,t[e+4>>2]=0),sr(10412)|0||K3(10412),10412}function K3(e){e=e|0,H7(e),Yp(e,57)}function j7(e){e=e|0,z7(e+24|0)}function z7(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)),_t(r))}function H7(e){e=e|0;var n=0;n=yr()|0,jn(e,5,5,n,G7()|0,0),t[e+24>>2]=0,t[e+28>>2]=0,t[e+32>>2]=0}function q7(e){e=e|0,W7(e)}function W7(e){e=e|0,V7(e)}function V7(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 G7(){return 1432}function Y7(){return K7()|0}function K7(){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 X7(e,n){e=e|0,n=n|0,t[e>>2]=Q7()|0,t[e+4>>2]=J7()|0,t[e+12>>2]=n,t[e+8>>2]=Z7()|0,t[e+32>>2]=6}function Q7(){return 11704}function J7(){return 1436}function Z7(){return __()|0}function $7(e,n,r,u){e=e|0,n=n|0,r=r|0,u=u|0,(Hl(u,896)|0)==512?r|0&&(eO(r),_t(r)):n|0&&_t(n)}function eO(e){e=e|0,e=t[e+4>>2]|0,e|0&&t2(e)}function tO(e){e=e|0,nO(e,4933),rO(e)|0,iO(e)|0}function nO(e,n){e=e|0,n=n|0;var r=0;r=AO()|0,t[e>>2]=r,OO(r,n),e2(t[e>>2]|0)}function rO(e){e=e|0;var n=0;return n=t[e>>2]|0,Gp(n,gO()|0),e|0}function iO(e){e=e|0;var n=0;return n=t[e>>2]|0,Gp(n,uO()|0),e|0}function uO(){var e=0;return c[7920]|0||(X3(10452),Vt(58,10452,ve|0)|0,e=7920,t[e>>2]=1,t[e+4>>2]=0),sr(10452)|0||X3(10452),10452}function X3(e){e=e|0,sO(e),Yp(e,1)}function oO(e){e=e|0,lO(e+24|0)}function lO(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)),_t(r))}function sO(e){e=e|0;var n=0;n=yr()|0,jn(e,5,1,n,dO()|0,2),t[e+24>>2]=0,t[e+28>>2]=0,t[e+32>>2]=0}function aO(e,n,r){e=e|0,n=+n,r=+r,fO(e,n,r)}function fO(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),cO(e,s,l),m=u}function cO(e,n,r){e=e|0,n=n|0,r=r|0,Q3(e+8|0,+B[n>>3],+B[r>>3]),c[e+24>>0]=1}function Q3(e,n,r){e=e|0,n=+n,r=+r,B[e>>3]=n,B[e+8>>3]=r}function dO(){return 1472}function pO(e,n){return e=+e,n=+n,hO(e,n)|0}function hO(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),Q3(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],J3(s,D,h),t[l>>2]=s,m=u,r|0}function J3(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 vO(e){e=e|0,Uv(e),_t(e)}function mO(e){e=e|0,e=t[e+12>>2]|0,e|0&&_t(e)}function yO(e){e=e|0,_t(e)}function gO(){var e=0;return c[7928]|0||(Z3(10488),Vt(59,10488,ve|0)|0,e=7928,t[e>>2]=1,t[e+4>>2]=0),sr(10488)|0||Z3(10488),10488}function Z3(e){e=e|0,DO(e),Yp(e,60)}function _O(e){e=e|0,EO(e+24|0)}function EO(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)),_t(r))}function DO(e){e=e|0;var n=0;n=yr()|0,jn(e,5,6,n,CO()|0,0),t[e+24>>2]=0,t[e+28>>2]=0,t[e+32>>2]=0}function wO(e){e=e|0,SO(e)}function SO(e){e=e|0,TO(e)}function TO(e){e=e|0,$3(e+8|0),c[e+24>>0]=1}function $3(e){e=e|0,t[e>>2]=0,t[e+4>>2]=0,t[e+8>>2]=0,t[e+12>>2]=0}function CO(){return 1492}function xO(){return RO()|0}function RO(){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,$3(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],J3(u,s,l),t[r>>2]=u,m=n,e|0}function AO(){var e=0;return c[7936]|0||(PO(10524),Vt(25,10524,ve|0)|0,e=7936,t[e>>2]=1,t[e+4>>2]=0),10524}function OO(e,n){e=e|0,n=n|0,t[e>>2]=MO()|0,t[e+4>>2]=kO()|0,t[e+12>>2]=n,t[e+8>>2]=LO()|0,t[e+32>>2]=7}function MO(){return 11700}function kO(){return 1484}function LO(){return __()|0}function NO(e,n,r,u){e=e|0,n=n|0,r=r|0,u=u|0,(Hl(u,896)|0)==512?r|0&&(FO(r),_t(r)):n|0&&_t(n)}function FO(e){e=e|0,e=t[e+4>>2]|0,e|0&&t2(e)}function PO(e){e=e|0,Qa(e)}function IO(e,n,r){e=e|0,n=n|0,r=r|0,e=Fr(n)|0,n=bO(r)|0,r=BO(r,0)|0,hM(e,n,r,kE()|0,0)}function bO(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=kE()|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?(t8(u,e,n),n=(t[r>>2]|0)+8|0,t[r>>2]=n):(VO(h,l,s),n=t[r>>2]|0),m=D,(n-(t[h>>2]|0)>>3)+-1|0}function kE(){var e=0,n=0;if(c[7944]|0||(e8(10568),Vt(61,10568,ve|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));e8(10568)}return 10568}function e8(e){e=e|0,zO(e)}function UO(e){e=e|0,jO(e+24|0)}function jO(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)),_t(r))}function zO(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 HO(e){return e=e|0,WO(t[(qO(e)|0)>>2]|0)|0}function qO(e){return e=e|0,(t[(kE()|0)+24>>2]|0)+(e<<3)|0}function WO(e){return e=e|0,qo(k_[e&7]()|0)|0}function t8(e,n,r){e=e|0,n=n|0,r=r|0,t[e>>2]=n,t[e+4>>2]=r}function VO(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=GO(e)|0,u>>>0>>0)hi(e);else{S=t[e>>2]|0,k=(t[e+8>>2]|0)-S|0,L=k>>2,YO(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,t8(t[h>>2]|0,t[n>>2]|0,t[r>>2]|0),t[h>>2]=(t[h>>2]|0)+8,KO(e,l),XO(l),m=D;return}}function GO(e){return e=e|0,536870911}function YO(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 KO(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?(gr(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 XO(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&&_t(e)}function QO(){JO()}function JO(){ZO(10604)}function ZO(e){e=e|0,$O(e,4955)}function $O(e,n){e=e|0,n=n|0;var r=0;r=eM()|0,t[e>>2]=r,tM(r,n),e2(t[e>>2]|0)}function eM(){var e=0;return c[7952]|0||(fM(10612),Vt(25,10612,ve|0)|0,e=7952,t[e>>2]=1,t[e+4>>2]=0),10612}function tM(e,n){e=e|0,n=n|0,t[e>>2]=uM()|0,t[e+4>>2]=oM()|0,t[e+12>>2]=n,t[e+8>>2]=lM()|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,nM(10608,r),m=n}function Fv(){return c[11714]|0||(t[2652]=0,Vt(62,10608,ve|0)|0,c[11714]=1),10608}function nM(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 rM(e){e=e|0,iM(e)}function iM(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,_t(r);while((n|0)!=0);t[e>>2]=0}function uM(){return 11715}function oM(){return 1496}function lM(){return N1()|0}function sM(e,n,r,u){e=e|0,n=n|0,r=r|0,u=u|0,(Hl(u,896)|0)==512?r|0&&(aM(r),_t(r)):n|0&&_t(n)}function aM(e){e=e|0,e=t[e+4>>2]|0,e|0&&t2(e)}function fM(e){e=e|0,Qa(e)}function cM(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?(I8(LE(u)|0,e)|0)==0:0);)if(r=t[r>>2]|0,!r)break e;dM(u,n)}while(0)}function LE(e){return e=e|0,t[e+12>>2]|0}function dM(e,n){e=e|0,n=n|0;var r=0;e=e+36|0,r=t[e>>2]|0,r|0&&(ca(r),_t(r)),r=pn(4)|0,Sf(r,n),t[e>>2]=r}function NE(){return c[11716]|0||(t[2664]=0,Vt(63,10656,ve|0)|0,c[11716]=1),10656}function n8(){var e=0;return c[11717]|0?e=t[2665]|0:(pM(),t[2665]=1504,c[11717]=1,e=1504),e|0}function pM(){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 r8(){return 1572}function hM(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,NE()|0,vM(10656,k,L,S,D,h),m=s}function vM(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,gd(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 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,Te=0,ye=0,Ze=0,Ge=0,ft=0;if(ft=m,m=m+32|0,Te=ft+20|0,ye=ft+8|0,Ze=ft+4|0,Ge=ft,n=t[n>>2]|0,n|0){Be=Te+4|0,S=Te+8|0,L=ye+4|0,k=ye+8|0,I=ye+8|0,K=Te+8|0;do{if(h=n+4|0,D=FE(h)|0,D|0){if(l=Ay(D)|0,t[Te>>2]=0,t[Be>>2]=0,t[S>>2]=0,u=(Oy(D)|0)+1|0,mM(Te,u),u|0)for(;u=u+-1|0,Yf(ye,t[l>>2]|0),s=t[Be>>2]|0,s>>>0<(t[K>>2]|0)>>>0?(t[s>>2]=t[ye>>2],t[Be>>2]=(t[Be>>2]|0)+4):PE(Te,ye),u;)l=l+4|0;u=My(D)|0,t[ye>>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)?yM(ye,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,Te,ye),IE(ye),F1(Te)}n=t[n>>2]|0}while((n|0)!=0)}m=ft}function FE(e){return e=e|0,t[e+12>>2]|0}function Ay(e){return e=e|0,t[e+12>>2]|0}function Oy(e){return e=e|0,t[e+16>>2]|0}function mM(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&&(d8(r,n,(t[e+4>>2]|0)-u>>2,e+8|0),p8(e,r),h8(r)),m=l}function PE(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=c8(e)|0,s>>>0>>0)hi(e);else{D=t[e>>2]|0,L=(t[e+8>>2]|0)-D|0,S=L>>1,d8(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,p8(e,r),h8(r),m=h;return}}function My(e){return e=e|0,t[e+8>>2]|0}function yM(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,bM(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),UM(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,_M(e,n,r,u,l,s)}function IE(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)),_t(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)),_t(r))}function _M(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=g0(e)|0,t[I>>2]=t[n>>2],r=t[r>>2]|0,u=t[u>>2]|0,bE(S,l),EM(L,s),t[k>>2]=t[I>>2],DM(e,k,r,u,S,L),IE(L),F1(S),La(D),m=h}function bE(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&&(PM(e,u),IM(e,t[n>>2]|0,t[r>>2]|0,u))}function EM(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&&(NM(e,u),FM(e,t[n>>2]|0,t[r>>2]|0,u))}function DM(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=_0(wM()|0)|0,t[I>>2]=t[n>>2],t[k>>2]=t[I>>2],n=Kp(k)|0,r=u8(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=UE(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,Qo(0,L|0,e|0,n|0,r|0,u|0,l|0,SM(S)|0)|0,IE(S),F1(D),m=h}function wM(){var e=0;return c[7968]|0||(kM(10708),e=7968,t[e>>2]=1,t[e+4>>2]=0),10708}function Kp(e){return e=e|0,l8(e)|0}function u8(e){return e=e|0,o8(e)|0}function BE(e){return e=e|0,qo(e)|0}function UE(e){return e=e|0,CM(e)|0}function SM(e){return e=e|0,TM(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[(t[e>>2]|0)+(n<<2)>>2]|0)|0,n=n+1|0;while((n|0)!=(r|0))}return u|0}function o8(e){return e=e|0,e|0}function CM(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]=l8((t[e>>2]|0)+(n<<2)|0)|0,n=n+1|0;while((n|0)!=(r|0))}return u|0}function l8(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(s8()|0)|0,u?(is(n,u),kf(r,n),sF(e,r),e=xs(n)|0):e=xM(e)|0,m=l,e|0}function s8(){var e=0;return c[7960]|0||(MM(10664),Vt(25,10664,ve|0)|0,e=7960,t[e>>2]=1,t[e+4>>2]=0),10664}function xM(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],a8(e,s,l),t[u>>2]=e,m=r,n|0}function a8(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 RM(e){e=e|0,Uv(e),_t(e)}function AM(e){e=e|0,e=t[e+12>>2]|0,e|0&&_t(e)}function OM(e){e=e|0,_t(e)}function MM(e){e=e|0,Qa(e)}function kM(e){e=e|0,ll(e,LM()|0,5)}function LM(){return 1676}function NM(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 FM(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&&(gr(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 PM(e,n){e=e|0,n=n|0;var r=0;if((c8(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 IM(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&&(gr(t[u>>2]|0,n|0,e|0)|0,t[u>>2]=(t[u>>2]|0)+(e>>>2<<2))}function c8(e){return e=e|0,1073741823}function bM(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?(gr(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 UM(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&&_t(e)}function d8(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 p8(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?(gr(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 h8(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&&_t(e)}function jM(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,Te=0,ye=0;if(ye=m,m=m+32|0,k=ye+20|0,I=ye+12|0,L=ye+16|0,K=ye+4|0,Be=ye,Te=ye+8|0,D=n8()|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),zM(e,k,D,S),s=s+4|0,h=t[s>>2]|0,h;)S=S+1|0,D=D+1|0;if(s=r8()|0,h=t[s>>2]|0,h|0)do Yf(k,h),t[I>>2]=t[s+4>>2],HM(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]=LE(n)|0,qM(r,k,I),s=t[s>>2]|0;while((s|0)!=0);if(Yf(L,0),s=NE()|0,t[k>>2]=t[L>>2],i8(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),WM(K,v8(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):PE(k,Be),h=t[h>>2]|0;while((h|0)!=0);VM(u,I,k),F1(k)}t[Te>>2]=t[I>>2],L=m8(S)|0,t[k>>2]=t[Te>>2],i8(k,L,l),Ed(K),s=t[s>>2]|0}while((s|0)!=0)}m=ye}function zM(e,n,r,u){e=e|0,n=n|0,r=r|0,u=u|0,rk(e,n,r,u)}function HM(e,n,r){e=e|0,n=n|0,r=r|0,nk(e,n,r)}function Pv(e){return e=e|0,e|0}function qM(e,n,r){e=e|0,n=n|0,r=r|0,ZM(e,n,r)}function v8(e){return e=e|0,e+16|0}function WM(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=JM(r)|0,u|0){if(u=pn(12)|0,h=(y8(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=(y8(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 VM(e,n,r){e=e|0,n=n|0,r=r|0,GM(e,n,r)}function m8(e){return e=e|0,e+24|0}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+24|0,l=u+16|0,D=u+12|0,s=u,ka(l),e=g0(e)|0,t[D>>2]=t[n>>2],bE(s,r),t[h>>2]=t[D>>2],YM(e,h,s),F1(s),La(l),m=u}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;u=m,m=m+32|0,h=u+16|0,D=u+12|0,l=u,s=_0(KM()|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,Io(0,s|0,e|0,n|0,UE(l)|0)|0,F1(l),m=u}function KM(){var e=0;return c[7976]|0||(XM(10720),e=7976,t[e>>2]=1,t[e+4>>2]=0),10720}function XM(e){e=e|0,ll(e,QM()|0,2)}function QM(){return 1732}function JM(e){return e=e|0,t[e>>2]|0}function y8(e){return e=e|0,t[e>>2]|0}function ZM(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=g0(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=_0($M()|0)|0,t[h>>2]=t[n>>2],t[s>>2]=t[h>>2],n=Kp(s)|0,Io(0,l|0,e|0,n|0,u8(r)|0)|0,m=u}function $M(){var e=0;return c[7984]|0||(ek(10732),e=7984,t[e>>2]=1,t[e+4>>2]=0),10732}function ek(e){e=e|0,ll(e,tk()|0,2)}function tk(){return 1744}function nk(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=g0(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 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+32|0,h=l+16|0,s=l+8|0,D=l,ka(s),e=g0(e)|0,t[D>>2]=t[n>>2],r=c[r>>0]|0,u=c[u>>0]|0,t[h>>2]=t[D>>2],ik(e,h,r,u),La(s),m=l}function ik(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=_0(uk()|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 uk(){var e=0;return c[7992]|0||(lk(10744),e=7992,t[e>>2]=1,t[e+4>>2]=0),10744}function Iv(e){return e=e|0,ok(e)|0}function ok(e){return e=e|0,e&255|0}function lk(e){e=e|0,ll(e,sk()|0,3)}function sk(){return 1756}function ak(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=lF(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,fk(S,r,L),D_(e,S)|0,jo(S);break}case 8:{I=VE(n)|0,c[L>>0]=8,Yf(k,t[I+4>>2]|0),ck(S,r,L,k,I+8|0),D_(e,S)|0,jo(S);break}case 9:{if(s=VE(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):PE(D,S),n;)l=l+4|0;c[L>>0]=9,Yf(k,t[s+8>>2]|0),dk(S,r,L,k,D),D_(e,S)|0,jo(S);break}default:I=VE(n)|0,c[L>>0]=u,Yf(k,t[I+4>>2]|0),pk(S,r,L,k),D_(e,S)|0,jo(S)}F1(D),m=K}function fk(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=g0(n)|0,xk(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 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;s=m,m=m+32|0,D=s+16|0,h=s+8|0,S=s,ka(h),n=g0(n)|0,r=c[r>>0]|0,t[S>>2]=t[u>>2],l=t[l>>2]|0,t[D>>2]=t[S>>2],wk(e,n,r,D,l),La(h),m=s}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,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=g0(n)|0,r=c[r>>0]|0,t[L>>2]=t[u>>2],bE(D,l),t[S>>2]=t[L>>2],gk(e,n,r,S,D),F1(D),La(h),m=s}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+32|0,h=l+16|0,s=l+8|0,D=l,ka(s),n=g0(n)|0,r=c[r>>0]|0,t[D>>2]=t[u>>2],t[h>>2]=t[D>>2],hk(e,n,r,h),La(s),m=l}function hk(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=_0(vk()|0)|0,r=Iv(r)|0,t[D>>2]=t[u>>2],t[s>>2]=t[D>>2],w_(e,Io(0,h|0,n|0,r|0,Kp(s)|0)|0),m=l}function vk(){var e=0;return c[8e3]|0||(mk(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 mk(e){e=e|0,ll(e,yk()|0,2)}function yk(){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=_0(_k()|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,UE(h)|0)|0),F1(h),m=s}function _k(){var e=0;return c[8008]|0||(Ek(10768),e=8008,t[e>>2]=1,t[e+4>>2]=0),10768}function Ek(e){e=e|0,ll(e,Dk()|0,3)}function Dk(){return 1784}function wk(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=_0(Sk()|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 Sk(){var e=0;return c[8016]|0||(Tk(10780),e=8016,t[e>>2]=1,t[e+4>>2]=0),10780}function Tk(e){e=e|0,ll(e,Ck()|0,3)}function Ck(){return 1800}function xk(e,n,r){e=e|0,n=n|0,r=r|0;var u=0;u=_0(Rk()|0)|0,w_(e,Ki(0,u|0,n|0,Iv(r)|0)|0)}function Rk(){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,Ok()|0,1)}function Ok(){return 1816}function Mk(){kk(),Lk(),Nk()}function kk(){t[2702]=G8(65536)|0}function Lk(){$k(10856)}function Nk(){Fk(10816)}function Fk(e){e=e|0,Pk(e,5044),Ik(e)|0}function Pk(e,n){e=e|0,n=n|0;var r=0;r=s8()|0,t[e>>2]=r,Yk(r,n),e2(t[e>>2]|0)}function Ik(e){e=e|0;var n=0;return n=t[e>>2]|0,Gp(n,bk()|0),e|0}function bk(){var e=0;return c[8032]|0||(_8(10820),Vt(64,10820,ve|0)|0,e=8032,t[e>>2]=1,t[e+4>>2]=0),sr(10820)|0||_8(10820),10820}function _8(e){e=e|0,jk(e),Yp(e,25)}function Bk(e){e=e|0,Uk(e+24|0)}function Uk(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)),_t(r))}function jk(e){e=e|0;var n=0;n=yr()|0,jn(e,5,18,n,Wk()|0,1),t[e+24>>2]=0,t[e+28>>2]=0,t[e+32>>2]=0}function zk(e,n){e=e|0,n=n|0,Hk(e,n)}function Hk(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,qk(e,u),m=r}function qk(e,n){e=e|0,n=n|0,E8(e+4|0,t[n>>2]|0),c[e+8>>0]=1}function E8(e,n){e=e|0,n=n|0,t[e>>2]=n}function Wk(){return 1824}function Vk(e){return e=e|0,Gk(e)|0}function Gk(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),E8(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],a8(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=G8(e+8|0)|0,t[e>>2]=t[2703],t[2703]=e,e=e+8|0),e|0}function Yk(e,n){e=e|0,n=n|0,t[e>>2]=Kk()|0,t[e+4>>2]=Xk()|0,t[e+12>>2]=n,t[e+8>>2]=Qk()|0,t[e+32>>2]=9}function Kk(){return 11744}function Xk(){return 1832}function Qk(){return __()|0}function Jk(e,n,r,u){e=e|0,n=n|0,r=r|0,u=u|0,(Hl(u,896)|0)==512?r|0&&(Zk(r),_t(r)):n|0&&_t(n)}function Zk(e){e=e|0,e=t[e+4>>2]|0,e|0&&t2(e)}function $k(e){e=e|0,eL(e,5052),tL(e)|0,nL(e,5058,26)|0,rL(e,5069,1)|0,iL(e,5077,10)|0,uL(e,5087,19)|0,oL(e,5094,27)|0}function eL(e,n){e=e|0,n=n|0;var r=0;r=$N()|0,t[e>>2]=r,eF(r,n),e2(t[e>>2]|0)}function tL(e){e=e|0;var n=0;return n=t[e>>2]|0,Gp(n,UN()|0),e|0}function nL(e,n,r){return e=e|0,n=n|0,r=r|0,DN(e,Fr(n)|0,r,0),e|0}function rL(e,n,r){return e=e|0,n=n|0,r=r|0,oN(e,Fr(n)|0,r,0),e|0}function iL(e,n,r){return e=e|0,n=n|0,r=r|0,bL(e,Fr(n)|0,r,0),e|0}function uL(e,n,r){return e=e|0,n=n|0,r=r|0,wL(e,Fr(n)|0,r,0),e|0}function D8(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}_t(r)}t[2701]=e}function oL(e,n,r){return e=e|0,n=n|0,r=r|0,lL(e,Fr(n)|0,r,0),e|0}function lL(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=sL(r)|0,wi(s,n,l,e,aL(r,u)|0,u)}function jE(){var e=0,n=0;if(c[8040]|0||(S8(10860),Vt(65,10860,ve|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));S8(10860)}return 10860}function sL(e){return e=e|0,e|0}function aL(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?(w8(u,e,n),n=(t[r>>2]|0)+8|0,t[r>>2]=n):(fL(h,l,s),n=t[r>>2]|0),m=D,(n-(t[h>>2]|0)>>3)+-1|0}function w8(e,n,r){e=e|0,n=n|0,r=r|0,t[e>>2]=n,t[e+4>>2]=r}function fL(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,dL(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,w8(t[h>>2]|0,t[n>>2]|0,t[r>>2]|0),t[h>>2]=(t[h>>2]|0)+8,pL(e,l),hL(l),m=D;return}}function cL(e){return e=e|0,536870911}function dL(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 pL(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?(gr(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 hL(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&&_t(e)}function S8(e){e=e|0,yL(e)}function vL(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)),_t(r))}function yL(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 _L(e,n,r){e=e|0,n=n|0,r=r|0,DL(t[(EL(e)|0)>>2]|0,n,r)}function EL(e){return e=e|0,(t[(jE()|0)+24>>2]|0)+(e<<3)|0}function DL(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 wL(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=SL(r)|0,wi(s,n,l,e,TL(r,u)|0,u)}function zE(){var e=0,n=0;if(c[8048]|0||(C8(10896),Vt(66,10896,ve|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));C8(10896)}return 10896}function SL(e){return e=e|0,e|0}function TL(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?(T8(u,e,n),n=(t[r>>2]|0)+8|0,t[r>>2]=n):(CL(h,l,s),n=t[r>>2]|0),m=D,(n-(t[h>>2]|0)>>3)+-1|0}function T8(e,n,r){e=e|0,n=n|0,r=r|0,t[e>>2]=n,t[e+4>>2]=r}function CL(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=xL(e)|0,u>>>0>>0)hi(e);else{S=t[e>>2]|0,k=(t[e+8>>2]|0)-S|0,L=k>>2,RL(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,T8(t[h>>2]|0,t[n>>2]|0,t[r>>2]|0),t[h>>2]=(t[h>>2]|0)+8,AL(e,l),OL(l),m=D;return}}function xL(e){return e=e|0,536870911}function RL(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?(gr(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 OL(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&&_t(e)}function C8(e){e=e|0,LL(e)}function ML(e){e=e|0,kL(e+24|0)}function kL(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)),_t(r))}function LL(e){e=e|0;var n=0;n=yr()|0,jn(e,1,11,n,NL()|0,1),t[e+24>>2]=0,t[e+28>>2]=0,t[e+32>>2]=0}function NL(){return 1852}function FL(e,n){return e=e|0,n=n|0,IL(t[(PL(e)|0)>>2]|0,n)|0}function PL(e){return e=e|0,(t[(zE()|0)+24>>2]|0)+(e<<3)|0}function IL(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=qo(Zp[e&31](n)|0)|0,m=r,n|0}function bL(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=BL(r)|0,wi(s,n,l,e,UL(r,u)|0,u)}function HE(){var e=0,n=0;if(c[8056]|0||(R8(10932),Vt(67,10932,ve|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));R8(10932)}return 10932}function BL(e){return e=e|0,e|0}function UL(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?(x8(u,e,n),n=(t[r>>2]|0)+8|0,t[r>>2]=n):(jL(h,l,s),n=t[r>>2]|0),m=D,(n-(t[h>>2]|0)>>3)+-1|0}function x8(e,n,r){e=e|0,n=n|0,r=r|0,t[e>>2]=n,t[e+4>>2]=r}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,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=zL(e)|0,u>>>0>>0)hi(e);else{S=t[e>>2]|0,k=(t[e+8>>2]|0)-S|0,L=k>>2,HL(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,x8(t[h>>2]|0,t[n>>2]|0,t[r>>2]|0),t[h>>2]=(t[h>>2]|0)+8,qL(e,l),WL(l),m=D;return}}function zL(e){return e=e|0,536870911}function HL(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 qL(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?(gr(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 WL(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&&_t(e)}function R8(e){e=e|0,KL(e)}function VL(e){e=e|0,YL(e+24|0)}function YL(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)),_t(r))}function KL(e){e=e|0;var n=0;n=yr()|0,jn(e,1,7,n,XL()|0,2),t[e+24>>2]=0,t[e+28>>2]=0,t[e+32>>2]=0}function XL(){return 1860}function QL(e,n,r){return e=e|0,n=n|0,r=r|0,ZL(t[(JL(e)|0)>>2]|0,n,r)|0}function JL(e){return e=e|0,(t[(HE()|0)+24>>2]|0)+(e<<3)|0}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,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,$L(S,n),eN(D,S,n),Ks(l,r),r=Xs(l,r)|0,t[h>>2]=t[D>>2],Fy[e&15](s,h,r),r=tN(s)|0,jo(s),Qs(l),m=u,r|0}function $L(e,n){e=e|0,n=n|0}function eN(e,n,r){e=e|0,n=n|0,r=r|0,nN(e,r)}function tN(e){return e=e|0,g0(e)|0}function nN(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?(rN(r,0),eu(u|0,r|0)|0,iN(e,r),uN(r)):t[e>>2]=t[n>>2],m=l}function rN(e,n){e=e|0,n=n|0,cd(e,n),t[e+4>>2]=0,c[e+8>>0]=0}function iN(e,n){e=e|0,n=n|0,t[e>>2]=t[n+4>>2]}function uN(e){e=e|0,c[e+8>>0]=0}function oN(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=lN(r)|0,wi(s,n,l,e,sN(r,u)|0,u)}function qE(){var e=0,n=0;if(c[8064]|0||(O8(10968),Vt(68,10968,ve|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));O8(10968)}return 10968}function lN(e){return e=e|0,e|0}function sN(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?(A8(u,e,n),n=(t[r>>2]|0)+8|0,t[r>>2]=n):(aN(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 aN(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=fN(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,A8(t[h>>2]|0,t[n>>2]|0,t[r>>2]|0),t[h>>2]=(t[h>>2]|0)+8,dN(e,l),pN(l),m=D;return}}function fN(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 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)+(0-(l>>3)<<3)|0,t[s>>2]=r,(l|0)>0?(gr(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 pN(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&&_t(e)}function O8(e){e=e|0,mN(e)}function hN(e){e=e|0,vN(e+24|0)}function vN(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)),_t(r))}function mN(e){e=e|0;var n=0;n=yr()|0,jn(e,1,1,n,yN()|0,5),t[e+24>>2]=0,t[e+28>>2]=0,t[e+32>>2]=0}function yN(){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,EN(t[(_N(e)|0)>>2]|0,n,r,u,l,s)}function _N(e){return e=e|0,(t[(qE()|0)+24>>2]|0)+(e<<3)|0}function EN(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,J8[e&1](n,r,u,l,s),Qs(I),Qs(k),Qs(L),Qs(S),Qs(D),m=h}function DN(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=WE()|0,e=wN(r)|0,wi(s,n,l,e,SN(r,u)|0,u)}function WE(){var e=0,n=0;if(c[8072]|0||(k8(11004),Vt(69,11004,ve|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));k8(11004)}return 11004}function wN(e){return e=e|0,e|0}function SN(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=WE()|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?(M8(u,e,n),n=(t[r>>2]|0)+8|0,t[r>>2]=n):(TN(h,l,s),n=t[r>>2]|0),m=D,(n-(t[h>>2]|0)>>3)+-1|0}function M8(e,n,r){e=e|0,n=n|0,r=r|0,t[e>>2]=n,t[e+4>>2]=r}function TN(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=CN(e)|0,u>>>0>>0)hi(e);else{S=t[e>>2]|0,k=(t[e+8>>2]|0)-S|0,L=k>>2,xN(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,M8(t[h>>2]|0,t[n>>2]|0,t[r>>2]|0),t[h>>2]=(t[h>>2]|0)+8,RN(e,l),AN(l),m=D;return}}function CN(e){return e=e|0,536870911}function xN(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 RN(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?(gr(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&&_t(e)}function k8(e){e=e|0,kN(e)}function ON(e){e=e|0,MN(e+24|0)}function MN(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)),_t(r))}function kN(e){e=e|0;var n=0;n=yr()|0,jn(e,1,12,n,LN()|0,2),t[e+24>>2]=0,t[e+28>>2]=0,t[e+32>>2]=0}function LN(){return 1896}function NN(e,n,r){e=e|0,n=n|0,r=r|0,PN(t[(FN(e)|0)>>2]|0,n,r)}function FN(e){return e=e|0,(t[(WE()|0)+24>>2]|0)+(e<<3)|0}function PN(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,IN(s,n),n=bN(s,n)|0,Ks(l,r),r=Xs(l,r)|0,I1[e&31](n,r),Qs(l),m=u}function IN(e,n){e=e|0,n=n|0}function bN(e,n){return e=e|0,n=n|0,BN(n)|0}function BN(e){return e=e|0,e|0}function UN(){var e=0;return c[8080]|0||(L8(11040),Vt(70,11040,ve|0)|0,e=8080,t[e>>2]=1,t[e+4>>2]=0),sr(11040)|0||L8(11040),11040}function L8(e){e=e|0,HN(e),Yp(e,71)}function jN(e){e=e|0,zN(e+24|0)}function zN(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)),_t(r))}function HN(e){e=e|0;var n=0;n=yr()|0,jn(e,5,7,n,GN()|0,0),t[e+24>>2]=0,t[e+28>>2]=0,t[e+32>>2]=0}function qN(e){e=e|0,WN(e)}function WN(e){e=e|0,VN(e)}function VN(e){e=e|0,c[e+8>>0]=1}function GN(){return 1936}function YN(){return KN()|0}function KN(){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],XN(u,s,l),t[r>>2]=u,m=n,e|0}function XN(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 QN(e){e=e|0,Uv(e),_t(e)}function JN(e){e=e|0,e=t[e+12>>2]|0,e|0&&_t(e)}function ZN(e){e=e|0,_t(e)}function $N(){var e=0;return c[8088]|0||(oF(11076),Vt(25,11076,ve|0)|0,e=8088,t[e>>2]=1,t[e+4>>2]=0),11076}function eF(e,n){e=e|0,n=n|0,t[e>>2]=tF()|0,t[e+4>>2]=nF()|0,t[e+12>>2]=n,t[e+8>>2]=rF()|0,t[e+32>>2]=10}function tF(){return 11745}function nF(){return 1940}function rF(){return N1()|0}function iF(e,n,r,u){e=e|0,n=n|0,r=r|0,u=u|0,(Hl(u,896)|0)==512?r|0&&(uF(r),_t(r)):n|0&&_t(n)}function uF(e){e=e|0,e=t[e+4>>2]|0,e|0&&t2(e)}function oF(e){e=e|0,Qa(e)}function Yf(e,n){e=e|0,n=n|0,t[e>>2]=n}function VE(e){return e=e|0,t[e>>2]|0}function lF(e){return e=e|0,c[t[e>>2]>>0]|0}function sF(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],aF(n,u)|0,m=r}function aF(e,n){e=e|0,n=n|0;var r=0;return r=fF(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 fF(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=g0(e)|0,n=cF(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 cF(e,n){e=e|0,n=n|0;var r=0;return r=_0(dF()|0)|0,Ki(0,r|0,e|0,BE(n)|0)|0}function La(e){e=e|0,D8(t[e>>2]|0,t[e+4>>2]|0)}function dF(){var e=0;return c[8096]|0||(pF(11120),e=8096,t[e>>2]=1,t[e+4>>2]=0),11120}function pF(e){e=e|0,ll(e,hF()|0,1)}function hF(){return 1948}function vF(){mF()}function mF(){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,Te=0,ye=0;if(Te=m,m=m+16|0,k=Te+4|0,I=Te,bn(65536,10804,t[2702]|0,10812),r=n8()|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,M[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=r8()|0,n=t[e>>2]|0,n|0)do k0(n|0,t[e+4>>2]|0),e=e+8|0,n=t[e>>2]|0;while((n|0)!=0);k0(yF()|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,!!(_F(l)|0);)if(t[I>>2]=S,t[k>>2]=t[I>>2],EF(L,k)|0,!e)break e;if(DF(l),S=t[S>>2]|0,n=N8(l)|0,s=c0()|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[(v8(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;ye=Pv(l)|0,n=wF(l)|0,r=N8(l)|0,u=SF(l)|0,L0(ye|0,n|0,h|0,D|0,r|0,u|0,LE(l)|0),gi(s|0)}while((e|0)!=0)}}while(0);if(e=t[(NE()|0)>>2]|0,e|0)do ye=e+4|0,L=FE(ye)|0,l=My(L)|0,s=Ay(L)|0,h=(Oy(L)|0)+1|0,D=S_(L)|0,S=F8(ye)|0,L=sr(L)|0,k=E_(ye)|0,I=GE(ye)|0,f0(0,l|0,s|0,h|0,D|0,S|0,L|0,k|0,I|0,YE(ye)|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[(m8(n)|0)>>2]|0,Be|0):0){r=Be;do{n=r+4|0,u=FE(n)|0;n:do if(u|0)switch(sr(u)|0){case 0:break t;case 4:case 3:case 2:{D=My(u)|0,S=Ay(u)|0,L=(Oy(u)|0)+1|0,k=S_(u)|0,I=sr(u)|0,ye=E_(n)|0,f0(K|0,D|0,S|0,L|0,k|0,0,I|0,ye|0,GE(n)|0,YE(n)|0);break n}case 1:{h=My(u)|0,D=Ay(u)|0,S=(Oy(u)|0)+1|0,L=S_(u)|0,k=F8(n)|0,I=sr(u)|0,ye=E_(n)|0,f0(K|0,h|0,D|0,S|0,L|0,k|0,I|0,ye|0,GE(n)|0,YE(n)|0);break n}case 5:{L=My(u)|0,k=Ay(u)|0,I=(Oy(u)|0)+1|0,ye=S_(u)|0,f0(K|0,L|0,k|0,I|0,ye|0,TF(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=Te}function yF(){return 11703}function gF(e){e=e|0,c[e+40>>0]=0}function _F(e){return e=e|0,(c[e+40>>0]|0)!=0|0}function EF(e,n){return e=e|0,n=n|0,n=CF(n)|0,e=t[n>>2]|0,t[n>>2]=t[e>>2],_t(e),t[n>>2]|0}function DF(e){e=e|0,c[e+40>>0]=1}function N8(e){return e=e|0,t[e+20>>2]|0}function wF(e){return e=e|0,t[e+8>>2]|0}function SF(e){return e=e|0,t[e+32>>2]|0}function S_(e){return e=e|0,t[e+4>>2]|0}function F8(e){return e=e|0,t[e+4>>2]|0}function GE(e){return e=e|0,t[e+8>>2]|0}function YE(e){return e=e|0,t[e+16>>2]|0}function TF(e){return e=e|0,t[e+20>>2]|0}function CF(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,Te=0,ye=0,Ze=0,Ge=0,ft=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-(ft|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 ft=h-I|0,t[2786]=ft,Pe=t[2789]|0,Me=Pe+I|0,t[2789]=Me,t[Me+4>>2]=ft|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?(ye=u+4|0,(e+(t[ye>>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[ye>>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,Te=Be+-1|0,n=((Te&n|0)==0?0:(Te+n&0-Be)-n|0)+L|0,Be=t[2891]|0,Te=n+Be|0,n>>>0>I>>>0&n>>>0<2147483647):0){if(ye=t[2893]|0,ye|0?Te>>>0<=Be>>>0|Te>>>0>ye>>>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)?(ft=n2(L|0)|0,ye=n2(0)|0,Ze=ye-ft|0,Ge=Ze>>>0>(I+40|0)>>>0,!((ft|0)==(-1|0)|Ge^1|ft>>>0>>0&((ft|0)!=(-1|0)&(ye|0)!=(-1|0))^1)):0)&&(h=Ge?Ze:n,s=ft,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-(ft|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-(ft|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 ft=n-I|0,t[2786]=ft,Pe=t[2789]|0,Me=Pe+I|0,t[2789]=Me,t[Me+4>>2]=ft|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 xF(){return 11628}function RF(e){e=e|0;var n=0,r=0;return n=m,m=m+16|0,r=n,t[r>>2]=MF(t[e+60>>2]|0)|0,e=x_(Ou(6,r|0)|0)|0,m=n,e|0}function P8(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_(mo(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_(mo(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_(Li(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(OF()|0)+64|0}function OF(){return KE()|0}function KE(){return 2084}function MF(e){return e=e|0,e|0}function kF(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,bo(54,u|0)|0):0)&&(c[e+75>>0]=-1),u=P8(e,n,r)|0,m=l,u|0}function I8(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 LF(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 b8(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,Te=0,ye=0;ye=m,m=m+224|0,k=ye+120|0,I=ye+80|0,Be=ye,Te=ye+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],(XE(0,n,k,Be,I)|0)<0?r=-1:((t[e+76>>2]|0)>-1?K=NF(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=XE(e,n,k,Be,I)|0:(l=e+44|0,s=t[l>>2]|0,t[l>>2]=Te,h=e+28|0,t[h>>2]=Te,D=e+20|0,t[D>>2]=Te,t[u>>2]=80,S=e+16|0,t[S>>2]=Te+80,r=XE(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&&FF(e),r=(u&32|0)==0?r:-1),m=ye,r|0}function XE(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,Te=0,ye=0,Ze=0,Ge=0,ft=0,Me=0,Pe=0,Zt=0,Br=0,In=0,gn=0,_r=0,Pr=0,Ln=0;Ln=m,m=m+64|0,In=Ln+16|0,gn=Ln,Zt=Ln+24|0,_r=Ln+8|0,Pr=Ln+20|0,t[In>>2]=n,ft=(e|0)!=0,Me=Zt+40|0,Pe=Me,Zt=Zt+39|0,Br=_r+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,ft&&Y0(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,ye=Ze?h:-1,k=Ze?1:k,S=Ze?D+3|0:S):ye=-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}ft?(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}ft?(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(Te=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+(Te*58|0))>>0]|0,K=I&255,(K+-1|0)>>>0<8)Te=K,S=Ze;else break}if(!(I<<24>>24)){s=-1;break}Be=(ye|0)>-1;do if(I<<24>>24==19)if(Be){s=-1;break e}else Ge=49;else{if(Be){t[l+(ye<<2)>>2]=K,Be=u+(ye<<3)|0,ye=t[Be+4>>2]|0,Ge=gn,t[Ge>>2]=t[Be>>2],t[Ge+4>>2]=ye,Ge=49;break}if(!ft){s=0;break e}U8(gn,K,r)}while(0);if((Ge|0)==49?(Ge=0,!ft):0){h=0,n=Ze;continue}S=c[S>>0]|0,S=(Te|0)!=0&(S&15|0)==3?S&-33:S,Be=L&-65537,ye=(L&8192|0)==0?L:Be;t:do switch(S|0){case 110:switch((Te&255)<<24>>24){case 0:{t[t[gn>>2]>>2]=s,h=0,n=Ze;continue e}case 1:{t[t[gn>>2]>>2]=s,h=0,n=Ze;continue e}case 2:{h=t[gn>>2]|0,t[h>>2]=s,t[h+4>>2]=((s|0)<0)<<31>>31,h=0,n=Ze;continue e}case 3:{_[t[gn>>2]>>1]=s,h=0,n=Ze;continue e}case 4:{c[t[gn>>2]>>0]=s,h=0,n=Ze;continue e}case 6:{t[t[gn>>2]>>2]=s,h=0,n=Ze;continue e}case 7:{h=t[gn>>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=ye|8,Ge=61;break}case 88:case 120:{n=ye,Ge=61;break}case 111:{S=gn,n=t[S>>2]|0,S=t[S+4>>2]|0,K=IF(n,S,Me)|0,Be=Pe-K|0,L=0,I=5642,D=(ye&8|0)==0|(D|0)>(Be|0)?D:Be+1|0,Be=ye,Ge=67;break}case 105:case 100:if(S=gn,n=t[S>>2]|0,S=t[S+4>>2]|0,(S|0)<0){n=R_(0,0,n|0,S|0)|0,S=tt,L=gn,t[L>>2]=n,t[L+4>>2]=S,L=1,I=5642,Ge=66;break t}else{L=(ye&2049|0)!=0&1,I=(ye&2048|0)==0?(ye&1|0)==0?5642:5644:5643,Ge=66;break t}case 117:{S=gn,L=0,I=5642,n=t[S>>2]|0,S=t[S+4>>2]|0,Ge=66;break}case 99:{c[Zt>>0]=t[gn>>2],n=Zt,L=0,I=5642,K=Me,S=1,D=Be;break}case 109:{S=bF(t[(bv()|0)>>2]|0)|0,Ge=71;break}case 115:{S=t[gn>>2]|0,S=S|0?S:5652,Ge=71;break}case 67:{t[_r>>2]=t[gn>>2],t[Br>>2]=0,t[gn>>2]=_r,K=-1,S=_r,Ge=75;break}case 83:{n=t[gn>>2]|0,D?(K=D,S=n,Ge=75):(_l(e,32,h,0,ye),n=0,Ge=84);break}case 65:case 71:case 70:case 69:case 97:case 103:case 102:case 101:{h=UF(e,+B[gn>>3],h,D,ye,S)|0,n=Ze;continue e}default:L=0,I=5642,K=Me,S=D,D=ye}while(0);t:do if((Ge|0)==61)ye=gn,Te=t[ye>>2]|0,ye=t[ye+4>>2]|0,K=PF(Te,ye,Me,S&32)|0,I=(n&8|0)==0|(Te|0)==0&(ye|0)==0,L=I?0:2,I=I?5642:5642+(S>>4)|0,Be=n,n=Te,S=ye,Ge=67;else if((Ge|0)==66)K=Bv(n,S,Me)|0,Be=ye,Ge=67;else if((Ge|0)==71)Ge=0,ye=BF(S,0,D)|0,Te=(ye|0)==0,n=S,L=0,I=5642,K=Te?S+D|0:ye,S=Te?D:ye-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=j8(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,ye),!n)n=0,Ge=84;else for(L=0;;){if(D=t[S>>2]|0,!D){Ge=84;break t}if(D=j8(Pr,D)|0,L=D+L|0,(L|0)>(n|0)){Ge=84;break t}if(Y0(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,ye=(D|0)!=0|S,S=((S^1)&1)+(Pe-K)|0,n=ye?K:Me,K=Me,S=ye?(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,ye^8192),h=(h|0)>(n|0)?h:n,n=Ze;continue}Te=K-n|0,Be=(S|0)<(Te|0)?Te:S,ye=Be+L|0,h=(h|0)<(ye|0)?ye:h,_l(e,32,h,ye,D),Y0(e,I,L),_l(e,48,h,ye,D^65536),_l(e,48,Be,Te,0),Y0(e,n,Te),_l(e,32,h,ye,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(U8(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 NF(e){return e=e|0,0}function FF(e){e=e|0}function Y0(e,n,r){e=e|0,n=n|0,r=r|0,t[e>>2]&32||KF(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 U8(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 PF(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]=M[5694+(e&15)>>0]|0|u,e=A_(e|0,n|0,4)|0,n=tt;while(!((e|0)==0&(n|0)==0));return r|0}function IF(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=A_(e|0,n|0,3)|0,n=tt;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=$E(e|0,n|0,10,0)|0,r=r+-1|0,c[r>>0]=u&255|48,u=e,e=ZE(e|0,n|0,10,0)|0,n>>>0>9|(n|0)==9&u>>>0>4294967295;)n=tt;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 bF(e){return e=e|0,WF(e,t[(qF()|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 Y0(e,s,256),l=l+-256|0;while(l>>>0>255);l=n&255}Y0(e,s,l)}m=h}function j8(e,n){return e=e|0,n=n|0,e?e=zF(e,n,0)|0:e=0,e|0}function UF(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,Te=0,ye=0,Ze=0,Ge=0,ft=0,Me=0,Pe=0,Zt=0,Br=0,In=0,gn=0,_r=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,_r=L+12|0,z8(n)|0,(tt|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),z8(n)|0,gn=tt&2146435072;do if(gn>>>0<2146435072|(gn|0)==2146435072&0<0){if(Be=+jF(n,Ze)*2,h=Be!=0,h&&(t[Ze>>2]=(t[Ze>>2]|0)+-1),ft=s|32,(ft|0)==97){Te=s&32,K=(Te|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,_r)|0,(h|0)==(_r|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 gn=~~n,D=h+1|0,c[h>>0]=M[5694+gn>>0]|Te,n=(n-+(gn|0))*16,((D-Pr|0)==1?!(S&(L&n==0)):0)?(c[D>>0]=46,h=h+2|0):h=D;while(n!=0);gn=h-Pr|0,Pr=_r-k|0,_r=(u|0)!=0&(gn+-2|0)<(u|0)?u+2|0:gn,h=Pr+I+_r|0,_l(e,32,r,h,l),Y0(e,K,I),_l(e,48,r,h,l^65536),Y0(e,Ln,gn),_l(e,48,_r-gn|0,0,0),Y0(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),gn=(h|0)<0?S:S+288|0,S=gn;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=gn,I=S;;){if(k=(h|0)<29?h:29,h=I+-4|0,h>>>0>=L>>>0){S=0;do Me=Y8(t[h>>2]|0,0,k|0)|0,Me=JE(Me|0,tt|0,S|0,0)|0,Pe=tt,Ge=$E(Me|0,Pe|0,1e9,0)|0,t[h>>2]=Ge,S=ZE(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=gn;if((h|0)<0){u=((D+25|0)/9|0)+1|0,ye=(ft|0)==102;do{if(Te=0-h|0,Te=(Te|0)<9?Te:9,L>>>0>>0){k=(1<>>Te,K=0,h=L;do Pe=t[h>>2]|0,t[h>>2]=(Pe>>>Te)+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=ye?gn:L,S=(h-S>>2|0)>(u|0)?S+(u<<2)|0:h,h=(t[Ze>>2]|0)+Te|0,t[Ze>>2]=h}while((h|0)<0);h=L,u=S}else h=L,u=S;if(Pe=gn,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(ye=(ft|0)==103,Ge=(D|0)!=0,L=D-((ft|0)!=102?S:0)+((Ge&ye)<<31>>31)|0,(L|0)<(((u-Pe>>2)*9|0)+-9|0)){if(L=L+9216|0,Te=gn+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[Te>>2]|0,K=(I>>>0)%(k>>>0)|0,L=(Te+4|0)==(u|0),L&(K|0)==0)L=Te;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[Te>>2]=L,Be+n!=Be){if(Me=L+k|0,t[Te>>2]=Me,Me>>>0>999999999)for(S=Te;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=Te;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=Te;L=L+4|0,L=u>>>0>L>>>0?L:u,Me=h}else L=u,Me=h;for(ft=L;;){if(ft>>>0<=Me>>>0){Ze=0;break}if(h=ft+-4|0,!(t[h>>2]|0))ft=h;else{Ze=1;break}}u=0-S|0;do if(ye)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)Te=h;else{if(Ze?(Zt=t[ft+-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=((ft-Pe>>2)*9|0)+-9|0,(k|32|0)==102){Te=h-L|0,Te=(Te|0)>0?Te:0,D=(D|0)<(Te|0)?D:Te,Te=0;break}else{Te=h+S-L|0,Te=(Te|0)>0?Te:0,D=(D|0)<(Te|0)?D:Te,Te=0;break}}else k=s,Te=l&8;while(0);if(ye=D|Te,I=(ye|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,_r)|0,L=_r,(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),Y0(e,Br,In),_l(e,48,r,h,l^65536),K){k=Me>>>0>gn>>>0?gn:Me,Te=Ln+9|0,I=Te,K=Ln+8|0,L=k;do{if(S=Bv(t[L>>2]|0,0,Te)|0,(L|0)==(k|0))(S|0)==(Te|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)}Y0(e,S,I-S|0),L=L+4|0}while(L>>>0<=gn>>>0);if(ye|0&&Y0(e,5710,1),L>>>0>>0&(D|0)>0)for(;;){if(S=Bv(t[L>>2]|0,0,Te)|0,S>>>0>Ln>>>0){jv(Ln|0,48,S-Pr|0)|0;do S=S+-1|0;while(S>>>0>Ln>>>0)}if(Y0(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(ye=Ze?ft:Me+4|0,(D|0)>-1){Ze=Ln+9|0,Te=(Te|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,Y0(e,S,1),Te&(D|0)<1){S=L;break}Y0(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,Y0(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),Y0(e,Ge,_r-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),Y0(e,Br,In),Y0(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 z8(e){e=+e;var n=0;return B[q>>3]=e,n=t[q>>2]|0,tt=t[q+4>>2]|0,n|0}function jF(e,n){return e=+e,n=n|0,+ +H8(e,n)}function H8(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=A_(r|0,u|0,52)|0,l&2047){case 0:{e!=0?(e=+H8(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 zF(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[(HF()|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 HF(){return KE()|0}function qF(){return KE()|0}function WF(e,n){e=e|0,n=n|0;var r=0,u=0;for(u=0;;){if((M[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 VF(r,t[n+20>>2]|0)|0}function VF(e,n){return e=e|0,n=n|0,GF(e,n)|0}function GF(e,n){return e=e|0,n=n|0,n?n=YF(t[n>>2]|0,t[n+4>>2]|0,e)|0:n=0,(n|0?n:e)|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,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=I8(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=Q8(e|0)|0,((n|0)==0?e:r)|0}function KF(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:XF(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);gr(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 XF(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 Ru(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?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=W8(e)|0;do if((r&2147483647)>>>0<=2139095040){if(u=W8(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 QE(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|((QF(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 QF(e){return e=w(e),T[q>>2]=e,t[q>>2]|0|0}function JF(e,n){return e=e|0,n=n|0,b8(t[582]|0,e,n)|0}function hi(e){e=e|0,$n()}function Uv(e){e=e|0}function ZF(e,n){return e=e|0,n=n|0,0}function $F(e){return e=e|0,(V8(e+4|0)|0)==-1?(P1[t[(t[e>>2]|0)+8>>2]&127](e),e=1):e=0,e|0}function V8(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,$F(e)|0&&eP(e)}function eP(e){e=e|0;var n=0;n=e+8|0,((t[n>>2]|0)!=0?(V8(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=nP()|0,!e){e=0;break}oS[e&0]()}return e|0}function G8(e){return e=e|0,pn(e)|0}function _t(e){e=e|0,C_(e)}function tP(e){e=e|0,(c[e+11>>0]|0)<0&&_t(t[e>>2]|0)}function nP(){var e=0;return e=t[2923]|0,t[2923]=e+0,e|0}function rP(){}function R_(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,tt=u,e-r>>>0|0|0}function JE(e,n,r,u){return e=e|0,n=n|0,r=r|0,u=u|0,r=e+r>>>0,tt=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 Y8(e,n,r){return e=e|0,n=n|0,r=r|0,(r|0)<32?(tt=n<>>32-r,e<>>r,e>>>r|(n&(1<>>r-32|0)}function gr(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 K8(e){e=e|0;var n=0;return n=c[ge+(e&255)>>0]|0,(n|0)<8?n|0:(n=c[ge+(e>>8&255)>>0]|0,(n|0)<8?n+8|0:(n=c[ge+(e>>16&255)>>0]|0,(n|0)<8?n+16|0:(c[ge+(e>>>24)>>0]|0)+24|0))}function X8(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,Te=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,tt=K,l|0):(K=0,l=0,tt=K,l|0):(s&&(t[l>>2]=(k>>>0)%(h>>>0),t[l+4>>2]=0),K=0,l=(k>>>0)/(h>>>0)>>>0,tt=K,l|0);s=(D|0)==0;do if(h){if(!s){if(s=(Er(D|0)|0)-(Er(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,tt=K,l|0):(K=0,l=0,tt=K,l|0)}if(s=h-1|0,s&h|0){D=(Er(h|0)|0)+33-(Er(L|0)|0)|0,Te=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,Te=e|0|0,tt=Be,Te|0):(Te=K8(h|0)|0,Be=L>>>(Te>>>0)|0,Te=L<<32-Te|k>>>(Te>>>0)|0,tt=Be,Te|0)}else{if(s)return l|0&&(t[l>>2]=(L>>>0)%(h>>>0),t[l+4>>2]=0),Be=0,Te=(L>>>0)/(h>>>0)>>>0,tt=Be,Te|0;if(!k)return l|0&&(t[l>>2]=0,t[l+4>>2]=(L>>>0)%(D>>>0)),Be=0,Te=(L>>>0)/(D>>>0)>>>0,tt=Be,Te|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,Te=L>>>((K8(D|0)|0)>>>0),tt=Be,Te|0;if(s=(Er(D|0)|0)-(Er(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,Te=0,tt=Be,Te|0):(Be=0,Te=0,tt=Be,Te|0)}while(0);if(!h)L=D,S=0,D=0;else{I=r|0|0,k=K|u&0,L=JE(I|0,k|0,-1,-1)|0,r=tt,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,R_(L|0,r|0,u|0,K|0)|0,Te=tt,Be=Te>>31|((Te|0)<0?-1:0)<<1,D=Be&1,e=R_(u|0,K|0,Be&I|0,(((Te|0)<0?-1:0)>>31|((Te|0)<0?-1:0)<<1)&k|0)|0,n=tt,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,Te=(s<<1|0>>>31)&-2|D,tt=Be,Te|0}function ZE(e,n,r,u){return e=e|0,n=n|0,r=r|0,u=u|0,X8(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 ky(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 gr(e,n,r)|0;return e|0}function $E(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,X8(e,n,r,u,l)|0,m=s,tt=t[l+4>>2]|0,t[l>>2]|0|0}function Q8(e){return e=e|0,(e&255)<<24|(e>>8&255)<<16|(e>>16&255)<<8|e>>>24|0}function iP(e,n,r,u,l,s){e=e|0,n=n|0,r=r|0,u=u|0,l=l|0,s=s|0,J8[e&1](n|0,r|0,u|0,l|0,s|0)}function uP(e,n,r){e=e|0,n=n|0,r=w(r),Z8[e&1](n|0,w(r))}function oP(e,n,r){e=e|0,n=n|0,r=+r,$8[e&31](n|0,+r)}function lP(e,n,r,u){return e=e|0,n=n|0,r=w(r),u=w(u),w(eS[e&0](n|0,w(r),w(u)))}function sP(e,n){e=e|0,n=n|0,P1[e&127](n|0)}function aP(e,n,r){e=e|0,n=n|0,r=r|0,I1[e&31](n|0,r|0)}function fP(e,n){return e=e|0,n=n|0,Zp[e&31](n|0)|0}function cP(e,n,r,u,l){e=e|0,n=n|0,r=+r,u=+u,l=l|0,tS[e&1](n|0,+r,+u,l|0)}function dP(e,n,r,u){e=e|0,n=n|0,r=+r,u=+u,GP[e&1](n|0,+r,+u)}function pP(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 hP(e,n,r,u){return e=e|0,n=n|0,r=r|0,u=u|0,+YP[e&1](n|0,r|0,u|0)}function vP(e,n){return e=e|0,n=n|0,+nS[e&15](n|0)}function mP(e,n,r){return e=e|0,n=n|0,r=+r,KP[e&1](n|0,+r)|0}function yP(e,n,r){return e=e|0,n=n|0,r=r|0,tD[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,XP[e&1](n|0,r|0,+u,+l,s|0)}function _P(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,QP[e&1](n|0,r|0,u|0,l|0,s|0,h|0)}function EP(e,n,r){return e=e|0,n=n|0,r=r|0,+rS[e&7](n|0,r|0)}function DP(e){return e=e|0,k_[e&7]()|0}function wP(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,iS[e&1](n|0,r|0,u|0,l|0,s|0)|0}function SP(e,n,r,u,l){e=e|0,n=n|0,r=r|0,u=u|0,l=+l,JP[e&1](n|0,r|0,u|0,+l)}function TP(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,uS[e&1](n|0,r|0,w(u),l|0,w(s),h|0)}function CP(e,n,r,u){e=e|0,n=n|0,r=r|0,u=u|0,Fy[e&15](n|0,r|0,u|0)}function xP(e){e=e|0,oS[e&0]()}function RP(e,n,r,u){e=e|0,n=n|0,r=r|0,u=+u,lS[e&15](n|0,r|0,+u)}function AP(e,n,r){return e=e|0,n=+n,r=+r,ZP[e&1](+n,+r)|0}function OP(e,n,r,u,l){e=e|0,n=n|0,r=r|0,u=u|0,l=l|0,nD[e&15](n|0,r|0,u|0,l|0)}function MP(e,n,r,u,l){e=e|0,n=n|0,r=r|0,u=u|0,l=l|0,jt(0)}function kP(e,n){e=e|0,n=w(n),jt(1)}function ea(e,n){e=e|0,n=+n,jt(2)}function LP(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 Ly(e,n){e=e|0,n=n|0,jt(5)}function Na(e){return e=e|0,jt(6),0}function NP(e,n,r,u){e=e|0,n=+n,r=+r,u=u|0,jt(7)}function FP(e,n,r){e=e|0,n=+n,r=+r,jt(8)}function PP(e,n,r){return e=e|0,n=n|0,r=r|0,jt(9),0}function IP(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 bP(e,n){return e=e|0,n=+n,jt(12),0}function Ny(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 UP(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 eD(e,n){return e=e|0,n=n|0,jt(16),0}function jP(){return jt(17),0}function zP(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 HP(e,n,r,u){e=e|0,n=n|0,r=r|0,u=+u,jt(19)}function qP(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 WP(){jt(22)}function zv(e,n,r){e=e|0,n=n|0,r=+r,jt(23)}function VP(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 J8=[MP,jM],Z8=[kP,no],$8=[ea,da,Ss,Ts,ns,H0,Df,ol,Wa,ro,wf,Wc,pc,Ol,Cs,pa,od,ha,hc,ea,ea,ea,ea,ea,ea,ea,ea,ea,ea,ea,ea,ea],eS=[LP],P1=[Zn,Uv,cn,us,D0,jf,M1,jl,vO,mO,yO,RM,AM,OM,QN,JN,ZN,Ne,cc,ja,Gu,zo,yh,Tf,r1,Ff,Da,kh,ym,g1,_1,Zh,mp,Pd,jm,C1,Oc,Jm,ey,xv,Mv,on,$4,fE,p_,Nt,xu,to,OR,VR,fA,AA,qA,f7,E7,S7,j7,q7,oO,_O,wO,UO,rM,_d,Bk,vL,ML,VL,hN,ON,jN,qN,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=[Ly,D2,rd,qc,Rl,ul,w2,Ws,Al,za,Ha,qa,Ml,ze,lt,$t,Wn,si,ur,Va,T2,_h,pE,gE,LA,zk,cM,D8,Ly,Ly,Ly,Ly],Zp=[Na,RF,Ef,y,J,de,gt,xt,Lt,xr,du,Ho,Ga,ld,Xc,ks,YA,HO,Vk,Ma,Na,Na,Na,Na,Na,Na,Na,Na,Na,Na,Na,Na],tS=[NP,R2],GP=[FP,aO],M_=[PP,P8,AF,kF,Wh,vv,NR,QL],YP=[IP,fv],nS=[Jp,uo,Ve,ci,gh,al,va,A2,O2,vc,Jp,Jp,Jp,Jp,Jp,Jp],KP=[bP,y7],tD=[Ny,ZF,S2,dl,W2,xm,dp,Ap,ty,kr,j0,FL,Ny,Ny,Ny,Ny],XP=[BP,xh],QP=[UP,gN],rS=[eD,Qi,M2,pd,Qc,ml,eD,eD],k_=[jP,Jc,u0,wo,R7,Y7,xO,YN],iS=[zP,li],JP=[HP,vy],uS=[qP,sd],Fy=[O_,R,io,Gr,Cu,m1,Fd,ar,_y,m0,ak,_L,NN,O_,O_,O_],oS=[WP],lS=[zv,id,y0,ud,z0,Vc,qi,g,jp,XR,p7,zv,zv,zv,zv,zv],ZP=[VP,pO],nD=[Hv,wp,Fc,hA,n7,N7,$7,NO,sM,Jk,iF,Hv,Hv,Hv,Hv,Hv];return{_llvm_bswap_i32:Q8,dynCall_idd:AP,dynCall_i:DP,_i64Subtract:R_,___udivdi3:ZE,dynCall_vif:uP,setThrew:ms,dynCall_viii:CP,_bitshift64Lshr:A_,_bitshift64Shl:Y8,dynCall_vi:sP,dynCall_viiddi:gP,dynCall_diii:hP,dynCall_iii:yP,_memset:jv,_sbrk:n2,_memcpy:gr,__GLOBAL__sub_I_Yoga_cpp:ru,dynCall_vii:aP,___uremdi3:$E,dynCall_vid:oP,stackAlloc:d0,_nbind_init:vF,getTempRet0:Q,dynCall_di:vP,dynCall_iid:mP,setTempRet0:Bo,_i64Add:JE,dynCall_fiff:lP,dynCall_iiii:pP,_emscripten_get_global_libc:xF,dynCall_viid:RP,dynCall_viiid:SP,dynCall_viififi:TP,dynCall_ii:fP,__GLOBAL__sub_I_Binding_cc:Mk,dynCall_viiii:OP,dynCall_iiiiii:wP,stackSave:nl,dynCall_viiiii:iP,__GLOBAL__sub_I_nbind_cc:Vs,dynCall_vidd:dP,_free:C_,runPostSets:rP,dynCall_viiiiii:_P,establishStackSpace:ju,_memmove:ky,stackRestore:Zl,_malloc:T_,__GLOBAL__sub_I_common_cc:QO,dynCall_viddi:cP,dynCall_dii:EP,dynCall_v:xP}}(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 O=0;O<4-1;O++)_.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,ST)=>{"use strict";var WI=DT(),VI=wT(),UD=!1,jD=null;VI({},function(i,o){if(!UD){if(UD=!0,i)throw i;jD=o}});if(!UD)throw new Error("Failed to load the yoga module - it needed to be loaded synchronously, but didn't");ST.exports=WI(jD.bind,jD.lib)});var CT=Ke((GW,TT)=>{"use strict";TT.exports=({onlyFirst:i=!1}={})=>{let o=["[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]+)*|[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 zD=Ke((YW,xT)=>{"use strict";var GI=CT();xT.exports=i=>typeof i=="string"?i.replace(GI(),""):i});var qD=Ke((KW,HD)=>{"use strict";var RT=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);HD.exports=RT;HD.exports.default=RT});var OT=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,WD)=>{"use strict";var YI=zD(),KI=qD(),XI=OT(),MT=i=>{if(i=i.replace(XI()," "),typeof i!="string"||i.length===0)return 0;i=YI(i);let o=0;for(let a=0;a=127&&c<=159||c>=768&&c<=879||(c>65535&&a++,o+=KI(c)?2:1)}return o};WD.exports=MT;WD.exports.default=MT});var GD=Ke((JW,VD)=>{"use strict";var QI=Z_(),kT=i=>{let o=0;for(let a of i.split(` -`))o=Math.max(o,QI(a));return o};VD.exports=kT;VD.exports.default=kT});var LT=Ke(Jy=>{"use strict";var JI=Jy&&Jy.__importDefault||function(i){return i&&i.__esModule?i:{default:i}};Object.defineProperty(Jy,"__esModule",{value:!0});var ZI=JI(GD()),YD={};Jy.default=i=>{if(i.length===0)return{width:0,height:0};if(YD[i])return YD[i];let o=ZI.default(i),a=i.split(` -`).length;return YD[i]={width:o,height:a},{width:o,height:a}}});var NT=Ke(Zy=>{"use strict";var $I=Zy&&Zy.__importDefault||function(i){return i&&i.__esModule?i:{default:i}};Object.defineProperty(Zy,"__esModule",{value:!0});var Vi=$I(eh()),eb=(i,o)=>{"position"in o&&i.setPositionType(o.position==="absolute"?Vi.default.POSITION_TYPE_ABSOLUTE:Vi.default.POSITION_TYPE_RELATIVE)},tb=(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)},nb=(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)},rb=(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))},ib=(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))},ub=(i,o)=>{"display"in o&&i.setDisplay(o.display==="flex"?Vi.default.DISPLAY_FLEX:Vi.default.DISPLAY_NONE)},ob=(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)}};Zy.default=(i,o={})=>{eb(i,o),tb(i,o),nb(i,o),rb(i,o),ib(i,o),ub(i,o),ob(i,o)}});var PT=Ke((eV,FT)=>{"use strict";FT.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 KD=Ke((tV,IT)=>{var $y=PT(),bT={};for(let i of Object.keys($y))bT[$y[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"]}};IT.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),M=t-_,N,O;t===_?N=0:o===t?N=(a-c)/M:a===t?N=2+(c-o)/M:c===t&&(N=4+(o-a)/M),N=Math.min(N*60,360),N<0&&(N+=360);let T=(_+t)/2;return t===_?O=0:T<=.5?O=M/(t+_):O=M/(2-t-_),[N,O*100,T*100]};zn.rgb.hsv=function(i){let o,a,c,_,t,M=i[0]/255,N=i[1]/255,O=i[2]/255,T=Math.max(M,N,O),B=T-Math.min(M,N,O),H=function(q){return(T-q)/6/B+1/2};return B===0?(_=0,t=0):(t=B/T,o=H(M),a=H(N),c=H(O),M===T?_=c-a:N===T?_=1/3+o-c:O===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,M=(1-a-_)/(1-_)||0,N=(1-c-_)/(1-_)||0;return[t*100,M*100,N*100,_*100]};function lb(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=bT[i];if(o)return o;let a=Infinity,c;for(let _ of Object.keys($y)){let t=$y[_],M=lb(i,t);M.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,M=o*.0193+a*.1192+c*.9505;return[_*100,t*100,M*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,M=500*(a-c),N=200*(c-_);return[t,M,N]};zn.hsl.rgb=function(i){let o=i[0]/360,a=i[1]/100,c=i[2]/100,_,t,M;if(a===0)return M=c*255,[M,M,M];c<.5?_=c*(1+a):_=c+a-c*a;let N=2*c-_,O=[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?M=N+(_-N)*6*t:2*t<1?M=_:3*t<2?M=N+(_-N)*(2/3-t)*6:M=N,O[T]=M*255;return O};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 M=(c+a)/2,N=c===0?2*_/(t+_):2*a/(c+a);return[o,N*100,M*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),M=255*c*(1-a),N=255*c*(1-a*t),O=255*c*(1-a*(1-t));switch(c*=255,_){case 0:return[c,O,M];case 1:return[N,c,M];case 2:return[M,c,O];case 3:return[M,N,c];case 4:return[O,M,c];case 5:return[c,M,N]}};zn.hsv.hsl=function(i){let o=i[0],a=i[1]/100,c=i[2]/100,_=Math.max(c,.01),t,M;M=(2-a)*c;let N=(2-a)*_;return t=a*_,t/=N<=1?N:2-N,t=t||0,M/=2,[o,t*100,M*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 M=Math.floor(6*o),N=1-c;t=6*o-M,(M&1)!=0&&(t=1-t);let O=a+t*(N-a),T,B,H;switch(M){default:case 6:case 0:T=N,B=O,H=a;break;case 1:T=O,B=N,H=a;break;case 2:T=a,B=N,H=O;break;case 3:T=a,B=O,H=N;break;case 4:T=O,B=a,H=N;break;case 5:T=N,B=a,H=O;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-_)+_),M=1-Math.min(1,a*(1-_)+_),N=1-Math.min(1,c*(1-_)+_);return[t*255,M*255,N*255]};zn.xyz.rgb=function(i){let o=i[0]/100,a=i[1]/100,c=i[2]/100,_,t,M;return _=o*3.2406+a*-1.5372+c*-.4986,t=o*-.9689+a*1.8758+c*.0415,M=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,M=M>.0031308?1.055*M**(1/2.4)-.055:M*12.92,_=Math.min(Math.max(0,_),1),t=Math.min(Math.max(0,t),1),M=Math.min(Math.max(0,M),1),[_*255,t*255,M*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),M=200*(a-c);return[_,t,M]};zn.lab.xyz=function(i){let o=i[0],a=i[1],c=i[2],_,t,M;t=(o+16)/116,_=a/500+t,M=t-c/200;let N=t**3,O=_**3,T=M**3;return t=N>.008856?N:(t-16/116)/7.787,_=O>.008856?O:(_-16/116)/7.787,M=T>.008856?T:(M-16/116)/7.787,_*=95.047,t*=100,M*=108.883,[_,t,M]};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 M=Math.sqrt(a*a+c*c);return[o,M,_]};zn.lch.lab=function(i){let o=i[0],a=i[1],_=i[2]/360*2*Math.PI,t=a*Math.cos(_),M=a*Math.sin(_);return[o,t,M]};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 M=30+(Math.round(_/255)<<2|Math.round(c/255)<<1|Math.round(a/255));return t===2&&(M+=60),M};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,M=c&255;return[_,t,M]};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),M=_-t,N,O;return M<1?N=t/(1-M):N=0,M<=0?O=0:_===o?O=(a-c)/M%6:_===a?O=2+(c-o)/M:O=4+(o-a)/M,O/=6,O%=1,[O*360,M*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,M=t%1,N=1-M,O=0;switch(Math.floor(t)){case 0:_[0]=1,_[1]=M,_[2]=0;break;case 1:_[0]=N,_[1]=1,_[2]=0;break;case 2:_[0]=0,_[1]=1,_[2]=M;break;case 3:_[0]=0,_[1]=N,_[2]=1;break;case 4:_[0]=M,_[1]=0,_[2]=1;break;default:_[0]=1,_[1]=0,_[2]=N}return O=(1-a)*c,[(a*_[0]+O)*255,(a*_[1]+O)*255,(a*_[2]+O)*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 UT=Ke((nV,BT)=>{var $_=KD();function sb(){let i={},o=Object.keys($_);for(let a=o.length,c=0;c{var XD=KD(),db=UT(),Qv={},pb=Object.keys(XD);function hb(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 vb(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,M=0;M{Qv[i]={},Object.defineProperty(Qv[i],"channels",{value:XD[i].channels}),Object.defineProperty(Qv[i],"labels",{value:XD[i].labels});let o=db(i);Object.keys(o).forEach(c=>{let _=o[c];Qv[i][c]=vb(_),Qv[i][c].raw=hb(_)})});jT.exports=Qv});var t4=Ke((iV,HT)=>{"use strict";var qT=(i,o)=>(...a)=>`[${i(...a)+o}m`,WT=(i,o)=>(...a)=>{let c=i(...a);return`[${38+o};5;${c}m`},VT=(i,o)=>(...a)=>{let c=i(...a);return`[${38+o};2;${c[0]};${c[1]};${c[2]}m`},e4=i=>i,GT=(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})},QD,Zv=(i,o,a,c)=>{QD===void 0&&(QD=zT());let _=c?10:0,t={};for(let[M,N]of Object.entries(QD)){let O=M==="ansi16"?"ansi":M;M===o?t[O]=i(a,_):typeof N=="object"&&(t[O]=i(N[o],_))}return t};function mb(){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(qT,"ansi16",e4,!1)),Jv(o.color,"ansi256",()=>Zv(WT,"ansi256",e4,!1)),Jv(o.color,"ansi16m",()=>Zv(VT,"rgb",GT,!1)),Jv(o.bgColor,"ansi",()=>Zv(qT,"ansi16",e4,!0)),Jv(o.bgColor,"ansi256",()=>Zv(WT,"ansi256",e4,!0)),Jv(o.bgColor,"ansi16m",()=>Zv(VT,"rgb",GT,!0)),o}Object.defineProperty(HT,"exports",{enumerable:!0,get:mb})});var XT=Ke((uV,YT)=>{"use strict";var eg=Z_(),yb=zD(),gb=t4(),JD=new Set(["","\x9B"]),_b=39,KT=i=>`${JD.values().next().value}[${i}m`,Eb=i=>i.split(" ").map(o=>eg(o)),ZD=(i,o,a)=>{let c=[...o],_=!1,t=eg(yb(i[i.length-1]));for(let[M,N]of c.entries()){let O=eg(N);if(t+O<=a?i[i.length-1]+=N:(i.push(N),t=0),JD.has(N))_=!0;else if(_&&N==="m"){_=!1;continue}_||(t+=O,t===a&&M0&&i.length>1&&(i[i.length-2]+=i.pop())},Db=i=>{let o=i.split(" "),a=o.length;for(;a>0&&!(eg(o[a-1])>0);)a--;return a===o.length?i:o.slice(0,a).join(" ")+o.slice(a).join("")},wb=(i,o,a={})=>{if(a.trim!==!1&&i.trim()==="")return"";let c="",_="",t,M=Eb(i),N=[""];for(let[O,T]of i.split(" ").entries()){a.trim!==!1&&(N[N.length-1]=N[N.length-1].trimLeft());let B=eg(N[N.length-1]);if(O!==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&&M[O]>o){let H=o-B,q=1+Math.floor((M[O]-H-1)/o);Math.floor((M[O]-1)/o)o&&B>0&&M[O]>0){if(a.wordWrap===!1&&Bo&&a.wordWrap===!1){ZD(N,T,o);continue}N[N.length-1]+=T}a.trim!==!1&&(N=N.map(Db)),c=N.join(` -`);for(let[O,T]of[...c].entries()){if(_+=T,JD.has(T)){let H=parseFloat(/\d[^m]*/.exec(c.slice(O,O+4)));t=H===_b?null:H}let B=gb.codes.get(Number(t));t&&B&&(c[O+1]===` -`?_+=KT(B):T===` -`&&(_+=KT(t)))}return _};YT.exports=(i,o,a)=>String(i).normalize().replace(/\r\n/g,` -`).split(` -`).map(c=>wb(c,o,a)).join(` -`)});var ZT=Ke((oV,QT)=>{"use strict";var JT="[\uD800-\uDBFF][\uDC00-\uDFFF]",Sb=i=>i&&i.exact?new RegExp(`^${JT}$`):new RegExp(JT,"g");QT.exports=Sb});var $D=Ke((lV,$T)=>{"use strict";var Tb=qD(),Cb=ZT(),eC=t4(),tC=["","\x9B"],n4=i=>`${tC[0]}[${i}m`,nC=(i,o,a)=>{let c=[];i=[...i];for(let _ of i){let t=_;_.match(";")&&(_=_.split(";")[0][0]+"0");let M=eC.codes.get(parseInt(_,10));if(M){let N=i.indexOf(M.toString());N>=0?i.splice(N,1):c.push(n4(o?M: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(eC.codes.get(parseInt(a,10)));c=c.reduce((t,M)=>M===_?[M,...t]:[...t,M],[])}return c.join("")};$T.exports=(i,o,a)=>{let c=[...i.normalize()],_=[];a=typeof a=="number"?a:c.length;let t=!1,M,N=0,O="";for(let[T,B]of c.entries()){let H=!1;if(tC.includes(B)){let q=/\d[^m]*/.exec(i.slice(T,T+18));M=q&&q.length>0?q[0]:void 0,No&&N<=a)O+=B;else if(N===o&&!t&&M!==void 0)O=nC(_);else if(N>=a){O+=nC(_,!0,M);break}}return O}});var iC=Ke((sV,rC)=>{"use strict";var p2=$D(),xb=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}rC.exports=(i,o,a)=>{a=qt({position:"end",preferTruncationOnSpace:!1},a);let{position:c,space:_,preferTruncationOnSpace:t}=a,M="\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 M;let O=xb(i);if(O<=o)return i;if(c==="start"){if(t){let T=r4(i,O-o+1,!0);return M+p2(i,T,O).trim()}return _===!0&&(M+=" ",N=2),M+p2(i,O-o+N,O)}if(c==="middle"){_===!0&&(M=" "+M+" ",N=3);let T=Math.floor(o/2);if(t){let B=r4(i,T),H=r4(i,O-(o-T)+1,!0);return p2(i,0,B)+M+p2(i,H,O).trim()}return p2(i,0,T)+M+p2(i,O-(o-T)+N,O)}if(c==="end"){if(t){let T=r4(i,o-1);return p2(i,0,T)+M}return _===!0&&(M=" "+M,N=2),p2(i,0,o-N)+M}throw new Error(`Expected \`options.position\` to be either \`start\`, \`middle\` or \`end\`, got ${c}`)}});var tw=Ke(tg=>{"use strict";var uC=tg&&tg.__importDefault||function(i){return i&&i.__esModule?i:{default:i}};Object.defineProperty(tg,"__esModule",{value:!0});var Rb=uC(XT()),Ab=uC(iC()),ew={};tg.default=(i,o,a)=>{let c=i+String(o)+String(a);if(ew[c])return ew[c];let _=i;if(a==="wrap"&&(_=Rb.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 ew[c]=_,_}});var rw=Ke(nw=>{"use strict";Object.defineProperty(nw,"__esModule",{value:!0});var oC=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=oC(a)),c.length>0&&typeof a.internal_transform=="function"&&(c=a.internal_transform(c))),o+=c}return o};nw.default=oC});var iw=Ke(co=>{"use strict";var ng=co&&co.__importDefault||function(i){return i&&i.__esModule?i:{default:i}};Object.defineProperty(co,"__esModule",{value:!0});co.setTextNodeValue=co.createTextNode=co.setStyle=co.setAttribute=co.removeChildNode=co.insertBeforeNode=co.appendChildNode=co.createNode=co.TEXT_NAME=void 0;var Ob=ng(eh()),lC=ng(LT()),Mb=ng(NT()),kb=ng(tw()),Lb=ng(rw());co.TEXT_NAME="#text";co.createNode=i=>{var o;let a={nodeName:i,style:{},attributes:{},childNodes:[],parentNode:null,yogaNode:i==="ink-virtual-text"?void 0:Ob.default.Node.create()};return i==="ink-text"&&((o=a.yogaNode)===null||o===void 0||o.setMeasureFunc(Nb.bind(null,a))),a};co.appendChildNode=(i,o)=>{var a;o.parentNode&&co.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)};co.insertBeforeNode=(i,o,a)=>{var c,_;o.parentNode&&co.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)};co.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)};co.setAttribute=(i,o,a)=>{i.attributes[o]=a};co.setStyle=(i,o)=>{i.style=o,i.yogaNode&&Mb.default(i.yogaNode,o)};co.createTextNode=i=>{let o={nodeName:"#text",nodeValue:i,yogaNode:void 0,parentNode:null,style:{}};return co.setTextNodeValue(o,i),o};var Nb=function(i,o){var a,c;let _=i.nodeName==="#text"?i.nodeValue:Lb.default(i),t=lC.default(_);if(t.width<=o||t.width>=1&&o>0&&o<1)return t;let M=(c=(a=i.style)===null||a===void 0?void 0:a.textWrap)!==null&&c!==void 0?c:"wrap",N=kb.default(_,o,M);return lC.default(N)},sC=i=>{var o;if(!(!i||!i.parentNode))return(o=i.yogaNode)!==null&&o!==void 0?o:sC(i.parentNode)},i4=i=>{let o=sC(i);o==null||o.markDirty()};co.setTextNodeValue=(i,o)=>{typeof o!="string"&&(o=String(o)),i.nodeValue=o,i4(i)}});var th=Ke((dV,aC)=>{"use strict";aC.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 rg=Ke((pV,uw)=>{"use strict";var{EMPTY_BUFFER:Fb}=th();function fC(i,o){if(i.length===0)return Fb;if(i.length===1)return i[0];let a=Buffer.allocUnsafe(o),c=0;for(let _=0;_{"use strict";var vC=Symbol("kDone"),ow=Symbol("kRun"),mC=class{constructor(o){this[vC]=()=>{this.pending--,this[ow]()},this.concurrency=o||Infinity,this.jobs=[],this.pending=0}add(o){this.jobs.push(o),this[ow]()}[ow](){if(this.pending!==this.concurrency&&this.jobs.length){let o=this.jobs.shift();this.pending++,o(this[vC])}}};hC.exports=mC});var og=Ke((vV,gC)=>{"use strict";var ig=require("zlib"),_C=rg(),Pb=yC(),{kStatusCode:EC,NOOP:Ib}=th(),bb=Buffer.from([0,0,255,255]),o4=Symbol("permessage-deflate"),X1=Symbol("total-length"),ug=Symbol("callback"),h2=Symbol("buffers"),lw=Symbol("error"),l4,DC=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 Pb(_)}}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[ug];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,M)=>{_(),c(t,M)})})}compress(o,a,c){l4.add(_=>{this._compress(o,a,(t,M)=>{_(),c(t,M)})})}_decompress(o,a,c){let _=this._isServer?"client":"server";if(!this._inflate){let t=`${_}_max_window_bits`,M=typeof this.params[t]!="number"?ig.Z_DEFAULT_WINDOWBITS:this.params[t];this._inflate=ig.createInflateRaw(Zr(qt({},this._options.zlibInflateOptions),{windowBits:M})),this._inflate[o4]=this,this._inflate[X1]=0,this._inflate[h2]=[],this._inflate.on("error",Ub),this._inflate.on("data",wC)}this._inflate[ug]=c,this._inflate.write(o),a&&this._inflate.write(bb),this._inflate.flush(()=>{let t=this._inflate[lw];if(t){this._inflate.close(),this._inflate=null,c(t);return}let M=_C.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,M)})}_compress(o,a,c){let _=this._isServer?"server":"client";if(!this._deflate){let t=`${_}_max_window_bits`,M=typeof this.params[t]!="number"?ig.Z_DEFAULT_WINDOWBITS:this.params[t];this._deflate=ig.createDeflateRaw(Zr(qt({},this._options.zlibDeflateOptions),{windowBits:M})),this._deflate[X1]=0,this._deflate[h2]=[],this._deflate.on("error",Ib),this._deflate.on("data",Bb)}this._deflate[ug]=c,this._deflate.write(o),this._deflate.flush(ig.Z_SYNC_FLUSH,()=>{if(!this._deflate)return;let t=_C.concat(this._deflate[h2],this._deflate[X1]);a&&(t=t.slice(0,t.length-4)),this._deflate[ug]=null,this._deflate[X1]=0,this._deflate[h2]=[],a&&this.params[`${_}_no_context_takeover`]&&this._deflate.reset(),c(null,t)})}};gC.exports=DC;function Bb(i){this[h2].push(i),this[X1]+=i.length}function wC(i){if(this[X1]+=i.length,this[o4]._maxPayload<1||this[X1]<=this[o4]._maxPayload){this[h2].push(i);return}this[lw]=new RangeError("Max payload size exceeded"),this[lw][EC]=1009,this.removeListener("data",wC),this.reset()}function Ub(i){this[o4]._inflate=null,i[EC]=1007,this[ug](i)}});var aw=Ke((mV,sw)=>{"use strict";function SC(i){return i>=1e3&&i<=1014&&i!==1004&&i!==1005&&i!==1006||i>=3e3&&i<=4999}function TC(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),sw.exports={isValidStatusCode:SC,isValidUTF8(o){return o.length<150?TC(o):i(o)}}}catch(i){sw.exports={isValidStatusCode:SC,isValidUTF8:TC}}});var dw=Ke((yV,CC)=>{"use strict";var{Writable:jb}=require("stream"),xC=og(),{BINARY_TYPES:zb,EMPTY_BUFFER:Hb,kStatusCode:qb,kWebSocket:Wb}=th(),{concat:fw,toArrayBuffer:Vb,unmask:Gb}=rg(),{isValidStatusCode:Yb,isValidUTF8:RC}=aw(),lg=0,AC=1,OC=2,MC=3,cw=4,Kb=5,kC=class extends jb{constructor(o,a,c,_){super();this._binaryType=o||zb[0],this[Wb]=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=lg,this._loop=!1}_write(o,a,c){if(this._opcode===8&&this._state==lg)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 lg:a=this.getInfo();break;case AC:a=this.getPayloadLength16();break;case OC:a=this.getPayloadLength64();break;case MC:this.getMask();break;case cw: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,K0(RangeError,"RSV2 and RSV3 must be clear",!0,1002);let a=(o[0]&64)==64;if(a&&!this._extensions[xC.extensionName])return this._loop=!1,K0(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,K0(RangeError,"RSV1 must be clear",!0,1002);if(!this._fragmented)return this._loop=!1,K0(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,K0(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,K0(RangeError,"FIN must be set",!0,1002);if(a)return this._loop=!1,K0(RangeError,"RSV1 must be clear",!0,1002);if(this._payloadLength>125)return this._loop=!1,K0(RangeError,`invalid payload length ${this._payloadLength}`,!0,1002)}else return this._loop=!1,K0(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,K0(RangeError,"MASK must be set",!0,1002)}else if(this._masked)return this._loop=!1,K0(RangeError,"MASK must be clear",!0,1002);if(this._payloadLength===126)this._state=AC;else if(this._payloadLength===127)this._state=OC;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,K0(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,K0(RangeError,"Max payload size exceeded",!1,1009);this._masked?this._state=MC:this._state=cw}getMask(){if(this._bufferedBytes<4){this._loop=!1;return}this._mask=this.consume(4),this._state=cw}getData(o){let a=Hb;if(this._payloadLength){if(this._bufferedBytes7)return this.controlMessage(a);if(this._compressed){this._state=Kb,this.decompress(a,o);return}return a.length&&(this._messageLength=this._totalPayloadLength,this._fragments.push(a)),this.dataMessage()}decompress(o,a){this._extensions[xC.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(K0(RangeError,"Max payload size exceeded",!1,1009));this._fragments.push(t)}let M=this.dataMessage();if(M)return a(M);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=fw(a,o):this._binaryType==="arraybuffer"?c=Vb(fw(a,o)):c=a,this.emit("message",c)}else{let c=fw(a,o);if(!RC(c))return this._loop=!1,K0(Error,"invalid UTF-8 sequence",!0,1007);this.emit("message",c.toString())}}this._state=lg}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 K0(RangeError,"invalid payload length 1",!0,1002);{let a=o.readUInt16BE(0);if(!Yb(a))return K0(RangeError,`invalid status code ${a}`,!0,1002);let c=o.slice(2);if(!RC(c))return K0(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=lg}};CC.exports=kC;function K0(i,o,a,c){let _=new i(a?`Invalid WebSocket frame: ${o}`:o);return Error.captureStackTrace(_,K0),_[qb]=c,_}});var pw=Ke((gV,LC)=>{"use strict";var{randomFillSync:Xb}=require("crypto"),NC=og(),{EMPTY_BUFFER:Qb}=th(),{isValidStatusCode:Jb}=aw(),{mask:FC,toBuffer:Q1}=rg(),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 M=Buffer.allocUnsafe(c?o.length+_:_);return M[0]=a.fin?a.opcode|128:a.opcode,a.rsv1&&(M[0]|=64),M[1]=t,t===126?M.writeUInt16BE(o.length,2):t===127&&(M.writeUInt32BE(0,2),M.writeUInt32BE(o.length,6)),a.mask?(Xb(nh,0,4),M[1]|=128,M[_-4]=nh[0],M[_-3]=nh[1],M[_-2]=nh[2],M[_-1]=nh[3],c?(FC(o,nh,M,_,o.length),[M]):(FC(o,nh,o,0,o.length),[M,o])):[M,o]}close(o,a,c,_){let t;if(o===void 0)t=Qb;else{if(typeof o!="number"||!Jb(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 M=Buffer.byteLength(a);if(M>123)throw new RangeError("The message must not be greater than 123 bytes");t=Buffer.allocUnsafe(2+M),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[NC.extensionName],M=a.binary?2:1,N=a.compress;if(this._firstFragment?(this._firstFragment=!1,N&&t&&(N=_.length>=t._threshold),this._compress=N):(N=!1,M=0),a.fin&&(this._firstFragment=!0),t){let O={fin:a.fin,rsv1:N,opcode:M,mask:a.mask,readOnly:Q1.readOnly};this._deflating?this.enqueue([this.dispatch,_,this._compress,O,c]):this.dispatch(_,this._compress,O,c)}else this.sendFrame(J1.frame(_,{fin:a.fin,rsv1:!1,opcode:M,mask:a.mask,readOnly:Q1.readOnly}),c)}dispatch(o,a,c,_){if(!a){this.sendFrame(J1.frame(o,c),_);return}let t=this._extensions[NC.extensionName];this._bufferedBytes+=o.length,this._deflating=!0,t.compress(o,c.fin,(M,N)=>{if(this._socket.destroyed){let O=new Error("The socket was closed while data was being compressed");typeof _=="function"&&_(O);for(let T=0;T{"use strict";var sg=class{constructor(o,a){this.target=a,this.type=o}},IC=class extends sg{constructor(o,a){super("message",a);this.data=o}},bC=class extends sg{constructor(o,a,c){super("close",c);this.wasClean=c._closeFrameReceived&&c._closeFrameSent,this.reason=a,this.code=o}},BC=class extends sg{constructor(o){super("open",o)}},UC=class extends sg{constructor(o,a){super("error",a);this.message=o.message,this.error=o}},Zb={addEventListener(i,o,a){if(typeof o!="function")return;function c(O){o.call(this,new IC(O,this))}function _(O,T){o.call(this,new bC(O,T,this))}function t(O){o.call(this,new UC(O,this))}function M(){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"?(M._listener=o,this[N](i,M)):this[N](i,o)},removeEventListener(i,o){let a=this.listeners(i);for(let c=0;c{"use strict";var ag=[0,0,0,0,0,0,0,0,0,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 $b(i){let o=Object.create(null);if(i===void 0||i==="")return o;let a=Object.create(null),c=!1,_=!1,t=!1,M,N,O=-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(M=>M===!0?_:`${_}=${M}`).join("; ")})).join("; ")).join(", ")}).join(", ")}zC.exports={format:eB,parse:$b}});var _w=Ke((DV,HC)=>{"use strict";var tB=require("events"),nB=require("https"),rB=require("http"),qC=require("net"),iB=require("tls"),{randomBytes:uB,createHash:oB}=require("crypto"),{URL:vw}=require("url"),v2=og(),lB=dw(),sB=pw(),{BINARY_TYPES:WC,EMPTY_BUFFER:mw,GUID:aB,kStatusCode:fB,kWebSocket:na,NOOP:VC}=th(),{addEventListener:cB,removeEventListener:dB}=jC(),{format:pB,parse:hB}=hw(),{toBuffer:vB}=rg(),GC=["CONNECTING","OPEN","CLOSING","CLOSED"],yw=[8,13],mB=30*1e3,Gi=class extends tB{constructor(o,a,c){super();this._binaryType=WC[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),YC(this,o,a,c)):this._isServer=!0}get binaryType(){return this._binaryType}set binaryType(o){!WC.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 lB(this.binaryType,this._extensions,this._isServer,c);this._sender=new sB(o,this._extensions),this._receiver=_,this._socket=o,_[na]=this,o[na]=this,_.on("conclude",yB),_.on("drain",gB),_.on("error",_B),_.on("message",EB),_.on("ping",DB),_.on("pong",wB),o.setTimeout(0),o.setNoDelay(),a.length>0&&o.unshift(a),o.on("close",KC),o.on("data",s4),o.on("end",XC),o.on("error",QC),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),mB)}}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){gw(this,o,c);return}a===void 0&&(a=!this._isServer),this._sender.ping(o||mw,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){gw(this,o,c);return}a===void 0&&(a=!this._isServer),this._sender.pong(o||mw,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){gw(this,o,c);return}let _=qt({binary:typeof o!="string",mask:!this._isServer,compress:!0,fin:!0},a);this._extensions[v2.extensionName]||(_.compress=!1),this._sender.send(o||mw,_,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())}}};GC.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,pe=ne.statusCode;if(m&&_.followRedirects&&pe>=300&&pe<400){if(++i._redirects>_.maxRedirects){Z1(i,q,"Maximum redirects exceeded");return}q.abort();let ge=new vw(m,o);YC(i,ge,a,c)}else i.emit("unexpected-response",q,ne)||Z1(i,q,`Unexpected server response: ${ne.statusCode}`)}),q.on("upgrade",(ne,m,pe)=>{if(i.emit("upgrade",ne),i.readyState!==Gi.CONNECTING)return;q=i._req=null;let ge=oB("sha1").update(T+aB).digest("base64");if(ne.headers["sec-websocket-accept"]!==ge){Z1(i,m,"Invalid Sec-WebSocket-Accept header");return}let ve=ne.headers["sec-websocket-protocol"],ue=(a||"").split(/, */),_e;if(!a&&ve?_e="Server sent a subprotocol but none was requested":a&&!ve?_e="Server sent no subprotocol":ve&&!ue.includes(ve)&&(_e="Server sent an invalid subprotocol"),_e){Z1(i,m,_e);return}if(ve&&(i._protocol=ve),H)try{let ce=hB(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,pe,_.maxPayload)})}function SB(i){return i.path=i.socketPath,qC.connect(i)}function TB(i){return i.path=void 0,!i.servername&&i.servername!==""&&(i.servername=qC.isIP(i.host)?"":i.host),iB.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 gw(i,o,a){if(o){let c=vB(o).length;i._socket?i._sender._bufferedBytes+=c:i._bufferedAmount+=c}if(a){let c=new Error(`WebSocket is not open: readyState ${i.readyState} (${GC[i.readyState]})`);a(c)}}function yB(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 _B(i){let o=this[na];o._socket.removeListener("data",s4),o._readyState=Gi.CLOSING,o._closeCode=i[fB],o.emit("error",i),o._socket.destroy()}function JC(){this[na].emitClose()}function EB(i){this[na].emit("message",i)}function DB(i){let o=this[na];o.pong(i,!o._isServer,VC),o.emit("ping",i)}function wB(i){this[na].emit("pong",i)}function KC(){let i=this[na];this.removeListener("close",KC),this.removeListener("end",XC),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",JC),i._receiver.on("finish",JC))}function s4(i){this[na]._receiver.write(i)||this.pause()}function XC(){let i=this[na];i._readyState=Gi.CLOSING,i._receiver.end(),this.end()}function QC(){let i=this[na];this.removeListener("error",QC),this.on("error",VC),i&&(i._readyState=Gi.CLOSING,this.destroy())}});var t6=Ke((wV,ZC)=>{"use strict";var{Duplex:CB}=require("stream");function $C(i){i.emit("close")}function xB(){!this.destroyed&&this._writableState.finished&&this.destroy()}function e6(i){this.removeListener("error",e6),this.destroy(),this.listenerCount("error")===0&&this.emit("error",i)}function RB(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 CB(Zr(qt({},o),{autoDestroy:!1,emitClose:!1,objectMode:!1,writableObjectMode:!1}));return i.on("message",function(M){_.push(M)||(a=!1,i._socket.pause())}),i.once("error",function(M){_.destroyed||_.destroy(M)}),i.once("close",function(){_.destroyed||_.push(null)}),_._destroy=function(t,M){if(i.readyState===i.CLOSED){M(t),process.nextTick($C,_);return}let N=!1;i.once("error",function(T){N=!0,M(T)}),i.once("close",function(){N||M(t),process.nextTick($C,_)}),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,M,N){if(i.readyState===i.CONNECTING){i.once("open",function(){_._write(t,M,N)});return}i.send(t,N)},_.on("end",xB),_.on("error",e6),_}ZC.exports=RB});var i6=Ke((SV,n6)=>{"use strict";var AB=require("events"),{createHash:OB}=require("crypto"),{createServer:MB,STATUS_CODES:Ew}=require("http"),rh=og(),kB=_w(),{format:LB,parse:NB}=hw(),{GUID:FB,kWebSocket:PB}=th(),IB=/^[+/0-9A-Za-z]{22}==$/,r6=class extends AB{constructor(o,a){super();if(o=qt({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=MB((c,_)=>{let t=Ew[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=bB(this._server,{listening:this.emit.bind(this,"listening"),error:this.emit.bind(this,"error"),upgrade:(_,t,M)=>{this.handleUpgrade(_,t,M,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",Dw);let t=o.headers["sec-websocket-key"]!==void 0?o.headers["sec-websocket-key"].trim():!1,M=+o.headers["sec-websocket-version"],N={};if(o.method!=="GET"||o.headers.upgrade.toLowerCase()!=="websocket"||!t||!IB.test(t)||M!==8&&M!==13||!this.shouldHandle(o))return a4(a,400);if(this.options.perMessageDeflate){let O=new rh(this.options.perMessageDeflate,!0,this.options.maxPayload);try{let T=NB(o.headers["sec-websocket-extensions"]);T[rh.extensionName]&&(O.accept(T[rh.extensionName]),N[rh.extensionName]=O)}catch(T){return a4(a,400)}}if(this.options.verifyClient){let O={origin:o.headers[`${M===8?"sec-websocket-origin":"origin"}`],secure:!!(o.socket.authorized||o.socket.encrypted),req:o};if(this.options.verifyClient.length===2){this.options.verifyClient(O,(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(O))return a4(a,401)}this.completeUpgrade(t,N,o,a,c,_)}completeUpgrade(o,a,c,_,t,M){if(!_.readable||!_.writable)return _.destroy();if(_[PB])throw new Error("server.handleUpgrade() was called more than once with the same socket, possibly due to a misconfiguration");let N=OB("sha1").update(o+FB).digest("base64"),O=["HTTP/1.1 101 Switching Protocols","Upgrade: websocket","Connection: Upgrade",`Sec-WebSocket-Accept: ${N}`],T=new kB(null),B=c.headers["sec-websocket-protocol"];if(B&&(B=B.split(",").map(UB),this.options.handleProtocols?B=this.options.handleProtocols(B,c):B=B[0],B&&(O.push(`Sec-WebSocket-Protocol: ${B}`),T._protocol=B)),a[rh.extensionName]){let H=a[rh.extensionName].params,q=LB({[rh.extensionName]:[H]});O.push(`Sec-WebSocket-Extensions: ${q}`),T._extensions=a}this.emit("headers",O,c),_.write(O.concat(`\r -`).join(`\r -`)),_.removeListener("error",Dw),T.setSocket(_,t,this.options.maxPayload),this.clients&&(this.clients.add(T),T.on("close",()=>this.clients.delete(T))),M(T,c)}};n6.exports=r6;function bB(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 Dw(){this.destroy()}function a4(i,o,a,c){i.writable&&(a=a||Ew[o],c=qt({Connection:"close","Content-Type":"text/html","Content-Length":Buffer.byteLength(a)},c),i.write(`HTTP/1.1 ${o} ${Ew[o]}\r -`+Object.keys(c).map(_=>`${_}: ${c[_]}`).join(`\r -`)+`\r -\r -`+a)),i.removeListener("error",Dw),i.destroy()}function UB(i){return i.trim()}});var o6=Ke((TV,u6)=>{"use strict";var fg=_w();fg.createWebSocketStream=t6();fg.Server=i6();fg.Receiver=dw();fg.Sender=pw();u6.exports=fg});var l6=Ke(f4=>{"use strict";var jB=f4&&f4.__importDefault||function(i){return i&&i.__esModule?i:{default:i}};Object.defineProperty(f4,"__esModule",{value:!0});var zB=jB(o6()),cg=global;cg.WebSocket||(cg.WebSocket=zB.default);cg.window||(cg.window=global);cg.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 s6=Ke((c4,ww)=>{(function(i,o){typeof c4=="object"&&typeof ww=="object"?ww.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 M in c)a.d(t,M,function(N){return c[N]}.bind(null,M));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 M(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 O={},T=0;T<10;T++)O["_"+String.fromCharCode(T)]=T;if(Object.getOwnPropertyNames(O).map(function(H){return O[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,O){for(var T,B,H=M(N),q=1;q=re||nn<0||zt&&Rt-He>=ct}function le(){var Rt=ge();if(xe(Rt))return qe(Rt);Xe=setTimeout(le,function(nn){var an=re-(nn-tt);return zt?pe(an,ct-(nn-He)):an}(Rt))}function qe(Rt){return Xe=void 0,nt&&Ie?X(Rt):(Ie=je=void 0,pt)}function dt(){var Rt=ge(),nn=xe(Rt);if(Ie=arguments,je=this,tt=Rt,nn){if(Xe===void 0)return fe(tt);if(zt)return Xe=setTimeout(le,re),X(tt)}return Xe===void 0&&(Xe=setTimeout(le,re)),pt}return re=ce(re)||0,ue(we)&&(kt=!!we.leading,ct=(zt="maxWait"in we)?m(ce(we.maxWait)||0,re):ct,nt="trailing"in we?!!we.trailing:nt),dt.cancel=function(){Xe!==void 0&&clearTimeout(Xe),He=0,Ie=tt=je=Xe=void 0},dt.flush=function(){return Xe===void 0?pt:qe(ge())},dt}function ue(me){var re=_(me);return!!me&&(re=="object"||re=="function")}function _e(me){return _(me)=="symbol"||function(re){return!!re&&_(re)=="object"}(me)&&ne.call(me)=="[object Symbol]"}function ce(me){if(typeof me=="number")return me;if(_e(me))return NaN;if(ue(me)){var re=typeof me.valueOf=="function"?me.valueOf():me;me=ue(re)?re+"":re}if(typeof me!="string")return me===0?me:+me;me=me.replace(t,"");var we=N.test(me);return we||O.test(me)?T(me.slice(2),we?2:8):M.test(me)?NaN:+me}i.exports=function(me,re,we){var Ie=!0,je=!0;if(typeof me!="function")throw new TypeError("Expected a function");return ue(we)&&(Ie="leading"in we?!!we.leading:Ie,je="trailing"in we?!!we.trailing:je),ve(me,re,{leading:Ie,maxWait:re,trailing:je})}}).call(this,a(4))},function(i,o,a){(function(c){function _(X){return(_=typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?function(fe){return typeof fe}:function(fe){return fe&&typeof Symbol=="function"&&fe.constructor===Symbol&&fe!==Symbol.prototype?"symbol":typeof fe})(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 M=Number.MAX_SAFE_INTEGER||9007199254740991,N=o.re=[],O=o.src=[],T=o.tokens={},B=0;function H(X){T[X]=B++}H("NUMERICIDENTIFIER"),O[T.NUMERICIDENTIFIER]="0|[1-9]\\d*",H("NUMERICIDENTIFIERLOOSE"),O[T.NUMERICIDENTIFIERLOOSE]="[0-9]+",H("NONNUMERICIDENTIFIER"),O[T.NONNUMERICIDENTIFIER]="\\d*[a-zA-Z-][a-zA-Z0-9-]*",H("MAINVERSION"),O[T.MAINVERSION]="("+O[T.NUMERICIDENTIFIER]+")\\.("+O[T.NUMERICIDENTIFIER]+")\\.("+O[T.NUMERICIDENTIFIER]+")",H("MAINVERSIONLOOSE"),O[T.MAINVERSIONLOOSE]="("+O[T.NUMERICIDENTIFIERLOOSE]+")\\.("+O[T.NUMERICIDENTIFIERLOOSE]+")\\.("+O[T.NUMERICIDENTIFIERLOOSE]+")",H("PRERELEASEIDENTIFIER"),O[T.PRERELEASEIDENTIFIER]="(?:"+O[T.NUMERICIDENTIFIER]+"|"+O[T.NONNUMERICIDENTIFIER]+")",H("PRERELEASEIDENTIFIERLOOSE"),O[T.PRERELEASEIDENTIFIERLOOSE]="(?:"+O[T.NUMERICIDENTIFIERLOOSE]+"|"+O[T.NONNUMERICIDENTIFIER]+")",H("PRERELEASE"),O[T.PRERELEASE]="(?:-("+O[T.PRERELEASEIDENTIFIER]+"(?:\\."+O[T.PRERELEASEIDENTIFIER]+")*))",H("PRERELEASELOOSE"),O[T.PRERELEASELOOSE]="(?:-?("+O[T.PRERELEASEIDENTIFIERLOOSE]+"(?:\\."+O[T.PRERELEASEIDENTIFIERLOOSE]+")*))",H("BUILDIDENTIFIER"),O[T.BUILDIDENTIFIER]="[0-9A-Za-z-]+",H("BUILD"),O[T.BUILD]="(?:\\+("+O[T.BUILDIDENTIFIER]+"(?:\\."+O[T.BUILDIDENTIFIER]+")*))",H("FULL"),H("FULLPLAIN"),O[T.FULLPLAIN]="v?"+O[T.MAINVERSION]+O[T.PRERELEASE]+"?"+O[T.BUILD]+"?",O[T.FULL]="^"+O[T.FULLPLAIN]+"$",H("LOOSEPLAIN"),O[T.LOOSEPLAIN]="[v=\\s]*"+O[T.MAINVERSIONLOOSE]+O[T.PRERELEASELOOSE]+"?"+O[T.BUILD]+"?",H("LOOSE"),O[T.LOOSE]="^"+O[T.LOOSEPLAIN]+"$",H("GTLT"),O[T.GTLT]="((?:<|>)?=?)",H("XRANGEIDENTIFIERLOOSE"),O[T.XRANGEIDENTIFIERLOOSE]=O[T.NUMERICIDENTIFIERLOOSE]+"|x|X|\\*",H("XRANGEIDENTIFIER"),O[T.XRANGEIDENTIFIER]=O[T.NUMERICIDENTIFIER]+"|x|X|\\*",H("XRANGEPLAIN"),O[T.XRANGEPLAIN]="[v=\\s]*("+O[T.XRANGEIDENTIFIER]+")(?:\\.("+O[T.XRANGEIDENTIFIER]+")(?:\\.("+O[T.XRANGEIDENTIFIER]+")(?:"+O[T.PRERELEASE]+")?"+O[T.BUILD]+"?)?)?",H("XRANGEPLAINLOOSE"),O[T.XRANGEPLAINLOOSE]="[v=\\s]*("+O[T.XRANGEIDENTIFIERLOOSE]+")(?:\\.("+O[T.XRANGEIDENTIFIERLOOSE]+")(?:\\.("+O[T.XRANGEIDENTIFIERLOOSE]+")(?:"+O[T.PRERELEASELOOSE]+")?"+O[T.BUILD]+"?)?)?",H("XRANGE"),O[T.XRANGE]="^"+O[T.GTLT]+"\\s*"+O[T.XRANGEPLAIN]+"$",H("XRANGELOOSE"),O[T.XRANGELOOSE]="^"+O[T.GTLT]+"\\s*"+O[T.XRANGEPLAINLOOSE]+"$",H("COERCE"),O[T.COERCE]="(^|[^\\d])(\\d{1,16})(?:\\.(\\d{1,16}))?(?:\\.(\\d{1,16}))?(?:$|[^\\d])",H("COERCERTL"),N[T.COERCERTL]=new RegExp(O[T.COERCE],"g"),H("LONETILDE"),O[T.LONETILDE]="(?:~>?)",H("TILDETRIM"),O[T.TILDETRIM]="(\\s*)"+O[T.LONETILDE]+"\\s+",N[T.TILDETRIM]=new RegExp(O[T.TILDETRIM],"g"),H("TILDE"),O[T.TILDE]="^"+O[T.LONETILDE]+O[T.XRANGEPLAIN]+"$",H("TILDELOOSE"),O[T.TILDELOOSE]="^"+O[T.LONETILDE]+O[T.XRANGEPLAINLOOSE]+"$",H("LONECARET"),O[T.LONECARET]="(?:\\^)",H("CARETTRIM"),O[T.CARETTRIM]="(\\s*)"+O[T.LONECARET]+"\\s+",N[T.CARETTRIM]=new RegExp(O[T.CARETTRIM],"g"),H("CARET"),O[T.CARET]="^"+O[T.LONECARET]+O[T.XRANGEPLAIN]+"$",H("CARETLOOSE"),O[T.CARETLOOSE]="^"+O[T.LONECARET]+O[T.XRANGEPLAINLOOSE]+"$",H("COMPARATORLOOSE"),O[T.COMPARATORLOOSE]="^"+O[T.GTLT]+"\\s*("+O[T.LOOSEPLAIN]+")$|^$",H("COMPARATOR"),O[T.COMPARATOR]="^"+O[T.GTLT]+"\\s*("+O[T.FULLPLAIN]+")$|^$",H("COMPARATORTRIM"),O[T.COMPARATORTRIM]="(\\s*)"+O[T.GTLT]+"\\s*("+O[T.LOOSEPLAIN]+"|"+O[T.XRANGEPLAIN]+")",N[T.COMPARATORTRIM]=new RegExp(O[T.COMPARATORTRIM],"g"),H("HYPHENRANGE"),O[T.HYPHENRANGE]="^\\s*("+O[T.XRANGEPLAIN]+")\\s+-\\s+("+O[T.XRANGEPLAIN]+")\\s*$",H("HYPHENRANGELOOSE"),O[T.HYPHENRANGELOOSE]="^\\s*("+O[T.XRANGEPLAINLOOSE]+")\\s+-\\s+("+O[T.XRANGEPLAINLOOSE]+")\\s*$",H("STAR"),O[T.STAR]="(<|>)?=?\\s*\\*";for(var q=0;q256||!(fe.loose?N[T.LOOSE]:N[T.FULL]).test(X))return null;try{return new m(X,fe)}catch(xe){return null}}function m(X,fe){if(fe&&_(fe)==="object"||(fe={loose:!!fe,includePrerelease:!1}),X instanceof m){if(X.loose===fe.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,fe);t("SemVer",X,fe),this.options=fe,this.loose=!!fe.loose;var xe=X.trim().match(fe.loose?N[T.LOOSE]:N[T.FULL]);if(!xe)throw new TypeError("Invalid Version: "+X);if(this.raw=X,this.major=+xe[1],this.minor=+xe[2],this.patch=+xe[3],this.major>M||this.major<0)throw new TypeError("Invalid major version");if(this.minor>M||this.minor<0)throw new TypeError("Invalid minor version");if(this.patch>M||this.patch<0)throw new TypeError("Invalid patch version");xe[4]?this.prerelease=xe[4].split(".").map(function(le){if(/^[0-9]+$/.test(le)){var qe=+le;if(qe>=0&&qe=0;)typeof this.prerelease[xe]=="number"&&(this.prerelease[xe]++,xe=-2);xe===-1&&this.prerelease.push(0)}fe&&(this.prerelease[0]===fe?isNaN(this.prerelease[1])&&(this.prerelease=[fe,0]):this.prerelease=[fe,0]);break;default:throw new Error("invalid increment argument: "+X)}return this.format(),this.raw=this.version,this},o.inc=function(X,fe,xe,le){typeof xe=="string"&&(le=xe,xe=void 0);try{return new m(X,xe).inc(fe,le).version}catch(qe){return null}},o.diff=function(X,fe){if(ce(X,fe))return null;var xe=ne(X),le=ne(fe),qe="";if(xe.prerelease.length||le.prerelease.length){qe="pre";var dt="prerelease"}for(var Rt in xe)if((Rt==="major"||Rt==="minor"||Rt==="patch")&&xe[Rt]!==le[Rt])return qe+Rt;return dt},o.compareIdentifiers=ge;var pe=/^[0-9]+$/;function ge(X,fe){var xe=pe.test(X),le=pe.test(fe);return xe&&le&&(X=+X,fe=+fe),X===fe?0:xe&&!le?-1:le&&!xe?1:X0}function _e(X,fe,xe){return ve(X,fe,xe)<0}function ce(X,fe,xe){return ve(X,fe,xe)===0}function me(X,fe,xe){return ve(X,fe,xe)!==0}function re(X,fe,xe){return ve(X,fe,xe)>=0}function we(X,fe,xe){return ve(X,fe,xe)<=0}function Ie(X,fe,xe,le){switch(fe){case"===":return _(X)==="object"&&(X=X.version),_(xe)==="object"&&(xe=xe.version),X===xe;case"!==":return _(X)==="object"&&(X=X.version),_(xe)==="object"&&(xe=xe.version),X!==xe;case"":case"=":case"==":return ce(X,xe,le);case"!=":return me(X,xe,le);case">":return ue(X,xe,le);case">=":return re(X,xe,le);case"<":return _e(X,xe,le);case"<=":return we(X,xe,le);default:throw new TypeError("Invalid operator: "+fe)}}function je(X,fe){if(fe&&_(fe)==="object"||(fe={loose:!!fe,includePrerelease:!1}),X instanceof je){if(X.loose===!!fe.loose)return X;X=X.value}if(!(this instanceof je))return new je(X,fe);t("comparator",X,fe),this.options=fe,this.loose=!!fe.loose,this.parse(X),this.semver===ct?this.value="":this.value=this.operator+this.semver.version,t("comp",this)}o.rcompareIdentifiers=function(X,fe){return ge(fe,X)},o.major=function(X,fe){return new m(X,fe).major},o.minor=function(X,fe){return new m(X,fe).minor},o.patch=function(X,fe){return new m(X,fe).patch},o.compare=ve,o.compareLoose=function(X,fe){return ve(X,fe,!0)},o.compareBuild=function(X,fe,xe){var le=new m(X,xe),qe=new m(fe,xe);return le.compare(qe)||le.compareBuild(qe)},o.rcompare=function(X,fe,xe){return ve(fe,X,xe)},o.sort=function(X,fe){return X.sort(function(xe,le){return o.compareBuild(xe,le,fe)})},o.rsort=function(X,fe){return X.sort(function(xe,le){return o.compareBuild(le,xe,fe)})},o.gt=ue,o.lt=_e,o.eq=ce,o.neq=me,o.gte=re,o.lte=we,o.cmp=Ie,o.Comparator=je;var ct={};function pt(X,fe){if(fe&&_(fe)==="object"||(fe={loose:!!fe,includePrerelease:!1}),X instanceof pt)return X.loose===!!fe.loose&&X.includePrerelease===!!fe.includePrerelease?X:new pt(X.raw,fe);if(X instanceof je)return new pt(X.value,fe);if(!(this instanceof pt))return new pt(X,fe);if(this.options=fe,this.loose=!!fe.loose,this.includePrerelease=!!fe.includePrerelease,this.raw=X,this.set=X.split(/\s*\|\|\s*/).map(function(xe){return this.parseRange(xe.trim())},this).filter(function(xe){return xe.length}),!this.set.length)throw new TypeError("Invalid SemVer Range: "+X);this.format()}function Xe(X,fe){for(var xe=!0,le=X.slice(),qe=le.pop();xe&&le.length;)xe=le.every(function(dt){return qe.intersects(dt,fe)}),qe=le.pop();return xe}function tt(X){return!X||X.toLowerCase()==="x"||X==="*"}function He(X,fe,xe,le,qe,dt,Rt,nn,an,Mn,lr,ln,Gt){return((fe=tt(xe)?"":tt(le)?">="+xe+".0.0":tt(qe)?">="+xe+"."+le+".0":">="+fe)+" "+(nn=tt(an)?"":tt(Mn)?"<"+(+an+1)+".0.0":tt(lr)?"<"+an+"."+(+Mn+1)+".0":ln?"<="+an+"."+Mn+"."+lr+"-"+ln:"<="+nn)).trim()}function kt(X,fe,xe){for(var le=0;le0){var qe=X[le].semver;if(qe.major===fe.major&&qe.minor===fe.minor&&qe.patch===fe.patch)return!0}return!1}return!0}function zt(X,fe,xe){try{fe=new pt(fe,xe)}catch(le){return!1}return fe.test(X)}function nt(X,fe,xe,le){var qe,dt,Rt,nn,an;switch(X=new m(X,le),fe=new pt(fe,le),xe){case">":qe=ue,dt=we,Rt=_e,nn=">",an=">=";break;case"<":qe=_e,dt=re,Rt=ue,nn="<",an="<=";break;default:throw new TypeError('Must provide a hilo val of "<" or ">"')}if(zt(X,fe,le))return!1;for(var Mn=0;Mn=0.0.0")),ln=ln||Er,Gt=Gt||Er,qe(Er.semver,ln.semver,le)?ln=Er:Rt(Er.semver,Gt.semver,le)&&(Gt=Er)}),ln.operator===nn||ln.operator===an||(!Gt.operator||Gt.operator===nn)&&dt(X,Gt.semver)||Gt.operator===an&&Rt(X,Gt.semver))return!1}return!0}je.prototype.parse=function(X){var fe=this.options.loose?N[T.COMPARATORLOOSE]:N[T.COMPARATOR],xe=X.match(fe);if(!xe)throw new TypeError("Invalid comparator: "+X);this.operator=xe[1]!==void 0?xe[1]:"",this.operator==="="&&(this.operator=""),xe[2]?this.semver=new m(xe[2],this.options.loose):this.semver=ct},je.prototype.toString=function(){return this.value},je.prototype.test=function(X){if(t("Comparator.test",X,this.options.loose),this.semver===ct||X===ct)return!0;if(typeof X=="string")try{X=new m(X,this.options)}catch(fe){return!1}return Ie(X,this.operator,this.semver,this.options)},je.prototype.intersects=function(X,fe){if(!(X instanceof je))throw new TypeError("a Comparator is required");var xe;if(fe&&_(fe)==="object"||(fe={loose:!!fe,includePrerelease:!1}),this.operator==="")return this.value===""||(xe=new pt(X.value,fe),zt(this.value,xe,fe));if(X.operator==="")return X.value===""||(xe=new pt(this.value,fe),zt(X.semver,xe,fe));var le=!(this.operator!==">="&&this.operator!==">"||X.operator!==">="&&X.operator!==">"),qe=!(this.operator!=="<="&&this.operator!=="<"||X.operator!=="<="&&X.operator!=="<"),dt=this.semver.version===X.semver.version,Rt=!(this.operator!==">="&&this.operator!=="<="||X.operator!==">="&&X.operator!=="<="),nn=Ie(this.semver,"<",X.semver,fe)&&(this.operator===">="||this.operator===">")&&(X.operator==="<="||X.operator==="<"),an=Ie(this.semver,">",X.semver,fe)&&(this.operator==="<="||this.operator==="<")&&(X.operator===">="||X.operator===">");return le||qe||dt&&Rt||nn||an},o.Range=pt,pt.prototype.format=function(){return this.range=this.set.map(function(X){return X.join(" ").trim()}).join("||").trim(),this.range},pt.prototype.toString=function(){return this.range},pt.prototype.parseRange=function(X){var fe=this.options.loose;X=X.trim();var xe=fe?N[T.HYPHENRANGELOOSE]:N[T.HYPHENRANGE];X=X.replace(xe,He),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 le=fe?N[T.COMPARATORLOOSE]:N[T.COMPARATOR],qe=X.split(" ").map(function(dt){return function(Rt,nn){return t("comp",Rt,nn),Rt=function(an,Mn){return an.trim().split(/\s+/).map(function(lr){return function(ln,Gt){t("caret",ln,Gt);var Er=Gt.loose?N[T.CARETLOOSE]:N[T.CARET];return ln.replace(Er,function(w,jt,Xn,vr,jr){var fr;return t("caret",ln,w,jt,Xn,vr,jr),tt(jt)?fr="":tt(Xn)?fr=">="+jt+".0.0 <"+(+jt+1)+".0.0":tt(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(" ")}(Rt,nn),t("caret",Rt),Rt=function(an,Mn){return an.trim().split(/\s+/).map(function(lr){return function(ln,Gt){var Er=Gt.loose?N[T.TILDELOOSE]:N[T.TILDE];return ln.replace(Er,function(w,jt,Xn,vr,jr){var fr;return t("tilde",ln,w,jt,Xn,vr,jr),tt(jt)?fr="":tt(Xn)?fr=">="+jt+".0.0 <"+(+jt+1)+".0.0":tt(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(" ")}(Rt,nn),t("tildes",Rt),Rt=function(an,Mn){return t("replaceXRanges",an,Mn),an.split(/\s+/).map(function(lr){return function(ln,Gt){ln=ln.trim();var Er=Gt.loose?N[T.XRANGELOOSE]:N[T.XRANGE];return ln.replace(Er,function(w,jt,Xn,vr,jr,fr){t("xRange",ln,w,jt,Xn,vr,jr,fr);var zr=tt(Xn),Qt=zr||tt(vr),wu=Qt||tt(jr),po=wu;return jt==="="&&po&&(jt=""),fr=Gt.includePrerelease?"-0":"",zr?w=jt===">"||jt==="<"?"<0.0.0-0":"*":jt&&po?(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(" ")}(Rt,nn),t("xrange",Rt),Rt=function(an,Mn){return t("replaceStars",an,Mn),an.trim().replace(N[T.STAR],"")}(Rt,nn),t("stars",Rt),Rt}(dt,this.options)},this).join(" ").split(/\s+/);return this.options.loose&&(qe=qe.filter(function(dt){return!!dt.match(le)})),qe=qe.map(function(dt){return new je(dt,this.options)},this)},pt.prototype.intersects=function(X,fe){if(!(X instanceof pt))throw new TypeError("a Range is required");return this.set.some(function(xe){return Xe(xe,fe)&&X.set.some(function(le){return Xe(le,fe)&&xe.every(function(qe){return le.every(function(dt){return qe.intersects(dt,fe)})})})})},o.toComparators=function(X,fe){return new pt(X,fe).set.map(function(xe){return xe.map(function(le){return le.value}).join(" ").trim().split(" ")})},pt.prototype.test=function(X){if(!X)return!1;if(typeof X=="string")try{X=new m(X,this.options)}catch(xe){return!1}for(var fe=0;fe":dt.prerelease.length===0?dt.patch++:dt.prerelease.push(0),dt.raw=dt.format();case"":case">=":xe&&!ue(xe,dt)||(xe=dt);break;case"<":case"<=":break;default:throw new Error("Unexpected operation: "+qe.operator)}});return xe&&X.test(xe)?xe:null},o.validRange=function(X,fe){try{return new pt(X,fe).range||"*"}catch(xe){return null}},o.ltr=function(X,fe,xe){return nt(X,fe,"<",xe)},o.gtr=function(X,fe,xe){return nt(X,fe,">",xe)},o.outside=nt,o.prerelease=function(X,fe){var xe=ne(X,fe);return xe&&xe.prerelease.length?xe.prerelease:null},o.intersects=function(X,fe,xe){return X=new pt(X,xe),fe=new pt(fe,xe),X.intersects(fe)},o.coerce=function(X,fe){if(X instanceof m)return X;if(typeof X=="number"&&(X=String(X)),typeof X!="string")return null;var xe=null;if((fe=fe||{}).rtl){for(var le;(le=N[T.COERCERTL].exec(X))&&(!xe||xe.index+xe[0].length!==X.length);)xe&&le.index+le[0].length===xe.index+xe[0].length||(xe=le),N[T.COERCERTL].lastIndex=le.index+le[1].length+le[2].length;N[T.COERCERTL].lastIndex=-1}else xe=X.match(N[T.COERCE]);return xe===null?null:ne(xe[2]+"."+(xe[3]||"0")+"."+(xe[4]||"0"),fe)}}).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 M(){throw new Error("clearTimeout has not been defined")}function N(ge){if(a===setTimeout)return setTimeout(ge,0);if((a===t||!a)&&setTimeout)return a=setTimeout,setTimeout(ge,0);try{return a(ge,0)}catch(ve){try{return a.call(null,ge,0)}catch(ue){return a.call(this,ge,0)}}}(function(){try{a=typeof setTimeout=="function"?setTimeout:t}catch(ge){a=t}try{c=typeof clearTimeout=="function"?clearTimeout:M}catch(ge){c=M}})();var O,T=[],B=!1,H=-1;function q(){B&&O&&(B=!1,O.length?T=O.concat(T):H=-1,T.length&&ne())}function ne(){if(!B){var ge=N(q);B=!0;for(var ve=T.length;ve;){for(O=T,T=[];++H1)for(var ue=1;uethis[M])return me(this,this[m].get(Xe)),!1;var nt=this[m].get(Xe).value;return this[H]&&(this[q]||this[H](Xe,nt.value)),nt.now=kt,nt.maxAge=He,nt.value=tt,this[N]+=zt-nt.length,nt.length=zt,this.get(Xe),ce(this),!0}var X=new re(Xe,tt,zt,kt,He);return X.length>this[M]?(this[H]&&this[H](Xe,tt),!1):(this[N]+=X.length,this[ne].unshift(X),this[m].set(Xe,this[ne].head),ce(this),!0)}},{key:"has",value:function(Xe){if(!this[m].has(Xe))return!1;var tt=this[m].get(Xe).value;return!_e(this,tt)}},{key:"get",value:function(Xe){return ue(this,Xe,!0)}},{key:"peek",value:function(Xe){return ue(this,Xe,!1)}},{key:"pop",value:function(){var Xe=this[ne].tail;return Xe?(me(this,Xe),Xe.value):null}},{key:"del",value:function(Xe){me(this,this[m].get(Xe))}},{key:"load",value:function(Xe){this.reset();for(var tt=Date.now(),He=Xe.length-1;He>=0;He--){var kt=Xe[He],zt=kt.e||0;if(zt===0)this.set(kt.k,kt.v);else{var nt=zt-tt;nt>0&&this.set(kt.k,kt.v,nt)}}}},{key:"prune",value:function(){var Xe=this;this[m].forEach(function(tt,He){return ue(Xe,He,!1)})}},{key:"max",set:function(Xe){if(typeof Xe!="number"||Xe<0)throw new TypeError("max must be a non-negative number");this[M]=Xe||1/0,ce(this)},get:function(){return this[M]}},{key:"allowStale",set:function(Xe){this[T]=!!Xe},get:function(){return this[T]}},{key:"maxAge",set:function(Xe){if(typeof Xe!="number")throw new TypeError("maxAge must be a non-negative number");this[B]=Xe,ce(this)},get:function(){return this[B]}},{key:"lengthCalculator",set:function(Xe){var tt=this;typeof Xe!="function"&&(Xe=ge),Xe!==this[O]&&(this[O]=Xe,this[N]=0,this[ne].forEach(function(He){He.length=tt[O](He.value,He.key),tt[N]+=He.length})),ce(this)},get:function(){return this[O]}},{key:"length",get:function(){return this[N]}},{key:"itemCount",get:function(){return this[ne].length}}])&&_(je.prototype,ct),pt&&_(je,pt),Ie}(),ue=function(Ie,je,ct){var pt=Ie[m].get(je);if(pt){var Xe=pt.value;if(_e(Ie,Xe)){if(me(Ie,pt),!Ie[T])return}else ct&&(Ie[pe]&&(pt.value.now=Date.now()),Ie[ne].unshiftNode(pt));return Xe.value}},_e=function(Ie,je){if(!je||!je.maxAge&&!Ie[B])return!1;var ct=Date.now()-je.now;return je.maxAge?ct>je.maxAge:Ie[B]&&ct>Ie[B]},ce=function(Ie){if(Ie[N]>Ie[M])for(var je=Ie[ne].tail;Ie[N]>Ie[M]&&je!==null;){var ct=je.prev;me(Ie,je),je=ct}},me=function(Ie,je){if(je){var ct=je.value;Ie[H]&&Ie[H](ct.key,ct.value),Ie[N]-=ct.length,Ie[m].delete(ct.key),Ie[ne].removeNode(je)}},re=function Ie(je,ct,pt,Xe,tt){c(this,Ie),this.key=je,this.value=ct,this.length=pt,this.now=Xe,this.maxAge=tt||0},we=function(Ie,je,ct,pt){var Xe=ct.value;_e(Ie,Xe)&&(me(Ie,ct),Ie[T]||(Xe=void 0)),Xe&&je.call(pt,Xe.value,Xe.key,Ie)};i.exports=ve},function(i,o,a){(function(c){function _(t){return(_=typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?function(M){return typeof M}:function(M){return M&&typeof Symbol=="function"&&M.constructor===Symbol&&M!==Symbol.prototype?"symbol":typeof M})(t)}i.exports=function(){if(typeof document=="undefined"||!document.addEventListener)return null;var t,M,N,O={};return O.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,pe){T=!0,typeof ne=="string"?B={"text/plain":ne}:ne instanceof Node?B={"text/html":new XMLSerializer().serializeToString(ne)}:ne instanceof Object?B=ne:pe("Invalid data type. Must be string, DOM node, or an object mapping MIME types to strings."),function ge(ve){try{if(document.execCommand("copy"))q(),m();else{if(ve)throw q(),new Error("Unable to copy. Perhaps it's not available in your browser?");(function(){var ue=document.getSelection();if(!document.queryCommandEnabled("copy")&&ue.isCollapsed){var _e=document.createRange();_e.selectNodeContents(document.body),ue.removeAllRanges(),ue.addRange(_e),H=!0}})(),ge(!0)}}catch(ue){q(),pe(ue)}}(!1)})}}(),O.paste=(N=!1,document.addEventListener("paste",function(T){if(N){N=!1,T.preventDefault();var B=t;t=null,B(T.clipboardData.getData(M))}}),function(T){return new Promise(function(B,H){N=!0,t=B,M=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=[],ve(ce,B(ne,this),B(m,this))}function q(ce){var me=this;return this._state===null?void this._deferreds.push(ce):void ue(function(){var re=me._state?ce.onFulfilled:ce.onRejected;if(re!==null){var we;try{we=re(me._value)}catch(Ie){return void ce.reject(Ie)}ce.resolve(we)}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 ve(B(me,ce),B(ne,this),B(m,this))}this._state=!0,this._value=ce,pe.call(this)}catch(re){m.call(this,re)}}function m(ce){this._state=!1,this._value=ce,pe.call(this)}function pe(){for(var ce=0,me=this._deferreds.length;me>ce;ce++)q.call(this,this._deferreds[ce]);this._deferreds=null}function ge(ce,me,re,we){this.onFulfilled=typeof ce=="function"?ce:null,this.onRejected=typeof me=="function"?me:null,this.resolve=re,this.reject=we}function ve(ce,me,re){var we=!1;try{ce(function(Ie){we||(we=!0,me(Ie))},function(Ie){we||(we=!0,re(Ie))})}catch(Ie){if(we)return;we=!0,re(Ie)}}var ue=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 re=this;return new H(function(we,Ie){q.call(re,new ge(ce,me,we,Ie))})},H.all=function(){var ce=Array.prototype.slice.call(arguments.length===1&&_e(arguments[0])?arguments[0]:arguments);return new H(function(me,re){function we(ct,pt){try{if(pt&&(_(pt)=="object"||typeof pt=="function")){var Xe=pt.then;if(typeof Xe=="function")return void Xe.call(pt,function(tt){we(ct,tt)},re)}ce[ct]=pt,--Ie==0&&me(ce)}catch(tt){re(tt)}}if(ce.length===0)return me([]);for(var Ie=ce.length,je=0;jewe;we++)ce[we].then(me,re)})},i.exports?i.exports=H:T.Promise||(T.Promise=H)}(this),O.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."))})},O.paste=function(){return new Promise(function(T,B){var H=window.clipboardData.getData("Text");H?T(H):B(new Error("Pasting was rejected."))})}),O}()}).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(O){var T=this;if(T instanceof c||(T=new c),T.tail=null,T.head=null,T.length=0,O&&typeof O.forEach=="function")O.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=O(B,H.value,q),H=H.next;return B},c.prototype.reduceReverse=function(O,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=O(B,H.value,q),H=H.prev;return B},c.prototype.toArray=function(){for(var O=new Array(this.length),T=0,B=this.head;B!==null;T++)O[T]=B.value,B=B.next;return O},c.prototype.toArrayReverse=function(){for(var O=new Array(this.length),T=0,B=this.tail;B!==null;T++)O[T]=B.value,B=B.prev;return O},c.prototype.slice=function(O,T){(T=T||this.length)<0&&(T+=this.length),(O=O||0)<0&&(O+=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>O;H--,q=q.prev)B.push(q.value);return B},c.prototype.splice=function(O,T){O>this.length&&(O=this.length-1),O<0&&(O=this.length+O);for(var B=0,H=this.head;H!==null&&B=0&&(N._idleTimeoutId=setTimeout(function(){N._onTimeout&&N._onTimeout()},O))},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,M){"use strict";if(!t.setImmediate){var N,O,T,B,H,q=1,ne={},m=!1,pe=t.document,ge=Object.getPrototypeOf&&Object.getPrototypeOf(t);ge=ge&&ge.setTimeout?ge:t,{}.toString.call(t.process)==="[object process]"?N=function(_e){_.nextTick(function(){ue(_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&&ue(+_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){ue(_e.data)},N=function(_e){T.port2.postMessage(_e)}):pe&&"onreadystatechange"in pe.createElement("script")?(O=pe.documentElement,N=function(_e){var ce=pe.createElement("script");ce.onreadystatechange=function(){ue(_e),ce.onreadystatechange=null,O.removeChild(ce),ce=null},O.appendChild(ce)}):N=function(_e){setTimeout(ue,0,_e)},ge.setImmediate=function(_e){typeof _e!="function"&&(_e=new Function(""+_e));for(var ce=new Array(arguments.length-1),me=0;mefe;fe++)if((X=ve(nt,kt,fe))!==-1){ge=fe,kt=X;break e}kt=-1}}e:{if(nt=zt,(X=q().get(He.primitive))!==void 0){for(fe=0;fekt-nt?null:zt.slice(nt,kt-1))!==null){if(kt=0,je!==null){for(;ktkt;je--)ct=Xe.pop()}for(je=zt.length-kt-1;1<=je;je--)kt=[],ct.push({id:null,isStateEditable:!1,name:_e(zt[je-1].functionName),value:void 0,subHooks:kt}),Xe.push(ct),ct=kt;je=zt}kt=(zt=He.primitive)==="Context"||zt==="DebugValue"?null:pt++,ct.push({id:kt,isStateEditable:zt==="Reducer"||zt==="State",name:zt,value:He.value,subHooks:[]})}return function xe(le,qe){for(var dt=[],Rt=0;Rt-1&&(ne=ne.replace(/eval code/g,"eval").replace(/(\(eval at [^()]*)|(\),.*$)/g,""));var m=ne.replace(/^\s+/,"").replace(/\(eval code/g,"("),pe=m.match(/ (\((.+):(\d+):(\d+)\)$)/),ge=(m=pe?m.replace(pe[0],""):m).split(/\s+/).slice(1),ve=this.extractLocation(pe?pe[1]:ge.pop()),ue=ge.join(" ")||void 0,_e=["eval",""].indexOf(ve[0])>-1?void 0:ve[0];return new O({functionName:ue,fileName:_e,lineNumber:ve[1],columnNumber:ve[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 O({functionName:ne});var m=/((.*".+"[^@]*)?[^@]*)(?:@)/,pe=ne.match(m),ge=pe&&pe[1]?pe[1]:void 0,ve=this.extractLocation(ne.replace(m,""));return new O({functionName:ge,fileName:ve[0],lineNumber:ve[1],columnNumber:ve[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(` -`),pe=[],ge=2,ve=m.length;ge/,"$2").replace(/\([^)]*\)/g,"")||void 0;ve.match(/\(([^)]*)\)/)&&(m=ve.replace(/^[^(]+\(([^)]*)\)$/,"$1"));var _e=m===void 0||m==="[arguments not available]"?void 0:m.split(",");return new O({functionName:ue,args:_e,fileName:ge[0],lineNumber:ge[1],columnNumber:ge[2],source:ne})},this)}}})=="function"?c.apply(o,_):c)===void 0||(i.exports=t)})()},function(i,o,a){var c,_,t;(function(M,N){"use strict";_=[],(t=typeof(c=function(){function O(ue){return ue.charAt(0).toUpperCase()+ue.substring(1)}function T(ue){return function(){return this[ue]}}var B=["isConstructor","isEval","isNative","isToplevel"],H=["columnNumber","lineNumber"],q=["fileName","functionName","source"],ne=B.concat(H,q,["args"]);function m(ue){if(ue)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),M=a.n(t);try{var N=a(9).default,O=function(U){var z=new RegExp("".concat(U,": ([0-9]+)")),G=N.match(z);return parseInt(G[1],10)};O("comfortable-line-height-data"),O("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 pe(U){return U.ownerDocument?U.ownerDocument.defaultView:null}function ge(U){var z=pe(U);return z?z.frameElement:null}function ve(U){var z=ce(U);return ue([U.getBoundingClientRect(),{top:z.borderTop,left:z.borderLeft,bottom:z.borderBottom,right:z.borderRight,width:0,height:0}])}function ue(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=ge(U);if(G&&G!==z){for(var $=[U.getBoundingClientRect()],Ce=G,Ee=!1;Ce;){var Ae=ve(Ce);if($.push(Ae),Ce=ge(Ce),Ee)break;Ce&&pe(Ce)===z&&(Ee=!0)}return ue($)}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 re(ke,Je);var mt=Object.prototype.toString.call(ke).slice(8,-1);if(mt==="Object"&&ke.constructor&&(mt=ke.constructor.name),mt==="Map"||mt==="Set")return Array.from(ke);if(mt==="Arguments"||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(mt))return re(ke,Je)}}(U))||z&&U&&typeof U.length=="number"){G&&(U=G);var $=0,Ce=function(){};return{s:Ce,n:function(){return $>=U.length?{done:!0}:{done:!1,value:U[$++]}},e:function(ke){throw ke},f:Ce}}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 Ee,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,Ee=ke},f:function(){try{Ae||G.return==null||G.return()}finally{if(Z)throw Ee}}}}function re(U,z){(z==null||z>U.length)&&(z=U.length);for(var G=0,$=new Array(z);GAe.left+Ae.width&&(oe=Ae.left+Ae.width-mt-5),{style:{top:ke+="px",left:oe+="px"}}}(z,G,{width:$.width,height:$.height});m()(this.tip.style,Ce.style)}}]),U}(),Xe=function(){function U(){we(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 pt($,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,Ce=z.filter(function(Ct){return Ct.nodeType===Node.ELEMENT_NODE});this.rects.length>Ce.length;)this.rects.pop().remove();if(Ce.length!==0){for(;this.rects.length1&&arguments[1]!==void 0?arguments[1]:q,it=void 0,Ct=[],Mt=void 0,It=!1,sn=function(Ft,Dn){return We(Ft,Ct[Dn])},rn=function(){for(var Ft=arguments.length,Dn=Array(Ft),dr=0;dr5&&arguments[5]!==void 0?arguments[5]:0,Z=M0(U);switch(Z){case"html_element":return z.push($),{inspectable:!1,preview_short:ki(U,!1),preview_long:ki(U,!0),name:U.tagName,type:Z};case"function":return z.push($),{inspectable:!1,preview_short:ki(U,!1),preview_long:ki(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:ki(U,!1),preview_long:ki(U,!0),name:U.toString(),type:Z};case"react_element":return z.push($),{inspectable:!1,preview_short:ki(U,!1),preview_long:ki(U,!0),name:Po(U)||"Unknown",type:Z};case"array_buffer":case"data_view":return z.push($),{inspectable:!1,preview_short:ki(U,!1),preview_long:ki(U,!0),name:Z==="data_view"?"DataView":"ArrayBuffer",size:U.byteLength,type:Z};case"array":return Ee=Ce($),Ae>=2&&!Ee?po(Z,!0,U,z,$):U.map(function(mt,oe){return A0(mt,z,G,$.concat([oe]),Ce,Ee?1:Ae+1)});case"html_all_collection":case"typed_array":case"iterator":if(Ee=Ce($),Ae>=2&&!Ee)return po(Z,!0,U,z,$);var ke={unserializable:!0,type:Z,readonly:!0,size:Z==="typed_array"?U.length:void 0,preview_short:ki(U,!1),preview_long:ki(U,!0),name:U.constructor&&U.constructor.name!=="Object"?U.constructor.name:""};return Qt(U[Symbol.iterator])&&Array.from(U).forEach(function(mt,oe){return ke[oe]=A0(mt,z,G,$.concat([oe]),Ce,Ee?1:Ae+1)}),G.push($),ke;case"opaque_iterator":return z.push($),{inspectable:!1,preview_short:ki(U,!1),preview_long:ki(U,!0),name:U[Symbol.toStringTag],type:Z};case"date":case"regexp":return z.push($),{inspectable:!1,preview_short:ki(U,!1),preview_long:ki(U,!0),name:U.toString(),type:Z};case"object":if(Ee=Ce($),Ae>=2&&!Ee)return po(Z,!0,U,z,$);var Je={};return su(U).forEach(function(mt){var oe=mt.toString();Je[oe]=A0(U[mt],z,G,$.concat([oe]),Ce,Ee?1:Ae+1)}),Je;case"infinity":case"nan":case"undefined":return z.push($),{type:Z};default:return U}}function J0(U){return(J0=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 Z0(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 Z0(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 Z0(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 Z0(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 Ce=[].concat(Ps(Object.keys(G)),Ps(Object.getOwnPropertySymbols(G))),Ee=Object.getOwnPropertyDescriptors(G);Ce.forEach(function(Ae){Ee[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=$0.get(U);if(G!=null)return G;var $=z;return typeof U.displayName=="string"?$=U.displayName:typeof U.name=="string"&&U.name!==""&&($=U.name),$0.set(U,$),$}var Dr=0;function el(){return++Dr}function Ko(U){var z=Wt.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 ki(U,z){if(U!=null&&hasOwnProperty.call(U,wu.type))return z?U[wu.preview_long]:U[wu.preview_short];switch(M0(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(Po(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+=ki(U[$],!1)).length>50));$++);return"[".concat(au(G),"]")}var Ce=hasOwnProperty.call(U,wu.size)?U[wu.size]:U.length;return"Array(".concat(Ce,")");case"typed_array":var Ee="".concat(U.constructor.name,"(").concat(U.length,")");if(z){for(var Ae="",Z=0;Z0&&(Ae+=", "),!((Ae+=U[Z]).length>50));Z++);return"".concat(Ee," [").concat(au(Ae),"]")}return Ee;case"iterator":var ke=U.constructor.name;if(z){for(var Je=Array.from(U),mt="",oe=0;oe0&&(mt+=", "),Array.isArray(We)){var it=ki(We[0],!0),Ct=ki(We[1],!1);mt+="".concat(it," => ").concat(Ct)}else mt+=ki(We,!1);if(mt.length>50)break}return"".concat(ke,"(").concat(U.size,") {").concat(au(mt),"}")}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(xi),It="",sn=0;sn0&&(It+=", "),(It+="".concat(rn.toString(),": ").concat(ki(U[rn],!1))).length>50)break}return"{".concat(au(It),"}")}return"{\u2026}";case"boolean":case"number":case"infinity":case"nan":case"null":case"undefined":return U;default:try{return au(""+U)}catch(Ft){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 Io(U,z){var G=Object.keys(U);if(Object.getOwnPropertySymbols){var $=Object.getOwnPropertySymbols(U);z&&($=$.filter(function(Ce){return Object.getOwnPropertyDescriptor(U,Ce).enumerable})),G.push.apply(G,$)}return G}function ho(U){for(var z=1;z2&&arguments[2]!==void 0?arguments[2]:[];if(U!==null){var $=[],Ce=[],Ee=A0(U,$,Ce,G,z);return{data:Ee,cleaned:$,unserializable:Ce}}return null}function Qo(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})),Ce=$===void 0?"undefined":$,Ee=window.__REACT_DEVTOOLS_GLOBAL_HOOK__.clipboardCopyText;typeof Ee=="function"?Ee(Ce).catch(function(Ae){}):Object(Is.copy)(Ce)}function yi(U,z){var G=arguments.length>2&&arguments[2]!==void 0?arguments[2]:0,$=z[G],Ce=Array.isArray(U)?U.slice():ho({},U);return G+1===z.length?Array.isArray(Ce)?Ce.splice($,1):delete Ce[$]:Ce[$]=yi(U[$],z,G+1),Ce}function en(U,z,G){var $=arguments.length>3&&arguments[3]!==void 0?arguments[3]:0,Ce=z[$],Ee=Array.isArray(U)?U.slice():ho({},U);if($+1===z.length){var Ae=G[$];Ee[Ae]=Ee[Ce],Array.isArray(Ee)?Ee.splice(Ce,1):delete Ee[Ce]}else Ee[Ce]=en(U[Ce],z,G,$+1);return Ee}function bn(U,z,G){var $=arguments.length>3&&arguments[3]!==void 0?arguments[3]:0;if($>=z.length)return G;var Ce=z[$],Ee=Array.isArray(U)?U.slice():ho({},U);return Ee[Ce]=bn(U[Ce],z,G,$+1),Ee}var Ai=a(8);function gi(U,z){var G=Object.keys(U);if(Object.getOwnPropertySymbols){var $=Object.getOwnPropertySymbols(U);z&&($=$.filter(function(Ce){return Object.getOwnPropertyDescriptor(U,Ce).enumerable})),G.push.apply(G,$)}return G}function Vt(U){for(var z=1;z=U.length?{done:!0}:{done:!1,value:U[$++]}},e:function(ke){throw ke},f:Ce}}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 Ee,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,Ee=ke},f:function(){try{Ae||G.return==null||G.return()}finally{if(Z)throw Ee}}}}function Ql(U,z){if(U){if(typeof U=="string")return k0(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)?k0(U,z):void 0}}function k0(U,z){(z==null||z>U.length)&&(z=U.length);for(var G=0,$=new Array(z);G0){var yt=Ee(ae);if(yt!=null){var Jt,On=Yi(I0);try{for(On.s();!(Jt=On.n()).done;)if(Jt.value.test(yt))return!0}catch(ir){On.e(ir)}finally{On.f()}}}if(ie!=null&&gs.size>0){var Sn,_n=ie.fileName,Tn=Yi(gs);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 ie=ae.type;switch(ae.tag){case Ct:case Cr:return 1;case it:case An:return 5;case rn:return 6;case Ft:return 11;case dr:return 7;case Dn:case er:case sn:return 9;case Lr:case Nr:return 8;case ut:return 12;case Dt:return 13;default:switch(Ae(ie)){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(U0.has(ae))return ae;var ie=ae.alternate;return ie!=null&&U0.has(ie)?ie:(U0.add(ae),ae)}window.__REACT_DEVTOOLS_COMPONENT_FILTERS__!=null?_s(window.__REACT_DEVTOOLS_COMPONENT_FILTERS__):_s([{type:1,value:7,isEnabled:!0}]);var xo=new Map,e0=new Map,U0=new Set,sa=new Map,es=new Map,tu=-1;function ei(ae){if(!xo.has(ae)){var ie=el();xo.set(ae,ie),e0.set(ie,ae)}return xo.get(ae)}function h0(ae){switch(Tu(ae)){case 1:if(Uo!==null){var ie=ei(Ei(ae)),Fe=Ci(ae);Fe!==null&&Uo.set(ie,Fe)}}}var Bi={};function Ci(ae){switch(Tu(ae)){case 1:var ie=ae.stateNode,Fe=Bi,Oe=Bi;return ie!=null&&(ie.constructor&&ie.constructor.contextType!=null?Oe=ie.context:(Fe=ie.context)&&Object.keys(Fe).length===0&&(Fe=Bi)),[Fe,Oe];default:return null}}function yf(ae){switch(Tu(ae)){case 1:if(Uo!==null){var ie=ei(Ei(ae)),Fe=Uo.has(ie)?Uo.get(ie):null,Oe=Ci(ae);if(Fe==null||Oe==null)return null;var st=Jo(Fe,2),yt=st[0],Jt=st[1],On=Jo(Oe,2),Sn=On[0],_n=On[1];if(Sn!==Bi)return t0(yt,Sn);if(_n!==Bi)return Jt!==_n}}return null}function gf(ae,ie){if(ae==null||ie==null)return!1;if(ie.hasOwnProperty("baseState")&&ie.hasOwnProperty("memoizedState")&&ie.hasOwnProperty("next")&&ie.hasOwnProperty("queue"))for(;ie!==null;){if(ie.memoizedState!==ae.memoizedState)return!0;ie=ie.next,ae=ae.next}return!1}function t0(ae,ie){if(ae==null||ie==null||ie.hasOwnProperty("baseState")&&ie.hasOwnProperty("memoizedState")&&ie.hasOwnProperty("next")&&ie.hasOwnProperty("queue"))return null;var Fe,Oe=[],st=Yi(new Set([].concat(eu(Object.keys(ae)),eu(Object.keys(ie)))));try{for(st.s();!(Fe=st.n()).done;){var yt=Fe.value;ae[yt]!==ie[yt]&&Oe.push(yt)}}catch(Jt){st.e(Jt)}finally{st.f()}return Oe}function n0(ae,ie){switch(ie.tag){case Ct:case it:case Mt:case Lr:case Nr:return(f0(ie)&oe)===oe;default:return ae.memoizedProps!==ie.memoizedProps||ae.memoizedState!==ie.memoizedState||ae.ref!==ie.ref}}var Re=[],rt=[],Ye=[],Kt=[],Xt=new Map,pr=0,Wr=null;function xn(ae){Re.push(ae)}function yu(ae){if(Re.length!==0||rt.length!==0||Ye.length!==0||Wr!==null||Pu){var ie=rt.length+Ye.length+(Wr===null?0:1),Fe=new Array(3+pr+(ie>0?2+ie:0)+Re.length),Oe=0;if(Fe[Oe++]=z,Fe[Oe++]=tu,Fe[Oe++]=pr,Xt.forEach(function(On,Sn){Fe[Oe++]=Sn.length;for(var _n=Ko(Sn),Tn=0;Tn<_n.length;Tn++)Fe[Oe+Tn]=_n[Tn];Oe+=Sn.length}),ie>0){Fe[Oe++]=2,Fe[Oe++]=ie;for(var st=rt.length-1;st>=0;st--)Fe[Oe++]=rt[st];for(var yt=0;yt0?ae.forEach(function(ie){U.emit("operations",ie)}):(Rr!==null&&(cu=!0),U.getFiberRoots(z).forEach(function(ie){eo(tu=ei(Ei(ie.current)),ie.current),Pu&&ie.memoizedInteractions!=null&&(il={changeDescriptions:ts?new Map:null,durations:[],commitTime:Jl()-Zu,interactions:Array.from(ie.memoizedInteractions).map(function(Fe){return Vt(Vt({},Fe),{},{timestamp:Fe.timestamp-Zu})}),maxActualDuration:0,priorityLevel:null}),Jr(ie.current,null,!1,!1),yu(),tu=-1}))},getBestMatchForTrackedPath:function(){if(Rr===null||r0===null)return null;for(var ae=r0;ae!==null&&Qu(ae);)ae=ae.return;return ae===null?null:{id:ei(Ei(ae)),isFullMatch:nu===Rr.length-1}},getDisplayNameForFiberID:function(ae){var ie=e0.get(ae);return ie!=null?Ee(ie):null},getFiberIDForNative:function(ae){var ie=arguments.length>1&&arguments[1]!==void 0&&arguments[1],Fe=G.findFiberByHostInstance(ae);if(Fe!=null){if(ie)for(;Fe!==null&&Qu(Fe);)Fe=Fe.return;return ei(Ei(Fe))}return null},getInstanceAndStyle:function(ae){var ie=null,Fe=null,Oe=Vu(ae);return Oe!==null&&(ie=Oe.stateNode,Oe.memoizedProps!==null&&(Fe=Oe.memoizedProps.style)),{instance:ie,style:Fe}},getOwnersList:function(ae){var ie=Vu(ae);if(ie==null)return null;var Fe=ie._debugOwner,Oe=[{displayName:Ee(ie)||"Anonymous",id:ae,type:Tu(ie)}];if(Fe)for(var st=Fe;st!==null;)Oe.unshift({displayName:Ee(st)||"Anonymous",id:ei(Ei(st)),type:Tu(st)}),st=st._debugOwner||null;return Oe},getPathForElement:function(ae){var ie=e0.get(ae);if(ie==null)return null;for(var Fe=[];ie!==null;)Fe.push(Do(ie)),ie=ie.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(ie,Fe){var Oe=[],st=[],yt=new Map,Jt=new Map,On=xl!==null&&xl.get(Fe)||"Unknown";Mo!=null&&Mo.forEach(function(Sn,_n){v0!=null&&v0.get(_n)===Fe&&st.push([_n,Sn])}),ie.forEach(function(Sn,_n){var Tn=Sn.changeDescriptions,ir=Sn.durations,Bt=Sn.interactions,Fi=Sn.maxActualDuration,Ar=Sn.priorityLevel,mr=Sn.commitTime,Y=[];Bt.forEach(function(Di){yt.has(Di.id)||yt.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 eo(tu,Fe),Jr(Fe,null,!1,!1);if(Pu&&st){var On=Es.get(tu);On!=null?On.push(il):Es.set(tu,[il])}yu(),b0&&U.emit("traceUpdates",B0),tu=-1},handleCommitFiberUnmount:function(ae){ti(ae,!1)},inspectElement:function(ae,ie){if(zi(ae)){if(ie!=null){Oo(ie);var Fe=null;return ie[0]==="hooks"&&(Fe="hooks"),{id:ae,type:"hydrated-path",path:ie,value:Ri(Uu(Xi,ie),Hi(null,Fe),ie)}}return{id:ae,type:"no-change"}}if(qs=!1,Xi!==null&&Xi.id===ae||(Ao={}),(Xi=aa(ae))===null)return{id:ae,type:"not-found"};ie!=null&&Oo(ie),function(st){var yt=st.hooks,Jt=st.id,On=st.props,Sn=e0.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 An:$.$r=Tn;break;case it:$.$r={hooks:yt,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 Oe=Vt({},Xi);return Oe.context=Ri(Oe.context,Hi("context",null)),Oe.hooks=Ri(Oe.hooks,Hi("hooks","hooks")),Oe.props=Ri(Oe.props,Hi("props",null)),Oe.state=Ri(Oe.state,Hi("state",null)),{id:ae,type:"full-data",value:Oe}},logElementToConsole:function(ae){var ie=zi(ae)?Xi:aa(ae);if(ie!==null){var Fe=typeof console.groupCollapsed=="function";Fe&&console.groupCollapsed("[Click to expand] %c<".concat(ie.displayName||"Component"," />"),"color: var(--dom-tag-name-color); font-weight: normal;"),ie.props!==null&&console.log("Props:",ie.props),ie.state!==null&&console.log("State:",ie.state),ie.hooks!==null&&console.log("Hooks:",ie.hooks);var Oe=Cl(ae);Oe!==null&&console.log("Nodes:",Oe),ie.source!==null&&console.log("Location:",ie.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,ie){zi(ae)&&(window.$attribute=Uu(Xi,ie))},prepareViewElementSource:function(ae){var ie=e0.get(ae);if(ie!=null){var Fe=ie.elementType,Oe=ie.tag,st=ie.type;switch(Oe){case Ct:case Cr:case An:case it:$.$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,ie){if(typeof P0!="function"||typeof rl!="function")throw new Error("Expected overrideSuspense() to not get called for earlier React versions.");ie?($u.add(ae),$u.size===1&&P0(Ds)):($u.delete(ae),$u.size===0&&P0(_f));var Fe=e0.get(ae);Fe!=null&&rl(Fe)},overrideValueAtPath:function(ae,ie,Fe,Oe,st){var yt=Vu(ie);if(yt!==null){var Jt=yt.stateNode;switch(ae){case"context":switch(Oe=Oe.slice(1),yt.tag){case Ct:Oe.length===0?Jt.context=st:O0(Jt.context,Oe,st),Jt.forceUpdate()}break;case"hooks":typeof fu=="function"&&fu(yt,Fe,Oe,st);break;case"props":switch(yt.tag){case Ct:yt.pendingProps=bn(Jt.props,Oe,st),Jt.forceUpdate();break;default:typeof $o=="function"&&$o(yt,Oe,st)}break;case"state":switch(yt.tag){case Ct:O0(Jt.state,Oe,st),Jt.forceUpdate()}}}},renamePath:function(ae,ie,Fe,Oe,st){var yt=Vu(ie);if(yt!==null){var Jt=yt.stateNode;switch(ae){case"context":switch(Oe=Oe.slice(1),st=st.slice(1),yt.tag){case Ct:Oe.length===0||Xr(Jt.context,Oe,st),Jt.forceUpdate()}break;case"hooks":typeof Co=="function"&&Co(yt,Fe,Oe,st);break;case"props":Jt===null?typeof _i=="function"&&_i(yt,Oe,st):(yt.pendingProps=en(Jt.props,Oe,st),Jt.forceUpdate());break;case"state":Xr(Jt.state,Oe,st),Jt.forceUpdate()}}},renderer:G,setTraceUpdatesEnabled:function(ae){b0=ae},setTrackedPath:Ni,startProfiling:fa,stopProfiling:function(){Pu=!1,ts=!1},storeAsGlobal:function(ae,ie,Fe){if(zi(ae)){var Oe=Uu(Xi,ie),st="$reactTemp".concat(Fe);window[st]=Oe,console.log(st),console.log(Oe)}},updateComponentFilters:function(ae){if(Pu)throw Error("Cannot modify filter preferences while profiling");U.getFiberRoots(z).forEach(function(ie){tu=ei(Ei(ie.current)),Wu(ie.current),ti(ie.current,!1),tu=-1}),_s(ae),Kn.clear(),U.getFiberRoots(z).forEach(function(ie){eo(tu=ei(Ei(ie.current)),ie.current),Jr(ie.current,null,!1,!1),yu(ie),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 c0(U,z,G){if($n===void 0)try{throw Error()}catch(Ce){var $=Ce.stack.trim().match(/\n( *(at )?)/);$n=$&&$[1]||""}return` -`+$n+U}var bo=!1;function Sl(U,z,G){if(!U||bo)return"";var $,Ce=Error.prepareStackTrace;Error.prepareStackTrace=void 0,bo=!0;var Ee=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(We){$=We}Reflect.construct(U,[],Ae)}else{try{Ae.call()}catch(We){$=We}U.call(Ae.prototype)}}else{try{throw Error()}catch(We){$=We}U()}}catch(We){if(We&&$&&typeof We.stack=="string"){for(var Z=We.stack.split(` -`),ke=$.stack.split(` -`),Je=Z.length-1,mt=ke.length-1;Je>=1&&mt>=0&&Z[Je]!==ke[mt];)mt--;for(;Je>=1&&mt>=0;Je--,mt--)if(Z[Je]!==ke[mt]){if(Je!==1||mt!==1)do if(Je--,--mt<0||Z[Je]!==ke[mt])return` -`+Z[Je].replace(" at new "," at ");while(Je>=1&&mt>=0);break}}}finally{bo=!1,Error.prepareStackTrace=Ce,G.current=Ee}var oe=U?U.displayName||U.name:"";return oe?c0(oe):""}function N0(U,z,G,$){return Sl(U,!1,$)}function wt(U,z,G){var $=U.HostComponent,Ce=U.LazyComponent,Ee=U.SuspenseComponent,Ae=U.SuspenseListComponent,Z=U.FunctionComponent,ke=U.IndeterminateComponent,Je=U.SimpleMemoComponent,mt=U.ForwardRef,oe=U.Block,We=U.ClassComponent;switch(z.tag){case $:return c0(z.type);case Ce:return c0("Lazy");case Ee:return c0("Suspense");case Ae:return c0("SuspenseList");case Z:case ke:case Je:return N0(z.type,0,0,G);case mt:return N0(z.type.render,0,0,G);case oe:return N0(z.type._render,0,0,G);case We:return function(it,Ct,Mt,It){return Sl(it,!0,It)}(z.type,0,0,G);default:return""}}function bt(U,z,G){try{var $="",Ce=z;do $+=wt(U,Ce,G),Ce=Ce.return;while(Ce);return $}catch(Ee){return` -Error generating stack: `+Ee.message+` -`+Ee.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 mt=Object.prototype.toString.call(ke).slice(8,-1);if(mt==="Object"&&ke.constructor&&(mt=ke.constructor.name),mt==="Map"||mt==="Set")return Array.from(ke);if(mt==="Arguments"||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(mt))return qr(ke,Je)}}(U))||z&&U&&typeof U.length=="number"){G&&(U=G);var $=0,Ce=function(){};return{s:Ce,n:function(){return $>=U.length?{done:!0}:{done:!1,value:U[$++]}},e:function(ke){throw ke},f:Ce}}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 Ee,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,Ee=ke},f:function(){try{Ae||G.return==null||G.return()}finally{if(Z)throw Ee}}}}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,We=oe!==null&&(Qr.test(oe)||Ou.test(oe));if(!We){var it,Ct=Hn(vo.values());try{for(Ct.s();!(it=Ct.n()).done;){var Mt=it.value,It=Mt.currentDispatcherRef,sn=Mt.getCurrentFiber,rn=Mt.workTagMap,Ft=sn();if(Ft!=null){var Dn=bt(rn,Ft,It);Dn!==""&&Je.push(Dn);break}}}catch(dr){Ct.e(dr)}finally{Ct.f()}}}catch(dr){}Ee.apply(void 0,Je)};Ae.__REACT_DEVTOOLS_ORIGINAL_METHOD__=Ee,Li[Ce]=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?oe[oe.length-1]:0),oe.push(un),Z.set(et,Je(Pt._topLevelWrapper));try{var fn=ut.apply(this,Dt);return oe.pop(),fn}catch(wr){throw oe=[],wr}finally{if(oe.length===0){var Jn=Z.get(et);if(Jn===void 0)throw new Error("Expected to find root ID.");dr(Jn)}}},performUpdateIfNecessary:function(ut,Dt){var et=Dt[0];if(To(et)===9)return ut.apply(this,Dt);var Pt=Je(et);oe.push(Pt);var un=Qn(et);try{var fn=ut.apply(this,Dt),Jn=Qn(et);return mt(un,Jn)||Ct(et,Pt,Jn),oe.pop(),fn}catch(fu){throw oe=[],fu}finally{if(oe.length===0){var wr=Z.get(et);if(wr===void 0)throw new Error("Expected to find root ID.");dr(wr)}}},receiveComponent:function(ut,Dt){var et=Dt[0];if(To(et)===9)return ut.apply(this,Dt);var Pt=Je(et);oe.push(Pt);var un=Qn(et);try{var fn=ut.apply(this,Dt),Jn=Qn(et);return mt(un,Jn)||Ct(et,Pt,Jn),oe.pop(),fn}catch(fu){throw oe=[],fu}finally{if(oe.length===0){var wr=Z.get(et);if(wr===void 0)throw new Error("Expected to find root ID.");dr(wr)}}},unmountComponent:function(ut,Dt){var et=Dt[0];if(To(et)===9)return ut.apply(this,Dt);var Pt=Je(et);oe.push(Pt);try{var un=ut.apply(this,Dt);return oe.pop(),function(Jn,wr){rn.push(wr),Ee.delete(wr)}(0,Pt),un}catch(Jn){throw oe=[],Jn}finally{if(oe.length===0){var fn=Z.get(et);if(fn===void 0)throw new Error("Expected to find root ID.");dr(fn)}}}}));var It=[],sn=new Map,rn=[],Ft=0,Dn=null;function dr(ut){if(It.length!==0||rn.length!==0||Dn!==null){var Dt=rn.length+(Dn===null?0:1),et=new Array(3+Ft+(Dt>0?2+Dt:0)+It.length),Pt=0;if(et[Pt++]=z,et[Pt++]=ut,et[Pt++]=Ft,sn.forEach(function(Jn,wr){et[Pt++]=wr.length;for(var fu=Ko(wr),Lu=0;Lu0){et[Pt++]=2,et[Pt++]=Dt;for(var un=0;un"),"color: var(--dom-tag-name-color); font-weight: normal;"),Dt.props!==null&&console.log("Props:",Dt.props),Dt.state!==null&&console.log("State:",Dt.state),Dt.context!==null&&console.log("Context:",Dt.context);var Pt=Ce(ut);Pt!==null&&console.log("Node:",Pt),(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(ut,'"'))},overrideSuspense:function(){throw new Error("overrideSuspense not supported by this renderer")},overrideValueAtPath:function(ut,Dt,et,Pt,un){var fn=Ee.get(Dt);if(fn!=null){var Jn=fn._instance;if(Jn!=null)switch(ut){case"context":O0(Jn.context,Pt,un),yo(Jn);break;case"hooks":throw new Error("Hooks not supported by this renderer");case"props":var wr=fn._currentElement;fn._currentElement=Zo(Zo({},wr),{},{props:bn(wr.props,Pt,un)}),yo(Jn);break;case"state":O0(Jn.state,Pt,un),yo(Jn)}}},renamePath:function(ut,Dt,et,Pt,un){var fn=Ee.get(Dt);if(fn!=null){var Jn=fn._instance;if(Jn!=null)switch(ut){case"context":Xr(Jn.context,Pt,un),yo(Jn);break;case"hooks":throw new Error("Hooks not supported by this renderer");case"props":var wr=fn._currentElement;fn._currentElement=Zo(Zo({},wr),{},{props:en(wr.props,Pt,un)}),yo(Jn);break;case"state":Xr(Jn.state,Pt,un),yo(Jn)}}},prepareViewAttributeSource:function(ut,Dt){var et=Nr(ut);et!==null&&(window.$attribute=Uu(et,Dt))},prepareViewElementSource:function(ut){var Dt=Ee.get(ut);if(Dt!=null){var et=Dt._currentElement;et!=null?$.$type=et.type:console.warn('Could not find element with id "'.concat(ut,'"'))}else console.warn('Could not find instance with id "'.concat(ut,'"'))},renderer:G,setTraceUpdatesEnabled:function(ut){},setTrackedPath:function(ut){},startProfiling:function(){},stopProfiling:function(){},storeAsGlobal:function(ut,Dt,et){var Pt=Nr(ut);if(Pt!==null){var un=Uu(Pt,Dt),fn="$reactTemp".concat(et);window[fn]=un,console.log(fn),console.log(un)}},updateComponentFilters:function(ut){}}}function fi(U,z){var G=!1,$={bottom:0,left:0,right:0,top:0},Ce=z[U];if(Ce!=null){for(var Ee=0,Ae=Object.keys($);Ee0?"development":"production";var It=Function.prototype.toString;if(Mt.Mount&&Mt.Mount._renderNewRootComponent){var sn=It.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 oe=window.__REACT_DEVTOOLS_APPEND_COMPONENT_STACK__!==!1,We=window.__REACT_DEVTOOLS_BREAK_ON_CONSOLE_ERRORS__===!0;(oe||We)&&(d0(ke),Zl({appendComponentStack:oe,breakOnConsoleErrors:We}))}catch(Mt){}var it=U.__REACT_DEVTOOLS_ATTACH__;if(typeof it=="function"){var Ct=it(Z,Je,ke,U);Z.rendererInterfaces.set(Je,Ct)}return Z.emit("renderer",{id:Je,renderer:ke,reactBuildType:mt}),Je},on:function(ke,Je){Ee[ke]||(Ee[ke]=[]),Ee[ke].push(Je)},off:function(ke,Je){if(Ee[ke]){var mt=Ee[ke].indexOf(Je);mt!==-1&&Ee[ke].splice(mt,1),Ee[ke].length||delete Ee[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 mt=Ce.get(ke);mt!=null&&mt.handleCommitFiberUnmount(Je)},onCommitFiberRoot:function(ke,Je,mt){var oe=Z.getFiberRoots(ke),We=Je.current,it=oe.has(Je),Ct=We.memoizedState==null||We.memoizedState.element==null;it||Ct?it&&Ct&&oe.delete(Je):oe.add(Je);var Mt=Ce.get(ke);Mt!=null&&Mt.handleCommitFiberRoot(Je,mt)}};Object.defineProperty(U,"__REACT_DEVTOOLS_GLOBAL_HOOK__",{configurable:!1,enumerable:!1,get:function(){return Z}})})(window);var go=window.__REACT_DEVTOOLS_GLOBAL_HOOK__,js=[{type:1,value:7,isEnabled:!0}];function ji(U){if(go!=null){var z=U||{},G=z.host,$=G===void 0?"localhost":G,Ce=z.nativeStyleEditorValidAttributes,Ee=z.useHttps,Ae=Ee!==void 0&&Ee,Z=z.port,ke=Z===void 0?8097:Z,Je=z.websocket,mt=z.resolveRNStyle,oe=mt===void 0?null:mt,We=z.isAppActive,it=Ae?"wss":"ws",Ct=null;if((We===void 0?function(){return!0}:We)()){var Mt=null,It=[],sn=it+"://"+$+":"+ke,rn=Je||new window.WebSocket(sn);rn.onclose=function(){Mt!==null&&Mt.emit("shutdown"),Ft()},rn.onerror=function(){Ft()},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)}It.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 p0({listen:function(An){return It.push(An),function(){var Lr=It.indexOf(An);Lr>=0&&It.splice(Lr,1)}},send:function(An,Lr,_o){rn.readyState===rn.OPEN?rn.send(JSON.stringify({event:An,payload:Lr})):(Mt!==null&&Mt.shutdown(),Ft())}})).addListener("inspectElement",function(An){var Lr=An.id,_o=An.rendererID,Nr=Dn.rendererInterfaces[_o];if(Nr!=null){var ut=Nr.findNativeNodesForFiberID(Lr);ut!=null&&ut[0]!=null&&Dn.emit("showNativeHighlight",ut[0])}}),Mt.addListener("updateComponentFilters",function(An){js=An}),window.__REACT_DEVTOOLS_COMPONENT_FILTERS__==null&&Mt.send("overrideComponentFilters",js);var Dn=new Yn(Mt);if(Dn.addListener("shutdown",function(){go.emit("shutdown")}),function(An,Lr,_o){if(An==null)return function(){};var Nr=[An.sub("renderer-attached",function(et){var Pt=et.id,un=(et.renderer,et.rendererInterface);Lr.setRendererInterface(Pt,un),un.flushInitialOperations()}),An.sub("unsupported-renderer-version",function(et){Lr.onUnsupportedRenderer(et)}),An.sub("operations",Lr.onHookOperations),An.sub("traceUpdates",Lr.onTraceUpdates)],ut=function(et,Pt){var un=An.rendererInterfaces.get(et);un==null&&(typeof Pt.findFiberByHostInstance=="function"?un=bs(An,et,Pt,_o):Pt.ComponentTree&&(un=fc(An,et,Pt,_o)),un!=null&&An.rendererInterfaces.set(et,un)),un!=null?An.emit("renderer-attached",{id:et,renderer:Pt,rendererInterface:un}):An.emit("unsupported-renderer-version",et)};An.renderers.forEach(function(et,Pt){ut(Pt,et)}),Nr.push(An.sub("renderer",function(et){var Pt=et.id,un=et.renderer;ut(Pt,un)})),An.emit("react-devtools",Lr),An.reactDevtoolsAgent=Lr;var Dt=function(){Nr.forEach(function(et){return et()}),An.rendererInterfaces.forEach(function(et){et.cleanup()}),An.reactDevtoolsAgent=null};Lr.addListener("shutdown",Dt),Nr.push(function(){Lr.removeListener("shutdown",Dt)})}(go,Dn,window),oe!=null||go.resolveRNStyle!=null)la(Mt,Dn,oe||go.resolveRNStyle,Ce||go.nativeStyleEditorValidAttributes||null);else{var dr,er,Cr=function(){Mt!==null&&la(Mt,Dn,dr,er)};go.hasOwnProperty("resolveRNStyle")||Object.defineProperty(go,"resolveRNStyle",{enumerable:!1,get:function(){return dr},set:function(An){dr=An,Cr()}}),go.hasOwnProperty("nativeStyleEditorValidAttributes")||Object.defineProperty(go,"nativeStyleEditorValidAttributes",{enumerable:!1,get:function(){return er},set:function(An){er=An,Cr()}})}}}else Ft()}function Ft(){Ct===null&&(Ct=setTimeout(function(){return ji(U)},2e3))}}}])})});var f6=Ke(a6=>{"use strict";Object.defineProperty(a6,"__esModule",{value:!0});l6();var HB=s6();HB.connectToDevTools()});var v6=Ke(dg=>{"use strict";var c6=dg&&dg.__importDefault||function(i){return i&&i.__esModule?i:{default:i}};Object.defineProperty(dg,"__esModule",{value:!0});var d6=Q_(),qB=c6(vT()),p6=c6(eh()),hs=iw();process.env.DEV==="true"&&f6();var h6=i=>{i==null||i.unsetMeasureFunc(),i==null||i.freeRecursive()};dg.default=qB.default({schedulePassiveEffects:d6.unstable_scheduleCallback,cancelPassiveEffects:d6.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[M,N]of Object.entries(o))M!=="children"&&(M==="style"?hs.setStyle(t,N):M==="internal_transform"?t.internal_transform=N:M==="internal_static"?t.internal_static=!0:hs.setAttribute(t,M,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(p6.default.DISPLAY_NONE)},unhideInstance:i=>{var o;(o=i.yogaNode)===null||o===void 0||o.setDisplay(p6.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),h6(o.yogaNode)},prepareUpdate:(i,o,a,c,_)=>{i.internal_static&&(_.isStaticDirty=!0);let t={},M=Object.keys(c);for(let N of M)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),h6(o.yogaNode)}})});var y6=Ke((AV,m6)=>{"use strict";m6.exports=(i,o=1,a)=>{if(a=qt({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(pg=>{"use strict";var WB=pg&&pg.__importDefault||function(i){return i&&i.__esModule?i:{default:i}};Object.defineProperty(pg,"__esModule",{value:!0});var d4=WB(eh());pg.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 E6=Ke((MV,_6)=>{_6.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 w6=Ke((kV,Sw)=>{"use strict";var D6=E6();Sw.exports=D6;Sw.exports.default=D6});var T6=Ke((LV,S6)=>{"use strict";S6.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 R6=Ke((NV,C6)=>{"use strict";var VB=require("os"),x6=require("tty"),pf=T6(),{env:X0}=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 X0&&(X0.FORCE_COLOR==="true"?m2=1:X0.FORCE_COLOR==="false"?m2=0:m2=X0.FORCE_COLOR.length===0?1:Math.min(parseInt(X0.FORCE_COLOR,10),3));function Tw(i){return i===0?!1:{level:i,hasBasic:!0,has256:i>=2,has16m:i>=3}}function Cw(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(X0.TERM==="dumb")return a;if(process.platform==="win32"){let c=VB.release().split(".");return Number(c[0])>=10&&Number(c[2])>=10586?Number(c[2])>=14931?3:2:1}if("CI"in X0)return["TRAVIS","CIRCLECI","APPVEYOR","GITLAB_CI"].some(c=>c in X0)||X0.CI_NAME==="codeship"?1:a;if("TEAMCITY_VERSION"in X0)return/^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(X0.TEAMCITY_VERSION)?1:0;if("GITHUB_ACTIONS"in X0)return 1;if(X0.COLORTERM==="truecolor")return 3;if("TERM_PROGRAM"in X0){let c=parseInt((X0.TERM_PROGRAM_VERSION||"").split(".")[0],10);switch(X0.TERM_PROGRAM){case"iTerm.app":return c>=3?3:2;case"Apple_Terminal":return 2}}return/-256(color)?$/i.test(X0.TERM)?2:/^screen|^xterm|^vt100|^vt220|^rxvt|color|ansi|cygwin|linux/i.test(X0.TERM)||"COLORTERM"in X0?1:a}function GB(i){let o=Cw(i,i&&i.isTTY);return Tw(o)}C6.exports={supportsColor:GB,stdout:Tw(Cw(!0,x6.isatty(1))),stderr:Tw(Cw(!0,x6.isatty(2)))}});var O6=Ke((FV,A6)=>{"use strict";var YB=(i,o,a)=>{let c=i.indexOf(o);if(c===-1)return i;let _=o.length,t=0,M="";do M+=i.substr(t,c-t)+o+a,t=c+_,c=i.indexOf(o,t);while(c!==-1);return M+=i.substr(t),M},KB=(i,o,a,c)=>{let _=0,t="";do{let M=i[c-1]==="\r";t+=i.substr(_,(M?c-1:c)-_)+o+(M?`\r -`:` -`)+a,_=c+1,c=i.indexOf(` -`,_)}while(c!==-1);return t+=i.substr(_),t};A6.exports={stringReplaceAll:YB,stringEncaseCRLFWithFirstIndex:KB}});var F6=Ke((PV,M6)=>{"use strict";var XB=/(?:\\(u(?:[a-f\d]{4}|\{[a-f\d]{1,6}\})|x[a-f\d]{2}|.))|(?:\{(~)?(\w+(?:\([^)]*\))?(?:\.\w+(?:\([^)]*\))?)*)(?:[ \t]|(?=\r?\n)))|(\})|((?:.|[\r\n\f])+?)/gi,k6=/(?:^|\.)(\w+)(?:\(([^)]*)\))?/g,QB=/^(['"])((?:\\.|(?!\1)[^\\])*)\1$/,JB=/\\(u(?:[a-f\d]{4}|{[a-f\d]{1,6}})|x[a-f\d]{2}|.)|([^\\])/gi,ZB=new Map([["n",` -`],["r","\r"],["t"," "],["b","\b"],["f","\f"],["v","\v"],["0","\0"],["\\","\\"],["e",""],["a","\x07"]]);function L6(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)):ZB.get(i)||i}function $B(i,o){let a=[],c=o.trim().split(/\s*,\s*/g),_;for(let t of c){let M=Number(t);if(!Number.isNaN(M))a.push(M);else if(_=t.match(QB))a.push(_[2].replace(JB,(N,O,T)=>O?L6(O):T));else throw new Error(`Invalid Chalk template style argument: ${t} (in style '${i}')`)}return a}function eU(i){k6.lastIndex=0;let o=[],a;for(;(a=k6.exec(i))!==null;){let c=a[1];if(a[2]){let _=$B(c,a[2]);o.push([c].concat(_))}else o.push([c])}return o}function N6(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}M6.exports=(i,o)=>{let a=[],c=[],_=[];if(o.replace(XB,(t,M,N,O,T,B)=>{if(M)_.push(L6(M));else if(O){let H=_.join("");_=[],c.push(a.length===0?H:N6(i,a)(H)),a.push({inverse:N,styles:eU(O)})}else if(T){if(a.length===0)throw new Error("Found extraneous } in Chalk template literal");c.push(N6(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 y4=Ke((IV,P6)=>{"use strict";var hg=t4(),{stdout:xw,stderr:Rw}=R6(),{stringReplaceAll:tU,stringEncaseCRLFWithFirstIndex:nU}=O6(),{isArray:p4}=Array,I6=["ansi","ansi","ansi256","ansi16m"],$v=Object.create(null),rU=(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=xw?xw.level:0;i.level=o.level===void 0?a:o.level},b6=class{constructor(o){return B6(o)}},B6=i=>{let o={};return rU(o,i),o.template=(...a)=>U6(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=b6,o.template};function h4(i){return B6(i)}for(let[i,o]of Object.entries(hg))$v[i]={get(){let a=v4(this,Aw(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 j6=["rgb","hex","keyword","hsl","hsv","hwb","ansi","ansi256"];for(let i of j6)$v[i]={get(){let{level:o}=this;return function(...a){let c=Aw(hg.color[I6[o]][i](...a),hg.color.close,this._styler);return v4(this,c,this._isEmpty)}}};for(let i of j6){let o="bg"+i[0].toUpperCase()+i.slice(1);$v[o]={get(){let{level:a}=this;return function(...c){let _=Aw(hg.bgColor[I6[a]][i](...c),hg.bgColor.close,this._styler);return v4(this,_,this._isEmpty)}}}}var iU=Object.defineProperties(()=>{},Zr(qt({},$v),{level:{enumerable:!0,get(){return this._generator.level},set(i){this._generator.level=i}}})),Aw=(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)?z6(c,U6(c,..._)):z6(c,_.length===1?""+_[0]:_.join(" "));return Object.setPrototypeOf(c,iU),c._generator=i,c._styler=o,c._isEmpty=a,c},z6=(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=tU(o,a.close,a.open),a=a.parent;let t=o.indexOf(` -`);return t!==-1&&(o=nU(o,_,c,t)),c+o+_},Ow,U6=(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 uU=vg&&vg.__importDefault||function(i){return i&&i.__esModule?i:{default:i}};Object.defineProperty(vg,"__esModule",{value:!0});var mg=uU(y4()),oU=/^(rgb|hsl|hsv|hwb)\(\s?(\d+),\s?(\d+),\s?(\d+)\s?\)$/,lU=/^(ansi|ansi256)\(\s?(\d+)\s?\)$/,g4=(i,o)=>o==="foreground"?i:"bg"+i[0].toUpperCase()+i.slice(1);vg.default=(i,o,a)=>{if(!o)return i;if(o in mg.default){let _=g4(o,a);return mg.default[_](i)}if(o.startsWith("#")){let _=g4("hex",a);return mg.default[_](o)(i)}if(o.startsWith("ansi")){let _=lU.exec(o);if(!_)return i;let t=g4(_[1],a),M=Number(_[2]);return mg.default[t](M)(i)}if(o.startsWith("rgb")||o.startsWith("hsl")||o.startsWith("hsv")||o.startsWith("hwb")){let _=oU.exec(o);if(!_)return i;let t=g4(_[1],a),M=Number(_[2]),N=Number(_[3]),O=Number(_[4]);return mg.default[t](M,N,O)(i)}return i}});var q6=Ke(yg=>{"use strict";var H6=yg&&yg.__importDefault||function(i){return i&&i.__esModule?i:{default:i}};Object.defineProperty(yg,"__esModule",{value:!0});var sU=H6(w6()),kw=H6(Mw());yg.default=(i,o,a,c)=>{if(typeof a.style.borderStyle=="string"){let _=a.yogaNode.getComputedWidth(),t=a.yogaNode.getComputedHeight(),M=a.style.borderColor,N=sU.default[a.style.borderStyle],O=kw.default(N.topLeft+N.horizontal.repeat(_-2)+N.topRight,M,"foreground"),T=(kw.default(N.vertical,M,"foreground")+` -`).repeat(t-2),B=kw.default(N.bottomLeft+N.horizontal.repeat(_-2)+N.bottomRight,M,"foreground");c.write(i,o,O,{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 V6=Ke(gg=>{"use strict";var ih=gg&&gg.__importDefault||function(i){return i&&i.__esModule?i:{default:i}};Object.defineProperty(gg,"__esModule",{value:!0});var aU=ih(eh()),fU=ih(GD()),cU=ih(y6()),dU=ih(tw()),pU=ih(g6()),hU=ih(rw()),vU=ih(q6()),mU=(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)+cU.default(o,_)}return o},W6=(i,o,a)=>{var c;let{offsetX:_=0,offsetY:t=0,transformers:M=[],skipStaticElements:N}=a;if(N&&i.internal_static)return;let{yogaNode:O}=i;if(O){if(O.getDisplay()===aU.default.DISPLAY_NONE)return;let T=_+O.getComputedLeft(),B=t+O.getComputedTop(),H=M;if(typeof i.internal_transform=="function"&&(H=[i.internal_transform,...M]),i.nodeName==="ink-text"){let q=hU.default(i);if(q.length>0){let ne=fU.default(q),m=pU.default(O);if(ne>m){let pe=(c=i.style.textWrap)!==null&&c!==void 0?c:"wrap";q=dU.default(q,m,pe)}q=mU(i,q),o.write(T,B,q,{transformers:H})}return}if(i.nodeName==="ink-box"&&vU.default(T,B,i,o),i.nodeName==="ink-root"||i.nodeName==="ink-box")for(let q of i.childNodes)W6(q,o,{offsetX:T,offsetY:B,transformers:H,skipStaticElements:N})}};gg.default=W6});var Y6=Ke((jV,G6)=>{"use strict";G6.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 X6=Ke((zV,Lw)=>{"use strict";var yU=Y6(),K6=i=>typeof i=="string"?i.replace(yU(),""):i;Lw.exports=K6;Lw.exports.default=K6});var Z6=Ke((HV,Q6)=>{"use strict";var J6="[\uD800-\uDBFF][\uDC00-\uDFFF]";Q6.exports=i=>i&&i.exact?new RegExp(`^${J6}$`):new RegExp(J6,"g")});var ex=Ke((qV,Nw)=>{"use strict";var gU=X6(),_U=Z6(),$6=i=>gU(i).replace(_U()," ").length;Nw.exports=$6;Nw.exports.default=$6});var ix=Ke(_g=>{"use strict";var tx=_g&&_g.__importDefault||function(i){return i&&i.__esModule?i:{default:i}};Object.defineProperty(_g,"__esModule",{value:!0});var nx=tx($D()),EU=tx(ex()),rx=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}}};_g.default=rx});var lx=Ke(Eg=>{"use strict";var Fw=Eg&&Eg.__importDefault||function(i){return i&&i.__esModule?i:{default:i}};Object.defineProperty(Eg,"__esModule",{value:!0});var DU=Fw(eh()),ux=Fw(V6()),ox=Fw(ix());Eg.default=(i,o)=>{var a;if(i.yogaNode.setWidth(o),i.yogaNode){i.yogaNode.calculateLayout(void 0,void 0,DU.default.DIRECTION_LTR);let c=new ox.default({width:i.yogaNode.getComputedWidth(),height:i.yogaNode.getComputedHeight()});ux.default(i,c,{skipStaticElements:!0});let _;((a=i.staticNode)===null||a===void 0?void 0:a.yogaNode)&&(_=new ox.default({width:i.staticNode.yogaNode.getComputedWidth(),height:i.staticNode.yogaNode.getComputedHeight()}),ux.default(i.staticNode,_,{skipStaticElements:!1}));let{output:t,height:M}=c.get();return{output:t,outputHeight:M,staticOutput:_?`${_.get().output} -`:""}}return{output:"",outputHeight:0,staticOutput:""}}});var cx=Ke((GV,sx)=>{"use strict";var ax=require("stream"),fx=["assert","count","countReset","debug","dir","dirxml","error","group","groupCollapsed","groupEnd","info","log","table","time","timeEnd","timeLog","trace","warn"],Pw={},wU=i=>{let o=new ax.PassThrough,a=new ax.PassThrough;o.write=_=>i("stdout",_),a.write=_=>i("stderr",_);let c=new console.Console(o,a);for(let _ of fx)Pw[_]=console[_],console[_]=c[_];return()=>{for(let _ of fx)console[_]=Pw[_];Pw={}}};sx.exports=wU});var bw=Ke(Iw=>{"use strict";Object.defineProperty(Iw,"__esModule",{value:!0});Iw.default=new WeakMap});var Uw=Ke(Bw=>{"use strict";Object.defineProperty(Bw,"__esModule",{value:!0});var SU=Mi(),dx=SU.createContext({exit:()=>{}});dx.displayName="InternalAppContext";Bw.default=dx});var zw=Ke(jw=>{"use strict";Object.defineProperty(jw,"__esModule",{value:!0});var TU=Mi(),px=TU.createContext({stdin:void 0,setRawMode:()=>{},isRawModeSupported:!1,internal_exitOnCtrlC:!0});px.displayName="InternalStdinContext";jw.default=px});var qw=Ke(Hw=>{"use strict";Object.defineProperty(Hw,"__esModule",{value:!0});var CU=Mi(),hx=CU.createContext({stdout:void 0,write:()=>{}});hx.displayName="InternalStdoutContext";Hw.default=hx});var Vw=Ke(Ww=>{"use strict";Object.defineProperty(Ww,"__esModule",{value:!0});var xU=Mi(),vx=xU.createContext({stderr:void 0,write:()=>{}});vx.displayName="InternalStderrContext";Ww.default=vx});var _4=Ke(Gw=>{"use strict";Object.defineProperty(Gw,"__esModule",{value:!0});var RU=Mi(),mx=RU.createContext({activeId:void 0,add:()=>{},remove:()=>{},activate:()=>{},deactivate:()=>{},enableFocus:()=>{},disableFocus:()=>{},focusNext:()=>{},focusPrevious:()=>{}});mx.displayName="InternalFocusContext";Gw.default=mx});var gx=Ke(($V,yx)=>{"use strict";var AU=/[|\\{}()[\]^$+*?.-]/g;yx.exports=i=>{if(typeof i!="string")throw new TypeError("Expected a string");return i.replace(AU,"\\$&")}});var wx=Ke((eG,_x)=>{"use strict";var OU=gx(),Ex=[].concat(require("module").builtinModules,"bootstrap_node","node").map(i=>new RegExp(`(?:\\(${i}\\.js:\\d+:\\d+\\)$|^\\s*at ${i}\\.js:\\d+:\\d+$)`));Ex.push(/\(internal\/[^:]+:\d+:\d+\)$/,/\s*at internal\/[^:]+:\d+:\d+$/,/\/\.node-spawn-wrap-\w+-\w+\/node:\d+:\d+\)?$/);var E4=class{constructor(o){o=qt({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,MU(o.ignoredPackages)),this._wrapCallSite=o.wrapCallSite||!1}static nodeInternals(){return[...Ex]}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(M=>{if(M=M.replace(/\\/g,"/"),this._internals.some(O=>O.test(M)))return;let N=/^\s*at /.test(M);c?M=M.trimEnd().replace(/^(\s+)at /,"$1"):(M=M.trim(),N&&(M=M.slice(3))),M=M.replace(`${this._cwd}/`,""),M&&(N?(_&&(t.push(_),_=null),t.push(M)):(c=!0,_=M))}),t.map(M=>`${a}${M} -`).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,O)=>this._wrapCallSite?O.map(this._wrapCallSite):O,o&&(Error.stackTraceLimit=o);let t={};Error.captureStackTrace(t,a);let{stack:M}=t;return Object.assign(Error,{prepareStackTrace:c,stackTraceLimit:_}),M}at(o=this.at){let[a]=this.capture(1,o);if(!a)return{};let c={line:a.getLineNumber(),column:a.getColumnNumber()};Dx(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 M=a.getMethodName();return M&&t!==M&&(c.method=M),c}parseLine(o){let a=o&&o.match(kU);if(!a)return null;let c=a[1]==="new",_=a[2],t=a[3],M=a[4],N=Number(a[5]),O=Number(a[6]),T=a[7],B=a[8],H=a[9],q=a[10]==="native",ne=a[11]===")",m,pe={};if(B&&(pe.line=Number(B)),H&&(pe.column=Number(H)),ne&&T){let ge=0;for(let ve=T.length-1;ve>0;ve--)if(T.charAt(ve)===")")ge++;else if(T.charAt(ve)==="("&&T.charAt(ve-1)===" "&&(ge--,ge===-1&&T.charAt(ve-1)===" ")){let ue=T.slice(0,ve-1);T=T.slice(ve+1),_+=` (${ue}`;break}}if(_){let ge=_.match(LU);ge&&(_=ge[1],m=ge[2])}return Dx(pe,T,this._cwd),c&&(pe.constructor=!0),t&&(pe.evalOrigin=t,pe.evalLine=N,pe.evalColumn=O,pe.evalFile=M&&M.replace(/\\/g,"/")),q&&(pe.native=!0),_&&(pe.function=_),m&&_!==m&&(pe.method=m),pe}};function Dx(i,o,a){o&&(o=o.replace(/\\/g,"/"),o.startsWith(`${a}/`)&&(o=o.slice(a.length+1)),i.file=o)}function MU(i){if(i.length===0)return[];let o=i.map(a=>OU(a));return new RegExp(`[/\\\\]node_modules[/\\\\](?:${o.join("|")})[/\\\\][^:]+:\\d+:\\d+`)}var kU=new RegExp("^(?:\\s*at )?(?:(new) )?(?:(.*?) \\()?(?:eval at ([^ ]+) \\((.+?):(\\d+):(\\d+)\\), )?(?:(.+?):(\\d+):(\\d+)|(native))(\\)?)$"),LU=/^(.*?) \[as (.*?)\]$/;_x.exports=E4});var Tx=Ke((tG,Sx)=>{"use strict";Sx.exports=(i,o)=>i.replace(/^\t+/gm,a=>" ".repeat(a.length*(o||2)))});var xx=Ke((nG,Cx)=>{"use strict";var NU=Tx(),FU=(i,o)=>{let a=[],c=i-o,_=i+o;for(let t=c;t<=_;t++)a.push(t);return a};Cx.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=NU(i).split(/\r?\n/),!(o>i.length))return a=qt({around:3},a),FU(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 PU=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]}),IU=rc&&rc.__setModuleDefault||(Object.create?function(i,o){Object.defineProperty(i,"default",{enumerable:!0,value:o})}:function(i,o){i.default=o}),bU=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)&&PU(o,i,a);return IU(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 Rx.default.createElement("ink-box",{ref:o,style:_},a)});Yw.displayName="Box";Yw.defaultProps={flexDirection:"row",flexGrow:0,flexShrink:1};rc.default=Yw});var Qw=Ke(Dg=>{"use strict";var Kw=Dg&&Dg.__importDefault||function(i){return i&&i.__esModule?i:{default:i}};Object.defineProperty(Dg,"__esModule",{value:!0});var UU=Kw(Mi()),em=Kw(y4()),Ax=Kw(Mw()),Xw=({color:i,backgroundColor:o,dimColor:a,bold:c,italic:_,underline:t,strikethrough:M,inverse:N,wrap:O,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)),M&&(H=em.default.strikethrough(H)),N&&(H=em.default.inverse(H)),H);return UU.default.createElement("ink-text",{style:{flexGrow:0,flexShrink:1,flexDirection:"row",textWrap:O},internal_transform:B},T)};Xw.displayName="Text";Xw.defaultProps={dimColor:!1,bold:!1,italic:!1,underline:!1,strikethrough:!1,wrap:"wrap"};Dg.default=Xw});var Lx=Ke(ic=>{"use strict";var jU=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]}),zU=ic&&ic.__setModuleDefault||(Object.create?function(i,o){Object.defineProperty(i,"default",{enumerable:!0,value:o})}:function(i,o){i.default=o}),HU=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)&&jU(o,i,a);return zU(o,i),o},wg=ic&&ic.__importDefault||function(i){return i&&i.__esModule?i:{default:i}};Object.defineProperty(ic,"__esModule",{value:!0});var Ox=HU(require("fs")),Q0=wg(Mi()),Mx=wg(wx()),qU=wg(xx()),$1=wg(D4()),Hc=wg(Qw()),kx=new Mx.default({cwd:process.cwd(),internals:Mx.default.nodeInternals()}),WU=({error:i})=>{let o=i.stack?i.stack.split(` -`).slice(1):void 0,a=o?kx.parseLine(o[0]):void 0,c,_=0;if((a==null?void 0:a.file)&&(a==null?void 0:a.line)&&Ox.existsSync(a.file)){let t=Ox.readFileSync(a.file,"utf8");if(c=qU.default(t,a.line),c)for(let{line:M}of c)_=Math.max(_,String(M).length)}return Q0.default.createElement($1.default,{flexDirection:"column",padding:1},Q0.default.createElement($1.default,null,Q0.default.createElement(Hc.default,{backgroundColor:"red",color:"white"}," ","ERROR"," "),Q0.default.createElement(Hc.default,null," ",i.message)),a&&Q0.default.createElement($1.default,{marginTop:1},Q0.default.createElement(Hc.default,{dimColor:!0},a.file,":",a.line,":",a.column)),a&&c&&Q0.default.createElement($1.default,{marginTop:1,flexDirection:"column"},c.map(({line:t,value:M})=>Q0.default.createElement($1.default,{key:t},Q0.default.createElement($1.default,{width:_+1},Q0.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(_," "),":")),Q0.default.createElement(Hc.default,{key:t,backgroundColor:t===a.line?"red":void 0,color:t===a.line?"white":void 0}," "+M)))),i.stack&&Q0.default.createElement($1.default,{marginTop:1,flexDirection:"column"},i.stack.split(` -`).slice(1).map(t=>{let M=kx.parseLine(t);return M?Q0.default.createElement($1.default,{key:t},Q0.default.createElement(Hc.default,{dimColor:!0},"- "),Q0.default.createElement(Hc.default,{dimColor:!0,bold:!0},M.function),Q0.default.createElement(Hc.default,{dimColor:!0,color:"gray"}," ","(",M.file,":",M.line,":",M.column,")")):Q0.default.createElement($1.default,{key:t},Q0.default.createElement(Hc.default,{dimColor:!0},"- "),Q0.default.createElement(Hc.default,{dimColor:!0,bold:!0},t))})))};ic.default=WU});var Fx=Ke(uc=>{"use strict";var VU=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]}),GU=uc&&uc.__setModuleDefault||(Object.create?function(i,o){Object.defineProperty(i,"default",{enumerable:!0,value:o})}:function(i,o){i.default=o}),YU=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)&&VU(o,i,a);return GU(o,i),o},uh=uc&&uc.__importDefault||function(i){return i&&i.__esModule?i:{default:i}};Object.defineProperty(uc,"__esModule",{value:!0});var oh=YU(Mi()),Nx=uh(SD()),KU=uh(Uw()),XU=uh(zw()),QU=uh(qw()),JU=uh(Vw()),ZU=uh(_4()),$U=uh(Lx()),ej=" ",tj="",nj="",Jw=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===nj&&this.state.activeFocusId&&this.setState({activeFocusId:void 0}),this.state.isFocusEnabled&&this.state.focusables.length>0&&(o===ej&&this.focusNext(),o===tj&&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(KU.default.Provider,{value:{exit:this.handleExit}},oh.default.createElement(XU.default.Provider,{value:{stdin:this.props.stdin,setRawMode:this.handleSetRawMode,isRawModeSupported:this.isRawModeSupported(),internal_exitOnCtrlC:this.props.exitOnCtrlC}},oh.default.createElement(QU.default.Provider,{value:{stdout:this.props.stdout,write:this.props.writeToStdout}},oh.default.createElement(JU.default.Provider,{value:{stderr:this.props.stderr,write:this.props.writeToStderr}},oh.default.createElement(ZU.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($U.default,{error:this.state.error}):this.props.children)))))}componentDidMount(){Nx.default.hide(this.props.stdout)}componentWillUnmount(){Nx.default.show(this.props.stdout),this.isRawModeSupported()&&this.handleSetRawMode(!1)}componentDidCatch(o){this.handleExit(o)}};uc.default=Jw;Jw.displayName="InternalApp"});var Bx=Ke(oc=>{"use strict";var rj=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]}),ij=oc&&oc.__setModuleDefault||(Object.create?function(i,o){Object.defineProperty(i,"default",{enumerable:!0,value:o})}:function(i,o){i.default=o}),uj=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)&&rj(o,i,a);return ij(o,i),o},lc=oc&&oc.__importDefault||function(i){return i&&i.__esModule?i:{default:i}};Object.defineProperty(oc,"__esModule",{value:!0});var oj=lc(Mi()),Px=kS(),lj=lc(GS()),sj=lc(yD()),aj=lc($S()),fj=lc(tT()),w4=lc(v6()),cj=lc(lx()),dj=lc(wD()),pj=lc(cx()),hj=uj(iw()),vj=lc(bw()),mj=lc(Fx()),tm=process.env.CI==="false"?!1:aj.default,Ix=()=>{},bx=class{constructor(o){this.resolveExitPromise=()=>{},this.rejectExitPromise=()=>{},this.unsubscribeExit=()=>{},this.onRender=()=>{if(this.isUnmounted)return;let{output:a,outputHeight:c,staticOutput:_}=cj.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(sj.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},fj.default(this),this.options=o,this.rootNode=hj.createNode("ink-root"),this.rootNode.onRender=o.debug?this.onRender:Px.throttle(this.onRender,32,{leading:!0,trailing:!0}),this.rootNode.onImmediateRender=this.onRender,this.log=lj.default.create(o.stdout),this.throttledLog=o.debug?this.log:Px.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=dj.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=oj.default.createElement(mj.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,Ix)}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,Ix),vj.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=pj.default((o,a)=>{o==="stdout"&&this.writeToStdout(a),o==="stderr"&&(a.startsWith("The above error occurred")||this.writeToStderr(a))}))}};oc.default=bx});var jx=Ke(Sg=>{"use strict";var Ux=Sg&&Sg.__importDefault||function(i){return i&&i.__esModule?i:{default:i}};Object.defineProperty(Sg,"__esModule",{value:!0});var yj=Ux(Bx()),S4=Ux(bw()),gj=require("stream"),Dj=(i,o)=>{let a=Object.assign({stdout:process.stdout,stdin:process.stdin,stderr:process.stderr,debug:!1,exitOnCtrlC:!0,patchConsole:!0},_j(o)),c=Ej(a.stdout,()=>new yj.default(a));return c.render(i),{rerender:c.render,unmount:()=>c.unmount(),waitUntilExit:c.waitUntilExit,cleanup:()=>S4.default.delete(a.stdout),clear:c.clear}};Sg.default=Dj;var _j=(i={})=>i instanceof gj.Stream?{stdout:i,stdin:process.stdin}:i,Ej=(i,o)=>{let a;return S4.default.has(i)?a=S4.default.get(i):(a=o(),S4.default.set(i,a)),a}});var Hx=Ke(ed=>{"use strict";var wj=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]}),Sj=ed&&ed.__setModuleDefault||(Object.create?function(i,o){Object.defineProperty(i,"default",{enumerable:!0,value:o})}:function(i,o){i.default=o}),Tj=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)&&wj(o,i,a);return Sj(o,i),o};Object.defineProperty(ed,"__esModule",{value:!0});var Tg=Tj(Mi()),zx=i=>{let{items:o,children:a,style:c}=i,[_,t]=Tg.useState(0),M=Tg.useMemo(()=>o.slice(_),[o,_]);Tg.useLayoutEffect(()=>{t(o.length)},[o.length]);let N=M.map((T,B)=>a(T,_+B)),O=Tg.useMemo(()=>Object.assign({position:"absolute",flexDirection:"column"},c),[c]);return Tg.default.createElement("ink-box",{internal_static:!0,style:O},N)};zx.displayName="Static";ed.default=zx});var Wx=Ke(Cg=>{"use strict";var Cj=Cg&&Cg.__importDefault||function(i){return i&&i.__esModule?i:{default:i}};Object.defineProperty(Cg,"__esModule",{value:!0});var xj=Cj(Mi()),qx=({children:i,transform:o})=>i==null?null:xj.default.createElement("ink-text",{style:{flexGrow:0,flexShrink:1,flexDirection:"row"},internal_transform:o},i);qx.displayName="Transform";Cg.default=qx});var Gx=Ke(xg=>{"use strict";var Rj=xg&&xg.__importDefault||function(i){return i&&i.__esModule?i:{default:i}};Object.defineProperty(xg,"__esModule",{value:!0});var Aj=Rj(Mi()),Vx=({count:i=1})=>Aj.default.createElement("ink-text",null,` -`.repeat(i));Vx.displayName="Newline";xg.default=Vx});var Xx=Ke(Rg=>{"use strict";var Yx=Rg&&Rg.__importDefault||function(i){return i&&i.__esModule?i:{default:i}};Object.defineProperty(Rg,"__esModule",{value:!0});var Oj=Yx(Mi()),Mj=Yx(D4()),Kx=()=>Oj.default.createElement(Mj.default,{flexGrow:1});Kx.displayName="Spacer";Rg.default=Kx});var T4=Ke(Ag=>{"use strict";var kj=Ag&&Ag.__importDefault||function(i){return i&&i.__esModule?i:{default:i}};Object.defineProperty(Ag,"__esModule",{value:!0});var Lj=Mi(),Nj=kj(zw()),Fj=()=>Lj.useContext(Nj.default);Ag.default=Fj});var Jx=Ke(Og=>{"use strict";var Pj=Og&&Og.__importDefault||function(i){return i&&i.__esModule?i:{default:i}};Object.defineProperty(Og,"__esModule",{value:!0});var Qx=Mi(),Ij=Pj(T4()),bj=(i,o={})=>{let{stdin:a,setRawMode:c,internal_exitOnCtrlC:_}=Ij.default();Qx.useEffect(()=>{if(o.isActive!==!1)return c(!0),()=>{c(!1)}},[o.isActive,c]),Qx.useEffect(()=>{if(o.isActive===!1)return;let t=M=>{let N=String(M),O={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<=""&&!O.return&&(N=String.fromCharCode(N.charCodeAt(0)+"a".charCodeAt(0)-1),O.ctrl=!0),N.startsWith("")&&(N=N.slice(1),O.meta=!0);let T=N>="A"&&N<="Z",B=N>="\u0410"&&N<="\u042F";N.length===1&&(T||B)&&(O.shift=!0),O.tab&&N==="[Z"&&(O.shift=!0),(O.tab||O.backspace||O.delete)&&(N=""),(!(N==="c"&&O.ctrl)||!_)&&i(N,O)};return a==null||a.on("data",t),()=>{a==null||a.off("data",t)}},[o.isActive,a,_,i])};Og.default=bj});var Zx=Ke(Mg=>{"use strict";var Bj=Mg&&Mg.__importDefault||function(i){return i&&i.__esModule?i:{default:i}};Object.defineProperty(Mg,"__esModule",{value:!0});var Uj=Mi(),jj=Bj(Uw()),zj=()=>Uj.useContext(jj.default);Mg.default=zj});var $x=Ke(kg=>{"use strict";var Hj=kg&&kg.__importDefault||function(i){return i&&i.__esModule?i:{default:i}};Object.defineProperty(kg,"__esModule",{value:!0});var qj=Mi(),Wj=Hj(qw()),Vj=()=>qj.useContext(Wj.default);kg.default=Vj});var e5=Ke(Lg=>{"use strict";var Gj=Lg&&Lg.__importDefault||function(i){return i&&i.__esModule?i:{default:i}};Object.defineProperty(Lg,"__esModule",{value:!0});var Yj=Mi(),Kj=Gj(Vw()),Xj=()=>Yj.useContext(Kj.default);Lg.default=Xj});var n5=Ke(Ng=>{"use strict";var t5=Ng&&Ng.__importDefault||function(i){return i&&i.__esModule?i:{default:i}};Object.defineProperty(Ng,"__esModule",{value:!0});var Fg=Mi(),Qj=t5(_4()),Jj=t5(T4()),Zj=({isActive:i=!0,autoFocus:o=!1}={})=>{let{isRawModeSupported:a,setRawMode:c}=Jj.default(),{activeId:_,add:t,remove:M,activate:N,deactivate:O}=Fg.useContext(Qj.default),T=Fg.useMemo(()=>Math.random().toString().slice(2,7),[]);return Fg.useEffect(()=>(t(T,{autoFocus:o}),()=>{M(T)}),[T,o]),Fg.useEffect(()=>{i?N(T):O(T)},[i,T]),Fg.useEffect(()=>{if(!(!a||!i))return c(!0),()=>{c(!1)}},[i]),{isFocused:Boolean(T)&&_===T}};Ng.default=Zj});var r5=Ke(Pg=>{"use strict";var $j=Pg&&Pg.__importDefault||function(i){return i&&i.__esModule?i:{default:i}};Object.defineProperty(Pg,"__esModule",{value:!0});var ez=Mi(),tz=$j(_4()),nz=()=>{let i=ez.useContext(tz.default);return{enableFocus:i.enableFocus,disableFocus:i.disableFocus,focusNext:i.focusNext,focusPrevious:i.focusPrevious}};Pg.default=nz});var i5=Ke(Zw=>{"use strict";Object.defineProperty(Zw,"__esModule",{value:!0});Zw.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 rz=jx();Object.defineProperty(Kl,"render",{enumerable:!0,get:function(){return rz.default}});var iz=D4();Object.defineProperty(Kl,"Box",{enumerable:!0,get:function(){return iz.default}});var uz=Qw();Object.defineProperty(Kl,"Text",{enumerable:!0,get:function(){return uz.default}});var oz=Hx();Object.defineProperty(Kl,"Static",{enumerable:!0,get:function(){return oz.default}});var lz=Wx();Object.defineProperty(Kl,"Transform",{enumerable:!0,get:function(){return lz.default}});var sz=Gx();Object.defineProperty(Kl,"Newline",{enumerable:!0,get:function(){return sz.default}});var az=Xx();Object.defineProperty(Kl,"Spacer",{enumerable:!0,get:function(){return az.default}});var fz=Jx();Object.defineProperty(Kl,"useInput",{enumerable:!0,get:function(){return fz.default}});var cz=Zx();Object.defineProperty(Kl,"useApp",{enumerable:!0,get:function(){return cz.default}});var dz=T4();Object.defineProperty(Kl,"useStdin",{enumerable:!0,get:function(){return dz.default}});var pz=$x();Object.defineProperty(Kl,"useStdout",{enumerable:!0,get:function(){return pz.default}});var hz=e5();Object.defineProperty(Kl,"useStderr",{enumerable:!0,get:function(){return hz.default}});var vz=n5();Object.defineProperty(Kl,"useFocus",{enumerable:!0,get:function(){return vz.default}});var mz=r5();Object.defineProperty(Kl,"useFocusManager",{enumerable:!0,get:function(){return mz.default}});var yz=i5();Object.defineProperty(Kl,"measureElement",{enumerable:!0,get:function(){return yz.default}})});var h5=Ke(Ig=>{"use strict";Object.defineProperty(Ig,"__esModule",{value:!0});Ig.UncontrolledTextInput=void 0;var c5=Mi(),t3=Mi(),d5=sc(),ah=y4(),p5=({value:i,placeholder:o="",focus:a=!0,mask:c,highlightPastedText:_=!1,showCursor:t=!0,onChange:M,onSubmit:N})=>{let[{cursorOffset:O,cursorWidth:T},B]=t3.useState({cursorOffset:(i||"").length,cursorWidth:0});t3.useEffect(()=>{B(pe=>{if(!a||!t)return pe;let ge=i||"";return pe.cursorOffset>ge.length-1?{cursorOffset:ge.length,cursorWidth:0}:pe})},[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 pe=0;for(let ge of q)pe>=O-H&&pe<=O?ne+=ah.inverse(ge):ne+=ge,pe++;q.length>0&&O===q.length&&(ne+=ah.inverse(" "))}return d5.useInput((pe,ge)=>{if(ge.upArrow||ge.downArrow||ge.ctrl&&pe==="c"||ge.tab||ge.shift&&ge.tab)return;if(ge.return){N&&N(i);return}let ve=O,ue=i,_e=0;ge.leftArrow?t&&ve--:ge.rightArrow?t&&ve++:ge.backspace||ge.delete?O>0&&(ue=i.slice(0,O-1)+i.slice(O,i.length),ve--):(ue=i.slice(0,O)+pe+i.slice(O,i.length),ve+=pe.length,pe.length>1&&(_e=pe.length)),O<0&&(ve=0),O>i.length&&(ve=i.length),B({cursorOffset:ve,cursorWidth:_e}),ue!==i&&M(ue)},{isActive:a}),c5.createElement(d5.Text,null,o?q.length>0?ne:m:ne)};Ig.default=p5;Ig.UncontrolledTextInput=i=>{let[o,a]=t3.useState("");return c5.createElement(p5,Object.assign({},i,{value:o,onChange:a}))}});var m5=Ke(N4=>{"use strict";Object.defineProperty(N4,"__esModule",{value:!0});function bg(i){let o=[...i.caches],a=o.shift();return a===void 0?v5():{get(c,_,t={miss:()=>Promise.resolve()}){return a.get(c,_,t).catch(()=>bg({caches:o}).get(c,_,t))},set(c,_){return a.set(c,_).catch(()=>bg({caches:o}).set(c,_))},delete(c){return a.delete(c).catch(()=>bg({caches:o}).delete(c))},clear(){return a.clear().catch(()=>bg({caches:o}).clear())}}}function v5(){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=bg;N4.createNullCache=v5});var g5=Ke((jG,y5)=>{y5.exports=m5()});var _5=Ke(n3=>{"use strict";Object.defineProperty(n3,"__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 M=c(),N=_&&_.miss||(()=>Promise.resolve());return M.then(O=>N(O)).then(()=>M)},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()}}}n3.createInMemoryCache=gz});var D5=Ke((HG,E5)=>{E5.exports=_5()});var S5=Ke(ac=>{"use strict";Object.defineProperty(ac,"__esModule",{value:!0});function _z(i,o,a){let c={"x-algolia-api-key":a,"x-algolia-application-id":o};return{headers(){return i===r3.WithinHeaders?c:{}},queryParameters(){return i===r3.WithinQueryParameters?c:{}}}}function Ez(i){let o=0,a=()=>(o++,new Promise(c=>{setTimeout(()=>{c(i(a))},Math.min(100*o,1e3))}));return i(a)}function w5(i,o=(a,c)=>Promise.resolve()){return Object.assign(i,{wait(a){return w5(i.then(c=>Promise.all([o(c,a),c])).then(c=>c[1]))}})}function Dz(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 wz(i,o){return Object.keys(o!==void 0?o:{}).forEach(a=>{i[a]=o[a](i)}),i}function Sz(i,...o){let a=0;return i.replace(/%s/g,()=>encodeURIComponent(o[a++]))}var Tz="4.2.0",Cz=i=>()=>i.transporter.requester.destroy(),r3={WithinQueryParameters:0,WithinHeaders:1};ac.AuthMode=r3;ac.addMethods=wz;ac.createAuth=_z;ac.createRetryablePromise=Ez;ac.createWaitablePromise=w5;ac.destroy=Cz;ac.encode=Sz;ac.shuffle=Dz;ac.version=Tz});var Bg=Ke((WG,T5)=>{T5.exports=S5()});var C5=Ke(i3=>{"use strict";Object.defineProperty(i3,"__esModule",{value:!0});var xz={Delete:"DELETE",Get:"GET",Post:"POST",Put:"PUT"};i3.MethodEnum=xz});var Ug=Ke((GG,x5)=>{x5.exports=C5()});var z5=Ke(Go=>{"use strict";Object.defineProperty(Go,"__esModule",{value:!0});var R5=Ug();function u3(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 o3(i,o=nm.Up){return Zr(qt({},i),{status:o,lastUpdate:Date.now()})}function O5(i){return i.status===nm.Up||Date.now()-i.lastUpdate>A5}function M5(i){return i.status===nm.Timeouted&&Date.now()-i.lastUpdate<=A5}function l3(i){return{protocol:i.protocol||"https",url:i.url,accept:i.accept||F4.Any}}function Rz(i,o){return Promise.all(o.map(a=>i.get(a,()=>Promise.resolve(o3(a))))).then(a=>{let c=a.filter(N=>O5(N)),_=a.filter(N=>M5(N)),t=[...c,..._],M=t.length>0?t.map(N=>l3(N)):o;return{getTimeout(N,O){return(_.length===0&&N===0?1:_.length+3+N)*O},statelessHosts:M}})}var Az=({isTimedOut:i,status:o})=>!i&&~~o==0,Oz=i=>{let o=i.status;return i.isTimedOut||Az(i)||~~(o/100)!=2&&~~(o/100)!=4},Mz=({status:i})=>~~(i/100)==2,kz=(i,o)=>Oz(i)?o.onRetry(i):Mz(i)?o.onSucess(i):o.onFail(i);function b5(i,o,a,c){let _=[],t=F5(a,c),M=P5(i,c),N=a.method,O=a.method!==R5.MethodEnum.Get?{}:qt(qt({},a.data),c.data),T=qt(qt(qt({"x-algolia-agent":i.userAgent.value},i.queryParameters),O),c.queryParameters),B=0,H=(q,ne)=>{let m=q.pop();if(m===void 0)throw I5(s3(_));let pe={data:t,headers:M,method:N,url:N5(m,a.path,T),connectTimeout:ne(B,i.timeouts.connect),responseTimeout:ne(B,c.timeout)},ge=ue=>{let _e={request:pe,response:ue,host:m,triesLeft:q.length};return _.push(_e),_e},ve={onSucess:ue=>k5(ue),onRetry(ue){let _e=ge(ue);return ue.isTimedOut&&B++,Promise.all([i.logger.info("Retryable failure",a3(_e)),i.hostsCache.set(m,o3(m,ue.isTimedOut?nm.Timeouted:nm.Down))]).then(()=>H(q,ne))},onFail(ue){throw ge(ue),L5(ue,s3(_))}};return i.requester.send(pe).then(ue=>kz(ue,ve))};return Rz(i.hostsCache,o).then(q=>H([...q.statelessHosts].reverse(),q.getTimeout))}function Lz(i){let{hostsCache:o,logger:a,requester:c,requestsCache:_,responsesCache:t,timeouts:M,userAgent:N,hosts:O,queryParameters:T,headers:B}=i,H={hostsCache:o,logger:a,requester:c,requestsCache:_,responsesCache:t,timeouts:M,userAgent:N,headers:B,queryParameters:T,hosts:O.map(q=>l3(q)),read(q,ne){let m=u3(ne,H.timeouts.read),pe=()=>b5(H,H.hosts.filter(ue=>(ue.accept&F4.Read)!=0),q,m);if((m.cacheable!==void 0?m.cacheable:q.cacheable)!==!0)return pe();let ve={request:q,mappedRequestOptions:m,transporter:{queryParameters:H.queryParameters,headers:H.headers}};return H.responsesCache.get(ve,()=>H.requestsCache.get(ve,()=>H.requestsCache.set(ve,pe()).then(ue=>Promise.all([H.requestsCache.delete(ve),ue]),ue=>Promise.all([H.requestsCache.delete(ve),Promise.reject(ue)])).then(([ue,_e])=>_e)),{miss:ue=>H.responsesCache.set(ve,ue)})},write(q,ne){return b5(H,H.hosts.filter(m=>(m.accept&F4.Write)!=0),q,u3(ne,H.timeouts.write))}};return H}function Nz(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 k5(i){try{return JSON.parse(i.content)}catch(o){throw B5(o.message,i)}}function L5({content:i,status:o},a){let c=i;try{c=JSON.parse(i).message}catch(_){}return U5(c,o,a)}function Fz(i,...o){let a=0;return i.replace(/%s/g,()=>encodeURIComponent(o[a++]))}function N5(i,o,a){let c=j5(a),_=`${i.protocol}://${i.url}/${o.charAt(0)==="/"?o.substr(1):o}`;return c.length&&(_+=`?${c}`),_}function j5(i){let o=a=>Object.prototype.toString.call(a)==="[object Object]"||Object.prototype.toString.call(a)==="[object Array]";return Object.keys(i).map(a=>Fz("%s=%s",a,o(i[a])?JSON.stringify(i[a]):i[a])).join("&")}function F5(i,o){if(i.method===R5.MethodEnum.Get||i.data===void 0&&o.data===void 0)return;let a=Array.isArray(i.data)?i.data:qt(qt({},i.data),o.data);return JSON.stringify(a)}function P5(i,o){let a=qt(qt({},i.headers),o.headers),c={};return Object.keys(a).forEach(_=>{let t=a[_];c[_.toLowerCase()]=t}),c}function s3(i){return i.map(o=>a3(o))}function a3(i){let o=i.request.headers["x-algolia-api-key"]?{"x-algolia-api-key":"*****"}:{};return Zr(qt({},i),{request:Zr(qt({},i.request),{headers:qt(qt({},i.request.headers),o)})})}function U5(i,o,a){return{name:"ApiError",message:i,status:o,transporterStackTrace:a}}function B5(i,o){return{name:"DeserializationError",message:i,response:o}}function I5(i){return{name:"RetryError",message:"Unreachable hosts - your application id may be incorrect. If the error persists, contact support@algolia.com.",transporterStackTrace:i}}Go.CallEnum=F4;Go.HostStatusEnum=nm;Go.createApiError=U5;Go.createDeserializationError=B5;Go.createMappedRequestOptions=u3;Go.createRetryError=I5;Go.createStatefulHost=o3;Go.createStatelessHost=l3;Go.createTransporter=Lz;Go.createUserAgent=Nz;Go.deserializeFailure=L5;Go.deserializeSuccess=k5;Go.isStatefulHostTimeouted=M5;Go.isStatefulHostUp=O5;Go.serializeData=F5;Go.serializeHeaders=P5;Go.serializeQueryParameters=j5;Go.serializeUrl=N5;Go.stackFrameWithoutCredentials=a3;Go.stackTraceWithoutCredentials=s3});var jg=Ke((KG,H5)=>{H5.exports=z5()});var q5=Ke(_2=>{"use strict";Object.defineProperty(_2,"__esModule",{value:!0});var rm=Bg(),Pz=jg(),zg=Ug(),Iz=i=>{let o=i.region||"us",a=rm.createAuth(rm.AuthMode.WithinHeaders,i.appId,i.apiKey),c=Pz.createTransporter(Zr(qt({hosts:[{url:`analytics.${o}.algolia.com`}]},i),{headers:qt(Zr(qt({},a.headers()),{"content-type":"application/json"}),i.headers),queryParameters:qt(qt({},a.queryParameters()),i.queryParameters)})),_=i.appId;return rm.addMethods({appId:_,transporter:c},i.methods)},bz=i=>(o,a)=>i.transporter.write({method:zg.MethodEnum.Post,path:"2/abtests",data:o},a),Bz=i=>(o,a)=>i.transporter.write({method:zg.MethodEnum.Delete,path:rm.encode("2/abtests/%s",o)},a),Uz=i=>(o,a)=>i.transporter.read({method:zg.MethodEnum.Get,path:rm.encode("2/abtests/%s",o)},a),jz=i=>o=>i.transporter.read({method:zg.MethodEnum.Get,path:"2/abtests"},o),zz=i=>(o,a)=>i.transporter.write({method:zg.MethodEnum.Post,path:rm.encode("2/abtests/%s/stop",o)},a);_2.addABTest=bz;_2.createAnalyticsClient=Iz;_2.deleteABTest=Bz;_2.getABTest=Uz;_2.getABTests=jz;_2.stopABTest=zz});var V5=Ke((QG,W5)=>{W5.exports=q5()});var Y5=Ke(Hg=>{"use strict";Object.defineProperty(Hg,"__esModule",{value:!0});var f3=Bg(),Hz=jg(),G5=Ug(),qz=i=>{let o=i.region||"us",a=f3.createAuth(f3.AuthMode.WithinHeaders,i.appId,i.apiKey),c=Hz.createTransporter(Zr(qt({hosts:[{url:`recommendation.${o}.algolia.com`}]},i),{headers:qt(Zr(qt({},a.headers()),{"content-type":"application/json"}),i.headers),queryParameters:qt(qt({},a.queryParameters()),i.queryParameters)}));return f3.addMethods({appId:i.appId,transporter:c},i.methods)},Wz=i=>o=>i.transporter.read({method:G5.MethodEnum.Get,path:"1/strategies/personalization"},o),Vz=i=>(o,a)=>i.transporter.write({method:G5.MethodEnum.Post,path:"1/strategies/personalization",data:o},a);Hg.createRecommendationClient=qz;Hg.getPersonalizationStrategy=Wz;Hg.setPersonalizationStrategy=Vz});var X5=Ke((ZG,K5)=>{K5.exports=Y5()});var s9=Ke(tn=>{"use strict";Object.defineProperty(tn,"__esModule",{value:!0});var Nn=Bg(),ia=jg(),Ur=Ug(),Gz=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 Yz=i=>{let o=i.appId,a=Nn.createAuth(i.authMode!==void 0?i.authMode:Nn.AuthMode.WithinHeaders,o,i.apiKey),c=ia.createTransporter(Zr(qt({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:qt(Zr(qt({},a.headers()),{"content-type":"application/x-www-form-urlencoded"}),i.headers),queryParameters:qt(qt({},a.queryParameters()),i.queryParameters)})),_={transporter:c,appId:o,addAlgoliaAgent(t,M){c.userAgent.add({segment:t,version:M})},clearCache(){return Promise.all([c.requestsCache.clear(),c.responsesCache.clear()]).then(()=>{})}};return Nn.addMethods(_,i.methods)};function Q5(){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 J5(){return{name:"ObjectNotFoundError",message:"Object not found."}}function Z5(){return{name:"ValidUntilNotFoundError",message:"ValidUntil not found in given secured api key."}}var Kz=i=>(o,a)=>{let N=a||{},{queryParameters:c}=N,_=wl(N,["queryParameters"]),t=qt({acl:o},c!==void 0?{queryParameters:c}:{}),M=(O,T)=>Nn.createRetryablePromise(B=>qg(i)(O.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},_),M)},Xz=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}},_)},Qz=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,M)=>Wg(i)(o,{methods:{waitTask:x0}}).waitTask(t.taskID,M);return Nn.createWaitablePromise(i.transporter.write({method:Ur.MethodEnum.Post,path:Nn.encode("1/indexes/%s/operation",o),data:{operation:"copy",destination:a}},c),_)},Jz=i=>(o,a,c)=>I4(i)(o,a,Zr(qt({},c),{scope:[b4.Rules]})),Zz=i=>(o,a,c)=>I4(i)(o,a,Zr(qt({},c),{scope:[b4.Settings]})),$z=i=>(o,a,c)=>I4(i)(o,a,Zr(qt({},c),{scope:[b4.Synonyms]})),eH=i=>(o,a)=>{let c=(_,t)=>Nn.createRetryablePromise(M=>qg(i)(o,t).then(M).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)},tH=()=>(i,o)=>{let a=ia.serializeQueryParameters(o),c=Gz.createHmac("sha256",i).update(a).digest("hex");return Buffer.from(c+a).toString("base64")},qg=i=>(o,a)=>i.transporter.read({method:Ur.MethodEnum.Get,path:Nn.encode("1/keys/%s",o)},a),nH=i=>o=>i.transporter.read({method:Ur.MethodEnum.Get,path:"1/logs"},o),rH=()=>i=>{let o=Buffer.from(i,"base64").toString("ascii"),a=/validUntil=(\d+)/,c=o.match(a);if(c===null)throw Z5();return parseInt(c[1],10)-Math.round(new Date().getTime()/1e3)},iH=i=>o=>i.transporter.read({method:Ur.MethodEnum.Get,path:"1/clusters/mapping/top"},o),uH=i=>(o,a)=>i.transporter.read({method:Ur.MethodEnum.Get,path:Nn.encode("1/clusters/mapping/%s",o)},a),oH=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)},Wg=i=>(o,a={})=>{let c={transporter:i.transporter,appId:i.appId,indexName:o};return Nn.addMethods(c,a.methods)},lH=i=>o=>i.transporter.read({method:Ur.MethodEnum.Get,path:"1/keys"},o),sH=i=>o=>i.transporter.read({method:Ur.MethodEnum.Get,path:"1/clusters"},o),aH=i=>o=>i.transporter.read({method:Ur.MethodEnum.Get,path:"1/indexes"},o),fH=i=>o=>i.transporter.read({method:Ur.MethodEnum.Get,path:"1/clusters/mapping"},o),cH=i=>(o,a,c)=>{let _=(t,M)=>Wg(i)(o,{methods:{waitTask:x0}}).waitTask(t.taskID,M);return Nn.createWaitablePromise(i.transporter.write({method:Ur.MethodEnum.Post,path:Nn.encode("1/indexes/%s/operation",o),data:{operation:"move",destination:a}},c),_)},dH=i=>(o,a)=>{let c=(_,t)=>Promise.all(Object.keys(_.taskID).map(M=>Wg(i)(M,{methods:{waitTask:x0}}).waitTask(_.taskID[M],t)));return Nn.createWaitablePromise(i.transporter.write({method:Ur.MethodEnum.Post,path:"1/indexes/*/batch",data:{requests:o}},a),c)},pH=i=>(o,a)=>i.transporter.read({method:Ur.MethodEnum.Post,path:"1/indexes/*/objects",data:{requests:o}},a),hH=i=>(o,a)=>{let c=o.map(_=>Zr(qt({},_),{params:ia.serializeQueryParameters(_.params||{})}));return i.transporter.read({method:Ur.MethodEnum.Post,path:"1/indexes/*/queries",data:{requests:c},cacheable:!0},a)},vH=i=>(o,a)=>Promise.all(o.map(c=>{let N=c.params,{facetName:_,facetQuery:t}=N,M=wl(N,["facetName","facetQuery"]);return Wg(i)(c.indexName,{methods:{searchForFacetValues:$5}}).searchForFacetValues(_,t,qt(qt({},a),M))})),mH=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)},yH=i=>(o,a)=>{let c=(_,t)=>Nn.createRetryablePromise(M=>qg(i)(o,t).catch(N=>{if(N.status!==404)throw N;return M()}));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),_H=i=>(o,a)=>{let c=Object.assign({},a),B=a||{},{queryParameters:_}=B,t=wl(B,["queryParameters"]),M=_?{queryParameters:_}:{},N=["acl","indexes","referers","restrictSources","queryParameters","description","maxQueriesPerIPPerHour","maxHitsPerQuery"],O=H=>Object.keys(c).filter(q=>N.indexOf(q)!==-1).every(q=>H[q]===c[q]),T=(H,q)=>Nn.createRetryablePromise(ne=>qg(i)(o,q).then(m=>O(m)?Promise.resolve():ne()));return Nn.createWaitablePromise(i.transporter.write({method:Ur.MethodEnum.Put,path:Nn.encode("1/keys/%s",o),data:M},t),T)},e9=i=>(o,a)=>{let c=(_,t)=>x0(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)},EH=i=>o=>P4(Zr(qt({},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)})),DH=i=>o=>{let a=qt({hitsPerPage:1e3},o);return P4(Zr(qt({},a),{shouldStop:c=>c.hits.lengthZr(qt({},_),{hits:_.hits.map(t=>(delete t._highlightResult,t))}))}}))},wH=i=>o=>{let a=qt({hitsPerPage:1e3},o);return P4(Zr(qt({},a),{shouldStop:c=>c.hits.lengthZr(qt({},_),{hits:_.hits.map(t=>(delete t._highlightResult,t))}))}}))},B4=i=>(o,a,c)=>{let O=c||{},{batchSize:_}=O,t=wl(O,["batchSize"]),M={taskIDs:[],objectIDs:[]},N=(T=0)=>{let B=[],H;for(H=T;H({action:a,body:q})),t).then(q=>(M.objectIDs=M.objectIDs.concat(q.objectIDs),M.taskIDs.push(q.taskID),H++,N(H)))};return Nn.createWaitablePromise(N(),(T,B)=>Promise.all(T.taskIDs.map(H=>x0(i)(H,B))))},SH=i=>o=>Nn.createWaitablePromise(i.transporter.write({method:Ur.MethodEnum.Post,path:Nn.encode("1/indexes/%s/clear",i.indexName)},o),(a,c)=>x0(i)(a.taskID,c)),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/rules/clear",i.indexName)},_),(M,N)=>x0(i)(M.taskID,N))},CH=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)},_),(M,N)=>x0(i)(M.taskID,N))},xH=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,_)=>x0(i)(c.taskID,_)),RH=i=>o=>Nn.createWaitablePromise(i.transporter.write({method:Ur.MethodEnum.Delete,path:Nn.encode("1/indexes/%s",i.indexName)},o),(a,c)=>x0(i)(a.taskID,c)),AH=i=>(o,a)=>Nn.createWaitablePromise(r9(i)([o],a).then(c=>({taskID:c.taskIDs[0]})),(c,_)=>x0(i)(c.taskID,_)),r9=i=>(o,a)=>{let c=o.map(_=>({objectID:_}));return B4(i)(c,fh.DeleteObject,a)},OH=i=>(o,a)=>{let M=a||{},{forwardToReplicas:c}=M,_=wl(M,["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,O)=>x0(i)(N.taskID,O))},MH=i=>(o,a)=>{let M=a||{},{forwardToReplicas:c}=M,_=wl(M,["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,O)=>x0(i)(N.taskID,O))},kH=i=>o=>i9(i)(o).then(()=>!0).catch(a=>{if(a.status!==404)throw a;return!1}),LH=i=>(o,a)=>{let O=a||{},{query:c,paginate:_}=O,t=wl(O,["query","paginate"]),M=0,N=()=>u9(i)(c||"",Zr(qt({},t),{page:M})).then(T=>{for(let[B,H]of Object.entries(T.hits))if(o(H))return{object:H,position:parseInt(B,10),page:M};if(M++,_===!1||M>=T.nbPages)throw J5();return N()});return N()},NH=i=>(o,a)=>i.transporter.read({method:Ur.MethodEnum.Get,path:Nn.encode("1/indexes/%s/%s",i.indexName,o)},a),FH=()=>(i,o)=>{for(let[a,c]of Object.entries(i.hits))if(c.objectID===o)return parseInt(a,10);return-1},PH=i=>(o,a)=>{let M=a||{},{attributesToRetrieve:c}=M,_=wl(M,["attributesToRetrieve"]),t=o.map(N=>qt({indexName:i.indexName,objectID:N},c?{attributesToRetrieve:c}:{}));return i.transporter.read({method:Ur.MethodEnum.Post,path:"1/indexes/*/objects",data:{requests:t}},_)},IH=i=>(o,a)=>i.transporter.read({method:Ur.MethodEnum.Get,path:Nn.encode("1/indexes/%s/rules/%s",i.indexName,o)},a),i9=i=>o=>i.transporter.read({method:Ur.MethodEnum.Get,path:Nn.encode("1/indexes/%s/settings",i.indexName),data:{getVersion:2}},o),bH=i=>(o,a)=>i.transporter.read({method:Ur.MethodEnum.Get,path:Nn.encode("1/indexes/%s/synonyms/%s",i.indexName,o)},a),o9=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(l9(i)([o],a).then(c=>({objectID:c.objectIDs[0],taskID:c.taskIDs[0]})),(c,_)=>x0(i)(c.taskID,_)),l9=i=>(o,a)=>{let M=a||{},{createIfNotExists:c}=M,_=wl(M,["createIfNotExists"]),t=c?fh.PartialUpdateObject:fh.PartialUpdateObjectNoCreate;return B4(i)(o,t,_)},UH=i=>(o,a)=>{let m=a||{},{safe:c,autoGenerateObjectIDIfNotExist:_,batchSize:t}=m,M=wl(m,["safe","autoGenerateObjectIDIfNotExist","batchSize"]),N=(pe,ge,ve,ue)=>Nn.createWaitablePromise(i.transporter.write({method:Ur.MethodEnum.Post,path:Nn.encode("1/indexes/%s/operation",pe),data:{operation:ve,destination:ge}},ue),(_e,ce)=>x0(i)(_e.taskID,ce)),O=Math.random().toString(36).substring(7),T=`${i.indexName}_tmp_${O}`,B=c3({appId:i.appId,transporter:i.transporter,indexName:T}),H=[],q=N(i.indexName,T,"copy",Zr(qt({},M),{scope:["settings","synonyms","rules"]}));H.push(q);let ne=(c?q.wait(M):q).then(()=>{let pe=B(o,Zr(qt({},M),{autoGenerateObjectIDIfNotExist:_,batchSize:t}));return H.push(pe),c?pe.wait(M):pe}).then(()=>{let pe=N(T,i.indexName,"move",M);return H.push(pe),c?pe.wait(M):pe}).then(()=>Promise.all(H)).then(([pe,ge,ve])=>({objectIDs:ge.objectIDs,taskIDs:[pe.taskID,...ge.taskIDs,ve.taskID]}));return Nn.createWaitablePromise(ne,(pe,ge)=>Promise.all(H.map(ve=>ve.wait(ge))))},jH=i=>(o,a)=>d3(i)(o,Zr(qt({},a),{clearExistingRules:!0})),zH=i=>(o,a)=>p3(i)(o,Zr(qt({},a),{replaceExistingSynonyms:!0})),HH=i=>(o,a)=>Nn.createWaitablePromise(c3(i)([o],a).then(c=>({objectID:c.objectIDs[0],taskID:c.taskIDs[0]})),(c,_)=>x0(i)(c.taskID,_)),c3=i=>(o,a)=>{let M=a||{},{autoGenerateObjectIDIfNotExist:c}=M,_=wl(M,["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(Q5()))}return B4(i)(o,t,_)},qH=i=>(o,a)=>d3(i)([o],a),d3=i=>(o,a)=>{let N=a||{},{forwardToReplicas:c,clearExistingRules:_}=N,t=wl(N,["forwardToReplicas","clearExistingRules"]),M=ia.createMappedRequestOptions(t);return c&&(M.queryParameters.forwardToReplicas=1),_&&(M.queryParameters.clearExistingRules=1),Nn.createWaitablePromise(i.transporter.write({method:Ur.MethodEnum.Post,path:Nn.encode("1/indexes/%s/rules/batch",i.indexName),data:o},M),(O,T)=>x0(i)(O.taskID,T))},WH=i=>(o,a)=>p3(i)([o],a),p3=i=>(o,a)=>{let N=a||{},{forwardToReplicas:c,replaceExistingSynonyms:_}=N,t=wl(N,["forwardToReplicas","replaceExistingSynonyms"]),M=ia.createMappedRequestOptions(t);return c&&(M.queryParameters.forwardToReplicas=1),_&&(M.queryParameters.replaceExistingSynonyms=1),Nn.createWaitablePromise(i.transporter.write({method:Ur.MethodEnum.Post,path:Nn.encode("1/indexes/%s/synonyms/batch",i.indexName),data:o},M),(O,T)=>x0(i)(O.taskID,T))},u9=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),$5=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),t9=i=>(o,a)=>i.transporter.read({method:Ur.MethodEnum.Post,path:Nn.encode("1/indexes/%s/rules/search",i.indexName),data:{query:o}},a),n9=i=>(o,a)=>i.transporter.read({method:Ur.MethodEnum.Post,path:Nn.encode("1/indexes/%s/synonyms/search",i.indexName),data:{query:o}},a),VH=i=>(o,a)=>{let M=a||{},{forwardToReplicas:c}=M,_=wl(M,["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,O)=>x0(i)(N.taskID,O))},x0=i=>(o,a)=>Nn.createRetryablePromise(c=>o9(i)(o,a).then(_=>_.status!=="published"?c():void 0)),GH={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"},YH={None:"none",StopIfEnoughMatches:"stopIfEnoughMatches"},KH={Synonym:"synonym",OneWaySynonym:"oneWaySynonym",AltCorrection1:"altCorrection1",AltCorrection2:"altCorrection2",Placeholder:"placeholder"};tn.ApiKeyACLEnum=GH;tn.BatchActionEnum=fh;tn.ScopeEnum=b4;tn.StrategyEnum=YH;tn.SynonymEnum=KH;tn.addApiKey=Kz;tn.assignUserID=Xz;tn.assignUserIDs=Qz;tn.batch=e9;tn.browseObjects=EH;tn.browseRules=DH;tn.browseSynonyms=wH;tn.chunkedBatch=B4;tn.clearObjects=SH;tn.clearRules=TH;tn.clearSynonyms=CH;tn.copyIndex=I4;tn.copyRules=Jz;tn.copySettings=Zz;tn.copySynonyms=$z;tn.createBrowsablePromise=P4;tn.createMissingObjectIDError=Q5;tn.createObjectNotFoundError=J5;tn.createSearchClient=Yz;tn.createValidUntilNotFoundError=Z5;tn.deleteApiKey=eH;tn.deleteBy=xH;tn.deleteIndex=RH;tn.deleteObject=AH;tn.deleteObjects=r9;tn.deleteRule=OH;tn.deleteSynonym=MH;tn.exists=kH;tn.findObject=LH;tn.generateSecuredApiKey=tH;tn.getApiKey=qg;tn.getLogs=nH;tn.getObject=NH;tn.getObjectPosition=FH;tn.getObjects=PH;tn.getRule=IH;tn.getSecuredApiKeyRemainingValidity=rH;tn.getSettings=i9;tn.getSynonym=bH;tn.getTask=o9;tn.getTopUserIDs=iH;tn.getUserID=uH;tn.hasPendingMappings=oH;tn.initIndex=Wg;tn.listApiKeys=lH;tn.listClusters=sH;tn.listIndices=aH;tn.listUserIDs=fH;tn.moveIndex=cH;tn.multipleBatch=dH;tn.multipleGetObjects=pH;tn.multipleQueries=hH;tn.multipleSearchForFacetValues=vH;tn.partialUpdateObject=BH;tn.partialUpdateObjects=l9;tn.removeUserID=mH;tn.replaceAllObjects=UH;tn.replaceAllRules=jH;tn.replaceAllSynonyms=zH;tn.restoreApiKey=yH;tn.saveObject=HH;tn.saveObjects=c3;tn.saveRule=qH;tn.saveRules=d3;tn.saveSynonym=WH;tn.saveSynonyms=p3;tn.search=u9;tn.searchForFacetValues=$5;tn.searchRules=t9;tn.searchSynonyms=n9;tn.searchUserIDs=gH;tn.setSettings=VH;tn.updateApiKey=_H;tn.waitTask=x0});var f9=Ke((eY,a9)=>{a9.exports=s9()});var c9=Ke(U4=>{"use strict";Object.defineProperty(U4,"__esModule",{value:!0});function XH(){return{debug(i,o){return Promise.resolve()},info(i,o){return Promise.resolve()},error(i,o){return Promise.resolve()}}}var QH={Debug:1,Info:2,Error:3};U4.LogLevelEnum=QH;U4.createNullLogger=XH});var p9=Ke((nY,d9)=>{d9.exports=c9()});var m9=Ke(h3=>{"use strict";Object.defineProperty(h3,"__esModule",{value:!0});var h9=require("http"),v9=require("https"),JH=require("url");function ZH(){let i={keepAlive:!0},o=new h9.Agent(i),a=new v9.Agent(i);return{send(c){return new Promise(_=>{let t=JH.parse(c.url),M=t.query===null?t.pathname:`${t.pathname}?${t.query}`,N=qt({agent:t.protocol==="https:"?a:o,hostname:t.hostname,path:M,method:c.method,headers:c.headers},t.port!==void 0?{port:t.port||""}:{}),O=(t.protocol==="https:"?v9:h9).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(()=>{O.abort(),_({status:0,content:ne,isTimedOut:!0})},q*1e3),B=T(c.connectTimeout,"Connection timeout"),H;O.on("error",q=>{clearTimeout(B),clearTimeout(H),_({status:0,content:q.message,isTimedOut:!1})}),O.once("response",()=>{clearTimeout(B),H=T(c.responseTimeout,"Socket timeout")}),c.data!==void 0&&O.write(c.data),O.end()})},destroy(){return o.destroy(),a.destroy(),Promise.resolve()}}}h3.createNodeHttpRequester=ZH});var g9=Ke((iY,y9)=>{y9.exports=m9()});var w9=Ke((uY,_9)=>{"use strict";var E9=g5(),$H=D5(),im=V5(),v3=Bg(),m3=X5(),wn=f9(),eq=p9(),tq=g9(),nq=jg();function D9(i,o,a){let c={appId:i,apiKey:o,timeouts:{connect:2,read:5,write:30},requester:tq.createNodeHttpRequester(),logger:eq.createNullLogger(),responsesCache:E9.createNullCache(),requestsCache:E9.createNullCache(),hostsCache:$H.createInMemoryCache(),userAgent:nq.createUserAgent(v3.version).add({segment:"Node.js",version:process.versions.node})};return wn.createSearchClient(Zr(qt(qt({},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:v3.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(qt(qt({},c),_),{methods:{addABTest:im.addABTest,getABTest:im.getABTest,getABTests:im.getABTests,stopABTest:im.stopABTest,deleteABTest:im.deleteABTest}})),initRecommendation:()=>_=>m3.createRecommendationClient(Zr(qt(qt({},c),_),{methods:{getPersonalizationStrategy:m3.getPersonalizationStrategy,setPersonalizationStrategy:m3.setPersonalizationStrategy}}))}}))}D9.version=v3.version;_9.exports=D9});var T9=Ke((oY,y3)=>{var S9=w9();y3.exports=S9;y3.exports.default=S9});var nd=Ke(E3=>{"use strict";Object.defineProperty(E3,"__esModule",{value:!0});E3.default=N9;function N9(){}N9.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 M(pe){return _?(setTimeout(function(){_(void 0,pe)},0),!0):pe}o=this.castInput(o),a=this.castInput(a),o=this.removeEmpty(this.tokenize(o)),a=this.removeEmpty(this.tokenize(a));var N=a.length,O=o.length,T=1,B=N+O,H=[{newPos:-1,components:[]}],q=this.extractCommon(H[0],a,o,0);if(H[0].newPos+1>=N&&q+1>=O)return M([{value:this.join(a),count:a.length}]);function ne(){for(var pe=-1*T;pe<=T;pe+=2){var ge=void 0,ve=H[pe-1],ue=H[pe+1],_e=(ue?ue.newPos:0)-pe;ve&&(H[pe-1]=void 0);var ce=ve&&ve.newPos+1=N&&_e+1>=O)return M(iq(t,ge.components,a,o,t.useLongestToken));H[pe]=ge}T++}if(_)(function pe(){setTimeout(function(){if(T>B)return _();ne()||pe()},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,M=c.length,N=o.newPos,O=N-_,T=0;N+1ne.length?pe:ne}),T.value=i.join(B)}else T.value=i.join(a.slice(N,N+T.count));N+=T.count,T.added||(O+=T.count)}}var q=o[M-1];return M>1&&typeof q.value=="string"&&(q.added||q.removed)&&i.equals("",q.value)&&(o[M-2].value+=q.value,o.pop()),o}function uq(i){return{newPos:i.newPos,components:i.components.slice(0)}}});var P9=Ke(Kg=>{"use strict";Object.defineProperty(Kg,"__esModule",{value:!0});Kg.diffChars=oq;Kg.characterDiff=void 0;var sq=lq(nd());function lq(i){return i&&i.__esModule?i:{default:i}}var F9=new sq.default;Kg.characterDiff=F9;function oq(i,o,a){return F9.diff(i,o,a)}});var w3=Ke(D3=>{"use strict";Object.defineProperty(D3,"__esModule",{value:!0});D3.generateOptions=aq;function aq(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=fq;um.diffWordsWithSpace=cq;um.wordDiff=void 0;var pq=dq(nd()),hq=w3();function dq(i){return i&&i.__esModule?i:{default:i}}var I9=/^[A-Za-z\xC0-\u02C6\u02C8-\u02D7\u02DE-\u02FF\u1E00-\u1EFF]+$/,b9=/\S/,Xg=new pq.default;um.wordDiff=Xg;Xg.equals=function(i,o){return this.options.ignoreCase&&(i=i.toLowerCase(),o=o.toLowerCase()),i===o||this.options.ignoreWhitespace&&!b9.test(i)&&!b9.test(o)};Xg.tokenize=function(i){for(var o=i.split(/(\s+|[()[\]{}'"]|\b)/),a=0;a{"use strict";Object.defineProperty(om,"__esModule",{value:!0});om.diffLines=vq;om.diffTrimmedLines=mq;om.lineDiff=void 0;var gq=yq(nd()),_q=w3();function yq(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(Qg,"__esModule",{value:!0});Qg.diffSentences=Eq;Qg.sentenceDiff=void 0;var wq=Dq(nd());function Dq(i){return i&&i.__esModule?i:{default:i}}var S3=new wq.default;Qg.sentenceDiff=S3;S3.tokenize=function(i){return i.split(/(\S.+?[.!?])(?=\s+|$)/)};function Eq(i,o,a){return S3.diff(i,o,a)}});var j9=Ke(Jg=>{"use strict";Object.defineProperty(Jg,"__esModule",{value:!0});Jg.diffCss=Sq;Jg.cssDiff=void 0;var Cq=Tq(nd());function Tq(i){return i&&i.__esModule?i:{default:i}}var T3=new Cq.default;Jg.cssDiff=T3;T3.tokenize=function(i){return i.split(/([{}:;,]|\s+)/)};function Sq(i,o,a){return T3.diff(i,o,a)}});var H9=Ke(lm=>{"use strict";Object.defineProperty(lm,"__esModule",{value:!0});lm.diffJson=xq;lm.canonicalize=q4;lm.jsonDiff=void 0;var z9=Rq(nd()),Aq=H4();function Rq(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 Oq=Object.prototype.toString,dh=new z9.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,M){return typeof M=="undefined"?a:M}:c;return typeof i=="string"?i:JSON.stringify(q4(i,null,null,_),_," ")};dh.equals=function(i,o){return z9.default.prototype.equals.call(dh,i.replace(/,([\r\n])/g,"$1"),o.replace(/,([\r\n])/g,"$1"))};function xq(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(Zg,"__esModule",{value:!0});Zg.diffArrays=Mq;Zg.arrayDiff=void 0;var Lq=kq(nd());function kq(i){return i&&i.__esModule?i:{default:i}}var $g=new Lq.default;Zg.arrayDiff=$g;$g.tokenize=function(i){return i.slice()};$g.join=$g.removeEmpty=function(i){return i};function Mq(i,o,a){return $g.diff(i,o,a)}});var V4=Ke(C3=>{"use strict";Object.defineProperty(C3,"__esModule",{value:!0});C3.parsePatch=Nq;function Nq(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 M(){var T={};for(_.push(T);t{"use strict";Object.defineProperty(x3,"__esModule",{value:!0});x3.default=Fq;function Fq(i,o,a){var c=!0,_=!1,t=!1,M=1;return function N(){if(c&&!t){if(_?M++:c=!1,i+M<=a)return M;t=!0}if(!_)return t||(c=!0),o<=i-M?-M++:(_=!0,N())}}});var Y9=Ke(G4=>{"use strict";Object.defineProperty(G4,"__esModule",{value:!0});G4.applyPatch=V9;G4.applyPatches=Pq;var G9=V4(),bq=Iq(W9());function Iq(i){return i&&i.__esModule?i:{default:i}}function V9(i,o){var a=arguments.length>2&&arguments[2]!==void 0?arguments[2]:{};if(typeof o=="string"&&(o=(0,G9.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,M=a.compareLine||function(kt,zt,nt,X){return zt===X},N=0,O=a.fuzzFactor||0,T=0,B=0,H,q;function ne(kt,zt){for(var nt=0;nt0?X[0]:" ",xe=X.length>0?X.substr(1):X;if(fe===" "||fe==="-"){if(!M(zt+1,c[zt],fe,xe)&&(N++,N>O))return!1;zt++}}return!0}for(var m=0;m0?je[0]:" ",pt=je.length>0?je.substr(1):je,Xe=re.linedelimiters[Ie];if(ct===" ")we++;else if(ct==="-")c.splice(we,1),_.splice(we,1);else if(ct==="+")c.splice(we,0,pt),_.splice(we,0,Xe),we++;else if(ct==="\\"){var tt=re.lines[Ie-1]?re.lines[Ie-1][0]:null;tt==="+"?H=!0:tt==="-"&&(q=!0)}}}if(H)for(;!c[c.length-1];)c.pop(),_.pop();else q&&(c.push(""),_.push(` -`));for(var He=0;He{"use strict";Object.defineProperty(e_,"__esModule",{value:!0});e_.structuredPatch=K9;e_.createTwoFilesPatch=X9;e_.createPatch=Bq;var Uq=H4();function R3(i){return Hq(i)||zq(i)||jq()}function jq(){throw new TypeError("Invalid attempt to spread non-iterable instance")}function zq(i){if(Symbol.iterator in Object(i)||Object.prototype.toString.call(i)==="[object Arguments]")return Array.from(i)}function Hq(i){if(Array.isArray(i)){for(var o=0,a=new Array(i.length);o0?O(re.lines.slice(-M.context)):[],B-=q.length,H-=q.length)}(me=q).push.apply(me,R3(ce.map(function(He){return(_e.added?"+":"-")+He}))),_e.added?m+=ce.length:ne+=ce.length}else{if(B)if(ce.length<=M.context*2&&ue=N.length-2&&ce.length<=M.context){var pt=/\n$/.test(a),Xe=/\n$/.test(c),tt=ce.length==0&&q.length>ct.oldLines;!pt&&tt&&q.splice(ct.oldLines,0,"\\ No newline at end of file"),(!pt&&!tt||!Xe)&&q.push("\\ No newline at end of file")}T.push(ct),B=0,H=0,q=[]}ne+=ce.length,m+=ce.length}},ge=0;ge{"use strict";Object.defineProperty(Y4,"__esModule",{value:!0});Y4.arrayEqual=qq;Y4.arrayStartsWith=Q9;function qq(i,o){return i.length!==o.length?!1:Q9(i,o)}function Q9(i,o){if(o.length>i.length)return!1;for(var a=0;a{"use strict";Object.defineProperty(K4,"__esModule",{value:!0});K4.calcLineCount=Z9;K4.merge=Wq;var Vq=A3(),Gq=V4(),O3=J9();function sm(i){return Xq(i)||Kq(i)||Yq()}function Yq(){throw new TypeError("Invalid attempt to spread non-iterable instance")}function Kq(i){if(Symbol.iterator in Object(i)||Object.prototype.toString.call(i)==="[object Arguments]")return Array.from(i)}function Xq(i){if(Array.isArray(i)){for(var o=0,a=new Array(i.length);o{"use strict";Object.defineProperty(L3,"__esModule",{value:!0});L3.convertChangesToDMP=$q;function $q(i){for(var o=[],a,c,_=0;_{"use strict";Object.defineProperty(N3,"__esModule",{value:!0});N3.convertChangesToXML=eW;function eW(i){for(var o=[],a=0;a"):c.removed&&o.push(""),o.push(tW(c.value)),c.added?o.push(""):c.removed&&o.push("")}return o.join("")}function tW(i){var o=i;return o=o.replace(/&/g,"&"),o=o.replace(//g,">"),o=o.replace(/"/g,"""),o}});var vR=Ke(Yo=>{"use strict";Object.defineProperty(Yo,"__esModule",{value:!0});Object.defineProperty(Yo,"Diff",{enumerable:!0,get:function(){return nW.default}});Object.defineProperty(Yo,"diffChars",{enumerable:!0,get:function(){return rW.diffChars}});Object.defineProperty(Yo,"diffWords",{enumerable:!0,get:function(){return cR.diffWords}});Object.defineProperty(Yo,"diffWordsWithSpace",{enumerable:!0,get:function(){return cR.diffWordsWithSpace}});Object.defineProperty(Yo,"diffLines",{enumerable:!0,get:function(){return dR.diffLines}});Object.defineProperty(Yo,"diffTrimmedLines",{enumerable:!0,get:function(){return dR.diffTrimmedLines}});Object.defineProperty(Yo,"diffSentences",{enumerable:!0,get:function(){return iW.diffSentences}});Object.defineProperty(Yo,"diffCss",{enumerable:!0,get:function(){return uW.diffCss}});Object.defineProperty(Yo,"diffJson",{enumerable:!0,get:function(){return pR.diffJson}});Object.defineProperty(Yo,"canonicalize",{enumerable:!0,get:function(){return pR.canonicalize}});Object.defineProperty(Yo,"diffArrays",{enumerable:!0,get:function(){return oW.diffArrays}});Object.defineProperty(Yo,"applyPatch",{enumerable:!0,get:function(){return hR.applyPatch}});Object.defineProperty(Yo,"applyPatches",{enumerable:!0,get:function(){return hR.applyPatches}});Object.defineProperty(Yo,"parsePatch",{enumerable:!0,get:function(){return lW.parsePatch}});Object.defineProperty(Yo,"merge",{enumerable:!0,get:function(){return sW.merge}});Object.defineProperty(Yo,"structuredPatch",{enumerable:!0,get:function(){return F3.structuredPatch}});Object.defineProperty(Yo,"createTwoFilesPatch",{enumerable:!0,get:function(){return F3.createTwoFilesPatch}});Object.defineProperty(Yo,"createPatch",{enumerable:!0,get:function(){return F3.createPatch}});Object.defineProperty(Yo,"convertChangesToDMP",{enumerable:!0,get:function(){return aW.convertChangesToDMP}});Object.defineProperty(Yo,"convertChangesToXML",{enumerable:!0,get:function(){return fW.convertChangesToXML}});var nW=cW(nd()),rW=P9(),cR=B9(),dR=H4(),iW=U9(),uW=j9(),pR=H9(),oW=q9(),hR=Y9(),lW=V4(),sW=sR(),F3=A3(),aW=aR(),fW=fR();function cW(i){return i&&i.__esModule?i:{default:i}}});var dW={};oI(dW,{default:()=>hW});var x9=ou(require("@yarnpkg/cli")),ch=ou(require("@yarnpkg/core"));var u5=ou(sc()),lh=ou(Mi()),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(u5.Text,{color:a},o)});var g2=ou(sc()),ra=ou(Mi());var o5=ou(sc()),x4=ou(Mi());function y2({active:i},o,a){let{stdin:c}=(0,o5.useStdin)(),_=(0,x4.useCallback)((t,M)=>o(t,M),a);(0,x4.useEffect)(()=>{if(!(!i||!c))return c.on("keypress",_),()=>{c.off("keypress",_)}},[i,_,c])}var R4;(function(a){a.BEFORE="before",a.AFTER="after"})(R4||(R4={}));var l5=function({active:i},o,a){y2({active:i},(c,_)=>{_.name==="tab"&&(_.shift?o(R4.BEFORE):o(R4.AFTER))},a)};var A4=function(i,o,{active:a,minus:c,plus:_,set:t,loop:M=!0}){y2({active:a},(N,O)=>{let T=o.indexOf(i);switch(O.name){case c:{let B=T-1;if(M){t(o[(o.length+B)%o.length]);return}if(B<0)return;t(o[B])}break;case _:{let B=T+1;if(M){t(o[B%o.length]);return}if(B>=o.length)return;t(o[B])}break}},[o,i,_,t,M])};var O4=({active:i=!0,children:o=[],radius:a=10,size:c=1,loop:_=!0,onFocusRequest:t,willReachEnd:M})=>{let N=ge=>{if(ge.key===null)throw new Error("Expected all children to have a key");return ge.key},O=ra.default.Children.map(o,ge=>N(ge)),T=O[0],[B,H]=(0,ra.useState)(T),q=O.indexOf(B);(0,ra.useEffect)(()=>{O.includes(B)||H(T)},[o]),(0,ra.useEffect)(()=>{M&&q>=O.length-2&&M()},[q]),l5({active:i&&!!t},ge=>{t==null||t(ge)},[t]),A4(B,O,{active:i,minus:"up",plus:"down",set:H,loop:_});let ne=q-a,m=q+a;m>O.length&&(ne-=m-O.length,m=O.length),ne<0&&(m+=-ne,ne=0),m>=O.length&&(m=O.length-1);let pe=[];for(let ge=ne;ge<=m;++ge){let ve=O[ge],ue=i&&ve===B;pe.push(ra.default.createElement(g2.Box,{key:ve,height:c},ra.default.createElement(g2.Box,{marginLeft:1,marginRight:1},ra.default.createElement(g2.Text,null,ue?ra.default.createElement(g2.Text,{color:"cyan",bold:!0},">"):" ")),ra.default.createElement(g2.Box,null,ra.default.cloneElement(o[ge],{active:ue}))))}return ra.default.createElement(g2.Box,{flexDirection:"column",width:"100%"},pe)};var M4=ou(Mi());var s5=ou(sc()),td=ou(Mi()),a5=ou(require("readline")),$w=td.default.createContext(null),f5=({children:i})=>{let{stdin:o,setRawMode:a}=(0,s5.useStdin)();(0,td.useEffect)(()=>{a&&a(!0),o&&(0,a5.emitKeypressEvents)(o)},[o,a]);let[c,_]=(0,td.useState)(new Map),t=(0,td.useMemo)(()=>({getAll:()=>c,get:M=>c.get(M),set:(M,N)=>_(new Map([...c,[M,N]]))}),[c,_]);return td.default.createElement($w.Provider,{value:t,children:i})};function sh(i,o){let a=(0,M4.useContext)($w);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()),e3=ou(Mi());async function L4(i,o,{stdin:a,stdout:c,stderr:_}={}){let t,M=O=>{let{exit:T}=(0,k4.useApp)();y2({active:!0},(B,H)=>{H.name==="return"&&(t=O,T())},[T,O])},{waitUntilExit:N}=(0,k4.render)(e3.default.createElement(f5,null,e3.default.createElement(i,Zr(qt({},o),{useSubmit:M}))),{stdin:a,stdout:c,stderr:_});return await N(),t}var R9=ou(require("clipanion")),A9=ou(h5()),or=ou(sc()),En=ou(Mi());var C9=ou(T9()),g3={appId:"OFCNCOG2CU",apiKey:"6fe4476ee5a1832882e326b506d14126",indexName:"npm-search"},rq=(0,C9.default)(g3.appId,g3.apiKey).initIndex(g3.indexName),_3=async(i,o=0)=>await rq.search(i,{analyticsTags:["yarn-plugin-interactive-tools"],attributesToRetrieve:["name","version","owner","repository","humanDownloadsLast30Days"],page:o,hitsPerPage:10});var Vg=["regular","dev","peer"],Gg=class extends x9.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[pe,ge]=sh(ne.name,null);y2({active:m},(_e,ce)=>{if(ce.name!=="space")return;if(!pe){ge(Vg[0]);return}let me=Vg.indexOf(pe)+1;me===Vg.length?ge(null):ge(Vg[me])},[pe,ge]);let ve=ch.structUtils.parseIdent(ne.name),ue=ch.structUtils.prettyIdent(o,ve);return En.default.createElement(or.Box,null,En.default.createElement(or.Box,{width:45},En.default.createElement(or.Text,{bold:!0,wrap:"wrap"},ue)),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)))},M=({name:ne,active:m})=>{let[pe]=sh(ne,null),ge=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,ge))),Vg.map(ve=>En.default.createElement(or.Box,{key:ve,width:14,marginLeft:1},En.default.createElement(or.Text,null," ",En.default.createElement(C4,{active:pe===ve})," ",En.default.createElement(or.Text,{bold:!0},ve)))))},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 pe=Array.from(m.keys()).filter(je=>m.get(je)!==null),[ge,ve]=(0,En.useState)(""),[ue,_e]=(0,En.useState)(0),[ce,me]=(0,En.useState)([]),re=je=>{je.match(/\t| /)||ve(je)},we=async()=>{_e(0);let je=await _3(ge);je.query===ge&&me(je.hits)},Ie=async()=>{let je=await _3(ge,ue+1);je.query===ge&&je.page-1===ue&&(_e(je.page),me([...ce,...je.hits]))};return(0,En.useEffect)(()=>{ge?we():me([])},[ge]),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:ge,onChange:re,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:Ie}):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)),pe.length?pe.map(je=>En.default.createElement(M,{key:je,name:je,active:!1})):En.default.createElement(or.Text,{color:"gray"},"No selected packages..."),En.default.createElement(N,null))},{},{stdin:this.context.stdin,stdout:this.context.stdout,stderr:this.context.stderr});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}};Gg.paths=[["search"]],Gg.usage=R9.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 O9=Gg;var Q4=ou(require("@yarnpkg/cli")),R0=ou(require("@yarnpkg/core"));var Yg=ou(sc()),E2=ou(Mi());var M9=ou(sc()),k9=ou(Mi()),j4=({length:i,active:o})=>{if(i===0)return null;let a=i>1?` ${"-".repeat(i-1)}`:" ";return k9.default.createElement(M9.Text,{dimColor:!o},a)};var L9=function({active:i,skewer:o,options:a,value:c,onChange:_,sizes:t=[]}){let M=a.filter(({label:O})=>!!O).map(({value:O})=>O),N=a.findIndex(O=>O.value===c&&O.label!="");return A4(c,M,{active:i,minus:"left",plus:"right",set:_}),E2.default.createElement(E2.default.Fragment,null,a.map(({label:O},T)=>{let B=T===N,H=t[T]-1||0,q=O.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 O?E2.default.createElement(Yg.Box,{key:O,width:H,marginLeft:1},E2.default.createElement(Yg.Text,{wrap:"truncate"},E2.default.createElement(C4,{active:B})," ",O),o?E2.default.createElement(j4,{active:i,length:ne}):null):E2.default.createElement(Yg.Box,{key:`spacer-${T}`,width:H,marginLeft:1})}))};var mR=ou(require("@yarnpkg/plugin-essentials")),J4=ou(require("clipanion")),yR=ou(vR()),bi=ou(sc()),Tr=ou(Mi()),gR=ou(require("semver")),_R=/^((?:[\^~]|>=?)?)([0-9]+)(\.[0-9]+)(\.[0-9]+)((?:-\S+)?)$/,ER=(i,o)=>i.length>0?[i.slice(0,o)].concat(ER(i.slice(o),o)):[],t_=class extends Q4.BaseCommand{async execute(){if(!this.context.stdout.isTTY)throw new J4.UsageError("This command can only be run in a TTY environment");let o=await R0.Configuration.find(this.context.cwd,this.context.plugins),{project:a,workspace:c}=await R0.Project.find(o,this.context.cwd),_=await R0.Cache.find(o);if(!c)throw new Q4.WorkspaceRequiredError(a.cwd,this.context.cwd);await a.restoreInstallState({restoreResolutions:!1});let t=this.context.stdout.rows-7,M=(ue,_e)=>{let ce=(0,yR.diffWords)(ue,_e),me="";for(let re of ce)re.added?me+=R0.formatUtils.pretty(o,re.value,"green"):re.removed||(me+=re.value);return me},N=(ue,_e)=>{if(ue===_e)return _e;let ce=R0.structUtils.parseRange(ue),me=R0.structUtils.parseRange(_e),re=ce.selector.match(_R),we=me.selector.match(_R);if(!re||!we)return M(ue,_e);let Ie=["gray","red","yellow","green","magenta"],je=null,ct="";for(let pt=1;pt{let me=await mR.suggestUtils.fetchDescriptorFrom(ue,ce,{project:a,cache:_,preserveModifier:_e,workspace:c});return me!==null?me.range:ue.range},T=async ue=>{let _e=gR.default.valid(ue.range)?`^${ue.range}`:ue.range,[ce,me]=await Promise.all([O(ue,ue.range,_e).catch(()=>null),O(ue,ue.range,"latest").catch(()=>null)]),re=[{value:null,label:ue.range}];return ce&&ce!==ue.range?re.push({value:ce,label:N(ue.range,ce)}):re.push({value:null,label:""}),me&&me!==ce&&me!==ue.range?re.push({value:me,label:N(ue.range,me)}):re.push({value:null,label:""}),re},B=()=>Tr.default.createElement(bi.Box,{flexDirection:"row"},Tr.default.createElement(bi.Box,{flexDirection:"column",width:49},Tr.default.createElement(bi.Box,{marginLeft:1},Tr.default.createElement(bi.Text,null,"Press ",Tr.default.createElement(bi.Text,{bold:!0,color:"cyanBright"},""),"/",Tr.default.createElement(bi.Text,{bold:!0,color:"cyanBright"},"")," to select packages.")),Tr.default.createElement(bi.Box,{marginLeft:1},Tr.default.createElement(bi.Text,null,"Press ",Tr.default.createElement(bi.Text,{bold:!0,color:"cyanBright"},""),"/",Tr.default.createElement(bi.Text,{bold:!0,color:"cyanBright"},"")," to select versions."))),Tr.default.createElement(bi.Box,{flexDirection:"column"},Tr.default.createElement(bi.Box,{marginLeft:1},Tr.default.createElement(bi.Text,null,"Press ",Tr.default.createElement(bi.Text,{bold:!0,color:"cyanBright"},"")," to install.")),Tr.default.createElement(bi.Box,{marginLeft:1},Tr.default.createElement(bi.Text,null,"Press ",Tr.default.createElement(bi.Text,{bold:!0,color:"cyanBright"},"")," to abort.")))),H=()=>Tr.default.createElement(bi.Box,{flexDirection:"row",paddingTop:1,paddingBottom:1},Tr.default.createElement(bi.Box,{width:50},Tr.default.createElement(bi.Text,{bold:!0},Tr.default.createElement(bi.Text,{color:"greenBright"},"?")," Pick the packages you want to upgrade.")),Tr.default.createElement(bi.Box,{width:17},Tr.default.createElement(bi.Text,{bold:!0,underline:!0,color:"gray"},"Current")),Tr.default.createElement(bi.Box,{width:17},Tr.default.createElement(bi.Text,{bold:!0,underline:!0,color:"gray"},"Range")),Tr.default.createElement(bi.Box,{width:17},Tr.default.createElement(bi.Text,{bold:!0,underline:!0,color:"gray"},"Latest"))),q=({active:ue,descriptor:_e,suggestions:ce})=>{let[me,re]=sh(_e.descriptorHash,null),we=R0.structUtils.stringifyIdent(_e),Ie=Math.max(0,45-we.length);return Tr.default.createElement(Tr.default.Fragment,null,Tr.default.createElement(bi.Box,null,Tr.default.createElement(bi.Box,{width:45},Tr.default.createElement(bi.Text,{bold:!0},R0.structUtils.prettyIdent(o,_e)),Tr.default.createElement(j4,{active:ue,length:Ie})),Tr.default.createElement(L9,{active:ue,options:ce,value:me,skewer:!0,onChange:re,sizes:[17,17,17]})))},ne=({dependencies:ue})=>{let[_e,ce]=(0,Tr.useState)(ue.map(()=>null)),me=(0,Tr.useRef)(!0),re=async we=>{let Ie=await T(we);return Ie.filter(je=>je.label!=="").length<=1?null:{descriptor:we,suggestions:Ie}};return(0,Tr.useEffect)(()=>()=>{me.current=!1},[]),(0,Tr.useEffect)(()=>{let we=Math.trunc(t*1.75),Ie=ue.slice(0,we),je=ue.slice(we),ct=ER(je,t),pt=Ie.map(re).reduce(async(Xe,tt)=>{await Xe;let He=await tt;He!==null&&(!me.current||ce(kt=>{let zt=kt.findIndex(X=>X===null),nt=[...kt];return nt[zt]=He,nt}))},Promise.resolve());ct.reduce((Xe,tt)=>Promise.all(tt.map(He=>Promise.resolve().then(()=>re(He)))).then(async He=>{He=He.filter(kt=>kt!==null),await Xe,me.current&&ce(kt=>{let zt=kt.findIndex(nt=>nt===null);return kt.slice(0,zt).concat(He).concat(kt.slice(zt+He.length))})}),pt).then(()=>{me.current&&ce(Xe=>Xe.filter(tt=>tt!==null))})},[]),_e.length?Tr.default.createElement(O4,{radius:t>>1,children:_e.map((we,Ie)=>we!==null?Tr.default.createElement(q,{key:Ie,active:!1,descriptor:we.descriptor,suggestions:we.suggestions}):Tr.default.createElement(bi.Text,{key:Ie},"Loading..."))}):Tr.default.createElement(bi.Text,null,"No upgrades found")},pe=await L4(({useSubmit:ue})=>{ue(sh());let _e=new Map;for(let me of a.workspaces)for(let re of["dependencies","devDependencies"])for(let we of me.manifest[re].values())a.tryWorkspaceByDescriptor(we)===null&&_e.set(we.descriptorHash,we);let ce=R0.miscUtils.sortMap(_e.values(),me=>R0.structUtils.stringifyDescriptor(me));return Tr.default.createElement(bi.Box,{flexDirection:"column"},Tr.default.createElement(B,null),Tr.default.createElement(H,null),Tr.default.createElement(ne,{dependencies:ce}))},{},{stdin:this.context.stdin,stdout:this.context.stdout,stderr:this.context.stderr});if(typeof pe=="undefined")return 1;let ge=!1;for(let ue of a.workspaces)for(let _e of["dependencies","devDependencies"]){let ce=ue.manifest[_e];for(let me of ce.values()){let re=pe.get(me.descriptorHash);typeof re!="undefined"&&re!==null&&(ce.set(me.identHash,R0.structUtils.makeDescriptor(me,re)),ge=!0)}}return ge?(await R0.StreamReport.start({configuration:o,stdout:this.context.stdout,includeLogs:!this.context.quiet},async ue=>{await a.install({cache:_,report:ue})})).exitCode():0}};t_.paths=[["upgrade-interactive"]],t_.usage=J4.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 DR=t_;var pW={commands:[O9,DR]},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/releases/yarn-3.2.2.cjs b/.yarn/releases/yarn-3.2.2.cjs deleted file mode 100755 index 0912bea85ea..00000000000 --- a/.yarn/releases/yarn-3.2.2.cjs +++ /dev/null @@ -1,783 +0,0 @@ -#!/usr/bin/env node -/* eslint-disable */ -//prettier-ignore -(()=>{var nge=Object.create,Mh=Object.defineProperty,sge=Object.defineProperties,oge=Object.getOwnPropertyDescriptor,age=Object.getOwnPropertyDescriptors,Age=Object.getOwnPropertyNames,DE=Object.getOwnPropertySymbols,lge=Object.getPrototypeOf,eQ=Object.prototype.hasOwnProperty,OO=Object.prototype.propertyIsEnumerable;var MO=(r,e,t)=>e in r?Mh(r,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):r[e]=t,N=(r,e)=>{for(var t in e||(e={}))eQ.call(e,t)&&MO(r,t,e[t]);if(DE)for(var t of DE(e))OO.call(e,t)&&MO(r,t,e[t]);return r},te=(r,e)=>sge(r,age(e)),cge=r=>Mh(r,"__esModule",{value:!0});var Or=(r,e)=>{var t={};for(var i in r)eQ.call(r,i)&&e.indexOf(i)<0&&(t[i]=r[i]);if(r!=null&&DE)for(var i of DE(r))e.indexOf(i)<0&&OO.call(r,i)&&(t[i]=r[i]);return t},uge=(r,e)=>()=>(r&&(e=r(r=0)),e),w=(r,e)=>()=>(e||r((e={exports:{}}).exports,e),e.exports),ft=(r,e)=>{for(var t in e)Mh(r,t,{get:e[t],enumerable:!0})},gge=(r,e,t)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of Age(e))!eQ.call(r,i)&&i!=="default"&&Mh(r,i,{get:()=>e[i],enumerable:!(t=oge(e,i))||t.enumerable});return r},ge=r=>gge(cge(Mh(r!=null?nge(lge(r)):{},"default",r&&r.__esModule&&"default"in r?{get:()=>r.default,enumerable:!0}:{value:r,enumerable:!0})),r);var cM=w((i7e,oM)=>{oM.exports=aM;aM.sync=xge;var AM=require("fs");function kge(r,e){var t=e.pathExt!==void 0?e.pathExt:process.env.PATHEXT;if(!t||(t=t.split(";"),t.indexOf("")!==-1))return!0;for(var i=0;i{uM.exports=gM;gM.sync=Pge;var fM=require("fs");function gM(r,e,t){fM.stat(r,function(i,n){t(i,i?!1:hM(n,e))})}function Pge(r,e){return hM(fM.statSync(r),e)}function hM(r,e){return r.isFile()&&Dge(r,e)}function Dge(r,e){var t=r.mode,i=r.uid,n=r.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=t&c||t&l&&n===o||t&a&&i===s||t&u&&s===0;return g}});var CM=w((o7e,dM)=>{var s7e=require("fs"),zE;process.platform==="win32"||global.TESTING_WINDOWS?zE=cM():zE=pM();dM.exports=CQ;CQ.sync=Rge;function CQ(r,e,t){if(typeof e=="function"&&(t=e,e={}),!t){if(typeof Promise!="function")throw new TypeError("callback not provided");return new Promise(function(i,n){CQ(r,e||{},function(s,o){s?n(s):i(o)})})}zE(r,e||{},function(i,n){i&&(i.code==="EACCES"||e&&e.ignoreErrors)&&(i=null,n=!1),t(i,n)})}function Rge(r,e){try{return zE.sync(r,e||{})}catch(t){if(e&&e.ignoreErrors||t.code==="EACCES")return!1;throw t}}});var bM=w((a7e,mM)=>{var Xu=process.platform==="win32"||process.env.OSTYPE==="cygwin"||process.env.OSTYPE==="msys",EM=require("path"),Fge=Xu?";":":",IM=CM(),yM=r=>Object.assign(new Error(`not found: ${r}`),{code:"ENOENT"}),wM=(r,e)=>{let t=e.colon||Fge,i=r.match(/\//)||Xu&&r.match(/\\/)?[""]:[...Xu?[process.cwd()]:[],...(e.path||process.env.PATH||"").split(t)],n=Xu?e.pathExt||process.env.PATHEXT||".EXE;.CMD;.BAT;.COM":"",s=Xu?n.split(t):[""];return Xu&&r.indexOf(".")!==-1&&s[0]!==""&&s.unshift(""),{pathEnv:i,pathExt:s,pathExtExe:n}},BM=(r,e,t)=>{typeof e=="function"&&(t=e,e={}),e||(e={});let{pathEnv:i,pathExt:n,pathExtExe:s}=wM(r,e),o=[],a=c=>new Promise((u,g)=>{if(c===i.length)return e.all&&o.length?u(o):g(yM(r));let f=i[c],h=/^".*"$/.test(f)?f.slice(1,-1):f,p=EM.join(h,r),m=!h&&/^\.[\\\/]/.test(r)?r.slice(0,2)+p:p;u(l(m,c,0))}),l=(c,u,g)=>new Promise((f,h)=>{if(g===n.length)return f(a(u+1));let p=n[g];IM(c+p,{pathExt:s},(m,y)=>{if(!m&&y)if(e.all)o.push(c+p);else return f(c+p);return f(l(c,u,g+1))})});return t?a(0).then(c=>t(null,c),t):a(0)},Nge=(r,e)=>{e=e||{};let{pathEnv:t,pathExt:i,pathExtExe:n}=wM(r,e),s=[];for(let o=0;o{"use strict";var QM=(r={})=>{let e=r.env||process.env;return(r.platform||process.platform)!=="win32"?"PATH":Object.keys(e).reverse().find(i=>i.toUpperCase()==="PATH")||"Path"};mQ.exports=QM;mQ.exports.default=QM});var PM=w((l7e,vM)=>{"use strict";var xM=require("path"),Lge=bM(),Tge=SM();function kM(r,e){let t=r.options.env||process.env,i=process.cwd(),n=r.options.cwd!=null,s=n&&process.chdir!==void 0&&!process.chdir.disabled;if(s)try{process.chdir(r.options.cwd)}catch(a){}let o;try{o=Lge.sync(r.command,{path:t[Tge({env:t})],pathExt:e?xM.delimiter:void 0})}catch(a){}finally{s&&process.chdir(i)}return o&&(o=xM.resolve(n?r.options.cwd:"",o)),o}function Oge(r){return kM(r)||kM(r,!0)}vM.exports=Oge});var DM=w((c7e,EQ)=>{"use strict";var IQ=/([()\][%!^"`<>&|;, *?])/g;function Mge(r){return r=r.replace(IQ,"^$1"),r}function Kge(r,e){return r=`${r}`,r=r.replace(/(\\*)"/g,'$1$1\\"'),r=r.replace(/(\\*)$/,"$1$1"),r=`"${r}"`,r=r.replace(IQ,"^$1"),e&&(r=r.replace(IQ,"^$1")),r}EQ.exports.command=Mge;EQ.exports.argument=Kge});var FM=w((u7e,RM)=>{"use strict";RM.exports=/^#!(.*)/});var LM=w((g7e,NM)=>{"use strict";var Uge=FM();NM.exports=(r="")=>{let e=r.match(Uge);if(!e)return null;let[t,i]=e[0].replace(/#! ?/,"").split(" "),n=t.split("/").pop();return n==="env"?i:i?`${n} ${i}`:n}});var OM=w((f7e,TM)=>{"use strict";var yQ=require("fs"),Hge=LM();function jge(r){let e=150,t=Buffer.alloc(e),i;try{i=yQ.openSync(r,"r"),yQ.readSync(i,t,0,e,0),yQ.closeSync(i)}catch(n){}return Hge(t.toString())}TM.exports=jge});var HM=w((h7e,MM)=>{"use strict";var Gge=require("path"),KM=PM(),UM=DM(),Yge=OM(),qge=process.platform==="win32",Jge=/\.(?:com|exe)$/i,Wge=/node_modules[\\/].bin[\\/][^\\/]+\.cmd$/i;function zge(r){r.file=KM(r);let e=r.file&&Yge(r.file);return e?(r.args.unshift(r.file),r.command=e,KM(r)):r.file}function _ge(r){if(!qge)return r;let e=zge(r),t=!Jge.test(e);if(r.options.forceShell||t){let i=Wge.test(e);r.command=Gge.normalize(r.command),r.command=UM.command(r.command),r.args=r.args.map(s=>UM.argument(s,i));let n=[r.command].concat(r.args).join(" ");r.args=["/d","/s","/c",`"${n}"`],r.command=process.env.comspec||"cmd.exe",r.options.windowsVerbatimArguments=!0}return r}function Vge(r,e,t){e&&!Array.isArray(e)&&(t=e,e=null),e=e?e.slice(0):[],t=Object.assign({},t);let i={command:r,args:e,options:t,file:void 0,original:{command:r,args:e}};return t.shell?i:_ge(i)}MM.exports=Vge});var YM=w((p7e,jM)=>{"use strict";var wQ=process.platform==="win32";function BQ(r,e){return Object.assign(new Error(`${e} ${r.command} ENOENT`),{code:"ENOENT",errno:"ENOENT",syscall:`${e} ${r.command}`,path:r.command,spawnargs:r.args})}function Xge(r,e){if(!wQ)return;let t=r.emit;r.emit=function(i,n){if(i==="exit"){let s=GM(n,e,"spawn");if(s)return t.call(r,"error",s)}return t.apply(r,arguments)}}function GM(r,e){return wQ&&r===1&&!e.file?BQ(e.original,"spawn"):null}function Zge(r,e){return wQ&&r===1&&!e.file?BQ(e.original,"spawnSync"):null}jM.exports={hookChildProcess:Xge,verifyENOENT:GM,verifyENOENTSync:Zge,notFoundError:BQ}});var SQ=w((d7e,Zu)=>{"use strict";var qM=require("child_process"),bQ=HM(),QQ=YM();function JM(r,e,t){let i=bQ(r,e,t),n=qM.spawn(i.command,i.args,i.options);return QQ.hookChildProcess(n,i),n}function $ge(r,e,t){let i=bQ(r,e,t),n=qM.spawnSync(i.command,i.args,i.options);return n.error=n.error||QQ.verifyENOENTSync(n.status,i),n}Zu.exports=JM;Zu.exports.spawn=JM;Zu.exports.sync=$ge;Zu.exports._parse=bQ;Zu.exports._enoent=QQ});var zM=w((C7e,WM)=>{"use strict";function efe(r,e){function t(){this.constructor=r}t.prototype=e.prototype,r.prototype=new t}function cc(r,e,t,i){this.message=r,this.expected=e,this.found=t,this.location=i,this.name="SyntaxError",typeof Error.captureStackTrace=="function"&&Error.captureStackTrace(this,cc)}efe(cc,Error);cc.buildMessage=function(r,e){var t={literal:function(c){return'"'+n(c.text)+'"'},class:function(c){var u="",g;for(g=0;g0){for(g=1,f=1;g>",le=me(">>",!1),fe=">&",gt=me(">&",!1),Ht=">",Mt=me(">",!1),Ei="<<<",jt=me("<<<",!1),Qr="<&",Oi=me("<&",!1),Xs="<",Un=me("<",!1),Hn=function(C){return{type:"argument",segments:[].concat(...C)}},Sr=function(C){return C},jn="$'",fs=me("$'",!1),ba="'",DA=me("'",!1),Nu=function(C){return[{type:"text",text:C}]},hs='""',RA=me('""',!1),Qa=function(){return{type:"text",text:""}},Lu='"',FA=me('"',!1),NA=function(C){return C},vr=function(C){return{type:"arithmetic",arithmetic:C,quoted:!0}},zl=function(C){return{type:"shell",shell:C,quoted:!0}},Tu=function(C){return te(N({type:"variable"},C),{quoted:!0})},xo=function(C){return{type:"text",text:C}},Ou=function(C){return{type:"arithmetic",arithmetic:C,quoted:!1}},Sh=function(C){return{type:"shell",shell:C,quoted:!1}},vh=function(C){return te(N({type:"variable"},C),{quoted:!1})},Dr=function(C){return{type:"glob",pattern:C}},Ae=/^[^']/,ko=_e(["'"],!0,!1),Gn=function(C){return C.join("")},Mu=/^[^$"]/,St=_e(["$",'"'],!0,!1),_l=`\\ -`,Yn=me(`\\ -`,!1),ps=function(){return""},ds="\\",pt=me("\\",!1),Po=/^[\\$"`]/,lt=_e(["\\","$",'"',"`"],!1,!1),mn=function(C){return C},S="\\a",Tt=me("\\a",!1),Ku=function(){return"a"},Vl="\\b",xh=me("\\b",!1),kh=function(){return"\b"},Ph=/^[Ee]/,Dh=_e(["E","e"],!1,!1),Rh=function(){return""},j="\\f",wt=me("\\f",!1),LA=function(){return"\f"},$i="\\n",Xl=me("\\n",!1),$e=function(){return` -`},Sa="\\r",Uu=me("\\r",!1),yE=function(){return"\r"},Fh="\\t",wE=me("\\t",!1),gr=function(){return" "},qn="\\v",Zl=me("\\v",!1),Nh=function(){return"\v"},Zs=/^[\\'"?]/,va=_e(["\\","'",'"',"?"],!1,!1),En=function(C){return String.fromCharCode(parseInt(C,16))},Oe="\\x",Hu=me("\\x",!1),$l="\\u",$s=me("\\u",!1),ec="\\U",TA=me("\\U",!1),ju=function(C){return String.fromCodePoint(parseInt(C,16))},Gu=/^[0-7]/,xa=_e([["0","7"]],!1,!1),ka=/^[0-9a-fA-f]/,nt=_e([["0","9"],["a","f"],["A","f"]],!1,!1),Do=ot(),OA="-",tc=me("-",!1),eo="+",rc=me("+",!1),BE=".",Lh=me(".",!1),Yu=function(C,Q,F){return{type:"number",value:(C==="-"?-1:1)*parseFloat(Q.join("")+"."+F.join(""))}},Th=function(C,Q){return{type:"number",value:(C==="-"?-1:1)*parseInt(Q.join(""))}},bE=function(C){return N({type:"variable"},C)},ic=function(C){return{type:"variable",name:C}},QE=function(C){return C},qu="*",MA=me("*",!1),Tr="/",SE=me("/",!1),to=function(C,Q,F){return{type:Q==="*"?"multiplication":"division",right:F}},ro=function(C,Q){return Q.reduce((F,U)=>N({left:F},U),C)},Ju=function(C,Q,F){return{type:Q==="+"?"addition":"subtraction",right:F}},KA="$((",R=me("$((",!1),G="))",Ce=me("))",!1),He=function(C){return C},Te="$(",Xe=me("$(",!1),Et=function(C){return C},Rt="${",Jn=me("${",!1),Ob=":-",lO=me(":-",!1),cO=function(C,Q){return{name:C,defaultValue:Q}},Mb=":-}",uO=me(":-}",!1),gO=function(C){return{name:C,defaultValue:[]}},Kb=":+",fO=me(":+",!1),hO=function(C,Q){return{name:C,alternativeValue:Q}},Ub=":+}",pO=me(":+}",!1),dO=function(C){return{name:C,alternativeValue:[]}},Hb=function(C){return{name:C}},CO="$",mO=me("$",!1),EO=function(C){return e.isGlobPattern(C)},IO=function(C){return C},jb=/^[a-zA-Z0-9_]/,Gb=_e([["a","z"],["A","Z"],["0","9"],"_"],!1,!1),Yb=function(){return M()},qb=/^[$@*?#a-zA-Z0-9_\-]/,Jb=_e(["$","@","*","?","#",["a","z"],["A","Z"],["0","9"],"_","-"],!1,!1),yO=/^[(){}<>$|&; \t"']/,Wu=_e(["(",")","{","}","<",">","$","|","&",";"," "," ",'"',"'"],!1,!1),Wb=/^[<>&; \t"']/,zb=_e(["<",">","&",";"," "," ",'"',"'"],!1,!1),vE=/^[ \t]/,xE=_e([" "," "],!1,!1),B=0,Ue=0,UA=[{line:1,column:1}],d=0,E=[],I=0,D;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 M(){return r.substring(Ue,B)}function z(){return yt(Ue,B)}function ie(C,Q){throw Q=Q!==void 0?Q:yt(Ue,B),Mi([ut(C)],r.substring(Ue,B),Q)}function we(C,Q){throw Q=Q!==void 0?Q:yt(Ue,B),Wn(C,Q)}function me(C,Q){return{type:"literal",text:C,ignoreCase:Q}}function _e(C,Q,F){return{type:"class",parts:C,inverted:Q,ignoreCase:F}}function ot(){return{type:"any"}}function Bt(){return{type:"end"}}function ut(C){return{type:"other",description:C}}function st(C){var Q=UA[C],F;if(Q)return Q;for(F=C-1;!UA[F];)F--;for(Q=UA[F],Q={line:Q.line,column:Q.column};Fd&&(d=B,E=[]),E.push(C))}function Wn(C,Q){return new cc(C,null,null,Q)}function Mi(C,Q,F){return new cc(cc.buildMessage(C,Q),C,Q,F)}function HA(){var C,Q;return C=B,Q=Yr(),Q===t&&(Q=null),Q!==t&&(Ue=C,Q=s(Q)),C=Q,C}function Yr(){var C,Q,F,U,ue;if(C=B,Q=qr(),Q!==t){for(F=[],U=Ye();U!==t;)F.push(U),U=Ye();F!==t?(U=Pa(),U!==t?(ue=Cs(),ue===t&&(ue=null),ue!==t?(Ue=C,Q=o(Q,U,ue),C=Q):(B=C,C=t)):(B=C,C=t)):(B=C,C=t)}else B=C,C=t;if(C===t)if(C=B,Q=qr(),Q!==t){for(F=[],U=Ye();U!==t;)F.push(U),U=Ye();F!==t?(U=Pa(),U===t&&(U=null),U!==t?(Ue=C,Q=a(Q,U),C=Q):(B=C,C=t)):(B=C,C=t)}else B=C,C=t;return C}function Cs(){var C,Q,F,U,ue;for(C=B,Q=[],F=Ye();F!==t;)Q.push(F),F=Ye();if(Q!==t)if(F=Yr(),F!==t){for(U=[],ue=Ye();ue!==t;)U.push(ue),ue=Ye();U!==t?(Ue=C,Q=l(F),C=Q):(B=C,C=t)}else B=C,C=t;else B=C,C=t;return C}function Pa(){var C;return r.charCodeAt(B)===59?(C=c,B++):(C=t,I===0&&xe(u)),C===t&&(r.charCodeAt(B)===38?(C=g,B++):(C=t,I===0&&xe(f))),C}function qr(){var C,Q,F;return C=B,Q=wO(),Q!==t?(F=Hue(),F===t&&(F=null),F!==t?(Ue=C,Q=h(Q,F),C=Q):(B=C,C=t)):(B=C,C=t),C}function Hue(){var C,Q,F,U,ue,De,Ct;for(C=B,Q=[],F=Ye();F!==t;)Q.push(F),F=Ye();if(Q!==t)if(F=jue(),F!==t){for(U=[],ue=Ye();ue!==t;)U.push(ue),ue=Ye();if(U!==t)if(ue=qr(),ue!==t){for(De=[],Ct=Ye();Ct!==t;)De.push(Ct),Ct=Ye();De!==t?(Ue=C,Q=p(F,ue),C=Q):(B=C,C=t)}else B=C,C=t;else B=C,C=t}else B=C,C=t;else B=C,C=t;return C}function jue(){var C;return r.substr(B,2)===m?(C=m,B+=2):(C=t,I===0&&xe(y)),C===t&&(r.substr(B,2)===b?(C=b,B+=2):(C=t,I===0&&xe(v))),C}function wO(){var C,Q,F;return C=B,Q=que(),Q!==t?(F=Gue(),F===t&&(F=null),F!==t?(Ue=C,Q=x(Q,F),C=Q):(B=C,C=t)):(B=C,C=t),C}function Gue(){var C,Q,F,U,ue,De,Ct;for(C=B,Q=[],F=Ye();F!==t;)Q.push(F),F=Ye();if(Q!==t)if(F=Yue(),F!==t){for(U=[],ue=Ye();ue!==t;)U.push(ue),ue=Ye();if(U!==t)if(ue=wO(),ue!==t){for(De=[],Ct=Ye();Ct!==t;)De.push(Ct),Ct=Ye();De!==t?(Ue=C,Q=T(F,ue),C=Q):(B=C,C=t)}else B=C,C=t;else B=C,C=t}else B=C,C=t;else B=C,C=t;return C}function Yue(){var C;return r.substr(B,2)===q?(C=q,B+=2):(C=t,I===0&&xe(Y)),C===t&&(r.charCodeAt(B)===124?(C=$,B++):(C=t,I===0&&xe(_))),C}function kE(){var C,Q,F,U,ue,De;if(C=B,Q=NO(),Q!==t)if(r.charCodeAt(B)===61?(F=ne,B++):(F=t,I===0&&xe(ee)),F!==t)if(U=QO(),U!==t){for(ue=[],De=Ye();De!==t;)ue.push(De),De=Ye();ue!==t?(Ue=C,Q=A(Q,U),C=Q):(B=C,C=t)}else B=C,C=t;else B=C,C=t;else B=C,C=t;if(C===t)if(C=B,Q=NO(),Q!==t)if(r.charCodeAt(B)===61?(F=ne,B++):(F=t,I===0&&xe(ee)),F!==t){for(U=[],ue=Ye();ue!==t;)U.push(ue),ue=Ye();U!==t?(Ue=C,Q=oe(Q),C=Q):(B=C,C=t)}else B=C,C=t;else B=C,C=t;return C}function que(){var C,Q,F,U,ue,De,Ct,bt,$r,Ii,ms;for(C=B,Q=[],F=Ye();F!==t;)Q.push(F),F=Ye();if(Q!==t)if(r.charCodeAt(B)===40?(F=ce,B++):(F=t,I===0&&xe(Z)),F!==t){for(U=[],ue=Ye();ue!==t;)U.push(ue),ue=Ye();if(U!==t)if(ue=Yr(),ue!==t){for(De=[],Ct=Ye();Ct!==t;)De.push(Ct),Ct=Ye();if(De!==t)if(r.charCodeAt(B)===41?(Ct=O,B++):(Ct=t,I===0&&xe(L)),Ct!==t){for(bt=[],$r=Ye();$r!==t;)bt.push($r),$r=Ye();if(bt!==t){for($r=[],Ii=Oh();Ii!==t;)$r.push(Ii),Ii=Oh();if($r!==t){for(Ii=[],ms=Ye();ms!==t;)Ii.push(ms),ms=Ye();Ii!==t?(Ue=C,Q=de(ue,$r),C=Q):(B=C,C=t)}else B=C,C=t}else B=C,C=t}else B=C,C=t;else B=C,C=t}else B=C,C=t;else B=C,C=t}else B=C,C=t;else B=C,C=t;if(C===t){for(C=B,Q=[],F=Ye();F!==t;)Q.push(F),F=Ye();if(Q!==t)if(r.charCodeAt(B)===123?(F=Be,B++):(F=t,I===0&&xe(je)),F!==t){for(U=[],ue=Ye();ue!==t;)U.push(ue),ue=Ye();if(U!==t)if(ue=Yr(),ue!==t){for(De=[],Ct=Ye();Ct!==t;)De.push(Ct),Ct=Ye();if(De!==t)if(r.charCodeAt(B)===125?(Ct=re,B++):(Ct=t,I===0&&xe(se)),Ct!==t){for(bt=[],$r=Ye();$r!==t;)bt.push($r),$r=Ye();if(bt!==t){for($r=[],Ii=Oh();Ii!==t;)$r.push(Ii),Ii=Oh();if($r!==t){for(Ii=[],ms=Ye();ms!==t;)Ii.push(ms),ms=Ye();Ii!==t?(Ue=C,Q=be(ue,$r),C=Q):(B=C,C=t)}else B=C,C=t}else B=C,C=t}else B=C,C=t;else B=C,C=t}else B=C,C=t;else B=C,C=t}else B=C,C=t;else B=C,C=t;if(C===t){for(C=B,Q=[],F=Ye();F!==t;)Q.push(F),F=Ye();if(Q!==t){for(F=[],U=kE();U!==t;)F.push(U),U=kE();if(F!==t){for(U=[],ue=Ye();ue!==t;)U.push(ue),ue=Ye();if(U!==t){if(ue=[],De=bO(),De!==t)for(;De!==t;)ue.push(De),De=bO();else ue=t;if(ue!==t){for(De=[],Ct=Ye();Ct!==t;)De.push(Ct),Ct=Ye();De!==t?(Ue=C,Q=he(F,ue),C=Q):(B=C,C=t)}else B=C,C=t}else B=C,C=t}else B=C,C=t}else B=C,C=t;if(C===t){for(C=B,Q=[],F=Ye();F!==t;)Q.push(F),F=Ye();if(Q!==t){if(F=[],U=kE(),U!==t)for(;U!==t;)F.push(U),U=kE();else F=t;if(F!==t){for(U=[],ue=Ye();ue!==t;)U.push(ue),ue=Ye();U!==t?(Ue=C,Q=Fe(F),C=Q):(B=C,C=t)}else B=C,C=t}else B=C,C=t}}}return C}function BO(){var C,Q,F,U,ue;for(C=B,Q=[],F=Ye();F!==t;)Q.push(F),F=Ye();if(Q!==t){if(F=[],U=PE(),U!==t)for(;U!==t;)F.push(U),U=PE();else F=t;if(F!==t){for(U=[],ue=Ye();ue!==t;)U.push(ue),ue=Ye();U!==t?(Ue=C,Q=Ke(F),C=Q):(B=C,C=t)}else B=C,C=t}else B=C,C=t;return C}function bO(){var C,Q,F;for(C=B,Q=[],F=Ye();F!==t;)Q.push(F),F=Ye();if(Q!==t?(F=Oh(),F!==t?(Ue=C,Q=ke(F),C=Q):(B=C,C=t)):(B=C,C=t),C===t){for(C=B,Q=[],F=Ye();F!==t;)Q.push(F),F=Ye();Q!==t?(F=PE(),F!==t?(Ue=C,Q=ke(F),C=Q):(B=C,C=t)):(B=C,C=t)}return C}function Oh(){var C,Q,F,U,ue;for(C=B,Q=[],F=Ye();F!==t;)Q.push(F),F=Ye();return Q!==t?(ve.test(r.charAt(B))?(F=r.charAt(B),B++):(F=t,I===0&&xe(pe)),F===t&&(F=null),F!==t?(U=Jue(),U!==t?(ue=PE(),ue!==t?(Ue=C,Q=V(F,U,ue),C=Q):(B=C,C=t)):(B=C,C=t)):(B=C,C=t)):(B=C,C=t),C}function Jue(){var C;return r.substr(B,2)===Qe?(C=Qe,B+=2):(C=t,I===0&&xe(le)),C===t&&(r.substr(B,2)===fe?(C=fe,B+=2):(C=t,I===0&&xe(gt)),C===t&&(r.charCodeAt(B)===62?(C=Ht,B++):(C=t,I===0&&xe(Mt)),C===t&&(r.substr(B,3)===Ei?(C=Ei,B+=3):(C=t,I===0&&xe(jt)),C===t&&(r.substr(B,2)===Qr?(C=Qr,B+=2):(C=t,I===0&&xe(Oi)),C===t&&(r.charCodeAt(B)===60?(C=Xs,B++):(C=t,I===0&&xe(Un))))))),C}function PE(){var C,Q,F;for(C=B,Q=[],F=Ye();F!==t;)Q.push(F),F=Ye();return Q!==t?(F=QO(),F!==t?(Ue=C,Q=ke(F),C=Q):(B=C,C=t)):(B=C,C=t),C}function QO(){var C,Q,F;if(C=B,Q=[],F=SO(),F!==t)for(;F!==t;)Q.push(F),F=SO();else Q=t;return Q!==t&&(Ue=C,Q=Hn(Q)),C=Q,C}function SO(){var C,Q;return C=B,Q=Wue(),Q!==t&&(Ue=C,Q=Sr(Q)),C=Q,C===t&&(C=B,Q=zue(),Q!==t&&(Ue=C,Q=Sr(Q)),C=Q,C===t&&(C=B,Q=_ue(),Q!==t&&(Ue=C,Q=Sr(Q)),C=Q,C===t&&(C=B,Q=Vue(),Q!==t&&(Ue=C,Q=Sr(Q)),C=Q))),C}function Wue(){var C,Q,F,U;return C=B,r.substr(B,2)===jn?(Q=jn,B+=2):(Q=t,I===0&&xe(fs)),Q!==t?(F=$ue(),F!==t?(r.charCodeAt(B)===39?(U=ba,B++):(U=t,I===0&&xe(DA)),U!==t?(Ue=C,Q=Nu(F),C=Q):(B=C,C=t)):(B=C,C=t)):(B=C,C=t),C}function zue(){var C,Q,F,U;return C=B,r.charCodeAt(B)===39?(Q=ba,B++):(Q=t,I===0&&xe(DA)),Q!==t?(F=Xue(),F!==t?(r.charCodeAt(B)===39?(U=ba,B++):(U=t,I===0&&xe(DA)),U!==t?(Ue=C,Q=Nu(F),C=Q):(B=C,C=t)):(B=C,C=t)):(B=C,C=t),C}function _ue(){var C,Q,F,U;if(C=B,r.substr(B,2)===hs?(Q=hs,B+=2):(Q=t,I===0&&xe(RA)),Q!==t&&(Ue=C,Q=Qa()),C=Q,C===t)if(C=B,r.charCodeAt(B)===34?(Q=Lu,B++):(Q=t,I===0&&xe(FA)),Q!==t){for(F=[],U=vO();U!==t;)F.push(U),U=vO();F!==t?(r.charCodeAt(B)===34?(U=Lu,B++):(U=t,I===0&&xe(FA)),U!==t?(Ue=C,Q=NA(F),C=Q):(B=C,C=t)):(B=C,C=t)}else B=C,C=t;return C}function Vue(){var C,Q,F;if(C=B,Q=[],F=xO(),F!==t)for(;F!==t;)Q.push(F),F=xO();else Q=t;return Q!==t&&(Ue=C,Q=NA(Q)),C=Q,C}function vO(){var C,Q;return C=B,Q=RO(),Q!==t&&(Ue=C,Q=vr(Q)),C=Q,C===t&&(C=B,Q=FO(),Q!==t&&(Ue=C,Q=zl(Q)),C=Q,C===t&&(C=B,Q=Zb(),Q!==t&&(Ue=C,Q=Tu(Q)),C=Q,C===t&&(C=B,Q=Zue(),Q!==t&&(Ue=C,Q=xo(Q)),C=Q))),C}function xO(){var C,Q;return C=B,Q=RO(),Q!==t&&(Ue=C,Q=Ou(Q)),C=Q,C===t&&(C=B,Q=FO(),Q!==t&&(Ue=C,Q=Sh(Q)),C=Q,C===t&&(C=B,Q=Zb(),Q!==t&&(Ue=C,Q=vh(Q)),C=Q,C===t&&(C=B,Q=rge(),Q!==t&&(Ue=C,Q=Dr(Q)),C=Q,C===t&&(C=B,Q=tge(),Q!==t&&(Ue=C,Q=xo(Q)),C=Q)))),C}function Xue(){var C,Q,F;for(C=B,Q=[],Ae.test(r.charAt(B))?(F=r.charAt(B),B++):(F=t,I===0&&xe(ko));F!==t;)Q.push(F),Ae.test(r.charAt(B))?(F=r.charAt(B),B++):(F=t,I===0&&xe(ko));return Q!==t&&(Ue=C,Q=Gn(Q)),C=Q,C}function Zue(){var C,Q,F;if(C=B,Q=[],F=kO(),F===t&&(Mu.test(r.charAt(B))?(F=r.charAt(B),B++):(F=t,I===0&&xe(St))),F!==t)for(;F!==t;)Q.push(F),F=kO(),F===t&&(Mu.test(r.charAt(B))?(F=r.charAt(B),B++):(F=t,I===0&&xe(St)));else Q=t;return Q!==t&&(Ue=C,Q=Gn(Q)),C=Q,C}function kO(){var C,Q,F;return C=B,r.substr(B,2)===_l?(Q=_l,B+=2):(Q=t,I===0&&xe(Yn)),Q!==t&&(Ue=C,Q=ps()),C=Q,C===t&&(C=B,r.charCodeAt(B)===92?(Q=ds,B++):(Q=t,I===0&&xe(pt)),Q!==t?(Po.test(r.charAt(B))?(F=r.charAt(B),B++):(F=t,I===0&&xe(lt)),F!==t?(Ue=C,Q=mn(F),C=Q):(B=C,C=t)):(B=C,C=t)),C}function $ue(){var C,Q,F;for(C=B,Q=[],F=PO(),F===t&&(Ae.test(r.charAt(B))?(F=r.charAt(B),B++):(F=t,I===0&&xe(ko)));F!==t;)Q.push(F),F=PO(),F===t&&(Ae.test(r.charAt(B))?(F=r.charAt(B),B++):(F=t,I===0&&xe(ko)));return Q!==t&&(Ue=C,Q=Gn(Q)),C=Q,C}function PO(){var C,Q,F;return C=B,r.substr(B,2)===S?(Q=S,B+=2):(Q=t,I===0&&xe(Tt)),Q!==t&&(Ue=C,Q=Ku()),C=Q,C===t&&(C=B,r.substr(B,2)===Vl?(Q=Vl,B+=2):(Q=t,I===0&&xe(xh)),Q!==t&&(Ue=C,Q=kh()),C=Q,C===t&&(C=B,r.charCodeAt(B)===92?(Q=ds,B++):(Q=t,I===0&&xe(pt)),Q!==t?(Ph.test(r.charAt(B))?(F=r.charAt(B),B++):(F=t,I===0&&xe(Dh)),F!==t?(Ue=C,Q=Rh(),C=Q):(B=C,C=t)):(B=C,C=t),C===t&&(C=B,r.substr(B,2)===j?(Q=j,B+=2):(Q=t,I===0&&xe(wt)),Q!==t&&(Ue=C,Q=LA()),C=Q,C===t&&(C=B,r.substr(B,2)===$i?(Q=$i,B+=2):(Q=t,I===0&&xe(Xl)),Q!==t&&(Ue=C,Q=$e()),C=Q,C===t&&(C=B,r.substr(B,2)===Sa?(Q=Sa,B+=2):(Q=t,I===0&&xe(Uu)),Q!==t&&(Ue=C,Q=yE()),C=Q,C===t&&(C=B,r.substr(B,2)===Fh?(Q=Fh,B+=2):(Q=t,I===0&&xe(wE)),Q!==t&&(Ue=C,Q=gr()),C=Q,C===t&&(C=B,r.substr(B,2)===qn?(Q=qn,B+=2):(Q=t,I===0&&xe(Zl)),Q!==t&&(Ue=C,Q=Nh()),C=Q,C===t&&(C=B,r.charCodeAt(B)===92?(Q=ds,B++):(Q=t,I===0&&xe(pt)),Q!==t?(Zs.test(r.charAt(B))?(F=r.charAt(B),B++):(F=t,I===0&&xe(va)),F!==t?(Ue=C,Q=mn(F),C=Q):(B=C,C=t)):(B=C,C=t),C===t&&(C=ege()))))))))),C}function ege(){var C,Q,F,U,ue,De,Ct,bt,$r,Ii,ms,$b;return C=B,r.charCodeAt(B)===92?(Q=ds,B++):(Q=t,I===0&&xe(pt)),Q!==t?(F=_b(),F!==t?(Ue=C,Q=En(F),C=Q):(B=C,C=t)):(B=C,C=t),C===t&&(C=B,r.substr(B,2)===Oe?(Q=Oe,B+=2):(Q=t,I===0&&xe(Hu)),Q!==t?(F=B,U=B,ue=_b(),ue!==t?(De=zn(),De!==t?(ue=[ue,De],U=ue):(B=U,U=t)):(B=U,U=t),U===t&&(U=_b()),U!==t?F=r.substring(F,B):F=U,F!==t?(Ue=C,Q=En(F),C=Q):(B=C,C=t)):(B=C,C=t),C===t&&(C=B,r.substr(B,2)===$l?(Q=$l,B+=2):(Q=t,I===0&&xe($s)),Q!==t?(F=B,U=B,ue=zn(),ue!==t?(De=zn(),De!==t?(Ct=zn(),Ct!==t?(bt=zn(),bt!==t?(ue=[ue,De,Ct,bt],U=ue):(B=U,U=t)):(B=U,U=t)):(B=U,U=t)):(B=U,U=t),U!==t?F=r.substring(F,B):F=U,F!==t?(Ue=C,Q=En(F),C=Q):(B=C,C=t)):(B=C,C=t),C===t&&(C=B,r.substr(B,2)===ec?(Q=ec,B+=2):(Q=t,I===0&&xe(TA)),Q!==t?(F=B,U=B,ue=zn(),ue!==t?(De=zn(),De!==t?(Ct=zn(),Ct!==t?(bt=zn(),bt!==t?($r=zn(),$r!==t?(Ii=zn(),Ii!==t?(ms=zn(),ms!==t?($b=zn(),$b!==t?(ue=[ue,De,Ct,bt,$r,Ii,ms,$b],U=ue):(B=U,U=t)):(B=U,U=t)):(B=U,U=t)):(B=U,U=t)):(B=U,U=t)):(B=U,U=t)):(B=U,U=t)):(B=U,U=t),U!==t?F=r.substring(F,B):F=U,F!==t?(Ue=C,Q=ju(F),C=Q):(B=C,C=t)):(B=C,C=t)))),C}function _b(){var C;return Gu.test(r.charAt(B))?(C=r.charAt(B),B++):(C=t,I===0&&xe(xa)),C}function zn(){var C;return ka.test(r.charAt(B))?(C=r.charAt(B),B++):(C=t,I===0&&xe(nt)),C}function tge(){var C,Q,F,U,ue;if(C=B,Q=[],F=B,r.charCodeAt(B)===92?(U=ds,B++):(U=t,I===0&&xe(pt)),U!==t?(r.length>B?(ue=r.charAt(B),B++):(ue=t,I===0&&xe(Do)),ue!==t?(Ue=F,U=mn(ue),F=U):(B=F,F=t)):(B=F,F=t),F===t&&(F=B,U=B,I++,ue=LO(),I--,ue===t?U=void 0:(B=U,U=t),U!==t?(r.length>B?(ue=r.charAt(B),B++):(ue=t,I===0&&xe(Do)),ue!==t?(Ue=F,U=mn(ue),F=U):(B=F,F=t)):(B=F,F=t)),F!==t)for(;F!==t;)Q.push(F),F=B,r.charCodeAt(B)===92?(U=ds,B++):(U=t,I===0&&xe(pt)),U!==t?(r.length>B?(ue=r.charAt(B),B++):(ue=t,I===0&&xe(Do)),ue!==t?(Ue=F,U=mn(ue),F=U):(B=F,F=t)):(B=F,F=t),F===t&&(F=B,U=B,I++,ue=LO(),I--,ue===t?U=void 0:(B=U,U=t),U!==t?(r.length>B?(ue=r.charAt(B),B++):(ue=t,I===0&&xe(Do)),ue!==t?(Ue=F,U=mn(ue),F=U):(B=F,F=t)):(B=F,F=t));else Q=t;return Q!==t&&(Ue=C,Q=Gn(Q)),C=Q,C}function Vb(){var C,Q,F,U,ue,De;if(C=B,r.charCodeAt(B)===45?(Q=OA,B++):(Q=t,I===0&&xe(tc)),Q===t&&(r.charCodeAt(B)===43?(Q=eo,B++):(Q=t,I===0&&xe(rc))),Q===t&&(Q=null),Q!==t){if(F=[],ve.test(r.charAt(B))?(U=r.charAt(B),B++):(U=t,I===0&&xe(pe)),U!==t)for(;U!==t;)F.push(U),ve.test(r.charAt(B))?(U=r.charAt(B),B++):(U=t,I===0&&xe(pe));else F=t;if(F!==t)if(r.charCodeAt(B)===46?(U=BE,B++):(U=t,I===0&&xe(Lh)),U!==t){if(ue=[],ve.test(r.charAt(B))?(De=r.charAt(B),B++):(De=t,I===0&&xe(pe)),De!==t)for(;De!==t;)ue.push(De),ve.test(r.charAt(B))?(De=r.charAt(B),B++):(De=t,I===0&&xe(pe));else ue=t;ue!==t?(Ue=C,Q=Yu(Q,F,ue),C=Q):(B=C,C=t)}else B=C,C=t;else B=C,C=t}else B=C,C=t;if(C===t){if(C=B,r.charCodeAt(B)===45?(Q=OA,B++):(Q=t,I===0&&xe(tc)),Q===t&&(r.charCodeAt(B)===43?(Q=eo,B++):(Q=t,I===0&&xe(rc))),Q===t&&(Q=null),Q!==t){if(F=[],ve.test(r.charAt(B))?(U=r.charAt(B),B++):(U=t,I===0&&xe(pe)),U!==t)for(;U!==t;)F.push(U),ve.test(r.charAt(B))?(U=r.charAt(B),B++):(U=t,I===0&&xe(pe));else F=t;F!==t?(Ue=C,Q=Th(Q,F),C=Q):(B=C,C=t)}else B=C,C=t;if(C===t&&(C=B,Q=Zb(),Q!==t&&(Ue=C,Q=bE(Q)),C=Q,C===t&&(C=B,Q=nc(),Q!==t&&(Ue=C,Q=ic(Q)),C=Q,C===t)))if(C=B,r.charCodeAt(B)===40?(Q=ce,B++):(Q=t,I===0&&xe(Z)),Q!==t){for(F=[],U=Ye();U!==t;)F.push(U),U=Ye();if(F!==t)if(U=DO(),U!==t){for(ue=[],De=Ye();De!==t;)ue.push(De),De=Ye();ue!==t?(r.charCodeAt(B)===41?(De=O,B++):(De=t,I===0&&xe(L)),De!==t?(Ue=C,Q=QE(U),C=Q):(B=C,C=t)):(B=C,C=t)}else B=C,C=t;else B=C,C=t}else B=C,C=t}return C}function Xb(){var C,Q,F,U,ue,De,Ct,bt;if(C=B,Q=Vb(),Q!==t){for(F=[],U=B,ue=[],De=Ye();De!==t;)ue.push(De),De=Ye();if(ue!==t)if(r.charCodeAt(B)===42?(De=qu,B++):(De=t,I===0&&xe(MA)),De===t&&(r.charCodeAt(B)===47?(De=Tr,B++):(De=t,I===0&&xe(SE))),De!==t){for(Ct=[],bt=Ye();bt!==t;)Ct.push(bt),bt=Ye();Ct!==t?(bt=Vb(),bt!==t?(Ue=U,ue=to(Q,De,bt),U=ue):(B=U,U=t)):(B=U,U=t)}else B=U,U=t;else B=U,U=t;for(;U!==t;){for(F.push(U),U=B,ue=[],De=Ye();De!==t;)ue.push(De),De=Ye();if(ue!==t)if(r.charCodeAt(B)===42?(De=qu,B++):(De=t,I===0&&xe(MA)),De===t&&(r.charCodeAt(B)===47?(De=Tr,B++):(De=t,I===0&&xe(SE))),De!==t){for(Ct=[],bt=Ye();bt!==t;)Ct.push(bt),bt=Ye();Ct!==t?(bt=Vb(),bt!==t?(Ue=U,ue=to(Q,De,bt),U=ue):(B=U,U=t)):(B=U,U=t)}else B=U,U=t;else B=U,U=t}F!==t?(Ue=C,Q=ro(Q,F),C=Q):(B=C,C=t)}else B=C,C=t;return C}function DO(){var C,Q,F,U,ue,De,Ct,bt;if(C=B,Q=Xb(),Q!==t){for(F=[],U=B,ue=[],De=Ye();De!==t;)ue.push(De),De=Ye();if(ue!==t)if(r.charCodeAt(B)===43?(De=eo,B++):(De=t,I===0&&xe(rc)),De===t&&(r.charCodeAt(B)===45?(De=OA,B++):(De=t,I===0&&xe(tc))),De!==t){for(Ct=[],bt=Ye();bt!==t;)Ct.push(bt),bt=Ye();Ct!==t?(bt=Xb(),bt!==t?(Ue=U,ue=Ju(Q,De,bt),U=ue):(B=U,U=t)):(B=U,U=t)}else B=U,U=t;else B=U,U=t;for(;U!==t;){for(F.push(U),U=B,ue=[],De=Ye();De!==t;)ue.push(De),De=Ye();if(ue!==t)if(r.charCodeAt(B)===43?(De=eo,B++):(De=t,I===0&&xe(rc)),De===t&&(r.charCodeAt(B)===45?(De=OA,B++):(De=t,I===0&&xe(tc))),De!==t){for(Ct=[],bt=Ye();bt!==t;)Ct.push(bt),bt=Ye();Ct!==t?(bt=Xb(),bt!==t?(Ue=U,ue=Ju(Q,De,bt),U=ue):(B=U,U=t)):(B=U,U=t)}else B=U,U=t;else B=U,U=t}F!==t?(Ue=C,Q=ro(Q,F),C=Q):(B=C,C=t)}else B=C,C=t;return C}function RO(){var C,Q,F,U,ue,De;if(C=B,r.substr(B,3)===KA?(Q=KA,B+=3):(Q=t,I===0&&xe(R)),Q!==t){for(F=[],U=Ye();U!==t;)F.push(U),U=Ye();if(F!==t)if(U=DO(),U!==t){for(ue=[],De=Ye();De!==t;)ue.push(De),De=Ye();ue!==t?(r.substr(B,2)===G?(De=G,B+=2):(De=t,I===0&&xe(Ce)),De!==t?(Ue=C,Q=He(U),C=Q):(B=C,C=t)):(B=C,C=t)}else B=C,C=t;else B=C,C=t}else B=C,C=t;return C}function FO(){var C,Q,F,U;return C=B,r.substr(B,2)===Te?(Q=Te,B+=2):(Q=t,I===0&&xe(Xe)),Q!==t?(F=Yr(),F!==t?(r.charCodeAt(B)===41?(U=O,B++):(U=t,I===0&&xe(L)),U!==t?(Ue=C,Q=Et(F),C=Q):(B=C,C=t)):(B=C,C=t)):(B=C,C=t),C}function Zb(){var C,Q,F,U,ue,De;return C=B,r.substr(B,2)===Rt?(Q=Rt,B+=2):(Q=t,I===0&&xe(Jn)),Q!==t?(F=nc(),F!==t?(r.substr(B,2)===Ob?(U=Ob,B+=2):(U=t,I===0&&xe(lO)),U!==t?(ue=BO(),ue!==t?(r.charCodeAt(B)===125?(De=re,B++):(De=t,I===0&&xe(se)),De!==t?(Ue=C,Q=cO(F,ue),C=Q):(B=C,C=t)):(B=C,C=t)):(B=C,C=t)):(B=C,C=t)):(B=C,C=t),C===t&&(C=B,r.substr(B,2)===Rt?(Q=Rt,B+=2):(Q=t,I===0&&xe(Jn)),Q!==t?(F=nc(),F!==t?(r.substr(B,3)===Mb?(U=Mb,B+=3):(U=t,I===0&&xe(uO)),U!==t?(Ue=C,Q=gO(F),C=Q):(B=C,C=t)):(B=C,C=t)):(B=C,C=t),C===t&&(C=B,r.substr(B,2)===Rt?(Q=Rt,B+=2):(Q=t,I===0&&xe(Jn)),Q!==t?(F=nc(),F!==t?(r.substr(B,2)===Kb?(U=Kb,B+=2):(U=t,I===0&&xe(fO)),U!==t?(ue=BO(),ue!==t?(r.charCodeAt(B)===125?(De=re,B++):(De=t,I===0&&xe(se)),De!==t?(Ue=C,Q=hO(F,ue),C=Q):(B=C,C=t)):(B=C,C=t)):(B=C,C=t)):(B=C,C=t)):(B=C,C=t),C===t&&(C=B,r.substr(B,2)===Rt?(Q=Rt,B+=2):(Q=t,I===0&&xe(Jn)),Q!==t?(F=nc(),F!==t?(r.substr(B,3)===Ub?(U=Ub,B+=3):(U=t,I===0&&xe(pO)),U!==t?(Ue=C,Q=dO(F),C=Q):(B=C,C=t)):(B=C,C=t)):(B=C,C=t),C===t&&(C=B,r.substr(B,2)===Rt?(Q=Rt,B+=2):(Q=t,I===0&&xe(Jn)),Q!==t?(F=nc(),F!==t?(r.charCodeAt(B)===125?(U=re,B++):(U=t,I===0&&xe(se)),U!==t?(Ue=C,Q=Hb(F),C=Q):(B=C,C=t)):(B=C,C=t)):(B=C,C=t),C===t&&(C=B,r.charCodeAt(B)===36?(Q=CO,B++):(Q=t,I===0&&xe(mO)),Q!==t?(F=nc(),F!==t?(Ue=C,Q=Hb(F),C=Q):(B=C,C=t)):(B=C,C=t)))))),C}function rge(){var C,Q,F;return C=B,Q=ige(),Q!==t?(Ue=B,F=EO(Q),F?F=void 0:F=t,F!==t?(Ue=C,Q=IO(Q),C=Q):(B=C,C=t)):(B=C,C=t),C}function ige(){var C,Q,F,U,ue;if(C=B,Q=[],F=B,U=B,I++,ue=TO(),I--,ue===t?U=void 0:(B=U,U=t),U!==t?(r.length>B?(ue=r.charAt(B),B++):(ue=t,I===0&&xe(Do)),ue!==t?(Ue=F,U=mn(ue),F=U):(B=F,F=t)):(B=F,F=t),F!==t)for(;F!==t;)Q.push(F),F=B,U=B,I++,ue=TO(),I--,ue===t?U=void 0:(B=U,U=t),U!==t?(r.length>B?(ue=r.charAt(B),B++):(ue=t,I===0&&xe(Do)),ue!==t?(Ue=F,U=mn(ue),F=U):(B=F,F=t)):(B=F,F=t);else Q=t;return Q!==t&&(Ue=C,Q=Gn(Q)),C=Q,C}function NO(){var C,Q,F;if(C=B,Q=[],jb.test(r.charAt(B))?(F=r.charAt(B),B++):(F=t,I===0&&xe(Gb)),F!==t)for(;F!==t;)Q.push(F),jb.test(r.charAt(B))?(F=r.charAt(B),B++):(F=t,I===0&&xe(Gb));else Q=t;return Q!==t&&(Ue=C,Q=Yb()),C=Q,C}function nc(){var C,Q,F;if(C=B,Q=[],qb.test(r.charAt(B))?(F=r.charAt(B),B++):(F=t,I===0&&xe(Jb)),F!==t)for(;F!==t;)Q.push(F),qb.test(r.charAt(B))?(F=r.charAt(B),B++):(F=t,I===0&&xe(Jb));else Q=t;return Q!==t&&(Ue=C,Q=Yb()),C=Q,C}function LO(){var C;return yO.test(r.charAt(B))?(C=r.charAt(B),B++):(C=t,I===0&&xe(Wu)),C}function TO(){var C;return Wb.test(r.charAt(B))?(C=r.charAt(B),B++):(C=t,I===0&&xe(zb)),C}function Ye(){var C,Q;if(C=[],vE.test(r.charAt(B))?(Q=r.charAt(B),B++):(Q=t,I===0&&xe(xE)),Q!==t)for(;Q!==t;)C.push(Q),vE.test(r.charAt(B))?(Q=r.charAt(B),B++):(Q=t,I===0&&xe(xE));else C=t;return C}if(D=n(),D!==t&&B===r.length)return D;throw D!==t&&B{"use strict";function rfe(r,e){function t(){this.constructor=r}t.prototype=e.prototype,r.prototype=new t}function gc(r,e,t,i){this.message=r,this.expected=e,this.found=t,this.location=i,this.name="SyntaxError",typeof Error.captureStackTrace=="function"&&Error.captureStackTrace(this,gc)}rfe(gc,Error);gc.buildMessage=function(r,e){var t={literal:function(c){return'"'+n(c.text)+'"'},class:function(c){var u="",g;for(g=0;g0){for(g=1,f=1;gq&&(q=v,Y=[]),Y.push(pe))}function se(pe,V){return new gc(pe,null,null,V)}function be(pe,V,Qe){return new gc(gc.buildMessage(pe,V),pe,V,Qe)}function he(){var pe,V,Qe,le;return pe=v,V=Fe(),V!==t?(r.charCodeAt(v)===47?(Qe=s,v++):(Qe=t,$===0&&re(o)),Qe!==t?(le=Fe(),le!==t?(x=pe,V=a(V,le),pe=V):(v=pe,pe=t)):(v=pe,pe=t)):(v=pe,pe=t),pe===t&&(pe=v,V=Fe(),V!==t&&(x=pe,V=l(V)),pe=V),pe}function Fe(){var pe,V,Qe,le;return pe=v,V=Ke(),V!==t?(r.charCodeAt(v)===64?(Qe=c,v++):(Qe=t,$===0&&re(u)),Qe!==t?(le=ve(),le!==t?(x=pe,V=g(V,le),pe=V):(v=pe,pe=t)):(v=pe,pe=t)):(v=pe,pe=t),pe===t&&(pe=v,V=Ke(),V!==t&&(x=pe,V=f(V)),pe=V),pe}function Ke(){var pe,V,Qe,le,fe;return pe=v,r.charCodeAt(v)===64?(V=c,v++):(V=t,$===0&&re(u)),V!==t?(Qe=ke(),Qe!==t?(r.charCodeAt(v)===47?(le=s,v++):(le=t,$===0&&re(o)),le!==t?(fe=ke(),fe!==t?(x=pe,V=h(),pe=V):(v=pe,pe=t)):(v=pe,pe=t)):(v=pe,pe=t)):(v=pe,pe=t),pe===t&&(pe=v,V=ke(),V!==t&&(x=pe,V=h()),pe=V),pe}function ke(){var pe,V,Qe;if(pe=v,V=[],p.test(r.charAt(v))?(Qe=r.charAt(v),v++):(Qe=t,$===0&&re(m)),Qe!==t)for(;Qe!==t;)V.push(Qe),p.test(r.charAt(v))?(Qe=r.charAt(v),v++):(Qe=t,$===0&&re(m));else V=t;return V!==t&&(x=pe,V=h()),pe=V,pe}function ve(){var pe,V,Qe;if(pe=v,V=[],y.test(r.charAt(v))?(Qe=r.charAt(v),v++):(Qe=t,$===0&&re(b)),Qe!==t)for(;Qe!==t;)V.push(Qe),y.test(r.charAt(v))?(Qe=r.charAt(v),v++):(Qe=t,$===0&&re(b));else V=t;return V!==t&&(x=pe,V=h()),pe=V,pe}if(_=n(),_!==t&&v===r.length)return _;throw _!==t&&v{"use strict";function $M(r){return typeof r=="undefined"||r===null}function nfe(r){return typeof r=="object"&&r!==null}function sfe(r){return Array.isArray(r)?r:$M(r)?[]:[r]}function ofe(r,e){var t,i,n,s;if(e)for(s=Object.keys(e),t=0,i=s.length;t{"use strict";function ep(r,e){Error.call(this),this.name="YAMLException",this.reason=r,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||""}ep.prototype=Object.create(Error.prototype);ep.prototype.constructor=ep;ep.prototype.toString=function(e){var t=this.name+": ";return t+=this.reason||"(unknown reason)",!e&&this.mark&&(t+=" "+this.mark.toString()),t};e1.exports=ep});var i1=w((L7e,t1)=>{"use strict";var r1=hc();function RQ(r,e,t,i,n){this.name=r,this.buffer=e,this.position=t,this.line=i,this.column=n}RQ.prototype.getSnippet=function(e,t){var i,n,s,o,a;if(!this.buffer)return null;for(e=e||4,t=t||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>t/2-1){i=" ... ",n+=5;break}for(s="",o=this.position;ot/2-1){s=" ... ",o-=5;break}return a=this.buffer.slice(n,o),r1.repeat(" ",e)+i+a+s+` -`+r1.repeat(" ",e+this.position-n+i.length)+"^"};RQ.prototype.toString=function(e){var t,i="";return this.name&&(i+='in "'+this.name+'" '),i+="at line "+(this.line+1)+", column "+(this.column+1),e||(t=this.getSnippet(),t&&(i+=`: -`+t)),i};t1.exports=RQ});var ci=w((T7e,n1)=>{"use strict";var s1=tg(),lfe=["kind","resolve","construct","instanceOf","predicate","represent","defaultStyle","styleAliases"],cfe=["scalar","sequence","mapping"];function ufe(r){var e={};return r!==null&&Object.keys(r).forEach(function(t){r[t].forEach(function(i){e[String(i)]=t})}),e}function gfe(r,e){if(e=e||{},Object.keys(e).forEach(function(t){if(lfe.indexOf(t)===-1)throw new s1('Unknown option "'+t+'" is met in definition of "'+r+'" YAML type.')}),this.tag=r,this.kind=e.kind||null,this.resolve=e.resolve||function(){return!0},this.construct=e.construct||function(t){return t},this.instanceOf=e.instanceOf||null,this.predicate=e.predicate||null,this.represent=e.represent||null,this.defaultStyle=e.defaultStyle||null,this.styleAliases=ufe(e.styleAliases||null),cfe.indexOf(this.kind)===-1)throw new s1('Unknown kind "'+this.kind+'" is specified for "'+r+'" YAML type.')}n1.exports=gfe});var pc=w((O7e,o1)=>{"use strict";var a1=hc(),tI=tg(),ffe=ci();function FQ(r,e,t){var i=[];return r.include.forEach(function(n){t=FQ(n,e,t)}),r[e].forEach(function(n){t.forEach(function(s,o){s.tag===n.tag&&s.kind===n.kind&&i.push(o)}),t.push(n)}),t.filter(function(n,s){return i.indexOf(s)===-1})}function hfe(){var r={scalar:{},sequence:{},mapping:{},fallback:{}},e,t;function i(n){r[n.kind][n.tag]=r.fallback[n.tag]=n}for(e=0,t=arguments.length;e{"use strict";var pfe=ci();A1.exports=new pfe("tag:yaml.org,2002:str",{kind:"scalar",construct:function(r){return r!==null?r:""}})});var u1=w((K7e,c1)=>{"use strict";var dfe=ci();c1.exports=new dfe("tag:yaml.org,2002:seq",{kind:"sequence",construct:function(r){return r!==null?r:[]}})});var f1=w((U7e,g1)=>{"use strict";var Cfe=ci();g1.exports=new Cfe("tag:yaml.org,2002:map",{kind:"mapping",construct:function(r){return r!==null?r:{}}})});var rI=w((H7e,h1)=>{"use strict";var mfe=pc();h1.exports=new mfe({explicit:[l1(),u1(),f1()]})});var d1=w((j7e,p1)=>{"use strict";var Efe=ci();function Ife(r){if(r===null)return!0;var e=r.length;return e===1&&r==="~"||e===4&&(r==="null"||r==="Null"||r==="NULL")}function yfe(){return null}function wfe(r){return r===null}p1.exports=new Efe("tag:yaml.org,2002:null",{kind:"scalar",resolve:Ife,construct:yfe,predicate:wfe,represent:{canonical:function(){return"~"},lowercase:function(){return"null"},uppercase:function(){return"NULL"},camelcase:function(){return"Null"}},defaultStyle:"lowercase"})});var m1=w((G7e,C1)=>{"use strict";var Bfe=ci();function bfe(r){if(r===null)return!1;var e=r.length;return e===4&&(r==="true"||r==="True"||r==="TRUE")||e===5&&(r==="false"||r==="False"||r==="FALSE")}function Qfe(r){return r==="true"||r==="True"||r==="TRUE"}function Sfe(r){return Object.prototype.toString.call(r)==="[object Boolean]"}C1.exports=new Bfe("tag:yaml.org,2002:bool",{kind:"scalar",resolve:bfe,construct:Qfe,predicate:Sfe,represent:{lowercase:function(r){return r?"true":"false"},uppercase:function(r){return r?"TRUE":"FALSE"},camelcase:function(r){return r?"True":"False"}},defaultStyle:"lowercase"})});var I1=w((Y7e,E1)=>{"use strict";var vfe=hc(),xfe=ci();function kfe(r){return 48<=r&&r<=57||65<=r&&r<=70||97<=r&&r<=102}function Pfe(r){return 48<=r&&r<=55}function Dfe(r){return 48<=r&&r<=57}function Rfe(r){if(r===null)return!1;var e=r.length,t=0,i=!1,n;if(!e)return!1;if(n=r[t],(n==="-"||n==="+")&&(n=r[++t]),n==="0"){if(t+1===e)return!0;if(n=r[++t],n==="b"){for(t++;t=0?"0b"+r.toString(2):"-0b"+r.toString(2).slice(1)},octal:function(r){return r>=0?"0"+r.toString(8):"-0"+r.toString(8).slice(1)},decimal:function(r){return r.toString(10)},hexadecimal:function(r){return r>=0?"0x"+r.toString(16).toUpperCase():"-0x"+r.toString(16).toUpperCase().slice(1)}},defaultStyle:"decimal",styleAliases:{binary:[2,"bin"],octal:[8,"oct"],decimal:[10,"dec"],hexadecimal:[16,"hex"]}})});var B1=w((q7e,y1)=>{"use strict";var w1=hc(),Lfe=ci(),Tfe=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 Ofe(r){return!(r===null||!Tfe.test(r)||r[r.length-1]==="_")}function Mfe(r){var e,t,i,n;return e=r.replace(/_/g,"").toLowerCase(),t=e[0]==="-"?-1:1,n=[],"+-".indexOf(e[0])>=0&&(e=e.slice(1)),e===".inf"?t===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}),t*e):t*parseFloat(e,10)}var Kfe=/^[-+]?[0-9]+e/;function Ufe(r,e){var t;if(isNaN(r))switch(e){case"lowercase":return".nan";case"uppercase":return".NAN";case"camelcase":return".NaN"}else if(Number.POSITIVE_INFINITY===r)switch(e){case"lowercase":return".inf";case"uppercase":return".INF";case"camelcase":return".Inf"}else if(Number.NEGATIVE_INFINITY===r)switch(e){case"lowercase":return"-.inf";case"uppercase":return"-.INF";case"camelcase":return"-.Inf"}else if(w1.isNegativeZero(r))return"-0.0";return t=r.toString(10),Kfe.test(t)?t.replace("e",".e"):t}function Hfe(r){return Object.prototype.toString.call(r)==="[object Number]"&&(r%1!=0||w1.isNegativeZero(r))}y1.exports=new Lfe("tag:yaml.org,2002:float",{kind:"scalar",resolve:Ofe,construct:Mfe,predicate:Hfe,represent:Ufe,defaultStyle:"lowercase"})});var NQ=w((J7e,b1)=>{"use strict";var jfe=pc();b1.exports=new jfe({include:[rI()],implicit:[d1(),m1(),I1(),B1()]})});var LQ=w((W7e,Q1)=>{"use strict";var Gfe=pc();Q1.exports=new Gfe({include:[NQ()]})});var k1=w((z7e,S1)=>{"use strict";var Yfe=ci(),v1=new RegExp("^([0-9][0-9][0-9][0-9])-([0-9][0-9])-([0-9][0-9])$"),x1=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 qfe(r){return r===null?!1:v1.exec(r)!==null||x1.exec(r)!==null}function Jfe(r){var e,t,i,n,s,o,a,l=0,c=null,u,g,f;if(e=v1.exec(r),e===null&&(e=x1.exec(r)),e===null)throw new Error("Date resolve error");if(t=+e[1],i=+e[2]-1,n=+e[3],!e[4])return new Date(Date.UTC(t,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(t,i,n,s,o,a,l)),c&&f.setTime(f.getTime()-c),f}function Wfe(r){return r.toISOString()}S1.exports=new Yfe("tag:yaml.org,2002:timestamp",{kind:"scalar",resolve:qfe,construct:Jfe,instanceOf:Date,represent:Wfe})});var D1=w((_7e,P1)=>{"use strict";var zfe=ci();function _fe(r){return r==="<<"||r===null}P1.exports=new zfe("tag:yaml.org,2002:merge",{kind:"scalar",resolve:_fe})});var N1=w((V7e,R1)=>{"use strict";var dc;try{F1=require,dc=F1("buffer").Buffer}catch(r){}var F1,Vfe=ci(),TQ=`ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/= -\r`;function Xfe(r){if(r===null)return!1;var e,t,i=0,n=r.length,s=TQ;for(t=0;t64)){if(e<0)return!1;i+=6}return i%8==0}function Zfe(r){var e,t,i=r.replace(/[\r\n=]/g,""),n=i.length,s=TQ,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 t=n%4*6,t===0?(a.push(o>>16&255),a.push(o>>8&255),a.push(o&255)):t===18?(a.push(o>>10&255),a.push(o>>2&255)):t===12&&a.push(o>>4&255),dc?dc.from?dc.from(a):new dc(a):a}function $fe(r){var e="",t=0,i,n,s=r.length,o=TQ;for(i=0;i>18&63],e+=o[t>>12&63],e+=o[t>>6&63],e+=o[t&63]),t=(t<<8)+r[i];return n=s%3,n===0?(e+=o[t>>18&63],e+=o[t>>12&63],e+=o[t>>6&63],e+=o[t&63]):n===2?(e+=o[t>>10&63],e+=o[t>>4&63],e+=o[t<<2&63],e+=o[64]):n===1&&(e+=o[t>>2&63],e+=o[t<<4&63],e+=o[64],e+=o[64]),e}function ehe(r){return dc&&dc.isBuffer(r)}R1.exports=new Vfe("tag:yaml.org,2002:binary",{kind:"scalar",resolve:Xfe,construct:Zfe,predicate:ehe,represent:$fe})});var T1=w((X7e,L1)=>{"use strict";var the=ci(),rhe=Object.prototype.hasOwnProperty,ihe=Object.prototype.toString;function nhe(r){if(r===null)return!0;var e=[],t,i,n,s,o,a=r;for(t=0,i=a.length;t{"use strict";var ohe=ci(),ahe=Object.prototype.toString;function Ahe(r){if(r===null)return!0;var e,t,i,n,s,o=r;for(s=new Array(o.length),e=0,t=o.length;e{"use strict";var che=ci(),uhe=Object.prototype.hasOwnProperty;function ghe(r){if(r===null)return!0;var e,t=r;for(e in t)if(uhe.call(t,e)&&t[e]!==null)return!1;return!0}function fhe(r){return r!==null?r:{}}K1.exports=new che("tag:yaml.org,2002:set",{kind:"mapping",resolve:ghe,construct:fhe})});var ig=w((eXe,H1)=>{"use strict";var hhe=pc();H1.exports=new hhe({include:[LQ()],implicit:[k1(),D1()],explicit:[N1(),T1(),M1(),U1()]})});var G1=w((tXe,j1)=>{"use strict";var phe=ci();function dhe(){return!0}function Che(){}function mhe(){return""}function Ehe(r){return typeof r=="undefined"}j1.exports=new phe("tag:yaml.org,2002:js/undefined",{kind:"scalar",resolve:dhe,construct:Che,predicate:Ehe,represent:mhe})});var q1=w((rXe,Y1)=>{"use strict";var Ihe=ci();function yhe(r){if(r===null||r.length===0)return!1;var e=r,t=/\/([gim]*)$/.exec(r),i="";return!(e[0]==="/"&&(t&&(i=t[1]),i.length>3||e[e.length-i.length-1]!=="/"))}function whe(r){var e=r,t=/\/([gim]*)$/.exec(r),i="";return e[0]==="/"&&(t&&(i=t[1]),e=e.slice(1,e.length-i.length-1)),new RegExp(e,i)}function Bhe(r){var e="/"+r.source+"/";return r.global&&(e+="g"),r.multiline&&(e+="m"),r.ignoreCase&&(e+="i"),e}function bhe(r){return Object.prototype.toString.call(r)==="[object RegExp]"}Y1.exports=new Ihe("tag:yaml.org,2002:js/regexp",{kind:"scalar",resolve:yhe,construct:whe,predicate:bhe,represent:Bhe})});var z1=w((iXe,J1)=>{"use strict";var iI;try{W1=require,iI=W1("esprima")}catch(r){typeof window!="undefined"&&(iI=window.esprima)}var W1,Qhe=ci();function She(r){if(r===null)return!1;try{var e="("+r+")",t=iI.parse(e,{range:!0});return!(t.type!=="Program"||t.body.length!==1||t.body[0].type!=="ExpressionStatement"||t.body[0].expression.type!=="ArrowFunctionExpression"&&t.body[0].expression.type!=="FunctionExpression")}catch(i){return!1}}function vhe(r){var e="("+r+")",t=iI.parse(e,{range:!0}),i=[],n;if(t.type!=="Program"||t.body.length!==1||t.body[0].type!=="ExpressionStatement"||t.body[0].expression.type!=="ArrowFunctionExpression"&&t.body[0].expression.type!=="FunctionExpression")throw new Error("Failed to resolve function");return t.body[0].expression.params.forEach(function(s){i.push(s.name)}),n=t.body[0].expression.body.range,t.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 xhe(r){return r.toString()}function khe(r){return Object.prototype.toString.call(r)==="[object Function]"}J1.exports=new Qhe("tag:yaml.org,2002:js/function",{kind:"scalar",resolve:She,construct:vhe,predicate:khe,represent:xhe})});var tp=w((nXe,_1)=>{"use strict";var V1=pc();_1.exports=V1.DEFAULT=new V1({include:[ig()],explicit:[G1(),q1(),z1()]})});var pK=w((sXe,rp)=>{"use strict";var Oa=hc(),X1=tg(),Phe=i1(),Z1=ig(),Dhe=tp(),JA=Object.prototype.hasOwnProperty,nI=1,$1=2,eK=3,sI=4,OQ=1,Rhe=2,tK=3,Fhe=/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F-\x84\x86-\x9F\uFFFE\uFFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF]/,Nhe=/[\x85\u2028\u2029]/,Lhe=/[,\[\]\{\}]/,rK=/^(?:!|!!|![a-z\-]+!)$/i,iK=/^(?:!|[^,\[\]\{\}])(?:%[0-9a-f]{2}|[0-9a-z\-#;\/\?:@&=\+\$,_\.!~\*'\(\)\[\]])*$/i;function nK(r){return Object.prototype.toString.call(r)}function Lo(r){return r===10||r===13}function Cc(r){return r===9||r===32}function yn(r){return r===9||r===32||r===10||r===13}function ng(r){return r===44||r===91||r===93||r===123||r===125}function The(r){var e;return 48<=r&&r<=57?r-48:(e=r|32,97<=e&&e<=102?e-97+10:-1)}function Ohe(r){return r===120?2:r===117?4:r===85?8:0}function Mhe(r){return 48<=r&&r<=57?r-48:-1}function sK(r){return r===48?"\0":r===97?"\x07":r===98?"\b":r===116||r===9?" ":r===110?` -`:r===118?"\v":r===102?"\f":r===114?"\r":r===101?"":r===32?" ":r===34?'"':r===47?"/":r===92?"\\":r===78?"\x85":r===95?"\xA0":r===76?"\u2028":r===80?"\u2029":""}function Khe(r){return r<=65535?String.fromCharCode(r):String.fromCharCode((r-65536>>10)+55296,(r-65536&1023)+56320)}var oK=new Array(256),aK=new Array(256);for(var sg=0;sg<256;sg++)oK[sg]=sK(sg)?1:0,aK[sg]=sK(sg);function Uhe(r,e){this.input=r,this.filename=e.filename||null,this.schema=e.schema||Dhe,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=r.length,this.position=0,this.line=0,this.lineStart=0,this.lineIndent=0,this.documents=[]}function AK(r,e){return new X1(e,new Phe(r.filename,r.input,r.position,r.line,r.position-r.lineStart))}function dt(r,e){throw AK(r,e)}function oI(r,e){r.onWarning&&r.onWarning.call(null,AK(r,e))}var lK={YAML:function(e,t,i){var n,s,o;e.version!==null&&dt(e,"duplication of %YAML directive"),i.length!==1&&dt(e,"YAML directive accepts exactly one argument"),n=/^([0-9]+)\.([0-9]+)$/.exec(i[0]),n===null&&dt(e,"ill-formed argument of the YAML directive"),s=parseInt(n[1],10),o=parseInt(n[2],10),s!==1&&dt(e,"unacceptable YAML version of the document"),e.version=i[0],e.checkLineBreaks=o<2,o!==1&&o!==2&&oI(e,"unsupported YAML version of the document")},TAG:function(e,t,i){var n,s;i.length!==2&&dt(e,"TAG directive accepts exactly two arguments"),n=i[0],s=i[1],rK.test(n)||dt(e,"ill-formed tag handle (first argument) of the TAG directive"),JA.call(e.tagMap,n)&&dt(e,'there is a previously declared suffix for "'+n+'" tag handle'),iK.test(s)||dt(e,"ill-formed tag prefix (second argument) of the TAG directive"),e.tagMap[n]=s}};function WA(r,e,t,i){var n,s,o,a;if(e1&&(r.result+=Oa.repeat(` -`,e-1))}function Hhe(r,e,t){var i,n,s,o,a,l,c,u,g=r.kind,f=r.result,h;if(h=r.input.charCodeAt(r.position),yn(h)||ng(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=r.input.charCodeAt(r.position+1),yn(n)||t&&ng(n)))return!1;for(r.kind="scalar",r.result="",s=o=r.position,a=!1;h!==0;){if(h===58){if(n=r.input.charCodeAt(r.position+1),yn(n)||t&&ng(n))break}else if(h===35){if(i=r.input.charCodeAt(r.position-1),yn(i))break}else{if(r.position===r.lineStart&&aI(r)||t&&ng(h))break;if(Lo(h))if(l=r.line,c=r.lineStart,u=r.lineIndent,ei(r,!1,-1),r.lineIndent>=e){a=!0,h=r.input.charCodeAt(r.position);continue}else{r.position=o,r.line=l,r.lineStart=c,r.lineIndent=u;break}}a&&(WA(r,s,o,!1),KQ(r,r.line-l),s=o=r.position,a=!1),Cc(h)||(o=r.position+1),h=r.input.charCodeAt(++r.position)}return WA(r,s,o,!1),r.result?!0:(r.kind=g,r.result=f,!1)}function jhe(r,e){var t,i,n;if(t=r.input.charCodeAt(r.position),t!==39)return!1;for(r.kind="scalar",r.result="",r.position++,i=n=r.position;(t=r.input.charCodeAt(r.position))!==0;)if(t===39)if(WA(r,i,r.position,!0),t=r.input.charCodeAt(++r.position),t===39)i=r.position,r.position++,n=r.position;else return!0;else Lo(t)?(WA(r,i,n,!0),KQ(r,ei(r,!1,e)),i=n=r.position):r.position===r.lineStart&&aI(r)?dt(r,"unexpected end of the document within a single quoted scalar"):(r.position++,n=r.position);dt(r,"unexpected end of the stream within a single quoted scalar")}function Ghe(r,e){var t,i,n,s,o,a;if(a=r.input.charCodeAt(r.position),a!==34)return!1;for(r.kind="scalar",r.result="",r.position++,t=i=r.position;(a=r.input.charCodeAt(r.position))!==0;){if(a===34)return WA(r,t,r.position,!0),r.position++,!0;if(a===92){if(WA(r,t,r.position,!0),a=r.input.charCodeAt(++r.position),Lo(a))ei(r,!1,e);else if(a<256&&oK[a])r.result+=aK[a],r.position++;else if((o=Ohe(a))>0){for(n=o,s=0;n>0;n--)a=r.input.charCodeAt(++r.position),(o=The(a))>=0?s=(s<<4)+o:dt(r,"expected hexadecimal character");r.result+=Khe(s),r.position++}else dt(r,"unknown escape sequence");t=i=r.position}else Lo(a)?(WA(r,t,i,!0),KQ(r,ei(r,!1,e)),t=i=r.position):r.position===r.lineStart&&aI(r)?dt(r,"unexpected end of the document within a double quoted scalar"):(r.position++,i=r.position)}dt(r,"unexpected end of the stream within a double quoted scalar")}function Yhe(r,e){var t=!0,i,n=r.tag,s,o=r.anchor,a,l,c,u,g,f={},h,p,m,y;if(y=r.input.charCodeAt(r.position),y===91)l=93,g=!1,s=[];else if(y===123)l=125,g=!0,s={};else return!1;for(r.anchor!==null&&(r.anchorMap[r.anchor]=s),y=r.input.charCodeAt(++r.position);y!==0;){if(ei(r,!0,e),y=r.input.charCodeAt(r.position),y===l)return r.position++,r.tag=n,r.anchor=o,r.kind=g?"mapping":"sequence",r.result=s,!0;t||dt(r,"missed comma between flow collection entries"),p=h=m=null,c=u=!1,y===63&&(a=r.input.charCodeAt(r.position+1),yn(a)&&(c=u=!0,r.position++,ei(r,!0,e))),i=r.line,ag(r,e,nI,!1,!0),p=r.tag,h=r.result,ei(r,!0,e),y=r.input.charCodeAt(r.position),(u||r.line===i)&&y===58&&(c=!0,y=r.input.charCodeAt(++r.position),ei(r,!0,e),ag(r,e,nI,!1,!0),m=r.result),g?og(r,s,f,p,h,m):c?s.push(og(r,null,f,p,h,m)):s.push(h),ei(r,!0,e),y=r.input.charCodeAt(r.position),y===44?(t=!0,y=r.input.charCodeAt(++r.position)):t=!1}dt(r,"unexpected end of the stream within a flow collection")}function qhe(r,e){var t,i,n=OQ,s=!1,o=!1,a=e,l=0,c=!1,u,g;if(g=r.input.charCodeAt(r.position),g===124)i=!1;else if(g===62)i=!0;else return!1;for(r.kind="scalar",r.result="";g!==0;)if(g=r.input.charCodeAt(++r.position),g===43||g===45)OQ===n?n=g===43?tK:Rhe:dt(r,"repeat of a chomping mode identifier");else if((u=Mhe(g))>=0)u===0?dt(r,"bad explicit indentation width of a block scalar; it cannot be less than one"):o?dt(r,"repeat of an indentation width identifier"):(a=e+u-1,o=!0);else break;if(Cc(g)){do g=r.input.charCodeAt(++r.position);while(Cc(g));if(g===35)do g=r.input.charCodeAt(++r.position);while(!Lo(g)&&g!==0)}for(;g!==0;){for(MQ(r),r.lineIndent=0,g=r.input.charCodeAt(r.position);(!o||r.lineIndenta&&(a=r.lineIndent),Lo(g)){l++;continue}if(r.lineIndente)&&l!==0)dt(r,"bad indentation of a sequence entry");else if(r.lineIndente)&&(ag(r,e,sI,!0,n)&&(p?f=r.result:h=r.result),p||(og(r,c,u,g,f,h,s,o),g=f=h=null),ei(r,!0,-1),y=r.input.charCodeAt(r.position)),r.lineIndent>e&&y!==0)dt(r,"bad indentation of a mapping entry");else if(r.lineIndente?l=1:r.lineIndent===e?l=0:r.lineIndente?l=1:r.lineIndent===e?l=0:r.lineIndent tag; it should be "scalar", not "'+r.kind+'"'),g=0,f=r.implicitTypes.length;g tag; it should be "'+h.kind+'", not "'+r.kind+'"'),h.resolve(r.result)?(r.result=h.construct(r.result),r.anchor!==null&&(r.anchorMap[r.anchor]=r.result)):dt(r,"cannot resolve a node with !<"+r.tag+"> explicit tag")):dt(r,"unknown tag !<"+r.tag+">");return r.listener!==null&&r.listener("close",r),r.tag!==null||r.anchor!==null||u}function Vhe(r){var e=r.position,t,i,n,s=!1,o;for(r.version=null,r.checkLineBreaks=r.legacy,r.tagMap={},r.anchorMap={};(o=r.input.charCodeAt(r.position))!==0&&(ei(r,!0,-1),o=r.input.charCodeAt(r.position),!(r.lineIndent>0||o!==37));){for(s=!0,o=r.input.charCodeAt(++r.position),t=r.position;o!==0&&!yn(o);)o=r.input.charCodeAt(++r.position);for(i=r.input.slice(t,r.position),n=[],i.length<1&&dt(r,"directive name must not be less than one character in length");o!==0;){for(;Cc(o);)o=r.input.charCodeAt(++r.position);if(o===35){do o=r.input.charCodeAt(++r.position);while(o!==0&&!Lo(o));break}if(Lo(o))break;for(t=r.position;o!==0&&!yn(o);)o=r.input.charCodeAt(++r.position);n.push(r.input.slice(t,r.position))}o!==0&&MQ(r),JA.call(lK,i)?lK[i](r,i,n):oI(r,'unknown document directive "'+i+'"')}if(ei(r,!0,-1),r.lineIndent===0&&r.input.charCodeAt(r.position)===45&&r.input.charCodeAt(r.position+1)===45&&r.input.charCodeAt(r.position+2)===45?(r.position+=3,ei(r,!0,-1)):s&&dt(r,"directives end mark is expected"),ag(r,r.lineIndent-1,sI,!1,!0),ei(r,!0,-1),r.checkLineBreaks&&Nhe.test(r.input.slice(e,r.position))&&oI(r,"non-ASCII line breaks are interpreted as content"),r.documents.push(r.result),r.position===r.lineStart&&aI(r)){r.input.charCodeAt(r.position)===46&&(r.position+=3,ei(r,!0,-1));return}if(r.position{"use strict";var ip=hc(),np=tg(),$he=tp(),epe=ig(),dK=Object.prototype.toString,CK=Object.prototype.hasOwnProperty,tpe=9,sp=10,rpe=13,ipe=32,npe=33,spe=34,mK=35,ope=37,ape=38,Ape=39,lpe=42,EK=44,cpe=45,IK=58,upe=61,gpe=62,fpe=63,hpe=64,yK=91,wK=93,ppe=96,BK=123,dpe=124,bK=125,Ki={};Ki[0]="\\0";Ki[7]="\\a";Ki[8]="\\b";Ki[9]="\\t";Ki[10]="\\n";Ki[11]="\\v";Ki[12]="\\f";Ki[13]="\\r";Ki[27]="\\e";Ki[34]='\\"';Ki[92]="\\\\";Ki[133]="\\N";Ki[160]="\\_";Ki[8232]="\\L";Ki[8233]="\\P";var Cpe=["y","Y","yes","Yes","YES","on","On","ON","n","N","no","No","NO","off","Off","OFF"];function mpe(r,e){var t,i,n,s,o,a,l;if(e===null)return{};for(t={},i=Object.keys(e),n=0,s=i.length;n0?r.charCodeAt(s-1):null,f=f&&vK(o,a)}else{for(s=0;si&&r[g+1]!==" ",g=s);else if(!Ag(o))return AI;a=s>0?r.charCodeAt(s-1):null,f=f&&vK(o,a)}c=c||u&&s-g-1>i&&r[g+1]!==" "}return!l&&!c?f&&!n(r)?kK:PK:t>9&&xK(r)?AI:c?RK:DK}function Spe(r,e,t,i){r.dump=function(){if(e.length===0)return"''";if(!r.noCompatMode&&Cpe.indexOf(e)!==-1)return"'"+e+"'";var n=r.indent*Math.max(1,t),s=r.lineWidth===-1?-1:Math.max(Math.min(r.lineWidth,40),r.lineWidth-n),o=i||r.flowLevel>-1&&t>=r.flowLevel;function a(l){return Ipe(r,l)}switch(Bpe(e,o,r.indent,s,a)){case kK:return e;case PK:return"'"+e.replace(/'/g,"''")+"'";case DK:return"|"+FK(e,r.indent)+NK(SK(e,n));case RK:return">"+FK(e,r.indent)+NK(SK(bpe(e,s),n));case AI:return'"'+Qpe(e,s)+'"';default:throw new np("impossible error: invalid scalar style")}}()}function FK(r,e){var t=xK(r)?String(e):"",i=r[r.length-1]===` -`,n=i&&(r[r.length-2]===` -`||r===` -`),s=n?"+":i?"":"-";return t+s+` -`}function NK(r){return r[r.length-1]===` -`?r.slice(0,-1):r}function bpe(r,e){for(var t=/(\n+)([^\n]*)/g,i=function(){var c=r.indexOf(` -`);return c=c!==-1?c:r.length,t.lastIndex=c,LK(r.slice(0,c),e)}(),n=r[0]===` -`||r[0]===" ",s,o;o=t.exec(r);){var a=o[1],l=o[2];s=l[0]===" ",i+=a+(!n&&!s&&l!==""?` -`:"")+LK(l,e),n=s}return i}function LK(r,e){if(r===""||r[0]===" ")return r;for(var t=/ [^ ]/g,i,n=0,s,o=0,a=0,l="";i=t.exec(r);)a=i.index,a-n>e&&(s=o>n?o:a,l+=` -`+r.slice(n,s),n=s+1),o=a;return l+=` -`,r.length-n>e&&o>n?l+=r.slice(n,o)+` -`+r.slice(o+1):l+=r.slice(n),l.slice(1)}function Qpe(r){for(var e="",t,i,n,s=0;s=55296&&t<=56319&&(i=r.charCodeAt(s+1),i>=56320&&i<=57343)){e+=QK((t-55296)*1024+i-56320+65536),s++;continue}n=Ki[t],e+=!n&&Ag(t)?r[s]:n||QK(t)}return e}function vpe(r,e,t){var i="",n=r.tag,s,o;for(s=0,o=t.length;s1024&&(u+="? "),u+=r.dump+(r.condenseFlow?'"':"")+":"+(r.condenseFlow?"":" "),!!mc(r,e,c,!1,!1)&&(u+=r.dump,i+=u));r.tag=n,r.dump="{"+i+"}"}function Ppe(r,e,t,i){var n="",s=r.tag,o=Object.keys(t),a,l,c,u,g,f;if(r.sortKeys===!0)o.sort();else if(typeof r.sortKeys=="function")o.sort(r.sortKeys);else if(r.sortKeys)throw new np("sortKeys must be a boolean or a function");for(a=0,l=o.length;a1024,g&&(r.dump&&sp===r.dump.charCodeAt(0)?f+="?":f+="? "),f+=r.dump,g&&(f+=HQ(r,e)),!!mc(r,e+1,u,!0,g)&&(r.dump&&sp===r.dump.charCodeAt(0)?f+=":":f+=": ",f+=r.dump,n+=f));r.tag=s,r.dump=n||"{}"}function TK(r,e,t){var i,n,s,o,a,l;for(n=t?r.explicitTypes:r.implicitTypes,s=0,o=n.length;s tag resolver accepts not "'+l+'" style');r.dump=i}return!0}return!1}function mc(r,e,t,i,n,s){r.tag=null,r.dump=t,TK(r,t,!1)||TK(r,t,!0);var o=dK.call(r.dump);i&&(i=r.flowLevel<0||r.flowLevel>e);var a=o==="[object Object]"||o==="[object Array]",l,c;if(a&&(l=r.duplicates.indexOf(t),c=l!==-1),(r.tag!==null&&r.tag!=="?"||c||r.indent!==2&&e>0)&&(n=!1),c&&r.usedDuplicates[l])r.dump="*ref_"+l;else{if(a&&c&&!r.usedDuplicates[l]&&(r.usedDuplicates[l]=!0),o==="[object Object]")i&&Object.keys(r.dump).length!==0?(Ppe(r,e,r.dump,n),c&&(r.dump="&ref_"+l+r.dump)):(kpe(r,e,r.dump),c&&(r.dump="&ref_"+l+" "+r.dump));else if(o==="[object Array]"){var u=r.noArrayIndent&&e>0?e-1:e;i&&r.dump.length!==0?(xpe(r,u,r.dump,n),c&&(r.dump="&ref_"+l+r.dump)):(vpe(r,u,r.dump),c&&(r.dump="&ref_"+l+" "+r.dump))}else if(o==="[object String]")r.tag!=="?"&&Spe(r,r.dump,e,s);else{if(r.skipInvalid)return!1;throw new np("unacceptable kind of an object to dump "+o)}r.tag!==null&&r.tag!=="?"&&(r.dump="!<"+r.tag+"> "+r.dump)}return!0}function Dpe(r,e){var t=[],i=[],n,s;for(GQ(r,t,i),n=0,s=i.length;n{"use strict";var lI=pK(),KK=MK();function cI(r){return function(){throw new Error("Function "+r+" is deprecated and cannot be used.")}}Mr.exports.Type=ci();Mr.exports.Schema=pc();Mr.exports.FAILSAFE_SCHEMA=rI();Mr.exports.JSON_SCHEMA=NQ();Mr.exports.CORE_SCHEMA=LQ();Mr.exports.DEFAULT_SAFE_SCHEMA=ig();Mr.exports.DEFAULT_FULL_SCHEMA=tp();Mr.exports.load=lI.load;Mr.exports.loadAll=lI.loadAll;Mr.exports.safeLoad=lI.safeLoad;Mr.exports.safeLoadAll=lI.safeLoadAll;Mr.exports.dump=KK.dump;Mr.exports.safeDump=KK.safeDump;Mr.exports.YAMLException=tg();Mr.exports.MINIMAL_SCHEMA=rI();Mr.exports.SAFE_SCHEMA=ig();Mr.exports.DEFAULT_SCHEMA=tp();Mr.exports.scan=cI("scan");Mr.exports.parse=cI("parse");Mr.exports.compose=cI("compose");Mr.exports.addConstructor=cI("addConstructor")});var jK=w((AXe,HK)=>{"use strict";var Fpe=UK();HK.exports=Fpe});var YK=w((lXe,GK)=>{"use strict";function Npe(r,e){function t(){this.constructor=r}t.prototype=e.prototype,r.prototype=new t}function Ec(r,e,t,i){this.message=r,this.expected=e,this.found=t,this.location=i,this.name="SyntaxError",typeof Error.captureStackTrace=="function"&&Error.captureStackTrace(this,Ec)}Npe(Ec,Error);Ec.buildMessage=function(r,e){var t={literal:function(c){return'"'+n(c.text)+'"'},class:function(c){var u="",g;for(g=0;g0){for(g=1,f=1;g({[He]:Ce})))},q=function(R){return R},Y=function(R){return R},$=Zs("correct indentation"),_=" ",ne=gr(" ",!1),ee=function(R){return R.length===KA*Ju},A=function(R){return R.length===(KA+1)*Ju},oe=function(){return KA++,!0},ce=function(){return KA--,!0},Z=function(){return Uu()},O=Zs("pseudostring"),L=/^[^\r\n\t ?:,\][{}#&*!|>'"%@`\-]/,de=qn(["\r",` -`," "," ","?",":",",","]","[","{","}","#","&","*","!","|",">","'",'"',"%","@","`","-"],!0,!1),Be=/^[^\r\n\t ,\][{}:#"']/,je=qn(["\r",` -`," "," ",",","]","[","{","}",":","#",'"',"'"],!0,!1),re=function(){return Uu().replace(/^ *| *$/g,"")},se="--",be=gr("--",!1),he=/^[a-zA-Z\/0-9]/,Fe=qn([["a","z"],["A","Z"],"/",["0","9"]],!1,!1),Ke=/^[^\r\n\t :,]/,ke=qn(["\r",` -`," "," ",":",","],!0,!1),ve="null",pe=gr("null",!1),V=function(){return null},Qe="true",le=gr("true",!1),fe=function(){return!0},gt="false",Ht=gr("false",!1),Mt=function(){return!1},Ei=Zs("string"),jt='"',Qr=gr('"',!1),Oi=function(){return""},Xs=function(R){return R},Un=function(R){return R.join("")},Hn=/^[^"\\\0-\x1F\x7F]/,Sr=qn(['"',"\\",["\0",""],"\x7F"],!0,!1),jn='\\"',fs=gr('\\"',!1),ba=function(){return'"'},DA="\\\\",Nu=gr("\\\\",!1),hs=function(){return"\\"},RA="\\/",Qa=gr("\\/",!1),Lu=function(){return"/"},FA="\\b",NA=gr("\\b",!1),vr=function(){return"\b"},zl="\\f",Tu=gr("\\f",!1),xo=function(){return"\f"},Ou="\\n",Sh=gr("\\n",!1),vh=function(){return` -`},Dr="\\r",Ae=gr("\\r",!1),ko=function(){return"\r"},Gn="\\t",Mu=gr("\\t",!1),St=function(){return" "},_l="\\u",Yn=gr("\\u",!1),ps=function(R,G,Ce,He){return String.fromCharCode(parseInt(`0x${R}${G}${Ce}${He}`))},ds=/^[0-9a-fA-F]/,pt=qn([["0","9"],["a","f"],["A","F"]],!1,!1),Po=Zs("blank space"),lt=/^[ \t]/,mn=qn([" "," "],!1,!1),S=Zs("white space"),Tt=/^[ \t\n\r]/,Ku=qn([" "," ",` -`,"\r"],!1,!1),Vl=`\r -`,xh=gr(`\r -`,!1),kh=` -`,Ph=gr(` -`,!1),Dh="\r",Rh=gr("\r",!1),j=0,wt=0,LA=[{line:1,column:1}],$i=0,Xl=[],$e=0,Sa;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 Uu(){return r.substring(wt,j)}function yE(){return En(wt,j)}function Fh(R,G){throw G=G!==void 0?G:En(wt,j),$l([Zs(R)],r.substring(wt,j),G)}function wE(R,G){throw G=G!==void 0?G:En(wt,j),Hu(R,G)}function gr(R,G){return{type:"literal",text:R,ignoreCase:G}}function qn(R,G,Ce){return{type:"class",parts:R,inverted:G,ignoreCase:Ce}}function Zl(){return{type:"any"}}function Nh(){return{type:"end"}}function Zs(R){return{type:"other",description:R}}function va(R){var G=LA[R],Ce;if(G)return G;for(Ce=R-1;!LA[Ce];)Ce--;for(G=LA[Ce],G={line:G.line,column:G.column};Ce$i&&($i=j,Xl=[]),Xl.push(R))}function Hu(R,G){return new Ec(R,null,null,G)}function $l(R,G,Ce){return new Ec(Ec.buildMessage(R,G),R,G,Ce)}function $s(){var R;return R=ju(),R}function ec(){var R,G,Ce;for(R=j,G=[],Ce=TA();Ce!==t;)G.push(Ce),Ce=TA();return G!==t&&(wt=R,G=s(G)),R=G,R}function TA(){var R,G,Ce,He,Te;return R=j,G=ka(),G!==t?(r.charCodeAt(j)===45?(Ce=o,j++):(Ce=t,$e===0&&Oe(a)),Ce!==t?(He=Tr(),He!==t?(Te=xa(),Te!==t?(wt=R,G=l(Te),R=G):(j=R,R=t)):(j=R,R=t)):(j=R,R=t)):(j=R,R=t),R}function ju(){var R,G,Ce;for(R=j,G=[],Ce=Gu();Ce!==t;)G.push(Ce),Ce=Gu();return G!==t&&(wt=R,G=c(G)),R=G,R}function Gu(){var R,G,Ce,He,Te,Xe,Et,Rt,Jn;if(R=j,G=Tr(),G===t&&(G=null),G!==t){if(Ce=j,r.charCodeAt(j)===35?(He=u,j++):(He=t,$e===0&&Oe(g)),He!==t){if(Te=[],Xe=j,Et=j,$e++,Rt=ro(),$e--,Rt===t?Et=void 0:(j=Et,Et=t),Et!==t?(r.length>j?(Rt=r.charAt(j),j++):(Rt=t,$e===0&&Oe(f)),Rt!==t?(Et=[Et,Rt],Xe=Et):(j=Xe,Xe=t)):(j=Xe,Xe=t),Xe!==t)for(;Xe!==t;)Te.push(Xe),Xe=j,Et=j,$e++,Rt=ro(),$e--,Rt===t?Et=void 0:(j=Et,Et=t),Et!==t?(r.length>j?(Rt=r.charAt(j),j++):(Rt=t,$e===0&&Oe(f)),Rt!==t?(Et=[Et,Rt],Xe=Et):(j=Xe,Xe=t)):(j=Xe,Xe=t);else Te=t;Te!==t?(He=[He,Te],Ce=He):(j=Ce,Ce=t)}else j=Ce,Ce=t;if(Ce===t&&(Ce=null),Ce!==t){if(He=[],Te=to(),Te!==t)for(;Te!==t;)He.push(Te),Te=to();else He=t;He!==t?(wt=R,G=h(),R=G):(j=R,R=t)}else j=R,R=t}else j=R,R=t;if(R===t&&(R=j,G=ka(),G!==t?(Ce=tc(),Ce!==t?(He=Tr(),He===t&&(He=null),He!==t?(r.charCodeAt(j)===58?(Te=p,j++):(Te=t,$e===0&&Oe(m)),Te!==t?(Xe=Tr(),Xe===t&&(Xe=null),Xe!==t?(Et=xa(),Et!==t?(wt=R,G=y(Ce,Et),R=G):(j=R,R=t)):(j=R,R=t)):(j=R,R=t)):(j=R,R=t)):(j=R,R=t)):(j=R,R=t),R===t&&(R=j,G=ka(),G!==t?(Ce=eo(),Ce!==t?(He=Tr(),He===t&&(He=null),He!==t?(r.charCodeAt(j)===58?(Te=p,j++):(Te=t,$e===0&&Oe(m)),Te!==t?(Xe=Tr(),Xe===t&&(Xe=null),Xe!==t?(Et=xa(),Et!==t?(wt=R,G=y(Ce,Et),R=G):(j=R,R=t)):(j=R,R=t)):(j=R,R=t)):(j=R,R=t)):(j=R,R=t)):(j=R,R=t),R===t))){if(R=j,G=ka(),G!==t)if(Ce=eo(),Ce!==t)if(He=Tr(),He!==t)if(Te=BE(),Te!==t){if(Xe=[],Et=to(),Et!==t)for(;Et!==t;)Xe.push(Et),Et=to();else Xe=t;Xe!==t?(wt=R,G=y(Ce,Te),R=G):(j=R,R=t)}else j=R,R=t;else j=R,R=t;else j=R,R=t;else j=R,R=t;if(R===t)if(R=j,G=ka(),G!==t)if(Ce=eo(),Ce!==t){if(He=[],Te=j,Xe=Tr(),Xe===t&&(Xe=null),Xe!==t?(r.charCodeAt(j)===44?(Et=b,j++):(Et=t,$e===0&&Oe(v)),Et!==t?(Rt=Tr(),Rt===t&&(Rt=null),Rt!==t?(Jn=eo(),Jn!==t?(wt=Te,Xe=x(Ce,Jn),Te=Xe):(j=Te,Te=t)):(j=Te,Te=t)):(j=Te,Te=t)):(j=Te,Te=t),Te!==t)for(;Te!==t;)He.push(Te),Te=j,Xe=Tr(),Xe===t&&(Xe=null),Xe!==t?(r.charCodeAt(j)===44?(Et=b,j++):(Et=t,$e===0&&Oe(v)),Et!==t?(Rt=Tr(),Rt===t&&(Rt=null),Rt!==t?(Jn=eo(),Jn!==t?(wt=Te,Xe=x(Ce,Jn),Te=Xe):(j=Te,Te=t)):(j=Te,Te=t)):(j=Te,Te=t)):(j=Te,Te=t);else He=t;He!==t?(Te=Tr(),Te===t&&(Te=null),Te!==t?(r.charCodeAt(j)===58?(Xe=p,j++):(Xe=t,$e===0&&Oe(m)),Xe!==t?(Et=Tr(),Et===t&&(Et=null),Et!==t?(Rt=xa(),Rt!==t?(wt=R,G=T(Ce,He,Rt),R=G):(j=R,R=t)):(j=R,R=t)):(j=R,R=t)):(j=R,R=t)):(j=R,R=t)}else j=R,R=t;else j=R,R=t}return R}function xa(){var R,G,Ce,He,Te,Xe,Et;if(R=j,G=j,$e++,Ce=j,He=ro(),He!==t?(Te=nt(),Te!==t?(r.charCodeAt(j)===45?(Xe=o,j++):(Xe=t,$e===0&&Oe(a)),Xe!==t?(Et=Tr(),Et!==t?(He=[He,Te,Xe,Et],Ce=He):(j=Ce,Ce=t)):(j=Ce,Ce=t)):(j=Ce,Ce=t)):(j=Ce,Ce=t),$e--,Ce!==t?(j=G,G=void 0):G=t,G!==t?(Ce=to(),Ce!==t?(He=Do(),He!==t?(Te=ec(),Te!==t?(Xe=OA(),Xe!==t?(wt=R,G=q(Te),R=G):(j=R,R=t)):(j=R,R=t)):(j=R,R=t)):(j=R,R=t)):(j=R,R=t),R===t&&(R=j,G=ro(),G!==t?(Ce=Do(),Ce!==t?(He=ju(),He!==t?(Te=OA(),Te!==t?(wt=R,G=q(He),R=G):(j=R,R=t)):(j=R,R=t)):(j=R,R=t)):(j=R,R=t),R===t))if(R=j,G=rc(),G!==t){if(Ce=[],He=to(),He!==t)for(;He!==t;)Ce.push(He),He=to();else Ce=t;Ce!==t?(wt=R,G=Y(G),R=G):(j=R,R=t)}else j=R,R=t;return R}function ka(){var R,G,Ce;for($e++,R=j,G=[],r.charCodeAt(j)===32?(Ce=_,j++):(Ce=t,$e===0&&Oe(ne));Ce!==t;)G.push(Ce),r.charCodeAt(j)===32?(Ce=_,j++):(Ce=t,$e===0&&Oe(ne));return G!==t?(wt=j,Ce=ee(G),Ce?Ce=void 0:Ce=t,Ce!==t?(G=[G,Ce],R=G):(j=R,R=t)):(j=R,R=t),$e--,R===t&&(G=t,$e===0&&Oe($)),R}function nt(){var R,G,Ce;for(R=j,G=[],r.charCodeAt(j)===32?(Ce=_,j++):(Ce=t,$e===0&&Oe(ne));Ce!==t;)G.push(Ce),r.charCodeAt(j)===32?(Ce=_,j++):(Ce=t,$e===0&&Oe(ne));return G!==t?(wt=j,Ce=A(G),Ce?Ce=void 0:Ce=t,Ce!==t?(G=[G,Ce],R=G):(j=R,R=t)):(j=R,R=t),R}function Do(){var R;return wt=j,R=oe(),R?R=void 0:R=t,R}function OA(){var R;return wt=j,R=ce(),R?R=void 0:R=t,R}function tc(){var R;return R=ic(),R===t&&(R=Lh()),R}function eo(){var R,G,Ce;if(R=ic(),R===t){if(R=j,G=[],Ce=Yu(),Ce!==t)for(;Ce!==t;)G.push(Ce),Ce=Yu();else G=t;G!==t&&(wt=R,G=Z()),R=G}return R}function rc(){var R;return R=Th(),R===t&&(R=bE(),R===t&&(R=ic(),R===t&&(R=Lh()))),R}function BE(){var R;return R=Th(),R===t&&(R=ic(),R===t&&(R=Yu())),R}function Lh(){var R,G,Ce,He,Te,Xe;if($e++,R=j,L.test(r.charAt(j))?(G=r.charAt(j),j++):(G=t,$e===0&&Oe(de)),G!==t){for(Ce=[],He=j,Te=Tr(),Te===t&&(Te=null),Te!==t?(Be.test(r.charAt(j))?(Xe=r.charAt(j),j++):(Xe=t,$e===0&&Oe(je)),Xe!==t?(Te=[Te,Xe],He=Te):(j=He,He=t)):(j=He,He=t);He!==t;)Ce.push(He),He=j,Te=Tr(),Te===t&&(Te=null),Te!==t?(Be.test(r.charAt(j))?(Xe=r.charAt(j),j++):(Xe=t,$e===0&&Oe(je)),Xe!==t?(Te=[Te,Xe],He=Te):(j=He,He=t)):(j=He,He=t);Ce!==t?(wt=R,G=re(),R=G):(j=R,R=t)}else j=R,R=t;return $e--,R===t&&(G=t,$e===0&&Oe(O)),R}function Yu(){var R,G,Ce,He,Te;if(R=j,r.substr(j,2)===se?(G=se,j+=2):(G=t,$e===0&&Oe(be)),G===t&&(G=null),G!==t)if(he.test(r.charAt(j))?(Ce=r.charAt(j),j++):(Ce=t,$e===0&&Oe(Fe)),Ce!==t){for(He=[],Ke.test(r.charAt(j))?(Te=r.charAt(j),j++):(Te=t,$e===0&&Oe(ke));Te!==t;)He.push(Te),Ke.test(r.charAt(j))?(Te=r.charAt(j),j++):(Te=t,$e===0&&Oe(ke));He!==t?(wt=R,G=re(),R=G):(j=R,R=t)}else j=R,R=t;else j=R,R=t;return R}function Th(){var R,G;return R=j,r.substr(j,4)===ve?(G=ve,j+=4):(G=t,$e===0&&Oe(pe)),G!==t&&(wt=R,G=V()),R=G,R}function bE(){var R,G;return R=j,r.substr(j,4)===Qe?(G=Qe,j+=4):(G=t,$e===0&&Oe(le)),G!==t&&(wt=R,G=fe()),R=G,R===t&&(R=j,r.substr(j,5)===gt?(G=gt,j+=5):(G=t,$e===0&&Oe(Ht)),G!==t&&(wt=R,G=Mt()),R=G),R}function ic(){var R,G,Ce,He;return $e++,R=j,r.charCodeAt(j)===34?(G=jt,j++):(G=t,$e===0&&Oe(Qr)),G!==t?(r.charCodeAt(j)===34?(Ce=jt,j++):(Ce=t,$e===0&&Oe(Qr)),Ce!==t?(wt=R,G=Oi(),R=G):(j=R,R=t)):(j=R,R=t),R===t&&(R=j,r.charCodeAt(j)===34?(G=jt,j++):(G=t,$e===0&&Oe(Qr)),G!==t?(Ce=QE(),Ce!==t?(r.charCodeAt(j)===34?(He=jt,j++):(He=t,$e===0&&Oe(Qr)),He!==t?(wt=R,G=Xs(Ce),R=G):(j=R,R=t)):(j=R,R=t)):(j=R,R=t)),$e--,R===t&&(G=t,$e===0&&Oe(Ei)),R}function QE(){var R,G,Ce;if(R=j,G=[],Ce=qu(),Ce!==t)for(;Ce!==t;)G.push(Ce),Ce=qu();else G=t;return G!==t&&(wt=R,G=Un(G)),R=G,R}function qu(){var R,G,Ce,He,Te,Xe;return Hn.test(r.charAt(j))?(R=r.charAt(j),j++):(R=t,$e===0&&Oe(Sr)),R===t&&(R=j,r.substr(j,2)===jn?(G=jn,j+=2):(G=t,$e===0&&Oe(fs)),G!==t&&(wt=R,G=ba()),R=G,R===t&&(R=j,r.substr(j,2)===DA?(G=DA,j+=2):(G=t,$e===0&&Oe(Nu)),G!==t&&(wt=R,G=hs()),R=G,R===t&&(R=j,r.substr(j,2)===RA?(G=RA,j+=2):(G=t,$e===0&&Oe(Qa)),G!==t&&(wt=R,G=Lu()),R=G,R===t&&(R=j,r.substr(j,2)===FA?(G=FA,j+=2):(G=t,$e===0&&Oe(NA)),G!==t&&(wt=R,G=vr()),R=G,R===t&&(R=j,r.substr(j,2)===zl?(G=zl,j+=2):(G=t,$e===0&&Oe(Tu)),G!==t&&(wt=R,G=xo()),R=G,R===t&&(R=j,r.substr(j,2)===Ou?(G=Ou,j+=2):(G=t,$e===0&&Oe(Sh)),G!==t&&(wt=R,G=vh()),R=G,R===t&&(R=j,r.substr(j,2)===Dr?(G=Dr,j+=2):(G=t,$e===0&&Oe(Ae)),G!==t&&(wt=R,G=ko()),R=G,R===t&&(R=j,r.substr(j,2)===Gn?(G=Gn,j+=2):(G=t,$e===0&&Oe(Mu)),G!==t&&(wt=R,G=St()),R=G,R===t&&(R=j,r.substr(j,2)===_l?(G=_l,j+=2):(G=t,$e===0&&Oe(Yn)),G!==t?(Ce=MA(),Ce!==t?(He=MA(),He!==t?(Te=MA(),Te!==t?(Xe=MA(),Xe!==t?(wt=R,G=ps(Ce,He,Te,Xe),R=G):(j=R,R=t)):(j=R,R=t)):(j=R,R=t)):(j=R,R=t)):(j=R,R=t)))))))))),R}function MA(){var R;return ds.test(r.charAt(j))?(R=r.charAt(j),j++):(R=t,$e===0&&Oe(pt)),R}function Tr(){var R,G;if($e++,R=[],lt.test(r.charAt(j))?(G=r.charAt(j),j++):(G=t,$e===0&&Oe(mn)),G!==t)for(;G!==t;)R.push(G),lt.test(r.charAt(j))?(G=r.charAt(j),j++):(G=t,$e===0&&Oe(mn));else R=t;return $e--,R===t&&(G=t,$e===0&&Oe(Po)),R}function SE(){var R,G;if($e++,R=[],Tt.test(r.charAt(j))?(G=r.charAt(j),j++):(G=t,$e===0&&Oe(Ku)),G!==t)for(;G!==t;)R.push(G),Tt.test(r.charAt(j))?(G=r.charAt(j),j++):(G=t,$e===0&&Oe(Ku));else R=t;return $e--,R===t&&(G=t,$e===0&&Oe(S)),R}function to(){var R,G,Ce,He,Te,Xe;if(R=j,G=ro(),G!==t){for(Ce=[],He=j,Te=Tr(),Te===t&&(Te=null),Te!==t?(Xe=ro(),Xe!==t?(Te=[Te,Xe],He=Te):(j=He,He=t)):(j=He,He=t);He!==t;)Ce.push(He),He=j,Te=Tr(),Te===t&&(Te=null),Te!==t?(Xe=ro(),Xe!==t?(Te=[Te,Xe],He=Te):(j=He,He=t)):(j=He,He=t);Ce!==t?(G=[G,Ce],R=G):(j=R,R=t)}else j=R,R=t;return R}function ro(){var R;return r.substr(j,2)===Vl?(R=Vl,j+=2):(R=t,$e===0&&Oe(xh)),R===t&&(r.charCodeAt(j)===10?(R=kh,j++):(R=t,$e===0&&Oe(Ph)),R===t&&(r.charCodeAt(j)===13?(R=Dh,j++):(R=t,$e===0&&Oe(Rh)))),R}let Ju=2,KA=0;if(Sa=n(),Sa!==t&&j===r.length)return Sa;throw Sa!==t&&j{"use strict";var Upe=r=>{let e=!1,t=!1,i=!1;for(let n=0;n{if(!(typeof r=="string"||Array.isArray(r)))throw new TypeError("Expected the input to be `string | string[]`");e=Object.assign({pascalCase:!1},e);let t=n=>e.pascalCase?n.charAt(0).toUpperCase()+n.slice(1):n;return Array.isArray(r)?r=r.map(n=>n.trim()).filter(n=>n.length).join("-"):r=r.trim(),r.length===0?"":r.length===1?e.pascalCase?r.toUpperCase():r.toLowerCase():(r!==r.toLowerCase()&&(r=Upe(r)),r=r.replace(/^[_.\- ]+/,"").toLowerCase().replace(/[_.\- ]+(\w|$)/g,(n,s)=>s.toUpperCase()).replace(/\d+(\w|$)/g,n=>n.toUpperCase()),t(r))};JQ.exports=_K;JQ.exports.default=_K});var ZK=w((pXe,XK)=>{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 Ic=w(Xn=>{"use strict";var $K=ZK(),To=process.env;Object.defineProperty(Xn,"_vendors",{value:$K.map(function(r){return r.constant})});Xn.name=null;Xn.isPR=null;$K.forEach(function(r){let t=(Array.isArray(r.env)?r.env:[r.env]).every(function(i){return eU(i)});if(Xn[r.constant]=t,t)switch(Xn.name=r.name,typeof r.pr){case"string":Xn.isPR=!!To[r.pr];break;case"object":"env"in r.pr?Xn.isPR=r.pr.env in To&&To[r.pr.env]!==r.pr.ne:"any"in r.pr?Xn.isPR=r.pr.any.some(function(i){return!!To[i]}):Xn.isPR=eU(r.pr);break;default:Xn.isPR=null}});Xn.isCI=!!(To.CI||To.CONTINUOUS_INTEGRATION||To.BUILD_NUMBER||To.RUN_ID||Xn.name);function eU(r){return typeof r=="string"?!!To[r]:Object.keys(r).every(function(e){return To[e]===r[e]})}});var cg={};ft(cg,{KeyRelationship:()=>Bc,applyCascade:()=>fp,base64RegExp:()=>sU,colorStringAlphaRegExp:()=>nU,colorStringRegExp:()=>iU,computeKey:()=>zA,getPrintable:()=>ti,hasExactLength:()=>cU,hasForbiddenKeys:()=>mde,hasKeyRelationship:()=>eS,hasMaxLength:()=>tde,hasMinLength:()=>ede,hasMutuallyExclusiveKeys:()=>Ede,hasRequiredKeys:()=>Cde,hasUniqueItems:()=>rde,isArray:()=>Jpe,isAtLeast:()=>sde,isAtMost:()=>ode,isBase64:()=>pde,isBoolean:()=>Gpe,isDate:()=>qpe,isDict:()=>zpe,isEnum:()=>nn,isHexColor:()=>hde,isISO8601:()=>fde,isInExclusiveRange:()=>Ade,isInInclusiveRange:()=>ade,isInstanceOf:()=>Vpe,isInteger:()=>lde,isJSON:()=>dde,isLiteral:()=>Hpe,isLowerCase:()=>cde,isNegative:()=>ide,isNullable:()=>$pe,isNumber:()=>Ype,isObject:()=>_pe,isOneOf:()=>Xpe,isOptional:()=>Zpe,isPositive:()=>nde,isString:()=>gp,isTuple:()=>Wpe,isUUID4:()=>gde,isUnknown:()=>lU,isUpperCase:()=>ude,iso8601RegExp:()=>$Q,makeCoercionFn:()=>wc,makeSetter:()=>AU,makeTrait:()=>aU,makeValidator:()=>vt,matchesRegExp:()=>hp,plural:()=>hI,pushError:()=>mt,simpleKeyRegExp:()=>rU,uuid4RegExp:()=>oU});function vt({test:r}){return aU(r)()}function ti(r){return r===null?"null":r===void 0?"undefined":r===""?"an empty string":JSON.stringify(r)}function zA(r,e){var t,i,n;return typeof e=="number"?`${(t=r==null?void 0:r.p)!==null&&t!==void 0?t:"."}[${e}]`:rU.test(e)?`${(i=r==null?void 0:r.p)!==null&&i!==void 0?i:""}.${e}`:`${(n=r==null?void 0:r.p)!==null&&n!==void 0?n:"."}[${JSON.stringify(e)}]`}function wc(r,e){return t=>{let i=r[e];return r[e]=t,wc(r,e).bind(null,i)}}function AU(r,e){return t=>{r[e]=t}}function hI(r,e,t){return r===1?e:t}function mt({errors:r,p:e}={},t){return r==null||r.push(`${e!=null?e:"."}: ${t}`),!1}function Hpe(r){return vt({test:(e,t)=>e!==r?mt(t,`Expected a literal (got ${ti(r)})`):!0})}function nn(r){let e=Array.isArray(r)?r:Object.values(r),t=new Set(e);return vt({test:(i,n)=>t.has(i)?!0:mt(n,`Expected a valid enumeration value (got ${ti(i)})`)})}var rU,iU,nU,sU,oU,$Q,aU,lU,gp,jpe,Gpe,Ype,qpe,Jpe,Wpe,zpe,_pe,Vpe,Xpe,fp,Zpe,$pe,ede,tde,cU,rde,ide,nde,sde,ode,ade,Ade,lde,hp,cde,ude,gde,fde,hde,pde,dde,Cde,mde,Ede,Bc,Ide,eS,ys=uge(()=>{rU=/^[a-zA-Z_][a-zA-Z0-9_]*$/,iU=/^#[0-9a-f]{6}$/i,nU=/^#[0-9a-f]{6}([0-9a-f]{2})?$/i,sU=/^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/,oU=/^[a-f0-9]{8}-[a-f0-9]{4}-4[a-f0-9]{3}-[89aAbB][a-f0-9]{3}-[a-f0-9]{12}$/i,$Q=/^(?:[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)?)$/,aU=r=>()=>r;lU=()=>vt({test:(r,e)=>!0});gp=()=>vt({test:(r,e)=>typeof r!="string"?mt(e,`Expected a string (got ${ti(r)})`):!0});jpe=new Map([["true",!0],["True",!0],["1",!0],[1,!0],["false",!1],["False",!1],["0",!1],[0,!1]]),Gpe=()=>vt({test:(r,e)=>{var t;if(typeof r!="boolean"){if(typeof(e==null?void 0:e.coercions)!="undefined"){if(typeof(e==null?void 0:e.coercion)=="undefined")return mt(e,"Unbound coercion result");let i=jpe.get(r);if(typeof i!="undefined")return e.coercions.push([(t=e.p)!==null&&t!==void 0?t:".",e.coercion.bind(null,i)]),!0}return mt(e,`Expected a boolean (got ${ti(r)})`)}return!0}}),Ype=()=>vt({test:(r,e)=>{var t;if(typeof r!="number"){if(typeof(e==null?void 0:e.coercions)!="undefined"){if(typeof(e==null?void 0:e.coercion)=="undefined")return mt(e,"Unbound coercion result");let i;if(typeof r=="string"){let n;try{n=JSON.parse(r)}catch(s){}if(typeof n=="number")if(JSON.stringify(n)===r)i=n;else return mt(e,`Received a number that can't be safely represented by the runtime (${r})`)}if(typeof i!="undefined")return e.coercions.push([(t=e.p)!==null&&t!==void 0?t:".",e.coercion.bind(null,i)]),!0}return mt(e,`Expected a number (got ${ti(r)})`)}return!0}}),qpe=()=>vt({test:(r,e)=>{var t;if(!(r instanceof Date)){if(typeof(e==null?void 0:e.coercions)!="undefined"){if(typeof(e==null?void 0:e.coercion)=="undefined")return mt(e,"Unbound coercion result");let i;if(typeof r=="string"&&$Q.test(r))i=new Date(r);else{let n;if(typeof r=="string"){let s;try{s=JSON.parse(r)}catch(o){}typeof s=="number"&&(n=s)}else typeof r=="number"&&(n=r);if(typeof n!="undefined")if(Number.isSafeInteger(n)||!Number.isSafeInteger(n*1e3))i=new Date(n*1e3);else return mt(e,`Received a timestamp that can't be safely represented by the runtime (${r})`)}if(typeof i!="undefined")return e.coercions.push([(t=e.p)!==null&&t!==void 0?t:".",e.coercion.bind(null,i)]),!0}return mt(e,`Expected a date (got ${ti(r)})`)}return!0}}),Jpe=(r,{delimiter:e}={})=>vt({test:(t,i)=>{var n;if(typeof t=="string"&&typeof e!="undefined"&&typeof(i==null?void 0:i.coercions)!="undefined"){if(typeof(i==null?void 0:i.coercion)=="undefined")return mt(i,"Unbound coercion result");t=t.split(e),i.coercions.push([(n=i.p)!==null&&n!==void 0?n:".",i.coercion.bind(null,t)])}if(!Array.isArray(t))return mt(i,`Expected an array (got ${ti(t)})`);let s=!0;for(let o=0,a=t.length;o{let t=cU(r.length);return vt({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 mt(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 mt(n,`Expected a tuple (got ${ti(i)})`);let o=t(i,Object.assign({},n));for(let a=0,l=i.length;avt({test:(t,i)=>{if(typeof t!="object"||t===null)return mt(i,`Expected an object (got ${ti(t)})`);let n=Object.keys(t),s=!0;for(let o=0,a=n.length;o{let t=Object.keys(r);return vt({test:(i,n)=>{if(typeof i!="object"||i===null)return mt(n,`Expected an object (got ${ti(i)})`);let s=new Set([...t,...Object.keys(i)]),o={},a=!0;for(let l of s){if(l==="constructor"||l==="__proto__")a=mt(Object.assign(Object.assign({},n),{p:zA(n,l)}),"Unsafe property name");else{let c=Object.prototype.hasOwnProperty.call(r,l)?r[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:zA(n,l),coercion:wc(i,l)}))&&a:e===null?a=mt(Object.assign(Object.assign({},n),{p:zA(n,l)}),`Extraneous property (got ${ti(u)})`):Object.defineProperty(o,l,{enumerable:!0,get:()=>u,set:AU(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}})},Vpe=r=>vt({test:(e,t)=>e instanceof r?!0:mt(t,`Expected an instance of ${r.name} (got ${ti(e)})`)}),Xpe=(r,{exclusive:e=!1}={})=>vt({test:(t,i)=>{var n,s,o;let a=[],l=typeof(i==null?void 0:i.errors)!="undefined"?[]:void 0;for(let c=0,u=r.length;c1?mt(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}}),fp=(r,e)=>vt({test:(t,i)=>{var n,s;let o={value:t},a=typeof(i==null?void 0:i.coercions)!="undefined"?wc(o,"value"):void 0,l=typeof(i==null?void 0:i.coercions)!="undefined"?[]:void 0;if(!r(t,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!==t){if(typeof(i==null?void 0:i.coercion)=="undefined")return mt(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()}}}),Zpe=r=>vt({test:(e,t)=>typeof e=="undefined"?!0:r(e,t)}),$pe=r=>vt({test:(e,t)=>e===null?!0:r(e,t)}),ede=r=>vt({test:(e,t)=>e.length>=r?!0:mt(t,`Expected to have a length of at least ${r} elements (got ${e.length})`)}),tde=r=>vt({test:(e,t)=>e.length<=r?!0:mt(t,`Expected to have a length of at most ${r} elements (got ${e.length})`)}),cU=r=>vt({test:(e,t)=>e.length!==r?mt(t,`Expected to have a length of exactly ${r} elements (got ${e.length})`):!0}),rde=({map:r}={})=>vt({test:(e,t)=>{let i=new Set,n=new Set;for(let s=0,o=e.length;svt({test:(r,e)=>r<=0?!0:mt(e,`Expected to be negative (got ${r})`)}),nde=()=>vt({test:(r,e)=>r>=0?!0:mt(e,`Expected to be positive (got ${r})`)}),sde=r=>vt({test:(e,t)=>e>=r?!0:mt(t,`Expected to be at least ${r} (got ${e})`)}),ode=r=>vt({test:(e,t)=>e<=r?!0:mt(t,`Expected to be at most ${r} (got ${e})`)}),ade=(r,e)=>vt({test:(t,i)=>t>=r&&t<=e?!0:mt(i,`Expected to be in the [${r}; ${e}] range (got ${t})`)}),Ade=(r,e)=>vt({test:(t,i)=>t>=r&&tvt({test:(e,t)=>e!==Math.round(e)?mt(t,`Expected to be an integer (got ${e})`):Number.isSafeInteger(e)?!0:mt(t,`Expected to be a safe integer (got ${e})`)}),hp=r=>vt({test:(e,t)=>r.test(e)?!0:mt(t,`Expected to match the pattern ${r.toString()} (got ${ti(e)})`)}),cde=()=>vt({test:(r,e)=>r!==r.toLowerCase()?mt(e,`Expected to be all-lowercase (got ${r})`):!0}),ude=()=>vt({test:(r,e)=>r!==r.toUpperCase()?mt(e,`Expected to be all-uppercase (got ${r})`):!0}),gde=()=>vt({test:(r,e)=>oU.test(r)?!0:mt(e,`Expected to be a valid UUID v4 (got ${ti(r)})`)}),fde=()=>vt({test:(r,e)=>$Q.test(r)?!1:mt(e,`Expected to be a valid ISO 8601 date string (got ${ti(r)})`)}),hde=({alpha:r=!1})=>vt({test:(e,t)=>(r?iU.test(e):nU.test(e))?!0:mt(t,`Expected to be a valid hexadecimal color string (got ${ti(e)})`)}),pde=()=>vt({test:(r,e)=>sU.test(r)?!0:mt(e,`Expected to be a valid base 64 string (got ${ti(r)})`)}),dde=(r=lU())=>vt({test:(e,t)=>{let i;try{i=JSON.parse(e)}catch(n){return mt(t,`Expected to be a valid JSON string (got ${ti(e)})`)}return r(i,t)}}),Cde=r=>{let e=new Set(r);return vt({test:(t,i)=>{let n=new Set(Object.keys(t)),s=[];for(let o of e)n.has(o)||s.push(o);return s.length>0?mt(i,`Missing required ${hI(s.length,"property","properties")} ${s.map(o=>`"${o}"`).join(", ")}`):!0}})},mde=r=>{let e=new Set(r);return vt({test:(t,i)=>{let n=new Set(Object.keys(t)),s=[];for(let o of e)n.has(o)&&s.push(o);return s.length>0?mt(i,`Forbidden ${hI(s.length,"property","properties")} ${s.map(o=>`"${o}"`).join(", ")}`):!0}})},Ede=r=>{let e=new Set(r);return vt({test:(t,i)=>{let n=new Set(Object.keys(t)),s=[];for(let o of e)n.has(o)&&s.push(o);return s.length>1?mt(i,`Mutually exclusive properties ${s.map(o=>`"${o}"`).join(", ")}`):!0}})};(function(r){r.Forbids="Forbids",r.Requires="Requires"})(Bc||(Bc={}));Ide={[Bc.Forbids]:{expect:!1,message:"forbids using"},[Bc.Requires]:{expect:!0,message:"requires using"}},eS=(r,e,t,{ignore:i=[]}={})=>{let n=new Set(i),s=new Set(t),o=Ide[e];return vt({test:(a,l)=>{let c=new Set(Object.keys(a));if(!c.has(r)||n.has(a[r]))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?mt(l,`Property "${r}" ${o.message} ${hI(u.length,"property","properties")} ${u.map(g=>`"${g}"`).join(", ")}`):!0}})}});var kU=w((dZe,xU)=>{"use strict";xU.exports=(r,...e)=>new Promise(t=>{t(r(...e))})});var gg=w((CZe,aS)=>{"use strict";var Ode=kU(),PU=r=>{if(r<1)throw new TypeError("Expected `concurrency` to be a number from 1 and up");let e=[],t=0,i=()=>{t--,e.length>0&&e.shift()()},n=(a,l,...c)=>{t++;let u=Ode(a,...c);l(u),u.then(i,i)},s=(a,l,...c)=>{tnew Promise(c=>s(a,c,...l));return Object.defineProperties(o,{activeCount:{get:()=>t},pendingCount:{get:()=>e.length}}),o};aS.exports=PU;aS.exports.default=PU});var mp=w((EZe,DU)=>{var Mde="2.0.0",Kde=256,Ude=Number.MAX_SAFE_INTEGER||9007199254740991,Hde=16;DU.exports={SEMVER_SPEC_VERSION:Mde,MAX_LENGTH:Kde,MAX_SAFE_INTEGER:Ude,MAX_SAFE_COMPONENT_LENGTH:Hde}});var Ep=w((IZe,RU)=>{var jde=typeof process=="object"&&process.env&&process.env.NODE_DEBUG&&/\bsemver\b/i.test(process.env.NODE_DEBUG)?(...r)=>console.error("SEMVER",...r):()=>{};RU.exports=jde});var bc=w((VA,FU)=>{var{MAX_SAFE_COMPONENT_LENGTH:AS}=mp(),Gde=Ep();VA=FU.exports={};var Yde=VA.re=[],rt=VA.src=[],it=VA.t={},qde=0,xt=(r,e,t)=>{let i=qde++;Gde(i,e),it[r]=i,rt[i]=e,Yde[i]=new RegExp(e,t?"g":void 0)};xt("NUMERICIDENTIFIER","0|[1-9]\\d*");xt("NUMERICIDENTIFIERLOOSE","[0-9]+");xt("NONNUMERICIDENTIFIER","\\d*[a-zA-Z-][a-zA-Z0-9-]*");xt("MAINVERSION",`(${rt[it.NUMERICIDENTIFIER]})\\.(${rt[it.NUMERICIDENTIFIER]})\\.(${rt[it.NUMERICIDENTIFIER]})`);xt("MAINVERSIONLOOSE",`(${rt[it.NUMERICIDENTIFIERLOOSE]})\\.(${rt[it.NUMERICIDENTIFIERLOOSE]})\\.(${rt[it.NUMERICIDENTIFIERLOOSE]})`);xt("PRERELEASEIDENTIFIER",`(?:${rt[it.NUMERICIDENTIFIER]}|${rt[it.NONNUMERICIDENTIFIER]})`);xt("PRERELEASEIDENTIFIERLOOSE",`(?:${rt[it.NUMERICIDENTIFIERLOOSE]}|${rt[it.NONNUMERICIDENTIFIER]})`);xt("PRERELEASE",`(?:-(${rt[it.PRERELEASEIDENTIFIER]}(?:\\.${rt[it.PRERELEASEIDENTIFIER]})*))`);xt("PRERELEASELOOSE",`(?:-?(${rt[it.PRERELEASEIDENTIFIERLOOSE]}(?:\\.${rt[it.PRERELEASEIDENTIFIERLOOSE]})*))`);xt("BUILDIDENTIFIER","[0-9A-Za-z-]+");xt("BUILD",`(?:\\+(${rt[it.BUILDIDENTIFIER]}(?:\\.${rt[it.BUILDIDENTIFIER]})*))`);xt("FULLPLAIN",`v?${rt[it.MAINVERSION]}${rt[it.PRERELEASE]}?${rt[it.BUILD]}?`);xt("FULL",`^${rt[it.FULLPLAIN]}$`);xt("LOOSEPLAIN",`[v=\\s]*${rt[it.MAINVERSIONLOOSE]}${rt[it.PRERELEASELOOSE]}?${rt[it.BUILD]}?`);xt("LOOSE",`^${rt[it.LOOSEPLAIN]}$`);xt("GTLT","((?:<|>)?=?)");xt("XRANGEIDENTIFIERLOOSE",`${rt[it.NUMERICIDENTIFIERLOOSE]}|x|X|\\*`);xt("XRANGEIDENTIFIER",`${rt[it.NUMERICIDENTIFIER]}|x|X|\\*`);xt("XRANGEPLAIN",`[v=\\s]*(${rt[it.XRANGEIDENTIFIER]})(?:\\.(${rt[it.XRANGEIDENTIFIER]})(?:\\.(${rt[it.XRANGEIDENTIFIER]})(?:${rt[it.PRERELEASE]})?${rt[it.BUILD]}?)?)?`);xt("XRANGEPLAINLOOSE",`[v=\\s]*(${rt[it.XRANGEIDENTIFIERLOOSE]})(?:\\.(${rt[it.XRANGEIDENTIFIERLOOSE]})(?:\\.(${rt[it.XRANGEIDENTIFIERLOOSE]})(?:${rt[it.PRERELEASELOOSE]})?${rt[it.BUILD]}?)?)?`);xt("XRANGE",`^${rt[it.GTLT]}\\s*${rt[it.XRANGEPLAIN]}$`);xt("XRANGELOOSE",`^${rt[it.GTLT]}\\s*${rt[it.XRANGEPLAINLOOSE]}$`);xt("COERCE",`(^|[^\\d])(\\d{1,${AS}})(?:\\.(\\d{1,${AS}}))?(?:\\.(\\d{1,${AS}}))?(?:$|[^\\d])`);xt("COERCERTL",rt[it.COERCE],!0);xt("LONETILDE","(?:~>?)");xt("TILDETRIM",`(\\s*)${rt[it.LONETILDE]}\\s+`,!0);VA.tildeTrimReplace="$1~";xt("TILDE",`^${rt[it.LONETILDE]}${rt[it.XRANGEPLAIN]}$`);xt("TILDELOOSE",`^${rt[it.LONETILDE]}${rt[it.XRANGEPLAINLOOSE]}$`);xt("LONECARET","(?:\\^)");xt("CARETTRIM",`(\\s*)${rt[it.LONECARET]}\\s+`,!0);VA.caretTrimReplace="$1^";xt("CARET",`^${rt[it.LONECARET]}${rt[it.XRANGEPLAIN]}$`);xt("CARETLOOSE",`^${rt[it.LONECARET]}${rt[it.XRANGEPLAINLOOSE]}$`);xt("COMPARATORLOOSE",`^${rt[it.GTLT]}\\s*(${rt[it.LOOSEPLAIN]})$|^$`);xt("COMPARATOR",`^${rt[it.GTLT]}\\s*(${rt[it.FULLPLAIN]})$|^$`);xt("COMPARATORTRIM",`(\\s*)${rt[it.GTLT]}\\s*(${rt[it.LOOSEPLAIN]}|${rt[it.XRANGEPLAIN]})`,!0);VA.comparatorTrimReplace="$1$2$3";xt("HYPHENRANGE",`^\\s*(${rt[it.XRANGEPLAIN]})\\s+-\\s+(${rt[it.XRANGEPLAIN]})\\s*$`);xt("HYPHENRANGELOOSE",`^\\s*(${rt[it.XRANGEPLAINLOOSE]})\\s+-\\s+(${rt[it.XRANGEPLAINLOOSE]})\\s*$`);xt("STAR","(<|>)?=?\\s*\\*");xt("GTE0","^\\s*>=\\s*0.0.0\\s*$");xt("GTE0PRE","^\\s*>=\\s*0.0.0-0\\s*$")});var Ip=w((yZe,NU)=>{var Jde=["includePrerelease","loose","rtl"],Wde=r=>r?typeof r!="object"?{loose:!0}:Jde.filter(e=>r[e]).reduce((e,t)=>(e[t]=!0,e),{}):{};NU.exports=Wde});var yI=w((wZe,LU)=>{var TU=/^[0-9]+$/,OU=(r,e)=>{let t=TU.test(r),i=TU.test(e);return t&&i&&(r=+r,e=+e),r===e?0:t&&!i?-1:i&&!t?1:rOU(e,r);LU.exports={compareIdentifiers:OU,rcompareIdentifiers:zde}});var Hi=w((BZe,MU)=>{var wI=Ep(),{MAX_LENGTH:KU,MAX_SAFE_INTEGER:BI}=mp(),{re:UU,t:HU}=bc(),_de=Ip(),{compareIdentifiers:yp}=yI(),Bs=class{constructor(e,t){if(t=_de(t),e instanceof Bs){if(e.loose===!!t.loose&&e.includePrerelease===!!t.includePrerelease)return e;e=e.version}else if(typeof e!="string")throw new TypeError(`Invalid Version: ${e}`);if(e.length>KU)throw new TypeError(`version is longer than ${KU} characters`);wI("SemVer",e,t),this.options=t,this.loose=!!t.loose,this.includePrerelease=!!t.includePrerelease;let i=e.trim().match(t.loose?UU[HU.LOOSE]:UU[HU.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>BI||this.major<0)throw new TypeError("Invalid major version");if(this.minor>BI||this.minor<0)throw new TypeError("Invalid minor version");if(this.patch>BI||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=0;)typeof this.prerelease[i]=="number"&&(this.prerelease[i]++,i=-2);i===-1&&this.prerelease.push(0)}t&&(this.prerelease[0]===t?isNaN(this.prerelease[1])&&(this.prerelease=[t,0]):this.prerelease=[t,0]);break;default:throw new Error(`invalid increment argument: ${e}`)}return this.format(),this.raw=this.version,this}};MU.exports=Bs});var Qc=w((bZe,jU)=>{var{MAX_LENGTH:Vde}=mp(),{re:GU,t:YU}=bc(),qU=Hi(),Xde=Ip(),Zde=(r,e)=>{if(e=Xde(e),r instanceof qU)return r;if(typeof r!="string"||r.length>Vde||!(e.loose?GU[YU.LOOSE]:GU[YU.FULL]).test(r))return null;try{return new qU(r,e)}catch(i){return null}};jU.exports=Zde});var WU=w((QZe,JU)=>{var $de=Qc(),eCe=(r,e)=>{let t=$de(r,e);return t?t.version:null};JU.exports=eCe});var _U=w((SZe,zU)=>{var tCe=Qc(),rCe=(r,e)=>{let t=tCe(r.trim().replace(/^[=v]+/,""),e);return t?t.version:null};zU.exports=rCe});var XU=w((vZe,VU)=>{var iCe=Hi(),nCe=(r,e,t,i)=>{typeof t=="string"&&(i=t,t=void 0);try{return new iCe(r,t).inc(e,i).version}catch(n){return null}};VU.exports=nCe});var bs=w((xZe,ZU)=>{var $U=Hi(),sCe=(r,e,t)=>new $U(r,t).compare(new $U(e,t));ZU.exports=sCe});var bI=w((kZe,e2)=>{var oCe=bs(),aCe=(r,e,t)=>oCe(r,e,t)===0;e2.exports=aCe});var i2=w((PZe,t2)=>{var r2=Qc(),ACe=bI(),lCe=(r,e)=>{if(ACe(r,e))return null;{let t=r2(r),i=r2(e),n=t.prerelease.length||i.prerelease.length,s=n?"pre":"",o=n?"prerelease":"";for(let a in t)if((a==="major"||a==="minor"||a==="patch")&&t[a]!==i[a])return s+a;return o}};t2.exports=lCe});var s2=w((DZe,n2)=>{var cCe=Hi(),uCe=(r,e)=>new cCe(r,e).major;n2.exports=uCe});var a2=w((RZe,o2)=>{var gCe=Hi(),fCe=(r,e)=>new gCe(r,e).minor;o2.exports=fCe});var l2=w((FZe,A2)=>{var hCe=Hi(),pCe=(r,e)=>new hCe(r,e).patch;A2.exports=pCe});var u2=w((NZe,c2)=>{var dCe=Qc(),CCe=(r,e)=>{let t=dCe(r,e);return t&&t.prerelease.length?t.prerelease:null};c2.exports=CCe});var f2=w((LZe,g2)=>{var mCe=bs(),ECe=(r,e,t)=>mCe(e,r,t);g2.exports=ECe});var p2=w((TZe,h2)=>{var ICe=bs(),yCe=(r,e)=>ICe(r,e,!0);h2.exports=yCe});var QI=w((OZe,d2)=>{var C2=Hi(),wCe=(r,e,t)=>{let i=new C2(r,t),n=new C2(e,t);return i.compare(n)||i.compareBuild(n)};d2.exports=wCe});var E2=w((MZe,m2)=>{var BCe=QI(),bCe=(r,e)=>r.sort((t,i)=>BCe(t,i,e));m2.exports=bCe});var y2=w((KZe,I2)=>{var QCe=QI(),SCe=(r,e)=>r.sort((t,i)=>QCe(i,t,e));I2.exports=SCe});var wp=w((UZe,w2)=>{var vCe=bs(),xCe=(r,e,t)=>vCe(r,e,t)>0;w2.exports=xCe});var SI=w((HZe,B2)=>{var kCe=bs(),PCe=(r,e,t)=>kCe(r,e,t)<0;B2.exports=PCe});var lS=w((jZe,b2)=>{var DCe=bs(),RCe=(r,e,t)=>DCe(r,e,t)!==0;b2.exports=RCe});var vI=w((GZe,Q2)=>{var FCe=bs(),NCe=(r,e,t)=>FCe(r,e,t)>=0;Q2.exports=NCe});var xI=w((YZe,S2)=>{var LCe=bs(),TCe=(r,e,t)=>LCe(r,e,t)<=0;S2.exports=TCe});var cS=w((qZe,v2)=>{var OCe=bI(),MCe=lS(),KCe=wp(),UCe=vI(),HCe=SI(),jCe=xI(),GCe=(r,e,t,i)=>{switch(e){case"===":return typeof r=="object"&&(r=r.version),typeof t=="object"&&(t=t.version),r===t;case"!==":return typeof r=="object"&&(r=r.version),typeof t=="object"&&(t=t.version),r!==t;case"":case"=":case"==":return OCe(r,t,i);case"!=":return MCe(r,t,i);case">":return KCe(r,t,i);case">=":return UCe(r,t,i);case"<":return HCe(r,t,i);case"<=":return jCe(r,t,i);default:throw new TypeError(`Invalid operator: ${e}`)}};v2.exports=GCe});var k2=w((JZe,x2)=>{var YCe=Hi(),qCe=Qc(),{re:kI,t:PI}=bc(),JCe=(r,e)=>{if(r instanceof YCe)return r;if(typeof r=="number"&&(r=String(r)),typeof r!="string")return null;e=e||{};let t=null;if(!e.rtl)t=r.match(kI[PI.COERCE]);else{let i;for(;(i=kI[PI.COERCERTL].exec(r))&&(!t||t.index+t[0].length!==r.length);)(!t||i.index+i[0].length!==t.index+t[0].length)&&(t=i),kI[PI.COERCERTL].lastIndex=i.index+i[1].length+i[2].length;kI[PI.COERCERTL].lastIndex=-1}return t===null?null:qCe(`${t[2]}.${t[3]||"0"}.${t[4]||"0"}`,e)};x2.exports=JCe});var D2=w((WZe,P2)=>{"use strict";P2.exports=function(r){r.prototype[Symbol.iterator]=function*(){for(let e=this.head;e;e=e.next)yield e.value}}});var Bp=w((zZe,R2)=>{"use strict";R2.exports=Gt;Gt.Node=Sc;Gt.create=Gt;function Gt(r){var e=this;if(e instanceof Gt||(e=new Gt),e.tail=null,e.head=null,e.length=0,r&&typeof r.forEach=="function")r.forEach(function(n){e.push(n)});else if(arguments.length>0)for(var t=0,i=arguments.length;t1)t=e;else if(this.head)i=this.head.next,t=this.head.value;else throw new TypeError("Reduce of empty list with no initial value");for(var n=0;i!==null;n++)t=r(t,i.value,n),i=i.next;return t};Gt.prototype.reduceReverse=function(r,e){var t,i=this.tail;if(arguments.length>1)t=e;else if(this.tail)i=this.tail.prev,t=this.tail.value;else throw new TypeError("Reduce of empty list with no initial value");for(var n=this.length-1;i!==null;n--)t=r(t,i.value,n),i=i.prev;return t};Gt.prototype.toArray=function(){for(var r=new Array(this.length),e=0,t=this.head;t!==null;e++)r[e]=t.value,t=t.next;return r};Gt.prototype.toArrayReverse=function(){for(var r=new Array(this.length),e=0,t=this.tail;t!==null;e++)r[e]=t.value,t=t.prev;return r};Gt.prototype.slice=function(r,e){e=e||this.length,e<0&&(e+=this.length),r=r||0,r<0&&(r+=this.length);var t=new Gt;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>r;i--,n=n.prev)t.push(n.value);return t};Gt.prototype.splice=function(r,e,...t){r>this.length&&(r=this.length-1),r<0&&(r=this.length+r);for(var i=0,n=this.head;n!==null&&i{"use strict";var VCe=Bp(),vc=Symbol("max"),Ua=Symbol("length"),fg=Symbol("lengthCalculator"),bp=Symbol("allowStale"),xc=Symbol("maxAge"),Ha=Symbol("dispose"),N2=Symbol("noDisposeOnSet"),yi=Symbol("lruList"),oo=Symbol("cache"),L2=Symbol("updateAgeOnGet"),uS=()=>1,T2=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 t=this[vc]=e.max||Infinity,i=e.length||uS;if(this[fg]=typeof i!="function"?uS:i,this[bp]=e.stale||!1,e.maxAge&&typeof e.maxAge!="number")throw new TypeError("maxAge must be a number");this[xc]=e.maxAge||0,this[Ha]=e.dispose,this[N2]=e.noDisposeOnSet||!1,this[L2]=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[vc]=e||Infinity,Qp(this)}get max(){return this[vc]}set allowStale(e){this[bp]=!!e}get allowStale(){return this[bp]}set maxAge(e){if(typeof e!="number")throw new TypeError("maxAge must be a non-negative number");this[xc]=e,Qp(this)}get maxAge(){return this[xc]}set lengthCalculator(e){typeof e!="function"&&(e=uS),e!==this[fg]&&(this[fg]=e,this[Ua]=0,this[yi].forEach(t=>{t.length=this[fg](t.value,t.key),this[Ua]+=t.length})),Qp(this)}get lengthCalculator(){return this[fg]}get length(){return this[Ua]}get itemCount(){return this[yi].length}rforEach(e,t){t=t||this;for(let i=this[yi].tail;i!==null;){let n=i.prev;M2(this,e,i,t),i=n}}forEach(e,t){t=t||this;for(let i=this[yi].head;i!==null;){let n=i.next;M2(this,e,i,t),i=n}}keys(){return this[yi].toArray().map(e=>e.key)}values(){return this[yi].toArray().map(e=>e.value)}reset(){this[Ha]&&this[yi]&&this[yi].length&&this[yi].forEach(e=>this[Ha](e.key,e.value)),this[oo]=new Map,this[yi]=new VCe,this[Ua]=0}dump(){return this[yi].map(e=>DI(this,e)?!1:{k:e.key,v:e.value,e:e.now+(e.maxAge||0)}).toArray().filter(e=>e)}dumpLru(){return this[yi]}set(e,t,i){if(i=i||this[xc],i&&typeof i!="number")throw new TypeError("maxAge must be a number");let n=i?Date.now():0,s=this[fg](t,e);if(this[oo].has(e)){if(s>this[vc])return hg(this,this[oo].get(e)),!1;let l=this[oo].get(e).value;return this[Ha]&&(this[N2]||this[Ha](e,l.value)),l.now=n,l.maxAge=i,l.value=t,this[Ua]+=s-l.length,l.length=s,this.get(e),Qp(this),!0}let o=new O2(e,t,s,n,i);return o.length>this[vc]?(this[Ha]&&this[Ha](e,t),!1):(this[Ua]+=o.length,this[yi].unshift(o),this[oo].set(e,this[yi].head),Qp(this),!0)}has(e){if(!this[oo].has(e))return!1;let t=this[oo].get(e).value;return!DI(this,t)}get(e){return gS(this,e,!0)}peek(e){return gS(this,e,!1)}pop(){let e=this[yi].tail;return e?(hg(this,e),e.value):null}del(e){hg(this,this[oo].get(e))}load(e){this.reset();let t=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-t;o>0&&this.set(n.k,n.v,o)}}}prune(){this[oo].forEach((e,t)=>gS(this,t,!1))}},gS=(r,e,t)=>{let i=r[oo].get(e);if(i){let n=i.value;if(DI(r,n)){if(hg(r,i),!r[bp])return}else t&&(r[L2]&&(i.value.now=Date.now()),r[yi].unshiftNode(i));return n.value}},DI=(r,e)=>{if(!e||!e.maxAge&&!r[xc])return!1;let t=Date.now()-e.now;return e.maxAge?t>e.maxAge:r[xc]&&t>r[xc]},Qp=r=>{if(r[Ua]>r[vc])for(let e=r[yi].tail;r[Ua]>r[vc]&&e!==null;){let t=e.prev;hg(r,e),e=t}},hg=(r,e)=>{if(e){let t=e.value;r[Ha]&&r[Ha](t.key,t.value),r[Ua]-=t.length,r[oo].delete(t.key),r[yi].removeNode(e)}},O2=class{constructor(e,t,i,n,s){this.key=e,this.value=t,this.length=i,this.now=n,this.maxAge=s||0}},M2=(r,e,t,i)=>{let n=t.value;DI(r,n)&&(hg(r,t),r[bp]||(n=void 0)),n&&e.call(i,n.value,n.key,r)};F2.exports=T2});var Qs=w((VZe,U2)=>{var pg=class{constructor(e,t){if(t=XCe(t),e instanceof pg)return e.loose===!!t.loose&&e.includePrerelease===!!t.includePrerelease?e:new pg(e.raw,t);if(e instanceof fS)return this.raw=e.value,this.set=[[e]],this.format(),this;if(this.options=t,this.loose=!!t.loose,this.includePrerelease=!!t.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=>!j2(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&&rme(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=H2.get(i);if(n)return n;let s=this.options.loose,o=s?ji[ki.HYPHENRANGELOOSE]:ji[ki.HYPHENRANGE];e=e.replace(o,sme(this.options.includePrerelease)),zr("hyphen replace",e),e=e.replace(ji[ki.COMPARATORTRIM],$Ce),zr("comparator trim",e,ji[ki.COMPARATORTRIM]),e=e.replace(ji[ki.TILDETRIM],eme),e=e.replace(ji[ki.CARETTRIM],tme),e=e.split(/\s+/).join(" ");let a=s?ji[ki.COMPARATORLOOSE]:ji[ki.COMPARATOR],l=e.split(" ").map(f=>ime(f,this.options)).join(" ").split(/\s+/).map(f=>nme(f,this.options)).filter(this.options.loose?f=>!!f.match(a):()=>!0).map(f=>new fS(f,this.options)),c=l.length,u=new Map;for(let f of l){if(j2(f))return[f];u.set(f.value,f)}u.size>1&&u.has("")&&u.delete("");let g=[...u.values()];return H2.set(i,g),g}intersects(e,t){if(!(e instanceof pg))throw new TypeError("a Range is required");return this.set.some(i=>G2(i,t)&&e.set.some(n=>G2(n,t)&&i.every(s=>n.every(o=>s.intersects(o,t)))))}test(e){if(!e)return!1;if(typeof e=="string")try{e=new ZCe(e,this.options)}catch(t){return!1}for(let t=0;tr.value==="<0.0.0-0",rme=r=>r.value==="",G2=(r,e)=>{let t=!0,i=r.slice(),n=i.pop();for(;t&&i.length;)t=i.every(s=>n.intersects(s,e)),n=i.pop();return t},ime=(r,e)=>(zr("comp",r,e),r=lme(r,e),zr("caret",r),r=Ame(r,e),zr("tildes",r),r=cme(r,e),zr("xrange",r),r=ume(r,e),zr("stars",r),r),on=r=>!r||r.toLowerCase()==="x"||r==="*",Ame=(r,e)=>r.trim().split(/\s+/).map(t=>gme(t,e)).join(" "),gme=(r,e)=>{let t=e.loose?ji[ki.TILDELOOSE]:ji[ki.TILDE];return r.replace(t,(i,n,s,o,a)=>{zr("tilde",r,i,n,s,o,a);let l;return on(n)?l="":on(s)?l=`>=${n}.0.0 <${+n+1}.0.0-0`:on(o)?l=`>=${n}.${s}.0 <${n}.${+s+1}.0-0`:a?(zr("replaceTilde pr",a),l=`>=${n}.${s}.${o}-${a} <${n}.${+s+1}.0-0`):l=`>=${n}.${s}.${o} <${n}.${+s+1}.0-0`,zr("tilde return",l),l})},lme=(r,e)=>r.trim().split(/\s+/).map(t=>fme(t,e)).join(" "),fme=(r,e)=>{zr("caret",r,e);let t=e.loose?ji[ki.CARETLOOSE]:ji[ki.CARET],i=e.includePrerelease?"-0":"";return r.replace(t,(n,s,o,a,l)=>{zr("caret",r,n,s,o,a,l);let c;return on(s)?c="":on(o)?c=`>=${s}.0.0${i} <${+s+1}.0.0-0`:on(a)?s==="0"?c=`>=${s}.${o}.0${i} <${s}.${+o+1}.0-0`:c=`>=${s}.${o}.0${i} <${+s+1}.0.0-0`:l?(zr("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`):(zr("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`),zr("caret return",c),c})},cme=(r,e)=>(zr("replaceXRanges",r,e),r.split(/\s+/).map(t=>hme(t,e)).join(" ")),hme=(r,e)=>{r=r.trim();let t=e.loose?ji[ki.XRANGELOOSE]:ji[ki.XRANGE];return r.replace(t,(i,n,s,o,a,l)=>{zr("xRange",r,i,n,s,o,a,l);let c=on(s),u=c||on(o),g=u||on(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`),zr("xRange return",i),i})},ume=(r,e)=>(zr("replaceStars",r,e),r.trim().replace(ji[ki.STAR],"")),nme=(r,e)=>(zr("replaceGTE0",r,e),r.trim().replace(ji[e.includePrerelease?ki.GTE0PRE:ki.GTE0],"")),sme=r=>(e,t,i,n,s,o,a,l,c,u,g,f,h)=>(on(i)?t="":on(n)?t=`>=${i}.0.0${r?"-0":""}`:on(s)?t=`>=${i}.${n}.0${r?"-0":""}`:o?t=`>=${t}`:t=`>=${t}${r?"-0":""}`,on(c)?l="":on(u)?l=`<${+c+1}.0.0-0`:on(g)?l=`<${c}.${+u+1}.0-0`:f?l=`<=${c}.${u}.${g}-${f}`:r?l=`<${c}.${u}.${+g+1}-0`:l=`<=${l}`,`${t} ${l}`.trim()),ome=(r,e,t)=>{for(let i=0;i0){let n=r[i].semver;if(n.major===e.major&&n.minor===e.minor&&n.patch===e.patch)return!0}return!1}return!0}});var Sp=w((XZe,Y2)=>{var vp=Symbol("SemVer ANY"),xp=class{static get ANY(){return vp}constructor(e,t){if(t=pme(t),e instanceof xp){if(e.loose===!!t.loose)return e;e=e.value}pS("comparator",e,t),this.options=t,this.loose=!!t.loose,this.parse(e),this.semver===vp?this.value="":this.value=this.operator+this.semver.version,pS("comp",this)}parse(e){let t=this.options.loose?q2[J2.COMPARATORLOOSE]:q2[J2.COMPARATOR],i=e.match(t);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 W2(i[2],this.options.loose):this.semver=vp}toString(){return this.value}test(e){if(pS("Comparator.test",e,this.options.loose),this.semver===vp||e===vp)return!0;if(typeof e=="string")try{e=new W2(e,this.options)}catch(t){return!1}return hS(e,this.operator,this.semver,this.options)}intersects(e,t){if(!(e instanceof xp))throw new TypeError("a Comparator is required");if((!t||typeof t!="object")&&(t={loose:!!t,includePrerelease:!1}),this.operator==="")return this.value===""?!0:new z2(e.value,t).test(this.value);if(e.operator==="")return e.value===""?!0:new z2(this.value,t).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=hS(this.semver,"<",e.semver,t)&&(this.operator===">="||this.operator===">")&&(e.operator==="<="||e.operator==="<"),l=hS(this.semver,">",e.semver,t)&&(this.operator==="<="||this.operator==="<")&&(e.operator===">="||e.operator===">");return i||n||s&&o||a||l}};Y2.exports=xp;var pme=Ip(),{re:q2,t:J2}=bc(),hS=cS(),pS=Ep(),W2=Hi(),z2=Qs()});var kp=w((ZZe,_2)=>{var dme=Qs(),Cme=(r,e,t)=>{try{e=new dme(e,t)}catch(i){return!1}return e.test(r)};_2.exports=Cme});var X2=w(($Ze,V2)=>{var mme=Qs(),Eme=(r,e)=>new mme(r,e).set.map(t=>t.map(i=>i.value).join(" ").trim().split(" "));V2.exports=Eme});var $2=w((e$e,Z2)=>{var Ime=Hi(),yme=Qs(),wme=(r,e,t)=>{let i=null,n=null,s=null;try{s=new yme(e,t)}catch(o){return null}return r.forEach(o=>{s.test(o)&&(!i||n.compare(o)===-1)&&(i=o,n=new Ime(i,t))}),i};Z2.exports=wme});var tH=w((t$e,eH)=>{var Bme=Hi(),bme=Qs(),Qme=(r,e,t)=>{let i=null,n=null,s=null;try{s=new bme(e,t)}catch(o){return null}return r.forEach(o=>{s.test(o)&&(!i||n.compare(o)===1)&&(i=o,n=new Bme(i,t))}),i};eH.exports=Qme});var nH=w((r$e,rH)=>{var dS=Hi(),Sme=Qs(),iH=wp(),vme=(r,e)=>{r=new Sme(r,e);let t=new dS("0.0.0");if(r.test(t)||(t=new dS("0.0.0-0"),r.test(t)))return t;t=null;for(let i=0;i{let a=new dS(o.semver.version);switch(o.operator){case">":a.prerelease.length===0?a.patch++:a.prerelease.push(0),a.raw=a.format();case"":case">=":(!s||iH(a,s))&&(s=a);break;case"<":case"<=":break;default:throw new Error(`Unexpected operation: ${o.operator}`)}}),s&&(!t||iH(t,s))&&(t=s)}return t&&r.test(t)?t:null};rH.exports=vme});var oH=w((i$e,sH)=>{var xme=Qs(),kme=(r,e)=>{try{return new xme(r,e).range||"*"}catch(t){return null}};sH.exports=kme});var RI=w((n$e,aH)=>{var Pme=Hi(),AH=Sp(),{ANY:Dme}=AH,Rme=Qs(),Fme=kp(),lH=wp(),cH=SI(),Nme=xI(),Lme=vI(),Tme=(r,e,t,i)=>{r=new Pme(r,i),e=new Rme(e,i);let n,s,o,a,l;switch(t){case">":n=lH,s=Nme,o=cH,a=">",l=">=";break;case"<":n=cH,s=Lme,o=lH,a="<",l="<=";break;default:throw new TypeError('Must provide a hilo val of "<" or ">"')}if(Fme(r,e,i))return!1;for(let c=0;c{h.semver===Dme&&(h=new AH(">=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(r,f.semver))return!1;if(f.operator===l&&o(r,f.semver))return!1}return!0};aH.exports=Tme});var gH=w((s$e,uH)=>{var Ome=RI(),Mme=(r,e,t)=>Ome(r,e,">",t);uH.exports=Mme});var hH=w((o$e,fH)=>{var Kme=RI(),Ume=(r,e,t)=>Kme(r,e,"<",t);fH.exports=Ume});var CH=w((a$e,pH)=>{var dH=Qs(),Hme=(r,e,t)=>(r=new dH(r,t),e=new dH(e,t),r.intersects(e));pH.exports=Hme});var EH=w((A$e,mH)=>{var jme=kp(),Gme=bs();mH.exports=(r,e,t)=>{let i=[],n=null,s=null,o=r.sort((u,g)=>Gme(u,g,t));for(let u of o)jme(u,e,t)?(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 yH=Qs(),FI=Sp(),{ANY:CS}=FI,Pp=kp(),mS=bs(),qme=(r,e,t={})=>{if(r===e)return!0;r=new yH(r,t),e=new yH(e,t);let i=!1;e:for(let n of r.set){for(let s of e.set){let o=Yme(n,s,t);if(i=i||o!==null,o)continue e}if(i)return!1}return!0},Yme=(r,e,t)=>{if(r===e)return!0;if(r.length===1&&r[0].semver===CS){if(e.length===1&&e[0].semver===CS)return!0;t.includePrerelease?r=[new FI(">=0.0.0-0")]:r=[new FI(">=0.0.0")]}if(e.length===1&&e[0].semver===CS){if(t.includePrerelease)return!0;e=[new FI(">=0.0.0")]}let i=new Set,n,s;for(let h of r)h.operator===">"||h.operator===">="?n=wH(n,h,t):h.operator==="<"||h.operator==="<="?s=BH(s,h,t):i.add(h.semver);if(i.size>1)return null;let o;if(n&&s){if(o=mS(n.semver,s.semver,t),o>0)return null;if(o===0&&(n.operator!==">="||s.operator!=="<="))return null}for(let h of i){if(n&&!Pp(h,String(n),t)||s&&!Pp(h,String(s),t))return null;for(let p of e)if(!Pp(h,String(p),t))return!1;return!0}let a,l,c,u,g=s&&!t.includePrerelease&&s.semver.prerelease.length?s.semver:!1,f=n&&!t.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=wH(n,h,t),a===h&&a!==n)return!1}else if(n.operator===">="&&!Pp(n.semver,String(h),t))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=BH(s,h,t),l===h&&l!==s)return!1}else if(s.operator==="<="&&!Pp(s.semver,String(h),t))return!1}if(!h.operator&&(s||n)&&o!==0)return!1}return!(n&&c&&!s&&o!==0||s&&u&&!n&&o!==0||f||g)},wH=(r,e,t)=>{if(!r)return e;let i=mS(r.semver,e.semver,t);return i>0?r:i<0||e.operator===">"&&r.operator===">="?e:r},BH=(r,e,t)=>{if(!r)return e;let i=mS(r.semver,e.semver,t);return i<0?r:i>0||e.operator==="<"&&r.operator==="<="?e:r};IH.exports=qme});var ri=w((c$e,QH)=>{var ES=bc();QH.exports={re:ES.re,src:ES.src,tokens:ES.t,SEMVER_SPEC_VERSION:mp().SEMVER_SPEC_VERSION,SemVer:Hi(),compareIdentifiers:yI().compareIdentifiers,rcompareIdentifiers:yI().rcompareIdentifiers,parse:Qc(),valid:WU(),clean:_U(),inc:XU(),diff:i2(),major:s2(),minor:a2(),patch:l2(),prerelease:u2(),compare:bs(),rcompare:f2(),compareLoose:p2(),compareBuild:QI(),sort:E2(),rsort:y2(),gt:wp(),lt:SI(),eq:bI(),neq:lS(),gte:vI(),lte:xI(),cmp:cS(),coerce:k2(),Comparator:Sp(),Range:Qs(),satisfies:kp(),toComparators:X2(),maxSatisfying:$2(),minSatisfying:tH(),minVersion:nH(),validRange:oH(),outside:RI(),gtr:gH(),ltr:hH(),intersects:CH(),simplifyRange:EH(),subset:bH()}});var IS=w(NI=>{"use strict";Object.defineProperty(NI,"__esModule",{value:!0});NI.VERSION=void 0;NI.VERSION="9.1.0"});var Yt=w((exports,module)=>{"use strict";var __spreadArray=exports&&exports.__spreadArray||function(r,e,t){if(t||arguments.length===2)for(var i=0,n=e.length,s;i{(function(r,e){typeof define=="function"&&define.amd?define([],e):typeof LI=="object"&&LI.exports?LI.exports=e():r.regexpToAst=e()})(typeof self!="undefined"?self:SH,function(){function r(){}r.prototype.saveState=function(){return{idx:this.idx,input:this.input,groupIdx:this.groupIdx}},r.prototype.restoreState=function(p){this.idx=p.idx,this.input=p.input,this.groupIdx=p.groupIdx},r.prototype.pattern=function(p){this.idx=0,this.input=p,this.groupIdx=0,this.consumeChar("/");var m=this.disjunction();this.consumeChar("/");for(var y={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(y,"global");break;case"i":o(y,"ignoreCase");break;case"m":o(y,"multiLine");break;case"u":o(y,"unicode");break;case"y":o(y,"sticky");break}if(this.idx!==this.input.length)throw Error("Redundant input: "+this.input.substring(this.idx));return{type:"Pattern",flags:y,value:m,loc:this.loc(0)}},r.prototype.disjunction=function(){var p=[],m=this.idx;for(p.push(this.alternative());this.peekChar()==="|";)this.consumeChar("|"),p.push(this.alternative());return{type:"Disjunction",value:p,loc:this.loc(m)}},r.prototype.alternative=function(){for(var p=[],m=this.idx;this.isTerm();)p.push(this.term());return{type:"Alternative",value:p,loc:this.loc(m)}},r.prototype.term=function(){return this.isAssertion()?this.assertion():this.atom()},r.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 m;switch(this.popChar()){case"=":m="Lookahead";break;case"!":m="NegativeLookahead";break}a(m);var y=this.disjunction();return this.consumeChar(")"),{type:m,value:y,loc:this.loc(p)}}l()},r.prototype.quantifier=function(p){var m,y=this.idx;switch(this.popChar()){case"*":m={atLeast:0,atMost:Infinity};break;case"+":m={atLeast:1,atMost:Infinity};break;case"?":m={atLeast:0,atMost:1};break;case"{":var b=this.integerIncludingZero();switch(this.popChar()){case"}":m={atLeast:b,atMost:b};break;case",":var v;this.isDigit()?(v=this.integerIncludingZero(),m={atLeast:b,atMost:v}):m={atLeast:b,atMost:Infinity},this.consumeChar("}");break}if(p===!0&&m===void 0)return;a(m);break}if(!(p===!0&&m===void 0))return a(m),this.peekChar(0)==="?"?(this.consumeChar("?"),m.greedy=!1):m.greedy=!0,m.type="Quantifier",m.loc=this.loc(y),m},r.prototype.atom=function(){var p,m=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(m),this.isQuantifier()&&(p.quantifier=this.quantifier()),p},r.prototype.dotAll=function(){return this.consumeChar("."),{type:"Set",complement:!0,value:[n(` -`),n("\r"),n("\u2028"),n("\u2029")]}},r.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()}},r.prototype.decimalEscapeAtom=function(){var p=this.positiveInteger();return{type:"GroupBackReference",value:p}},r.prototype.characterClassEscape=function(){var p,m=!1;switch(this.popChar()){case"d":p=u;break;case"D":p=u,m=!0;break;case"s":p=f;break;case"S":p=f,m=!0;break;case"w":p=g;break;case"W":p=g,m=!0;break}return a(p),{type:"Set",value:p,complement:m}},r.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}},r.prototype.controlLetterEscapeAtom=function(){this.consumeChar("c");var p=this.popChar();if(/[a-zA-Z]/.test(p)===!1)throw Error("Invalid ");var m=p.toUpperCase().charCodeAt(0)-64;return{type:"Character",value:m}},r.prototype.nulCharacterAtom=function(){return this.consumeChar("0"),{type:"Character",value:n("\0")}},r.prototype.hexEscapeSequenceAtom=function(){return this.consumeChar("x"),this.parseHexDigits(2)},r.prototype.regExpUnicodeEscapeSequenceAtom=function(){return this.consumeChar("u"),this.parseHexDigits(4)},r.prototype.identityEscapeAtom=function(){var p=this.popChar();return{type:"Character",value:n(p)}},r.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)}}},r.prototype.characterClass=function(){var p=[],m=!1;for(this.consumeChar("["),this.peekChar(0)==="^"&&(this.consumeChar("^"),m=!0);this.isClassAtom();){var y=this.classAtom(),b=y.type==="Character";if(b&&this.isRangeDash()){this.consumeChar("-");var v=this.classAtom(),x=v.type==="Character";if(x){if(v.value=this.input.length)throw Error("Unexpected end of input");this.idx++},r.prototype.loc=function(p){return{begin:p,end:this.idx}};var e=/[0-9a-fA-F]/,t=/[0-9]/,i=/[1-9]/;function n(p){return p.charCodeAt(0)}function s(p,m){p.length!==void 0?p.forEach(function(y){m.push(y)}):m.push(p)}function o(p,m){if(p[m]===!0)throw"duplicate flag "+m;p[m]=!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 m in p){var y=p[m];p.hasOwnProperty(m)&&(y.type!==void 0?this.visit(y):Array.isArray(y)&&y.forEach(function(b){this.visit(b)},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:r,BaseRegExpVisitor:h,VERSION:"0.5.0"}})});var MI=w(dg=>{"use strict";Object.defineProperty(dg,"__esModule",{value:!0});dg.clearRegExpParserCache=dg.getRegExpAst=void 0;var Jme=TI(),OI={},Wme=new Jme.RegExpParser;function zme(r){var e=r.toString();if(OI.hasOwnProperty(e))return OI[e];var t=Wme.pattern(e);return OI[e]=t,t}dg.getRegExpAst=zme;function _me(){OI={}}dg.clearRegExpParserCache=_me});var DH=w(Bn=>{"use strict";var Vme=Bn&&Bn.__extends||function(){var r=function(e,t){return r=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])},r(e,t)};return function(e,t){if(typeof t!="function"&&t!==null)throw new TypeError("Class extends value "+String(t)+" is not a constructor or null");r(e,t);function i(){this.constructor=e}e.prototype=t===null?Object.create(t):(i.prototype=t.prototype,new i)}}();Object.defineProperty(Bn,"__esModule",{value:!0});Bn.canMatchCharCode=Bn.firstCharOptimizedIndices=Bn.getOptimizedStartCodesIndices=Bn.failedOptimizationPrefixMsg=void 0;var vH=TI(),Ss=Yt(),xH=MI(),ja=yS(),kH="Complement Sets are not supported for first char optimization";Bn.failedOptimizationPrefixMsg=`Unable to use "first char" lexer optimizations: -`;function Xme(r,e){e===void 0&&(e=!1);try{var t=(0,xH.getRegExpAst)(r),i=KI(t.value,{},t.flags.ignoreCase);return i}catch(s){if(s.message===kH)e&&(0,Ss.PRINT_WARNING)(""+Bn.failedOptimizationPrefixMsg+(" Unable to optimize: < "+r.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,Ss.PRINT_ERROR)(Bn.failedOptimizationPrefixMsg+` -`+(" Failed parsing: < "+r.toString()+` > -`)+(" Using the regexp-to-ast library version: "+vH.VERSION+` -`)+" Please open an issue at: https://github.com/bd82/regexp-to-ast/issues"+n)}}return[]}Bn.getOptimizedStartCodesIndices=Xme;function KI(r,e,t){switch(r.type){case"Disjunction":for(var i=0;i=ja.minOptimizationVal)for(var f=u.from>=ja.minOptimizationVal?u.from:ja.minOptimizationVal,h=u.to,p=(0,ja.charCodeToOptimizedIndex)(f),m=(0,ja.charCodeToOptimizedIndex)(h),y=p;y<=m;y++)e[y]=y}}});break;case"Group":KI(o.value,e,t);break;default:throw Error("Non Exhaustive Match")}var a=o.quantifier!==void 0&&o.quantifier.atLeast===0;if(o.type==="Group"&&wS(o)===!1||o.type!=="Group"&&a===!1)break}break;default:throw Error("non exhaustive match!")}return(0,Ss.values)(e)}Bn.firstCharOptimizedIndices=KI;function UI(r,e,t){var i=(0,ja.charCodeToOptimizedIndex)(r);e[i]=i,t===!0&&Zme(r,e)}function Zme(r,e){var t=String.fromCharCode(r),i=t.toUpperCase();if(i!==t){var n=(0,ja.charCodeToOptimizedIndex)(i.charCodeAt(0));e[n]=n}else{var s=t.toLowerCase();if(s!==t){var n=(0,ja.charCodeToOptimizedIndex)(s.charCodeAt(0));e[n]=n}}}function PH(r,e){return(0,Ss.find)(r.value,function(t){if(typeof t=="number")return(0,Ss.contains)(e,t);var i=t;return(0,Ss.find)(e,function(n){return i.from<=n&&n<=i.to})!==void 0})}function wS(r){return r.quantifier&&r.quantifier.atLeast===0?!0:r.value?(0,Ss.isArray)(r.value)?(0,Ss.every)(r.value,wS):wS(r.value):!1}var $me=function(r){Vme(e,r);function e(t){var i=r.call(this)||this;return i.targetCharCodes=t,i.found=!1,i}return e.prototype.visitChildren=function(t){if(this.found!==!0){switch(t.type){case"Lookahead":this.visitLookahead(t);return;case"NegativeLookahead":this.visitNegativeLookahead(t);return}r.prototype.visitChildren.call(this,t)}},e.prototype.visitCharacter=function(t){(0,Ss.contains)(this.targetCharCodes,t.value)&&(this.found=!0)},e.prototype.visitSet=function(t){t.complement?PH(t,this.targetCharCodes)===void 0&&(this.found=!0):PH(t,this.targetCharCodes)!==void 0&&(this.found=!0)},e}(vH.BaseRegExpVisitor);function eEe(r,e){if(e instanceof RegExp){var t=(0,xH.getRegExpAst)(e),i=new $me(r);return i.visit(t),i.found}else return(0,Ss.find)(e,function(n){return(0,Ss.contains)(r,n.charCodeAt(0))})!==void 0}Bn.canMatchCharCode=eEe});var yS=w(Ze=>{"use strict";var RH=Ze&&Ze.__extends||function(){var r=function(e,t){return r=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])},r(e,t)};return function(e,t){if(typeof t!="function"&&t!==null)throw new TypeError("Class extends value "+String(t)+" is not a constructor or null");r(e,t);function i(){this.constructor=e}e.prototype=t===null?Object.create(t):(i.prototype=t.prototype,new i)}}();Object.defineProperty(Ze,"__esModule",{value:!0});Ze.charCodeToOptimizedIndex=Ze.minOptimizationVal=Ze.buildLineBreakIssueMessage=Ze.LineTerminatorOptimizedTester=Ze.isShortPattern=Ze.isCustomPattern=Ze.cloneEmptyGroups=Ze.performWarningRuntimeChecks=Ze.performRuntimeChecks=Ze.addStickyFlag=Ze.addStartOfInput=Ze.findUnreachablePatterns=Ze.findModesThatDoNotExist=Ze.findInvalidGroupType=Ze.findDuplicatePatterns=Ze.findUnsupportedFlags=Ze.findStartOfInputAnchor=Ze.findEmptyMatchRegExps=Ze.findEndOfInputAnchor=Ze.findInvalidPatterns=Ze.findMissingPatterns=Ze.validatePatterns=Ze.analyzeTokenTypes=Ze.enableSticky=Ze.disableSticky=Ze.SUPPORT_STICKY=Ze.MODES=Ze.DEFAULT_MODE=void 0;var FH=TI(),Ar=Dp(),Ne=Yt(),Cg=DH(),NH=MI(),Mo="PATTERN";Ze.DEFAULT_MODE="defaultMode";Ze.MODES="modes";Ze.SUPPORT_STICKY=typeof new RegExp("(?:)").sticky=="boolean";function tEe(){Ze.SUPPORT_STICKY=!1}Ze.disableSticky=tEe;function rEe(){Ze.SUPPORT_STICKY=!0}Ze.enableSticky=rEe;function nEe(r,e){e=(0,Ne.defaults)(e,{useSticky:Ze.SUPPORT_STICKY,debug:!1,safeMode:!1,positionTracking:"full",lineTerminatorCharacters:["\r",` -`],tracer:function(v,x){return x()}});var t=e.tracer;t("initCharCodeToOptimizedIndexMap",function(){iEe()});var i;t("Reject Lexer.NA",function(){i=(0,Ne.reject)(r,function(v){return v[Mo]===Ar.Lexer.NA})});var n=!1,s;t("Transform Patterns",function(){n=!1,s=(0,Ne.map)(i,function(v){var x=v[Mo];if((0,Ne.isRegExp)(x)){var T=x.source;return T.length===1&&T!=="^"&&T!=="$"&&T!=="."&&!x.ignoreCase?T:T.length===2&&T[0]==="\\"&&!(0,Ne.contains)(["d","D","s","S","t","r","n","t","0","c","b","B","f","v","w","W"],T[1])?T[1]:e.useSticky?bS(x):BS(x)}else{if((0,Ne.isFunction)(x))return n=!0,{exec:x};if((0,Ne.has)(x,"exec"))return n=!0,x;if(typeof x=="string"){if(x.length===1)return x;var q=x.replace(/[\\^$.*+?()[\]{}|]/g,"\\$&"),Y=new RegExp(q);return e.useSticky?bS(Y):BS(Y)}else throw Error("non exhaustive match")}})});var o,a,l,c,u;t("misc mapping",function(){o=(0,Ne.map)(i,function(v){return v.tokenTypeIdx}),a=(0,Ne.map)(i,function(v){var x=v.GROUP;if(x!==Ar.Lexer.SKIPPED){if((0,Ne.isString)(x))return x;if((0,Ne.isUndefined)(x))return!1;throw Error("non exhaustive match")}}),l=(0,Ne.map)(i,function(v){var x=v.LONGER_ALT;if(x){var T=(0,Ne.isArray)(x)?(0,Ne.map)(x,function(q){return(0,Ne.indexOf)(i,q)}):[(0,Ne.indexOf)(i,x)];return T}}),c=(0,Ne.map)(i,function(v){return v.PUSH_MODE}),u=(0,Ne.map)(i,function(v){return(0,Ne.has)(v,"POP_MODE")})});var g;t("Line Terminator Handling",function(){var v=OH(e.lineTerminatorCharacters);g=(0,Ne.map)(i,function(x){return!1}),e.positionTracking!=="onlyOffset"&&(g=(0,Ne.map)(i,function(x){if((0,Ne.has)(x,"LINE_BREAKS"))return x.LINE_BREAKS;if(TH(x,v)===!1)return(0,Cg.canMatchCharCode)(v,x.PATTERN)}))});var f,h,p,m;t("Misc Mapping #2",function(){f=(0,Ne.map)(i,QS),h=(0,Ne.map)(s,LH),p=(0,Ne.reduce)(i,function(v,x){var T=x.GROUP;return(0,Ne.isString)(T)&&T!==Ar.Lexer.SKIPPED&&(v[T]=[]),v},{}),m=(0,Ne.map)(s,function(v,x){return{pattern:s[x],longerAlt:l[x],canLineTerminator:g[x],isCustom:f[x],short:h[x],group:a[x],push:c[x],pop:u[x],tokenTypeIdx:o[x],tokenType:i[x]}})});var y=!0,b=[];return e.safeMode||t("First Char Optimization",function(){b=(0,Ne.reduce)(i,function(v,x,T){if(typeof x.PATTERN=="string"){var q=x.PATTERN.charCodeAt(0),Y=vS(q);SS(v,Y,m[T])}else if((0,Ne.isArray)(x.START_CHARS_HINT)){var $;(0,Ne.forEach)(x.START_CHARS_HINT,function(ne){var ee=typeof ne=="string"?ne.charCodeAt(0):ne,A=vS(ee);$!==A&&($=A,SS(v,A,m[T]))})}else if((0,Ne.isRegExp)(x.PATTERN))if(x.PATTERN.unicode)y=!1,e.ensureOptimizations&&(0,Ne.PRINT_ERROR)(""+Cg.failedOptimizationPrefixMsg+(" Unable to analyze < "+x.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 _=(0,Cg.getOptimizedStartCodesIndices)(x.PATTERN,e.ensureOptimizations);(0,Ne.isEmpty)(_)&&(y=!1),(0,Ne.forEach)(_,function(ne){SS(v,ne,m[T])})}else e.ensureOptimizations&&(0,Ne.PRINT_ERROR)(""+Cg.failedOptimizationPrefixMsg+(" TokenType: <"+x.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`),y=!1;return v},[])}),t("ArrayPacking",function(){b=(0,Ne.packArray)(b)}),{emptyGroups:p,patternIdxToConfig:m,charCodeToPatternIdxToConfig:b,hasCustom:n,canBeOptimized:y}}Ze.analyzeTokenTypes=nEe;function oEe(r,e){var t=[],i=MH(r);t=t.concat(i.errors);var n=KH(i.valid),s=n.valid;return t=t.concat(n.errors),t=t.concat(sEe(s)),t=t.concat(UH(s)),t=t.concat(HH(s,e)),t=t.concat(jH(s)),t}Ze.validatePatterns=oEe;function sEe(r){var e=[],t=(0,Ne.filter)(r,function(i){return(0,Ne.isRegExp)(i[Mo])});return e=e.concat(GH(t)),e=e.concat(qH(t)),e=e.concat(JH(t)),e=e.concat(WH(t)),e=e.concat(YH(t)),e}function MH(r){var e=(0,Ne.filter)(r,function(n){return!(0,Ne.has)(n,Mo)}),t=(0,Ne.map)(e,function(n){return{message:"Token Type: ->"+n.name+"<- missing static 'PATTERN' property",type:Ar.LexerDefinitionErrorType.MISSING_PATTERN,tokenTypes:[n]}}),i=(0,Ne.difference)(r,e);return{errors:t,valid:i}}Ze.findMissingPatterns=MH;function KH(r){var e=(0,Ne.filter)(r,function(n){var s=n[Mo];return!(0,Ne.isRegExp)(s)&&!(0,Ne.isFunction)(s)&&!(0,Ne.has)(s,"exec")&&!(0,Ne.isString)(s)}),t=(0,Ne.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:Ar.LexerDefinitionErrorType.INVALID_PATTERN,tokenTypes:[n]}}),i=(0,Ne.difference)(r,e);return{errors:t,valid:i}}Ze.findInvalidPatterns=KH;var aEe=/[^\\][\$]/;function GH(r){var e=function(n){RH(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}(FH.BaseRegExpVisitor),t=(0,Ne.filter)(r,function(n){var s=n[Mo];try{var o=(0,NH.getRegExpAst)(s),a=new e;return a.visit(o),a.found}catch(l){return aEe.test(s.source)}}),i=(0,Ne.map)(t,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:Ar.LexerDefinitionErrorType.EOI_ANCHOR_FOUND,tokenTypes:[n]}});return i}Ze.findEndOfInputAnchor=GH;function YH(r){var e=(0,Ne.filter)(r,function(i){var n=i[Mo];return n.test("")}),t=(0,Ne.map)(e,function(i){return{message:"Token Type: ->"+i.name+"<- static 'PATTERN' must not match an empty string",type:Ar.LexerDefinitionErrorType.EMPTY_MATCH_PATTERN,tokenTypes:[i]}});return t}Ze.findEmptyMatchRegExps=YH;var AEe=/[^\\[][\^]|^\^/;function qH(r){var e=function(n){RH(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}(FH.BaseRegExpVisitor),t=(0,Ne.filter)(r,function(n){var s=n[Mo];try{var o=(0,NH.getRegExpAst)(s),a=new e;return a.visit(o),a.found}catch(l){return AEe.test(s.source)}}),i=(0,Ne.map)(t,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:Ar.LexerDefinitionErrorType.SOI_ANCHOR_FOUND,tokenTypes:[n]}});return i}Ze.findStartOfInputAnchor=qH;function JH(r){var e=(0,Ne.filter)(r,function(i){var n=i[Mo];return n instanceof RegExp&&(n.multiline||n.global)}),t=(0,Ne.map)(e,function(i){return{message:"Token Type: ->"+i.name+"<- static 'PATTERN' may NOT contain global('g') or multiline('m')",type:Ar.LexerDefinitionErrorType.UNSUPPORTED_FLAGS_FOUND,tokenTypes:[i]}});return t}Ze.findUnsupportedFlags=JH;function WH(r){var e=[],t=(0,Ne.map)(r,function(s){return(0,Ne.reduce)(r,function(o,a){return s.PATTERN.source===a.PATTERN.source&&!(0,Ne.contains)(e,a)&&a.PATTERN!==Ar.Lexer.NA&&(e.push(a),o.push(a)),o},[])});t=(0,Ne.compact)(t);var i=(0,Ne.filter)(t,function(s){return s.length>1}),n=(0,Ne.map)(i,function(s){var o=(0,Ne.map)(s,function(l){return l.name}),a=(0,Ne.first)(s).PATTERN;return{message:"The same RegExp pattern ->"+a+"<-"+("has been used in all of the following Token Types: "+o.join(", ")+" <-"),type:Ar.LexerDefinitionErrorType.DUPLICATE_PATTERNS_FOUND,tokenTypes:s}});return n}Ze.findDuplicatePatterns=WH;function UH(r){var e=(0,Ne.filter)(r,function(i){if(!(0,Ne.has)(i,"GROUP"))return!1;var n=i.GROUP;return n!==Ar.Lexer.SKIPPED&&n!==Ar.Lexer.NA&&!(0,Ne.isString)(n)}),t=(0,Ne.map)(e,function(i){return{message:"Token Type: ->"+i.name+"<- static 'GROUP' can only be Lexer.SKIPPED/Lexer.NA/A String",type:Ar.LexerDefinitionErrorType.INVALID_GROUP_TYPE_FOUND,tokenTypes:[i]}});return t}Ze.findInvalidGroupType=UH;function HH(r,e){var t=(0,Ne.filter)(r,function(n){return n.PUSH_MODE!==void 0&&!(0,Ne.contains)(e,n.PUSH_MODE)}),i=(0,Ne.map)(t,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:Ar.LexerDefinitionErrorType.PUSH_MODE_DOES_NOT_EXIST,tokenTypes:[n]}});return i}Ze.findModesThatDoNotExist=HH;function jH(r){var e=[],t=(0,Ne.reduce)(r,function(i,n,s){var o=n.PATTERN;return o===Ar.Lexer.NA||((0,Ne.isString)(o)?i.push({str:o,idx:s,tokenType:n}):(0,Ne.isRegExp)(o)&&cEe(o)&&i.push({str:o.source,idx:s,tokenType:n})),i},[]);return(0,Ne.forEach)(r,function(i,n){(0,Ne.forEach)(t,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:Ar.LexerDefinitionErrorType.UNREACHABLE_PATTERN,tokenTypes:[i,l]})}})}),e}Ze.findUnreachablePatterns=jH;function lEe(r,e){if((0,Ne.isRegExp)(e)){var t=e.exec(r);return t!==null&&t.index===0}else{if((0,Ne.isFunction)(e))return e(r,0,[],{});if((0,Ne.has)(e,"exec"))return e.exec(r,0,[],{});if(typeof e=="string")return e===r;throw Error("non exhaustive match")}}function cEe(r){var e=[".","\\","[","]","|","^","$","(",")","?","*","+","{"];return(0,Ne.find)(e,function(t){return r.source.indexOf(t)!==-1})===void 0}function BS(r){var e=r.ignoreCase?"i":"";return new RegExp("^(?:"+r.source+")",e)}Ze.addStartOfInput=BS;function bS(r){var e=r.ignoreCase?"iy":"y";return new RegExp(""+r.source,e)}Ze.addStickyFlag=bS;function uEe(r,e,t){var i=[];return(0,Ne.has)(r,Ze.DEFAULT_MODE)||i.push({message:"A MultiMode Lexer cannot be initialized without a <"+Ze.DEFAULT_MODE+`> property in its definition -`,type:Ar.LexerDefinitionErrorType.MULTI_MODE_LEXER_WITHOUT_DEFAULT_MODE}),(0,Ne.has)(r,Ze.MODES)||i.push({message:"A MultiMode Lexer cannot be initialized without a <"+Ze.MODES+`> property in its definition -`,type:Ar.LexerDefinitionErrorType.MULTI_MODE_LEXER_WITHOUT_MODES_PROPERTY}),(0,Ne.has)(r,Ze.MODES)&&(0,Ne.has)(r,Ze.DEFAULT_MODE)&&!(0,Ne.has)(r.modes,r.defaultMode)&&i.push({message:"A MultiMode Lexer cannot be initialized with a "+Ze.DEFAULT_MODE+": <"+r.defaultMode+`>which does not exist -`,type:Ar.LexerDefinitionErrorType.MULTI_MODE_LEXER_DEFAULT_MODE_VALUE_DOES_NOT_EXIST}),(0,Ne.has)(r,Ze.MODES)&&(0,Ne.forEach)(r.modes,function(n,s){(0,Ne.forEach)(n,function(o,a){(0,Ne.isUndefined)(o)&&i.push({message:"A Lexer cannot be initialized using an undefined Token Type. Mode:"+("<"+s+"> at index: <"+a+`> -`),type:Ar.LexerDefinitionErrorType.LEXER_DEFINITION_CANNOT_CONTAIN_UNDEFINED})})}),i}Ze.performRuntimeChecks=uEe;function gEe(r,e,t){var i=[],n=!1,s=(0,Ne.compact)((0,Ne.flatten)((0,Ne.mapValues)(r.modes,function(l){return l}))),o=(0,Ne.reject)(s,function(l){return l[Mo]===Ar.Lexer.NA}),a=OH(t);return e&&(0,Ne.forEach)(o,function(l){var c=TH(l,a);if(c!==!1){var u=zH(l,c),g={message:u,type:c.issue,tokenType:l};i.push(g)}else(0,Ne.has)(l,"LINE_BREAKS")?l.LINE_BREAKS===!0&&(n=!0):(0,Cg.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:Ar.LexerDefinitionErrorType.NO_LINE_BREAKS_FLAGS}),i}Ze.performWarningRuntimeChecks=gEe;function fEe(r){var e={},t=(0,Ne.keys)(r);return(0,Ne.forEach)(t,function(i){var n=r[i];if((0,Ne.isArray)(n))e[i]=[];else throw Error("non exhaustive match")}),e}Ze.cloneEmptyGroups=fEe;function QS(r){var e=r.PATTERN;if((0,Ne.isRegExp)(e))return!1;if((0,Ne.isFunction)(e))return!0;if((0,Ne.has)(e,"exec"))return!0;if((0,Ne.isString)(e))return!1;throw Error("non exhaustive match")}Ze.isCustomPattern=QS;function LH(r){return(0,Ne.isString)(r)&&r.length===1?r.charCodeAt(0):!1}Ze.isShortPattern=LH;Ze.LineTerminatorOptimizedTester={test:function(r){for(var e=r.length,t=this.lastIndex;t Token Type -`)+(" Root cause: "+e.errMsg+`. -`)+" For details See: https://chevrotain.io/docs/guide/resolving_lexer_errors.html#IDENTIFY_TERMINATOR";if(e.issue===Ar.LexerDefinitionErrorType.CUSTOM_LINE_BREAK)return`Warning: A Custom Token Pattern should specify the option. -`+(" The problem is in the <"+r.name+`> Token Type -`)+" For details See: https://chevrotain.io/docs/guide/resolving_lexer_errors.html#CUSTOM_LINE_BREAK";throw Error("non exhaustive match")}Ze.buildLineBreakIssueMessage=zH;function OH(r){var e=(0,Ne.map)(r,function(t){return(0,Ne.isString)(t)&&t.length>0?t.charCodeAt(0):t});return e}function SS(r,e,t){r[e]===void 0?r[e]=[t]:r[e].push(t)}Ze.minOptimizationVal=256;var HI=[];function vS(r){return r255?255+~~(r/255):r}}});var mg=w(Ft=>{"use strict";Object.defineProperty(Ft,"__esModule",{value:!0});Ft.isTokenType=Ft.hasExtendingTokensTypesMapProperty=Ft.hasExtendingTokensTypesProperty=Ft.hasCategoriesProperty=Ft.hasShortKeyProperty=Ft.singleAssignCategoriesToksMap=Ft.assignCategoriesMapProp=Ft.assignCategoriesTokensProp=Ft.assignTokenDefaultProps=Ft.expandCategories=Ft.augmentTokenTypes=Ft.tokenIdxToClass=Ft.tokenShortNameIdx=Ft.tokenStructuredMatcherNoCategories=Ft.tokenStructuredMatcher=void 0;var ii=Yt();function hEe(r,e){var t=r.tokenTypeIdx;return t===e.tokenTypeIdx?!0:e.isParent===!0&&e.categoryMatchesMap[t]===!0}Ft.tokenStructuredMatcher=hEe;function pEe(r,e){return r.tokenTypeIdx===e.tokenTypeIdx}Ft.tokenStructuredMatcherNoCategories=pEe;Ft.tokenShortNameIdx=1;Ft.tokenIdxToClass={};function dEe(r){var e=_H(r);VH(e),ZH(e),XH(e),(0,ii.forEach)(e,function(t){t.isParent=t.categoryMatches.length>0})}Ft.augmentTokenTypes=dEe;function _H(r){for(var e=(0,ii.cloneArr)(r),t=r,i=!0;i;){t=(0,ii.compact)((0,ii.flatten)((0,ii.map)(t,function(s){return s.CATEGORIES})));var n=(0,ii.difference)(t,e);e=e.concat(n),(0,ii.isEmpty)(n)?i=!1:t=n}return e}Ft.expandCategories=_H;function VH(r){(0,ii.forEach)(r,function(e){$H(e)||(Ft.tokenIdxToClass[Ft.tokenShortNameIdx]=e,e.tokenTypeIdx=Ft.tokenShortNameIdx++),xS(e)&&!(0,ii.isArray)(e.CATEGORIES)&&(e.CATEGORIES=[e.CATEGORIES]),xS(e)||(e.CATEGORIES=[]),ej(e)||(e.categoryMatches=[]),tj(e)||(e.categoryMatchesMap={})})}Ft.assignTokenDefaultProps=VH;function XH(r){(0,ii.forEach)(r,function(e){e.categoryMatches=[],(0,ii.forEach)(e.categoryMatchesMap,function(t,i){e.categoryMatches.push(Ft.tokenIdxToClass[i].tokenTypeIdx)})})}Ft.assignCategoriesTokensProp=XH;function ZH(r){(0,ii.forEach)(r,function(e){kS([],e)})}Ft.assignCategoriesMapProp=ZH;function kS(r,e){(0,ii.forEach)(r,function(t){e.categoryMatchesMap[t.tokenTypeIdx]=!0}),(0,ii.forEach)(e.CATEGORIES,function(t){var i=r.concat(e);(0,ii.contains)(i,t)||kS(i,t)})}Ft.singleAssignCategoriesToksMap=kS;function $H(r){return(0,ii.has)(r,"tokenTypeIdx")}Ft.hasShortKeyProperty=$H;function xS(r){return(0,ii.has)(r,"CATEGORIES")}Ft.hasCategoriesProperty=xS;function ej(r){return(0,ii.has)(r,"categoryMatches")}Ft.hasExtendingTokensTypesProperty=ej;function tj(r){return(0,ii.has)(r,"categoryMatchesMap")}Ft.hasExtendingTokensTypesMapProperty=tj;function CEe(r){return(0,ii.has)(r,"tokenTypeIdx")}Ft.isTokenType=CEe});var PS=w(jI=>{"use strict";Object.defineProperty(jI,"__esModule",{value:!0});jI.defaultLexerErrorProvider=void 0;jI.defaultLexerErrorProvider={buildUnableToPopLexerModeMessage:function(r){return"Unable to pop Lexer Mode after encountering Token ->"+r.image+"<- The Mode Stack is empty"},buildUnexpectedCharactersMessage:function(r,e,t,i,n){return"unexpected character: ->"+r.charAt(e)+"<- at offset: "+e+","+(" skipped "+t+" characters.")}}});var Dp=w(kc=>{"use strict";Object.defineProperty(kc,"__esModule",{value:!0});kc.Lexer=kc.LexerDefinitionErrorType=void 0;var ao=yS(),lr=Yt(),mEe=mg(),EEe=PS(),IEe=MI(),yEe;(function(r){r[r.MISSING_PATTERN=0]="MISSING_PATTERN",r[r.INVALID_PATTERN=1]="INVALID_PATTERN",r[r.EOI_ANCHOR_FOUND=2]="EOI_ANCHOR_FOUND",r[r.UNSUPPORTED_FLAGS_FOUND=3]="UNSUPPORTED_FLAGS_FOUND",r[r.DUPLICATE_PATTERNS_FOUND=4]="DUPLICATE_PATTERNS_FOUND",r[r.INVALID_GROUP_TYPE_FOUND=5]="INVALID_GROUP_TYPE_FOUND",r[r.PUSH_MODE_DOES_NOT_EXIST=6]="PUSH_MODE_DOES_NOT_EXIST",r[r.MULTI_MODE_LEXER_WITHOUT_DEFAULT_MODE=7]="MULTI_MODE_LEXER_WITHOUT_DEFAULT_MODE",r[r.MULTI_MODE_LEXER_WITHOUT_MODES_PROPERTY=8]="MULTI_MODE_LEXER_WITHOUT_MODES_PROPERTY",r[r.MULTI_MODE_LEXER_DEFAULT_MODE_VALUE_DOES_NOT_EXIST=9]="MULTI_MODE_LEXER_DEFAULT_MODE_VALUE_DOES_NOT_EXIST",r[r.LEXER_DEFINITION_CANNOT_CONTAIN_UNDEFINED=10]="LEXER_DEFINITION_CANNOT_CONTAIN_UNDEFINED",r[r.SOI_ANCHOR_FOUND=11]="SOI_ANCHOR_FOUND",r[r.EMPTY_MATCH_PATTERN=12]="EMPTY_MATCH_PATTERN",r[r.NO_LINE_BREAKS_FLAGS=13]="NO_LINE_BREAKS_FLAGS",r[r.UNREACHABLE_PATTERN=14]="UNREACHABLE_PATTERN",r[r.IDENTIFY_TERMINATOR=15]="IDENTIFY_TERMINATOR",r[r.CUSTOM_LINE_BREAK=16]="CUSTOM_LINE_BREAK"})(yEe=kc.LexerDefinitionErrorType||(kc.LexerDefinitionErrorType={}));var Rp={deferDefinitionErrorsHandling:!1,positionTracking:"full",lineTerminatorsPattern:/\n|\r\n?/g,lineTerminatorCharacters:[` -`,"\r"],ensureOptimizations:!1,safeMode:!1,errorMessageProvider:EEe.defaultLexerErrorProvider,traceInitPerf:!1,skipValidations:!1};Object.freeze(Rp);var wEe=function(){function r(e,t){var i=this;if(t===void 0&&(t=Rp),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 t=="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,lr.merge)(Rp,t);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===Rp.lineTerminatorsPattern)i.config.lineTerminatorsPattern=ao.LineTerminatorOptimizedTester;else if(i.config.lineTerminatorCharacters===Rp.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(t.safeMode&&t.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,lr.isArray)(e)?(s={modes:{}},s.modes[ao.DEFAULT_MODE]=(0,lr.cloneArr)(e),s[ao.DEFAULT_MODE]=ao.DEFAULT_MODE):(o=!1,s=(0,lr.cloneObj)(e))}),i.config.skipValidations===!1&&(i.TRACE_INIT("performRuntimeChecks",function(){i.lexerDefinitionErrors=i.lexerDefinitionErrors.concat((0,ao.performRuntimeChecks)(s,i.trackStartLines,i.config.lineTerminatorCharacters))}),i.TRACE_INIT("performWarningRuntimeChecks",function(){i.lexerDefinitionWarning=i.lexerDefinitionWarning.concat((0,ao.performWarningRuntimeChecks)(s,i.trackStartLines,i.config.lineTerminatorCharacters))})),s.modes=s.modes?s.modes:{},(0,lr.forEach)(s.modes,function(u,g){s.modes[g]=(0,lr.reject)(u,function(f){return(0,lr.isUndefined)(f)})});var a=(0,lr.keys)(s.modes);if((0,lr.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,ao.validatePatterns)(u,a))}),(0,lr.isEmpty)(i.lexerDefinitionErrors)){(0,mEe.augmentTokenTypes)(u);var f;i.TRACE_INIT("analyzeTokenTypes",function(){f=(0,ao.analyzeTokenTypes)(u,{lineTerminatorCharacters:i.config.lineTerminatorCharacters,positionTracking:t.positionTracking,ensureOptimizations:t.ensureOptimizations,safeMode:t.safeMode,tracer:i.TRACE_INIT.bind(i)})}),i.patternIdxToConfig[g]=f.patternIdxToConfig,i.charCodeToPatternIdxToConfig[g]=f.charCodeToPatternIdxToConfig,i.emptyGroups=(0,lr.merge)(i.emptyGroups,f.emptyGroups),i.hasCustom=f.hasCustom||i.hasCustom,i.canModeBeOptimized[g]=f.canBeOptimized}})}),i.defaultMode=s.defaultMode,!(0,lr.isEmpty)(i.lexerDefinitionErrors)&&!i.config.deferDefinitionErrorsHandling){var l=(0,lr.map)(i.lexerDefinitionErrors,function(u){return u.message}),c=l.join(`----------------------- -`);throw new Error(`Errors detected in definition of Lexer: -`+c)}(0,lr.forEach)(i.lexerDefinitionWarning,function(u){(0,lr.PRINT_WARNING)(u.message)}),i.TRACE_INIT("Choosing sub-methods implementations",function(){if(ao.SUPPORT_STICKY?(i.chopInput=lr.IDENTITY,i.match=i.matchWithTest):(i.updateLastIndex=lr.NOOP,i.match=i.matchWithExec),o&&(i.handleModes=lr.NOOP),i.trackStartLines===!1&&(i.computeNewColumn=lr.IDENTITY),i.trackEndLines===!1&&(i.updateTokenEndLineColumnLocation=lr.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,lr.reduce)(i.canModeBeOptimized,function(g,f,h){return f===!1&&g.push(h),g},[]);if(t.ensureOptimizations&&!(0,lr.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,IEe.clearRegExpParserCache)()}),i.TRACE_INIT("toFastProperties",function(){(0,lr.toFastProperties)(i)})})}return r.prototype.tokenize=function(e,t){if(t===void 0&&(t=this.defaultMode),!(0,lr.isEmpty)(this.lexerDefinitionErrors)){var i=(0,lr.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,t);return s},r.prototype.tokenizeInternal=function(e,t){var i=this,n,s,o,a,l,c,u,g,f,h,p,m,y,b,v,x,T=e,q=T.length,Y=0,$=0,_=this.hasCustom?0:Math.floor(e.length/10),ne=new Array(_),ee=[],A=this.trackStartLines?1:void 0,oe=this.trackStartLines?1:void 0,ce=(0,ao.cloneEmptyGroups)(this.emptyGroups),Z=this.trackStartLines,O=this.config.lineTerminatorsPattern,L=0,de=[],Be=[],je=[],re=[];Object.freeze(re);var se=void 0;function be(){return de}function he(Sr){var jn=(0,ao.charCodeToOptimizedIndex)(Sr),fs=Be[jn];return fs===void 0?re:fs}var Fe=function(Sr){if(je.length===1&&Sr.tokenType.PUSH_MODE===void 0){var jn=i.config.errorMessageProvider.buildUnableToPopLexerModeMessage(Sr);ee.push({offset:Sr.startOffset,line:Sr.startLine!==void 0?Sr.startLine:void 0,column:Sr.startColumn!==void 0?Sr.startColumn:void 0,length:Sr.image.length,message:jn})}else{je.pop();var fs=(0,lr.last)(je);de=i.patternIdxToConfig[fs],Be=i.charCodeToPatternIdxToConfig[fs],L=de.length;var ba=i.canModeBeOptimized[fs]&&i.config.safeMode===!1;Be&&ba?se=he:se=be}};function Ke(Sr){je.push(Sr),Be=this.charCodeToPatternIdxToConfig[Sr],de=this.patternIdxToConfig[Sr],L=de.length,L=de.length;var jn=this.canModeBeOptimized[Sr]&&this.config.safeMode===!1;Be&&jn?se=he:se=be}Ke.call(this,t);for(var ke;Yc.length){c=a,u=g,ke=gt;break}}}break}}if(c!==null){if(f=c.length,h=ke.group,h!==void 0&&(p=ke.tokenTypeIdx,m=this.createTokenInstance(c,Y,p,ke.tokenType,A,oe,f),this.handlePayload(m,u),h===!1?$=this.addToken(ne,$,m):ce[h].push(m)),e=this.chopInput(e,f),Y=Y+f,oe=this.computeNewColumn(oe,f),Z===!0&&ke.canLineTerminator===!0){var Mt=0,Ei=void 0,jt=void 0;O.lastIndex=0;do Ei=O.test(c),Ei===!0&&(jt=O.lastIndex-1,Mt++);while(Ei===!0);Mt!==0&&(A=A+Mt,oe=f-jt,this.updateTokenEndLineColumnLocation(m,h,jt,Mt,A,oe,f))}this.handleModes(ke,Fe,Ke,m)}else{for(var Qr=Y,Oi=A,Xs=oe,Un=!1;!Un&&Y <"+e+">");var n=(0,lr.timer)(t),s=n.time,o=n.value,a=s>10?console.warn:console.log;return this.traceInitIndent time: "+s+"ms"),this.traceInitIndent--,o}else return t()},r.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.",r.NA=/NOT_APPLICABLE/,r}();kc.Lexer=wEe});var XA=w(Pi=>{"use strict";Object.defineProperty(Pi,"__esModule",{value:!0});Pi.tokenMatcher=Pi.createTokenInstance=Pi.EOF=Pi.createToken=Pi.hasTokenLabel=Pi.tokenName=Pi.tokenLabel=void 0;var Ao=Yt(),BEe=Dp(),DS=mg();function bEe(r){return rj(r)?r.LABEL:r.name}Pi.tokenLabel=bEe;function QEe(r){return r.name}Pi.tokenName=QEe;function rj(r){return(0,Ao.isString)(r.LABEL)&&r.LABEL!==""}Pi.hasTokenLabel=rj;var SEe="parent",ij="categories",nj="label",sj="group",oj="push_mode",aj="pop_mode",Aj="longer_alt",lj="line_breaks",cj="start_chars_hint";function uj(r){return vEe(r)}Pi.createToken=uj;function vEe(r){var e=r.pattern,t={};if(t.name=r.name,(0,Ao.isUndefined)(e)||(t.PATTERN=e),(0,Ao.has)(r,SEe))throw`The parent property is no longer supported. -See: https://github.com/chevrotain/chevrotain/issues/564#issuecomment-349062346 for details.`;return(0,Ao.has)(r,ij)&&(t.CATEGORIES=r[ij]),(0,DS.augmentTokenTypes)([t]),(0,Ao.has)(r,nj)&&(t.LABEL=r[nj]),(0,Ao.has)(r,sj)&&(t.GROUP=r[sj]),(0,Ao.has)(r,aj)&&(t.POP_MODE=r[aj]),(0,Ao.has)(r,oj)&&(t.PUSH_MODE=r[oj]),(0,Ao.has)(r,Aj)&&(t.LONGER_ALT=r[Aj]),(0,Ao.has)(r,lj)&&(t.LINE_BREAKS=r[lj]),(0,Ao.has)(r,cj)&&(t.START_CHARS_HINT=r[cj]),t}Pi.EOF=uj({name:"EOF",pattern:BEe.Lexer.NA});(0,DS.augmentTokenTypes)([Pi.EOF]);function xEe(r,e,t,i,n,s,o,a){return{image:e,startOffset:t,endOffset:i,startLine:n,endLine:s,startColumn:o,endColumn:a,tokenTypeIdx:r.tokenTypeIdx,tokenType:r}}Pi.createTokenInstance=xEe;function kEe(r,e){return(0,DS.tokenStructuredMatcher)(r,e)}Pi.tokenMatcher=kEe});var bn=w(Vt=>{"use strict";var Ga=Vt&&Vt.__extends||function(){var r=function(e,t){return r=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])},r(e,t)};return function(e,t){if(typeof t!="function"&&t!==null)throw new TypeError("Class extends value "+String(t)+" is not a constructor or null");r(e,t);function i(){this.constructor=e}e.prototype=t===null?Object.create(t):(i.prototype=t.prototype,new i)}}();Object.defineProperty(Vt,"__esModule",{value:!0});Vt.serializeProduction=Vt.serializeGrammar=Vt.Terminal=Vt.Alternation=Vt.RepetitionWithSeparator=Vt.Repetition=Vt.RepetitionMandatoryWithSeparator=Vt.RepetitionMandatory=Vt.Option=Vt.Alternative=Vt.Rule=Vt.NonTerminal=Vt.AbstractProduction=void 0;var fr=Yt(),PEe=XA(),Ko=function(){function r(e){this._definition=e}return Object.defineProperty(r.prototype,"definition",{get:function(){return this._definition},set:function(e){this._definition=e},enumerable:!1,configurable:!0}),r.prototype.accept=function(e){e.visit(this),(0,fr.forEach)(this.definition,function(t){t.accept(e)})},r}();Vt.AbstractProduction=Ko;var gj=function(r){Ga(e,r);function e(t){var i=r.call(this,[])||this;return i.idx=1,(0,fr.assign)(i,(0,fr.pick)(t,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(t){},enumerable:!1,configurable:!0}),e.prototype.accept=function(t){t.visit(this)},e}(Ko);Vt.NonTerminal=gj;var fj=function(r){Ga(e,r);function e(t){var i=r.call(this,t.definition)||this;return i.orgText="",(0,fr.assign)(i,(0,fr.pick)(t,function(n){return n!==void 0})),i}return e}(Ko);Vt.Rule=fj;var hj=function(r){Ga(e,r);function e(t){var i=r.call(this,t.definition)||this;return i.ignoreAmbiguities=!1,(0,fr.assign)(i,(0,fr.pick)(t,function(n){return n!==void 0})),i}return e}(Ko);Vt.Alternative=hj;var pj=function(r){Ga(e,r);function e(t){var i=r.call(this,t.definition)||this;return i.idx=1,(0,fr.assign)(i,(0,fr.pick)(t,function(n){return n!==void 0})),i}return e}(Ko);Vt.Option=pj;var dj=function(r){Ga(e,r);function e(t){var i=r.call(this,t.definition)||this;return i.idx=1,(0,fr.assign)(i,(0,fr.pick)(t,function(n){return n!==void 0})),i}return e}(Ko);Vt.RepetitionMandatory=dj;var Cj=function(r){Ga(e,r);function e(t){var i=r.call(this,t.definition)||this;return i.idx=1,(0,fr.assign)(i,(0,fr.pick)(t,function(n){return n!==void 0})),i}return e}(Ko);Vt.RepetitionMandatoryWithSeparator=Cj;var mj=function(r){Ga(e,r);function e(t){var i=r.call(this,t.definition)||this;return i.idx=1,(0,fr.assign)(i,(0,fr.pick)(t,function(n){return n!==void 0})),i}return e}(Ko);Vt.Repetition=mj;var Ej=function(r){Ga(e,r);function e(t){var i=r.call(this,t.definition)||this;return i.idx=1,(0,fr.assign)(i,(0,fr.pick)(t,function(n){return n!==void 0})),i}return e}(Ko);Vt.RepetitionWithSeparator=Ej;var Ij=function(r){Ga(e,r);function e(t){var i=r.call(this,t.definition)||this;return i.idx=1,i.ignoreAmbiguities=!1,i.hasPredicates=!1,(0,fr.assign)(i,(0,fr.pick)(t,function(n){return n!==void 0})),i}return Object.defineProperty(e.prototype,"definition",{get:function(){return this._definition},set:function(t){this._definition=t},enumerable:!1,configurable:!0}),e}(Ko);Vt.Alternation=Ij;var GI=function(){function r(e){this.idx=1,(0,fr.assign)(this,(0,fr.pick)(e,function(t){return t!==void 0}))}return r.prototype.accept=function(e){e.visit(this)},r}();Vt.Terminal=GI;function DEe(r){return(0,fr.map)(r,Fp)}Vt.serializeGrammar=DEe;function Fp(r){function e(s){return(0,fr.map)(s,Fp)}if(r instanceof gj){var t={type:"NonTerminal",name:r.nonTerminalName,idx:r.idx};return(0,fr.isString)(r.label)&&(t.label=r.label),t}else{if(r instanceof hj)return{type:"Alternative",definition:e(r.definition)};if(r instanceof pj)return{type:"Option",idx:r.idx,definition:e(r.definition)};if(r instanceof dj)return{type:"RepetitionMandatory",idx:r.idx,definition:e(r.definition)};if(r instanceof Cj)return{type:"RepetitionMandatoryWithSeparator",idx:r.idx,separator:Fp(new GI({terminalType:r.separator})),definition:e(r.definition)};if(r instanceof Ej)return{type:"RepetitionWithSeparator",idx:r.idx,separator:Fp(new GI({terminalType:r.separator})),definition:e(r.definition)};if(r instanceof mj)return{type:"Repetition",idx:r.idx,definition:e(r.definition)};if(r instanceof Ij)return{type:"Alternation",idx:r.idx,definition:e(r.definition)};if(r instanceof GI){var i={type:"Terminal",name:r.terminalType.name,label:(0,PEe.tokenLabel)(r.terminalType),idx:r.idx};(0,fr.isString)(r.label)&&(i.terminalLabel=r.label);var n=r.terminalType.PATTERN;return r.terminalType.PATTERN&&(i.pattern=(0,fr.isRegExp)(n)?n.source:n),i}else{if(r instanceof fj)return{type:"Rule",name:r.name,orgText:r.orgText,definition:e(r.definition)};throw Error("non exhaustive match")}}}Vt.serializeProduction=Fp});var qI=w(YI=>{"use strict";Object.defineProperty(YI,"__esModule",{value:!0});YI.RestWalker=void 0;var RS=Yt(),Qn=bn(),REe=function(){function r(){}return r.prototype.walk=function(e,t){var i=this;t===void 0&&(t=[]),(0,RS.forEach)(e.definition,function(n,s){var o=(0,RS.drop)(e.definition,s+1);if(n instanceof Qn.NonTerminal)i.walkProdRef(n,o,t);else if(n instanceof Qn.Terminal)i.walkTerminal(n,o,t);else if(n instanceof Qn.Alternative)i.walkFlat(n,o,t);else if(n instanceof Qn.Option)i.walkOption(n,o,t);else if(n instanceof Qn.RepetitionMandatory)i.walkAtLeastOne(n,o,t);else if(n instanceof Qn.RepetitionMandatoryWithSeparator)i.walkAtLeastOneSep(n,o,t);else if(n instanceof Qn.RepetitionWithSeparator)i.walkManySep(n,o,t);else if(n instanceof Qn.Repetition)i.walkMany(n,o,t);else if(n instanceof Qn.Alternation)i.walkOr(n,o,t);else throw Error("non exhaustive match")})},r.prototype.walkTerminal=function(e,t,i){},r.prototype.walkProdRef=function(e,t,i){},r.prototype.walkFlat=function(e,t,i){var n=t.concat(i);this.walk(e,n)},r.prototype.walkOption=function(e,t,i){var n=t.concat(i);this.walk(e,n)},r.prototype.walkAtLeastOne=function(e,t,i){var n=[new Qn.Option({definition:e.definition})].concat(t,i);this.walk(e,n)},r.prototype.walkAtLeastOneSep=function(e,t,i){var n=yj(e,t,i);this.walk(e,n)},r.prototype.walkMany=function(e,t,i){var n=[new Qn.Option({definition:e.definition})].concat(t,i);this.walk(e,n)},r.prototype.walkManySep=function(e,t,i){var n=yj(e,t,i);this.walk(e,n)},r.prototype.walkOr=function(e,t,i){var n=this,s=t.concat(i);(0,RS.forEach)(e.definition,function(o){var a=new Qn.Alternative({definition:[o]});n.walk(a,s)})},r}();YI.RestWalker=REe;function yj(r,e,t){var i=[new Qn.Option({definition:[new Qn.Terminal({terminalType:r.separator})].concat(r.definition)})],n=i.concat(e,t);return n}});var Eg=w(JI=>{"use strict";Object.defineProperty(JI,"__esModule",{value:!0});JI.GAstVisitor=void 0;var Uo=bn(),FEe=function(){function r(){}return r.prototype.visit=function(e){var t=e;switch(t.constructor){case Uo.NonTerminal:return this.visitNonTerminal(t);case Uo.Alternative:return this.visitAlternative(t);case Uo.Option:return this.visitOption(t);case Uo.RepetitionMandatory:return this.visitRepetitionMandatory(t);case Uo.RepetitionMandatoryWithSeparator:return this.visitRepetitionMandatoryWithSeparator(t);case Uo.RepetitionWithSeparator:return this.visitRepetitionWithSeparator(t);case Uo.Repetition:return this.visitRepetition(t);case Uo.Alternation:return this.visitAlternation(t);case Uo.Terminal:return this.visitTerminal(t);case Uo.Rule:return this.visitRule(t);default:throw Error("non exhaustive match")}},r.prototype.visitNonTerminal=function(e){},r.prototype.visitAlternative=function(e){},r.prototype.visitOption=function(e){},r.prototype.visitRepetition=function(e){},r.prototype.visitRepetitionMandatory=function(e){},r.prototype.visitRepetitionMandatoryWithSeparator=function(e){},r.prototype.visitRepetitionWithSeparator=function(e){},r.prototype.visitAlternation=function(e){},r.prototype.visitTerminal=function(e){},r.prototype.visitRule=function(e){},r}();JI.GAstVisitor=FEe});var Lp=w(Gi=>{"use strict";var NEe=Gi&&Gi.__extends||function(){var r=function(e,t){return r=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])},r(e,t)};return function(e,t){if(typeof t!="function"&&t!==null)throw new TypeError("Class extends value "+String(t)+" is not a constructor or null");r(e,t);function i(){this.constructor=e}e.prototype=t===null?Object.create(t):(i.prototype=t.prototype,new i)}}();Object.defineProperty(Gi,"__esModule",{value:!0});Gi.collectMethods=Gi.DslMethodsCollectorVisitor=Gi.getProductionDslName=Gi.isBranchingProd=Gi.isOptionalProd=Gi.isSequenceProd=void 0;var Np=Yt(),xr=bn(),LEe=Eg();function TEe(r){return r instanceof xr.Alternative||r instanceof xr.Option||r instanceof xr.Repetition||r instanceof xr.RepetitionMandatory||r instanceof xr.RepetitionMandatoryWithSeparator||r instanceof xr.RepetitionWithSeparator||r instanceof xr.Terminal||r instanceof xr.Rule}Gi.isSequenceProd=TEe;function FS(r,e){e===void 0&&(e=[]);var t=r instanceof xr.Option||r instanceof xr.Repetition||r instanceof xr.RepetitionWithSeparator;return t?!0:r instanceof xr.Alternation?(0,Np.some)(r.definition,function(i){return FS(i,e)}):r instanceof xr.NonTerminal&&(0,Np.contains)(e,r)?!1:r instanceof xr.AbstractProduction?(r instanceof xr.NonTerminal&&e.push(r),(0,Np.every)(r.definition,function(i){return FS(i,e)})):!1}Gi.isOptionalProd=FS;function OEe(r){return r instanceof xr.Alternation}Gi.isBranchingProd=OEe;function MEe(r){if(r instanceof xr.NonTerminal)return"SUBRULE";if(r instanceof xr.Option)return"OPTION";if(r instanceof xr.Alternation)return"OR";if(r instanceof xr.RepetitionMandatory)return"AT_LEAST_ONE";if(r instanceof xr.RepetitionMandatoryWithSeparator)return"AT_LEAST_ONE_SEP";if(r instanceof xr.RepetitionWithSeparator)return"MANY_SEP";if(r instanceof xr.Repetition)return"MANY";if(r instanceof xr.Terminal)return"CONSUME";throw Error("non exhaustive match")}Gi.getProductionDslName=MEe;var wj=function(r){NEe(e,r);function e(){var t=r!==null&&r.apply(this,arguments)||this;return t.separator="-",t.dslMethods={option:[],alternation:[],repetition:[],repetitionWithSeparator:[],repetitionMandatory:[],repetitionMandatoryWithSeparator:[]},t}return e.prototype.reset=function(){this.dslMethods={option:[],alternation:[],repetition:[],repetitionWithSeparator:[],repetitionMandatory:[],repetitionMandatoryWithSeparator:[]}},e.prototype.visitTerminal=function(t){var i=t.terminalType.name+this.separator+"Terminal";(0,Np.has)(this.dslMethods,i)||(this.dslMethods[i]=[]),this.dslMethods[i].push(t)},e.prototype.visitNonTerminal=function(t){var i=t.nonTerminalName+this.separator+"Terminal";(0,Np.has)(this.dslMethods,i)||(this.dslMethods[i]=[]),this.dslMethods[i].push(t)},e.prototype.visitOption=function(t){this.dslMethods.option.push(t)},e.prototype.visitRepetitionWithSeparator=function(t){this.dslMethods.repetitionWithSeparator.push(t)},e.prototype.visitRepetitionMandatory=function(t){this.dslMethods.repetitionMandatory.push(t)},e.prototype.visitRepetitionMandatoryWithSeparator=function(t){this.dslMethods.repetitionMandatoryWithSeparator.push(t)},e.prototype.visitRepetition=function(t){this.dslMethods.repetition.push(t)},e.prototype.visitAlternation=function(t){this.dslMethods.alternation.push(t)},e}(LEe.GAstVisitor);Gi.DslMethodsCollectorVisitor=wj;var WI=new wj;function KEe(r){WI.reset(),r.accept(WI);var e=WI.dslMethods;return WI.reset(),e}Gi.collectMethods=KEe});var LS=w(Ho=>{"use strict";Object.defineProperty(Ho,"__esModule",{value:!0});Ho.firstForTerminal=Ho.firstForBranching=Ho.firstForSequence=Ho.first=void 0;var zI=Yt(),Bj=bn(),NS=Lp();function _I(r){if(r instanceof Bj.NonTerminal)return _I(r.referencedRule);if(r instanceof Bj.Terminal)return Sj(r);if((0,NS.isSequenceProd)(r))return bj(r);if((0,NS.isBranchingProd)(r))return Qj(r);throw Error("non exhaustive match")}Ho.first=_I;function bj(r){for(var e=[],t=r.definition,i=0,n=t.length>i,s,o=!0;n&&o;)s=t[i],o=(0,NS.isOptionalProd)(s),e=e.concat(_I(s)),i=i+1,n=t.length>i;return(0,zI.uniq)(e)}Ho.firstForSequence=bj;function Qj(r){var e=(0,zI.map)(r.definition,function(t){return _I(t)});return(0,zI.uniq)((0,zI.flatten)(e))}Ho.firstForBranching=Qj;function Sj(r){return[r.terminalType]}Ho.firstForTerminal=Sj});var TS=w(VI=>{"use strict";Object.defineProperty(VI,"__esModule",{value:!0});VI.IN=void 0;VI.IN="_~IN~_"});var Dj=w(vs=>{"use strict";var UEe=vs&&vs.__extends||function(){var r=function(e,t){return r=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])},r(e,t)};return function(e,t){if(typeof t!="function"&&t!==null)throw new TypeError("Class extends value "+String(t)+" is not a constructor or null");r(e,t);function i(){this.constructor=e}e.prototype=t===null?Object.create(t):(i.prototype=t.prototype,new i)}}();Object.defineProperty(vs,"__esModule",{value:!0});vs.buildInProdFollowPrefix=vs.buildBetweenProdsFollowPrefix=vs.computeAllProdsFollows=vs.ResyncFollowsWalker=void 0;var HEe=qI(),jEe=LS(),vj=Yt(),xj=TS(),GEe=bn(),Pj=function(r){UEe(e,r);function e(t){var i=r.call(this)||this;return i.topProd=t,i.follows={},i}return e.prototype.startWalking=function(){return this.walk(this.topProd),this.follows},e.prototype.walkTerminal=function(t,i,n){},e.prototype.walkProdRef=function(t,i,n){var s=kj(t.referencedRule,t.idx)+this.topProd.name,o=i.concat(n),a=new GEe.Alternative({definition:o}),l=(0,jEe.first)(a);this.follows[s]=l},e}(HEe.RestWalker);vs.ResyncFollowsWalker=Pj;function YEe(r){var e={};return(0,vj.forEach)(r,function(t){var i=new Pj(t).startWalking();(0,vj.assign)(e,i)}),e}vs.computeAllProdsFollows=YEe;function kj(r,e){return r.name+e+xj.IN}vs.buildBetweenProdsFollowPrefix=kj;function qEe(r){var e=r.terminalType.name;return e+r.idx+xj.IN}vs.buildInProdFollowPrefix=qEe});var Tp=w(Ya=>{"use strict";Object.defineProperty(Ya,"__esModule",{value:!0});Ya.defaultGrammarValidatorErrorProvider=Ya.defaultGrammarResolverErrorProvider=Ya.defaultParserErrorProvider=void 0;var Ig=XA(),JEe=Yt(),lo=Yt(),OS=bn(),Rj=Lp();Ya.defaultParserErrorProvider={buildMismatchTokenMessage:function(r){var e=r.expected,t=r.actual,i=r.previous,n=r.ruleName,s=(0,Ig.hasTokenLabel)(e),o=s?"--> "+(0,Ig.tokenLabel)(e)+" <--":"token of type --> "+e.name+" <--",a="Expecting "+o+" but found --> '"+t.image+"' <--";return a},buildNotAllInputParsedMessage:function(r){var e=r.firstRedundant,t=r.ruleName;return"Redundant input, expecting EOF but found: "+e.image},buildNoViableAltMessage:function(r){var e=r.expectedPathsPerAlt,t=r.actual,i=r.previous,n=r.customUserDescription,s=r.ruleName,o="Expecting: ",a=(0,lo.first)(t).image,l=` -but found: '`+a+"'";if(n)return o+n+l;var c=(0,lo.reduce)(e,function(h,p){return h.concat(p)},[]),u=(0,lo.map)(c,function(h){return"["+(0,lo.map)(h,function(p){return(0,Ig.tokenLabel)(p)}).join(", ")+"]"}),g=(0,lo.map)(u,function(h,p){return" "+(p+1)+". "+h}),f=`one of these possible Token sequences: -`+g.join(` -`);return o+f+l},buildEarlyExitMessage:function(r){var e=r.expectedIterationPaths,t=r.actual,i=r.customUserDescription,n=r.ruleName,s="Expecting: ",o=(0,lo.first)(t).image,a=` -but found: '`+o+"'";if(i)return s+i+a;var l=(0,lo.map)(e,function(u){return"["+(0,lo.map)(u,function(g){return(0,Ig.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(Ya.defaultParserErrorProvider);Ya.defaultGrammarResolverErrorProvider={buildRuleNotFoundError:function(r,e){var t="Invalid grammar, reference to a rule which is not defined: ->"+e.nonTerminalName+`<- -inside top level rule: ->`+r.name+"<-";return t}};Ya.defaultGrammarValidatorErrorProvider={buildDuplicateFoundError:function(r,e){function t(u){return u instanceof OS.Terminal?u.terminalType.name:u instanceof OS.NonTerminal?u.nonTerminalName:""}var i=r.name,n=(0,lo.first)(e),s=n.idx,o=(0,Rj.getProductionDslName)(n),a=t(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(r){var e=`Namespace conflict found in grammar. -`+("The grammar has both a Terminal(Token) and a Non-Terminal(Rule) named: <"+r.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(r){var e=(0,lo.map)(r.prefixPath,function(n){return(0,Ig.tokenLabel)(n)}).join(", "),t=r.alternation.idx===0?"":r.alternation.idx,i="Ambiguous alternatives: <"+r.ambiguityIndices.join(" ,")+`> due to common lookahead prefix -`+("in inside <"+r.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(r){var e=(0,lo.map)(r.prefixPath,function(n){return(0,Ig.tokenLabel)(n)}).join(", "),t=r.alternation.idx===0?"":r.alternation.idx,i="Ambiguous Alternatives Detected: <"+r.ambiguityIndices.join(" ,")+"> in "+(" inside <"+r.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(r){var e=(0,Rj.getProductionDslName)(r.repetition);r.repetition.idx!==0&&(e+=r.repetition.idx);var t="The repetition <"+e+"> within Rule <"+r.topLevelRule.name+`> can never consume any tokens. -This could lead to an infinite loop.`;return t},buildTokenNameError:function(r){return"deprecated"},buildEmptyAlternationError:function(r){var e="Ambiguous empty alternative: <"+(r.emptyChoiceIdx+1)+">"+(" in inside <"+r.topLevelRule.name+`> Rule. -`)+"Only the last alternative may be an empty alternative.";return e},buildTooManyAlternativesError:function(r){var e=`An Alternation cannot have more than 256 alternatives: -`+(" inside <"+r.topLevelRule.name+`> Rule. - has `+(r.alternation.definition.length+1)+" alternatives.");return e},buildLeftRecursionError:function(r){var e=r.topLevelRule.name,t=JEe.map(r.leftRecursionPath,function(s){return s.name}),i=e+" --> "+t.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(r){return"deprecated"},buildDuplicateRuleNameError:function(r){var e;r.topLevelRule instanceof OS.Rule?e=r.topLevelRule.name:e=r.topLevelRule;var t="Duplicate definition, rule: ->"+e+"<- is already defined in the grammar: ->"+r.grammarName+"<-";return t}}});var Lj=w(ZA=>{"use strict";var WEe=ZA&&ZA.__extends||function(){var r=function(e,t){return r=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])},r(e,t)};return function(e,t){if(typeof t!="function"&&t!==null)throw new TypeError("Class extends value "+String(t)+" is not a constructor or null");r(e,t);function i(){this.constructor=e}e.prototype=t===null?Object.create(t):(i.prototype=t.prototype,new i)}}();Object.defineProperty(ZA,"__esModule",{value:!0});ZA.GastRefResolverVisitor=ZA.resolveGrammar=void 0;var zEe=$n(),Fj=Yt(),_Ee=Eg();function VEe(r,e){var t=new Nj(r,e);return t.resolveRefs(),t.errors}ZA.resolveGrammar=VEe;var Nj=function(r){WEe(e,r);function e(t,i){var n=r.call(this)||this;return n.nameToTopRule=t,n.errMsgProvider=i,n.errors=[],n}return e.prototype.resolveRefs=function(){var t=this;(0,Fj.forEach)((0,Fj.values)(this.nameToTopRule),function(i){t.currTopLevel=i,i.accept(t)})},e.prototype.visitNonTerminal=function(t){var i=this.nameToTopRule[t.nonTerminalName];if(i)t.referencedRule=i;else{var n=this.errMsgProvider.buildRuleNotFoundError(this.currTopLevel,t);this.errors.push({message:n,type:zEe.ParserDefinitionErrorType.UNRESOLVED_SUBRULE_REF,ruleName:this.currTopLevel.name,unresolvedRefName:t.nonTerminalName})}},e}(_Ee.GAstVisitor);ZA.GastRefResolverVisitor=Nj});var Mp=w(Kr=>{"use strict";var Pc=Kr&&Kr.__extends||function(){var r=function(e,t){return r=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])},r(e,t)};return function(e,t){if(typeof t!="function"&&t!==null)throw new TypeError("Class extends value "+String(t)+" is not a constructor or null");r(e,t);function i(){this.constructor=e}e.prototype=t===null?Object.create(t):(i.prototype=t.prototype,new i)}}();Object.defineProperty(Kr,"__esModule",{value:!0});Kr.nextPossibleTokensAfter=Kr.possiblePathsFrom=Kr.NextTerminalAfterAtLeastOneSepWalker=Kr.NextTerminalAfterAtLeastOneWalker=Kr.NextTerminalAfterManySepWalker=Kr.NextTerminalAfterManyWalker=Kr.AbstractNextTerminalAfterProductionWalker=Kr.NextAfterTokenWalker=Kr.AbstractNextPossibleTokensWalker=void 0;var Tj=qI(),Kt=Yt(),XEe=LS(),Dt=bn(),Oj=function(r){Pc(e,r);function e(t,i){var n=r.call(this)||this;return n.topProd=t,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,Kt.cloneArr)(this.path.ruleStack).reverse(),this.occurrenceStack=(0,Kt.cloneArr)(this.path.occurrenceStack).reverse(),this.ruleStack.pop(),this.occurrenceStack.pop(),this.updateExpectedNext(),this.walk(this.topProd),this.possibleTokTypes},e.prototype.walk=function(t,i){i===void 0&&(i=[]),this.found||r.prototype.walk.call(this,t,i)},e.prototype.walkProdRef=function(t,i,n){if(t.referencedRule.name===this.nextProductionName&&t.idx===this.nextProductionOccurrence){var s=i.concat(n);this.updateExpectedNext(),this.walk(t.referencedRule,s)}},e.prototype.updateExpectedNext=function(){(0,Kt.isEmpty)(this.ruleStack)?(this.nextProductionName="",this.nextProductionOccurrence=0,this.isAtEndOfPath=!0):(this.nextProductionName=this.ruleStack.pop(),this.nextProductionOccurrence=this.occurrenceStack.pop())},e}(Tj.RestWalker);Kr.AbstractNextPossibleTokensWalker=Oj;var ZEe=function(r){Pc(e,r);function e(t,i){var n=r.call(this,t,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(t,i,n){if(this.isAtEndOfPath&&t.terminalType.name===this.nextTerminalName&&t.idx===this.nextTerminalOccurrence&&!this.found){var s=i.concat(n),o=new Dt.Alternative({definition:s});this.possibleTokTypes=(0,XEe.first)(o),this.found=!0}},e}(Oj);Kr.NextAfterTokenWalker=ZEe;var Op=function(r){Pc(e,r);function e(t,i){var n=r.call(this)||this;return n.topRule=t,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}(Tj.RestWalker);Kr.AbstractNextTerminalAfterProductionWalker=Op;var $Ee=function(r){Pc(e,r);function e(){return r!==null&&r.apply(this,arguments)||this}return e.prototype.walkMany=function(t,i,n){if(t.idx===this.occurrence){var s=(0,Kt.first)(i.concat(n));this.result.isEndOfRule=s===void 0,s instanceof Dt.Terminal&&(this.result.token=s.terminalType,this.result.occurrence=s.idx)}else r.prototype.walkMany.call(this,t,i,n)},e}(Op);Kr.NextTerminalAfterManyWalker=$Ee;var eIe=function(r){Pc(e,r);function e(){return r!==null&&r.apply(this,arguments)||this}return e.prototype.walkManySep=function(t,i,n){if(t.idx===this.occurrence){var s=(0,Kt.first)(i.concat(n));this.result.isEndOfRule=s===void 0,s instanceof Dt.Terminal&&(this.result.token=s.terminalType,this.result.occurrence=s.idx)}else r.prototype.walkManySep.call(this,t,i,n)},e}(Op);Kr.NextTerminalAfterManySepWalker=eIe;var tIe=function(r){Pc(e,r);function e(){return r!==null&&r.apply(this,arguments)||this}return e.prototype.walkAtLeastOne=function(t,i,n){if(t.idx===this.occurrence){var s=(0,Kt.first)(i.concat(n));this.result.isEndOfRule=s===void 0,s instanceof Dt.Terminal&&(this.result.token=s.terminalType,this.result.occurrence=s.idx)}else r.prototype.walkAtLeastOne.call(this,t,i,n)},e}(Op);Kr.NextTerminalAfterAtLeastOneWalker=tIe;var rIe=function(r){Pc(e,r);function e(){return r!==null&&r.apply(this,arguments)||this}return e.prototype.walkAtLeastOneSep=function(t,i,n){if(t.idx===this.occurrence){var s=(0,Kt.first)(i.concat(n));this.result.isEndOfRule=s===void 0,s instanceof Dt.Terminal&&(this.result.token=s.terminalType,this.result.occurrence=s.idx)}else r.prototype.walkAtLeastOneSep.call(this,t,i,n)},e}(Op);Kr.NextTerminalAfterAtLeastOneSepWalker=rIe;function Mj(r,e,t){t===void 0&&(t=[]),t=(0,Kt.cloneArr)(t);var i=[],n=0;function s(c){return c.concat((0,Kt.drop)(r,n+1))}function o(c){var u=Mj(s(c),e,t);return i.concat(u)}for(;t.length=0;ce--){var Z=b.definition[ce],O={idx:p,def:Z.definition.concat((0,Kt.drop)(h)),ruleStack:m,occurrenceStack:y};g.push(O),g.push(o)}else if(b instanceof Dt.Alternative)g.push({idx:p,def:b.definition.concat((0,Kt.drop)(h)),ruleStack:m,occurrenceStack:y});else if(b instanceof Dt.Rule)g.push(iIe(b,p,m,y));else throw Error("non exhaustive match")}}return u}Kr.nextPossibleTokensAfter=nIe;function iIe(r,e,t,i){var n=(0,Kt.cloneArr)(t);n.push(r.name);var s=(0,Kt.cloneArr)(i);return s.push(1),{idx:e,def:r.definition,ruleStack:n,occurrenceStack:s}}});var Kp=w(tr=>{"use strict";var Kj=tr&&tr.__extends||function(){var r=function(e,t){return r=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])},r(e,t)};return function(e,t){if(typeof t!="function"&&t!==null)throw new TypeError("Class extends value "+String(t)+" is not a constructor or null");r(e,t);function i(){this.constructor=e}e.prototype=t===null?Object.create(t):(i.prototype=t.prototype,new i)}}();Object.defineProperty(tr,"__esModule",{value:!0});tr.areTokenCategoriesNotUsed=tr.isStrictPrefixOfPath=tr.containsPath=tr.getLookaheadPathsForOptionalProd=tr.getLookaheadPathsForOr=tr.lookAheadSequenceFromAlternatives=tr.buildSingleAlternativeLookaheadFunction=tr.buildAlternativesLookAheadFunc=tr.buildLookaheadFuncForOptionalProd=tr.buildLookaheadFuncForOr=tr.getProdType=tr.PROD_TYPE=void 0;var cr=Yt(),Uj=Mp(),sIe=qI(),XI=mg(),$A=bn(),oIe=Eg(),ui;(function(r){r[r.OPTION=0]="OPTION",r[r.REPETITION=1]="REPETITION",r[r.REPETITION_MANDATORY=2]="REPETITION_MANDATORY",r[r.REPETITION_MANDATORY_WITH_SEPARATOR=3]="REPETITION_MANDATORY_WITH_SEPARATOR",r[r.REPETITION_WITH_SEPARATOR=4]="REPETITION_WITH_SEPARATOR",r[r.ALTERNATION=5]="ALTERNATION"})(ui=tr.PROD_TYPE||(tr.PROD_TYPE={}));function aIe(r){if(r instanceof $A.Option)return ui.OPTION;if(r instanceof $A.Repetition)return ui.REPETITION;if(r instanceof $A.RepetitionMandatory)return ui.REPETITION_MANDATORY;if(r instanceof $A.RepetitionMandatoryWithSeparator)return ui.REPETITION_MANDATORY_WITH_SEPARATOR;if(r instanceof $A.RepetitionWithSeparator)return ui.REPETITION_WITH_SEPARATOR;if(r instanceof $A.Alternation)return ui.ALTERNATION;throw Error("non exhaustive match")}tr.getProdType=aIe;function AIe(r,e,t,i,n,s){var o=Hj(r,e,t),a=MS(o)?XI.tokenStructuredMatcherNoCategories:XI.tokenStructuredMatcher;return s(o,i,a,n)}tr.buildLookaheadFuncForOr=AIe;function lIe(r,e,t,i,n,s){var o=jj(r,e,n,t),a=MS(o)?XI.tokenStructuredMatcherNoCategories:XI.tokenStructuredMatcher;return s(o[0],a,i)}tr.buildLookaheadFuncForOptionalProd=lIe;function cIe(r,e,t,i){var n=r.length,s=(0,cr.every)(r,function(l){return(0,cr.every)(l,function(c){return c.length===1})});if(e)return function(l){for(var c=(0,cr.map)(l,function(x){return x.GATE}),u=0;u{"use strict";var HS=Xt&&Xt.__extends||function(){var r=function(e,t){return r=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])},r(e,t)};return function(e,t){if(typeof t!="function"&&t!==null)throw new TypeError("Class extends value "+String(t)+" is not a constructor or null");r(e,t);function i(){this.constructor=e}e.prototype=t===null?Object.create(t):(i.prototype=t.prototype,new i)}}();Object.defineProperty(Xt,"__esModule",{value:!0});Xt.checkPrefixAlternativesAmbiguities=Xt.validateSomeNonEmptyLookaheadPath=Xt.validateTooManyAlts=Xt.RepetionCollector=Xt.validateAmbiguousAlternationAlternatives=Xt.validateEmptyOrAlternative=Xt.getFirstNoneTerminal=Xt.validateNoLeftRecursion=Xt.validateRuleIsOverridden=Xt.validateRuleDoesNotAlreadyExist=Xt.OccurrenceValidationCollector=Xt.identifyProductionForDuplicates=Xt.validateGrammar=void 0;var nr=Yt(),kr=Yt(),jo=$n(),jS=Lp(),yg=Kp(),pIe=Mp(),co=bn(),GS=Eg();function mIe(r,e,t,i,n){var s=nr.map(r,function(h){return dIe(h,i)}),o=nr.map(r,function(h){return YS(h,h,i)}),a=[],l=[],c=[];(0,kr.every)(o,kr.isEmpty)&&(a=(0,kr.map)(r,function(h){return Wj(h,i)}),l=(0,kr.map)(r,function(h){return zj(h,e,i)}),c=Vj(r,e,i));var u=CIe(r,t,i),g=(0,kr.map)(r,function(h){return _j(h,i)}),f=(0,kr.map)(r,function(h){return Jj(h,r,n,i)});return nr.flatten(s.concat(c,o,a,l,u,g,f))}Xt.validateGrammar=mIe;function dIe(r,e){var t=new $j;r.accept(t);var i=t.allProductions,n=nr.groupBy(i,Xj),s=nr.pick(n,function(a){return a.length>1}),o=nr.map(nr.values(s),function(a){var l=nr.first(a),c=e.buildDuplicateFoundError(r,a),u=(0,jS.getProductionDslName)(l),g={message:c,type:jo.ParserDefinitionErrorType.DUPLICATE_PRODUCTIONS,ruleName:r.name,dslName:u,occurrence:l.idx},f=Zj(l);return f&&(g.parameter=f),g});return o}function Xj(r){return(0,jS.getProductionDslName)(r)+"_#_"+r.idx+"_#_"+Zj(r)}Xt.identifyProductionForDuplicates=Xj;function Zj(r){return r instanceof co.Terminal?r.terminalType.name:r instanceof co.NonTerminal?r.nonTerminalName:""}var $j=function(r){HS(e,r);function e(){var t=r!==null&&r.apply(this,arguments)||this;return t.allProductions=[],t}return e.prototype.visitNonTerminal=function(t){this.allProductions.push(t)},e.prototype.visitOption=function(t){this.allProductions.push(t)},e.prototype.visitRepetitionWithSeparator=function(t){this.allProductions.push(t)},e.prototype.visitRepetitionMandatory=function(t){this.allProductions.push(t)},e.prototype.visitRepetitionMandatoryWithSeparator=function(t){this.allProductions.push(t)},e.prototype.visitRepetition=function(t){this.allProductions.push(t)},e.prototype.visitAlternation=function(t){this.allProductions.push(t)},e.prototype.visitTerminal=function(t){this.allProductions.push(t)},e}(GS.GAstVisitor);Xt.OccurrenceValidationCollector=$j;function Jj(r,e,t,i){var n=[],s=(0,kr.reduce)(e,function(a,l){return l.name===r.name?a+1:a},0);if(s>1){var o=i.buildDuplicateRuleNameError({topLevelRule:r,grammarName:t});n.push({message:o,type:jo.ParserDefinitionErrorType.DUPLICATE_RULE_NAME,ruleName:r.name})}return n}Xt.validateRuleDoesNotAlreadyExist=Jj;function EIe(r,e,t){var i=[],n;return nr.contains(e,r)||(n="Invalid rule override, rule: ->"+r+"<- cannot be overridden in the grammar: ->"+t+"<-as it is not defined in any of the super grammars ",i.push({message:n,type:jo.ParserDefinitionErrorType.INVALID_RULE_OVERRIDE,ruleName:r})),i}Xt.validateRuleIsOverridden=EIe;function YS(r,e,t,i){i===void 0&&(i=[]);var n=[],s=Up(e.definition);if(nr.isEmpty(s))return[];var o=r.name,a=nr.contains(s,r);a&&n.push({message:t.buildLeftRecursionError({topLevelRule:r,leftRecursionPath:i}),type:jo.ParserDefinitionErrorType.LEFT_RECURSION,ruleName:o});var l=nr.difference(s,i.concat([r])),c=nr.map(l,function(u){var g=nr.cloneArr(i);return g.push(u),YS(r,u,t,g)});return n.concat(nr.flatten(c))}Xt.validateNoLeftRecursion=YS;function Up(r){var e=[];if(nr.isEmpty(r))return e;var t=nr.first(r);if(t instanceof co.NonTerminal)e.push(t.referencedRule);else if(t instanceof co.Alternative||t instanceof co.Option||t instanceof co.RepetitionMandatory||t instanceof co.RepetitionMandatoryWithSeparator||t instanceof co.RepetitionWithSeparator||t instanceof co.Repetition)e=e.concat(Up(t.definition));else if(t instanceof co.Alternation)e=nr.flatten(nr.map(t.definition,function(o){return Up(o.definition)}));else if(!(t instanceof co.Terminal))throw Error("non exhaustive match");var i=(0,jS.isOptionalProd)(t),n=r.length>1;if(i&&n){var s=nr.drop(r);return e.concat(Up(s))}else return e}Xt.getFirstNoneTerminal=Up;var qS=function(r){HS(e,r);function e(){var t=r!==null&&r.apply(this,arguments)||this;return t.alternations=[],t}return e.prototype.visitAlternation=function(t){this.alternations.push(t)},e}(GS.GAstVisitor);function Wj(r,e){var t=new qS;r.accept(t);var i=t.alternations,n=nr.reduce(i,function(s,o){var a=nr.dropRight(o.definition),l=nr.map(a,function(c,u){var g=(0,pIe.nextPossibleTokensAfter)([c],[],null,1);return nr.isEmpty(g)?{message:e.buildEmptyAlternationError({topLevelRule:r,alternation:o,emptyChoiceIdx:u}),type:jo.ParserDefinitionErrorType.NONE_LAST_EMPTY_ALT,ruleName:r.name,occurrence:o.idx,alternative:u+1}:null});return s.concat(nr.compact(l))},[]);return n}Xt.validateEmptyOrAlternative=Wj;function zj(r,e,t){var i=new qS;r.accept(i);var n=i.alternations;n=(0,kr.reject)(n,function(o){return o.ignoreAmbiguities===!0});var s=nr.reduce(n,function(o,a){var l=a.idx,c=a.maxLookahead||e,u=(0,yg.getLookaheadPathsForOr)(l,r,c,a),g=IIe(u,a,r,t),f=eG(u,a,r,t);return o.concat(g,f)},[]);return s}Xt.validateAmbiguousAlternationAlternatives=zj;var tG=function(r){HS(e,r);function e(){var t=r!==null&&r.apply(this,arguments)||this;return t.allProductions=[],t}return e.prototype.visitRepetitionWithSeparator=function(t){this.allProductions.push(t)},e.prototype.visitRepetitionMandatory=function(t){this.allProductions.push(t)},e.prototype.visitRepetitionMandatoryWithSeparator=function(t){this.allProductions.push(t)},e.prototype.visitRepetition=function(t){this.allProductions.push(t)},e}(GS.GAstVisitor);Xt.RepetionCollector=tG;function _j(r,e){var t=new qS;r.accept(t);var i=t.alternations,n=nr.reduce(i,function(s,o){return o.definition.length>255&&s.push({message:e.buildTooManyAlternativesError({topLevelRule:r,alternation:o}),type:jo.ParserDefinitionErrorType.TOO_MANY_ALTS,ruleName:r.name,occurrence:o.idx}),s},[]);return n}Xt.validateTooManyAlts=_j;function Vj(r,e,t){var i=[];return(0,kr.forEach)(r,function(n){var s=new tG;n.accept(s);var o=s.allProductions;(0,kr.forEach)(o,function(a){var l=(0,yg.getProdType)(a),c=a.maxLookahead||e,u=a.idx,g=(0,yg.getLookaheadPathsForOptionalProd)(u,n,l,c),f=g[0];if((0,kr.isEmpty)((0,kr.flatten)(f))){var h=t.buildEmptyRepetitionError({topLevelRule:n,repetition:a});i.push({message:h,type:jo.ParserDefinitionErrorType.NO_NON_EMPTY_LOOKAHEAD,ruleName:n.name})}})}),i}Xt.validateSomeNonEmptyLookaheadPath=Vj;function IIe(r,e,t,i){var n=[],s=(0,kr.reduce)(r,function(a,l,c){return e.definition[c].ignoreAmbiguities===!0||(0,kr.forEach)(l,function(u){var g=[c];(0,kr.forEach)(r,function(f,h){c!==h&&(0,yg.containsPath)(f,u)&&e.definition[h].ignoreAmbiguities!==!0&&g.push(h)}),g.length>1&&!(0,yg.containsPath)(n,u)&&(n.push(u),a.push({alts:g,path:u}))}),a},[]),o=nr.map(s,function(a){var l=(0,kr.map)(a.alts,function(u){return u+1}),c=i.buildAlternationAmbiguityError({topLevelRule:t,alternation:e,ambiguityIndices:l,prefixPath:a.path});return{message:c,type:jo.ParserDefinitionErrorType.AMBIGUOUS_ALTS,ruleName:t.name,occurrence:e.idx,alternatives:[a.alts]}});return o}function eG(r,e,t,i){var n=[],s=(0,kr.reduce)(r,function(o,a,l){var c=(0,kr.map)(a,function(u){return{idx:l,path:u}});return o.concat(c)},[]);return(0,kr.forEach)(s,function(o){var a=e.definition[o.idx];if(a.ignoreAmbiguities!==!0){var l=o.idx,c=o.path,u=(0,kr.findAll)(s,function(f){return e.definition[f.idx].ignoreAmbiguities!==!0&&f.idx{"use strict";Object.defineProperty(wg,"__esModule",{value:!0});wg.validateGrammar=wg.resolveGrammar=void 0;var WS=Yt(),yIe=Lj(),wIe=JS(),rG=Tp();function BIe(r){r=(0,WS.defaults)(r,{errMsgProvider:rG.defaultGrammarResolverErrorProvider});var e={};return(0,WS.forEach)(r.rules,function(t){e[t.name]=t}),(0,yIe.resolveGrammar)(e,r.errMsgProvider)}wg.resolveGrammar=BIe;function bIe(r){return r=(0,WS.defaults)(r,{errMsgProvider:rG.defaultGrammarValidatorErrorProvider}),(0,wIe.validateGrammar)(r.rules,r.maxLookahead,r.tokenTypes,r.errMsgProvider,r.grammarName)}wg.validateGrammar=bIe});var Bg=w(Sn=>{"use strict";var Hp=Sn&&Sn.__extends||function(){var r=function(e,t){return r=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])},r(e,t)};return function(e,t){if(typeof t!="function"&&t!==null)throw new TypeError("Class extends value "+String(t)+" is not a constructor or null");r(e,t);function i(){this.constructor=e}e.prototype=t===null?Object.create(t):(i.prototype=t.prototype,new i)}}();Object.defineProperty(Sn,"__esModule",{value:!0});Sn.EarlyExitException=Sn.NotAllInputParsedException=Sn.NoViableAltException=Sn.MismatchedTokenException=Sn.isRecognitionException=void 0;var QIe=Yt(),nG="MismatchedTokenException",sG="NoViableAltException",oG="EarlyExitException",aG="NotAllInputParsedException",AG=[nG,sG,oG,aG];Object.freeze(AG);function SIe(r){return(0,QIe.contains)(AG,r.name)}Sn.isRecognitionException=SIe;var ZI=function(r){Hp(e,r);function e(t,i){var n=this.constructor,s=r.call(this,t)||this;return s.token=i,s.resyncedTokens=[],Object.setPrototypeOf(s,n.prototype),Error.captureStackTrace&&Error.captureStackTrace(s,s.constructor),s}return e}(Error),vIe=function(r){Hp(e,r);function e(t,i,n){var s=r.call(this,t,i)||this;return s.previousToken=n,s.name=nG,s}return e}(ZI);Sn.MismatchedTokenException=vIe;var xIe=function(r){Hp(e,r);function e(t,i,n){var s=r.call(this,t,i)||this;return s.previousToken=n,s.name=sG,s}return e}(ZI);Sn.NoViableAltException=xIe;var kIe=function(r){Hp(e,r);function e(t,i){var n=r.call(this,t,i)||this;return n.name=aG,n}return e}(ZI);Sn.NotAllInputParsedException=kIe;var PIe=function(r){Hp(e,r);function e(t,i,n){var s=r.call(this,t,i)||this;return s.previousToken=n,s.name=oG,s}return e}(ZI);Sn.EarlyExitException=PIe});var _S=w(Yi=>{"use strict";Object.defineProperty(Yi,"__esModule",{value:!0});Yi.attemptInRepetitionRecovery=Yi.Recoverable=Yi.InRuleRecoveryException=Yi.IN_RULE_RECOVERY_EXCEPTION=Yi.EOF_FOLLOW_KEY=void 0;var $I=XA(),xs=Yt(),DIe=Bg(),RIe=TS(),FIe=$n();Yi.EOF_FOLLOW_KEY={};Yi.IN_RULE_RECOVERY_EXCEPTION="InRuleRecoveryException";function zS(r){this.name=Yi.IN_RULE_RECOVERY_EXCEPTION,this.message=r}Yi.InRuleRecoveryException=zS;zS.prototype=Error.prototype;var NIe=function(){function r(){}return r.prototype.initRecoverable=function(e){this.firstAfterRepMap={},this.resyncFollows={},this.recoveryEnabled=(0,xs.has)(e,"recoveryEnabled")?e.recoveryEnabled:FIe.DEFAULT_PARSER_CONFIG.recoveryEnabled,this.recoveryEnabled&&(this.attemptInRepetitionRecovery=lG)},r.prototype.getTokenToInsert=function(e){var t=(0,$I.createTokenInstance)(e,"",NaN,NaN,NaN,NaN,NaN,NaN);return t.isInsertedInRecovery=!0,t},r.prototype.canTokenTypeBeInsertedInRecovery=function(e){return!0},r.prototype.tryInRepetitionRecovery=function(e,t,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()}),m=new DIe.MismatchedTokenException(p,u,s.LA(0));m.resyncedTokens=(0,xs.dropRight)(l),s.SAVE_ERROR(m)};!c;)if(this.tokenMatcher(g,n)){f();return}else if(i.call(this)){f(),e.apply(this,t);return}else this.tokenMatcher(g,o)?c=!0:(g=this.SKIP_TOKEN(),this.addToResyncTokens(g,l));this.importLexerState(a)},r.prototype.shouldInRepetitionRecoveryBeTried=function(e,t,i){return!(i===!1||e===void 0||t===void 0||this.tokenMatcher(this.LA(1),e)||this.isBackTracking()||this.canPerformInRuleRecovery(e,this.getFollowsForInRuleRecovery(e,t)))},r.prototype.getFollowsForInRuleRecovery=function(e,t){var i=this.getCurrentGrammarPath(e,t),n=this.getNextPossibleTokenTypes(i);return n},r.prototype.tryInRuleRecovery=function(e,t){if(this.canRecoverWithSingleTokenInsertion(e,t)){var i=this.getTokenToInsert(e);return i}if(this.canRecoverWithSingleTokenDeletion(e)){var n=this.SKIP_TOKEN();return this.consumeToken(),n}throw new zS("sad sad panda")},r.prototype.canPerformInRuleRecovery=function(e,t){return this.canRecoverWithSingleTokenInsertion(e,t)||this.canRecoverWithSingleTokenDeletion(e)},r.prototype.canRecoverWithSingleTokenInsertion=function(e,t){var i=this;if(!this.canTokenTypeBeInsertedInRecovery(e)||(0,xs.isEmpty)(t))return!1;var n=this.LA(1),s=(0,xs.find)(t,function(o){return i.tokenMatcher(n,o)})!==void 0;return s},r.prototype.canRecoverWithSingleTokenDeletion=function(e){var t=this.tokenMatcher(this.LA(2),e);return t},r.prototype.isInCurrentRuleReSyncSet=function(e){var t=this.getCurrFollowKey(),i=this.getFollowSetFromFollowKey(t);return(0,xs.contains)(i,e)},r.prototype.findReSyncTokenType=function(){for(var e=this.flattenFollowSet(),t=this.LA(1),i=2;;){var n=t.tokenType;if((0,xs.contains)(e,n))return n;t=this.LA(i),i++}},r.prototype.getCurrFollowKey=function(){if(this.RULE_STACK.length===1)return Yi.EOF_FOLLOW_KEY;var e=this.getLastExplicitRuleShortName(),t=this.getLastExplicitRuleOccurrenceIndex(),i=this.getPreviousExplicitRuleShortName();return{ruleName:this.shortRuleNameToFullName(e),idxInCallingRule:t,inRule:this.shortRuleNameToFullName(i)}},r.prototype.buildFullFollowKeyStack=function(){var e=this,t=this.RULE_STACK,i=this.RULE_OCCURRENCE_STACK;return(0,xs.map)(t,function(n,s){return s===0?Yi.EOF_FOLLOW_KEY:{ruleName:e.shortRuleNameToFullName(n),idxInCallingRule:i[s],inRule:e.shortRuleNameToFullName(t[s-1])}})},r.prototype.flattenFollowSet=function(){var e=this,t=(0,xs.map)(this.buildFullFollowKeyStack(),function(i){return e.getFollowSetFromFollowKey(i)});return(0,xs.flatten)(t)},r.prototype.getFollowSetFromFollowKey=function(e){if(e===Yi.EOF_FOLLOW_KEY)return[$I.EOF];var t=e.ruleName+e.idxInCallingRule+RIe.IN+e.inRule;return this.resyncFollows[t]},r.prototype.addToResyncTokens=function(e,t){return this.tokenMatcher(e,$I.EOF)||t.push(e),t},r.prototype.reSyncTo=function(e){for(var t=[],i=this.LA(1);this.tokenMatcher(i,e)===!1;)i=this.SKIP_TOKEN(),this.addToResyncTokens(i,t);return(0,xs.dropRight)(t)},r.prototype.attemptInRepetitionRecovery=function(e,t,i,n,s,o,a){},r.prototype.getCurrentGrammarPath=function(e,t){var i=this.getHumanReadableRuleStack(),n=(0,xs.cloneArr)(this.RULE_OCCURRENCE_STACK),s={ruleStack:i,occurrenceStack:n,lastTok:e,lastTokOccurrence:t};return s},r.prototype.getHumanReadableRuleStack=function(){var e=this;return(0,xs.map)(this.RULE_STACK,function(t){return e.shortRuleNameToFullName(t)})},r}();Yi.Recoverable=NIe;function lG(r,e,t,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=$I.EOF,h=1),this.shouldInRepetitionRecoveryBeTried(f,h,o)&&this.tryInRepetitionRecovery(r,e,t,f)}Yi.attemptInRepetitionRecovery=lG});var ey=w(Jt=>{"use strict";Object.defineProperty(Jt,"__esModule",{value:!0});Jt.getKeyForAutomaticLookahead=Jt.AT_LEAST_ONE_SEP_IDX=Jt.MANY_SEP_IDX=Jt.AT_LEAST_ONE_IDX=Jt.MANY_IDX=Jt.OPTION_IDX=Jt.OR_IDX=Jt.BITS_FOR_ALT_IDX=Jt.BITS_FOR_RULE_IDX=Jt.BITS_FOR_OCCURRENCE_IDX=Jt.BITS_FOR_METHOD_TYPE=void 0;Jt.BITS_FOR_METHOD_TYPE=4;Jt.BITS_FOR_OCCURRENCE_IDX=8;Jt.BITS_FOR_RULE_IDX=12;Jt.BITS_FOR_ALT_IDX=8;Jt.OR_IDX=1<{"use strict";Object.defineProperty(ty,"__esModule",{value:!0});ty.LooksAhead=void 0;var qa=Kp(),uo=Yt(),cG=$n(),Ja=ey(),Dc=Lp(),TIe=function(){function r(){}return r.prototype.initLooksAhead=function(e){this.dynamicTokensEnabled=(0,uo.has)(e,"dynamicTokensEnabled")?e.dynamicTokensEnabled:cG.DEFAULT_PARSER_CONFIG.dynamicTokensEnabled,this.maxLookahead=(0,uo.has)(e,"maxLookahead")?e.maxLookahead:cG.DEFAULT_PARSER_CONFIG.maxLookahead,this.lookAheadFuncsCache=(0,uo.isES2015MapSupported)()?new Map:[],(0,uo.isES2015MapSupported)()?(this.getLaFuncFromCache=this.getLaFuncFromMap,this.setLaFuncCache=this.setLaFuncCacheUsingMap):(this.getLaFuncFromCache=this.getLaFuncFromObj,this.setLaFuncCache=this.setLaFuncUsingObj)},r.prototype.preComputeLookaheadFunctions=function(e){var t=this;(0,uo.forEach)(e,function(i){t.TRACE_INIT(i.name+" Rule Lookahead",function(){var n=(0,Dc.collectMethods)(i),s=n.alternation,o=n.repetition,a=n.option,l=n.repetitionMandatory,c=n.repetitionMandatoryWithSeparator,u=n.repetitionWithSeparator;(0,uo.forEach)(s,function(g){var f=g.idx===0?"":g.idx;t.TRACE_INIT(""+(0,Dc.getProductionDslName)(g)+f,function(){var h=(0,qa.buildLookaheadFuncForOr)(g.idx,i,g.maxLookahead||t.maxLookahead,g.hasPredicates,t.dynamicTokensEnabled,t.lookAheadBuilderForAlternatives),p=(0,Ja.getKeyForAutomaticLookahead)(t.fullRuleNameToShort[i.name],Ja.OR_IDX,g.idx);t.setLaFuncCache(p,h)})}),(0,uo.forEach)(o,function(g){t.computeLookaheadFunc(i,g.idx,Ja.MANY_IDX,qa.PROD_TYPE.REPETITION,g.maxLookahead,(0,Dc.getProductionDslName)(g))}),(0,uo.forEach)(a,function(g){t.computeLookaheadFunc(i,g.idx,Ja.OPTION_IDX,qa.PROD_TYPE.OPTION,g.maxLookahead,(0,Dc.getProductionDslName)(g))}),(0,uo.forEach)(l,function(g){t.computeLookaheadFunc(i,g.idx,Ja.AT_LEAST_ONE_IDX,qa.PROD_TYPE.REPETITION_MANDATORY,g.maxLookahead,(0,Dc.getProductionDslName)(g))}),(0,uo.forEach)(c,function(g){t.computeLookaheadFunc(i,g.idx,Ja.AT_LEAST_ONE_SEP_IDX,qa.PROD_TYPE.REPETITION_MANDATORY_WITH_SEPARATOR,g.maxLookahead,(0,Dc.getProductionDslName)(g))}),(0,uo.forEach)(u,function(g){t.computeLookaheadFunc(i,g.idx,Ja.MANY_SEP_IDX,qa.PROD_TYPE.REPETITION_WITH_SEPARATOR,g.maxLookahead,(0,Dc.getProductionDslName)(g))})})})},r.prototype.computeLookaheadFunc=function(e,t,i,n,s,o){var a=this;this.TRACE_INIT(""+o+(t===0?"":t),function(){var l=(0,qa.buildLookaheadFuncForOptionalProd)(t,e,s||a.maxLookahead,a.dynamicTokensEnabled,n,a.lookAheadBuilderForOptional),c=(0,Ja.getKeyForAutomaticLookahead)(a.fullRuleNameToShort[e.name],i,t);a.setLaFuncCache(c,l)})},r.prototype.lookAheadBuilderForOptional=function(e,t,i){return(0,qa.buildSingleAlternativeLookaheadFunction)(e,t,i)},r.prototype.lookAheadBuilderForAlternatives=function(e,t,i,n){return(0,qa.buildAlternativesLookAheadFunc)(e,t,i,n)},r.prototype.getKeyForAutomaticLookahead=function(e,t){var i=this.getLastExplicitRuleShortName();return(0,Ja.getKeyForAutomaticLookahead)(i,e,t)},r.prototype.getLaFuncFromCache=function(e){},r.prototype.getLaFuncFromMap=function(e){return this.lookAheadFuncsCache.get(e)},r.prototype.getLaFuncFromObj=function(e){return this.lookAheadFuncsCache[e]},r.prototype.setLaFuncCache=function(e,t){},r.prototype.setLaFuncCacheUsingMap=function(e,t){this.lookAheadFuncsCache.set(e,t)},r.prototype.setLaFuncUsingObj=function(e,t){this.lookAheadFuncsCache[e]=t},r}();ty.LooksAhead=TIe});var gG=w(Go=>{"use strict";Object.defineProperty(Go,"__esModule",{value:!0});Go.addNoneTerminalToCst=Go.addTerminalToCst=Go.setNodeLocationFull=Go.setNodeLocationOnlyOffset=void 0;function OIe(r,e){isNaN(r.startOffset)===!0?(r.startOffset=e.startOffset,r.endOffset=e.endOffset):r.endOffset{"use strict";Object.defineProperty(el,"__esModule",{value:!0});el.defineNameProp=el.functionName=el.classNameFromInstance=void 0;var HIe=Yt();function jIe(r){return fG(r.constructor)}el.classNameFromInstance=jIe;var hG="name";function fG(r){var e=r.name;return e||"anonymous"}el.functionName=fG;function GIe(r,e){var t=Object.getOwnPropertyDescriptor(r,hG);return(0,HIe.isUndefined)(t)||t.configurable?(Object.defineProperty(r,hG,{enumerable:!1,configurable:!0,writable:!1,value:e}),!0):!1}el.defineNameProp=GIe});var EG=w(Di=>{"use strict";Object.defineProperty(Di,"__esModule",{value:!0});Di.validateRedundantMethods=Di.validateMissingCstMethods=Di.validateVisitor=Di.CstVisitorDefinitionError=Di.createBaseVisitorConstructorWithDefaults=Di.createBaseSemanticVisitorConstructor=Di.defaultVisit=void 0;var ks=Yt(),jp=VS();function pG(r,e){for(var t=(0,ks.keys)(r),i=t.length,n=0;n: - `+(""+s.join(` - -`).replace(/\n/g,` - `)))}}};return t.prototype=i,t.prototype.constructor=t,t._RULE_NAMES=e,t}Di.createBaseSemanticVisitorConstructor=YIe;function qIe(r,e,t){var i=function(){};(0,jp.defineNameProp)(i,r+"BaseSemanticsWithDefaults");var n=Object.create(t.prototype);return(0,ks.forEach)(e,function(s){n[s]=pG}),i.prototype=n,i.prototype.constructor=i,i}Di.createBaseVisitorConstructorWithDefaults=qIe;var XS;(function(r){r[r.REDUNDANT_METHOD=0]="REDUNDANT_METHOD",r[r.MISSING_METHOD=1]="MISSING_METHOD"})(XS=Di.CstVisitorDefinitionError||(Di.CstVisitorDefinitionError={}));function dG(r,e){var t=CG(r,e),i=mG(r,e);return t.concat(i)}Di.validateVisitor=dG;function CG(r,e){var t=(0,ks.map)(e,function(i){if(!(0,ks.isFunction)(r[i]))return{msg:"Missing visitor method: <"+i+"> on "+(0,jp.functionName)(r.constructor)+" CST Visitor.",type:XS.MISSING_METHOD,methodName:i}});return(0,ks.compact)(t)}Di.validateMissingCstMethods=CG;var JIe=["constructor","visit","validateVisitor"];function mG(r,e){var t=[];for(var i in r)(0,ks.isFunction)(r[i])&&!(0,ks.contains)(JIe,i)&&!(0,ks.contains)(e,i)&&t.push({msg:"Redundant visitor method: <"+i+"> on "+(0,jp.functionName)(r.constructor)+` CST Visitor -There is no Grammar Rule corresponding to this method's name. -`,type:XS.REDUNDANT_METHOD,methodName:i});return t}Di.validateRedundantMethods=mG});var yG=w(ry=>{"use strict";Object.defineProperty(ry,"__esModule",{value:!0});ry.TreeBuilder=void 0;var bg=gG(),ni=Yt(),IG=EG(),WIe=$n(),zIe=function(){function r(){}return r.prototype.initTreeBuilder=function(e){if(this.CST_STACK=[],this.outputCst=e.outputCst,this.nodeLocationTracking=(0,ni.has)(e,"nodeLocationTracking")?e.nodeLocationTracking:WIe.DEFAULT_PARSER_CONFIG.nodeLocationTracking,!this.outputCst)this.cstInvocationStateUpdate=ni.NOOP,this.cstFinallyStateUpdate=ni.NOOP,this.cstPostTerminal=ni.NOOP,this.cstPostNonTerminal=ni.NOOP,this.cstPostRule=ni.NOOP;else if(/full/i.test(this.nodeLocationTracking))this.recoveryEnabled?(this.setNodeLocationFromToken=bg.setNodeLocationFull,this.setNodeLocationFromNode=bg.setNodeLocationFull,this.cstPostRule=ni.NOOP,this.setInitialNodeLocation=this.setInitialNodeLocationFullRecovery):(this.setNodeLocationFromToken=ni.NOOP,this.setNodeLocationFromNode=ni.NOOP,this.cstPostRule=this.cstPostRuleFull,this.setInitialNodeLocation=this.setInitialNodeLocationFullRegular);else if(/onlyOffset/i.test(this.nodeLocationTracking))this.recoveryEnabled?(this.setNodeLocationFromToken=bg.setNodeLocationOnlyOffset,this.setNodeLocationFromNode=bg.setNodeLocationOnlyOffset,this.cstPostRule=ni.NOOP,this.setInitialNodeLocation=this.setInitialNodeLocationOnlyOffsetRecovery):(this.setNodeLocationFromToken=ni.NOOP,this.setNodeLocationFromNode=ni.NOOP,this.cstPostRule=this.cstPostRuleOnlyOffset,this.setInitialNodeLocation=this.setInitialNodeLocationOnlyOffsetRegular);else if(/none/i.test(this.nodeLocationTracking))this.setNodeLocationFromToken=ni.NOOP,this.setNodeLocationFromNode=ni.NOOP,this.cstPostRule=ni.NOOP,this.setInitialNodeLocation=ni.NOOP;else throw Error('Invalid config option: "'+e.nodeLocationTracking+'"')},r.prototype.setInitialNodeLocationOnlyOffsetRecovery=function(e){e.location={startOffset:NaN,endOffset:NaN}},r.prototype.setInitialNodeLocationOnlyOffsetRegular=function(e){e.location={startOffset:this.LA(1).startOffset,endOffset:NaN}},r.prototype.setInitialNodeLocationFullRecovery=function(e){e.location={startOffset:NaN,startLine:NaN,startColumn:NaN,endOffset:NaN,endLine:NaN,endColumn:NaN}},r.prototype.setInitialNodeLocationFullRegular=function(e){var t=this.LA(1);e.location={startOffset:t.startOffset,startLine:t.startLine,startColumn:t.startColumn,endOffset:NaN,endLine:NaN,endColumn:NaN}},r.prototype.cstInvocationStateUpdate=function(e,t){var i={name:e,children:{}};this.setInitialNodeLocation(i),this.CST_STACK.push(i)},r.prototype.cstFinallyStateUpdate=function(){this.CST_STACK.pop()},r.prototype.cstPostRuleFull=function(e){var t=this.LA(0),i=e.location;i.startOffset<=t.startOffset?(i.endOffset=t.endOffset,i.endLine=t.endLine,i.endColumn=t.endColumn):(i.startOffset=NaN,i.startLine=NaN,i.startColumn=NaN)},r.prototype.cstPostRuleOnlyOffset=function(e){var t=this.LA(0),i=e.location;i.startOffset<=t.startOffset?i.endOffset=t.endOffset:i.startOffset=NaN},r.prototype.cstPostTerminal=function(e,t){var i=this.CST_STACK[this.CST_STACK.length-1];(0,bg.addTerminalToCst)(i,t,e),this.setNodeLocationFromToken(i.location,t)},r.prototype.cstPostNonTerminal=function(e,t){var i=this.CST_STACK[this.CST_STACK.length-1];(0,bg.addNoneTerminalToCst)(i,t,e),this.setNodeLocationFromNode(i.location,e.location)},r.prototype.getBaseCstVisitorConstructor=function(){if((0,ni.isUndefined)(this.baseCstVisitorConstructor)){var e=(0,IG.createBaseSemanticVisitorConstructor)(this.className,(0,ni.keys)(this.gastProductionsCache));return this.baseCstVisitorConstructor=e,e}return this.baseCstVisitorConstructor},r.prototype.getBaseCstVisitorConstructorWithDefaults=function(){if((0,ni.isUndefined)(this.baseCstVisitorWithDefaultsConstructor)){var e=(0,IG.createBaseVisitorConstructorWithDefaults)(this.className,(0,ni.keys)(this.gastProductionsCache),this.getBaseCstVisitorConstructor());return this.baseCstVisitorWithDefaultsConstructor=e,e}return this.baseCstVisitorWithDefaultsConstructor},r.prototype.getLastExplicitRuleShortName=function(){var e=this.RULE_STACK;return e[e.length-1]},r.prototype.getPreviousExplicitRuleShortName=function(){var e=this.RULE_STACK;return e[e.length-2]},r.prototype.getLastExplicitRuleOccurrenceIndex=function(){var e=this.RULE_OCCURRENCE_STACK;return e[e.length-1]},r}();ry.TreeBuilder=zIe});var BG=w(iy=>{"use strict";Object.defineProperty(iy,"__esModule",{value:!0});iy.LexerAdapter=void 0;var wG=$n(),_Ie=function(){function r(){}return r.prototype.initLexerAdapter=function(){this.tokVector=[],this.tokVectorLength=0,this.currIdx=-1},Object.defineProperty(r.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}),r.prototype.SKIP_TOKEN=function(){return this.currIdx<=this.tokVector.length-2?(this.consumeToken(),this.LA(1)):wG.END_OF_FILE},r.prototype.LA=function(e){var t=this.currIdx+e;return t<0||this.tokVectorLength<=t?wG.END_OF_FILE:this.tokVector[t]},r.prototype.consumeToken=function(){this.currIdx++},r.prototype.exportLexerState=function(){return this.currIdx},r.prototype.importLexerState=function(e){this.currIdx=e},r.prototype.resetLexerState=function(){this.currIdx=-1},r.prototype.moveToTerminatedState=function(){this.currIdx=this.tokVector.length-1},r.prototype.getLexerPosition=function(){return this.exportLexerState()},r}();iy.LexerAdapter=_Ie});var QG=w(ny=>{"use strict";Object.defineProperty(ny,"__esModule",{value:!0});ny.RecognizerApi=void 0;var bG=Yt(),VIe=Bg(),ZS=$n(),XIe=Tp(),ZIe=JS(),$Ie=bn(),eye=function(){function r(){}return r.prototype.ACTION=function(e){return e.call(this)},r.prototype.consume=function(e,t,i){return this.consumeInternal(t,e,i)},r.prototype.subrule=function(e,t,i){return this.subruleInternal(t,e,i)},r.prototype.option=function(e,t){return this.optionInternal(t,e)},r.prototype.or=function(e,t){return this.orInternal(t,e)},r.prototype.many=function(e,t){return this.manyInternal(e,t)},r.prototype.atLeastOne=function(e,t){return this.atLeastOneInternal(e,t)},r.prototype.CONSUME=function(e,t){return this.consumeInternal(e,0,t)},r.prototype.CONSUME1=function(e,t){return this.consumeInternal(e,1,t)},r.prototype.CONSUME2=function(e,t){return this.consumeInternal(e,2,t)},r.prototype.CONSUME3=function(e,t){return this.consumeInternal(e,3,t)},r.prototype.CONSUME4=function(e,t){return this.consumeInternal(e,4,t)},r.prototype.CONSUME5=function(e,t){return this.consumeInternal(e,5,t)},r.prototype.CONSUME6=function(e,t){return this.consumeInternal(e,6,t)},r.prototype.CONSUME7=function(e,t){return this.consumeInternal(e,7,t)},r.prototype.CONSUME8=function(e,t){return this.consumeInternal(e,8,t)},r.prototype.CONSUME9=function(e,t){return this.consumeInternal(e,9,t)},r.prototype.SUBRULE=function(e,t){return this.subruleInternal(e,0,t)},r.prototype.SUBRULE1=function(e,t){return this.subruleInternal(e,1,t)},r.prototype.SUBRULE2=function(e,t){return this.subruleInternal(e,2,t)},r.prototype.SUBRULE3=function(e,t){return this.subruleInternal(e,3,t)},r.prototype.SUBRULE4=function(e,t){return this.subruleInternal(e,4,t)},r.prototype.SUBRULE5=function(e,t){return this.subruleInternal(e,5,t)},r.prototype.SUBRULE6=function(e,t){return this.subruleInternal(e,6,t)},r.prototype.SUBRULE7=function(e,t){return this.subruleInternal(e,7,t)},r.prototype.SUBRULE8=function(e,t){return this.subruleInternal(e,8,t)},r.prototype.SUBRULE9=function(e,t){return this.subruleInternal(e,9,t)},r.prototype.OPTION=function(e){return this.optionInternal(e,0)},r.prototype.OPTION1=function(e){return this.optionInternal(e,1)},r.prototype.OPTION2=function(e){return this.optionInternal(e,2)},r.prototype.OPTION3=function(e){return this.optionInternal(e,3)},r.prototype.OPTION4=function(e){return this.optionInternal(e,4)},r.prototype.OPTION5=function(e){return this.optionInternal(e,5)},r.prototype.OPTION6=function(e){return this.optionInternal(e,6)},r.prototype.OPTION7=function(e){return this.optionInternal(e,7)},r.prototype.OPTION8=function(e){return this.optionInternal(e,8)},r.prototype.OPTION9=function(e){return this.optionInternal(e,9)},r.prototype.OR=function(e){return this.orInternal(e,0)},r.prototype.OR1=function(e){return this.orInternal(e,1)},r.prototype.OR2=function(e){return this.orInternal(e,2)},r.prototype.OR3=function(e){return this.orInternal(e,3)},r.prototype.OR4=function(e){return this.orInternal(e,4)},r.prototype.OR5=function(e){return this.orInternal(e,5)},r.prototype.OR6=function(e){return this.orInternal(e,6)},r.prototype.OR7=function(e){return this.orInternal(e,7)},r.prototype.OR8=function(e){return this.orInternal(e,8)},r.prototype.OR9=function(e){return this.orInternal(e,9)},r.prototype.MANY=function(e){this.manyInternal(0,e)},r.prototype.MANY1=function(e){this.manyInternal(1,e)},r.prototype.MANY2=function(e){this.manyInternal(2,e)},r.prototype.MANY3=function(e){this.manyInternal(3,e)},r.prototype.MANY4=function(e){this.manyInternal(4,e)},r.prototype.MANY5=function(e){this.manyInternal(5,e)},r.prototype.MANY6=function(e){this.manyInternal(6,e)},r.prototype.MANY7=function(e){this.manyInternal(7,e)},r.prototype.MANY8=function(e){this.manyInternal(8,e)},r.prototype.MANY9=function(e){this.manyInternal(9,e)},r.prototype.MANY_SEP=function(e){this.manySepFirstInternal(0,e)},r.prototype.MANY_SEP1=function(e){this.manySepFirstInternal(1,e)},r.prototype.MANY_SEP2=function(e){this.manySepFirstInternal(2,e)},r.prototype.MANY_SEP3=function(e){this.manySepFirstInternal(3,e)},r.prototype.MANY_SEP4=function(e){this.manySepFirstInternal(4,e)},r.prototype.MANY_SEP5=function(e){this.manySepFirstInternal(5,e)},r.prototype.MANY_SEP6=function(e){this.manySepFirstInternal(6,e)},r.prototype.MANY_SEP7=function(e){this.manySepFirstInternal(7,e)},r.prototype.MANY_SEP8=function(e){this.manySepFirstInternal(8,e)},r.prototype.MANY_SEP9=function(e){this.manySepFirstInternal(9,e)},r.prototype.AT_LEAST_ONE=function(e){this.atLeastOneInternal(0,e)},r.prototype.AT_LEAST_ONE1=function(e){return this.atLeastOneInternal(1,e)},r.prototype.AT_LEAST_ONE2=function(e){this.atLeastOneInternal(2,e)},r.prototype.AT_LEAST_ONE3=function(e){this.atLeastOneInternal(3,e)},r.prototype.AT_LEAST_ONE4=function(e){this.atLeastOneInternal(4,e)},r.prototype.AT_LEAST_ONE5=function(e){this.atLeastOneInternal(5,e)},r.prototype.AT_LEAST_ONE6=function(e){this.atLeastOneInternal(6,e)},r.prototype.AT_LEAST_ONE7=function(e){this.atLeastOneInternal(7,e)},r.prototype.AT_LEAST_ONE8=function(e){this.atLeastOneInternal(8,e)},r.prototype.AT_LEAST_ONE9=function(e){this.atLeastOneInternal(9,e)},r.prototype.AT_LEAST_ONE_SEP=function(e){this.atLeastOneSepFirstInternal(0,e)},r.prototype.AT_LEAST_ONE_SEP1=function(e){this.atLeastOneSepFirstInternal(1,e)},r.prototype.AT_LEAST_ONE_SEP2=function(e){this.atLeastOneSepFirstInternal(2,e)},r.prototype.AT_LEAST_ONE_SEP3=function(e){this.atLeastOneSepFirstInternal(3,e)},r.prototype.AT_LEAST_ONE_SEP4=function(e){this.atLeastOneSepFirstInternal(4,e)},r.prototype.AT_LEAST_ONE_SEP5=function(e){this.atLeastOneSepFirstInternal(5,e)},r.prototype.AT_LEAST_ONE_SEP6=function(e){this.atLeastOneSepFirstInternal(6,e)},r.prototype.AT_LEAST_ONE_SEP7=function(e){this.atLeastOneSepFirstInternal(7,e)},r.prototype.AT_LEAST_ONE_SEP8=function(e){this.atLeastOneSepFirstInternal(8,e)},r.prototype.AT_LEAST_ONE_SEP9=function(e){this.atLeastOneSepFirstInternal(9,e)},r.prototype.RULE=function(e,t,i){if(i===void 0&&(i=ZS.DEFAULT_RULE_CONFIG),(0,bG.contains)(this.definedRulesNames,e)){var n=XIe.defaultGrammarValidatorErrorProvider.buildDuplicateRuleNameError({topLevelRule:e,grammarName:this.className}),s={message:n,type:ZS.ParserDefinitionErrorType.DUPLICATE_RULE_NAME,ruleName:e};this.definitionErrors.push(s)}this.definedRulesNames.push(e);var o=this.defineRule(e,t,i);return this[e]=o,o},r.prototype.OVERRIDE_RULE=function(e,t,i){i===void 0&&(i=ZS.DEFAULT_RULE_CONFIG);var n=[];n=n.concat((0,ZIe.validateRuleIsOverridden)(e,this.definedRulesNames,this.className)),this.definitionErrors=this.definitionErrors.concat(n);var s=this.defineRule(e,t,i);return this[e]=s,s},r.prototype.BACKTRACK=function(e,t){return function(){this.isBackTrackingStack.push(1);var i=this.saveRecogState();try{return e.apply(this,t),!0}catch(n){if((0,VIe.isRecognitionException)(n))return!1;throw n}finally{this.reloadRecogState(i),this.isBackTrackingStack.pop()}}},r.prototype.getGAstProductions=function(){return this.gastProductionsCache},r.prototype.getSerializedGastProductions=function(){return(0,$Ie.serializeGrammar)((0,bG.values)(this.gastProductionsCache))},r}();ny.RecognizerApi=eye});var kG=w(sy=>{"use strict";Object.defineProperty(sy,"__esModule",{value:!0});sy.RecognizerEngine=void 0;var Fr=Yt(),es=ey(),oy=Bg(),SG=Kp(),Qg=Mp(),vG=$n(),tye=_S(),xG=XA(),Gp=mg(),rye=VS(),iye=function(){function r(){}return r.prototype.initRecognizerEngine=function(e,t){if(this.className=(0,rye.classNameFromInstance)(this),this.shortRuleNameToFull={},this.fullRuleNameToShort={},this.ruleShortNameIdx=256,this.tokenMatcher=Gp.tokenStructuredMatcherNoCategories,this.definedRulesNames=[],this.tokensMap={},this.isBackTrackingStack=[],this.RULE_STACK=[],this.RULE_OCCURRENCE_STACK=[],this.gastProductionsCache={},(0,Fr.has)(t,"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,Fr.isArray)(e)){if((0,Fr.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,Fr.isArray)(e))this.tokensMap=(0,Fr.reduce)(e,function(o,a){return o[a.name]=a,o},{});else if((0,Fr.has)(e,"modes")&&(0,Fr.every)((0,Fr.flatten)((0,Fr.values)(e.modes)),Gp.isTokenType)){var i=(0,Fr.flatten)((0,Fr.values)(e.modes)),n=(0,Fr.uniq)(i);this.tokensMap=(0,Fr.reduce)(n,function(o,a){return o[a.name]=a,o},{})}else if((0,Fr.isObject)(e))this.tokensMap=(0,Fr.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=xG.EOF;var s=(0,Fr.every)((0,Fr.values)(e),function(o){return(0,Fr.isEmpty)(o.categoryMatches)});this.tokenMatcher=s?Gp.tokenStructuredMatcherNoCategories:Gp.tokenStructuredMatcher,(0,Gp.augmentTokenTypes)((0,Fr.values)(this.tokensMap))},r.prototype.defineRule=function(e,t,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,Fr.has)(i,"resyncEnabled")?i.resyncEnabled:vG.DEFAULT_RULE_CONFIG.resyncEnabled,s=(0,Fr.has)(i,"recoveryValueFunc")?i.recoveryValueFunc:vG.DEFAULT_RULE_CONFIG.recoveryValueFunc,o=this.ruleShortNameIdx<t},r.prototype.orInternal=function(e,t){var i=this.getKeyForAutomaticLookahead(es.OR_IDX,t),n=(0,Fr.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(t,e.ERR_MSG)},r.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),t=this.errorMessageProvider.buildNotAllInputParsedMessage({firstRedundant:e,ruleName:this.getCurrRuleFullName()});this.SAVE_ERROR(new oy.NotAllInputParsedException(t,e))}},r.prototype.subruleInternal=function(e,t,i){var n;try{var s=i!==void 0?i.ARGS:void 0;return n=e.call(this,t,s),this.cstPostNonTerminal(n,i!==void 0&&i.LABEL!==void 0?i.LABEL:e.ruleName),n}catch(o){this.subruleInternalError(o,i,e.ruleName)}},r.prototype.subruleInternalError=function(e,t,i){throw(0,oy.isRecognitionException)(e)&&e.partialCstResult!==void 0&&(this.cstPostNonTerminal(e.partialCstResult,t!==void 0&&t.LABEL!==void 0?t.LABEL:i),delete e.partialCstResult),e},r.prototype.consumeInternal=function(e,t,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,t,o)}return this.cstPostTerminal(i!==void 0&&i.LABEL!==void 0?i.LABEL:e.name,n),n},r.prototype.consumeInternalError=function(e,t,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:t,previous:s,ruleName:this.getCurrRuleFullName()}),this.SAVE_ERROR(new oy.MismatchedTokenException(n,t,s))},r.prototype.consumeInternalRecovery=function(e,t,i){if(this.recoveryEnabled&&i.name==="MismatchedTokenException"&&!this.isBackTracking()){var n=this.getFollowsForInRuleRecovery(e,t);try{return this.tryInRuleRecovery(e,n)}catch(s){throw s.name===tye.IN_RULE_RECOVERY_EXCEPTION?i:s}}else throw i},r.prototype.saveRecogState=function(){var e=this.errors,t=(0,Fr.cloneArr)(this.RULE_STACK);return{errors:e,lexerState:this.exportLexerState(),RULE_STACK:t,CST_STACK:this.CST_STACK}},r.prototype.reloadRecogState=function(e){this.errors=e.errors,this.importLexerState(e.lexerState),this.RULE_STACK=e.RULE_STACK},r.prototype.ruleInvocationStateUpdate=function(e,t,i){this.RULE_OCCURRENCE_STACK.push(i),this.RULE_STACK.push(e),this.cstInvocationStateUpdate(t,e)},r.prototype.isBackTracking=function(){return this.isBackTrackingStack.length!==0},r.prototype.getCurrRuleFullName=function(){var e=this.getLastExplicitRuleShortName();return this.shortRuleNameToFull[e]},r.prototype.shortRuleNameToFullName=function(e){return this.shortRuleNameToFull[e]},r.prototype.isAtEndOfInput=function(){return this.tokenMatcher(this.LA(1),xG.EOF)},r.prototype.reset=function(){this.resetLexerState(),this.isBackTrackingStack=[],this.errors=[],this.RULE_STACK=[],this.CST_STACK=[],this.RULE_OCCURRENCE_STACK=[]},r}();sy.RecognizerEngine=iye});var DG=w(ay=>{"use strict";Object.defineProperty(ay,"__esModule",{value:!0});ay.ErrorHandler=void 0;var $S=Bg(),ev=Yt(),PG=Kp(),nye=$n(),sye=function(){function r(){}return r.prototype.initErrorHandler=function(e){this._errors=[],this.errorMessageProvider=(0,ev.has)(e,"errorMessageProvider")?e.errorMessageProvider:nye.DEFAULT_PARSER_CONFIG.errorMessageProvider},r.prototype.SAVE_ERROR=function(e){if((0,$S.isRecognitionException)(e))return e.context={ruleStack:this.getHumanReadableRuleStack(),ruleOccurrenceStack:(0,ev.cloneArr)(this.RULE_OCCURRENCE_STACK)},this._errors.push(e),e;throw Error("Trying to save an Error which is not a RecognitionException")},Object.defineProperty(r.prototype,"errors",{get:function(){return(0,ev.cloneArr)(this._errors)},set:function(e){this._errors=e},enumerable:!1,configurable:!0}),r.prototype.raiseEarlyExitException=function(e,t,i){for(var n=this.getCurrRuleFullName(),s=this.getGAstProductions()[n],o=(0,PG.getLookaheadPathsForOptionalProd)(e,s,t,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 $S.EarlyExitException(u,this.LA(1),this.LA(0)))},r.prototype.raiseNoAltException=function(e,t){for(var i=this.getCurrRuleFullName(),n=this.getGAstProductions()[i],s=(0,PG.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:t,ruleName:this.getCurrRuleFullName()});throw this.SAVE_ERROR(new $S.NoViableAltException(c,this.LA(1),l))},r}();ay.ErrorHandler=sye});var NG=w(Ay=>{"use strict";Object.defineProperty(Ay,"__esModule",{value:!0});Ay.ContentAssist=void 0;var RG=Mp(),FG=Yt(),oye=function(){function r(){}return r.prototype.initContentAssist=function(){},r.prototype.computeContentAssist=function(e,t){var i=this.gastProductionsCache[e];if((0,FG.isUndefined)(i))throw Error("Rule ->"+e+"<- does not exist in this grammar.");return(0,RG.nextPossibleTokensAfter)([i],t,this.tokenMatcher,this.maxLookahead)},r.prototype.getNextPossibleTokenTypes=function(e){var t=(0,FG.first)(e.ruleStack),i=this.getGAstProductions(),n=i[t],s=new RG.NextAfterTokenWalker(n,e).startWalking();return s},r}();Ay.ContentAssist=oye});var jG=w(ly=>{"use strict";Object.defineProperty(ly,"__esModule",{value:!0});ly.GastRecorder=void 0;var vn=Yt(),Yo=bn(),aye=Dp(),LG=mg(),TG=XA(),Aye=$n(),lye=ey(),cy={description:"This Object indicates the Parser is during Recording Phase"};Object.freeze(cy);var OG=!0,MG=Math.pow(2,lye.BITS_FOR_OCCURRENCE_IDX)-1,KG=(0,TG.createToken)({name:"RECORDING_PHASE_TOKEN",pattern:aye.Lexer.NA});(0,LG.augmentTokenTypes)([KG]);var UG=(0,TG.createTokenInstance)(KG,`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(UG);var cye={name:`This CSTNode indicates the Parser is in Recording Phase - See: https://chevrotain.io/docs/guide/internals.html#grammar-recording for details`,children:{}},gye=function(){function r(){}return r.prototype.initGastRecorder=function(e){this.recordingProdStack=[],this.RECORDING_PHASE=!1},r.prototype.enableRecording=function(){var e=this;this.RECORDING_PHASE=!0,this.TRACE_INIT("Enable Recording",function(){for(var t=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++)t(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})},r.prototype.disableRecording=function(){var e=this;this.RECORDING_PHASE=!1,this.TRACE_INIT("Deleting Recording methods",function(){for(var t=0;t<10;t++){var i=t>0?t:"";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})},r.prototype.ACTION_RECORD=function(e){},r.prototype.BACKTRACK_RECORD=function(e,t){return function(){return!0}},r.prototype.LA_RECORD=function(e){return Aye.END_OF_FILE},r.prototype.topLevelRuleRecord=function(e,t){try{var i=new Yo.Rule({definition:[],name:e});return i.name=e,this.recordingProdStack.push(i),t.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}},r.prototype.optionInternalRecord=function(e,t){return Yp.call(this,Yo.Option,e,t)},r.prototype.atLeastOneInternalRecord=function(e,t){Yp.call(this,Yo.RepetitionMandatory,t,e)},r.prototype.atLeastOneSepFirstInternalRecord=function(e,t){Yp.call(this,Yo.RepetitionMandatoryWithSeparator,t,e,OG)},r.prototype.manyInternalRecord=function(e,t){Yp.call(this,Yo.Repetition,t,e)},r.prototype.manySepFirstInternalRecord=function(e,t){Yp.call(this,Yo.RepetitionWithSeparator,t,e,OG)},r.prototype.orInternalRecord=function(e,t){return uye.call(this,e,t)},r.prototype.subruleInternalRecord=function(e,t,i){if(uy(t),!e||(0,vn.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,vn.peek)(this.recordingProdStack),o=e.ruleName,a=new Yo.NonTerminal({idx:t,nonTerminalName:o,label:i==null?void 0:i.LABEL,referencedRule:void 0});return s.definition.push(a),this.outputCst?cye:cy},r.prototype.consumeInternalRecord=function(e,t,i){if(uy(t),!(0,LG.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,vn.peek)(this.recordingProdStack),o=new Yo.Terminal({idx:t,terminalType:e,label:i==null?void 0:i.LABEL});return s.definition.push(o),UG},r}();ly.GastRecorder=gye;function Yp(r,e,t,i){i===void 0&&(i=!1),uy(t);var n=(0,vn.peek)(this.recordingProdStack),s=(0,vn.isFunction)(e)?e:e.DEF,o=new r({definition:[],idx:t});return i&&(o.separator=e.SEP),(0,vn.has)(e,"MAX_LOOKAHEAD")&&(o.maxLookahead=e.MAX_LOOKAHEAD),this.recordingProdStack.push(o),s.call(this),n.definition.push(o),this.recordingProdStack.pop(),cy}function uye(r,e){var t=this;uy(e);var i=(0,vn.peek)(this.recordingProdStack),n=(0,vn.isArray)(r)===!1,s=n===!1?r:r.DEF,o=new Yo.Alternation({definition:[],idx:e,ignoreAmbiguities:n&&r.IGNORE_AMBIGUITIES===!0});(0,vn.has)(r,"MAX_LOOKAHEAD")&&(o.maxLookahead=r.MAX_LOOKAHEAD);var a=(0,vn.some)(s,function(l){return(0,vn.isFunction)(l.GATE)});return o.hasPredicates=a,i.definition.push(o),(0,vn.forEach)(s,function(l){var c=new Yo.Alternative({definition:[]});o.definition.push(c),(0,vn.has)(l,"IGNORE_AMBIGUITIES")?c.ignoreAmbiguities=l.IGNORE_AMBIGUITIES:(0,vn.has)(l,"GATE")&&(c.ignoreAmbiguities=!0),t.recordingProdStack.push(c),l.ALT.call(t),t.recordingProdStack.pop()}),cy}function HG(r){return r===0?"":""+r}function uy(r){if(r<0||r>MG){var e=new Error("Invalid DSL Method idx value: <"+r+`> - `+("Idx value must be a none negative value smaller than "+(MG+1)));throw e.KNOWN_RECORDER_ERROR=!0,e}}});var YG=w(gy=>{"use strict";Object.defineProperty(gy,"__esModule",{value:!0});gy.PerformanceTracer=void 0;var GG=Yt(),fye=$n(),hye=function(){function r(){}return r.prototype.initPerformanceTracer=function(e){if((0,GG.has)(e,"traceInitPerf")){var t=e.traceInitPerf,i=typeof t=="number";this.traceInitMaxIdent=i?t:Infinity,this.traceInitPerf=i?t>0:t}else this.traceInitMaxIdent=0,this.traceInitPerf=fye.DEFAULT_PARSER_CONFIG.traceInitPerf;this.traceInitIndent=-1},r.prototype.TRACE_INIT=function(e,t){if(this.traceInitPerf===!0){this.traceInitIndent++;var i=new Array(this.traceInitIndent+1).join(" ");this.traceInitIndent <"+e+">");var n=(0,GG.timer)(t),s=n.time,o=n.value,a=s>10?console.warn:console.log;return this.traceInitIndent time: "+s+"ms"),this.traceInitIndent--,o}else return t()},r}();gy.PerformanceTracer=hye});var qG=w(fy=>{"use strict";Object.defineProperty(fy,"__esModule",{value:!0});fy.applyMixins=void 0;function pye(r,e){e.forEach(function(t){var i=t.prototype;Object.getOwnPropertyNames(i).forEach(function(n){if(n!=="constructor"){var s=Object.getOwnPropertyDescriptor(i,n);s&&(s.get||s.set)?Object.defineProperty(r.prototype,n,s):r.prototype[n]=t.prototype[n]}})})}fy.applyMixins=pye});var $n=w(Er=>{"use strict";var JG=Er&&Er.__extends||function(){var r=function(e,t){return r=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])},r(e,t)};return function(e,t){if(typeof t!="function"&&t!==null)throw new TypeError("Class extends value "+String(t)+" is not a constructor or null");r(e,t);function i(){this.constructor=e}e.prototype=t===null?Object.create(t):(i.prototype=t.prototype,new i)}}();Object.defineProperty(Er,"__esModule",{value:!0});Er.EmbeddedActionsParser=Er.CstParser=Er.Parser=Er.EMPTY_ALT=Er.ParserDefinitionErrorType=Er.DEFAULT_RULE_CONFIG=Er.DEFAULT_PARSER_CONFIG=Er.END_OF_FILE=void 0;var an=Yt(),dye=Dj(),WG=XA(),zG=Tp(),_G=iG(),Cye=_S(),mye=uG(),Eye=yG(),Iye=BG(),yye=QG(),wye=kG(),Bye=DG(),bye=NG(),Qye=jG(),Sye=YG(),vye=qG();Er.END_OF_FILE=(0,WG.createTokenInstance)(WG.EOF,"",NaN,NaN,NaN,NaN,NaN,NaN);Object.freeze(Er.END_OF_FILE);Er.DEFAULT_PARSER_CONFIG=Object.freeze({recoveryEnabled:!1,maxLookahead:3,dynamicTokensEnabled:!1,outputCst:!0,errorMessageProvider:zG.defaultParserErrorProvider,nodeLocationTracking:"none",traceInitPerf:!1,skipValidations:!1});Er.DEFAULT_RULE_CONFIG=Object.freeze({recoveryValueFunc:function(){},resyncEnabled:!0});var xye;(function(r){r[r.INVALID_RULE_NAME=0]="INVALID_RULE_NAME",r[r.DUPLICATE_RULE_NAME=1]="DUPLICATE_RULE_NAME",r[r.INVALID_RULE_OVERRIDE=2]="INVALID_RULE_OVERRIDE",r[r.DUPLICATE_PRODUCTIONS=3]="DUPLICATE_PRODUCTIONS",r[r.UNRESOLVED_SUBRULE_REF=4]="UNRESOLVED_SUBRULE_REF",r[r.LEFT_RECURSION=5]="LEFT_RECURSION",r[r.NONE_LAST_EMPTY_ALT=6]="NONE_LAST_EMPTY_ALT",r[r.AMBIGUOUS_ALTS=7]="AMBIGUOUS_ALTS",r[r.CONFLICT_TOKENS_RULES_NAMESPACE=8]="CONFLICT_TOKENS_RULES_NAMESPACE",r[r.INVALID_TOKEN_NAME=9]="INVALID_TOKEN_NAME",r[r.NO_NON_EMPTY_LOOKAHEAD=10]="NO_NON_EMPTY_LOOKAHEAD",r[r.AMBIGUOUS_PREFIX_ALTS=11]="AMBIGUOUS_PREFIX_ALTS",r[r.TOO_MANY_ALTS=12]="TOO_MANY_ALTS"})(xye=Er.ParserDefinitionErrorType||(Er.ParserDefinitionErrorType={}));function kye(r){return r===void 0&&(r=void 0),function(){return r}}Er.EMPTY_ALT=kye;var hy=function(){function r(e,t){this.definitionErrors=[],this.selfAnalysisDone=!1;var i=this;if(i.initErrorHandler(t),i.initLexerAdapter(),i.initLooksAhead(t),i.initRecognizerEngine(e,t),i.initRecoverable(t),i.initTreeBuilder(t),i.initContentAssist(),i.initGastRecorder(t),i.initPerformanceTracer(t),(0,an.has)(t,"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,an.has)(t,"skipValidations")?t.skipValidations:Er.DEFAULT_PARSER_CONFIG.skipValidations}return r.performSelfAnalysis=function(e){throw Error("The **static** `performSelfAnalysis` method has been deprecated. \nUse the **instance** method with the same name instead.")},r.prototype.performSelfAnalysis=function(){var e=this;this.TRACE_INIT("performSelfAnalysis",function(){var t;e.selfAnalysisDone=!0;var i=e.className;e.TRACE_INIT("toFastProps",function(){(0,an.toFastProperties)(e)}),e.TRACE_INIT("Grammar Recording",function(){try{e.enableRecording(),(0,an.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,_G.resolveGrammar)({rules:(0,an.values)(e.gastProductionsCache)}),e.definitionErrors=e.definitionErrors.concat(n)}),e.TRACE_INIT("Grammar Validations",function(){if((0,an.isEmpty)(n)&&e.skipValidations===!1){var s=(0,_G.validateGrammar)({rules:(0,an.values)(e.gastProductionsCache),maxLookahead:e.maxLookahead,tokenTypes:(0,an.values)(e.tokensMap),errMsgProvider:zG.defaultGrammarValidatorErrorProvider,grammarName:i});e.definitionErrors=e.definitionErrors.concat(s)}}),(0,an.isEmpty)(e.definitionErrors)&&(e.recoveryEnabled&&e.TRACE_INIT("computeAllProdsFollows",function(){var s=(0,dye.computeAllProdsFollows)((0,an.values)(e.gastProductionsCache));e.resyncFollows=s}),e.TRACE_INIT("ComputeLookaheadFunctions",function(){e.preComputeLookaheadFunctions((0,an.values)(e.gastProductionsCache))})),!r.DEFER_DEFINITION_ERRORS_HANDLING&&!(0,an.isEmpty)(e.definitionErrors))throw t=(0,an.map)(e.definitionErrors,function(s){return s.message}),new Error(`Parser Definition Errors detected: - `+t.join(` -------------------------------- -`))})},r.DEFER_DEFINITION_ERRORS_HANDLING=!1,r}();Er.Parser=hy;(0,vye.applyMixins)(hy,[Cye.Recoverable,mye.LooksAhead,Eye.TreeBuilder,Iye.LexerAdapter,wye.RecognizerEngine,yye.RecognizerApi,Bye.ErrorHandler,bye.ContentAssist,Qye.GastRecorder,Sye.PerformanceTracer]);var Pye=function(r){JG(e,r);function e(t,i){i===void 0&&(i=Er.DEFAULT_PARSER_CONFIG);var n=this,s=(0,an.cloneObj)(i);return s.outputCst=!0,n=r.call(this,t,s)||this,n}return e}(hy);Er.CstParser=Pye;var Dye=function(r){JG(e,r);function e(t,i){i===void 0&&(i=Er.DEFAULT_PARSER_CONFIG);var n=this,s=(0,an.cloneObj)(i);return s.outputCst=!1,n=r.call(this,t,s)||this,n}return e}(hy);Er.EmbeddedActionsParser=Dye});var XG=w(py=>{"use strict";Object.defineProperty(py,"__esModule",{value:!0});py.createSyntaxDiagramsCode=void 0;var VG=IS();function Rye(r,e){var t=e===void 0?{}:e,i=t.resourceBase,n=i===void 0?"https://unpkg.com/chevrotain@"+VG.VERSION+"/diagrams/":i,s=t.css,o=s===void 0?"https://unpkg.com/chevrotain@"+VG.VERSION+"/diagrams/diagrams.css":s,a=` - - - - - -`,l=` - -`,c=` - - - - -`,u=` -
-`,g=` - -`,f=` - -`;return a+l+c+u+g+f}py.createSyntaxDiagramsCode=Rye});var eY=w(Ve=>{"use strict";Object.defineProperty(Ve,"__esModule",{value:!0});Ve.Parser=Ve.createSyntaxDiagramsCode=Ve.clearCache=Ve.GAstVisitor=Ve.serializeProduction=Ve.serializeGrammar=Ve.Terminal=Ve.Rule=Ve.RepetitionWithSeparator=Ve.RepetitionMandatoryWithSeparator=Ve.RepetitionMandatory=Ve.Repetition=Ve.Option=Ve.NonTerminal=Ve.Alternative=Ve.Alternation=Ve.defaultLexerErrorProvider=Ve.NoViableAltException=Ve.NotAllInputParsedException=Ve.MismatchedTokenException=Ve.isRecognitionException=Ve.EarlyExitException=Ve.defaultParserErrorProvider=Ve.tokenName=Ve.tokenMatcher=Ve.tokenLabel=Ve.EOF=Ve.createTokenInstance=Ve.createToken=Ve.LexerDefinitionErrorType=Ve.Lexer=Ve.EMPTY_ALT=Ve.ParserDefinitionErrorType=Ve.EmbeddedActionsParser=Ve.CstParser=Ve.VERSION=void 0;var Fye=IS();Object.defineProperty(Ve,"VERSION",{enumerable:!0,get:function(){return Fye.VERSION}});var dy=$n();Object.defineProperty(Ve,"CstParser",{enumerable:!0,get:function(){return dy.CstParser}});Object.defineProperty(Ve,"EmbeddedActionsParser",{enumerable:!0,get:function(){return dy.EmbeddedActionsParser}});Object.defineProperty(Ve,"ParserDefinitionErrorType",{enumerable:!0,get:function(){return dy.ParserDefinitionErrorType}});Object.defineProperty(Ve,"EMPTY_ALT",{enumerable:!0,get:function(){return dy.EMPTY_ALT}});var ZG=Dp();Object.defineProperty(Ve,"Lexer",{enumerable:!0,get:function(){return ZG.Lexer}});Object.defineProperty(Ve,"LexerDefinitionErrorType",{enumerable:!0,get:function(){return ZG.LexerDefinitionErrorType}});var Sg=XA();Object.defineProperty(Ve,"createToken",{enumerable:!0,get:function(){return Sg.createToken}});Object.defineProperty(Ve,"createTokenInstance",{enumerable:!0,get:function(){return Sg.createTokenInstance}});Object.defineProperty(Ve,"EOF",{enumerable:!0,get:function(){return Sg.EOF}});Object.defineProperty(Ve,"tokenLabel",{enumerable:!0,get:function(){return Sg.tokenLabel}});Object.defineProperty(Ve,"tokenMatcher",{enumerable:!0,get:function(){return Sg.tokenMatcher}});Object.defineProperty(Ve,"tokenName",{enumerable:!0,get:function(){return Sg.tokenName}});var Nye=Tp();Object.defineProperty(Ve,"defaultParserErrorProvider",{enumerable:!0,get:function(){return Nye.defaultParserErrorProvider}});var qp=Bg();Object.defineProperty(Ve,"EarlyExitException",{enumerable:!0,get:function(){return qp.EarlyExitException}});Object.defineProperty(Ve,"isRecognitionException",{enumerable:!0,get:function(){return qp.isRecognitionException}});Object.defineProperty(Ve,"MismatchedTokenException",{enumerable:!0,get:function(){return qp.MismatchedTokenException}});Object.defineProperty(Ve,"NotAllInputParsedException",{enumerable:!0,get:function(){return qp.NotAllInputParsedException}});Object.defineProperty(Ve,"NoViableAltException",{enumerable:!0,get:function(){return qp.NoViableAltException}});var Lye=PS();Object.defineProperty(Ve,"defaultLexerErrorProvider",{enumerable:!0,get:function(){return Lye.defaultLexerErrorProvider}});var qo=bn();Object.defineProperty(Ve,"Alternation",{enumerable:!0,get:function(){return qo.Alternation}});Object.defineProperty(Ve,"Alternative",{enumerable:!0,get:function(){return qo.Alternative}});Object.defineProperty(Ve,"NonTerminal",{enumerable:!0,get:function(){return qo.NonTerminal}});Object.defineProperty(Ve,"Option",{enumerable:!0,get:function(){return qo.Option}});Object.defineProperty(Ve,"Repetition",{enumerable:!0,get:function(){return qo.Repetition}});Object.defineProperty(Ve,"RepetitionMandatory",{enumerable:!0,get:function(){return qo.RepetitionMandatory}});Object.defineProperty(Ve,"RepetitionMandatoryWithSeparator",{enumerable:!0,get:function(){return qo.RepetitionMandatoryWithSeparator}});Object.defineProperty(Ve,"RepetitionWithSeparator",{enumerable:!0,get:function(){return qo.RepetitionWithSeparator}});Object.defineProperty(Ve,"Rule",{enumerable:!0,get:function(){return qo.Rule}});Object.defineProperty(Ve,"Terminal",{enumerable:!0,get:function(){return qo.Terminal}});var $G=bn();Object.defineProperty(Ve,"serializeGrammar",{enumerable:!0,get:function(){return $G.serializeGrammar}});Object.defineProperty(Ve,"serializeProduction",{enumerable:!0,get:function(){return $G.serializeProduction}});var Tye=Eg();Object.defineProperty(Ve,"GAstVisitor",{enumerable:!0,get:function(){return Tye.GAstVisitor}});function Oye(){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`)}Ve.clearCache=Oye;var Mye=XG();Object.defineProperty(Ve,"createSyntaxDiagramsCode",{enumerable:!0,get:function(){return Mye.createSyntaxDiagramsCode}});var Kye=function(){function r(){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 r}();Ve.Parser=Kye});var iY=w((Z$e,tY)=>{var Cy=eY(),Wa=Cy.createToken,rY=Cy.tokenMatcher,tv=Cy.Lexer,Uye=Cy.EmbeddedActionsParser;tY.exports=r=>{let e=Wa({name:"LogicalOperator",pattern:tv.NA}),t=Wa({name:"Or",pattern:/\|/,categories:e}),i=Wa({name:"Xor",pattern:/\^/,categories:e}),n=Wa({name:"And",pattern:/&/,categories:e}),s=Wa({name:"Not",pattern:/!/}),o=Wa({name:"LParen",pattern:/\(/}),a=Wa({name:"RParen",pattern:/\)/}),l=Wa({name:"Query",pattern:r}),u=[Wa({name:"WhiteSpace",pattern:/\s+/,group:tv.SKIPPED}),t,i,n,o,a,s,e,l],g=new tv(u);class f extends Uye{constructor(p){super(u);this.RULE("expression",()=>this.SUBRULE(this.logicalExpression)),this.RULE("logicalExpression",()=>{let y=this.SUBRULE(this.atomicExpression);return this.MANY(()=>{let b=y,v=this.CONSUME(e),x=this.SUBRULE2(this.atomicExpression);rY(v,t)?y=T=>b(T)||x(T):rY(v,i)?y=T=>!!(b(T)^x(T)):y=T=>b(T)&&x(T)}),y}),this.RULE("atomicExpression",()=>this.OR([{ALT:()=>this.SUBRULE(this.parenthesisExpression)},{ALT:()=>{let{image:m}=this.CONSUME(l);return y=>y(m)}},{ALT:()=>{this.CONSUME(s);let m=this.SUBRULE(this.atomicExpression);return y=>!m(y)}}])),this.RULE("parenthesisExpression",()=>{let m;return this.CONSUME(o),m=this.SUBRULE(this.expression),this.CONSUME(a),m}),this.performSelfAnalysis()}}return{TinylogicLexer:g,TinylogicParser:f}}});var nY=w(my=>{var Hye=iY();my.makeParser=(r=/[a-z]+/)=>{let{TinylogicLexer:e,TinylogicParser:t}=Hye(r),i=new t;return(n,s)=>{let o=e.tokenize(n);return i.input=o.tokens,i.expression()(s)}};my.parse=my.makeParser()});var oY=w((eet,sY)=>{"use strict";sY.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 rv=w((tet,aY)=>{var Jp=oY(),AY={};for(let r of Object.keys(Jp))AY[Jp[r]]=r;var at={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"]}};aY.exports=at;for(let r of Object.keys(at)){if(!("channels"in at[r]))throw new Error("missing channels property: "+r);if(!("labels"in at[r]))throw new Error("missing channel labels property: "+r);if(at[r].labels.length!==at[r].channels)throw new Error("channel and label counts mismatch: "+r);let{channels:e,labels:t}=at[r];delete at[r].channels,delete at[r].labels,Object.defineProperty(at[r],"channels",{value:e}),Object.defineProperty(at[r],"labels",{value:t})}at.rgb.hsl=function(r){let e=r[0]/255,t=r[1]/255,i=r[2]/255,n=Math.min(e,t,i),s=Math.max(e,t,i),o=s-n,a,l;s===n?a=0:e===s?a=(t-i)/o:t===s?a=2+(i-e)/o:i===s&&(a=4+(e-t)/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]};at.rgb.hsv=function(r){let e,t,i,n,s,o=r[0]/255,a=r[1]/255,l=r[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),t=g(a),i=g(l),o===c?n=i-t:a===c?n=1/3+e-i:l===c&&(n=2/3+t-e),n<0?n+=1:n>1&&(n-=1)),[n*360,s*100,c*100]};at.rgb.hwb=function(r){let e=r[0],t=r[1],i=r[2],n=at.rgb.hsl(r)[0],s=1/255*Math.min(e,Math.min(t,i));return i=1-1/255*Math.max(e,Math.max(t,i)),[n,s*100,i*100]};at.rgb.cmyk=function(r){let e=r[0]/255,t=r[1]/255,i=r[2]/255,n=Math.min(1-e,1-t,1-i),s=(1-e-n)/(1-n)||0,o=(1-t-n)/(1-n)||0,a=(1-i-n)/(1-n)||0;return[s*100,o*100,a*100,n*100]};function jye(r,e){return(r[0]-e[0])**2+(r[1]-e[1])**2+(r[2]-e[2])**2}at.rgb.keyword=function(r){let e=AY[r];if(e)return e;let t=Infinity,i;for(let n of Object.keys(Jp)){let s=Jp[n],o=jye(r,s);o.04045?((e+.055)/1.055)**2.4:e/12.92,t=t>.04045?((t+.055)/1.055)**2.4:t/12.92,i=i>.04045?((i+.055)/1.055)**2.4:i/12.92;let n=e*.4124+t*.3576+i*.1805,s=e*.2126+t*.7152+i*.0722,o=e*.0193+t*.1192+i*.9505;return[n*100,s*100,o*100]};at.rgb.lab=function(r){let e=at.rgb.xyz(r),t=e[0],i=e[1],n=e[2];t/=95.047,i/=100,n/=108.883,t=t>.008856?t**(1/3):7.787*t+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*(t-i),a=200*(i-n);return[s,o,a]};at.hsl.rgb=function(r){let e=r[0]/360,t=r[1]/100,i=r[2]/100,n,s,o;if(t===0)return o=i*255,[o,o,o];i<.5?n=i*(1+t):n=i+t-i*t;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};at.hsl.hsv=function(r){let e=r[0],t=r[1]/100,i=r[2]/100,n=t,s=Math.max(i,.01);i*=2,t*=i<=1?i:2-i,n*=s<=1?s:2-s;let o=(i+t)/2,a=i===0?2*n/(s+n):2*t/(i+t);return[e,a*100,o*100]};at.hsv.rgb=function(r){let e=r[0]/60,t=r[1]/100,i=r[2]/100,n=Math.floor(e)%6,s=e-Math.floor(e),o=255*i*(1-t),a=255*i*(1-t*s),l=255*i*(1-t*(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]}};at.hsv.hsl=function(r){let e=r[0],t=r[1]/100,i=r[2]/100,n=Math.max(i,.01),s,o;o=(2-t)*i;let a=(2-t)*n;return s=t*n,s/=a<=1?a:2-a,s=s||0,o/=2,[e,s*100,o*100]};at.hwb.rgb=function(r){let e=r[0]/360,t=r[1]/100,i=r[2]/100,n=t+i,s;n>1&&(t/=n,i/=n);let o=Math.floor(6*e),a=1-i;s=6*e-o,(o&1)!=0&&(s=1-s);let l=t+s*(a-t),c,u,g;switch(o){default:case 6:case 0:c=a,u=l,g=t;break;case 1:c=l,u=a,g=t;break;case 2:c=t,u=a,g=l;break;case 3:c=t,u=l,g=a;break;case 4:c=l,u=t,g=a;break;case 5:c=a,u=t,g=l;break}return[c*255,u*255,g*255]};at.cmyk.rgb=function(r){let e=r[0]/100,t=r[1]/100,i=r[2]/100,n=r[3]/100,s=1-Math.min(1,e*(1-n)+n),o=1-Math.min(1,t*(1-n)+n),a=1-Math.min(1,i*(1-n)+n);return[s*255,o*255,a*255]};at.xyz.rgb=function(r){let e=r[0]/100,t=r[1]/100,i=r[2]/100,n,s,o;return n=e*3.2406+t*-1.5372+i*-.4986,s=e*-.9689+t*1.8758+i*.0415,o=e*.0557+t*-.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]};at.xyz.lab=function(r){let e=r[0],t=r[1],i=r[2];e/=95.047,t/=100,i/=108.883,e=e>.008856?e**(1/3):7.787*e+16/116,t=t>.008856?t**(1/3):7.787*t+16/116,i=i>.008856?i**(1/3):7.787*i+16/116;let n=116*t-16,s=500*(e-t),o=200*(t-i);return[n,s,o]};at.lab.xyz=function(r){let e=r[0],t=r[1],i=r[2],n,s,o;s=(e+16)/116,n=t/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]};at.lab.lch=function(r){let e=r[0],t=r[1],i=r[2],n;n=Math.atan2(i,t)*360/2/Math.PI,n<0&&(n+=360);let o=Math.sqrt(t*t+i*i);return[e,o,n]};at.lch.lab=function(r){let e=r[0],t=r[1],n=r[2]/360*2*Math.PI,s=t*Math.cos(n),o=t*Math.sin(n);return[e,s,o]};at.rgb.ansi16=function(r,e=null){let[t,i,n]=r,s=e===null?at.rgb.hsv(r)[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(t/255));return s===2&&(o+=60),o};at.hsv.ansi16=function(r){return at.rgb.ansi16(at.hsv.rgb(r),r[2])};at.rgb.ansi256=function(r){let e=r[0],t=r[1],i=r[2];return e===t&&t===i?e<8?16:e>248?231:Math.round((e-8)/247*24)+232:16+36*Math.round(e/255*5)+6*Math.round(t/255*5)+Math.round(i/255*5)};at.ansi16.rgb=function(r){let e=r%10;if(e===0||e===7)return r>50&&(e+=3.5),e=e/10.5*255,[e,e,e];let t=(~~(r>50)+1)*.5,i=(e&1)*t*255,n=(e>>1&1)*t*255,s=(e>>2&1)*t*255;return[i,n,s]};at.ansi256.rgb=function(r){if(r>=232){let s=(r-232)*10+8;return[s,s,s]}r-=16;let e,t=Math.floor(r/36)/5*255,i=Math.floor((e=r%36)/6)/5*255,n=e%6/5*255;return[t,i,n]};at.rgb.hex=function(r){let t=(((Math.round(r[0])&255)<<16)+((Math.round(r[1])&255)<<8)+(Math.round(r[2])&255)).toString(16).toUpperCase();return"000000".substring(t.length)+t};at.hex.rgb=function(r){let e=r.toString(16).match(/[a-f0-9]{6}|[a-f0-9]{3}/i);if(!e)return[0,0,0];let t=e[0];e[0].length===3&&(t=t.split("").map(a=>a+a).join(""));let i=parseInt(t,16),n=i>>16&255,s=i>>8&255,o=i&255;return[n,s,o]};at.rgb.hcg=function(r){let e=r[0]/255,t=r[1]/255,i=r[2]/255,n=Math.max(Math.max(e,t),i),s=Math.min(Math.min(e,t),i),o=n-s,a,l;return o<1?a=s/(1-o):a=0,o<=0?l=0:n===e?l=(t-i)/o%6:n===t?l=2+(i-e)/o:l=4+(e-t)/o,l/=6,l%=1,[l*360,o*100,a*100]};at.hsl.hcg=function(r){let e=r[1]/100,t=r[2]/100,i=t<.5?2*e*t:2*e*(1-t),n=0;return i<1&&(n=(t-.5*i)/(1-i)),[r[0],i*100,n*100]};at.hsv.hcg=function(r){let e=r[1]/100,t=r[2]/100,i=e*t,n=0;return i<1&&(n=(t-i)/(1-i)),[r[0],i*100,n*100]};at.hcg.rgb=function(r){let e=r[0]/360,t=r[1]/100,i=r[2]/100;if(t===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-t)*i,[(t*n[0]+l)*255,(t*n[1]+l)*255,(t*n[2]+l)*255]};at.hcg.hsv=function(r){let e=r[1]/100,t=r[2]/100,i=e+t*(1-e),n=0;return i>0&&(n=e/i),[r[0],n*100,i*100]};at.hcg.hsl=function(r){let e=r[1]/100,i=r[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))),[r[0],n*100,i*100]};at.hcg.hwb=function(r){let e=r[1]/100,t=r[2]/100,i=e+t*(1-e);return[r[0],(i-e)*100,(1-i)*100]};at.hwb.hcg=function(r){let e=r[1]/100,t=r[2]/100,i=1-t,n=i-e,s=0;return n<1&&(s=(i-n)/(1-n)),[r[0],n*100,s*100]};at.apple.rgb=function(r){return[r[0]/65535*255,r[1]/65535*255,r[2]/65535*255]};at.rgb.apple=function(r){return[r[0]/255*65535,r[1]/255*65535,r[2]/255*65535]};at.gray.rgb=function(r){return[r[0]/100*255,r[0]/100*255,r[0]/100*255]};at.gray.hsl=function(r){return[0,0,r[0]]};at.gray.hsv=at.gray.hsl;at.gray.hwb=function(r){return[0,100,r[0]]};at.gray.cmyk=function(r){return[0,0,0,r[0]]};at.gray.lab=function(r){return[r[0],0,0]};at.gray.hex=function(r){let e=Math.round(r[0]/100*255)&255,i=((e<<16)+(e<<8)+e).toString(16).toUpperCase();return"000000".substring(i.length)+i};at.rgb.gray=function(r){return[(r[0]+r[1]+r[2])/3/255*100]}});var cY=w((ret,lY)=>{var Ey=rv();function Gye(){let r={},e=Object.keys(Ey);for(let t=e.length,i=0;i{var iv=rv(),Wye=cY(),vg={},zye=Object.keys(iv);function _ye(r){let e=function(...t){let i=t[0];return i==null?i:(i.length>1&&(t=i),r(t))};return"conversion"in r&&(e.conversion=r.conversion),e}function Vye(r){let e=function(...t){let i=t[0];if(i==null)return i;i.length>1&&(t=i);let n=r(t);if(typeof n=="object")for(let s=n.length,o=0;o{vg[r]={},Object.defineProperty(vg[r],"channels",{value:iv[r].channels}),Object.defineProperty(vg[r],"labels",{value:iv[r].labels});let e=Wye(r);Object.keys(e).forEach(i=>{let n=e[i];vg[r][i]=Vye(n),vg[r][i].raw=_ye(n)})});uY.exports=vg});var mY=w((net,fY)=>{"use strict";var hY=(r,e)=>(...t)=>`[${r(...t)+e}m`,pY=(r,e)=>(...t)=>{let i=r(...t);return`[${38+e};5;${i}m`},dY=(r,e)=>(...t)=>{let i=r(...t);return`[${38+e};2;${i[0]};${i[1]};${i[2]}m`},Iy=r=>r,CY=(r,e,t)=>[r,e,t],xg=(r,e,t)=>{Object.defineProperty(r,e,{get:()=>{let i=t();return Object.defineProperty(r,e,{value:i,enumerable:!0,configurable:!0}),i},enumerable:!0,configurable:!0})},nv,kg=(r,e,t,i)=>{nv===void 0&&(nv=gY());let n=i?10:0,s={};for(let[o,a]of Object.entries(nv)){let l=o==="ansi16"?"ansi":o;o===e?s[l]=r(t,n):typeof a=="object"&&(s[l]=r(a[e],n))}return s};function Xye(){let r=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[t,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],r.set(s[0],s[1]);Object.defineProperty(e,t,{value:i,enumerable:!1})}return Object.defineProperty(e,"codes",{value:r,enumerable:!1}),e.color.close="",e.bgColor.close="",xg(e.color,"ansi",()=>kg(hY,"ansi16",Iy,!1)),xg(e.color,"ansi256",()=>kg(pY,"ansi256",Iy,!1)),xg(e.color,"ansi16m",()=>kg(dY,"rgb",CY,!1)),xg(e.bgColor,"ansi",()=>kg(hY,"ansi16",Iy,!0)),xg(e.bgColor,"ansi256",()=>kg(pY,"ansi256",Iy,!0)),xg(e.bgColor,"ansi16m",()=>kg(dY,"rgb",CY,!0)),e}Object.defineProperty(fY,"exports",{enumerable:!0,get:Xye})});var IY=w((set,EY)=>{"use strict";EY.exports=(r,e=process.argv)=>{let t=r.startsWith("-")?"":r.length===1?"-":"--",i=e.indexOf(t+r),n=e.indexOf("--");return i!==-1&&(n===-1||i{"use strict";var Zye=require("os"),wY=require("tty"),Ps=IY(),{env:gi}=process,tl;Ps("no-color")||Ps("no-colors")||Ps("color=false")||Ps("color=never")?tl=0:(Ps("color")||Ps("colors")||Ps("color=true")||Ps("color=always"))&&(tl=1);"FORCE_COLOR"in gi&&(gi.FORCE_COLOR==="true"?tl=1:gi.FORCE_COLOR==="false"?tl=0:tl=gi.FORCE_COLOR.length===0?1:Math.min(parseInt(gi.FORCE_COLOR,10),3));function sv(r){return r===0?!1:{level:r,hasBasic:!0,has256:r>=2,has16m:r>=3}}function ov(r,e){if(tl===0)return 0;if(Ps("color=16m")||Ps("color=full")||Ps("color=truecolor"))return 3;if(Ps("color=256"))return 2;if(r&&!e&&tl===void 0)return 0;let t=tl||0;if(gi.TERM==="dumb")return t;if(process.platform==="win32"){let i=Zye.release().split(".");return Number(i[0])>=10&&Number(i[2])>=10586?Number(i[2])>=14931?3:2:1}if("CI"in gi)return["TRAVIS","CIRCLECI","APPVEYOR","GITLAB_CI"].some(i=>i in gi)||gi.CI_NAME==="codeship"?1:t;if("TEAMCITY_VERSION"in gi)return/^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(gi.TEAMCITY_VERSION)?1:0;if("GITHUB_ACTIONS"in gi)return 1;if(gi.COLORTERM==="truecolor")return 3;if("TERM_PROGRAM"in gi){let i=parseInt((gi.TERM_PROGRAM_VERSION||"").split(".")[0],10);switch(gi.TERM_PROGRAM){case"iTerm.app":return i>=3?3:2;case"Apple_Terminal":return 2}}return/-256(color)?$/i.test(gi.TERM)?2:/^screen|^xterm|^vt100|^vt220|^rxvt|color|ansi|cygwin|linux/i.test(gi.TERM)||"COLORTERM"in gi?1:t}function $ye(r){let e=ov(r,r&&r.isTTY);return sv(e)}yY.exports={supportsColor:$ye,stdout:sv(ov(!0,wY.isatty(1))),stderr:sv(ov(!0,wY.isatty(2)))}});var QY=w((aet,bY)=>{"use strict";var ewe=(r,e,t)=>{let i=r.indexOf(e);if(i===-1)return r;let n=e.length,s=0,o="";do o+=r.substr(s,i-s)+e+t,s=i+n,i=r.indexOf(e,s);while(i!==-1);return o+=r.substr(s),o},twe=(r,e,t,i)=>{let n=0,s="";do{let o=r[i-1]==="\r";s+=r.substr(n,(o?i-1:i)-n)+e+(o?`\r -`:` -`)+t,n=i+1,i=r.indexOf(` -`,n)}while(i!==-1);return s+=r.substr(n),s};bY.exports={stringReplaceAll:ewe,stringEncaseCRLFWithFirstIndex:twe}});var PY=w((Aet,SY)=>{"use strict";var rwe=/(?:\\(u(?:[a-f\d]{4}|\{[a-f\d]{1,6}\})|x[a-f\d]{2}|.))|(?:\{(~)?(\w+(?:\([^)]*\))?(?:\.\w+(?:\([^)]*\))?)*)(?:[ \t]|(?=\r?\n)))|(\})|((?:.|[\r\n\f])+?)/gi,vY=/(?:^|\.)(\w+)(?:\(([^)]*)\))?/g,iwe=/^(['"])((?:\\.|(?!\1)[^\\])*)\1$/,nwe=/\\(u(?:[a-f\d]{4}|\{[a-f\d]{1,6}\})|x[a-f\d]{2}|.)|([^\\])/gi,swe=new Map([["n",` -`],["r","\r"],["t"," "],["b","\b"],["f","\f"],["v","\v"],["0","\0"],["\\","\\"],["e",""],["a","\x07"]]);function xY(r){let e=r[0]==="u",t=r[1]==="{";return e&&!t&&r.length===5||r[0]==="x"&&r.length===3?String.fromCharCode(parseInt(r.slice(1),16)):e&&t?String.fromCodePoint(parseInt(r.slice(2,-1),16)):swe.get(r)||r}function owe(r,e){let t=[],i=e.trim().split(/\s*,\s*/g),n;for(let s of i){let o=Number(s);if(!Number.isNaN(o))t.push(o);else if(n=s.match(iwe))t.push(n[2].replace(nwe,(a,l,c)=>l?xY(l):c));else throw new Error(`Invalid Chalk template style argument: ${s} (in style '${r}')`)}return t}function awe(r){vY.lastIndex=0;let e=[],t;for(;(t=vY.exec(r))!==null;){let i=t[1];if(t[2]){let n=owe(i,t[2]);e.push([i].concat(n))}else e.push([i])}return e}function kY(r,e){let t={};for(let n of e)for(let s of n.styles)t[s[0]]=n.inverse?null:s.slice(1);let i=r;for(let[n,s]of Object.entries(t))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}SY.exports=(r,e)=>{let t=[],i=[],n=[];if(e.replace(rwe,(s,o,a,l,c,u)=>{if(o)n.push(xY(o));else if(l){let g=n.join("");n=[],i.push(t.length===0?g:kY(r,t)(g)),t.push({inverse:a,styles:awe(l)})}else if(c){if(t.length===0)throw new Error("Found extraneous } in Chalk template literal");i.push(kY(r,t)(n.join(""))),n=[],t.pop()}else n.push(u)}),i.push(n.join("")),t.length>0){let s=`Chalk template literal is missing ${t.length} closing bracket${t.length===1?"":"s"} (\`}\`)`;throw new Error(s)}return i.join("")}});var uv=w((cet,DY)=>{"use strict";var Wp=mY(),{stdout:av,stderr:Av}=BY(),{stringReplaceAll:Awe,stringEncaseCRLFWithFirstIndex:lwe}=QY(),RY=["ansi","ansi","ansi256","ansi16m"],Pg=Object.create(null),cwe=(r,e={})=>{if(e.level>3||e.level<0)throw new Error("The `level` option should be an integer from 0 to 3");let t=av?av.level:0;r.level=e.level===void 0?t:e.level},FY=class{constructor(e){return NY(e)}},NY=r=>{let e={};return cwe(e,r),e.template=(...t)=>uwe(e.template,...t),Object.setPrototypeOf(e,yy.prototype),Object.setPrototypeOf(e.template,e),e.template.constructor=()=>{throw new Error("`chalk.constructor()` is deprecated. Use `new chalk.Instance()` instead.")},e.template.Instance=FY,e.template};function yy(r){return NY(r)}for(let[r,e]of Object.entries(Wp))Pg[r]={get(){let t=wy(this,lv(e.open,e.close,this._styler),this._isEmpty);return Object.defineProperty(this,r,{value:t}),t}};Pg.visible={get(){let r=wy(this,this._styler,!0);return Object.defineProperty(this,"visible",{value:r}),r}};var LY=["rgb","hex","keyword","hsl","hsv","hwb","ansi","ansi256"];for(let r of LY)Pg[r]={get(){let{level:e}=this;return function(...t){let i=lv(Wp.color[RY[e]][r](...t),Wp.color.close,this._styler);return wy(this,i,this._isEmpty)}}};for(let r of LY){let e="bg"+r[0].toUpperCase()+r.slice(1);Pg[e]={get(){let{level:t}=this;return function(...i){let n=lv(Wp.bgColor[RY[t]][r](...i),Wp.bgColor.close,this._styler);return wy(this,n,this._isEmpty)}}}}var gwe=Object.defineProperties(()=>{},te(N({},Pg),{level:{enumerable:!0,get(){return this._generator.level},set(r){this._generator.level=r}}})),lv=(r,e,t)=>{let i,n;return t===void 0?(i=r,n=e):(i=t.openAll+r,n=e+t.closeAll),{open:r,close:e,openAll:i,closeAll:n,parent:t}},wy=(r,e,t)=>{let i=(...n)=>fwe(i,n.length===1?""+n[0]:n.join(" "));return i.__proto__=gwe,i._generator=r,i._styler=e,i._isEmpty=t,i},fwe=(r,e)=>{if(r.level<=0||!e)return r._isEmpty?"":e;let t=r._styler;if(t===void 0)return e;let{openAll:i,closeAll:n}=t;if(e.indexOf("")!==-1)for(;t!==void 0;)e=Awe(e,t.close,t.open),t=t.parent;let s=e.indexOf(` -`);return s!==-1&&(e=lwe(e,n,i,s)),i+e+n},cv,uwe=(r,...e)=>{let[t]=e;if(!Array.isArray(t))return e.join(" ");let i=e.slice(1),n=[t.raw[0]];for(let s=1;s{"use strict";Ds.isInteger=r=>typeof r=="number"?Number.isInteger(r):typeof r=="string"&&r.trim()!==""?Number.isInteger(Number(r)):!1;Ds.find=(r,e)=>r.nodes.find(t=>t.type===e);Ds.exceedsLimit=(r,e,t=1,i)=>i===!1||!Ds.isInteger(r)||!Ds.isInteger(e)?!1:(Number(e)-Number(r))/Number(t)>=i;Ds.escapeNode=(r,e=0,t)=>{let i=r.nodes[e];!i||(t&&i.type===t||i.type==="open"||i.type==="close")&&i.escaped!==!0&&(i.value="\\"+i.value,i.escaped=!0)};Ds.encloseBrace=r=>r.type!=="brace"?!1:r.commas>>0+r.ranges>>0==0?(r.invalid=!0,!0):!1;Ds.isInvalidBrace=r=>r.type!=="brace"?!1:r.invalid===!0||r.dollar?!0:r.commas>>0+r.ranges>>0==0||r.open!==!0||r.close!==!0?(r.invalid=!0,!0):!1;Ds.isOpenOrClose=r=>r.type==="open"||r.type==="close"?!0:r.open===!0||r.close===!0;Ds.reduce=r=>r.reduce((e,t)=>(t.type==="text"&&e.push(t.value),t.type==="range"&&(t.type="text"),e),[]);Ds.flatten=(...r)=>{let e=[],t=i=>{for(let n=0;n{"use strict";var OY=By();TY.exports=(r,e={})=>{let t=(i,n={})=>{let s=e.escapeInvalid&&OY.isInvalidBrace(n),o=i.invalid===!0&&e.escapeInvalid===!0,a="";if(i.value)return(s||o)&&OY.isOpenOrClose(i)?"\\"+i.value:i.value;if(i.value)return i.value;if(i.nodes)for(let l of i.nodes)a+=t(l);return a};return t(r)}});var KY=w((fet,MY)=>{"use strict";MY.exports=function(r){return typeof r=="number"?r-r==0:typeof r=="string"&&r.trim()!==""?Number.isFinite?Number.isFinite(+r):isFinite(+r):!1}});var zY=w((het,UY)=>{"use strict";var HY=KY(),Rc=(r,e,t)=>{if(HY(r)===!1)throw new TypeError("toRegexRange: expected the first argument to be a number");if(e===void 0||r===e)return String(r);if(HY(e)===!1)throw new TypeError("toRegexRange: expected the second argument to be a number.");let i=N({relaxZeros:!0},t);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=r+":"+e+"="+n+s+o+a;if(Rc.cache.hasOwnProperty(l))return Rc.cache[l].result;let c=Math.min(r,e),u=Math.max(r,e);if(Math.abs(c-u)===1){let m=r+"|"+e;return i.capture?`(${m})`:i.wrap===!1?m:`(?:${m})`}let g=GY(r)||GY(e),f={min:r,max:e,a:c,b:u},h=[],p=[];if(g&&(f.isPadded=g,f.maxLen=String(f.max).length),c<0){let m=u<0?Math.abs(u):1;p=jY(m,Math.abs(c),f,i),c=f.a=0}return u>=0&&(h=jY(c,u,f,i)),f.negatives=p,f.positives=h,f.result=hwe(p,h,i),i.capture===!0?f.result=`(${f.result})`:i.wrap!==!1&&h.length+p.length>1&&(f.result=`(?:${f.result})`),Rc.cache[l]=f,f.result};function hwe(r,e,t){let i=gv(r,e,"-",!1,t)||[],n=gv(e,r,"",!1,t)||[],s=gv(r,e,"-?",!0,t)||[];return i.concat(s).concat(n).join("|")}function dwe(r,e){let t=1,i=1,n=YY(r,t),s=new Set([e]);for(;r<=n&&n<=e;)s.add(n),t+=1,n=YY(r,t);for(n=qY(e+1,i)-1;r1&&a.count.pop(),a.count.push(u.count[0]),a.string=a.pattern+JY(a.count),o=c+1;continue}t.isPadded&&(g=Iwe(c,t,i)),u.string=g+u.pattern+JY(u.count),s.push(u),o=c+1,a=u}return s}function gv(r,e,t,i,n){let s=[];for(let o of r){let{string:a}=o;!i&&!WY(e,"string",a)&&s.push(t+a),i&&WY(e,"string",a)&&s.push(t+a)}return s}function Cwe(r,e){let t=[];for(let i=0;ie?1:e>r?-1:0}function WY(r,e,t){return r.some(i=>i[e]===t)}function YY(r,e){return Number(String(r).slice(0,-e)+"9".repeat(e))}function qY(r,e){return r-r%Math.pow(10,e)}function JY(r){let[e=0,t=""]=r;return t||e>1?`{${e+(t?","+t:"")}}`:""}function mwe(r,e,t){return`[${r}${e-r==1?"":"-"}${e}]`}function GY(r){return/^-?(0+)\d/.test(r)}function Iwe(r,e,t){if(!e.isPadded)return r;let i=Math.abs(e.maxLen-String(r).length),n=t.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}}`}}Rc.cache={};Rc.clearCache=()=>Rc.cache={};UY.exports=Rc});var pv=w((pet,_Y)=>{"use strict";var ywe=require("util"),VY=zY(),XY=r=>r!==null&&typeof r=="object"&&!Array.isArray(r),wwe=r=>e=>r===!0?Number(e):String(e),fv=r=>typeof r=="number"||typeof r=="string"&&r!=="",_p=r=>Number.isInteger(+r),hv=r=>{let e=`${r}`,t=-1;if(e[0]==="-"&&(e=e.slice(1)),e==="0")return!1;for(;e[++t]==="0";);return t>0},Bwe=(r,e,t)=>typeof r=="string"||typeof e=="string"?!0:t.stringify===!0,bwe=(r,e,t)=>{if(e>0){let i=r[0]==="-"?"-":"";i&&(r=r.slice(1)),r=i+r.padStart(i?e-1:e,"0")}return t===!1?String(r):r},ZY=(r,e)=>{let t=r[0]==="-"?"-":"";for(t&&(r=r.slice(1),e--);r.length{r.negatives.sort((o,a)=>oa?1:0),r.positives.sort((o,a)=>oa?1:0);let t=e.capture?"":"?:",i="",n="",s;return r.positives.length&&(i=r.positives.join("|")),r.negatives.length&&(n=`-(${t}${r.negatives.join("|")})`),i&&n?s=`${i}|${n}`:s=i||n,e.wrap?`(${t}${s})`:s},$Y=(r,e,t,i)=>{if(t)return VY(r,e,N({wrap:!1},i));let n=String.fromCharCode(r);if(r===e)return n;let s=String.fromCharCode(e);return`[${n}-${s}]`},eq=(r,e,t)=>{if(Array.isArray(r)){let i=t.wrap===!0,n=t.capture?"":"?:";return i?`(${n}${r.join("|")})`:r.join("|")}return VY(r,e,t)},tq=(...r)=>new RangeError("Invalid range arguments: "+ywe.inspect(...r)),rq=(r,e,t)=>{if(t.strictRanges===!0)throw tq([r,e]);return[]},Swe=(r,e)=>{if(e.strictRanges===!0)throw new TypeError(`Expected step "${r}" to be a number`);return[]},vwe=(r,e,t=1,i={})=>{let n=Number(r),s=Number(e);if(!Number.isInteger(n)||!Number.isInteger(s)){if(i.strictRanges===!0)throw tq([r,e]);return[]}n===0&&(n=0),s===0&&(s=0);let o=n>s,a=String(r),l=String(e),c=String(t);t=Math.max(Math.abs(t),1);let u=hv(a)||hv(l)||hv(c),g=u?Math.max(a.length,l.length,c.length):0,f=u===!1&&Bwe(r,e,i)===!1,h=i.transform||wwe(f);if(i.toRegex&&t===1)return $Y(ZY(r,g),ZY(e,g),!0,i);let p={negatives:[],positives:[]},m=v=>p[v<0?"negatives":"positives"].push(Math.abs(v)),y=[],b=0;for(;o?n>=s:n<=s;)i.toRegex===!0&&t>1?m(n):y.push(bwe(h(n,b),g,f)),n=o?n-t:n+t,b++;return i.toRegex===!0?t>1?Qwe(p,i):eq(y,null,N({wrap:!1},i)):y},xwe=(r,e,t=1,i={})=>{if(!_p(r)&&r.length>1||!_p(e)&&e.length>1)return rq(r,e,i);let n=i.transform||(f=>String.fromCharCode(f)),s=`${r}`.charCodeAt(0),o=`${e}`.charCodeAt(0),a=s>o,l=Math.min(s,o),c=Math.max(s,o);if(i.toRegex&&t===1)return $Y(l,c,!1,i);let u=[],g=0;for(;a?s>=o:s<=o;)u.push(n(s,g)),s=a?s-t:s+t,g++;return i.toRegex===!0?eq(u,null,{wrap:!1,options:i}):u},Qy=(r,e,t,i={})=>{if(e==null&&fv(r))return[r];if(!fv(r)||!fv(e))return rq(r,e,i);if(typeof t=="function")return Qy(r,e,1,{transform:t});if(XY(t))return Qy(r,e,0,t);let n=N({},i);return n.capture===!0&&(n.wrap=!0),t=t||n.step||1,_p(t)?_p(r)&&_p(e)?vwe(r,e,t,n):xwe(r,e,Math.max(Math.abs(t),1),n):t!=null&&!XY(t)?Swe(t,n):Qy(r,e,1,t)};_Y.exports=Qy});var sq=w((det,iq)=>{"use strict";var kwe=pv(),nq=By(),Pwe=(r,e={})=>{let t=(i,n={})=>{let s=nq.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=nq.reduce(i.nodes),g=kwe(...u,te(N({},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+=t(u,i);return c};return t(r)};iq.exports=Pwe});var Aq=w((Cet,oq)=>{"use strict";var Dwe=pv(),aq=by(),Dg=By(),Fc=(r="",e="",t=!1)=>{let i=[];if(r=[].concat(r),e=[].concat(e),!e.length)return r;if(!r.length)return t?Dg.flatten(e).map(n=>`{${n}}`):e;for(let n of r)if(Array.isArray(n))for(let s of n)i.push(Fc(s,e,t));else for(let s of e)t===!0&&typeof s=="string"&&(s=`{${s}}`),i.push(Array.isArray(s)?Fc(n,s,t):n+s);return Dg.flatten(i)},Rwe=(r,e={})=>{let t=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(Fc(a.pop(),aq(n,e)));return}if(n.type==="brace"&&n.invalid!==!0&&n.nodes.length===2){a.push(Fc(a.pop(),["{}"]));return}if(n.nodes&&n.ranges>0){let g=Dg.reduce(n.nodes);if(Dg.exceedsLimit(...g,e.step,t))throw new RangeError("expanded array length exceeds range limit. Use options.rangeLimit to increase or disable the limit.");let f=Dwe(...g,e);f.length===0&&(f=aq(n,e)),a.push(Fc(a.pop(),f)),n.nodes=[];return}let l=Dg.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";lq.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 pq=w((Eet,uq)=>{"use strict";var Fwe=by(),{MAX_LENGTH:gq,CHAR_BACKSLASH:dv,CHAR_BACKTICK:Nwe,CHAR_COMMA:Lwe,CHAR_DOT:Twe,CHAR_LEFT_PARENTHESES:Owe,CHAR_RIGHT_PARENTHESES:Mwe,CHAR_LEFT_CURLY_BRACE:Kwe,CHAR_RIGHT_CURLY_BRACE:Uwe,CHAR_LEFT_SQUARE_BRACKET:fq,CHAR_RIGHT_SQUARE_BRACKET:hq,CHAR_DOUBLE_QUOTE:Hwe,CHAR_SINGLE_QUOTE:jwe,CHAR_NO_BREAK_SPACE:Gwe,CHAR_ZERO_WIDTH_NOBREAK_SPACE:Ywe}=cq(),qwe=(r,e={})=>{if(typeof r!="string")throw new TypeError("Expected a string");let t=e||{},i=typeof t.maxLength=="number"?Math.min(gq,t.maxLength):gq;if(r.length>i)throw new SyntaxError(`Input length (${r.length}), exceeds max characters (${i})`);let n={type:"root",input:r,nodes:[]},s=[n],o=n,a=n,l=0,c=r.length,u=0,g=0,f,h={},p=()=>r[u++],m=y=>{if(y.type==="text"&&a.type==="dot"&&(a.type="text"),a&&a.type==="text"&&y.type==="text"){a.value+=y.value;return}return o.nodes.push(y),y.parent=o,y.prev=a,a=y,y};for(m({type:"bos"});u0){if(o.ranges>0){o.ranges=0;let y=o.nodes.shift();o.nodes=[y,{type:"text",value:Fwe(o)}]}m({type:"comma",value:f}),o.commas++;continue}if(f===Twe&&g>0&&o.commas===0){let y=o.nodes;if(g===0||y.length===0){m({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"){y.pop();let b=y[y.length-1];b.value+=a.value+f,a=b,o.ranges--;continue}m({type:"dot",value:f});continue}m({type:"text",value:f})}do if(o=s.pop(),o.type!=="root"){o.nodes.forEach(v=>{v.nodes||(v.type==="open"&&(v.isOpen=!0),v.type==="close"&&(v.isClose=!0),v.nodes||(v.type="text"),v.invalid=!0)});let y=s[s.length-1],b=y.nodes.indexOf(o);y.nodes.splice(b,1,...o.nodes)}while(s.length>0);return m({type:"eos"}),n};uq.exports=qwe});var mq=w((Iet,dq)=>{"use strict";var Cq=by(),Jwe=sq(),Wwe=Aq(),zwe=pq(),ts=(r,e={})=>{let t=[];if(Array.isArray(r))for(let i of r){let n=ts.create(i,e);Array.isArray(n)?t.push(...n):t.push(n)}else t=[].concat(ts.create(r,e));return e&&e.expand===!0&&e.nodupes===!0&&(t=[...new Set(t)]),t};ts.parse=(r,e={})=>zwe(r,e);ts.stringify=(r,e={})=>typeof r=="string"?Cq(ts.parse(r,e),e):Cq(r,e);ts.compile=(r,e={})=>(typeof r=="string"&&(r=ts.parse(r,e)),Jwe(r,e));ts.expand=(r,e={})=>{typeof r=="string"&&(r=ts.parse(r,e));let t=Wwe(r,e);return e.noempty===!0&&(t=t.filter(Boolean)),e.nodupes===!0&&(t=[...new Set(t)]),t};ts.create=(r,e={})=>r===""||r.length<3?[r]:e.expand!==!0?ts.compile(r,e):ts.expand(r,e);dq.exports=ts});var Vp=w((yet,Eq)=>{"use strict";var _we=require("path"),Jo="\\\\/",Iq=`[^${Jo}]`,za="\\.",Vwe="\\+",Xwe="\\?",Sy="\\/",Zwe="(?=.)",yq="[^/]",Cv=`(?:${Sy}|$)`,wq=`(?:^|${Sy})`,mv=`${za}{1,2}${Cv}`,$we=`(?!${za})`,eBe=`(?!${wq}${mv})`,tBe=`(?!${za}{0,1}${Cv})`,rBe=`(?!${mv})`,iBe=`[^.${Sy}]`,nBe=`${yq}*?`,Bq={DOT_LITERAL:za,PLUS_LITERAL:Vwe,QMARK_LITERAL:Xwe,SLASH_LITERAL:Sy,ONE_CHAR:Zwe,QMARK:yq,END_ANCHOR:Cv,DOTS_SLASH:mv,NO_DOT:$we,NO_DOTS:eBe,NO_DOT_SLASH:tBe,NO_DOTS_SLASH:rBe,QMARK_NO_DOT:iBe,STAR:nBe,START_ANCHOR:wq},sBe=te(N({},Bq),{SLASH_LITERAL:`[${Jo}]`,QMARK:Iq,STAR:`${Iq}*?`,DOTS_SLASH:`${za}{1,2}(?:[${Jo}]|$)`,NO_DOT:`(?!${za})`,NO_DOTS:`(?!(?:^|[${Jo}])${za}{1,2}(?:[${Jo}]|$))`,NO_DOT_SLASH:`(?!${za}{0,1}(?:[${Jo}]|$))`,NO_DOTS_SLASH:`(?!${za}{1,2}(?:[${Jo}]|$))`,QMARK_NO_DOT:`[^.${Jo}]`,START_ANCHOR:`(?:^|[${Jo}])`,END_ANCHOR:`(?:[${Jo}]|$)`}),oBe={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"};Eq.exports={MAX_LENGTH:1024*64,POSIX_REGEX_SOURCE:oBe,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:_we.sep,extglobChars(r){return{"!":{type:"negate",open:"(?:(?!(?:",close:`))${r.STAR})`},"?":{type:"qmark",open:"(?:",close:")?"},"+":{type:"plus",open:"(?:",close:")+"},"*":{type:"star",open:"(?:",close:")*"},"@":{type:"at",open:"(?:",close:")"}}},globChars(r){return r===!0?sBe:Bq}}});var Xp=w(xn=>{"use strict";var aBe=require("path"),ABe=process.platform==="win32",{REGEX_BACKSLASH:lBe,REGEX_REMOVE_BACKSLASH:cBe,REGEX_SPECIAL_CHARS:uBe,REGEX_SPECIAL_CHARS_GLOBAL:gBe}=Vp();xn.isObject=r=>r!==null&&typeof r=="object"&&!Array.isArray(r);xn.hasRegexChars=r=>uBe.test(r);xn.isRegexChar=r=>r.length===1&&xn.hasRegexChars(r);xn.escapeRegex=r=>r.replace(gBe,"\\$1");xn.toPosixSlashes=r=>r.replace(lBe,"/");xn.removeBackslashes=r=>r.replace(cBe,e=>e==="\\"?"":e);xn.supportsLookbehinds=()=>{let r=process.version.slice(1).split(".").map(Number);return r.length===3&&r[0]>=9||r[0]===8&&r[1]>=10};xn.isWindows=r=>r&&typeof r.windows=="boolean"?r.windows:ABe===!0||aBe.sep==="\\";xn.escapeLast=(r,e,t)=>{let i=r.lastIndexOf(e,t);return i===-1?r:r[i-1]==="\\"?xn.escapeLast(r,e,i-1):`${r.slice(0,i)}\\${r.slice(i)}`};xn.removePrefix=(r,e={})=>{let t=r;return t.startsWith("./")&&(t=t.slice(2),e.prefix="./"),t};xn.wrapOutput=(r,e={},t={})=>{let i=t.contains?"":"^",n=t.contains?"":"$",s=`${i}(?:${r})${n}`;return e.negated===!0&&(s=`(?:^(?!${s}).*$)`),s}});var Dq=w((Bet,bq)=>{"use strict";var Qq=Xp(),{CHAR_ASTERISK:Ev,CHAR_AT:fBe,CHAR_BACKWARD_SLASH:Zp,CHAR_COMMA:hBe,CHAR_DOT:Iv,CHAR_EXCLAMATION_MARK:yv,CHAR_FORWARD_SLASH:Sq,CHAR_LEFT_CURLY_BRACE:wv,CHAR_LEFT_PARENTHESES:Bv,CHAR_LEFT_SQUARE_BRACKET:pBe,CHAR_PLUS:dBe,CHAR_QUESTION_MARK:vq,CHAR_RIGHT_CURLY_BRACE:CBe,CHAR_RIGHT_PARENTHESES:xq,CHAR_RIGHT_SQUARE_BRACKET:mBe}=Vp(),kq=r=>r===Sq||r===Zp,Pq=r=>{r.isPrefix!==!0&&(r.depth=r.isGlobstar?Infinity:1)},EBe=(r,e)=>{let t=e||{},i=r.length-1,n=t.parts===!0||t.scanToEnd===!0,s=[],o=[],a=[],l=r,c=-1,u=0,g=0,f=!1,h=!1,p=!1,m=!1,y=!1,b=!1,v=!1,x=!1,T=!1,q=!1,Y=0,$,_,ne={value:"",depth:0,isGlob:!1},ee=()=>c>=i,A=()=>l.charCodeAt(c+1),oe=()=>($=_,l.charCodeAt(++c));for(;c0&&(Z=l.slice(0,u),l=l.slice(u),g-=u),ce&&p===!0&&g>0?(ce=l.slice(0,g),O=l.slice(g)):p===!0?(ce="",O=l):ce=l,ce&&ce!==""&&ce!=="/"&&ce!==l&&kq(ce.charCodeAt(ce.length-1))&&(ce=ce.slice(0,-1)),t.unescape===!0&&(O&&(O=Qq.removeBackslashes(O)),ce&&v===!0&&(ce=Qq.removeBackslashes(ce)));let L={prefix:Z,input:r,start:u,base:ce,glob:O,isBrace:f,isBracket:h,isGlob:p,isExtglob:m,isGlobstar:y,negated:x,negatedExtglob:T};if(t.tokens===!0&&(L.maxDepth=0,kq(_)||o.push(ne),L.tokens=o),t.parts===!0||t.tokens===!0){let de;for(let Be=0;Be{"use strict";var vy=Vp(),rs=Xp(),{MAX_LENGTH:xy,POSIX_REGEX_SOURCE:IBe,REGEX_NON_SPECIAL_CHARS:yBe,REGEX_SPECIAL_CHARS_BACKREF:wBe,REPLACEMENTS:Fq}=vy,BBe=(r,e)=>{if(typeof e.expandRange=="function")return e.expandRange(...r,e);r.sort();let t=`[${r.join("-")}]`;try{new RegExp(t)}catch(i){return r.map(n=>rs.escapeRegex(n)).join("..")}return t},Rg=(r,e)=>`Missing ${r}: "${e}" - use "\\\\${e}" to match literal characters`,Nq=(r,e)=>{if(typeof r!="string")throw new TypeError("Expected a string");r=Fq[r]||r;let t=N({},e),i=typeof t.maxLength=="number"?Math.min(xy,t.maxLength):xy,n=r.length;if(n>i)throw new SyntaxError(`Input length: ${n}, exceeds maximum allowed length: ${i}`);let s={type:"bos",value:"",output:t.prepend||""},o=[s],a=t.capture?"":"?:",l=rs.isWindows(e),c=vy.globChars(l),u=vy.extglobChars(c),{DOT_LITERAL:g,PLUS_LITERAL:f,SLASH_LITERAL:h,ONE_CHAR:p,DOTS_SLASH:m,NO_DOT:y,NO_DOT_SLASH:b,NO_DOTS_SLASH:v,QMARK:x,QMARK_NO_DOT:T,STAR:q,START_ANCHOR:Y}=c,$=V=>`(${a}(?:(?!${Y}${V.dot?m:g}).)*?)`,_=t.dot?"":y,ne=t.dot?x:T,ee=t.bash===!0?$(t):q;t.capture&&(ee=`(${ee})`),typeof t.noext=="boolean"&&(t.noextglob=t.noext);let A={input:r,index:-1,start:0,dot:t.dot===!0,consumed:"",output:"",prefix:"",backtrack:!1,negated:!1,brackets:0,braces:0,parens:0,quotes:0,globstar:!1,tokens:o};r=rs.removePrefix(r,A),n=r.length;let oe=[],ce=[],Z=[],O=s,L,de=()=>A.index===n-1,Be=A.peek=(V=1)=>r[A.index+V],je=A.advance=()=>r[++A.index]||"",re=()=>r.slice(A.index+1),se=(V="",Qe=0)=>{A.consumed+=V,A.index+=Qe},be=V=>{A.output+=V.output!=null?V.output:V.value,se(V.value)},he=()=>{let V=1;for(;Be()==="!"&&(Be(2)!=="("||Be(3)==="?");)je(),A.start++,V++;return V%2==0?!1:(A.negated=!0,A.start++,!0)},Fe=V=>{A[V]++,Z.push(V)},Ke=V=>{A[V]--,Z.pop()},ke=V=>{if(O.type==="globstar"){let Qe=A.braces>0&&(V.type==="comma"||V.type==="brace"),le=V.extglob===!0||oe.length&&(V.type==="pipe"||V.type==="paren");V.type!=="slash"&&V.type!=="paren"&&!Qe&&!le&&(A.output=A.output.slice(0,-O.output.length),O.type="star",O.value="*",O.output=ee,A.output+=O.output)}if(oe.length&&V.type!=="paren"&&(oe[oe.length-1].inner+=V.value),(V.value||V.output)&&be(V),O&&O.type==="text"&&V.type==="text"){O.value+=V.value,O.output=(O.output||"")+V.value;return}V.prev=O,o.push(V),O=V},ve=(V,Qe)=>{let le=te(N({},u[Qe]),{conditions:1,inner:""});le.prev=O,le.parens=A.parens,le.output=A.output;let fe=(t.capture?"(":"")+le.open;Fe("parens"),ke({type:V,value:Qe,output:A.output?"":p}),ke({type:"paren",extglob:!0,value:je(),output:fe}),oe.push(le)},pe=V=>{let Qe=V.close+(t.capture?")":""),le;if(V.type==="negate"){let fe=ee;V.inner&&V.inner.length>1&&V.inner.includes("/")&&(fe=$(t)),(fe!==ee||de()||/^\)+$/.test(re()))&&(Qe=V.close=`)$))${fe}`),V.inner.includes("*")&&(le=re())&&/^\.[^\\/.]+$/.test(le)&&(Qe=V.close=`)${le})${fe})`),V.prev.type==="bos"&&(A.negatedExtglob=!0)}ke({type:"paren",extglob:!0,value:L,output:Qe}),Ke("parens")};if(t.fastpaths!==!1&&!/(^[*!]|[/()[\]{}"])/.test(r)){let V=!1,Qe=r.replace(wBe,(le,fe,gt,Ht,Mt,Ei)=>Ht==="\\"?(V=!0,le):Ht==="?"?fe?fe+Ht+(Mt?x.repeat(Mt.length):""):Ei===0?ne+(Mt?x.repeat(Mt.length):""):x.repeat(gt.length):Ht==="."?g.repeat(gt.length):Ht==="*"?fe?fe+Ht+(Mt?ee:""):ee:fe?le:`\\${le}`);return V===!0&&(t.unescape===!0?Qe=Qe.replace(/\\/g,""):Qe=Qe.replace(/\\+/g,le=>le.length%2==0?"\\\\":le?"\\":"")),Qe===r&&t.contains===!0?(A.output=r,A):(A.output=rs.wrapOutput(Qe,A,e),A)}for(;!de();){if(L=je(),L==="\0")continue;if(L==="\\"){let le=Be();if(le==="/"&&t.bash!==!0||le==="."||le===";")continue;if(!le){L+="\\",ke({type:"text",value:L});continue}let fe=/^\\+/.exec(re()),gt=0;if(fe&&fe[0].length>2&&(gt=fe[0].length,A.index+=gt,gt%2!=0&&(L+="\\")),t.unescape===!0?L=je():L+=je(),A.brackets===0){ke({type:"text",value:L});continue}}if(A.brackets>0&&(L!=="]"||O.value==="["||O.value==="[^")){if(t.posix!==!1&&L===":"){let le=O.value.slice(1);if(le.includes("[")&&(O.posix=!0,le.includes(":"))){let fe=O.value.lastIndexOf("["),gt=O.value.slice(0,fe),Ht=O.value.slice(fe+2),Mt=IBe[Ht];if(Mt){O.value=gt+Mt,A.backtrack=!0,je(),!s.output&&o.indexOf(O)===1&&(s.output=p);continue}}}(L==="["&&Be()!==":"||L==="-"&&Be()==="]")&&(L=`\\${L}`),L==="]"&&(O.value==="["||O.value==="[^")&&(L=`\\${L}`),t.posix===!0&&L==="!"&&O.value==="["&&(L="^"),O.value+=L,be({value:L});continue}if(A.quotes===1&&L!=='"'){L=rs.escapeRegex(L),O.value+=L,be({value:L});continue}if(L==='"'){A.quotes=A.quotes===1?0:1,t.keepQuotes===!0&&ke({type:"text",value:L});continue}if(L==="("){Fe("parens"),ke({type:"paren",value:L});continue}if(L===")"){if(A.parens===0&&t.strictBrackets===!0)throw new SyntaxError(Rg("opening","("));let le=oe[oe.length-1];if(le&&A.parens===le.parens+1){pe(oe.pop());continue}ke({type:"paren",value:L,output:A.parens?")":"\\)"}),Ke("parens");continue}if(L==="["){if(t.nobracket===!0||!re().includes("]")){if(t.nobracket!==!0&&t.strictBrackets===!0)throw new SyntaxError(Rg("closing","]"));L=`\\${L}`}else Fe("brackets");ke({type:"bracket",value:L});continue}if(L==="]"){if(t.nobracket===!0||O&&O.type==="bracket"&&O.value.length===1){ke({type:"text",value:L,output:`\\${L}`});continue}if(A.brackets===0){if(t.strictBrackets===!0)throw new SyntaxError(Rg("opening","["));ke({type:"text",value:L,output:`\\${L}`});continue}Ke("brackets");let le=O.value.slice(1);if(O.posix!==!0&&le[0]==="^"&&!le.includes("/")&&(L=`/${L}`),O.value+=L,be({value:L}),t.literalBrackets===!1||rs.hasRegexChars(le))continue;let fe=rs.escapeRegex(O.value);if(A.output=A.output.slice(0,-O.value.length),t.literalBrackets===!0){A.output+=fe,O.value=fe;continue}O.value=`(${a}${fe}|${O.value})`,A.output+=O.value;continue}if(L==="{"&&t.nobrace!==!0){Fe("braces");let le={type:"brace",value:L,output:"(",outputIndex:A.output.length,tokensIndex:A.tokens.length};ce.push(le),ke(le);continue}if(L==="}"){let le=ce[ce.length-1];if(t.nobrace===!0||!le){ke({type:"text",value:L,output:L});continue}let fe=")";if(le.dots===!0){let gt=o.slice(),Ht=[];for(let Mt=gt.length-1;Mt>=0&&(o.pop(),gt[Mt].type!=="brace");Mt--)gt[Mt].type!=="dots"&&Ht.unshift(gt[Mt].value);fe=BBe(Ht,t),A.backtrack=!0}if(le.comma!==!0&&le.dots!==!0){let gt=A.output.slice(0,le.outputIndex),Ht=A.tokens.slice(le.tokensIndex);le.value=le.output="\\{",L=fe="\\}",A.output=gt;for(let Mt of Ht)A.output+=Mt.output||Mt.value}ke({type:"brace",value:L,output:fe}),Ke("braces"),ce.pop();continue}if(L==="|"){oe.length>0&&oe[oe.length-1].conditions++,ke({type:"text",value:L});continue}if(L===","){let le=L,fe=ce[ce.length-1];fe&&Z[Z.length-1]==="braces"&&(fe.comma=!0,le="|"),ke({type:"comma",value:L,output:le});continue}if(L==="/"){if(O.type==="dot"&&A.index===A.start+1){A.start=A.index+1,A.consumed="",A.output="",o.pop(),O=s;continue}ke({type:"slash",value:L,output:h});continue}if(L==="."){if(A.braces>0&&O.type==="dot"){O.value==="."&&(O.output=g);let le=ce[ce.length-1];O.type="dots",O.output+=L,O.value+=L,le.dots=!0;continue}if(A.braces+A.parens===0&&O.type!=="bos"&&O.type!=="slash"){ke({type:"text",value:L,output:g});continue}ke({type:"dot",value:L,output:g});continue}if(L==="?"){if(!(O&&O.value==="(")&&t.noextglob!==!0&&Be()==="("&&Be(2)!=="?"){ve("qmark",L);continue}if(O&&O.type==="paren"){let fe=Be(),gt=L;if(fe==="<"&&!rs.supportsLookbehinds())throw new Error("Node.js v10 or higher is required for regex lookbehinds");(O.value==="("&&!/[!=<:]/.test(fe)||fe==="<"&&!/<([!=]|\w+>)/.test(re()))&&(gt=`\\${L}`),ke({type:"text",value:L,output:gt});continue}if(t.dot!==!0&&(O.type==="slash"||O.type==="bos")){ke({type:"qmark",value:L,output:T});continue}ke({type:"qmark",value:L,output:x});continue}if(L==="!"){if(t.noextglob!==!0&&Be()==="("&&(Be(2)!=="?"||!/[!=<:]/.test(Be(3)))){ve("negate",L);continue}if(t.nonegate!==!0&&A.index===0){he();continue}}if(L==="+"){if(t.noextglob!==!0&&Be()==="("&&Be(2)!=="?"){ve("plus",L);continue}if(O&&O.value==="("||t.regex===!1){ke({type:"plus",value:L,output:f});continue}if(O&&(O.type==="bracket"||O.type==="paren"||O.type==="brace")||A.parens>0){ke({type:"plus",value:L});continue}ke({type:"plus",value:f});continue}if(L==="@"){if(t.noextglob!==!0&&Be()==="("&&Be(2)!=="?"){ke({type:"at",extglob:!0,value:L,output:""});continue}ke({type:"text",value:L});continue}if(L!=="*"){(L==="$"||L==="^")&&(L=`\\${L}`);let le=yBe.exec(re());le&&(L+=le[0],A.index+=le[0].length),ke({type:"text",value:L});continue}if(O&&(O.type==="globstar"||O.star===!0)){O.type="star",O.star=!0,O.value+=L,O.output=ee,A.backtrack=!0,A.globstar=!0,se(L);continue}let V=re();if(t.noextglob!==!0&&/^\([^?]/.test(V)){ve("star",L);continue}if(O.type==="star"){if(t.noglobstar===!0){se(L);continue}let le=O.prev,fe=le.prev,gt=le.type==="slash"||le.type==="bos",Ht=fe&&(fe.type==="star"||fe.type==="globstar");if(t.bash===!0&&(!gt||V[0]&&V[0]!=="/")){ke({type:"star",value:L,output:""});continue}let Mt=A.braces>0&&(le.type==="comma"||le.type==="brace"),Ei=oe.length&&(le.type==="pipe"||le.type==="paren");if(!gt&&le.type!=="paren"&&!Mt&&!Ei){ke({type:"star",value:L,output:""});continue}for(;V.slice(0,3)==="/**";){let jt=r[A.index+4];if(jt&&jt!=="/")break;V=V.slice(3),se("/**",3)}if(le.type==="bos"&&de()){O.type="globstar",O.value+=L,O.output=$(t),A.output=O.output,A.globstar=!0,se(L);continue}if(le.type==="slash"&&le.prev.type!=="bos"&&!Ht&&de()){A.output=A.output.slice(0,-(le.output+O.output).length),le.output=`(?:${le.output}`,O.type="globstar",O.output=$(t)+(t.strictSlashes?")":"|$)"),O.value+=L,A.globstar=!0,A.output+=le.output+O.output,se(L);continue}if(le.type==="slash"&&le.prev.type!=="bos"&&V[0]==="/"){let jt=V[1]!==void 0?"|$":"";A.output=A.output.slice(0,-(le.output+O.output).length),le.output=`(?:${le.output}`,O.type="globstar",O.output=`${$(t)}${h}|${h}${jt})`,O.value+=L,A.output+=le.output+O.output,A.globstar=!0,se(L+je()),ke({type:"slash",value:"/",output:""});continue}if(le.type==="bos"&&V[0]==="/"){O.type="globstar",O.value+=L,O.output=`(?:^|${h}|${$(t)}${h})`,A.output=O.output,A.globstar=!0,se(L+je()),ke({type:"slash",value:"/",output:""});continue}A.output=A.output.slice(0,-O.output.length),O.type="globstar",O.output=$(t),O.value+=L,A.output+=O.output,A.globstar=!0,se(L);continue}let Qe={type:"star",value:L,output:ee};if(t.bash===!0){Qe.output=".*?",(O.type==="bos"||O.type==="slash")&&(Qe.output=_+Qe.output),ke(Qe);continue}if(O&&(O.type==="bracket"||O.type==="paren")&&t.regex===!0){Qe.output=L,ke(Qe);continue}(A.index===A.start||O.type==="slash"||O.type==="dot")&&(O.type==="dot"?(A.output+=b,O.output+=b):t.dot===!0?(A.output+=v,O.output+=v):(A.output+=_,O.output+=_),Be()!=="*"&&(A.output+=p,O.output+=p)),ke(Qe)}for(;A.brackets>0;){if(t.strictBrackets===!0)throw new SyntaxError(Rg("closing","]"));A.output=rs.escapeLast(A.output,"["),Ke("brackets")}for(;A.parens>0;){if(t.strictBrackets===!0)throw new SyntaxError(Rg("closing",")"));A.output=rs.escapeLast(A.output,"("),Ke("parens")}for(;A.braces>0;){if(t.strictBrackets===!0)throw new SyntaxError(Rg("closing","}"));A.output=rs.escapeLast(A.output,"{"),Ke("braces")}if(t.strictSlashes!==!0&&(O.type==="star"||O.type==="bracket")&&ke({type:"maybe_slash",value:"",output:`${h}?`}),A.backtrack===!0){A.output="";for(let V of A.tokens)A.output+=V.output!=null?V.output:V.value,V.suffix&&(A.output+=V.suffix)}return A};Nq.fastpaths=(r,e)=>{let t=N({},e),i=typeof t.maxLength=="number"?Math.min(xy,t.maxLength):xy,n=r.length;if(n>i)throw new SyntaxError(`Input length: ${n}, exceeds maximum allowed length: ${i}`);r=Fq[r]||r;let s=rs.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}=vy.globChars(s),m=t.dot?g:u,y=t.dot?f:u,b=t.capture?"":"?:",v={negated:!1,prefix:""},x=t.bash===!0?".*?":h;t.capture&&(x=`(${x})`);let T=_=>_.noglobstar===!0?x:`(${b}(?:(?!${p}${_.dot?c:o}).)*?)`,q=_=>{switch(_){case"*":return`${m}${l}${x}`;case".*":return`${o}${l}${x}`;case"*.*":return`${m}${x}${o}${l}${x}`;case"*/*":return`${m}${x}${a}${l}${y}${x}`;case"**":return m+T(t);case"**/*":return`(?:${m}${T(t)}${a})?${y}${l}${x}`;case"**/*.*":return`(?:${m}${T(t)}${a})?${y}${x}${o}${l}${x}`;case"**/.*":return`(?:${m}${T(t)}${a})?${o}${l}${x}`;default:{let ne=/^(.*?)\.(\w+)$/.exec(_);if(!ne)return;let ee=q(ne[1]);return ee?ee+o+ne[2]:void 0}}},Y=rs.removePrefix(r,v),$=q(Y);return $&&t.strictSlashes!==!0&&($+=`${a}?`),$};Rq.exports=Nq});var Oq=w((Qet,Tq)=>{"use strict";var bBe=require("path"),QBe=Dq(),bv=Lq(),Qv=Xp(),SBe=Vp(),vBe=r=>r&&typeof r=="object"&&!Array.isArray(r),_r=(r,e,t=!1)=>{if(Array.isArray(r)){let u=r.map(f=>_r(f,e,t));return f=>{for(let h of u){let p=h(f);if(p)return p}return!1}}let i=vBe(r)&&r.tokens&&r.input;if(r===""||typeof r!="string"&&!i)throw new TypeError("Expected pattern to be a non-empty string");let n=e||{},s=Qv.isWindows(e),o=i?_r.compileRe(r,e):_r.makeRe(r,e,!1,!0),a=o.state;delete o.state;let l=()=>!1;if(n.ignore){let u=te(N({},e),{ignore:null,onMatch:null,onResult:null});l=_r(n.ignore,u,t)}let c=(u,g=!1)=>{let{isMatch:f,match:h,output:p}=_r.test(u,o,e,{glob:r,posix:s}),m={glob:r,state:a,regex:o,posix:s,input:u,output:p,match:h,isMatch:f};return typeof n.onResult=="function"&&n.onResult(m),f===!1?(m.isMatch=!1,g?m:!1):l(u)?(typeof n.onIgnore=="function"&&n.onIgnore(m),m.isMatch=!1,g?m:!1):(typeof n.onMatch=="function"&&n.onMatch(m),g?m:!0)};return t&&(c.state=a),c};_r.test=(r,e,t,{glob:i,posix:n}={})=>{if(typeof r!="string")throw new TypeError("Expected input to be a string");if(r==="")return{isMatch:!1,output:""};let s=t||{},o=s.format||(n?Qv.toPosixSlashes:null),a=r===i,l=a&&o?o(r):r;return a===!1&&(l=o?o(r):r,a=l===i),(a===!1||s.capture===!0)&&(s.matchBase===!0||s.basename===!0?a=_r.matchBase(r,e,t,n):a=e.exec(l)),{isMatch:Boolean(a),match:a,output:l}};_r.matchBase=(r,e,t,i=Qv.isWindows(t))=>(e instanceof RegExp?e:_r.makeRe(e,t)).test(bBe.basename(r));_r.isMatch=(r,e,t)=>_r(e,t)(r);_r.parse=(r,e)=>Array.isArray(r)?r.map(t=>_r.parse(t,e)):bv(r,te(N({},e),{fastpaths:!1}));_r.scan=(r,e)=>QBe(r,e);_r.compileRe=(r,e,t=!1,i=!1)=>{if(t===!0)return r.output;let n=e||{},s=n.contains?"":"^",o=n.contains?"":"$",a=`${s}(?:${r.output})${o}`;r&&r.negated===!0&&(a=`^(?!${a}).*$`);let l=_r.toRegex(a,e);return i===!0&&(l.state=r),l};_r.makeRe=(r,e={},t=!1,i=!1)=>{if(!r||typeof r!="string")throw new TypeError("Expected a non-empty string");let n={negated:!1,fastpaths:!0};return e.fastpaths!==!1&&(r[0]==="."||r[0]==="*")&&(n.output=bv.fastpaths(r,e)),n.output||(n=bv(r,e)),_r.compileRe(n,e,t,i)};_r.toRegex=(r,e)=>{try{let t=e||{};return new RegExp(r,t.flags||(t.nocase?"i":""))}catch(t){if(e&&e.debug===!0)throw t;return/$^/}};_r.constants=SBe;Tq.exports=_r});var Sv=w((vet,Mq)=>{"use strict";Mq.exports=Oq()});var is=w((xet,Kq)=>{"use strict";var Uq=require("util"),Hq=mq(),Wo=Sv(),vv=Xp(),jq=r=>r===""||r==="./",Pr=(r,e,t)=>{e=[].concat(e),r=[].concat(r);let i=new Set,n=new Set,s=new Set,o=0,a=u=>{s.add(u.output),t&&t.onResult&&t.onResult(u)};for(let u=0;u!i.has(u));if(t&&c.length===0){if(t.failglob===!0)throw new Error(`No matches found for "${e.join(", ")}"`);if(t.nonull===!0||t.nullglob===!0)return t.unescape?e.map(u=>u.replace(/\\/g,"")):e}return c};Pr.match=Pr;Pr.matcher=(r,e)=>Wo(r,e);Pr.isMatch=(r,e,t)=>Wo(e,t)(r);Pr.any=Pr.isMatch;Pr.not=(r,e,t={})=>{e=[].concat(e).map(String);let i=new Set,n=[],s=a=>{t.onResult&&t.onResult(a),n.push(a.output)},o=Pr(r,e,te(N({},t),{onResult:s}));for(let a of n)o.includes(a)||i.add(a);return[...i]};Pr.contains=(r,e,t)=>{if(typeof r!="string")throw new TypeError(`Expected a string: "${Uq.inspect(r)}"`);if(Array.isArray(e))return e.some(i=>Pr.contains(r,i,t));if(typeof e=="string"){if(jq(r)||jq(e))return!1;if(r.includes(e)||r.startsWith("./")&&r.slice(2).includes(e))return!0}return Pr.isMatch(r,e,te(N({},t),{contains:!0}))};Pr.matchKeys=(r,e,t)=>{if(!vv.isObject(r))throw new TypeError("Expected the first argument to be an object");let i=Pr(Object.keys(r),e,t),n={};for(let s of i)n[s]=r[s];return n};Pr.some=(r,e,t)=>{let i=[].concat(r);for(let n of[].concat(e)){let s=Wo(String(n),t);if(i.some(o=>s(o)))return!0}return!1};Pr.every=(r,e,t)=>{let i=[].concat(r);for(let n of[].concat(e)){let s=Wo(String(n),t);if(!i.every(o=>s(o)))return!1}return!0};Pr.all=(r,e,t)=>{if(typeof r!="string")throw new TypeError(`Expected a string: "${Uq.inspect(r)}"`);return[].concat(e).every(i=>Wo(i,t)(r))};Pr.capture=(r,e,t)=>{let i=vv.isWindows(t),s=Wo.makeRe(String(r),te(N({},t),{capture:!0})).exec(i?vv.toPosixSlashes(e):e);if(s)return s.slice(1).map(o=>o===void 0?"":o)};Pr.makeRe=(...r)=>Wo.makeRe(...r);Pr.scan=(...r)=>Wo.scan(...r);Pr.parse=(r,e)=>{let t=[];for(let i of[].concat(r||[]))for(let n of Hq(String(i),e))t.push(Wo.parse(n,e));return t};Pr.braces=(r,e)=>{if(typeof r!="string")throw new TypeError("Expected a string");return e&&e.nobrace===!0||!/\{.*\}/.test(r)?[r]:Hq(r,e)};Pr.braceExpand=(r,e)=>{if(typeof r!="string")throw new TypeError("Expected a string");return Pr.braces(r,te(N({},e),{expand:!0}))};Kq.exports=Pr});var Yq=w((ket,Gq)=>{"use strict";Gq.exports=({onlyFirst:r=!1}={})=>{let e=["[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]+)*|[a-zA-Z\\d]+(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?\\u0007)","(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-ntqry=><~]))"].join("|");return new RegExp(e,r?void 0:"g")}});var Jq=w((Pet,qq)=>{"use strict";var xBe=Yq();qq.exports=r=>typeof r=="string"?r.replace(xBe(),""):r});var AJ=w((zet,aJ)=>{"use strict";aJ.exports=(...r)=>[...new Set([].concat(...r))]});var jv=w((_et,lJ)=>{"use strict";var UBe=require("stream"),cJ=UBe.PassThrough,HBe=Array.prototype.slice;lJ.exports=jBe;function jBe(){let r=[],e=!1,t=HBe.call(arguments),i=t[t.length-1];i&&!Array.isArray(i)&&i.pipe==null?t.pop():i={};let n=i.end!==!1;i.objectMode==null&&(i.objectMode=!0),i.highWaterMark==null&&(i.highWaterMark=64*1024);let s=cJ(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(Fy,"__esModule",{value:!0});function GBe(r){return r.reduce((e,t)=>[].concat(e,t),[])}Fy.flatten=GBe;function YBe(r,e){let t=[[]],i=0;for(let n of r)e(n)?(i++,t[i]=[]):t[i].push(n);return t}Fy.splitWhen=YBe});var fJ=w(Gv=>{"use strict";Object.defineProperty(Gv,"__esModule",{value:!0});function qBe(r){return r.code==="ENOENT"}Gv.isEnoentCodeError=qBe});var pJ=w(Yv=>{"use strict";Object.defineProperty(Yv,"__esModule",{value:!0});var hJ=class{constructor(e,t){this.name=e,this.isBlockDevice=t.isBlockDevice.bind(t),this.isCharacterDevice=t.isCharacterDevice.bind(t),this.isDirectory=t.isDirectory.bind(t),this.isFIFO=t.isFIFO.bind(t),this.isFile=t.isFile.bind(t),this.isSocket=t.isSocket.bind(t),this.isSymbolicLink=t.isSymbolicLink.bind(t)}};function JBe(r,e){return new hJ(r,e)}Yv.createDirentFromStats=JBe});var dJ=w(Kg=>{"use strict";Object.defineProperty(Kg,"__esModule",{value:!0});var WBe=require("path"),zBe=2,_Be=/(\\?)([()*?[\]{|}]|^!|[!+@](?=\())/g;function VBe(r){return r.replace(/\\/g,"/")}Kg.unixify=VBe;function XBe(r,e){return WBe.resolve(r,e)}Kg.makeAbsolute=XBe;function ZBe(r){return r.replace(_Be,"\\$2")}Kg.escape=ZBe;function $Be(r){if(r.charAt(0)==="."){let e=r.charAt(1);if(e==="/"||e==="\\")return r.slice(zBe)}return r}Kg.removeLeadingDotSegment=$Be});var mJ=w((ett,CJ)=>{CJ.exports=function(e){if(typeof e!="string"||e==="")return!1;for(var t;t=/(\\).|([@?!+*]\(.*\))/g.exec(e);){if(t[2])return!0;e=e.slice(t.index+t[0].length)}return!1}});var yJ=w((ttt,EJ)=>{var e0e=mJ(),IJ={"{":"}","(":")","[":"]"},t0e=function(r){if(r[0]==="!")return!0;for(var e=0,t=-2,i=-2,n=-2,s=-2,o=-2;ee&&(o===-1||o>i||(o=r.indexOf("\\",e),o===-1||o>i)))||n!==-1&&r[e]==="{"&&r[e+1]!=="}"&&(n=r.indexOf("}",e),n>e&&(o=r.indexOf("\\",e),o===-1||o>n))||s!==-1&&r[e]==="("&&r[e+1]==="?"&&/[:!=]/.test(r[e+2])&&r[e+3]!==")"&&(s=r.indexOf(")",e),s>e&&(o=r.indexOf("\\",e),o===-1||o>s))||t!==-1&&r[e]==="("&&r[e+1]!=="|"&&(tt&&(o=r.indexOf("\\",t),o===-1||o>s))))return!0;if(r[e]==="\\"){var a=r[e+1];e+=2;var l=IJ[a];if(l){var c=r.indexOf(l,e);c!==-1&&(e=c+1)}if(r[e]==="!")return!0}else e++}return!1},r0e=function(r){if(r[0]==="!")return!0;for(var e=0;e{"use strict";var i0e=yJ(),n0e=require("path").posix.dirname,s0e=require("os").platform()==="win32",qv="/",o0e=/\\/g,a0e=/[\{\[].*[\}\]]$/,A0e=/(^|[^\\])([\{\[]|\([^\)]+$)/,l0e=/\\([\!\*\?\|\[\]\(\)\{\}])/g;wJ.exports=function(e,t){var i=Object.assign({flipBackslashes:!0},t);i.flipBackslashes&&s0e&&e.indexOf(qv)<0&&(e=e.replace(o0e,qv)),a0e.test(e)&&(e+=qv),e+="a";do e=n0e(e);while(i0e(e)||A0e.test(e));return e.replace(l0e,"$1")}});var RJ=w(si=>{"use strict";Object.defineProperty(si,"__esModule",{value:!0});var c0e=require("path"),u0e=BJ(),bJ=is(),g0e=Sv(),QJ="**",f0e="\\",h0e=/[*?]|^!/,p0e=/\[.*]/,d0e=/(?:^|[^!*+?@])\(.*\|.*\)/,C0e=/[!*+?@]\(.*\)/,m0e=/{.*(?:,|\.\.).*}/;function vJ(r,e={}){return!SJ(r,e)}si.isStaticPattern=vJ;function SJ(r,e={}){return!!(e.caseSensitiveMatch===!1||r.includes(f0e)||h0e.test(r)||p0e.test(r)||d0e.test(r)||e.extglob!==!1&&C0e.test(r)||e.braceExpansion!==!1&&m0e.test(r))}si.isDynamicPattern=SJ;function E0e(r){return Ny(r)?r.slice(1):r}si.convertToPositivePattern=E0e;function I0e(r){return"!"+r}si.convertToNegativePattern=I0e;function Ny(r){return r.startsWith("!")&&r[1]!=="("}si.isNegativePattern=Ny;function xJ(r){return!Ny(r)}si.isPositivePattern=xJ;function y0e(r){return r.filter(Ny)}si.getNegativePatterns=y0e;function w0e(r){return r.filter(xJ)}si.getPositivePatterns=w0e;function B0e(r){return u0e(r,{flipBackslashes:!1})}si.getBaseDirectory=B0e;function b0e(r){return r.includes(QJ)}si.hasGlobStar=b0e;function kJ(r){return r.endsWith("/"+QJ)}si.endsWithSlashGlobStar=kJ;function Q0e(r){let e=c0e.basename(r);return kJ(r)||vJ(e)}si.isAffectDepthOfReadingPattern=Q0e;function S0e(r){return r.reduce((e,t)=>e.concat(PJ(t)),[])}si.expandPatternsWithBraceExpansion=S0e;function PJ(r){return bJ.braces(r,{expand:!0,nodupes:!0})}si.expandBraceExpansion=PJ;function v0e(r,e){let t=g0e.scan(r,Object.assign(Object.assign({},e),{parts:!0}));return t.parts.length===0?[r]:t.parts}si.getPatternParts=v0e;function DJ(r,e){return bJ.makeRe(r,e)}si.makeRe=DJ;function x0e(r,e){return r.map(t=>DJ(t,e))}si.convertPatternsToRe=x0e;function k0e(r,e){return e.some(t=>t.test(r))}si.matchAny=k0e});var NJ=w(Jv=>{"use strict";Object.defineProperty(Jv,"__esModule",{value:!0});var P0e=jv();function D0e(r){let e=P0e(r);return r.forEach(t=>{t.once("error",i=>e.emit("error",i))}),e.once("close",()=>FJ(r)),e.once("end",()=>FJ(r)),e}Jv.merge=D0e;function FJ(r){r.forEach(e=>e.emit("close"))}});var LJ=w(Ly=>{"use strict";Object.defineProperty(Ly,"__esModule",{value:!0});function R0e(r){return typeof r=="string"}Ly.isString=R0e;function F0e(r){return r===""}Ly.isEmpty=F0e});var Xa=w(Va=>{"use strict";Object.defineProperty(Va,"__esModule",{value:!0});var N0e=gJ();Va.array=N0e;var L0e=fJ();Va.errno=L0e;var T0e=pJ();Va.fs=T0e;var O0e=dJ();Va.path=O0e;var M0e=RJ();Va.pattern=M0e;var K0e=NJ();Va.stream=K0e;var U0e=LJ();Va.string=U0e});var UJ=w(Za=>{"use strict";Object.defineProperty(Za,"__esModule",{value:!0});var Mc=Xa();function H0e(r,e){let t=TJ(r),i=OJ(r,e.ignore),n=t.filter(l=>Mc.pattern.isStaticPattern(l,e)),s=t.filter(l=>Mc.pattern.isDynamicPattern(l,e)),o=Wv(n,i,!1),a=Wv(s,i,!0);return o.concat(a)}Za.generate=H0e;function Wv(r,e,t){let i=MJ(r);return"."in i?[zv(".",r,e,t)]:KJ(i,e,t)}Za.convertPatternsToTasks=Wv;function TJ(r){return Mc.pattern.getPositivePatterns(r)}Za.getPositivePatterns=TJ;function OJ(r,e){return Mc.pattern.getNegativePatterns(r).concat(e).map(Mc.pattern.convertToPositivePattern)}Za.getNegativePatternsAsPositive=OJ;function MJ(r){let e={};return r.reduce((t,i)=>{let n=Mc.pattern.getBaseDirectory(i);return n in t?t[n].push(i):t[n]=[i],t},e)}Za.groupPatternsByBaseDirectory=MJ;function KJ(r,e,t){return Object.keys(r).map(i=>zv(i,r[i],e,t))}Za.convertPatternGroupsToTasks=KJ;function zv(r,e,t,i){return{dynamic:i,positive:e,negative:t,base:r,patterns:[].concat(e,t.map(Mc.pattern.convertToNegativePattern))}}Za.convertPatternGroupToTask=zv});var jJ=w(Ty=>{"use strict";Object.defineProperty(Ty,"__esModule",{value:!0});Ty.read=void 0;function j0e(r,e,t){e.fs.lstat(r,(i,n)=>{if(i!==null){HJ(t,i);return}if(!n.isSymbolicLink()||!e.followSymbolicLink){_v(t,n);return}e.fs.stat(r,(s,o)=>{if(s!==null){if(e.throwErrorOnBrokenSymbolicLink){HJ(t,s);return}_v(t,n);return}e.markSymbolicLink&&(o.isSymbolicLink=()=>!0),_v(t,o)})})}Ty.read=j0e;function HJ(r,e){r(e)}function _v(r,e){r(null,e)}});var GJ=w(Oy=>{"use strict";Object.defineProperty(Oy,"__esModule",{value:!0});Oy.read=void 0;function G0e(r,e){let t=e.fs.lstatSync(r);if(!t.isSymbolicLink()||!e.followSymbolicLink)return t;try{let i=e.fs.statSync(r);return e.markSymbolicLink&&(i.isSymbolicLink=()=>!0),i}catch(i){if(!e.throwErrorOnBrokenSymbolicLink)return t;throw i}}Oy.read=G0e});var YJ=w(rl=>{"use strict";Object.defineProperty(rl,"__esModule",{value:!0});rl.createFileSystemAdapter=rl.FILE_SYSTEM_ADAPTER=void 0;var My=require("fs");rl.FILE_SYSTEM_ADAPTER={lstat:My.lstat,stat:My.stat,lstatSync:My.lstatSync,statSync:My.statSync};function Y0e(r){return r===void 0?rl.FILE_SYSTEM_ADAPTER:Object.assign(Object.assign({},rl.FILE_SYSTEM_ADAPTER),r)}rl.createFileSystemAdapter=Y0e});var JJ=w(Vv=>{"use strict";Object.defineProperty(Vv,"__esModule",{value:!0});var q0e=YJ(),qJ=class{constructor(e={}){this._options=e,this.followSymbolicLink=this._getValue(this._options.followSymbolicLink,!0),this.fs=q0e.createFileSystemAdapter(this._options.fs),this.markSymbolicLink=this._getValue(this._options.markSymbolicLink,!1),this.throwErrorOnBrokenSymbolicLink=this._getValue(this._options.throwErrorOnBrokenSymbolicLink,!0)}_getValue(e,t){return e!=null?e:t}};Vv.default=qJ});var Kc=w(il=>{"use strict";Object.defineProperty(il,"__esModule",{value:!0});il.statSync=il.stat=il.Settings=void 0;var WJ=jJ(),J0e=GJ(),Xv=JJ();il.Settings=Xv.default;function W0e(r,e,t){if(typeof e=="function"){WJ.read(r,Zv(),e);return}WJ.read(r,Zv(e),t)}il.stat=W0e;function z0e(r,e){let t=Zv(e);return J0e.read(r,t)}il.statSync=z0e;function Zv(r={}){return r instanceof Xv.default?r:new Xv.default(r)}});var _J=w((ftt,zJ)=>{zJ.exports=_0e;function _0e(r,e){var t,i,n,s=!0;Array.isArray(r)?(t=[],i=r.length):(n=Object.keys(r),t={},i=n.length);function o(l){function c(){e&&e(l,t),e=null}s?process.nextTick(c):c()}function a(l,c,u){t[l]=u,(--i==0||c)&&o(c)}i?n?n.forEach(function(l){r[l](function(c,u){a(l,c,u)})}):r.forEach(function(l,c){l(function(u,g){a(c,u,g)})}):o(null),s=!1}});var $v=w(Ky=>{"use strict";Object.defineProperty(Ky,"__esModule",{value:!0});Ky.IS_SUPPORT_READDIR_WITH_FILE_TYPES=void 0;var Uy=process.versions.node.split(".");if(Uy[0]===void 0||Uy[1]===void 0)throw new Error(`Unexpected behavior. The 'process.versions.node' variable has invalid value: ${process.versions.node}`);var VJ=Number.parseInt(Uy[0],10),V0e=Number.parseInt(Uy[1],10),XJ=10,X0e=10,Z0e=VJ>XJ,$0e=VJ===XJ&&V0e>=X0e;Ky.IS_SUPPORT_READDIR_WITH_FILE_TYPES=Z0e||$0e});var $J=w(Hy=>{"use strict";Object.defineProperty(Hy,"__esModule",{value:!0});Hy.createDirentFromStats=void 0;var ZJ=class{constructor(e,t){this.name=e,this.isBlockDevice=t.isBlockDevice.bind(t),this.isCharacterDevice=t.isCharacterDevice.bind(t),this.isDirectory=t.isDirectory.bind(t),this.isFIFO=t.isFIFO.bind(t),this.isFile=t.isFile.bind(t),this.isSocket=t.isSocket.bind(t),this.isSymbolicLink=t.isSymbolicLink.bind(t)}};function ebe(r,e){return new ZJ(r,e)}Hy.createDirentFromStats=ebe});var ex=w(jy=>{"use strict";Object.defineProperty(jy,"__esModule",{value:!0});jy.fs=void 0;var tbe=$J();jy.fs=tbe});var tx=w(Gy=>{"use strict";Object.defineProperty(Gy,"__esModule",{value:!0});Gy.joinPathSegments=void 0;function rbe(r,e,t){return r.endsWith(t)?r+e:r+t+e}Gy.joinPathSegments=rbe});var s3=w(nl=>{"use strict";Object.defineProperty(nl,"__esModule",{value:!0});nl.readdir=nl.readdirWithFileTypes=nl.read=void 0;var ibe=Kc(),e3=_J(),nbe=$v(),t3=ex(),r3=tx();function sbe(r,e,t){if(!e.stats&&nbe.IS_SUPPORT_READDIR_WITH_FILE_TYPES){i3(r,e,t);return}n3(r,e,t)}nl.read=sbe;function i3(r,e,t){e.fs.readdir(r,{withFileTypes:!0},(i,n)=>{if(i!==null){Yy(t,i);return}let s=n.map(a=>({dirent:a,name:a.name,path:r3.joinPathSegments(r,a.name,e.pathSegmentSeparator)}));if(!e.followSymbolicLinks){rx(t,s);return}let o=s.map(a=>obe(a,e));e3(o,(a,l)=>{if(a!==null){Yy(t,a);return}rx(t,l)})})}nl.readdirWithFileTypes=i3;function obe(r,e){return t=>{if(!r.dirent.isSymbolicLink()){t(null,r);return}e.fs.stat(r.path,(i,n)=>{if(i!==null){if(e.throwErrorOnBrokenSymbolicLink){t(i);return}t(null,r);return}r.dirent=t3.fs.createDirentFromStats(r.name,n),t(null,r)})}}function n3(r,e,t){e.fs.readdir(r,(i,n)=>{if(i!==null){Yy(t,i);return}let s=n.map(o=>{let a=r3.joinPathSegments(r,o,e.pathSegmentSeparator);return l=>{ibe.stat(a,e.fsStatSettings,(c,u)=>{if(c!==null){l(c);return}let g={name:o,path:a,dirent:t3.fs.createDirentFromStats(o,u)};e.stats&&(g.stats=u),l(null,g)})}});e3(s,(o,a)=>{if(o!==null){Yy(t,o);return}rx(t,a)})})}nl.readdir=n3;function Yy(r,e){r(e)}function rx(r,e){r(null,e)}});var c3=w(sl=>{"use strict";Object.defineProperty(sl,"__esModule",{value:!0});sl.readdir=sl.readdirWithFileTypes=sl.read=void 0;var abe=Kc(),Abe=$v(),o3=ex(),a3=tx();function lbe(r,e){return!e.stats&&Abe.IS_SUPPORT_READDIR_WITH_FILE_TYPES?A3(r,e):l3(r,e)}sl.read=lbe;function A3(r,e){return e.fs.readdirSync(r,{withFileTypes:!0}).map(i=>{let n={dirent:i,name:i.name,path:a3.joinPathSegments(r,i.name,e.pathSegmentSeparator)};if(n.dirent.isSymbolicLink()&&e.followSymbolicLinks)try{let s=e.fs.statSync(n.path);n.dirent=o3.fs.createDirentFromStats(n.name,s)}catch(s){if(e.throwErrorOnBrokenSymbolicLink)throw s}return n})}sl.readdirWithFileTypes=A3;function l3(r,e){return e.fs.readdirSync(r).map(i=>{let n=a3.joinPathSegments(r,i,e.pathSegmentSeparator),s=abe.statSync(n,e.fsStatSettings),o={name:i,path:n,dirent:o3.fs.createDirentFromStats(i,s)};return e.stats&&(o.stats=s),o})}sl.readdir=l3});var u3=w(ol=>{"use strict";Object.defineProperty(ol,"__esModule",{value:!0});ol.createFileSystemAdapter=ol.FILE_SYSTEM_ADAPTER=void 0;var Ug=require("fs");ol.FILE_SYSTEM_ADAPTER={lstat:Ug.lstat,stat:Ug.stat,lstatSync:Ug.lstatSync,statSync:Ug.statSync,readdir:Ug.readdir,readdirSync:Ug.readdirSync};function cbe(r){return r===void 0?ol.FILE_SYSTEM_ADAPTER:Object.assign(Object.assign({},ol.FILE_SYSTEM_ADAPTER),r)}ol.createFileSystemAdapter=cbe});var f3=w(ix=>{"use strict";Object.defineProperty(ix,"__esModule",{value:!0});var ube=require("path"),gbe=Kc(),fbe=u3(),g3=class{constructor(e={}){this._options=e,this.followSymbolicLinks=this._getValue(this._options.followSymbolicLinks,!1),this.fs=fbe.createFileSystemAdapter(this._options.fs),this.pathSegmentSeparator=this._getValue(this._options.pathSegmentSeparator,ube.sep),this.stats=this._getValue(this._options.stats,!1),this.throwErrorOnBrokenSymbolicLink=this._getValue(this._options.throwErrorOnBrokenSymbolicLink,!0),this.fsStatSettings=new gbe.Settings({followSymbolicLink:this.followSymbolicLinks,fs:this.fs,throwErrorOnBrokenSymbolicLink:this.throwErrorOnBrokenSymbolicLink})}_getValue(e,t){return e!=null?e:t}};ix.default=g3});var qy=w(al=>{"use strict";Object.defineProperty(al,"__esModule",{value:!0});al.Settings=al.scandirSync=al.scandir=void 0;var h3=s3(),hbe=c3(),nx=f3();al.Settings=nx.default;function pbe(r,e,t){if(typeof e=="function"){h3.read(r,sx(),e);return}h3.read(r,sx(e),t)}al.scandir=pbe;function dbe(r,e){let t=sx(e);return hbe.read(r,t)}al.scandirSync=dbe;function sx(r={}){return r instanceof nx.default?r:new nx.default(r)}});var d3=w((Btt,p3)=>{"use strict";function Cbe(r){var e=new r,t=e;function i(){var s=e;return s.next?e=s.next:(e=new r,t=e),s.next=null,s}function n(s){t.next=s,t=s}return{get:i,release:n}}p3.exports=Cbe});var m3=w((btt,ox)=>{"use strict";var mbe=d3();function C3(r,e,t){if(typeof r=="function"&&(t=e,e=r,r=null),t<1)throw new Error("fastqueue concurrency must be greater than 1");var i=mbe(Ebe),n=null,s=null,o=0,a=null,l={push:m,drain:Vo,saturated:Vo,pause:u,paused:!1,concurrency:t,running:c,resume:h,idle:p,length:g,getQueue:f,unshift:y,empty:Vo,kill:v,killAndDrain:x,error:T};return l;function c(){return o}function u(){l.paused=!0}function g(){for(var q=n,Y=0;q;)q=q.next,Y++;return Y}function f(){for(var q=n,Y=[];q;)Y.push(q.value),q=q.next;return Y}function h(){if(!!l.paused){l.paused=!1;for(var q=0;q{"use strict";Object.defineProperty(Xo,"__esModule",{value:!0});Xo.joinPathSegments=Xo.replacePathSegmentSeparator=Xo.isAppliedFilter=Xo.isFatalError=void 0;function ybe(r,e){return r.errorFilter===null?!0:!r.errorFilter(e)}Xo.isFatalError=ybe;function wbe(r,e){return r===null||r(e)}Xo.isAppliedFilter=wbe;function Bbe(r,e){return r.split(/[/\\]/).join(e)}Xo.replacePathSegmentSeparator=Bbe;function bbe(r,e,t){return r===""?e:r.endsWith(t)?r+e:r+t+e}Xo.joinPathSegments=bbe});var Ax=w(ax=>{"use strict";Object.defineProperty(ax,"__esModule",{value:!0});var Qbe=Jy(),E3=class{constructor(e,t){this._root=e,this._settings=t,this._root=Qbe.replacePathSegmentSeparator(e,t.pathSegmentSeparator)}};ax.default=E3});var cx=w(lx=>{"use strict";Object.defineProperty(lx,"__esModule",{value:!0});var Sbe=require("events"),vbe=qy(),xbe=m3(),Wy=Jy(),kbe=Ax(),I3=class extends kbe.default{constructor(e,t){super(e,t);this._settings=t,this._scandir=vbe.scandir,this._emitter=new Sbe.EventEmitter,this._queue=xbe(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,t){let i={directory:e,base:t};this._queue.push(i,n=>{n!==null&&this._handleError(n)})}_worker(e,t){this._scandir(e.directory,this._settings.fsScandirSettings,(i,n)=>{if(i!==null){t(i,void 0);return}for(let s of n)this._handleEntry(s,e.base);t(null,void 0)})}_handleError(e){this._isDestroyed||!Wy.isFatalError(this._settings,e)||(this._isFatalError=!0,this._isDestroyed=!0,this._emitter.emit("error",e))}_handleEntry(e,t){if(this._isDestroyed||this._isFatalError)return;let i=e.path;t!==void 0&&(e.path=Wy.joinPathSegments(t,e.name,this._settings.pathSegmentSeparator)),Wy.isAppliedFilter(this._settings.entryFilter,e)&&this._emitEntry(e),e.dirent.isDirectory()&&Wy.isAppliedFilter(this._settings.deepFilter,e)&&this._pushToQueue(i,e.path)}_emitEntry(e){this._emitter.emit("entry",e)}};lx.default=I3});var w3=w(ux=>{"use strict";Object.defineProperty(ux,"__esModule",{value:!0});var Pbe=cx(),y3=class{constructor(e,t){this._root=e,this._settings=t,this._reader=new Pbe.default(this._root,this._settings),this._storage=new Set}read(e){this._reader.onError(t=>{Dbe(e,t)}),this._reader.onEntry(t=>{this._storage.add(t)}),this._reader.onEnd(()=>{Rbe(e,[...this._storage])}),this._reader.read()}};ux.default=y3;function Dbe(r,e){r(e)}function Rbe(r,e){r(null,e)}});var b3=w(gx=>{"use strict";Object.defineProperty(gx,"__esModule",{value:!0});var Fbe=require("stream"),Nbe=cx(),B3=class{constructor(e,t){this._root=e,this._settings=t,this._reader=new Nbe.default(this._root,this._settings),this._stream=new Fbe.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}};gx.default=B3});var S3=w(fx=>{"use strict";Object.defineProperty(fx,"__esModule",{value:!0});var Lbe=qy(),zy=Jy(),Tbe=Ax(),Q3=class extends Tbe.default{constructor(){super(...arguments);this._scandir=Lbe.scandirSync,this._storage=new Set,this._queue=new Set}read(){return this._pushToQueue(this._root,this._settings.basePath),this._handleQueue(),[...this._storage]}_pushToQueue(e,t){this._queue.add({directory:e,base:t})}_handleQueue(){for(let e of this._queue.values())this._handleDirectory(e.directory,e.base)}_handleDirectory(e,t){try{let i=this._scandir(e,this._settings.fsScandirSettings);for(let n of i)this._handleEntry(n,t)}catch(i){this._handleError(i)}}_handleError(e){if(!!zy.isFatalError(this._settings,e))throw e}_handleEntry(e,t){let i=e.path;t!==void 0&&(e.path=zy.joinPathSegments(t,e.name,this._settings.pathSegmentSeparator)),zy.isAppliedFilter(this._settings.entryFilter,e)&&this._pushToStorage(e),e.dirent.isDirectory()&&zy.isAppliedFilter(this._settings.deepFilter,e)&&this._pushToQueue(i,e.path)}_pushToStorage(e){this._storage.add(e)}};fx.default=Q3});var x3=w(hx=>{"use strict";Object.defineProperty(hx,"__esModule",{value:!0});var Obe=S3(),v3=class{constructor(e,t){this._root=e,this._settings=t,this._reader=new Obe.default(this._root,this._settings)}read(){return this._reader.read()}};hx.default=v3});var P3=w(px=>{"use strict";Object.defineProperty(px,"__esModule",{value:!0});var Mbe=require("path"),Kbe=qy(),k3=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,Mbe.sep),this.fsScandirSettings=new Kbe.Settings({followSymbolicLinks:this._options.followSymbolicLinks,fs:this._options.fs,pathSegmentSeparator:this._options.pathSegmentSeparator,stats:this._options.stats,throwErrorOnBrokenSymbolicLink:this._options.throwErrorOnBrokenSymbolicLink})}_getValue(e,t){return e!=null?e:t}};px.default=k3});var Cx=w(Zo=>{"use strict";Object.defineProperty(Zo,"__esModule",{value:!0});Zo.Settings=Zo.walkStream=Zo.walkSync=Zo.walk=void 0;var D3=w3(),Ube=b3(),Hbe=x3(),dx=P3();Zo.Settings=dx.default;function jbe(r,e,t){if(typeof e=="function"){new D3.default(r,_y()).read(e);return}new D3.default(r,_y(e)).read(t)}Zo.walk=jbe;function Gbe(r,e){let t=_y(e);return new Hbe.default(r,t).read()}Zo.walkSync=Gbe;function Ybe(r,e){let t=_y(e);return new Ube.default(r,t).read()}Zo.walkStream=Ybe;function _y(r={}){return r instanceof dx.default?r:new dx.default(r)}});var Ex=w(mx=>{"use strict";Object.defineProperty(mx,"__esModule",{value:!0});var qbe=require("path"),Jbe=Kc(),R3=Xa(),F3=class{constructor(e){this._settings=e,this._fsStatSettings=new Jbe.Settings({followSymbolicLink:this._settings.followSymbolicLinks,fs:this._settings.fs,throwErrorOnBrokenSymbolicLink:this._settings.followSymbolicLinks})}_getFullEntryPath(e){return qbe.resolve(this._settings.cwd,e)}_makeEntry(e,t){let i={name:t,path:t,dirent:R3.fs.createDirentFromStats(t,e)};return this._settings.stats&&(i.stats=e),i}_isFatalError(e){return!R3.errno.isEnoentCodeError(e)&&!this._settings.suppressErrors}};mx.default=F3});var yx=w(Ix=>{"use strict";Object.defineProperty(Ix,"__esModule",{value:!0});var Wbe=require("stream"),zbe=Kc(),_be=Cx(),Vbe=Ex(),N3=class extends Vbe.default{constructor(){super(...arguments);this._walkStream=_be.walkStream,this._stat=zbe.stat}dynamic(e,t){return this._walkStream(e,t)}static(e,t){let i=e.map(this._getFullEntryPath,this),n=new Wbe.PassThrough({objectMode:!0});n._write=(s,o,a)=>this._getEntry(i[s],e[s],t).then(l=>{l!==null&&t.entryFilter(l)&&n.push(l),s===i.length-1&&n.end(),a()}).catch(a);for(let s=0;sthis._makeEntry(n,t)).catch(n=>{if(i.errorFilter(n))return null;throw n})}_getStat(e){return new Promise((t,i)=>{this._stat(e,this._fsStatSettings,(n,s)=>n===null?t(s):i(n))})}};Ix.default=N3});var T3=w(wx=>{"use strict";Object.defineProperty(wx,"__esModule",{value:!0});var Hg=Xa(),L3=class{constructor(e,t,i){this._patterns=e,this._settings=t,this._micromatchOptions=i,this._storage=[],this._fillStorage()}_fillStorage(){let e=Hg.pattern.expandPatternsWithBraceExpansion(this._patterns);for(let t of e){let i=this._getPatternSegments(t),n=this._splitSegmentsIntoSections(i);this._storage.push({complete:n.length<=1,pattern:t,segments:i,sections:n})}}_getPatternSegments(e){return Hg.pattern.getPatternParts(e,this._micromatchOptions).map(i=>Hg.pattern.isDynamicPattern(i,this._settings)?{dynamic:!0,pattern:i,patternRe:Hg.pattern.makeRe(i,this._micromatchOptions)}:{dynamic:!1,pattern:i})}_splitSegmentsIntoSections(e){return Hg.array.splitWhen(e,t=>t.dynamic&&Hg.pattern.hasGlobStar(t.pattern))}};wx.default=L3});var M3=w(Bx=>{"use strict";Object.defineProperty(Bx,"__esModule",{value:!0});var Xbe=T3(),O3=class extends Xbe.default{match(e){let t=e.split("/"),i=t.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||t.every((l,c)=>{let u=s.segments[c];return!!(u.dynamic&&u.patternRe.test(l)||!u.dynamic&&u.pattern===l)}))return!0}return!1}};Bx.default=O3});var U3=w(bx=>{"use strict";Object.defineProperty(bx,"__esModule",{value:!0});var Vy=Xa(),Zbe=M3(),K3=class{constructor(e,t){this._settings=e,this._micromatchOptions=t}getFilter(e,t,i){let n=this._getMatcher(t),s=this._getNegativePatternsRe(i);return o=>this._filter(e,o,n,s)}_getMatcher(e){return new Zbe.default(e,this._settings,this._micromatchOptions)}_getNegativePatternsRe(e){let t=e.filter(Vy.pattern.isAffectDepthOfReadingPattern);return Vy.pattern.convertPatternsToRe(t,this._micromatchOptions)}_filter(e,t,i,n){let s=this._getEntryLevel(e,t.path);if(this._isSkippedByDeep(s)||this._isSkippedSymbolicLink(t))return!1;let o=Vy.path.removeLeadingDotSegment(t.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,t){let i=e.split("/").length;return t.split("/").length-(e===""?0:i)}_isSkippedByPositivePatterns(e,t){return!this._settings.baseNameMatch&&!t.match(e)}_isSkippedByNegativePatterns(e,t){return!Vy.pattern.matchAny(e,t)}};bx.default=K3});var j3=w(Qx=>{"use strict";Object.defineProperty(Qx,"__esModule",{value:!0});var sd=Xa(),H3=class{constructor(e,t){this._settings=e,this._micromatchOptions=t,this.index=new Map}getFilter(e,t){let i=sd.pattern.convertPatternsToRe(e,this._micromatchOptions),n=sd.pattern.convertPatternsToRe(t,this._micromatchOptions);return s=>this._filter(s,i,n)}_filter(e,t,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,t)&&!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,t){if(!this._settings.absolute)return!1;let i=sd.path.makeAbsolute(this._settings.cwd,e.path);return this._isMatchToPatterns(i,t)}_isMatchToPatterns(e,t){let i=sd.path.removeLeadingDotSegment(e);return sd.pattern.matchAny(i,t)}};Qx.default=H3});var Y3=w(Sx=>{"use strict";Object.defineProperty(Sx,"__esModule",{value:!0});var $be=Xa(),G3=class{constructor(e){this._settings=e}getFilter(){return e=>this._isNonFatalError(e)}_isNonFatalError(e){return $be.errno.isEnoentCodeError(e)||this._settings.suppressErrors}};Sx.default=G3});var W3=w(vx=>{"use strict";Object.defineProperty(vx,"__esModule",{value:!0});var q3=Xa(),J3=class{constructor(e){this._settings=e}getTransformer(){return e=>this._transform(e)}_transform(e){let t=e.path;return this._settings.absolute&&(t=q3.path.makeAbsolute(this._settings.cwd,t),t=q3.path.unixify(t)),this._settings.markDirectories&&e.dirent.isDirectory()&&(t+="/"),this._settings.objectMode?Object.assign(Object.assign({},e),{path:t}):t}};vx.default=J3});var Xy=w(xx=>{"use strict";Object.defineProperty(xx,"__esModule",{value:!0});var eQe=require("path"),tQe=U3(),rQe=j3(),iQe=Y3(),nQe=W3(),z3=class{constructor(e){this._settings=e,this.errorFilter=new iQe.default(this._settings),this.entryFilter=new rQe.default(this._settings,this._getMicromatchOptions()),this.deepFilter=new tQe.default(this._settings,this._getMicromatchOptions()),this.entryTransformer=new nQe.default(this._settings)}_getRootDirectory(e){return eQe.resolve(this._settings.cwd,e.base)}_getReaderOptions(e){let t=e.base==="."?"":e.base;return{basePath:t,pathSegmentSeparator:"/",concurrency:this._settings.concurrency,deepFilter:this.deepFilter.getFilter(t,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}}};xx.default=z3});var V3=w(kx=>{"use strict";Object.defineProperty(kx,"__esModule",{value:!0});var sQe=yx(),oQe=Xy(),_3=class extends oQe.default{constructor(){super(...arguments);this._reader=new sQe.default(this._settings)}read(e){let t=this._getRootDirectory(e),i=this._getReaderOptions(e),n=[];return new Promise((s,o)=>{let a=this.api(t,e,i);a.once("error",o),a.on("data",l=>n.push(i.transform(l))),a.once("end",()=>s(n))})}api(e,t,i){return t.dynamic?this._reader.dynamic(e,i):this._reader.static(t.patterns,i)}};kx.default=_3});var Z3=w(Px=>{"use strict";Object.defineProperty(Px,"__esModule",{value:!0});var aQe=require("stream"),AQe=yx(),lQe=Xy(),X3=class extends lQe.default{constructor(){super(...arguments);this._reader=new AQe.default(this._settings)}read(e){let t=this._getRootDirectory(e),i=this._getReaderOptions(e),n=this.api(t,e,i),s=new aQe.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,t,i){return t.dynamic?this._reader.dynamic(e,i):this._reader.static(t.patterns,i)}};Px.default=X3});var eW=w(Dx=>{"use strict";Object.defineProperty(Dx,"__esModule",{value:!0});var cQe=Kc(),uQe=Cx(),gQe=Ex(),$3=class extends gQe.default{constructor(){super(...arguments);this._walkSync=uQe.walkSync,this._statSync=cQe.statSync}dynamic(e,t){return this._walkSync(e,t)}static(e,t){let i=[];for(let n of e){let s=this._getFullEntryPath(n),o=this._getEntry(s,n,t);o===null||!t.entryFilter(o)||i.push(o)}return i}_getEntry(e,t,i){try{let n=this._getStat(e);return this._makeEntry(n,t)}catch(n){if(i.errorFilter(n))return null;throw n}}_getStat(e){return this._statSync(e,this._fsStatSettings)}};Dx.default=$3});var rW=w(Rx=>{"use strict";Object.defineProperty(Rx,"__esModule",{value:!0});var fQe=eW(),hQe=Xy(),tW=class extends hQe.default{constructor(){super(...arguments);this._reader=new fQe.default(this._settings)}read(e){let t=this._getRootDirectory(e),i=this._getReaderOptions(e);return this.api(t,e,i).map(i.transform)}api(e,t,i){return t.dynamic?this._reader.dynamic(e,i):this._reader.static(t.patterns,i)}};Rx.default=tW});var nW=w(od=>{"use strict";Object.defineProperty(od,"__esModule",{value:!0});var jg=require("fs"),pQe=require("os"),dQe=pQe.cpus().length;od.DEFAULT_FILE_SYSTEM_ADAPTER={lstat:jg.lstat,lstatSync:jg.lstatSync,stat:jg.stat,statSync:jg.statSync,readdir:jg.readdir,readdirSync:jg.readdirSync};var iW=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,dQe),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,t){return e===void 0?t:e}_getFileSystemMethods(e={}){return Object.assign(Object.assign({},od.DEFAULT_FILE_SYSTEM_ADAPTER),e)}};od.default=iW});var Zy=w((ztt,sW)=>{"use strict";var oW=UJ(),CQe=V3(),mQe=Z3(),EQe=rW(),Fx=nW(),Uc=Xa();async function Lx(r,e){Gg(r);let t=Nx(r,CQe.default,e),i=await Promise.all(t);return Uc.array.flatten(i)}(function(r){function e(o,a){Gg(o);let l=Nx(o,EQe.default,a);return Uc.array.flatten(l)}r.sync=e;function t(o,a){Gg(o);let l=Nx(o,mQe.default,a);return Uc.stream.merge(l)}r.stream=t;function i(o,a){Gg(o);let l=[].concat(o),c=new Fx.default(a);return oW.generate(l,c)}r.generateTasks=i;function n(o,a){Gg(o);let l=new Fx.default(a);return Uc.pattern.isDynamicPattern(o,l)}r.isDynamicPattern=n;function s(o){return Gg(o),Uc.path.escape(o)}r.escapePath=s})(Lx||(Lx={}));function Nx(r,e,t){let i=[].concat(r),n=new Fx.default(t),s=oW.generate(i,n),o=new e(n);return s.map(o.read,o)}function Gg(r){if(![].concat(r).every(i=>Uc.string.isString(i)&&!Uc.string.isEmpty(i)))throw new TypeError("Patterns must be a string (non empty) or an array of strings")}sW.exports=Lx});var AW=w(Hc=>{"use strict";var{promisify:IQe}=require("util"),aW=require("fs");async function Tx(r,e,t){if(typeof t!="string")throw new TypeError(`Expected a string, got ${typeof t}`);try{return(await IQe(aW[r])(t))[e]()}catch(i){if(i.code==="ENOENT")return!1;throw i}}function Ox(r,e,t){if(typeof t!="string")throw new TypeError(`Expected a string, got ${typeof t}`);try{return aW[r](t)[e]()}catch(i){if(i.code==="ENOENT")return!1;throw i}}Hc.isFile=Tx.bind(null,"stat","isFile");Hc.isDirectory=Tx.bind(null,"stat","isDirectory");Hc.isSymlink=Tx.bind(null,"lstat","isSymbolicLink");Hc.isFileSync=Ox.bind(null,"statSync","isFile");Hc.isDirectorySync=Ox.bind(null,"statSync","isDirectory");Hc.isSymlinkSync=Ox.bind(null,"lstatSync","isSymbolicLink")});var fW=w((Vtt,Mx)=>{"use strict";var jc=require("path"),lW=AW(),cW=r=>r.length>1?`{${r.join(",")}}`:r[0],uW=(r,e)=>{let t=r[0]==="!"?r.slice(1):r;return jc.isAbsolute(t)?t:jc.join(e,t)},yQe=(r,e)=>jc.extname(r)?`**/${r}`:`**/${r}.${cW(e)}`,gW=(r,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(t=>jc.posix.join(r,yQe(t,e.extensions))):e.files?e.files.map(t=>jc.posix.join(r,`**/${t}`)):e.extensions?[jc.posix.join(r,`**/*.${cW(e.extensions)}`)]:[jc.posix.join(r,"**")]};Mx.exports=async(r,e)=>{if(e=N({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 t=await Promise.all([].concat(r).map(async i=>await lW.isDirectory(uW(i,e.cwd))?gW(i,e):i));return[].concat.apply([],t)};Mx.exports.sync=(r,e)=>{if(e=N({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 t=[].concat(r).map(i=>lW.isDirectorySync(uW(i,e.cwd))?gW(i,e):i);return[].concat.apply([],t)}});var BW=w((Xtt,hW)=>{function pW(r){return Array.isArray(r)?r:[r]}var dW="",CW=" ",Kx="\\",wQe=/^\s+$/,BQe=/^\\!/,bQe=/^\\#/,QQe=/\r?\n/g,SQe=/^\.*\/|^\.+$/,Ux="/",mW=typeof Symbol!="undefined"?Symbol.for("node-ignore"):"node-ignore",vQe=(r,e,t)=>Object.defineProperty(r,e,{value:t}),xQe=/([0-z])-([0-z])/g,kQe=r=>r.replace(xQe,(e,t,i)=>t.charCodeAt(0)<=i.charCodeAt(0)?e:dW),PQe=r=>{let{length:e}=r;return r.slice(0,e-e%2)},DQe=[[/\\?\s+$/,r=>r.indexOf("\\")===0?CW:dW],[/\\\s/g,()=>CW],[/[\\$.|*+(){^]/g,r=>`\\${r}`],[/(?!\\)\?/g,()=>"[^/]"],[/^\//,()=>"^"],[/\//g,()=>"\\/"],[/^\^*\\\*\\\*\\\//,()=>"^(?:.*\\/)?"],[/^(?=[^^])/,function(){return/\/(?!$)/.test(this)?"^":"(?:^|\\/)"}],[/\\\/\\\*\\\*(?=\\\/|$)/g,(r,e,t)=>e+6`${e}[^\\/]*`],[/\\\\\\(?=[$.|*+(){^])/g,()=>Kx],[/\\\\/g,()=>Kx],[/(\\)?\[([^\]/]*?)(\\*)($|\])/g,(r,e,t,i,n)=>e===Kx?`\\[${t}${PQe(i)}${n}`:n==="]"&&i.length%2==0?`[${kQe(t)}${i}]`:"[]"],[/(?:[^*])$/,r=>/\/$/.test(r)?`${r}$`:`${r}(?=$|\\/$)`],[/(\^|\\\/)?\\\*$/,(r,e)=>`${e?`${e}[^/]+`:"[^/]*"}(?=$|\\/$)`]],EW=Object.create(null),RQe=(r,e)=>{let t=EW[r];return t||(t=DQe.reduce((i,n)=>i.replace(n[0],n[1].bind(r)),r),EW[r]=t),e?new RegExp(t,"i"):new RegExp(t)},Hx=r=>typeof r=="string",FQe=r=>r&&Hx(r)&&!wQe.test(r)&&r.indexOf("#")!==0,NQe=r=>r.split(QQe),IW=class{constructor(e,t,i,n){this.origin=e,this.pattern=t,this.negative=i,this.regex=n}},LQe=(r,e)=>{let t=r,i=!1;r.indexOf("!")===0&&(i=!0,r=r.substr(1)),r=r.replace(BQe,"!").replace(bQe,"#");let n=RQe(r,e);return new IW(t,r,i,n)},TQe=(r,e)=>{throw new e(r)},$a=(r,e,t)=>Hx(r)?r?$a.isNotRelative(r)?t(`path should be a \`path.relative()\`d string, but got "${e}"`,RangeError):!0:t("path must not be empty",TypeError):t(`path must be a string, but got \`${e}\``,TypeError),yW=r=>SQe.test(r);$a.isNotRelative=yW;$a.convert=r=>r;var wW=class{constructor({ignorecase:e=!0}={}){vQe(this,mW,!0),this._rules=[],this._ignorecase=e,this._initCache()}_initCache(){this._ignoreCache=Object.create(null),this._testCache=Object.create(null)}_addPattern(e){if(e&&e[mW]){this._rules=this._rules.concat(e._rules),this._added=!0;return}if(FQe(e)){let t=LQe(e,this._ignorecase);this._added=!0,this._rules.push(t)}}add(e){return this._added=!1,pW(Hx(e)?NQe(e):e).forEach(this._addPattern,this),this._added&&this._initCache(),this}addPattern(e){return this.add(e)}_testOne(e,t){let i=!1,n=!1;return this._rules.forEach(s=>{let{negative:o}=s;if(n===o&&i!==n||o&&!i&&!n&&!t)return;s.regex.test(e)&&(i=!o,n=o)}),{ignored:i,unignored:n}}_test(e,t,i,n){let s=e&&$a.convert(e);return $a(s,e,TQe),this._t(s,t,i,n)}_t(e,t,i,n){if(e in t)return t[e];if(n||(n=e.split(Ux)),n.pop(),!n.length)return t[e]=this._testOne(e,i);let s=this._t(n.join(Ux)+Ux,t,i,n);return t[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 pW(e).filter(this.createFilter())}test(e){return this._test(e,this._testCache,!0)}},$y=r=>new wW(r),OQe=()=>!1,MQe=r=>$a(r&&$a.convert(r),r,OQe);$y.isPathValid=MQe;$y.default=$y;hW.exports=$y;if(typeof process!="undefined"&&(process.env&&process.env.IGNORE_TEST_WIN32||process.platform==="win32")){let r=t=>/^\\\\\?\\/.test(t)||/["<>|\u0000-\u001F]+/u.test(t)?t:t.replace(/\\/g,"/");$a.convert=r;let e=/^[a-z]:\//i;$a.isNotRelative=t=>e.test(t)||yW(t)}});var QW=w((Ztt,bW)=>{"use strict";bW.exports=r=>{let e=/^\\\\\?\\/.test(r),t=/[^\u0000-\u0080]+/.test(r);return e||t?r:r.replace(/\\/g,"/")}});var RW=w(($tt,jx)=>{"use strict";var{promisify:KQe}=require("util"),SW=require("fs"),eA=require("path"),vW=Zy(),UQe=BW(),ad=QW(),xW=["**/node_modules/**","**/flow-typed/**","**/coverage/**","**/.git"],HQe=KQe(SW.readFile),jQe=r=>e=>e.startsWith("!")?"!"+eA.posix.join(r,e.slice(1)):eA.posix.join(r,e),GQe=(r,e)=>{let t=ad(eA.relative(e.cwd,eA.dirname(e.fileName)));return r.split(/\r?\n/).filter(Boolean).filter(i=>!i.startsWith("#")).map(jQe(t))},kW=r=>{let e=UQe();for(let t of r)e.add(GQe(t.content,{cwd:t.cwd,fileName:t.filePath}));return e},YQe=(r,e)=>{if(r=ad(r),eA.isAbsolute(e)){if(ad(e).startsWith(r))return e;throw new Error(`Path ${e} is not in cwd ${r}`)}return eA.join(r,e)},PW=(r,e)=>t=>r.ignores(ad(eA.relative(e,YQe(e,t.path||t)))),qQe=async(r,e)=>{let t=eA.join(e,r),i=await HQe(t,"utf8");return{cwd:e,filePath:t,content:i}},JQe=(r,e)=>{let t=eA.join(e,r),i=SW.readFileSync(t,"utf8");return{cwd:e,filePath:t,content:i}},DW=({ignore:r=[],cwd:e=ad(process.cwd())}={})=>({ignore:r,cwd:e});jx.exports=async r=>{r=DW(r);let e=await vW("**/.gitignore",{ignore:xW.concat(r.ignore),cwd:r.cwd}),t=await Promise.all(e.map(n=>qQe(n,r.cwd))),i=kW(t);return PW(i,r.cwd)};jx.exports.sync=r=>{r=DW(r);let t=vW.sync("**/.gitignore",{ignore:xW.concat(r.ignore),cwd:r.cwd}).map(n=>JQe(n,r.cwd)),i=kW(t);return PW(i,r.cwd)}});var TW=w((ert,FW)=>{"use strict";var{Transform:WQe}=require("stream"),Gx=class extends WQe{constructor(){super({objectMode:!0})}},NW=class extends Gx{constructor(e){super();this._filter=e}_transform(e,t,i){this._filter(e)&&this.push(e),i()}},LW=class extends Gx{constructor(){super();this._pushed=new Set}_transform(e,t,i){this._pushed.has(e)||(this.push(e),this._pushed.add(e)),i()}};FW.exports={FilterStream:NW,UniqueStream:LW}});var Wx=w((trt,Gc)=>{"use strict";var OW=require("fs"),ew=AJ(),zQe=jv(),tw=Zy(),rw=fW(),Yx=RW(),{FilterStream:_Qe,UniqueStream:VQe}=TW(),MW=()=>!1,KW=r=>r[0]==="!",XQe=r=>{if(!r.every(e=>typeof e=="string"))throw new TypeError("Patterns must be a string or an array of strings")},ZQe=(r={})=>{if(!r.cwd)return;let e;try{e=OW.statSync(r.cwd)}catch{return}if(!e.isDirectory())throw new Error("The `cwd` option must be a path to a directory")},$Qe=r=>r.stats instanceof OW.Stats?r.path:r,iw=(r,e)=>{r=ew([].concat(r)),XQe(r),ZQe(e);let t=[];e=N({ignore:[],expandDirectories:!0},e);for(let[i,n]of r.entries()){if(KW(n))continue;let s=r.slice(i).filter(a=>KW(a)).map(a=>a.slice(1)),o=te(N({},e),{ignore:e.ignore.concat(s)});t.push({pattern:n,options:o})}return t},eSe=(r,e)=>{let t={};return r.options.cwd&&(t.cwd=r.options.cwd),Array.isArray(r.options.expandDirectories)?t=te(N({},t),{files:r.options.expandDirectories}):typeof r.options.expandDirectories=="object"&&(t=N(N({},t),r.options.expandDirectories)),e(r.pattern,t)},qx=(r,e)=>r.options.expandDirectories?eSe(r,e):[r.pattern],UW=r=>r&&r.gitignore?Yx.sync({cwd:r.cwd,ignore:r.ignore}):MW,Jx=r=>e=>{let{options:t}=r;return t.ignore&&Array.isArray(t.ignore)&&t.expandDirectories&&(t.ignore=rw.sync(t.ignore)),{pattern:e,options:t}};Gc.exports=async(r,e)=>{let t=iw(r,e),i=async()=>e&&e.gitignore?Yx({cwd:e.cwd,ignore:e.ignore}):MW,n=async()=>{let l=await Promise.all(t.map(async c=>{let u=await qx(c,rw);return Promise.all(u.map(Jx(c)))}));return ew(...l)},[s,o]=await Promise.all([i(),n()]),a=await Promise.all(o.map(l=>tw(l.pattern,l.options)));return ew(...a).filter(l=>!s($Qe(l)))};Gc.exports.sync=(r,e)=>{let t=iw(r,e),i=[];for(let o of t){let a=qx(o,rw.sync).map(Jx(o));i.push(...a)}let n=UW(e),s=[];for(let o of i)s=ew(s,tw.sync(o.pattern,o.options));return s.filter(o=>!n(o))};Gc.exports.stream=(r,e)=>{let t=iw(r,e),i=[];for(let a of t){let l=qx(a,rw.sync).map(Jx(a));i.push(...l)}let n=UW(e),s=new _Qe(a=>!n(a)),o=new VQe;return zQe(i.map(a=>tw.stream(a.pattern,a.options))).pipe(s).pipe(o)};Gc.exports.generateGlobTasks=iw;Gc.exports.hasMagic=(r,e)=>[].concat(r).some(t=>tw.isDynamicPattern(t,e));Gc.exports.gitignore=Yx});var Rn=w((xrt,t4)=>{function fSe(r){var e=typeof r;return r!=null&&(e=="object"||e=="function")}t4.exports=fSe});var rk=w((krt,r4)=>{var hSe=typeof global=="object"&&global&&global.Object===Object&&global;r4.exports=hSe});var Ns=w((Prt,i4)=>{var pSe=rk(),dSe=typeof self=="object"&&self&&self.Object===Object&&self,CSe=pSe||dSe||Function("return this")();i4.exports=CSe});var s4=w((Drt,n4)=>{var mSe=Ns(),ESe=function(){return mSe.Date.now()};n4.exports=ESe});var a4=w((Rrt,o4)=>{var ISe=/\s/;function ySe(r){for(var e=r.length;e--&&ISe.test(r.charAt(e)););return e}o4.exports=ySe});var l4=w((Frt,A4)=>{var wSe=a4(),BSe=/^\s+/;function bSe(r){return r&&r.slice(0,wSe(r)+1).replace(BSe,"")}A4.exports=bSe});var Jc=w((Nrt,c4)=>{var QSe=Ns(),SSe=QSe.Symbol;c4.exports=SSe});var h4=w((Lrt,u4)=>{var g4=Jc(),f4=Object.prototype,vSe=f4.hasOwnProperty,xSe=f4.toString,Ed=g4?g4.toStringTag:void 0;function kSe(r){var e=vSe.call(r,Ed),t=r[Ed];try{r[Ed]=void 0;var i=!0}catch(s){}var n=xSe.call(r);return i&&(e?r[Ed]=t:delete r[Ed]),n}u4.exports=kSe});var d4=w((Trt,p4)=>{var PSe=Object.prototype,DSe=PSe.toString;function RSe(r){return DSe.call(r)}p4.exports=RSe});var Wc=w((Ort,C4)=>{var m4=Jc(),FSe=h4(),NSe=d4(),LSe="[object Null]",TSe="[object Undefined]",E4=m4?m4.toStringTag:void 0;function OSe(r){return r==null?r===void 0?TSe:LSe:E4&&E4 in Object(r)?FSe(r):NSe(r)}C4.exports=OSe});var ta=w((Mrt,I4)=>{function MSe(r){return r!=null&&typeof r=="object"}I4.exports=MSe});var Id=w((Krt,y4)=>{var KSe=Wc(),USe=ta(),HSe="[object Symbol]";function jSe(r){return typeof r=="symbol"||USe(r)&&KSe(r)==HSe}y4.exports=jSe});var Q4=w((Urt,w4)=>{var GSe=l4(),B4=Rn(),YSe=Id(),b4=0/0,qSe=/^[-+]0x[0-9a-f]+$/i,JSe=/^0b[01]+$/i,WSe=/^0o[0-7]+$/i,zSe=parseInt;function _Se(r){if(typeof r=="number")return r;if(YSe(r))return b4;if(B4(r)){var e=typeof r.valueOf=="function"?r.valueOf():r;r=B4(e)?e+"":e}if(typeof r!="string")return r===0?r:+r;r=GSe(r);var t=JSe.test(r);return t||WSe.test(r)?zSe(r.slice(2),t?2:8):qSe.test(r)?b4:+r}w4.exports=_Se});var x4=w((Hrt,S4)=>{var VSe=Rn(),ik=s4(),v4=Q4(),XSe="Expected a function",ZSe=Math.max,$Se=Math.min;function eve(r,e,t){var i,n,s,o,a,l,c=0,u=!1,g=!1,f=!0;if(typeof r!="function")throw new TypeError(XSe);e=v4(e)||0,VSe(t)&&(u=!!t.leading,g="maxWait"in t,s=g?ZSe(v4(t.maxWait)||0,e):s,f="trailing"in t?!!t.trailing:f);function h(Y){var $=i,_=n;return i=n=void 0,c=Y,o=r.apply(_,$),o}function p(Y){return c=Y,a=setTimeout(b,e),u?h(Y):o}function m(Y){var $=Y-l,_=Y-c,ne=e-$;return g?$Se(ne,s-_):ne}function y(Y){var $=Y-l,_=Y-c;return l===void 0||$>=e||$<0||g&&_>=s}function b(){var Y=ik();if(y(Y))return v(Y);a=setTimeout(b,m(Y))}function v(Y){return a=void 0,f&&i?h(Y):(i=n=void 0,o)}function x(){a!==void 0&&clearTimeout(a),c=0,i=l=n=a=void 0}function T(){return a===void 0?o:v(ik())}function q(){var Y=ik(),$=y(Y);if(i=arguments,n=this,l=Y,$){if(a===void 0)return p(l);if(g)return clearTimeout(a),a=setTimeout(b,e),h(l)}return a===void 0&&(a=setTimeout(b,e)),o}return q.cancel=x,q.flush=T,q}S4.exports=eve});var P4=w((jrt,k4)=>{var tve=x4(),rve=Rn(),ive="Expected a function";function nve(r,e,t){var i=!0,n=!0;if(typeof r!="function")throw new TypeError(ive);return rve(t)&&(i="leading"in t?!!t.leading:i,n="trailing"in t?!!t.trailing:n),tve(r,e,{leading:i,maxWait:e,trailing:n})}k4.exports=nve});var iA=w((rA,Bw)=>{"use strict";Object.defineProperty(rA,"__esModule",{value:!0});var M4=["Int8Array","Uint8Array","Uint8ClampedArray","Int16Array","Uint16Array","Int32Array","Uint32Array","Float32Array","Float64Array","BigInt64Array","BigUint64Array"];function Cve(r){return M4.includes(r)}var mve=["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",...M4];function Eve(r){return mve.includes(r)}var Ive=["null","undefined","string","number","bigint","boolean","symbol"];function yve(r){return Ive.includes(r)}function Xg(r){return e=>typeof e===r}var{toString:K4}=Object.prototype,vd=r=>{let e=K4.call(r).slice(8,-1);if(/HTML\w+Element/.test(e)&&W.domElement(r))return"HTMLElement";if(Eve(e))return e},hr=r=>e=>vd(e)===r;function W(r){if(r===null)return"null";switch(typeof r){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(W.observable(r))return"Observable";if(W.array(r))return"Array";if(W.buffer(r))return"Buffer";let e=vd(r);if(e)return e;if(r instanceof String||r instanceof Boolean||r instanceof Number)throw new TypeError("Please don't use object wrappers for primitive types");return"Object"}W.undefined=Xg("undefined");W.string=Xg("string");var wve=Xg("number");W.number=r=>wve(r)&&!W.nan(r);W.bigint=Xg("bigint");W.function_=Xg("function");W.null_=r=>r===null;W.class_=r=>W.function_(r)&&r.toString().startsWith("class ");W.boolean=r=>r===!0||r===!1;W.symbol=Xg("symbol");W.numericString=r=>W.string(r)&&!W.emptyStringOrWhitespace(r)&&!Number.isNaN(Number(r));W.array=(r,e)=>Array.isArray(r)?W.function_(e)?r.every(e):!0:!1;W.buffer=r=>{var e,t,i,n;return(n=(i=(t=(e=r)===null||e===void 0?void 0:e.constructor)===null||t===void 0?void 0:t.isBuffer)===null||i===void 0?void 0:i.call(t,r))!==null&&n!==void 0?n:!1};W.nullOrUndefined=r=>W.null_(r)||W.undefined(r);W.object=r=>!W.null_(r)&&(typeof r=="object"||W.function_(r));W.iterable=r=>{var e;return W.function_((e=r)===null||e===void 0?void 0:e[Symbol.iterator])};W.asyncIterable=r=>{var e;return W.function_((e=r)===null||e===void 0?void 0:e[Symbol.asyncIterator])};W.generator=r=>W.iterable(r)&&W.function_(r.next)&&W.function_(r.throw);W.asyncGenerator=r=>W.asyncIterable(r)&&W.function_(r.next)&&W.function_(r.throw);W.nativePromise=r=>hr("Promise")(r);var Bve=r=>{var e,t;return W.function_((e=r)===null||e===void 0?void 0:e.then)&&W.function_((t=r)===null||t===void 0?void 0:t.catch)};W.promise=r=>W.nativePromise(r)||Bve(r);W.generatorFunction=hr("GeneratorFunction");W.asyncGeneratorFunction=r=>vd(r)==="AsyncGeneratorFunction";W.asyncFunction=r=>vd(r)==="AsyncFunction";W.boundFunction=r=>W.function_(r)&&!r.hasOwnProperty("prototype");W.regExp=hr("RegExp");W.date=hr("Date");W.error=hr("Error");W.map=r=>hr("Map")(r);W.set=r=>hr("Set")(r);W.weakMap=r=>hr("WeakMap")(r);W.weakSet=r=>hr("WeakSet")(r);W.int8Array=hr("Int8Array");W.uint8Array=hr("Uint8Array");W.uint8ClampedArray=hr("Uint8ClampedArray");W.int16Array=hr("Int16Array");W.uint16Array=hr("Uint16Array");W.int32Array=hr("Int32Array");W.uint32Array=hr("Uint32Array");W.float32Array=hr("Float32Array");W.float64Array=hr("Float64Array");W.bigInt64Array=hr("BigInt64Array");W.bigUint64Array=hr("BigUint64Array");W.arrayBuffer=hr("ArrayBuffer");W.sharedArrayBuffer=hr("SharedArrayBuffer");W.dataView=hr("DataView");W.directInstanceOf=(r,e)=>Object.getPrototypeOf(r)===e.prototype;W.urlInstance=r=>hr("URL")(r);W.urlString=r=>{if(!W.string(r))return!1;try{return new URL(r),!0}catch(e){return!1}};W.truthy=r=>Boolean(r);W.falsy=r=>!r;W.nan=r=>Number.isNaN(r);W.primitive=r=>W.null_(r)||yve(typeof r);W.integer=r=>Number.isInteger(r);W.safeInteger=r=>Number.isSafeInteger(r);W.plainObject=r=>{if(K4.call(r)!=="[object Object]")return!1;let e=Object.getPrototypeOf(r);return e===null||e===Object.getPrototypeOf({})};W.typedArray=r=>Cve(vd(r));var bve=r=>W.safeInteger(r)&&r>=0;W.arrayLike=r=>!W.nullOrUndefined(r)&&!W.function_(r)&&bve(r.length);W.inRange=(r,e)=>{if(W.number(e))return r>=Math.min(0,e)&&r<=Math.max(e,0);if(W.array(e)&&e.length===2)return r>=Math.min(...e)&&r<=Math.max(...e);throw new TypeError(`Invalid range: ${JSON.stringify(e)}`)};var Qve=1,Sve=["innerHTML","ownerDocument","style","attributes","nodeValue"];W.domElement=r=>W.object(r)&&r.nodeType===Qve&&W.string(r.nodeName)&&!W.plainObject(r)&&Sve.every(e=>e in r);W.observable=r=>{var e,t,i,n;return r?r===((t=(e=r)[Symbol.observable])===null||t===void 0?void 0:t.call(e))||r===((n=(i=r)["@@observable"])===null||n===void 0?void 0:n.call(i)):!1};W.nodeStream=r=>W.object(r)&&W.function_(r.pipe)&&!W.observable(r);W.infinite=r=>r===Infinity||r===-Infinity;var U4=r=>e=>W.integer(e)&&Math.abs(e%2)===r;W.evenInteger=U4(0);W.oddInteger=U4(1);W.emptyArray=r=>W.array(r)&&r.length===0;W.nonEmptyArray=r=>W.array(r)&&r.length>0;W.emptyString=r=>W.string(r)&&r.length===0;W.nonEmptyString=r=>W.string(r)&&r.length>0;var vve=r=>W.string(r)&&!/\S/.test(r);W.emptyStringOrWhitespace=r=>W.emptyString(r)||vve(r);W.emptyObject=r=>W.object(r)&&!W.map(r)&&!W.set(r)&&Object.keys(r).length===0;W.nonEmptyObject=r=>W.object(r)&&!W.map(r)&&!W.set(r)&&Object.keys(r).length>0;W.emptySet=r=>W.set(r)&&r.size===0;W.nonEmptySet=r=>W.set(r)&&r.size>0;W.emptyMap=r=>W.map(r)&&r.size===0;W.nonEmptyMap=r=>W.map(r)&&r.size>0;W.propertyKey=r=>W.any([W.string,W.number,W.symbol],r);W.formData=r=>hr("FormData")(r);W.urlSearchParams=r=>hr("URLSearchParams")(r);var H4=(r,e,t)=>{if(!W.function_(e))throw new TypeError(`Invalid predicate: ${JSON.stringify(e)}`);if(t.length===0)throw new TypeError("Invalid number of values");return r.call(t,e)};W.any=(r,...e)=>(W.array(r)?r:[r]).some(i=>H4(Array.prototype.some,i,e));W.all=(r,...e)=>H4(Array.prototype.every,r,e);var We=(r,e,t,i={})=>{if(!r){let{multipleValues:n}=i,s=n?`received values of types ${[...new Set(t.map(o=>`\`${W(o)}\``))].join(", ")}`:`received value of type \`${W(t)}\``;throw new TypeError(`Expected value which is \`${e}\`, ${s}.`)}};rA.assert={undefined:r=>We(W.undefined(r),"undefined",r),string:r=>We(W.string(r),"string",r),number:r=>We(W.number(r),"number",r),bigint:r=>We(W.bigint(r),"bigint",r),function_:r=>We(W.function_(r),"Function",r),null_:r=>We(W.null_(r),"null",r),class_:r=>We(W.class_(r),"Class",r),boolean:r=>We(W.boolean(r),"boolean",r),symbol:r=>We(W.symbol(r),"symbol",r),numericString:r=>We(W.numericString(r),"string with a number",r),array:(r,e)=>{We(W.array(r),"Array",r),e&&r.forEach(e)},buffer:r=>We(W.buffer(r),"Buffer",r),nullOrUndefined:r=>We(W.nullOrUndefined(r),"null or undefined",r),object:r=>We(W.object(r),"Object",r),iterable:r=>We(W.iterable(r),"Iterable",r),asyncIterable:r=>We(W.asyncIterable(r),"AsyncIterable",r),generator:r=>We(W.generator(r),"Generator",r),asyncGenerator:r=>We(W.asyncGenerator(r),"AsyncGenerator",r),nativePromise:r=>We(W.nativePromise(r),"native Promise",r),promise:r=>We(W.promise(r),"Promise",r),generatorFunction:r=>We(W.generatorFunction(r),"GeneratorFunction",r),asyncGeneratorFunction:r=>We(W.asyncGeneratorFunction(r),"AsyncGeneratorFunction",r),asyncFunction:r=>We(W.asyncFunction(r),"AsyncFunction",r),boundFunction:r=>We(W.boundFunction(r),"Function",r),regExp:r=>We(W.regExp(r),"RegExp",r),date:r=>We(W.date(r),"Date",r),error:r=>We(W.error(r),"Error",r),map:r=>We(W.map(r),"Map",r),set:r=>We(W.set(r),"Set",r),weakMap:r=>We(W.weakMap(r),"WeakMap",r),weakSet:r=>We(W.weakSet(r),"WeakSet",r),int8Array:r=>We(W.int8Array(r),"Int8Array",r),uint8Array:r=>We(W.uint8Array(r),"Uint8Array",r),uint8ClampedArray:r=>We(W.uint8ClampedArray(r),"Uint8ClampedArray",r),int16Array:r=>We(W.int16Array(r),"Int16Array",r),uint16Array:r=>We(W.uint16Array(r),"Uint16Array",r),int32Array:r=>We(W.int32Array(r),"Int32Array",r),uint32Array:r=>We(W.uint32Array(r),"Uint32Array",r),float32Array:r=>We(W.float32Array(r),"Float32Array",r),float64Array:r=>We(W.float64Array(r),"Float64Array",r),bigInt64Array:r=>We(W.bigInt64Array(r),"BigInt64Array",r),bigUint64Array:r=>We(W.bigUint64Array(r),"BigUint64Array",r),arrayBuffer:r=>We(W.arrayBuffer(r),"ArrayBuffer",r),sharedArrayBuffer:r=>We(W.sharedArrayBuffer(r),"SharedArrayBuffer",r),dataView:r=>We(W.dataView(r),"DataView",r),urlInstance:r=>We(W.urlInstance(r),"URL",r),urlString:r=>We(W.urlString(r),"string with a URL",r),truthy:r=>We(W.truthy(r),"truthy",r),falsy:r=>We(W.falsy(r),"falsy",r),nan:r=>We(W.nan(r),"NaN",r),primitive:r=>We(W.primitive(r),"primitive",r),integer:r=>We(W.integer(r),"integer",r),safeInteger:r=>We(W.safeInteger(r),"integer",r),plainObject:r=>We(W.plainObject(r),"plain object",r),typedArray:r=>We(W.typedArray(r),"TypedArray",r),arrayLike:r=>We(W.arrayLike(r),"array-like",r),domElement:r=>We(W.domElement(r),"HTMLElement",r),observable:r=>We(W.observable(r),"Observable",r),nodeStream:r=>We(W.nodeStream(r),"Node.js Stream",r),infinite:r=>We(W.infinite(r),"infinite number",r),emptyArray:r=>We(W.emptyArray(r),"empty array",r),nonEmptyArray:r=>We(W.nonEmptyArray(r),"non-empty array",r),emptyString:r=>We(W.emptyString(r),"empty string",r),nonEmptyString:r=>We(W.nonEmptyString(r),"non-empty string",r),emptyStringOrWhitespace:r=>We(W.emptyStringOrWhitespace(r),"empty string or whitespace",r),emptyObject:r=>We(W.emptyObject(r),"empty object",r),nonEmptyObject:r=>We(W.nonEmptyObject(r),"non-empty object",r),emptySet:r=>We(W.emptySet(r),"empty set",r),nonEmptySet:r=>We(W.nonEmptySet(r),"non-empty set",r),emptyMap:r=>We(W.emptyMap(r),"empty map",r),nonEmptyMap:r=>We(W.nonEmptyMap(r),"non-empty map",r),propertyKey:r=>We(W.propertyKey(r),"PropertyKey",r),formData:r=>We(W.formData(r),"FormData",r),urlSearchParams:r=>We(W.urlSearchParams(r),"URLSearchParams",r),evenInteger:r=>We(W.evenInteger(r),"even integer",r),oddInteger:r=>We(W.oddInteger(r),"odd integer",r),directInstanceOf:(r,e)=>We(W.directInstanceOf(r,e),"T",r),inRange:(r,e)=>We(W.inRange(r,e),"in range",r),any:(r,...e)=>We(W.any(r,...e),"predicate returns truthy for any value",e,{multipleValues:!0}),all:(r,...e)=>We(W.all(r,...e),"predicate returns truthy for all values",e,{multipleValues:!0})};Object.defineProperties(W,{class:{value:W.class_},function:{value:W.function_},null:{value:W.null_}});Object.defineProperties(rA.assert,{class:{value:rA.assert.class_},function:{value:rA.assert.function_},null:{value:rA.assert.null_}});rA.default=W;Bw.exports=W;Bw.exports.default=W;Bw.exports.assert=rA.assert});var j4=w((Wit,Bk)=>{"use strict";var bk=class extends Error{constructor(e){super(e||"Promise was canceled");this.name="CancelError"}get isCanceled(){return!0}},xd=class{static fn(e){return(...t)=>new xd((i,n,s)=>{t.push(s),e(...t).then(i,n)})}constructor(e){this._cancelHandlers=[],this._isPending=!0,this._isCanceled=!1,this._rejectOnCancel=!0,this._promise=new Promise((t,i)=>{this._reject=i;let n=a=>{this._isPending=!1,t(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,t){return this._promise.then(e,t)}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 t of this._cancelHandlers)t()}catch(t){this._reject(t)}this._isCanceled=!0,this._rejectOnCancel&&this._reject(new bk(e))}}get isCanceled(){return this._isCanceled}};Object.setPrototypeOf(xd.prototype,Promise.prototype);Bk.exports=xd;Bk.exports.CancelError=bk});var G4=w((Qk,Sk)=>{"use strict";Object.defineProperty(Qk,"__esModule",{value:!0});var xve=require("tls"),vk=(r,e)=>{let t;typeof e=="function"?t={connect:e}:t=e;let i=typeof t.connect=="function",n=typeof t.secureConnect=="function",s=typeof t.close=="function",o=()=>{i&&t.connect(),r instanceof xve.TLSSocket&&n&&(r.authorized?t.secureConnect():r.authorizationError||r.once("secureConnect",t.secureConnect)),s&&r.once("close",t.close)};r.writable&&!r.connecting?o():r.connecting?r.once("connect",o):r.destroyed&&s&&t.close(r._hadError)};Qk.default=vk;Sk.exports=vk;Sk.exports.default=vk});var Y4=w((xk,kk)=>{"use strict";Object.defineProperty(xk,"__esModule",{value:!0});var kve=G4(),Pve=Number(process.versions.node.split(".")[0]),Pk=r=>{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}};r.timings=e;let t=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))};t(r),r.prependOnceListener("abort",()=>{e.abort=Date.now(),(!e.response||Pve>=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),kve.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}})};r.socket?i(r.socket):r.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 r.writableFinished=="boolean"?r.writableFinished:r.finished&&r.outputSize===0&&(!r.socket||r.socket.writableLength===0))()?n():r.prependOnceListener("finish",n),r.prependOnceListener("response",o=>{e.response=Date.now(),e.phases.firstByte=e.response-e.upload,o.timings=e,t(o),o.prependOnceListener("end",()=>{e.end=Date.now(),e.phases.download=e.end-e.response,e.phases.total=e.end-e.start})}),e};xk.default=Pk;kk.exports=Pk;kk.exports.default=Pk});var X4=w((zit,Dk)=>{"use strict";var{V4MAPPED:Dve,ADDRCONFIG:Rve,ALL:q4,promises:{Resolver:J4},lookup:Fve}=require("dns"),{promisify:Rk}=require("util"),Nve=require("os"),Zg=Symbol("cacheableLookupCreateConnection"),Fk=Symbol("cacheableLookupInstance"),W4=Symbol("expires"),Lve=typeof q4=="number",z4=r=>{if(!(r&&typeof r.createConnection=="function"))throw new Error("Expected an Agent instance as the first argument")},Tve=r=>{for(let e of r)e.family!==6&&(e.address=`::ffff:${e.address}`,e.family=6)},_4=()=>{let r=!1,e=!1;for(let t of Object.values(Nve.networkInterfaces()))for(let i of t)if(!i.internal&&(i.family==="IPv6"?e=!0:r=!0,r&&e))return{has4:r,has6:e};return{has4:r,has6:e}},Ove=r=>Symbol.iterator in r,V4={ttl:!0},Mve={all:!0},Nk=class{constructor({cache:e=new Map,maxTtl:t=Infinity,fallbackDuration:i=3600,errorTtl:n=.15,resolver:s=new J4,lookup:o=Fve}={}){if(this.maxTtl=t,this.errorTtl=n,this._cache=e,this._resolver=s,this._dnsLookup=Rk(o),this._resolver instanceof J4?(this._resolve4=this._resolver.resolve4.bind(this._resolver),this._resolve6=this._resolver.resolve6.bind(this._resolver)):(this._resolve4=Rk(this._resolver.resolve4.bind(this._resolver)),this._resolve6=Rk(this._resolver.resolve6.bind(this._resolver))),this._iface=_4(),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,t,i){if(typeof t=="function"?(i=t,t={}):typeof t=="number"&&(t={family:t}),!i)throw new Error("Callback must be a function.");this.lookupAsync(e,t).then(n=>{t.all?i(null,n):i(null,n.address,n.family,n.expires,n.ttl)},i)}async lookupAsync(e,t={}){typeof t=="number"&&(t={family:t});let i=await this.query(e);if(t.family===6){let n=i.filter(s=>s.family===6);t.hints&Dve&&(Lve&&t.hints&q4||n.length===0)?Tve(i):i=n}else t.family===4&&(i=i.filter(n=>n.family===4));if(t.hints&Rve){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 t.all?i:i[0]}async query(e){let t=await this._cache.get(e);if(!t){let i=this._pending[e];if(i)t=await i;else{let n=this.queryAndCache(e);this._pending[e]=n,t=await n}}return t=t.map(i=>N({},i)),t}async _resolve(e){let t=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,V4),this._resolve6(e,V4)].map(c=>t(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(t){return{entries:[],cacheTtl:0}}}async _set(e,t,i){if(this.maxTtl>0&&i>0){i=Math.min(i,this.maxTtl)*1e3,t[W4]=Date.now()+i;try{await this._cache.set(e,t,i)}catch(n){this.lookupAsync=async()=>{let s=new Error("Cache Error. Please recreate the CacheableLookup instance.");throw s.cause=n,s}}Ove(this._cache)&&this._tick(i)}}async queryAndCache(e){if(this._hostnamesToFallback.has(e))return this._dnsLookup(e,Mve);try{let t=await this._resolve(e);t.entries.length===0&&this._fallback&&(t=await this._lookup(e),t.entries.length!==0&&this._hostnamesToFallback.add(e));let i=t.entries.length===0?this.errorTtl:t.cacheTtl;return await this._set(e,t.entries,i),delete this._pending[e],t.entries}catch(t){throw delete this._pending[e],t}}_tick(e){let t=this._nextRemovalTime;(!t||e{this._nextRemovalTime=!1;let i=Infinity,n=Date.now();for(let[s,o]of this._cache){let a=o[W4];n>=a?this._cache.delete(s):a("lookup"in t||(t.lookup=this.lookup),e[Zg](t,i))}uninstall(e){if(z4(e),e[Zg]){if(e[Fk]!==this)throw new Error("The agent is not owned by this CacheableLookup instance");e.createConnection=e[Zg],delete e[Zg],delete e[Fk]}}updateInterfaceInfo(){let{_iface:e}=this;this._iface=_4(),(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()}};Dk.exports=Nk;Dk.exports.default=Nk});var e8=w((_it,Lk)=>{"use strict";var Kve=typeof URL=="undefined"?require("url").URL:URL,Uve="text/plain",Hve="us-ascii",Z4=(r,e)=>e.some(t=>t instanceof RegExp?t.test(r):t===r),jve=(r,{stripHash:e})=>{let t=r.match(/^data:([^,]*?),([^#]*?)(?:#(.*))?$/);if(!t)throw new Error(`Invalid URL: ${r}`);let i=t[1].split(";"),n=t[2],s=e?"":t[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===Hve)?"":`${g}${f?`=${f}`:""}`}).filter(Boolean)];return o&&c.push("base64"),(c.length!==0||a&&a!==Uve)&&c.unshift(a),`data:${c.join(";")},${o?n.trim():n}${s?`#${s}`:""}`},$4=(r,e)=>{if(e=N({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(r=r.trim(),/^data:/i.test(r))return jve(r,e);let t=r.startsWith("//");!t&&/^\.*\//.test(r)||(r=r.replace(/^(?!(?:\w+:)?\/\/)|^\/\//,e.defaultProtocol));let n=new Kve(r);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];Z4(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()])Z4(s,e.removeQueryParameters)&&n.searchParams.delete(s);return e.sortQueryParameters&&n.searchParams.sort(),e.removeTrailingSlash&&(n.pathname=n.pathname.replace(/\/$/,"")),r=n.toString(),(e.removeTrailingSlash||n.pathname==="/")&&n.hash===""&&(r=r.replace(/\/$/,"")),t&&!e.normalizeProtocol&&(r=r.replace(/^http:\/\//,"//")),e.stripProtocol&&(r=r.replace(/^(?:https?:)?\/\//,"")),r};Lk.exports=$4;Lk.exports.default=$4});var i8=w((Vit,t8)=>{t8.exports=r8;function r8(r,e){if(r&&e)return r8(r)(e);if(typeof r!="function")throw new TypeError("need wrapper function");return Object.keys(r).forEach(function(i){t[i]=r[i]}),t;function t(){for(var i=new Array(arguments.length),n=0;n{var n8=i8();Tk.exports=n8(bw);Tk.exports.strict=n8(s8);bw.proto=bw(function(){Object.defineProperty(Function.prototype,"once",{value:function(){return bw(this)},configurable:!0}),Object.defineProperty(Function.prototype,"onceStrict",{value:function(){return s8(this)},configurable:!0})});function bw(r){var e=function(){return e.called?e.value:(e.called=!0,e.value=r.apply(this,arguments))};return e.called=!1,e}function s8(r){var e=function(){if(e.called)throw new Error(e.onceError);return e.called=!0,e.value=r.apply(this,arguments)},t=r.name||"Function wrapped with `once`";return e.onceError=t+" shouldn't be called more than once",e.called=!1,e}});var Mk=w((Zit,o8)=>{var Gve=Ok(),Yve=function(){},qve=function(r){return r.setHeader&&typeof r.abort=="function"},Jve=function(r){return r.stdio&&Array.isArray(r.stdio)&&r.stdio.length===3},a8=function(r,e,t){if(typeof e=="function")return a8(r,null,e);e||(e={}),t=Gve(t||Yve);var i=r._writableState,n=r._readableState,s=e.readable||e.readable!==!1&&r.readable,o=e.writable||e.writable!==!1&&r.writable,a=function(){r.writable||l()},l=function(){o=!1,s||t.call(r)},c=function(){s=!1,o||t.call(r)},u=function(p){t.call(r,p?new Error("exited with error code: "+p):null)},g=function(p){t.call(r,p)},f=function(){if(s&&!(n&&n.ended))return t.call(r,new Error("premature close"));if(o&&!(i&&i.ended))return t.call(r,new Error("premature close"))},h=function(){r.req.on("finish",l)};return qve(r)?(r.on("complete",l),r.on("abort",f),r.req?h():r.on("request",h)):o&&!i&&(r.on("end",a),r.on("close",a)),Jve(r)&&r.on("exit",u),r.on("end",c),r.on("finish",l),e.error!==!1&&r.on("error",g),r.on("close",f),function(){r.removeListener("complete",l),r.removeListener("abort",f),r.removeListener("request",h),r.req&&r.req.removeListener("finish",l),r.removeListener("end",a),r.removeListener("close",a),r.removeListener("finish",l),r.removeListener("exit",u),r.removeListener("end",c),r.removeListener("error",g),r.removeListener("close",f)}};o8.exports=a8});var c8=w(($it,A8)=>{var Wve=Ok(),zve=Mk(),Kk=require("fs"),kd=function(){},_ve=/^v?\.0/.test(process.version),Qw=function(r){return typeof r=="function"},Vve=function(r){return!_ve||!Kk?!1:(r instanceof(Kk.ReadStream||kd)||r instanceof(Kk.WriteStream||kd))&&Qw(r.close)},Xve=function(r){return r.setHeader&&Qw(r.abort)},Zve=function(r,e,t,i){i=Wve(i);var n=!1;r.on("close",function(){n=!0}),zve(r,{readable:e,writable:t},function(o){if(o)return i(o);n=!0,i()});var s=!1;return function(o){if(!n&&!s){if(s=!0,Vve(r))return r.close(kd);if(Xve(r))return r.abort();if(Qw(r.destroy))return r.destroy();i(o||new Error("stream was destroyed"))}}},l8=function(r){r()},$ve=function(r,e){return r.pipe(e)},exe=function(){var r=Array.prototype.slice.call(arguments),e=Qw(r[r.length-1]||kd)&&r.pop()||kd;if(Array.isArray(r[0])&&(r=r[0]),r.length<2)throw new Error("pump requires two streams per minimum");var t,i=r.map(function(n,s){var o=s0;return Zve(n,o,a,function(l){t||(t=l),l&&i.forEach(l8),!o&&(i.forEach(l8),e(t))})});return r.reduce($ve)};A8.exports=exe});var g8=w((ent,u8)=>{"use strict";var{PassThrough:txe}=require("stream");u8.exports=r=>{r=N({},r);let{array:e}=r,{encoding:t}=r,i=t==="buffer",n=!1;e?n=!(t||i):t=t||"utf8",i&&(t=null);let s=new txe({objectMode:n});t&&s.setEncoding(t);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 f8=w((tnt,$g)=>{"use strict";var rxe=c8(),ixe=g8(),Uk=class extends Error{constructor(){super("maxBuffer exceeded");this.name="MaxBufferError"}};async function Sw(r,e){if(!r)return Promise.reject(new Error("Expected a stream"));e=N({maxBuffer:Infinity},e);let{maxBuffer:t}=e,i;return await new Promise((n,s)=>{let o=a=>{a&&(a.bufferedData=i.getBufferedValue()),s(a)};i=rxe(r,ixe(e),a=>{if(a){o(a);return}n()}),i.on("data",()=>{i.getBufferedLength()>t&&o(new Uk)})}),i.getBufferedValue()}$g.exports=Sw;$g.exports.default=Sw;$g.exports.buffer=(r,e)=>Sw(r,te(N({},e),{encoding:"buffer"}));$g.exports.array=(r,e)=>Sw(r,te(N({},e),{array:!0}));$g.exports.MaxBufferError=Uk});var p8=w((int,h8)=>{"use strict";var nxe=[200,203,204,206,300,301,404,405,410,414,501],sxe=[200,203,204,300,301,302,303,307,308,404,405,410,414,501],oxe={date:!0,connection:!0,"keep-alive":!0,"proxy-authenticate":!0,"proxy-authorization":!0,te:!0,trailer:!0,"transfer-encoding":!0,upgrade:!0},axe={"content-length":!0,"content-encoding":!0,"transfer-encoding":!0,"content-range":!0};function Hk(r){let e={};if(!r)return e;let t=r.trim().split(/\s*,\s*/);for(let i of t){let[n,s]=i.split(/\s*=\s*/,2);e[n]=s===void 0?!0:s.replace(/^"|"$/g,"")}return e}function Axe(r){let e=[];for(let t in r){let i=r[t];e.push(i===!0?t:t+"="+i)}if(!!e.length)return e.join(", ")}h8.exports=class{constructor(e,t,{shared:i,cacheHeuristic:n,immutableMinTimeToLive:s,ignoreCargoCult:o,trustServerDate:a,_fromObject:l}={}){if(l){this._fromObject(l);return}if(!t||!t.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 t?t.status:200,this._resHeaders=t.headers,this._rescc=Hk(t.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=t.headers.vary?e.headers:null,this._reqcc=Hk(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":Axe(this._rescc)}),delete this._resHeaders.expires,delete this._resHeaders.pragma),!t.headers["cache-control"]&&/no-cache/.test(t.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())&&sxe.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"]||nxe.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 t=Hk(e.headers["cache-control"]);return t["no-cache"]||/no-cache/.test(e.headers.pragma)||t["max-age"]&&this.age()>t["max-age"]||t["min-fresh"]&&this.timeToLive()<1e3*t["min-fresh"]||this.stale()&&!(t["max-stale"]&&!this._rescc["must-revalidate"]&&(t["max-stale"]===!0||t["max-stale"]>this.age()-this.maxAge()))?!1:this._requestMatches(e,!1)}_requestMatches(e,t){return(!this._url||this._url===e.url)&&this._host===e.headers.host&&(!e.method||this._method===e.method||t&&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 t=this._resHeaders.vary.trim().toLowerCase().split(/\s*,\s*/);for(let i of t)if(e.headers[i]!==this._reqHeaders[i])return!1;return!0}_copyWithoutHopByHopHeaders(e){let t={};for(let i in e)oxe[i]||(t[i]=e[i]);if(e.connection){let i=e.connection.trim().split(/\s*,\s*/);for(let n of i)delete t[n]}if(t.warning){let i=t.warning.split(/,/).filter(n=>!/^\s*1[0-9][0-9]/.test(n));i.length?t.warning=i.join(",").trim():delete t.warning}return t}responseHeaders(){let e=this._copyWithoutHopByHopHeaders(this._resHeaders),t=this.age();return t>3600*24&&!this._hasExplicitExpiration()&&this.maxAge()>3600*24&&(e.warning=(e.warning?`${e.warning}, `:"")+'113 - "rfc7234 5.5.4"'),e.age=`${Math.round(t)}`,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 t=8*3600*1e3;if(Math.abs(this._responseTime-e)e&&(e=i)}let t=(this.now()-this._responseTime)/1e3;return e+t}_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,t=this._serverDate();if(this._resHeaders.expires){let i=Date.parse(this._resHeaders.expires);return Number.isNaN(i)||ii)return Math.max(e,(t-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 t=this._copyWithoutHopByHopHeaders(e.headers);if(delete t["if-range"],!this._requestMatches(e,!0)||!this.storable())return delete t["if-none-match"],delete t["if-modified-since"],t;if(this._resHeaders.etag&&(t["if-none-match"]=t["if-none-match"]?`${t["if-none-match"]}, ${this._resHeaders.etag}`:this._resHeaders.etag),t["accept-ranges"]||t["if-match"]||t["if-unmodified-since"]||this._method&&this._method!="GET"){if(delete t["if-modified-since"],t["if-none-match"]){let n=t["if-none-match"].split(/,/).filter(s=>!/^\s*W\//.test(s));n.length?t["if-none-match"]=n.join(",").trim():delete t["if-none-match"]}}else this._resHeaders["last-modified"]&&!t["if-modified-since"]&&(t["if-modified-since"]=this._resHeaders["last-modified"]);return t}revalidatedPolicy(e,t){if(this._assertRequestHasHeaders(e),!t||!t.headers)throw Error("Response headers missing");let i=!1;if(t.status!==void 0&&t.status!=304?i=!1:t.headers.etag&&!/^\s*W\//.test(t.headers.etag)?i=this._resHeaders.etag&&this._resHeaders.etag.replace(/^\s*W\//,"")===t.headers.etag:this._resHeaders.etag&&t.headers.etag?i=this._resHeaders.etag.replace(/^\s*W\//,"")===t.headers.etag.replace(/^\s*W\//,""):this._resHeaders["last-modified"]?i=this._resHeaders["last-modified"]===t.headers["last-modified"]:!this._resHeaders.etag&&!this._resHeaders["last-modified"]&&!t.headers.etag&&!t.headers["last-modified"]&&(i=!0),!i)return{policy:new this.constructor(e,t),modified:t.status!=304,matches:!1};let n={};for(let o in this._resHeaders)n[o]=o in t.headers&&!axe[o]?t.headers[o]:this._resHeaders[o];let s=Object.assign({},t,{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 vw=w((nnt,d8)=>{"use strict";d8.exports=r=>{let e={};for(let[t,i]of Object.entries(r))e[t.toLowerCase()]=i;return e}});var E8=w((snt,C8)=>{"use strict";var lxe=require("stream").Readable,cxe=vw(),m8=class extends lxe{constructor(e,t,i,n){if(typeof e!="number")throw new TypeError("Argument `statusCode` should be a number");if(typeof t!="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=cxe(t),this.body=i,this.url=n}_read(){this.push(this.body),this.push(null)}};C8.exports=m8});var y8=w((ont,I8)=>{"use strict";var uxe=["destroy","setTimeout","socket","headers","trailers","rawHeaders","statusCode","httpVersion","httpVersionMinor","httpVersionMajor","rawTrailers","statusMessage"];I8.exports=(r,e)=>{let t=new Set(Object.keys(r).concat(uxe));for(let i of t)i in e||(e[i]=typeof r[i]=="function"?r[i].bind(r):r[i])}});var B8=w((ant,w8)=>{"use strict";var gxe=require("stream").PassThrough,fxe=y8(),hxe=r=>{if(!(r&&r.pipe))throw new TypeError("Parameter `response` must be a response stream.");let e=new gxe;return fxe(r,e),r.pipe(e)};w8.exports=hxe});var b8=w(jk=>{jk.stringify=function r(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 t="",i=Array.isArray(e);t=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||(t+=","),n=!1,i?e[s]==null?t+="null":t+=r(e[s]):e[s]!==void 0&&(t+=r(s)+":"+r(e[s])))}return t+=i?"]":"}",t}else return typeof e=="string"?JSON.stringify(/^:/.test(e)?":"+e:e):typeof e=="undefined"?"null":JSON.stringify(e)};jk.parse=function(r){return JSON.parse(r,function(e,t){return typeof t=="string"?/^:base64:/.test(t)?Buffer.from(t.substring(8),"base64"):/^:/.test(t)?t.substring(1):t:t})}});var x8=w((lnt,Q8)=>{"use strict";var pxe=require("events"),S8=b8(),dxe=r=>{let e={redis:"@keyv/redis",mongodb:"@keyv/mongo",mongo:"@keyv/mongo",sqlite:"@keyv/sqlite",postgresql:"@keyv/postgres",postgres:"@keyv/postgres",mysql:"@keyv/mysql"};if(r.adapter||r.uri){let t=r.adapter||/^[^:]*/.exec(r.uri)[0];return new(require(e[t]))(r)}return new Map},v8=class extends pxe{constructor(e,t){super();if(this.opts=Object.assign({namespace:"keyv",serialize:S8.stringify,deserialize:S8.parse},typeof e=="string"?{uri:e}:e,t),!this.opts.store){let i=Object.assign({},this.opts);this.opts.store=dxe(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,t){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 t&&t.raw?n:n.value}})}set(e,t,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 t={value:t,expires:s},this.opts.serialize(t)}).then(s=>n.set(e,s,i)).then(()=>!0)}delete(e){e=this._getKeyPrefix(e);let{store:t}=this.opts;return Promise.resolve().then(()=>t.delete(e))}clear(){let{store:e}=this.opts;return Promise.resolve().then(()=>e.clear())}};Q8.exports=v8});var D8=w((cnt,k8)=>{"use strict";var Cxe=require("events"),xw=require("url"),mxe=e8(),Exe=f8(),Gk=p8(),P8=E8(),Ixe=vw(),yxe=B8(),wxe=x8(),ia=class{constructor(e,t){if(typeof e!="function")throw new TypeError("Parameter `request` must be a function");return this.cache=new wxe({uri:typeof t=="string"&&t,store:typeof t!="string"&&t,namespace:"cacheable-request"}),this.createCacheableRequest(e)}createCacheableRequest(e){return(t,i)=>{let n;if(typeof t=="string")n=Yk(xw.parse(t)),t={};else if(t instanceof xw.URL)n=Yk(xw.parse(t.toString())),t={};else{let[g,...f]=(t.path||"").split("?"),h=f.length>0?`?${f.join("?")}`:"";n=Yk(te(N({},t),{pathname:g,search:h}))}t=N(N({headers:{},method:"GET",cache:!0,strictTtl:!1,automaticFailover:!1},t),Bxe(n)),t.headers=Ixe(t.headers);let s=new Cxe,o=mxe(xw.format(n),{stripWWW:!1,removeTrailingSlash:!1,stripAuthentication:!1}),a=`${t.method}:${o}`,l=!1,c=!1,u=g=>{c=!0;let f=!1,h,p=new Promise(y=>{h=()=>{f||(f=!0,y())}}),m=y=>{if(l&&!g.forceRefresh){y.status=y.statusCode;let v=Gk.fromObject(l.cachePolicy).revalidatedPolicy(g,y);if(!v.modified){let x=v.policy.responseHeaders();y=new P8(l.statusCode,x,l.body,l.url),y.cachePolicy=v.policy,y.fromCache=!0}}y.fromCache||(y.cachePolicy=new Gk(g,y,g),y.fromCache=!1);let b;g.cache&&y.cachePolicy.storable()?(b=yxe(y),(async()=>{try{let v=Exe.buffer(y);if(await Promise.race([p,new Promise(Y=>y.once("end",Y))]),f)return;let x=await v,T={cachePolicy:y.cachePolicy.toObject(),url:y.url,statusCode:y.fromCache?l.statusCode:y.statusCode,body:x},q=g.strictTtl?y.cachePolicy.timeToLive():void 0;g.maxTtl&&(q=q?Math.min(q,g.maxTtl):g.maxTtl),await this.cache.set(a,T,q)}catch(v){s.emit("error",new ia.CacheError(v))}})()):g.cache&&l&&(async()=>{try{await this.cache.delete(a)}catch(v){s.emit("error",new ia.CacheError(v))}})(),s.emit("response",b||y),typeof i=="function"&&i(b||y)};try{let y=e(g,m);y.once("error",h),y.once("abort",h),s.emit("request",y)}catch(y){s.emit("error",new ia.RequestError(y))}};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 m=Gk.fromObject(p.cachePolicy);if(m.satisfiesWithoutRevalidation(h)&&!h.forceRefresh){let y=m.responseHeaders(),b=new P8(p.statusCode,y,p.body,p.url);b.cachePolicy=m,b.fromCache=!0,s.emit("response",b),typeof i=="function"&&i(b)}else l=p,h.headers=m.revalidationHeaders(h),u(h)},f=h=>s.emit("error",new ia.CacheError(h));this.cache.once("error",f),s.on("response",()=>this.cache.removeListener("error",f));try{await g(t)}catch(h){t.automaticFailover&&!c&&u(t),s.emit("error",new ia.CacheError(h))}})(),s}}};function Bxe(r){let e=N({},r);return e.path=`${r.pathname||"/"}${r.search||""}`,delete e.pathname,delete e.search,e}function Yk(r){return{protocol:r.protocol,auth:r.auth,hostname:r.hostname||r.host||"localhost",port:r.port,pathname:r.pathname,search:r.search}}ia.RequestError=class extends Error{constructor(r){super(r.message);this.name="RequestError",Object.assign(this,r)}};ia.CacheError=class extends Error{constructor(r){super(r.message);this.name="CacheError",Object.assign(this,r)}};k8.exports=ia});var F8=w((unt,R8)=>{"use strict";var bxe=["aborted","complete","headers","httpVersion","httpVersionMinor","httpVersionMajor","method","rawHeaders","rawTrailers","setTimeout","socket","statusCode","statusMessage","trailers","url"];R8.exports=(r,e)=>{if(e._readableState.autoDestroy)throw new Error("The second stream must have the `autoDestroy` option set to `false`");let t=new Set(Object.keys(r).concat(bxe)),i={};for(let n of t)n in e||(i[n]={get(){let s=r[n];return typeof s=="function"?s.bind(r):s},set(s){r[n]=s},enumerable:!0,configurable:!1});return Object.defineProperties(e,i),r.once("aborted",()=>{e.destroy(),e.emit("aborted")}),r.once("close",()=>{r.complete&&e.readable?e.once("end",()=>{e.emit("close")}):e.emit("close")}),e}});var L8=w((gnt,N8)=>{"use strict";var{Transform:Qxe,PassThrough:Sxe}=require("stream"),qk=require("zlib"),vxe=F8();N8.exports=r=>{let e=(r.headers["content-encoding"]||"").toLowerCase();if(!["gzip","deflate","br"].includes(e))return r;let t=e==="br";if(t&&typeof qk.createBrotliDecompress!="function")return r.destroy(new Error("Brotli is not supported on Node.js < 12")),r;let i=!0,n=new Qxe({transform(a,l,c){i=!1,c(null,a)},flush(a){a()}}),s=new Sxe({autoDestroy:!1,destroy(a,l){r.destroy(),l(a)}}),o=t?qk.createBrotliDecompress():qk.createUnzip();return o.once("error",a=>{if(i&&!r.readable){s.end();return}s.destroy(a)}),vxe(r,s),r.pipe(n).pipe(o).pipe(s),s}});var Jk=w((fnt,T8)=>{"use strict";var O8=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,t){if(this.cache.set(e,t),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 t=this.oldCache.get(e);return this.oldCache.delete(e),this._set(e,t),t}}set(e,t){return this.cache.has(e)?this.cache.set(e,t):this._set(e,t),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 t=this.cache.delete(e);return t&&this._size--,this.oldCache.delete(e)||t}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[t]=e;this.cache.has(t)||(yield e)}}get size(){let e=0;for(let t of this.oldCache.keys())this.cache.has(t)||e++;return Math.min(this._size+e,this.maxSize)}};T8.exports=O8});var zk=w((hnt,M8)=>{"use strict";var xxe=require("events"),kxe=require("tls"),Pxe=require("http2"),Dxe=Jk(),gn=Symbol("currentStreamsCount"),K8=Symbol("request"),Ls=Symbol("cachedOriginSet"),ef=Symbol("gracefullyClosing"),Rxe=["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"],Fxe=(r,e,t)=>{let i=0,n=r.length;for(;i>>1;t(r[s],e)?i=s+1:n=s}return i},Nxe=(r,e)=>r.remoteSettings.maxConcurrentStreams>e.remoteSettings.maxConcurrentStreams,Wk=(r,e)=>{for(let t of r)t[Ls].lengthe[Ls].includes(i))&&t[gn]+e[gn]<=e.remoteSettings.maxConcurrentStreams&&U8(t)},Lxe=(r,e)=>{for(let t of r)e[Ls].lengtht[Ls].includes(i))&&e[gn]+t[gn]<=t.remoteSettings.maxConcurrentStreams&&U8(e)},H8=({agent:r,isFree:e})=>{let t={};for(let i in r.sessions){let s=r.sessions[i].filter(o=>{let a=o[nA.kCurrentStreamsCount]{r[ef]=!0,r[gn]===0&&r.close()},nA=class extends xxe{constructor({timeout:e=6e4,maxSessions:t=Infinity,maxFreeSessions:i=10,maxCachedTlsSessions:n=100}={}){super();this.sessions={},this.queue={},this.timeout=e,this.maxSessions=t,this.maxFreeSessions=i,this._freeSessionsCount=0,this._sessionsCount=0,this.settings={enablePush:!1},this.tlsSessionCache=new Dxe({maxSize:n})}static normalizeOrigin(e,t){return typeof e=="string"&&(e=new URL(e)),t&&e.hostname!==t&&(e.hostname=t),e.origin}normalizeOptions(e){let t="";if(e)for(let i of Rxe)e[i]&&(t+=`:${e[i]}`);return t}_tryToCreateNewSession(e,t){if(!(e in this.queue)||!(t in this.queue[e]))return;let i=this.queue[e][t];this._sessionsCount{Array.isArray(i)?(i=[...i],n()):i=[{resolve:n,reject:s}];let o=this.normalizeOptions(t),a=nA.normalizeOrigin(e,t&&t.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 m=p.remoteSettings.maxConcurrentStreams;if(m=m||p[ef]||p.destroyed)continue;h||(g=m),y>f&&(h=p,f=y)}}if(h){if(i.length!==1){for(let{reject:p}of i){let m=new Error(`Expected the length of listeners to be 1, got ${i.length}. -Please report this to https://github.com/szmarczak/http2-wrapper/`);p(m)}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=Pxe.connect(e,N({createConnection:this.createConnection,settings:this.settings,session:this.tlsSessionCache.get(u)},t));f[gn]=0,f[ef]=!1;let h=()=>f[gn]{this.tlsSessionCache.set(u,y)}),f.once("error",y=>{for(let{reject:b}of i)b(y);this.tlsSessionCache.delete(u)}),f.setTimeout(this.timeout,()=>{f.destroy()}),f.once("close",()=>{if(g){p&&this._freeSessionsCount--,this._sessionsCount--;let y=this.sessions[o];y.splice(y.indexOf(f),1),y.length===0&&delete this.sessions[o]}else{let y=new Error("Session closed without receiving a SETTINGS frame");y.code="HTTP2WRAPPER_NOSETTINGS";for(let{reject:b}of i)b(y);l()}this._tryToCreateNewSession(o,a)});let m=()=>{if(!(!(o in this.queue)||!h())){for(let y of f[Ls])if(y in this.queue[o]){let{listeners:b}=this.queue[o][y];for(;b.length!==0&&h();)b.shift().resolve(f);let v=this.queue[o];if(v[y].listeners.length===0&&(delete v[y],Object.keys(v).length===0)){delete this.queue[o];break}if(!h())break}}};f.on("origin",()=>{f[Ls]=f.originSet,!!h()&&(m(),Wk(this.sessions[o],f))}),f.once("remoteSettings",()=>{if(f.ref(),f.unref(),this._sessionsCount++,c.destroyed){let y=new Error("Agent has been destroyed");for(let b of i)b.reject(y);f.destroy();return}f[Ls]=f.originSet;{let y=this.sessions;if(o in y){let b=y[o];b.splice(Fxe(b,f,Nxe),0,f)}else y[o]=[f]}this._freeSessionsCount+=1,g=!0,this.emit("session",f),m(),l(),f[gn]===0&&this._freeSessionsCount>this.maxFreeSessions&&f.close(),i.length!==0&&(this.getSession(a,t,i),i.length=0),f.on("remoteSettings",()=>{m(),Wk(this.sessions[o],f)})}),f[K8]=f.request,f.request=(y,b)=>{if(f[ef])throw new Error("The session is gracefully closing. No new streams are allowed.");let v=f[K8](y,b);return f.ref(),++f[gn],f[gn]===f.remoteSettings.maxConcurrentStreams&&this._freeSessionsCount--,v.once("close",()=>{if(p=h(),--f[gn],!f.destroyed&&!f.closed&&(Lxe(this.sessions[o],f),h()&&!f.closed)){p||(this._freeSessionsCount++,p=!0);let x=f[gn]===0;x&&f.unref(),x&&(this._freeSessionsCount>this.maxFreeSessions||f[ef])?f.close():(Wk(this.sessions[o],f),m())}}),v}}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,t,i,n){return new Promise((s,o)=>{this.getSession(e,t,[{reject:o,resolve:a=>{try{s(a.request(i,n))}catch(l){o(l)}}}])})}createConnection(e,t){return nA.connect(e,t)}static connect(e,t){t.ALPNProtocols=["h2"];let i=e.port||443,n=e.hostname||e.host;return typeof t.servername=="undefined"&&(t.servername=n),kxe.connect(i,n,t)}closeFreeSessions(){for(let e of Object.values(this.sessions))for(let t of e)t[gn]===0&&t.close()}destroy(e){for(let t of Object.values(this.sessions))for(let i of t)i.destroy(e);for(let t of Object.values(this.queue))for(let i of Object.values(t))i.destroyed=!0;this.queue={}}get freeSessions(){return H8({agent:this,isFree:!0})}get busySessions(){return H8({agent:this,isFree:!1})}};nA.kCurrentStreamsCount=gn;nA.kGracefullyClosing=ef;M8.exports={Agent:nA,globalAgent:new nA}});var _k=w((pnt,j8)=>{"use strict";var{Readable:Txe}=require("stream"),G8=class extends Txe{constructor(e,t){super({highWaterMark:t,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,t){return this.req.setTimeout(e,t),this}_dump(){this._dumped||(this._dumped=!0,this.removeAllListeners("data"),this.resume())}_read(){this.req&&this.req._request.resume()}};j8.exports=G8});var Vk=w((dnt,Y8)=>{"use strict";Y8.exports=r=>{let e={protocol:r.protocol,hostname:typeof r.hostname=="string"&&r.hostname.startsWith("[")?r.hostname.slice(1,-1):r.hostname,host:r.host,hash:r.hash,search:r.search,pathname:r.pathname,href:r.href,path:`${r.pathname||""}${r.search||""}`};return typeof r.port=="string"&&r.port.length!==0&&(e.port=Number(r.port)),(r.username||r.password)&&(e.auth=`${r.username||""}:${r.password||""}`),e}});var J8=w((Cnt,q8)=>{"use strict";q8.exports=(r,e,t)=>{for(let i of t)r.on(i,(...n)=>e.emit(i,...n))}});var z8=w((mnt,W8)=>{"use strict";W8.exports=r=>{switch(r){case":method":case":scheme":case":authority":case":path":return!0;default:return!1}}});var V8=w((Int,_8)=>{"use strict";var tf=(r,e,t)=>{_8.exports[e]=class extends r{constructor(...n){super(typeof t=="string"?t:t(n));this.name=`${super.name} [${e}]`,this.code=e}}};tf(TypeError,"ERR_INVALID_ARG_TYPE",r=>{let e=r[0].includes(".")?"property":"argument",t=r[1],i=Array.isArray(t);return i&&(t=`${t.slice(0,-1).join(", ")} or ${t.slice(-1)}`),`The "${r[0]}" ${e} must be ${i?"one of":"of"} type ${t}. Received ${typeof r[2]}`});tf(TypeError,"ERR_INVALID_PROTOCOL",r=>`Protocol "${r[0]}" not supported. Expected "${r[1]}"`);tf(Error,"ERR_HTTP_HEADERS_SENT",r=>`Cannot ${r[0]} headers after they are sent to the client`);tf(TypeError,"ERR_INVALID_HTTP_TOKEN",r=>`${r[0]} must be a valid HTTP token [${r[1]}]`);tf(TypeError,"ERR_HTTP_INVALID_HEADER_VALUE",r=>`Invalid value "${r[0]} for header "${r[1]}"`);tf(TypeError,"ERR_INVALID_CHAR",r=>`Invalid character in ${r[0]} [${r[1]}]`)});var eP=w((ynt,X8)=>{"use strict";var Oxe=require("http2"),{Writable:Mxe}=require("stream"),{Agent:Z8,globalAgent:Kxe}=zk(),Uxe=_k(),Hxe=Vk(),jxe=J8(),Gxe=z8(),{ERR_INVALID_ARG_TYPE:Xk,ERR_INVALID_PROTOCOL:Yxe,ERR_HTTP_HEADERS_SENT:$8,ERR_INVALID_HTTP_TOKEN:qxe,ERR_HTTP_INVALID_HEADER_VALUE:Jxe,ERR_INVALID_CHAR:Wxe}=V8(),{HTTP2_HEADER_STATUS:ez,HTTP2_HEADER_METHOD:tz,HTTP2_HEADER_PATH:rz,HTTP2_METHOD_CONNECT:zxe}=Oxe.constants,Wi=Symbol("headers"),Zk=Symbol("origin"),$k=Symbol("session"),iz=Symbol("options"),kw=Symbol("flushedHeaders"),Pd=Symbol("jobs"),_xe=/^[\^`\-\w!#$%&*+.|~]+$/,Vxe=/[^\t\u0020-\u007E\u0080-\u00FF]/,nz=class extends Mxe{constructor(e,t,i){super({autoDestroy:!1});let n=typeof e=="string"||e instanceof URL;if(n&&(e=Hxe(e instanceof URL?e:new URL(e))),typeof t=="function"||t===void 0?(i=t,t=n?e:N({},e)):t=N(N({},e),t),t.h2session)this[$k]=t.h2session;else if(t.agent===!1)this.agent=new Z8({maxFreeSessions:0});else if(typeof t.agent=="undefined"||t.agent===null)typeof t.createConnection=="function"?(this.agent=new Z8({maxFreeSessions:0}),this.agent.createConnection=t.createConnection):this.agent=Kxe;else if(typeof t.agent.request=="function")this.agent=t.agent;else throw new Xk("options.agent",["Agent-like Object","undefined","false"],t.agent);if(t.protocol&&t.protocol!=="https:")throw new Yxe(t.protocol,"https:");let s=t.port||t.defaultPort||this.agent&&this.agent.defaultPort||443,o=t.hostname||t.host||"localhost";delete t.hostname,delete t.host,delete t.port;let{timeout:a}=t;if(t.timeout=void 0,this[Wi]=Object.create(null),this[Pd]=[],this.socket=null,this.connection=null,this.method=t.method||"GET",this.path=t.path,this.res=null,this.aborted=!1,this.reusedSocket=!1,t.headers)for(let[l,c]of Object.entries(t.headers))this.setHeader(l,c);t.auth&&!("authorization"in this[Wi])&&(this[Wi].authorization="Basic "+Buffer.from(t.auth).toString("base64")),t.session=t.tlsSession,t.path=t.socketPath,this[iz]=t,s===443?(this[Zk]=`https://${o}`,":authority"in this[Wi]||(this[Wi][":authority"]=o)):(this[Zk]=`https://${o}:${s}`,":authority"in this[Wi]||(this[Wi][":authority"]=`${o}:${s}`)),a&&this.setTimeout(a),i&&this.once("response",i),this[kw]=!1}get method(){return this[Wi][tz]}set method(e){e&&(this[Wi][tz]=e.toUpperCase())}get path(){return this[Wi][rz]}set path(e){e&&(this[Wi][rz]=e)}get _mustNotHaveABody(){return this.method==="GET"||this.method==="HEAD"||this.method==="DELETE"}_write(e,t,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,t,i);this._request?n():this[Pd].push(n)}_final(e){if(this.destroyed)return;this.flushHeaders();let t=()=>{if(this._mustNotHaveABody){e();return}this._request.end(e)};this._request?t():this[Pd].push(t)}abort(){this.res&&this.res.complete||(this.aborted||process.nextTick(()=>this.emit("abort")),this.aborted=!0,this.destroy())}_destroy(e,t){this.res&&this.res._dump(),this._request&&this._request.destroy(),t(e)}async flushHeaders(){if(this[kw]||this.destroyed)return;this[kw]=!0;let e=this.method===zxe,t=i=>{if(this._request=i,this.destroyed){i.destroy();return}e||jxe(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 Uxe(this.socket,i.readableHighWaterMark);this.res=c,c.req=this,c.statusCode=o[ez],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[ez]}))),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[Pd])o();this.emit("socket",this.socket)};if(this[$k])try{t(this[$k].request(this[Wi]))}catch(i){this.emit("error",i)}else{this.reusedSocket=!0;try{t(await this.agent.request(this[Zk],this[iz],this[Wi]))}catch(i){this.emit("error",i)}}}getHeader(e){if(typeof e!="string")throw new Xk("name","string",e);return this[Wi][e.toLowerCase()]}get headersSent(){return this[kw]}removeHeader(e){if(typeof e!="string")throw new Xk("name","string",e);if(this.headersSent)throw new $8("remove");delete this[Wi][e.toLowerCase()]}setHeader(e,t){if(this.headersSent)throw new $8("set");if(typeof e!="string"||!_xe.test(e)&&!Gxe(e))throw new qxe("Header name",e);if(typeof t=="undefined")throw new Jxe(t,e);if(Vxe.test(t))throw new Wxe("header content",e);this[Wi][e.toLowerCase()]=t}setNoDelay(){}setSocketKeepAlive(){}setTimeout(e,t){let i=()=>this._request.setTimeout(e,t);return this._request?i():this[Pd].push(i),this}get maxHeadersCount(){if(!this.destroyed&&this._request)return this._request.session.localSettings.maxHeaderListSize}set maxHeadersCount(e){}};X8.exports=nz});var oz=w((wnt,sz)=>{"use strict";var Xxe=require("tls");sz.exports=(r={})=>new Promise((e,t)=>{let i=Xxe.connect(r,()=>{r.resolveSocket?(i.off("error",t),e({alpnProtocol:i.alpnProtocol,socket:i})):(i.destroy(),e({alpnProtocol:i.alpnProtocol}))});i.on("error",t)})});var Az=w((Bnt,az)=>{"use strict";var Zxe=require("net");az.exports=r=>{let e=r.host,t=r.headers&&r.headers.host;return t&&(t.startsWith("[")?t.indexOf("]")===-1?e=t:e=t.slice(1,-1):e=t.split(":",1)[0]),Zxe.isIP(e)?"":e}});var uz=w((bnt,tP)=>{"use strict";var lz=require("http"),rP=require("https"),$xe=oz(),eke=Jk(),tke=eP(),rke=Az(),ike=Vk(),Pw=new eke({maxSize:100}),Dd=new Map,cz=(r,e,t)=>{e._httpMessage={shouldKeepAlive:!0};let i=()=>{r.emit("free",e,t)};e.on("free",i);let n=()=>{r.removeSocket(e,t)};e.on("close",n);let s=()=>{r.removeSocket(e,t),e.off("close",n),e.off("free",i),e.off("agentRemove",s)};e.on("agentRemove",s),r.emit("free",e,t)},nke=async r=>{let e=`${r.host}:${r.port}:${r.ALPNProtocols.sort()}`;if(!Pw.has(e)){if(Dd.has(e))return(await Dd.get(e)).alpnProtocol;let{path:t,agent:i}=r;r.path=r.socketPath;let n=$xe(r);Dd.set(e,n);try{let{socket:s,alpnProtocol:o}=await n;if(Pw.set(e,o),r.path=t,o==="h2")s.destroy();else{let{globalAgent:a}=rP,l=rP.Agent.prototype.createConnection;i?i.createConnection===l?cz(i,s,r):s.destroy():a.createConnection===l?cz(a,s,r):s.destroy()}return Dd.delete(e),o}catch(s){throw Dd.delete(e),s}}return Pw.get(e)};tP.exports=async(r,e,t)=>{if((typeof r=="string"||r instanceof URL)&&(r=ike(new URL(r))),typeof e=="function"&&(t=e,e=void 0),e=te(N(N({ALPNProtocols:["h2","http/1.1"]},r),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||rke(e),e.port=e.port||(i?443:80),e._defaultAgent=i?rP.globalAgent:lz.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 nke(e)==="h2"?(n&&(e.agent=n.http2),new tke(e,t)):lz.request(e,t)};tP.exports.protocolCache=Pw});var fz=w((Qnt,gz)=>{"use strict";var ske=require("http2"),oke=zk(),iP=eP(),ake=_k(),Ake=uz(),lke=(r,e,t)=>new iP(r,e,t),cke=(r,e,t)=>{let i=new iP(r,e,t);return i.end(),i};gz.exports=te(N(te(N({},ske),{ClientRequest:iP,IncomingMessage:ake}),oke),{request:lke,get:cke,auto:Ake})});var sP=w(nP=>{"use strict";Object.defineProperty(nP,"__esModule",{value:!0});var hz=iA();nP.default=r=>hz.default.nodeStream(r)&&hz.default.function_(r.getBoundary)});var mz=w(oP=>{"use strict";Object.defineProperty(oP,"__esModule",{value:!0});var pz=require("fs"),dz=require("util"),Cz=iA(),uke=sP(),gke=dz.promisify(pz.stat);oP.default=async(r,e)=>{if(e&&"content-length"in e)return Number(e["content-length"]);if(!r)return 0;if(Cz.default.string(r))return Buffer.byteLength(r);if(Cz.default.buffer(r))return r.length;if(uke.default(r))return dz.promisify(r.getLength.bind(r))();if(r instanceof pz.ReadStream){let{size:t}=await gke(r.path);return t===0?void 0:t}}});var AP=w(aP=>{"use strict";Object.defineProperty(aP,"__esModule",{value:!0});function fke(r,e,t){let i={};for(let n of t)i[n]=(...s)=>{e.emit(n,...s)},r.on(n,i[n]);return()=>{for(let n of t)r.off(n,i[n])}}aP.default=fke});var Ez=w(lP=>{"use strict";Object.defineProperty(lP,"__esModule",{value:!0});lP.default=()=>{let r=[];return{once(e,t,i){e.once(t,i),r.push({origin:e,event:t,fn:i})},unhandleAll(){for(let e of r){let{origin:t,event:i,fn:n}=e;t.removeListener(i,n)}r.length=0}}}});var yz=w(Rd=>{"use strict";Object.defineProperty(Rd,"__esModule",{value:!0});Rd.TimeoutError=void 0;var hke=require("net"),pke=Ez(),Iz=Symbol("reentry"),dke=()=>{},cP=class extends Error{constructor(e,t){super(`Timeout awaiting '${t}' for ${e}ms`);this.event=t,this.name="TimeoutError",this.code="ETIMEDOUT"}};Rd.TimeoutError=cP;Rd.default=(r,e,t)=>{if(Iz in r)return dke;r[Iz]=!0;let i=[],{once:n,unhandleAll:s}=pke.default(),o=(g,f,h)=>{var p;let m=setTimeout(f,g,g,h);(p=m.unref)===null||p===void 0||p.call(m);let y=()=>{clearTimeout(m)};return i.push(y),y},{host:a,hostname:l}=t,c=(g,f)=>{r.destroy(new cP(g,f))},u=()=>{for(let g of i)g();s()};if(r.once("error",g=>{if(u(),r.listenerCount("error")===0)throw g}),r.once("close",u),n(r,"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")};r.setTimeout(e.socket,g),i.push(()=>{r.removeListener("timeout",g)})}return n(r,"socket",g=>{var f;let{socketPath:h}=r;if(g.connecting){let p=Boolean(h!=null?h:hke.isIP((f=l!=null?l:a)!==null&&f!==void 0?f:"")!==0);if(typeof e.lookup!="undefined"&&!p&&typeof g.address().address=="undefined"){let m=o(e.lookup,c,"lookup");n(g,"lookup",m)}if(typeof e.connect!="undefined"){let m=()=>o(e.connect,c,"connect");p?n(g,"connect",m()):n(g,"lookup",y=>{y===null&&n(g,"connect",m())})}typeof e.secureConnect!="undefined"&&t.protocol==="https:"&&n(g,"connect",()=>{let m=o(e.secureConnect,c,"secureConnect");n(g,"secureConnect",m)})}if(typeof e.send!="undefined"){let p=()=>o(e.send,c,"send");g.connecting?n(g,"connect",()=>{n(r,"upload-complete",p())}):n(r,"upload-complete",p())}}),typeof e.response!="undefined"&&n(r,"upload-complete",()=>{let g=o(e.response,c,"response");n(r,"response",g)}),u}});var Bz=w(uP=>{"use strict";Object.defineProperty(uP,"__esModule",{value:!0});var wz=iA();uP.default=r=>{r=r;let e={protocol:r.protocol,hostname:wz.default.string(r.hostname)&&r.hostname.startsWith("[")?r.hostname.slice(1,-1):r.hostname,host:r.host,hash:r.hash,search:r.search,pathname:r.pathname,href:r.href,path:`${r.pathname||""}${r.search||""}`};return wz.default.string(r.port)&&r.port.length>0&&(e.port=Number(r.port)),(r.username||r.password)&&(e.auth=`${r.username||""}:${r.password||""}`),e}});var bz=w(gP=>{"use strict";Object.defineProperty(gP,"__esModule",{value:!0});var Cke=require("url"),mke=["protocol","host","hostname","port","pathname","search"];gP.default=(r,e)=>{var t,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(!r){if(!e.protocol)throw new TypeError("No URL protocol specified");r=`${e.protocol}//${(i=(t=e.hostname)!==null&&t!==void 0?t:e.host)!==null&&i!==void 0?i:""}`}let n=new Cke.URL(r);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 mke)e[s]&&(n[s]=e[s].toString());return n}});var Sz=w(fP=>{"use strict";Object.defineProperty(fP,"__esModule",{value:!0});var Qz=class{constructor(){this.weakMap=new WeakMap,this.map=new Map}set(e,t){typeof e=="object"?this.weakMap.set(e,t):this.map.set(e,t)}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)}};fP.default=Qz});var pP=w(hP=>{"use strict";Object.defineProperty(hP,"__esModule",{value:!0});var Eke=async r=>{let e=[],t=0;for await(let i of r)e.push(i),t+=Buffer.byteLength(i);return Buffer.isBuffer(e[0])?Buffer.concat(e,t):Buffer.from(e.join(""))};hP.default=Eke});var xz=w(Vc=>{"use strict";Object.defineProperty(Vc,"__esModule",{value:!0});Vc.dnsLookupIpVersionToFamily=Vc.isDnsLookupIpVersion=void 0;var vz={auto:0,ipv4:4,ipv6:6};Vc.isDnsLookupIpVersion=r=>r in vz;Vc.dnsLookupIpVersionToFamily=r=>{if(Vc.isDnsLookupIpVersion(r))return vz[r];throw new Error("Invalid DNS lookup IP version")}});var dP=w(Dw=>{"use strict";Object.defineProperty(Dw,"__esModule",{value:!0});Dw.isResponseOk=void 0;Dw.isResponseOk=r=>{let{statusCode:e}=r,t=r.request.options.followRedirect?299:399;return e>=200&&e<=t||e===304}});var Pz=w(CP=>{"use strict";Object.defineProperty(CP,"__esModule",{value:!0});var kz=new Set;CP.default=r=>{kz.has(r)||(kz.add(r),process.emitWarning(`Got: ${r}`,{type:"DeprecationWarning"}))}});var Dz=w(mP=>{"use strict";Object.defineProperty(mP,"__esModule",{value:!0});var Ir=iA(),Ike=(r,e)=>{if(Ir.default.null_(r.encoding))throw new TypeError("To get a Buffer, set `options.responseType` to `buffer` instead");Ir.assert.any([Ir.default.string,Ir.default.undefined],r.encoding),Ir.assert.any([Ir.default.boolean,Ir.default.undefined],r.resolveBodyOnly),Ir.assert.any([Ir.default.boolean,Ir.default.undefined],r.methodRewriting),Ir.assert.any([Ir.default.boolean,Ir.default.undefined],r.isStream),Ir.assert.any([Ir.default.string,Ir.default.undefined],r.responseType),r.responseType===void 0&&(r.responseType="text");let{retry:t}=r;if(e?r.retry=N({},e.retry):r.retry={calculateDelay:i=>i.computedValue,limit:0,methods:[],statusCodes:[],errorCodes:[],maxRetryAfter:void 0},Ir.default.object(t)?(r.retry=N(N({},r.retry),t),r.retry.methods=[...new Set(r.retry.methods.map(i=>i.toUpperCase()))],r.retry.statusCodes=[...new Set(r.retry.statusCodes)],r.retry.errorCodes=[...new Set(r.retry.errorCodes)]):Ir.default.number(t)&&(r.retry.limit=t),Ir.default.undefined(r.retry.maxRetryAfter)&&(r.retry.maxRetryAfter=Math.min(...[r.timeout.request,r.timeout.connect].filter(Ir.default.number))),Ir.default.object(r.pagination)){e&&(r.pagination=N(N({},e.pagination),r.pagination));let{pagination:i}=r;if(!Ir.default.function_(i.transform))throw new Error("`options.pagination.transform` must be implemented");if(!Ir.default.function_(i.shouldContinue))throw new Error("`options.pagination.shouldContinue` must be implemented");if(!Ir.default.function_(i.filter))throw new TypeError("`options.pagination.filter` must be implemented");if(!Ir.default.function_(i.paginate))throw new Error("`options.pagination.paginate` must be implemented")}return r.responseType==="json"&&r.headers.accept===void 0&&(r.headers.accept="application/json"),r};mP.default=Ike});var Rz=w(Fd=>{"use strict";Object.defineProperty(Fd,"__esModule",{value:!0});Fd.retryAfterStatusCodes=void 0;Fd.retryAfterStatusCodes=new Set([413,429,503]);var yke=({attemptCount:r,retryOptions:e,error:t,retryAfter:i})=>{if(r>e.limit)return 0;let n=e.methods.includes(t.options.method),s=e.errorCodes.includes(t.code),o=t.response&&e.statusCodes.includes(t.response.statusCode);if(!n||!s&&!o)return 0;if(t.response){if(i)return e.maxRetryAfter===void 0||i>e.maxRetryAfter?0:i;if(t.response.statusCode===413)return 0}let a=Math.random()*100;return 2**(r-1)*1e3+a};Fd.default=yke});var Ld=w(qt=>{"use strict";Object.defineProperty(qt,"__esModule",{value:!0});qt.UnsupportedProtocolError=qt.ReadError=qt.TimeoutError=qt.UploadError=qt.CacheError=qt.HTTPError=qt.MaxRedirectsError=qt.RequestError=qt.setNonEnumerableProperties=qt.knownHookEvents=qt.withoutBody=qt.kIsNormalizedAlready=void 0;var Fz=require("util"),Nz=require("stream"),wke=require("fs"),gl=require("url"),Lz=require("http"),EP=require("http"),Bke=require("https"),bke=Y4(),Qke=X4(),Tz=D8(),Ske=L8(),vke=fz(),xke=vw(),Ee=iA(),kke=mz(),Oz=sP(),Pke=AP(),Mz=yz(),Dke=Bz(),Kz=bz(),Rke=Sz(),Fke=pP(),Uz=xz(),Nke=dP(),fl=Pz(),Lke=Dz(),Tke=Rz(),IP,Fi=Symbol("request"),Rw=Symbol("response"),rf=Symbol("responseSize"),nf=Symbol("downloadedSize"),sf=Symbol("bodySize"),of=Symbol("uploadedSize"),Fw=Symbol("serverResponsesPiped"),Hz=Symbol("unproxyEvents"),jz=Symbol("isFromCache"),yP=Symbol("cancelTimeouts"),Gz=Symbol("startedReading"),af=Symbol("stopReading"),Nw=Symbol("triggerRead"),hl=Symbol("body"),Nd=Symbol("jobs"),Yz=Symbol("originalResponse"),qz=Symbol("retryTimeout");qt.kIsNormalizedAlready=Symbol("isNormalizedAlready");var Oke=Ee.default.string(process.versions.brotli);qt.withoutBody=new Set(["GET","HEAD"]);qt.knownHookEvents=["init","beforeRequest","beforeRedirect","beforeError","beforeRetry","afterResponse"];function Mke(r){for(let e in r){let t=r[e];if(!Ee.default.string(t)&&!Ee.default.number(t)&&!Ee.default.boolean(t)&&!Ee.default.null_(t)&&!Ee.default.undefined(t))throw new TypeError(`The \`searchParams\` value '${String(t)}' must be a string, number, boolean or null`)}}function Kke(r){return Ee.default.object(r)&&!("statusCode"in r)}var wP=new Rke.default,Uke=async r=>new Promise((e,t)=>{let i=n=>{t(n)};r.pending||e(),r.once("error",i),r.once("ready",()=>{r.off("error",i),e()})}),Hke=new Set([300,301,302,303,304,307,308]),jke=["context","body","json","form"];qt.setNonEnumerableProperties=(r,e)=>{let t={};for(let i of r)if(!!i)for(let n of jke)n in i&&(t[n]={writable:!0,configurable:!0,enumerable:!1,value:i[n]});Object.defineProperties(e,t)};var hi=class extends Error{constructor(e,t,i){var n;super(e);if(Error.captureStackTrace(this,this.constructor),this.name="RequestError",this.code=t.code,i instanceof BP?(Object.defineProperty(this,"request",{enumerable:!1,value:i}),Object.defineProperty(this,"response",{enumerable:!1,value:i[Rw]}),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,Ee.default.string(t.stack)&&Ee.default.string(this.stack)){let s=this.stack.indexOf(this.message)+this.message.length,o=this.stack.slice(s).split(` -`).reverse(),a=t.stack.slice(t.stack.indexOf(t.message)+t.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(` -`)}`}}};qt.RequestError=hi;var bP=class extends hi{constructor(e){super(`Redirected ${e.options.maxRedirects} times. Aborting.`,{},e);this.name="MaxRedirectsError"}};qt.MaxRedirectsError=bP;var QP=class extends hi{constructor(e){super(`Response code ${e.statusCode} (${e.statusMessage})`,{},e.request);this.name="HTTPError"}};qt.HTTPError=QP;var SP=class extends hi{constructor(e,t){super(e.message,e,t);this.name="CacheError"}};qt.CacheError=SP;var vP=class extends hi{constructor(e,t){super(e.message,e,t);this.name="UploadError"}};qt.UploadError=vP;var xP=class extends hi{constructor(e,t,i){super(e.message,e,i);this.name="TimeoutError",this.event=e.event,this.timings=t}};qt.TimeoutError=xP;var Lw=class extends hi{constructor(e,t){super(e.message,e,t);this.name="ReadError"}};qt.ReadError=Lw;var kP=class extends hi{constructor(e){super(`Unsupported protocol "${e.url.protocol}"`,{},e);this.name="UnsupportedProtocolError"}};qt.UnsupportedProtocolError=kP;var Gke=["socket","connect","continue","information","upgrade","timeout"],BP=class extends Nz.Duplex{constructor(e,t={},i){super({autoDestroy:!1,highWaterMark:0});this[nf]=0,this[of]=0,this.requestInitialized=!1,this[Fw]=new Set,this.redirects=[],this[af]=!1,this[Nw]=!1,this[Nd]=[],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 EP.IncomingMessage&&(this.options.headers=N(N({},c.headers),this.options.headers))});let{json:o,body:a,form:l}=t;if((o||a||l)&&this._lockWrite(),qt.kIsNormalizedAlready in t)this.options=t;else try{this.options=this.constructor.normalizeArguments(e,t,i)}catch(c){Ee.default.nodeStream(t.body)&&t.body.destroy(),this.destroy(c);return}(async()=>{var c;try{this.options.body instanceof wke.ReadStream&&await Uke(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[Fi])===null||c===void 0||c.destroy();return}for(let g of this[Nd])g();this[Nd].length=0,this.requestInitialized=!0}catch(u){if(u instanceof hi){this._beforeError(u);return}this.destroyed||this.destroy(u)}})()}static normalizeArguments(e,t,i){var n,s,o,a,l;let c=t;if(Ee.default.object(e)&&!Ee.default.urlInstance(e))t=N(N(N({},i),e),t);else{if(e&&t&&t.url!==void 0)throw new TypeError("The `url` option is mutually exclusive with the `input` argument");t=N(N({},i),t),e!==void 0&&(t.url=e),Ee.default.urlInstance(t.url)&&(t.url=new gl.URL(t.url.toString()))}if(t.cache===!1&&(t.cache=void 0),t.dnsCache===!1&&(t.dnsCache=void 0),Ee.assert.any([Ee.default.string,Ee.default.undefined],t.method),Ee.assert.any([Ee.default.object,Ee.default.undefined],t.headers),Ee.assert.any([Ee.default.string,Ee.default.urlInstance,Ee.default.undefined],t.prefixUrl),Ee.assert.any([Ee.default.object,Ee.default.undefined],t.cookieJar),Ee.assert.any([Ee.default.object,Ee.default.string,Ee.default.undefined],t.searchParams),Ee.assert.any([Ee.default.object,Ee.default.string,Ee.default.undefined],t.cache),Ee.assert.any([Ee.default.object,Ee.default.number,Ee.default.undefined],t.timeout),Ee.assert.any([Ee.default.object,Ee.default.undefined],t.context),Ee.assert.any([Ee.default.object,Ee.default.undefined],t.hooks),Ee.assert.any([Ee.default.boolean,Ee.default.undefined],t.decompress),Ee.assert.any([Ee.default.boolean,Ee.default.undefined],t.ignoreInvalidCookies),Ee.assert.any([Ee.default.boolean,Ee.default.undefined],t.followRedirect),Ee.assert.any([Ee.default.number,Ee.default.undefined],t.maxRedirects),Ee.assert.any([Ee.default.boolean,Ee.default.undefined],t.throwHttpErrors),Ee.assert.any([Ee.default.boolean,Ee.default.undefined],t.http2),Ee.assert.any([Ee.default.boolean,Ee.default.undefined],t.allowGetBody),Ee.assert.any([Ee.default.string,Ee.default.undefined],t.localAddress),Ee.assert.any([Uz.isDnsLookupIpVersion,Ee.default.undefined],t.dnsLookupIpVersion),Ee.assert.any([Ee.default.object,Ee.default.undefined],t.https),Ee.assert.any([Ee.default.boolean,Ee.default.undefined],t.rejectUnauthorized),t.https&&(Ee.assert.any([Ee.default.boolean,Ee.default.undefined],t.https.rejectUnauthorized),Ee.assert.any([Ee.default.function_,Ee.default.undefined],t.https.checkServerIdentity),Ee.assert.any([Ee.default.string,Ee.default.object,Ee.default.array,Ee.default.undefined],t.https.certificateAuthority),Ee.assert.any([Ee.default.string,Ee.default.object,Ee.default.array,Ee.default.undefined],t.https.key),Ee.assert.any([Ee.default.string,Ee.default.object,Ee.default.array,Ee.default.undefined],t.https.certificate),Ee.assert.any([Ee.default.string,Ee.default.undefined],t.https.passphrase),Ee.assert.any([Ee.default.string,Ee.default.buffer,Ee.default.array,Ee.default.undefined],t.https.pfx)),Ee.assert.any([Ee.default.object,Ee.default.undefined],t.cacheOptions),Ee.default.string(t.method)?t.method=t.method.toUpperCase():t.method="GET",t.headers===(i==null?void 0:i.headers)?t.headers=N({},t.headers):t.headers=xke(N(N({},i==null?void 0:i.headers),t.headers)),"slashes"in t)throw new TypeError("The legacy `url.Url` has been deprecated. Use `URL` instead.");if("auth"in t)throw new TypeError("Parameter `auth` is deprecated. Use `username` / `password` instead.");if("searchParams"in t&&t.searchParams&&t.searchParams!==(i==null?void 0:i.searchParams)){let h;if(Ee.default.string(t.searchParams)||t.searchParams instanceof gl.URLSearchParams)h=new gl.URLSearchParams(t.searchParams);else{Mke(t.searchParams),h=new gl.URLSearchParams;for(let p in t.searchParams){let m=t.searchParams[p];m===null?h.append(p,""):m!==void 0&&h.append(p,m)}}(n=i==null?void 0:i.searchParams)===null||n===void 0||n.forEach((p,m)=>{h.has(m)||h.append(m,p)}),t.searchParams=h}if(t.username=(s=t.username)!==null&&s!==void 0?s:"",t.password=(o=t.password)!==null&&o!==void 0?o:"",Ee.default.undefined(t.prefixUrl)?t.prefixUrl=(a=i==null?void 0:i.prefixUrl)!==null&&a!==void 0?a:"":(t.prefixUrl=t.prefixUrl.toString(),t.prefixUrl!==""&&!t.prefixUrl.endsWith("/")&&(t.prefixUrl+="/")),Ee.default.string(t.url)){if(t.url.startsWith("/"))throw new Error("`input` must not start with a slash when using `prefixUrl`");t.url=Kz.default(t.prefixUrl+t.url,t)}else(Ee.default.undefined(t.url)&&t.prefixUrl!==""||t.protocol)&&(t.url=Kz.default(t.prefixUrl,t));if(t.url){"port"in t&&delete t.port;let{prefixUrl:h}=t;Object.defineProperty(t,"prefixUrl",{set:m=>{let y=t.url;if(!y.href.startsWith(m))throw new Error(`Cannot change \`prefixUrl\` from ${h} to ${m}: ${y.href}`);t.url=new gl.URL(m+y.href.slice(h.length)),h=m},get:()=>h});let{protocol:p}=t.url;if(p==="unix:"&&(p="http:",t.url=new gl.URL(`http://unix${t.url.pathname}${t.url.search}`)),t.searchParams&&(t.url.search=t.searchParams.toString()),p!=="http:"&&p!=="https:")throw new kP(t);t.username===""?t.username=t.url.username:t.url.username=t.username,t.password===""?t.password=t.url.password:t.url.password=t.password}let{cookieJar:u}=t;if(u){let{setCookie:h,getCookieString:p}=u;Ee.assert.function_(h),Ee.assert.function_(p),h.length===4&&p.length===0&&(h=Fz.promisify(h.bind(t.cookieJar)),p=Fz.promisify(p.bind(t.cookieJar)),t.cookieJar={setCookie:h,getCookieString:p})}let{cache:g}=t;if(g&&(wP.has(g)||wP.set(g,new Tz((h,p)=>{let m=h[Fi](h,p);return Ee.default.promise(m)&&(m.once=(y,b)=>{if(y==="error")m.catch(b);else if(y==="abort")(async()=>{try{(await m).once("abort",b)}catch(v){}})();else throw new Error(`Unknown HTTP2 promise event: ${y}`);return m}),m},g))),t.cacheOptions=N({},t.cacheOptions),t.dnsCache===!0)IP||(IP=new Qke.default),t.dnsCache=IP;else if(!Ee.default.undefined(t.dnsCache)&&!t.dnsCache.lookup)throw new TypeError(`Parameter \`dnsCache\` must be a CacheableLookup instance or a boolean, got ${Ee.default(t.dnsCache)}`);Ee.default.number(t.timeout)?t.timeout={request:t.timeout}:i&&t.timeout!==i.timeout?t.timeout=N(N({},i.timeout),t.timeout):t.timeout=N({},t.timeout),t.context||(t.context={});let f=t.hooks===(i==null?void 0:i.hooks);t.hooks=N({},t.hooks);for(let h of qt.knownHookEvents)if(h in t.hooks)if(Ee.default.array(t.hooks[h]))t.hooks[h]=[...t.hooks[h]];else throw new TypeError(`Parameter \`${h}\` must be an Array, got ${Ee.default(t.hooks[h])}`);else t.hooks[h]=[];if(i&&!f)for(let h of qt.knownHookEvents)i.hooks[h].length>0&&(t.hooks[h]=[...i.hooks[h],...t.hooks[h]]);if("family"in t&&fl.default('"options.family" was never documented, please use "options.dnsLookupIpVersion"'),(i==null?void 0:i.https)&&(t.https=N(N({},i.https),t.https)),"rejectUnauthorized"in t&&fl.default('"options.rejectUnauthorized" is now deprecated, please use "options.https.rejectUnauthorized"'),"checkServerIdentity"in t&&fl.default('"options.checkServerIdentity" was never documented, please use "options.https.checkServerIdentity"'),"ca"in t&&fl.default('"options.ca" was never documented, please use "options.https.certificateAuthority"'),"key"in t&&fl.default('"options.key" was never documented, please use "options.https.key"'),"cert"in t&&fl.default('"options.cert" was never documented, please use "options.https.certificate"'),"passphrase"in t&&fl.default('"options.passphrase" was never documented, please use "options.https.passphrase"'),"pfx"in t&&fl.default('"options.pfx" was never documented, please use "options.https.pfx"'),"followRedirects"in t)throw new TypeError("The `followRedirects` option does not exist. Use `followRedirect` instead.");if(t.agent){for(let h in t.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 t.maxRedirects=(l=t.maxRedirects)!==null&&l!==void 0?l:0,qt.setNonEnumerableProperties([i,c],t),Lke.default(t,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:t}=e,i=!Ee.default.undefined(e.form),n=!Ee.default.undefined(e.json),s=!Ee.default.undefined(e.body),o=i||n||s,a=qt.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 Nz.Readable)&&!Ee.default.string(e.body)&&!Ee.default.buffer(e.body)&&!Oz.default(e.body))throw new TypeError("The `body` option must be a stream.Readable, string or Buffer");if(i&&!Ee.default.object(e.form))throw new TypeError("The `form` option must be an Object");{let l=!Ee.default.string(t["content-type"]);s?(Oz.default(e.body)&&l&&(t["content-type"]=`multipart/form-data; boundary=${e.body.getBoundary()}`),this[hl]=e.body):i?(l&&(t["content-type"]="application/x-www-form-urlencoded"),this[hl]=new gl.URLSearchParams(e.form).toString()):(l&&(t["content-type"]="application/json"),this[hl]=e.stringifyJson(e.json));let c=await kke.default(this[hl],e.headers);Ee.default.undefined(t["content-length"])&&Ee.default.undefined(t["transfer-encoding"])&&!a&&!Ee.default.undefined(c)&&(t["content-length"]=String(c))}}else a?this._lockWrite():this._unlockWrite();this[sf]=Number(t["content-length"])||void 0}async _onResponseBase(e){let{options:t}=this,{url:i}=t;this[Yz]=e,t.decompress&&(e=Ske(e));let n=e.statusCode,s=e;s.statusMessage=s.statusMessage?s.statusMessage:Lz.STATUS_CODES[n],s.url=t.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[jz]=s.isFromCache,this[rf]=Number(e.headers["content-length"])||void 0,this[Rw]=e,e.once("end",()=>{this[rf]=this[nf],this.emit("downloadProgress",this.downloadProgress)}),e.once("error",a=>{e.destroy(),this._beforeError(new Lw(a,this))}),e.once("aborted",()=>{this._beforeError(new Lw({name:"Error",message:"The server aborted pending request",code:"ECONNRESET"},this))}),this.emit("downloadProgress",this.downloadProgress);let o=e.headers["set-cookie"];if(Ee.default.object(t.cookieJar)&&o){let a=o.map(async l=>t.cookieJar.setCookie(l,i.toString()));t.ignoreInvalidCookies&&(a=a.map(async l=>l.catch(()=>{})));try{await Promise.all(a)}catch(l){this._beforeError(l);return}}if(t.followRedirect&&e.headers.location&&Hke.has(n)){if(e.resume(),this[Fi]&&(this[yP](),delete this[Fi],this[Hz]()),(n===303&&t.method!=="GET"&&t.method!=="HEAD"||!t.methodRewriting)&&(t.method="GET","body"in t&&delete t.body,"json"in t&&delete t.json,"form"in t&&delete t.form,this[hl]=void 0,delete t.headers["content-length"]),this.redirects.length>=t.maxRedirects){this._beforeError(new bP(this));return}try{let l=Buffer.from(e.headers.location,"binary").toString(),c=new gl.URL(l,i),u=c.toString();decodeURI(u),c.hostname!==i.hostname||c.port!==i.port?("host"in t.headers&&delete t.headers.host,"cookie"in t.headers&&delete t.headers.cookie,"authorization"in t.headers&&delete t.headers.authorization,(t.username||t.password)&&(t.username="",t.password="")):(c.username=t.username,c.password=t.password),this.redirects.push(u),t.url=c;for(let g of t.hooks.beforeRedirect)await g(t,s);this.emit("redirect",s,t),await this._makeRequest()}catch(l){this._beforeError(l);return}return}if(t.isStream&&t.throwHttpErrors&&!Nke.isResponseOk(s)){this._beforeError(new QP(s));return}e.on("readable",()=>{this[Nw]&&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[Fw])if(!a.headersSent){for(let l in e.headers){let c=t.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(t){this._beforeError(t)}}_onRequest(e){let{options:t}=this,{timeout:i,url:n}=t;bke.default(e),this[yP]=Mz.default(e,i,n);let s=t.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 Mz.TimeoutError?new xP(l,this.timings,this):new hi(l.message,l,this),this._beforeError(l)}),this[Hz]=Pke.default(e,this,Gke),this[Fi]=e,this.emit("uploadProgress",this.uploadProgress);let o=this[hl],a=this.redirects.length===0?this:e;Ee.default.nodeStream(o)?(o.pipe(a),o.once("error",l=>{this._beforeError(new vP(l,this))})):(this._unlockWrite(),Ee.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,t){return new Promise((i,n)=>{Object.assign(t,Dke.default(e)),delete t.url;let s,o=wP.get(t.cache)(t,async a=>{a._readableState.autoDestroy=!1,s&&(await s).emit("cacheableResponse",a),i(a)});t.url=e,o.once("error",n),o.once("request",async a=>{s=a,i(s)})})}async _makeRequest(){var e,t,i,n,s;let{options:o}=this,{headers:a}=o;for(let b in a)if(Ee.default.undefined(a[b]))delete a[b];else if(Ee.default.null_(a[b]))throw new TypeError(`Use \`undefined\` instead of \`null\` to delete the \`${b}\` header`);if(o.decompress&&Ee.default.undefined(a["accept-encoding"])&&(a["accept-encoding"]=Oke?"gzip, deflate, br":"gzip, deflate"),o.cookieJar){let b=await o.cookieJar.getCookieString(o.url.toString());Ee.default.nonEmptyString(b)&&(o.headers.cookie=b)}for(let b of o.hooks.beforeRequest){let v=await b(o);if(!Ee.default.undefined(v)){o.request=()=>v;break}}o.body&&this[hl]!==o.body&&(this[hl]=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 b=/(?.+?):(?.+)/.exec(`${g.pathname}${g.search}`);if(b==null?void 0:b.groups){let{socketPath:v,path:x}=b.groups;Object.assign(o,{socketPath:v,path:x,host:""})}}let f=g.protocol==="https:",h;o.http2?h=vke.auto:h=f?Bke.request:Lz.request;let p=(e=o.request)!==null&&e!==void 0?e:h,m=o.cache?this._createCacheableRequest:p;l&&!o.http2&&(o.agent=l[f?"https":"http"]),o[Fi]=p,delete o.request,delete o.timeout;let y=o;if(y.shared=(t=o.cacheOptions)===null||t===void 0?void 0:t.shared,y.cacheHeuristic=(i=o.cacheOptions)===null||i===void 0?void 0:i.cacheHeuristic,y.immutableMinTimeToLive=(n=o.cacheOptions)===null||n===void 0?void 0:n.immutableMinTimeToLive,y.ignoreCargoCult=(s=o.cacheOptions)===null||s===void 0?void 0:s.ignoreCargoCult,o.dnsLookupIpVersion!==void 0)try{y.family=Uz.dnsLookupIpVersionToFamily(o.dnsLookupIpVersion)}catch(b){throw new Error("Invalid `dnsLookupIpVersion` option value")}o.https&&("rejectUnauthorized"in o.https&&(y.rejectUnauthorized=o.https.rejectUnauthorized),o.https.checkServerIdentity&&(y.checkServerIdentity=o.https.checkServerIdentity),o.https.certificateAuthority&&(y.ca=o.https.certificateAuthority),o.https.certificate&&(y.cert=o.https.certificate),o.https.key&&(y.key=o.https.key),o.https.passphrase&&(y.passphrase=o.https.passphrase),o.https.pfx&&(y.pfx=o.https.pfx));try{let b=await m(g,y);Ee.default.undefined(b)&&(b=h(g,y)),o.request=c,o.timeout=u,o.agent=l,o.https&&("rejectUnauthorized"in o.https&&delete y.rejectUnauthorized,o.https.checkServerIdentity&&delete y.checkServerIdentity,o.https.certificateAuthority&&delete y.ca,o.https.certificate&&delete y.cert,o.https.key&&delete y.key,o.https.passphrase&&delete y.passphrase,o.https.pfx&&delete y.pfx),Kke(b)?this._onRequest(b):this.writable?(this.once("finish",()=>{this._onResponse(b)}),this._unlockWrite(),this.end(),this._lockWrite()):this._onResponse(b)}catch(b){throw b instanceof Tz.CacheError?new SP(b,this):new hi(b.message,b,this)}}async _error(e){try{for(let t of this.options.hooks.beforeError)e=await t(e)}catch(t){e=new hi(t.message,t,this)}this.destroy(e)}_beforeError(e){if(this[af])return;let{options:t}=this,i=this.retryCount+1;this[af]=!0,e instanceof hi||(e=new hi(e.message,e,this));let n=e,{response:s}=n;(async()=>{if(s&&!s.body){s.setEncoding(this._readableState.encoding);try{s.rawBody=await Fke.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 t.retry.calculateDelay({attemptCount:i,retryOptions:t.retry,error:n,retryAfter:a,computedValue:Tke.default({attemptCount:i,retryOptions:t.retry,error:n,retryAfter:a,computedValue:0})})}catch(a){this._error(new hi(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 hi(l.message,e,this));return}this.destroyed||(this.destroy(),this.emit("retry",i,e))};this[qz]=setTimeout(a,o);return}}this._error(n)})()}_read(){this[Nw]=!0;let e=this[Rw];if(e&&!this[af]){e.readableLength&&(this[Nw]=!1);let t;for(;(t=e.read())!==null;){this[nf]+=t.length,this[Gz]=!0;let i=this.downloadProgress;i.percent<1&&this.emit("downloadProgress",i),this.push(t)}}}_write(e,t,i){let n=()=>{this._writeRequest(e,t,i)};this.requestInitialized?n():this[Nd].push(n)}_writeRequest(e,t,i){this[Fi].destroyed||(this._progressCallbacks.push(()=>{this[of]+=Buffer.byteLength(e,t);let n=this.uploadProgress;n.percent<1&&this.emit("uploadProgress",n)}),this[Fi].write(e,t,n=>{!n&&this._progressCallbacks.length>0&&this._progressCallbacks.shift()(),i(n)}))}_final(e){let t=()=>{for(;this._progressCallbacks.length!==0;)this._progressCallbacks.shift()();if(!(Fi in this)){e();return}if(this[Fi].destroyed){e();return}this[Fi].end(i=>{i||(this[sf]=this[of],this.emit("uploadProgress",this.uploadProgress),this[Fi].emit("upload-complete")),e(i)})};this.requestInitialized?t():this[Nd].push(t)}_destroy(e,t){var i;this[af]=!0,clearTimeout(this[qz]),Fi in this&&(this[yP](),((i=this[Rw])===null||i===void 0?void 0:i.complete)||this[Fi].destroy()),e!==null&&!Ee.default.undefined(e)&&!(e instanceof hi)&&(e=new hi(e.message,e,this)),t(e)}get _isAboutToError(){return this[af]}get ip(){var e;return(e=this.socket)===null||e===void 0?void 0:e.remoteAddress}get aborted(){var e,t,i;return((t=(e=this[Fi])===null||e===void 0?void 0:e.destroyed)!==null&&t!==void 0?t:this.destroyed)&&!((i=this[Yz])===null||i===void 0?void 0:i.complete)}get socket(){var e,t;return(t=(e=this[Fi])===null||e===void 0?void 0:e.socket)!==null&&t!==void 0?t:void 0}get downloadProgress(){let e;return this[rf]?e=this[nf]/this[rf]:this[rf]===this[nf]?e=1:e=0,{percent:e,transferred:this[nf],total:this[rf]}}get uploadProgress(){let e;return this[sf]?e=this[of]/this[sf]:this[sf]===this[of]?e=1:e=0,{percent:e,transferred:this[of],total:this[sf]}}get timings(){var e;return(e=this[Fi])===null||e===void 0?void 0:e.timings}get isFromCache(){return this[jz]}pipe(e,t){if(this[Gz])throw new Error("Failed to pipe. The response has been emitted already.");return e instanceof EP.ServerResponse&&this[Fw].add(e),super.pipe(e,t)}unpipe(e){return e instanceof EP.ServerResponse&&this[Fw].delete(e),super.unpipe(e),this}};qt.default=BP});var Td=w(Co=>{"use strict";var Yke=Co&&Co.__createBinding||(Object.create?function(r,e,t,i){i===void 0&&(i=t),Object.defineProperty(r,i,{enumerable:!0,get:function(){return e[t]}})}:function(r,e,t,i){i===void 0&&(i=t),r[i]=e[t]}),qke=Co&&Co.__exportStar||function(r,e){for(var t in r)t!=="default"&&!Object.prototype.hasOwnProperty.call(e,t)&&Yke(e,r,t)};Object.defineProperty(Co,"__esModule",{value:!0});Co.CancelError=Co.ParseError=void 0;var Jz=Ld(),Wz=class extends Jz.RequestError{constructor(e,t){let{options:i}=t.request;super(`${e.message} in "${i.url.toString()}"`,e,t.request);this.name="ParseError"}};Co.ParseError=Wz;var zz=class extends Jz.RequestError{constructor(e){super("Promise was canceled",{},e);this.name="CancelError"}get isCanceled(){return!0}};Co.CancelError=zz;qke(Ld(),Co)});var Vz=w(PP=>{"use strict";Object.defineProperty(PP,"__esModule",{value:!0});var _z=Td(),Jke=(r,e,t,i)=>{let{rawBody:n}=r;try{if(e==="text")return n.toString(i);if(e==="json")return n.length===0?"":t(n.toString());if(e==="buffer")return n;throw new _z.ParseError({message:`Unknown body type '${e}'`,name:"Error"},r)}catch(s){throw new _z.ParseError(s,r)}};PP.default=Jke});var DP=w(pl=>{"use strict";var Wke=pl&&pl.__createBinding||(Object.create?function(r,e,t,i){i===void 0&&(i=t),Object.defineProperty(r,i,{enumerable:!0,get:function(){return e[t]}})}:function(r,e,t,i){i===void 0&&(i=t),r[i]=e[t]}),zke=pl&&pl.__exportStar||function(r,e){for(var t in r)t!=="default"&&!Object.prototype.hasOwnProperty.call(e,t)&&Wke(e,r,t)};Object.defineProperty(pl,"__esModule",{value:!0});var _ke=require("events"),Vke=iA(),Xke=j4(),Tw=Td(),Xz=Vz(),Zz=Ld(),Zke=AP(),$ke=pP(),$z=dP(),ePe=["request","response","redirect","uploadProgress","downloadProgress"];function e5(r){let e,t,i=new _ke.EventEmitter,n=new Xke((o,a,l)=>{let c=u=>{let g=new Zz.default(void 0,r);g.retryCount=u,g._noPipe=!0,l(()=>g.destroy()),l.shouldReject=!1,l(()=>a(new Tw.CancelError(g))),e=g,g.once("response",async p=>{var m;if(p.retryCount=u,p.request.aborted)return;let y;try{y=await $ke.default(g),p.rawBody=y}catch(T){return}if(g._isAboutToError)return;let b=((m=p.headers["content-encoding"])!==null&&m!==void 0?m:"").toLowerCase(),v=["gzip","deflate","br"].includes(b),{options:x}=g;if(v&&!x.decompress)p.body=y;else try{p.body=Xz.default(p,x.responseType,x.parseJson,x.encoding)}catch(T){if(p.body=y.toString(),$z.isResponseOk(p)){g._beforeError(T);return}}try{for(let[T,q]of x.hooks.afterResponse.entries())p=await q(p,async Y=>{let $=Zz.default.normalizeArguments(void 0,te(N({},Y),{retry:{calculateDelay:()=>0},throwHttpErrors:!1,resolveBodyOnly:!1}),x);$.hooks.afterResponse=$.hooks.afterResponse.slice(0,T);for(let ne of $.hooks.beforeRetry)await ne($);let _=e5($);return l(()=>{_.catch(()=>{}),_.cancel()}),_})}catch(T){g._beforeError(new Tw.RequestError(T.message,T,g));return}if(!$z.isResponseOk(p)){g._beforeError(new Tw.HTTPError(p));return}t=p,o(g.options.resolveBodyOnly?p.body:p)});let f=p=>{if(n.isCanceled)return;let{options:m}=g;if(p instanceof Tw.HTTPError&&!m.throwHttpErrors){let{response:y}=p;o(g.options.resolveBodyOnly?y.body:y);return}a(p)};g.once("error",f);let h=g.options.body;g.once("retry",(p,m)=>{var y,b;if(h===((y=m.request)===null||y===void 0?void 0:y.options.body)&&Vke.default.nodeStream((b=m.request)===null||b===void 0?void 0:b.options.body)){f(m);return}c(p)}),Zke.default(g,i,ePe)};c(0)});n.on=(o,a)=>(i.on(o,a),n);let s=o=>{let a=(async()=>{await n;let{options:l}=t.request;return Xz.default(t,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}pl.default=e5;zke(Td(),pl)});var t5=w(RP=>{"use strict";Object.defineProperty(RP,"__esModule",{value:!0});var tPe=Td();function rPe(r,...e){let t=(async()=>{if(r instanceof tPe.RequestError)try{for(let n of e)if(n)for(let s of n)r=await s(r)}catch(n){r=n}throw r})(),i=()=>t;return t.json=i,t.text=i,t.buffer=i,t.on=i,t}RP.default=rPe});var n5=w(FP=>{"use strict";Object.defineProperty(FP,"__esModule",{value:!0});var r5=iA();function i5(r){for(let e of Object.values(r))(r5.default.plainObject(e)||r5.default.array(e))&&i5(e);return Object.freeze(r)}FP.default=i5});var o5=w(s5=>{"use strict";Object.defineProperty(s5,"__esModule",{value:!0})});var NP=w(Ts=>{"use strict";var iPe=Ts&&Ts.__createBinding||(Object.create?function(r,e,t,i){i===void 0&&(i=t),Object.defineProperty(r,i,{enumerable:!0,get:function(){return e[t]}})}:function(r,e,t,i){i===void 0&&(i=t),r[i]=e[t]}),nPe=Ts&&Ts.__exportStar||function(r,e){for(var t in r)t!=="default"&&!Object.prototype.hasOwnProperty.call(e,t)&&iPe(e,r,t)};Object.defineProperty(Ts,"__esModule",{value:!0});Ts.defaultHandler=void 0;var a5=iA(),Os=DP(),sPe=t5(),Ow=Ld(),oPe=n5(),aPe={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},APe=async r=>new Promise(e=>{setTimeout(e,r)}),{normalizeArguments:Mw}=Ow.default,A5=(...r)=>{let e;for(let t of r)e=Mw(void 0,t,e);return e},lPe=r=>r.isStream?new Ow.default(void 0,r):Os.default(r),cPe=r=>"defaults"in r&&"options"in r.defaults,uPe=["get","post","put","patch","head","delete"];Ts.defaultHandler=(r,e)=>e(r);var l5=(r,e)=>{if(r)for(let t of r)t(e)},c5=r=>{r._rawHandlers=r.handlers,r.handlers=r.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=>r.handlers[l++](u,l===r.handlers.length?lPe:c);if(a5.default.plainObject(i)){let u=N(N({},i),n);Ow.setNonEnumerableProperties([i,n],u),n=u,i=void 0}try{let u;try{l5(r.options.hooks.init,n),l5((o=n.hooks)===null||o===void 0?void 0:o.init,n)}catch(f){u=f}let g=Mw(i,n,s!=null?s:r.options);if(g[Ow.kIsNormalizedAlready]=!0,u)throw new Os.RequestError(u.message,u,g);return c(g)}catch(u){if(n.isStream)throw u;return sPe.default(u,r.options.hooks.beforeError,(a=n.hooks)===null||a===void 0?void 0:a.beforeError)}};e.extend=(...i)=>{let n=[r.options],s=[...r._rawHandlers],o;for(let a of i)cPe(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!==Ts.defaultHandler),s.length===0&&s.push(Ts.defaultHandler),c5({options:A5(...n),handlers:s,mutableDefaults:Boolean(o)})};let t=async function*(i,n){let s=Mw(i,n,r.options);s.resolveBodyOnly=!1;let o=s.pagination;if(!a5.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 t(i,n))s.push(o);return s},e.paginate.each=t,e.stream=(i,n)=>e(i,te(N({},n),{isStream:!0}));for(let i of uPe)e[i]=(n,s)=>e(n,te(N({},s),{method:i})),e.stream[i]=(n,s)=>e(n,te(N({},s),{method:i,isStream:!0}));return Object.assign(e,aPe),Object.defineProperty(e,"defaults",{value:r.mutableDefaults?r:oPe.default(r),writable:r.mutableDefaults,configurable:r.mutableDefaults,enumerable:!0}),e.mergeOptions=A5,e};Ts.default=c5;nPe(o5(),Ts)});var Uw=w((sA,Kw)=>{"use strict";var gPe=sA&&sA.__createBinding||(Object.create?function(r,e,t,i){i===void 0&&(i=t),Object.defineProperty(r,i,{enumerable:!0,get:function(){return e[t]}})}:function(r,e,t,i){i===void 0&&(i=t),r[i]=e[t]}),u5=sA&&sA.__exportStar||function(r,e){for(var t in r)t!=="default"&&!Object.prototype.hasOwnProperty.call(e,t)&&gPe(e,r,t)};Object.defineProperty(sA,"__esModule",{value:!0});var fPe=require("url"),g5=NP(),hPe={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:r})=>r},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:r=>r.request.options.responseType==="json"?r.body:JSON.parse(r.body),paginate:r=>{if(!Reflect.has(r.headers,"link"))return!1;let e=r.headers.link.split(","),t;for(let i of e){let n=i.split(";");if(n[1].includes("next")){t=n[0].trimStart().trim(),t=t.slice(1,-1);break}}return t?{url:new fPe.URL(t)}:!1},filter:()=>!0,shouldContinue:()=>!0,countLimit:Infinity,backoff:0,requestLimit:1e4,stackAllItems:!0},parseJson:r=>JSON.parse(r),stringifyJson:r=>JSON.stringify(r),cacheOptions:{}},handlers:[g5.defaultHandler],mutableDefaults:!1},LP=g5.default(hPe);sA.default=LP;Kw.exports=LP;Kw.exports.default=LP;Kw.exports.__esModule=!0;u5(NP(),sA);u5(DP(),sA)});var d5=w(Af=>{"use strict";var znt=require("net"),pPe=require("tls"),TP=require("http"),f5=require("https"),dPe=require("events"),_nt=require("assert"),CPe=require("util");Af.httpOverHttp=mPe;Af.httpsOverHttp=EPe;Af.httpOverHttps=IPe;Af.httpsOverHttps=yPe;function mPe(r){var e=new oA(r);return e.request=TP.request,e}function EPe(r){var e=new oA(r);return e.request=TP.request,e.createSocket=h5,e.defaultPort=443,e}function IPe(r){var e=new oA(r);return e.request=f5.request,e}function yPe(r){var e=new oA(r);return e.request=f5.request,e.createSocket=h5,e.defaultPort=443,e}function oA(r){var e=this;e.options=r||{},e.proxyOptions=e.options.proxy||{},e.maxSockets=e.options.maxSockets||TP.Agent.defaultMaxSockets,e.requests=[],e.sockets=[],e.on("free",function(i,n,s,o){for(var a=p5(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)}})};oA.prototype.createSocket=function(e,t){var i=this,n={};i.sockets.push(n);var s=OP({},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")),dl("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){dl("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){dl("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 dl("tunneling connection has established"),i.sockets[i.sockets.indexOf(n)]=f,t(f)}function u(g){o.removeAllListeners(),dl(`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)}};oA.prototype.removeSocket=function(e){var t=this.sockets.indexOf(e);if(t!==-1){this.sockets.splice(t,1);var i=this.requests.shift();i&&this.createSocket(i,function(n){i.request.onSocket(n)})}};function h5(r,e){var t=this;oA.prototype.createSocket.call(t,r,function(i){var n=r.request.getHeader("host"),s=OP({},t.options,{socket:i,servername:n?n.replace(/:.*$/,""):r.host}),o=pPe.connect(0,s);t.sockets[t.sockets.indexOf(i)]=o,e(o)})}function p5(r,e,t){return typeof r=="string"?{host:r,port:e,localAddress:t}:r}function OP(r){for(var e=1,t=arguments.length;e{C5.exports=d5()});var x5=w((Gw,jP)=>{var v5=Object.assign({},require("fs")),GP=function(){var r=typeof document!="undefined"&&document.currentScript?document.currentScript.src:void 0;return typeof __filename!="undefined"&&(r=r||__filename),function(e){e=e||{};var t=typeof e!="undefined"?e:{},i,n;t.ready=new Promise(function(d,E){i=d,n=E});var s={},o;for(o in t)t.hasOwnProperty(o)&&(s[o]=t[o]);var a=[],l="./this.program",c=function(d,E){throw E},u=!1,g=!0,f="";function h(d){return t.locateFile?t.locateFile(d,f):f+d}var p,m,y,b;g&&(u?f=require("path").dirname(f)+"/":f=__dirname+"/",p=function(E,I){var D=xa(E);return D?I?D:D.toString():(y||(y=v5),b||(b=require("path")),E=b.normalize(E),y.readFileSync(E,I?null:"utf8"))},m=function(E){var I=p(E,!0);return I.buffer||(I=new Uint8Array(I)),Z(I.buffer),I},process.argv.length>1&&(l=process.argv[1].replace(/\\/g,"/")),a=process.argv.slice(2),c=function(d){process.exit(d)},t.inspect=function(){return"[Emscripten Module object]"});var v=t.print||console.log.bind(console),x=t.printErr||console.warn.bind(console);for(o in s)s.hasOwnProperty(o)&&(t[o]=s[o]);s=null,t.arguments&&(a=t.arguments),t.thisProgram&&(l=t.thisProgram),t.quit&&(c=t.quit);var T=16;function q(d,E){return E||(E=T),Math.ceil(d/E)*E}var Y=0,$=function(d){Y=d},_;t.wasmBinary&&(_=t.wasmBinary);var ne=t.noExitRuntime||!0;typeof WebAssembly!="object"&&vr("no native wasm support detected");function ee(d,E,I){switch(E=E||"i8",E.charAt(E.length-1)==="*"&&(E="i32"),E){case"i1":return pe[d>>0];case"i8":return pe[d>>0];case"i16":return Qe[d>>1];case"i32":return fe[d>>2];case"i64":return fe[d>>2];case"float":return Ht[d>>2];case"double":return Mt[d>>3];default:vr("invalid type for getValue: "+E)}return null}var A,oe=!1,ce;function Z(d,E){d||vr("Assertion failed: "+E)}function O(d){var E=t["_"+d];return Z(E,"Cannot call unknown function "+d+", make sure it is exported"),E}function L(d,E,I,D,M){var z={string:function(st){var yt=0;if(st!=null&&st!==0){var xe=(st.length<<2)+1;yt=B(xe),be(st,yt,xe)}return yt},array:function(st){var yt=B(st.length);return Ke(st,yt),yt}};function ie(st){return E==="string"?re(st):E==="boolean"?Boolean(st):st}var we=O(d),me=[],_e=0;if(D)for(var ot=0;ot=D);)++M;if(M-E>16&&d.subarray&&Be)return Be.decode(d.subarray(E,M));for(var z="";E>10,56320|_e&1023)}}return z}function re(d,E){return d?je(V,d,E):""}function se(d,E,I,D){if(!(D>0))return 0;for(var M=I,z=I+D-1,ie=0;ie=55296&&we<=57343){var me=d.charCodeAt(++ie);we=65536+((we&1023)<<10)|me&1023}if(we<=127){if(I>=z)break;E[I++]=we}else if(we<=2047){if(I+1>=z)break;E[I++]=192|we>>6,E[I++]=128|we&63}else if(we<=65535){if(I+2>=z)break;E[I++]=224|we>>12,E[I++]=128|we>>6&63,E[I++]=128|we&63}else{if(I+3>=z)break;E[I++]=240|we>>18,E[I++]=128|we>>12&63,E[I++]=128|we>>6&63,E[I++]=128|we&63}}return E[I]=0,I-M}function be(d,E,I){return se(d,V,E,I)}function he(d){for(var E=0,I=0;I=55296&&D<=57343&&(D=65536+((D&1023)<<10)|d.charCodeAt(++I)&1023),D<=127?++E:D<=2047?E+=2:D<=65535?E+=3:E+=4}return E}function Fe(d){var E=he(d)+1,I=Et(E);return I&&se(d,pe,I,E),I}function Ke(d,E){pe.set(d,E)}function ke(d,E){return d%E>0&&(d+=E-d%E),d}var ve,pe,V,Qe,le,fe,gt,Ht,Mt;function Ei(d){ve=d,t.HEAP8=pe=new Int8Array(d),t.HEAP16=Qe=new Int16Array(d),t.HEAP32=fe=new Int32Array(d),t.HEAPU8=V=new Uint8Array(d),t.HEAPU16=le=new Uint16Array(d),t.HEAPU32=gt=new Uint32Array(d),t.HEAPF32=Ht=new Float32Array(d),t.HEAPF64=Mt=new Float64Array(d)}var jt=t.INITIAL_MEMORY||16777216,Qr,Oi=[],Xs=[],Un=[],Hn=!1;function Sr(){if(t.preRun)for(typeof t.preRun=="function"&&(t.preRun=[t.preRun]);t.preRun.length;)ba(t.preRun.shift());ko(Oi)}function jn(){Hn=!0,!t.noFSInit&&!S.init.initialized&&S.init(),ps.init(),ko(Xs)}function fs(){if(t.postRun)for(typeof t.postRun=="function"&&(t.postRun=[t.postRun]);t.postRun.length;)Nu(t.postRun.shift());ko(Un)}function ba(d){Oi.unshift(d)}function DA(d){Xs.unshift(d)}function Nu(d){Un.unshift(d)}var hs=0,RA=null,Qa=null;function Lu(d){return d}function FA(d){hs++,t.monitorRunDependencies&&t.monitorRunDependencies(hs)}function NA(d){if(hs--,t.monitorRunDependencies&&t.monitorRunDependencies(hs),hs==0&&(RA!==null&&(clearInterval(RA),RA=null),Qa)){var E=Qa;Qa=null,E()}}t.preloadedImages={},t.preloadedAudios={};function vr(d){t.onAbort&&t.onAbort(d),d+="",x(d),oe=!0,ce=1,d="abort("+d+"). Build with -s ASSERTIONS=1 for more info.";var E=new WebAssembly.RuntimeError(d);throw n(E),E}var zl="data:application/octet-stream;base64,";function Tu(d){return d.startsWith(zl)}var xo="data:application/octet-stream;base64,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ACgCFC0AAiAAKAIYajYCGCAAIAAoAhggACgCDGo2AgwgACAAKAIULQADIAAoAhhqNgIYIAAgACgCGCAAKAIMajYCDCAAIAAoAhQtAAQgACgCGGo2AhggACAAKAIYIAAoAgxqNgIMIAAgACgCFC0ABSAAKAIYajYCGCAAIAAoAhggACgCDGo2AgwgACAAKAIULQAGIAAoAhhqNgIYIAAgACgCGCAAKAIMajYCDCAAIAAoAhQtAAcgACgCGGo2AhggACAAKAIYIAAoAgxqNgIMIAAgACgCFC0ACCAAKAIYajYCGCAAIAAoAhggACgCDGo2AgwgACAAKAIULQAJIAAoAhhqNgIYIAAgACgCGCAAKAIMajYCDCAAIAAoAhQtAAogACgCGGo2AhggACAAKAIYIAAoAgxqNgIMIAAgACgCFC0ACyAAKAIYajYCGCAAIAAoAhggACgCDGo2AgwgACAAKAIULQAMIAAoAhhqNgIYIAAgACgCGCAAKAIMajYCDCAAIAAoAhQtAA0gACgCGGo2AhggACAAKAIYIAAoAgxqNgIMIAAgACgCFC0ADiAAKAIYajYCGCAAIAAoAhggACgCDGo2AgwgACAAKAIULQAPIAAoAhhqNgIYIAAgACgCGCAAKAIMajYCDCAAIAAoAhRBEGo2AhQgACAAKAIIQQFrIgE2AgggAQ0ACyAAIAAoAhhB8f8DcDYCGCAAIAAoAgxB8f8DcDYCDAwBCwsgACgCEARAA0AgACgCEEEQTwRAIAAgACgCEEEQazYCECAAIAAoAhQtAAAgACgCGGo2AhggACAAKAIYIAAoAgxqNgIMIAAgACgCFC0AASAAKAIYajYCGCAAIAAoAhggACgCDGo2AgwgACAAKAIULQACIAAoAhhqNgIYIAAgACgCGCAAKAIMajYCDCAAIAAoAhQtAAMgACgCGGo2AhggACAAKAIYIAAoAgxqNgIMIAAgACgCFC0ABCAAKAIYajYCGCAAIAAoAhggACgCDGo2AgwgACAAKAIULQAFIAAoAhhqNgIYIAAgACgCGCAAKAIMajYCDCAAIAAoAhQtAAYgACgCGGo2AhggACAAKAIYIAAoAgxqNgIMIAAgACgCFC0AByAAKAIYajYCGCAAIAAoAhggACgCDGo2AgwgACAAKAIULQAIIAAoAhhqNgIYIAAgACgCGCAAKAIMajYC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NgIYIAEoAgxCADcDICABKAIMQgA3AyggASgCDEEANgIwIAEoAgxBADYCNCABKAIMQQA2AjggASgCDEEANgI8IAEoAgxBADsBQCABKAIMQYCA2I14NgJEIAEoAgxCADcDSCABKAIMQQA7AVAgASgCDEEAOwFSIAEoAgxBADYCVAvSEwEBfyMAQbABayIDJAAgAyAANgKoASADIAE2AqQBIAMgAjYCoAEgA0EANgKQASADIAMoAqQBKAIwQQAQOjYClAEgAyADKAKkASgCOEEAEDo2ApgBAkACQAJAAkAgAygClAFBAkYEQCADKAKYAUEBRg0BCyADKAKUAUEBRgRAIAMoApgBQQJGDQELIAMoApQBQQJHDQEgAygCmAFBAkcNAQsgAygCpAEiACAALwEMQYAQcjsBDAwBCyADKAKkASIAIAAvAQxB/+8DcTsBDCADKAKUAUECRgRAIANB9eABIAMoAqQBKAIwIAMoAqgBQQhqEI4BNgKQASADKAKQAUUEQCADQX82AqwBDAMLCwJAIAMoAqABQYACcQ0AIAMoApgBQQJHDQAgA0H1xgEgAygCpAEoAjggAygCqAFBCGoQjgE2AkggAygCSEUEQCADKAKQARAjIANBfzYCrAEMAwsgAygCSCADKAKQATYCACADIAMoAkg2ApABCwsCQCADKAKkAS8BUkUEQCADKAKkASIAIAAvAQxB/v8DcTsBDAwBCyADKAKkASIAIAAvAQxBAXI7AQwLIAMgAygCpAEgAygCoAEQZUEBcToAhgEgAyADKAKgAUGACnFBgApHBH8gAy0AhgEFQQELQQFxOgCHASADAn9BASADKAKkAS8BUkGBAkYNABpBASADKAKkAS8BUkGCAkYNABogAygCpAEvAVJBgwJGC0EBcToAhQEgAy0AhwFBAXEEQCADIANBIGpCHBApNgIcIAMoAhxFBEAgAygCqAFBCGpBDkEAEBQgAygCkAEQIyADQX82AqwBDAILAkAgAygCoAFBgAJxBEACQCADKAKgAUGACHENACADKAKkASkDIEL/////D1YNACADKAKkASkDKEL/////D1gNAgsgAygCHCADKAKkASkDKBAtIAMoAhwgAygCpAEpAyAQLQwBCwJAAkAgAygCoAFBgAhxDQAgAygCpAEpAyBC/////w9WDQAgAygCpAEpAyhC/////w9WDQAgAygCpAEpA0hC/////w9YDQELIAMoAqQBKQMoQv////8PWgRAIAMoAhwgAygCpAEpAygQLQsgAygCpAEpAyBC/////w9aBEAgAygCHCADKAKkASkDIBAtCyADKAKkASkDSEL/////D1oEQCADKAIcIAMoAqQBKQNIEC0LCwsCfyMAQRBrIgAgAygCHDYCDCAAKAIMLQAAQQFxRQsEQCADKAKoAUEIakEUQQAQFCADKAIcEBYgAygCkAEQIyADQX82AqwBDAILIANBAQJ/IwBBEGsiACADKAIcNgIMAn4gACgCDC0AAEEBcQRAIAAoAgwpAxAMAQtCAAunQf//A3ELIANBIGpBgAYQVTYCjAEgAygCHBAWIAMoAowBIAMoApABNgIAIAMgAygCjAE2ApABCyADLQCFAUEBcQRAIAMgA0EVakIHECk2AhAgAygCEEUEQCADKAKoAUEIakEOQQAQFCADKAKQARAjIANBfzYCrAEMAgsgAygCEEECEB8gAygCEEG9EkECEEEgAygCECADKAKkAS8BUkH/AXEQlgEgAygCECADKAKkASgCEEH//wNxEB8CfyMAQRBrIgAgAygCEDYCDCAAKAIMLQAAQQFxRQsEQCADKAKoAUEIakEUQQAQFCADKAIQEBYgAygCkAEQIyADQX82AqwBDAILIANBgbICQQcgA0EVakGABhBVNgIMIAMoAhAQFiADKAIMIAMoApABNgIAIAMgAygCDDYCkAELIAMgA0HQAGpCLhApIgA2AkwgAEUEQCADKAKoAUEIakEOQQAQFCADKAKQARAjIANBfzYCrAEMAQsgAygCTEHxEkH2EiADKAKgAUGAAnEbQQQQQSADKAKgAUGAAnFFBEAgAygCTCADLQCGAUEBcQR/QS0FIAMoAqQBLwEIC0H//wNxEB8LIAMoAkwgAy0AhgFBAXEEf0EtBSADKAKkAS8BCgtB//8DcRAfIAMoAkwgAygCpAEvAQwQHwJAIAMtAIUBQQFxBEAgAygCTEHjABAfDAELIAMoAkwgAygCpAEoAhBB//8DcRAfCyADKAKkASgCFCADQZ4BaiADQZwBahCNASADKAJMIAMvAZ4BEB8gAygCTCADLwGcARAfAkACQCADLQCFAUEBcUUNACADKAKkASkDKEIUWg0AIAMoAkxBABAhDAELIAMoAkwgAygCpAEoAhgQIQsCQAJAIAMoAqABQYACcUGAAkcNACADKAKkASkDIEL/////D1QEQCADKAKkASkDKEL/////D1QNAQsgAygCTEF/ECEgAygCTEF/ECEMAQsCQCADKAKkASkDIEL/////D1QEQCADKAJMIAMoAqQBKQMgpxAhDAELIAMoAkxBfxAhCwJAIAMoAqQBKQMoQv////8PVARAIAMoAkwgAygCpAEpAyinECEMAQsgAygCTEF/ECELCyADKAJMIAMoAqQBKAIwEFFB//8DcRAfIAMgAygCpAEoAjQgAygCoAEQkgFB//8DcSADKAKQAUGABhCSAUH//wNxajYCiAEgAygCTCADKAKIAUH//wNxEB8gAygCoAFBgAJxRQRAIAMoAkwgAygCpAEoAjgQUUH//wNxEB8gAygCTCADKAKkASgCPEH//wNxEB8gAygCTCADKAKkAS8BQBAfIAMoAkwgAygCpAEoAkQQIQJAIAMoAqQBKQNIQv////8PVARAIAMoAkwgAygCpAEpA0inECEMAQsgAygCTEF/ECELCwJ/IwBBEGsiACADKAJMNgIMIAAoAgwtAABBAXFFCwRAIAMoAqgBQQhqQRRBABAUIAMoAkwQFiADKAKQARAjIANBfzYCrAEMAQsgAygCqAEgA0HQAGoCfiMAQRBrIgAgAygCTDYCDAJ+IAAoAgwtAABBAXEEQCAAKAIMKQMQDAELQgALCxA2QQBIBEAgAygCTBAWIAMoApABECMgA0F/NgKsAQwBCyADKAJMEBYgAygCpAEoAjAEQCADKAKoASADKAKkASgCMBCFAUEASARAIAMoApABECMgA0F/NgKsAQwCCwsgAygCkAEEQCADKAKoASADKAKQAUGABhCRAUEASARAIAMoApABECMgA0F/NgKsAQwCCwsgAygCkAEQIyADKAKkASgCNARAIAMoAqgBIAMoAqQBKAI0IAMoAqABEJEBQQBIBEAgA0F/NgKsAQwCCwsgAygCoAFBgAJxRQRAIAMoAqQBKAI4BEAgAygCqAEgAygCpAEoAjgQhQFBAEgEQCADQX82AqwBDAMLCwsgAyADLQCHAUEBcTYCrAELIAMoAqwBIQAgA0GwAWokACAAC+ACAQF/IwBBIGsiBCQAIAQgADsBGiAEIAE7ARggBCACNgIUIAQgAzYCECAEQRAQGCIANgIMAkAg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AAAgAygCHEHcFmogAygCDEECdGooAgAgAygCHEHYKGpqLQAASg0ADAELIAMoAhxB3BZqIAMoAhRBAnRqIAMoAhxB3BZqIAMoAgxBAnRqKAIANgIAIAMgAygCDDYCFCADIAMoAgxBAXQ2AgwMAQsLIAMoAhxB3BZqIAMoAhRBAnRqIAMoAhA2AgAL1xMBA38jAEEwayICJAAgAiAANgIsIAIgATYCKCACIAIoAigoAgA2AiQgAiACKAIoKAIIKAIANgIgIAIgAigCKCgCCCgCDDYCHCACQX82AhAgAigCLEEANgLQKCACKAIsQb0ENgLUKCACQQA2AhgDQCACKAIYIAIoAhxIBEACQCACKAIkIAIoAhhBAnRqLwEABEAgAiACKAIYIgE2AhAgAigCLEHcFmohAyACKAIsIgQoAtAoQQFqIQAgBCAANgLQKCAAQQJ0IANqIAE2AgAgAigCGCACKAIsQdgoampBADoAAAwBCyACKAIkIAIoAhhBAnRqQQA7AQILIAIgAigCGEEBajYCGAwBCwsDQCACKAIsKALQKEECSARAAkAgAigCEEECSARAIAIgAigCEEEBaiIANgIQDAELQQAhAAsgAigCLEHcFmohAyACKAIsIgQoAtAoQQFqIQEgBCABNgLQKCABQQJ0IANqIAA2AgAgAiAANgIMIAIoAiQgAigCDEECdGpBATsBACACKAIMIAIoAixB2ChqakEAOgAAIAIoAiwiACAAKAKoLUEBazYCqC0gAigCIARAIAIoAiwiACAAKAKsLSACKAIgIAIoAgxBAnRqLwECazYCrC0LDAELCyACKAIoIAIoAhA2AgQgAiACKAIsKALQKEECbTYCGANAIAIoAhhBAU4EQCACKAIsIAIoAiQgAigCGBB5IAIgAigCGEEBazYCGAwBCwsgAiACKAIcNgIMA0AgAiACKAIsKALgFjYCGCACKAIsQdwWaiEBIAIoAiwiAygC0CghACADIABBAWs2AtAoIAIoAiwgAEECdCABaigCADYC4BYgAigCLCACKAIkQQEQeSACIAIoAiwoAuAWNgIUIAIoAhghASACKAIsQdwWaiEDIAIoAiwiBCgC1ChBAWshACAEIAA2AtQoIABBAnQgA2ogATYCACACKAIUIQEgAigCLEHcFmohAyACKAIsIgQoAtQoQQFrIQAgBCAANgLUKCAA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AQsgAigCCEEANgIAIAIoAghCADcDECACKAIIQgA3AwggAigCCEIANwMgIAIoAghCADcDGCACKAIIQQA2AiggAigCCEEAOgAsIAIoAgggAikDECACKAIMEI8BQQFxRQRAIAIoAggQJSACQQA2AhwMAQsgAiACKAIINgIcCyACKAIcIQEgAkEgaiQAIAEL1gIBAX8jAEEgayIDJAAgAyAANgIYIAMgATYCFCADIAI2AhAgAyADQQxqQgQQKTYCCAJAIAMoAghFBEAgA0F/NgIcDAELA0AgAygCFARAIAMoAhQoAgQgAygCEHFBgAZxBEAgAygCCEIAECwaIAMoAgggAygCFC8BCBAfIAMoAgggAygCFC8BChAfAn8jAEEQayIAIAMoAgg2AgwgACgCDC0AAEEBcUULBEAgAygCGEEIakEUQQAQFCADKAIIEBYgA0F/NgIcDAQLIAMoAhggA0EMakIEEDZBAEgEQCADKAIIEBYgA0F/NgIcDAQLIAMoAhQvAQoEQCADKAIYIAMoAhQoAgwgAygCFC8BCq0QNkEASARAIAMoAggQFiADQX82AhwMBQsLCyADIAMoAhQoAgA2AhQMAQsLIAMoAggQFiADQQA2AhwLIAMoAhwhACADQSBqJAAgAAtoAQF/IwBBEGsiAiAANgIMIAIgATYCCCACQQA7AQYDQCACKAIMBEAgAigCDCgCBCACKAIIcUGABnEEQCACIAIoAgwvAQogAi8BBkEEamo7AQYLIAIgAigCDCgCADYCDAwBCwsgAi8BBgvwAQEBfyMAQRBrIgEkACABIAA2AgwgASABKAIMNgIIIAFBADYCBANAIAEoAgwEQAJAAkAgASgCDC8BCEH1xgFGDQAgASgCDC8BCEH14AFGDQAgASgCDC8BCEGBsgJGDQAgASgCDC8BCEEBRw0BCyABIAEoAgwoAgA2AgAgASgCCCABKAIMRgRAIAEgASgCADYCCAsgASgCDEEANgIAIAEoAgwQIyABKAIEBEAgASgCBCABKAIANgIACyABIAEoAgA2AgwMAgsgASABKAIMNgIEIAEgASgCDCgCADYCDAwBCwsgASgCCCEAIAFBEGokACAAC7IEAQF/IwBBQGoiBSQAIAUgADYCOCAFIAE7ATYgBSACNgIwIAUgAzYCLCAFIAQ2AiggBSAFKAI4IAUvATatECkiADYC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IAEoAhBB//8DRgRAIAEgASgCDDYCEAsgASgCCEH//wNGBEAgASABKAIENgIICwJAIAEoApQBQQRxRQ0AIAEoAgggASgCBEYEQCABKAIQIAEoAgxGDQELIAEoApABQRVBABAUIAEtABdBAXEEQCABKAKkARAWCyABQQA2AqwBDAELAkAgASgCEEUEQCABKAIIRQ0BCyABKAKQAUEBQQAQFCABLQAXQQFxBEAgASgCpAEQFgsgAUEANgKsAQwBCyABIAEoAqQBEDE3AyggASABKAKkARAxNwMgIAEpAyggASkDIFIEQCABKAKQAUEBQQAQFCABLQAXQQFxBEAgASgCpAEQFgsgAUEANgKsAQwBCyABIAEoAqQBEDE3AzAgASABKAKkARAxNwOAAQJ/IwBBEGsiBSABKAKkATYCDCAFKAIMLQAAQQFxRQsEQCABKAKQAUEUQQAQFCABLQAXQQFxBEAgASgCpAEQFgsgAUEANgKsAQwBCyABLQAXQQFxBEAgASgCpAEQFgsCQCABKQOAAUL///////////8AWARAIAEpA4ABIAEpA4ABIAEpAzB8WA0BCyABKAKQAUEEQRYQFCABQQA2AqwBDAELIAEpA4ABIAEpAzB8IAEpA5gBIAEpAzh8VgRAIAEoApABQRVBABAUIAFBADYCrAEMAQsCQCABKAKUAUEEcUUNACABKQOAASABKQMwfCABKQOYASABKQM4fFENACABKAKQAUEVQQAQFCABQQA2AqwBDAELIAEpAyggASkDMEIugFYEQCABKAKQAUEVQQAQFCABQQA2AqwBDAELIAEgASkDKCABKAKQARCQASIFNgKMASAFRQRAIAFBADYCrAEMAQsgASgCjAFBAToALCABKAKMASABKQMwNwMYIAEoAowBIAEpA4ABNwMgIAEgASgCjAE2AqwBCyABKAKsASEFIAFBsAFqJAAgACAFNgJQDAELIAAoAmQgACkDMBAsGiAAKAJkIQUgACkDWCEJIAAoAmgoAhQhBiAAKAJUIQcjAEHQAGsiASQAIAEgBTYCSCABIAk3A0AgASAGNgI8IAEgBzYCOAJAIAEoAkgQMEIWVARAIAEoAjhBFUEAEBQgAUEANgJMDAELIwBBEGsiBSABKAJINgIMIAECfiAFKAIMLQAAQQFxBEAgBSgCDCkDEAwBC0IACzcDCCABKAJIQgQQHhogASgCSBAqBEAgASgCOEEBQQAQFCABQQA2AkwMAQsgASABKAJIEB1B//8Dca03AyggASABKAJIEB1B//8Dca03AyAgASkDICABKQMoUgRAIAEoAjhBE0EAEBQgAUEANgJMDAELIAEgASgCSBAqrTcDGCABIAEoAkgQKq03AxAgASkDECABKQMQIAEpAxh8VgRAIAEoAjhBBEEWEBQgAUEANgJMDAELIAEpAxAgASkDGHwgASkDQCABKQMIfFYEQCABKAI4QRVBABAUIAFBADYCTAwBCwJAIAEoAjxBBHFFDQAgASkDECABKQMYfCABKQNAIAEpAwh8UQ0AIAEoAjhBFUEAEBQgAUEANgJMDAELIAEgASkDICABKAI4EJABIgU2AjQgBUUEQCABQQA2AkwMAQsgASgCNEEAOgAsIAEoAjQgASkDGDcDGCABKAI0IAEpAxA3AyAgASABKAI0NgJMCyABKAJMIQUgAUHQAGokACAAIAU2AlALIAAoAlBFBEAgAEEANgJsDAELIAAoAmQgACkDMEIUfBAsGiAAIAAoAmQQHTsBTiAAKAJQKQMgIAAoAlApAxh8IAApA1ggACkDMHxWBEAgACgCVEEVQQAQFCAAKAJQECUgAEEANgJsDAELAkAgAC8BTkUEQCAAKAJoKAIEQQRxRQ0BCyAAKAJkIAApAzBCFnwQLBogACAAKAJkEDA3AyACQCAAKQMgIAAvAU6tWgRAIAAoAmgoAgRBBHFFDQEgACkDICAALwFOrVENAQsgACgCVEEVQQAQFCAAKAJQECUgAEEANgJsDAILIAAvAU4EQCAAKAJkIAAvAU6tEB4gAC8BTkEAIAAoAlQQUCEBIAAoAlAgATYCKCABRQRAIAAoAlAQJSAAQQA2AmwMAwsLCwJAIAAoAlApAyAgACkDWFoEQCAAKAJkIAAoAlApAyAgACkDWH0QLBogACAAKAJkIAAoAlApAxgQHiIBNgIcIAFFBEAgACgCVEEVQQAQFCAAKAJQECUgAEEANgJsDAMLIAAgACgCHCAAKAJQKQMYECkiATYCLCABRQRAIAAoAlRBDkEAEBQgACgCUBAlIABBADYCbAwDCwwBCyAAQQA2AiwgACgCaCgCACAAKAJQKQMgQQAQJ0EASARAIAAoAlQgACgCaCgCABAXIAAoAlAQJSAAQQA2AmwMAgsgACgCaCgCABBJIAAoAlApAyBSBEAgACgCVEETQQAQFCAAKAJQECUgAEEANgJsDAILCyAAIAAoAlApAxg3AzggAEIANwNAA0ACQCAAKQM4UA0AIABBADoAGyAAKQNAIAAoAlApAwhRBEAgACgCUC0ALEEBcQ0BIAApAzhCLlQNASAAKAJQQoCABCAAKAJUEI8BQQFxRQRAIAAoAlAQJSAAKAIsEBYgAEEANgJsDAQLIABBAToAGwsjAEEQayIBJAAgAUHYABAYIgU2AggCQCAFRQRAIAFBADYCDAwBCyABKAIIEFMgASABKAIINgIMCyABKAIMIQUgAUEQaiQAIAUhASAAKAJQKAIAIAApA0CnQQR0aiABNgIAAkAgAQRAIAAgACgCUCgCACAAKQNAp0EEdGooAgAgACgCaCgCACAAKAIsQQAgACgCVBCMASIJNwMQIAlCAFkNAQsCQCAALQAbQQFxRQ0AIwBBEGsiASAAKAJUNgIMIAEoAgwoAgBBE0cNACAAKAJUQRVBABAUCyAAKAJQECUgACgCLBAWIABBADYCbAwDCyAAIAApA0BCAXw3A0AgACAAKQM4IAApAxB9NwM4DAELCwJAIAApA0AgACgCUCkDCFEEQCAAKQM4UA0BCyAAKAJUQRVBABAUIAAoAiwQFiAAKAJQECUgAEEANgJsDAELIAAoAmgoAgRBBHEEQAJAIAAoAiwEQCAAIAAoAiwQR0EBcToADwwBCyAAIAAoAmgoAgAQSTcDACAAKQMAQgBTBEAgACgCVCAAKAJoKAIAEBcgACgCUBAlIABBADYCbAwDCyAAIAApAwAgACgCUCkDICAAKAJQKQMYfFE6AA8LIAAtAA9BAXFFBEAgACgCVEEVQQAQFCAAKAIsEBYgACgCUBAlIABBADYCbAwCCwsgACgCLBAWIAAgACgCUDYCbAsgACgCbCEBIABB8ABqJAAgAiABNgJIIAEEQAJAIAIoAkwEQCACKQMgQgBXBEAgAiACKAJYIAIoAkwgAkEQahBoNwMgCyACIAIoAlggAigCSCACQRBqEGg3AygCQCACKQMgIAIpAyhTBEAgAigCTBAlIAIgAigCSDYCTCACIAIpAyg3AyAMAQsgAigCSBAlCwwBCyACIAIoAkg2AkwCQCACKAJYKAIEQQRxBEAgAiACKAJYIAIoAkwgAkEQahBoNwMgDAELIAJCADcDIAsLIAJBADYCSAsgAiACKAJEQQFqNgJEIAIoAgwgAigCRAJ/IwBBEGsiACACKAIMNgIMIAAoAgwoAgQLa6wQLBoMAQsLIAIoAgwQFiACKQMgQgBTBEAgAigCWEEIaiACQRBqEEUgAigCTBAlIAJBADYCXAwBCyACIAIoAkw2AlwLIAIoAlwhACACQeAAaiQAIAMgADYCWCAARQRAIAMoAmAgAygCXEEIahBFIwBBEGsiACADKAJoNgIMIAAoAgwiACAAKAIwQQFqNgIwIAMoAlwQPCADQQA2AmwMAQsgAygCXCADKAJYKAIANgJAIAMoAlwgAygCWCkDCDcDMCADKAJcIAMoAlgpAxA3AzggAygCXCADKAJYKAIoNgIgIAMoAlgQFSADKAJcKAJQIQAgAygCXCkDMCEJIAMoAlxBCGohAiMAQSBrIgEkACABIAA2AhggASAJNwMQIAEgAjYCDAJAIAEpAxBQBEAgAUEBOgAfDAELIwBBIGsiACABKQMQNwMQIAAgACkDELpEAAAAAAAA6D+jOQMIAkAgACsDCEQAAOD////vQWQEQCAAQX82AgQMAQsgAAJ/IAArAwgiCkQAAAAAAADwQWMgCkQAAAAAAAAAAGZxBEAgCqsMAQtBAAs2AgQLAkAgACgCBEGAgICAeEsEQCAAQYCAgIB4NgIcDAELIAAgACgCBEEBazYCBCAAIAAoAgQgACgCBEEBdnI2AgQgACAAKAIEIAAoAgRBAnZyNgIEIAAgACgCBCAAKAIEQQR2cjYCBCAAIAAoAgQgACgCBEEIdnI2AgQgACAAKAIEIAAoAgRBEHZyNgIEIAAgACgCBEEBajYCBCAAIAAoAgQ2AhwLIAEgACgCHDYCCCABKAIIIAEoAhgoAgBNBEAgAUEBOgAfDAELIAEoAhggASgCCCABKAIMEFpBAXFFBEAgAUEAOgAfDAELIAFBAToAHwsgAS0AHxogAUEgaiQAIANCADcDEANAIAMpAxAgAygCXCkDMFQEQCADIAMoAlwoAkAgAykDEKdBBHRqKAIAKAIwQQBBACADKAJgEEY2AgwgAygCDEUEQCMAQRBrIgAgAygCaDYCDCAAKAIMIgAgACgCMEEBajYCMCADKAJcEDwgA0EANgJsDAMLIAMoAlwoAlAgAygCDCADKQMQQQggAygCXEEIahB0QQFxRQRAAkAgAygCXCgCCEEKRgRAIAMoAmRBBHFFDQELIAMoAmAgAygCXEEIahBFIwBBEGsiACADKAJoNgIMIAAoAgwiACAAKAIwQQFqNgIwIAMoAlwQPCADQQA2AmwMBAsLIAMgAykDEEIBfDcDEAwBCwsgAygCXCADKAJcKAIUNgIYIAMgAygCXDYCbAsgAygCbCEAIANB8ABqJAAgBCAANgI4CyAEKAI4RQRAIAQoAlgQLxogBEEANgJcDAELIAQgBCgCODYCXAsgBCgCXCEAIARB4ABqJAAgAAuOAQEBfyMAQRBrIgIkACACIAA2AgwgAiABNgIIIAJBADYCBCACKAIIBEAjAEEQayIAIAIoAgg2AgwgAiAAKAIMKAIANgIEIAIoAggQrAFBAUYEQCMAQRBrIgAgAigCCDYCDEG0mwEgACgCDCgCBDYCAAsLIAIoAgwEQCACKAIMIAIoAgQ2AgALIAJBEGokAAuVAQEBfyMAQRBrIgEkACABIAA2AggCQAJ/IwBBEGsiACABKAIINgIMIAAoAgwpAxhCgIAQg1ALBEAgASgCCCgCAARAIAEgASgCCCgCABCeAUEBcToADwwCCyABQQE6AA8MAQsgASABKAIIQQBCAEESECA+AgQgASABKAIEQQBHOgAPCyABLQAPQQFxIQAgAUEQaiQAIAALfwEBfyMAQSBrIgMkACADIAA2AhggAyABNwMQIANBADYCDCADIAI2AggCQCADKQMQQv///////////wBWBEAgAygCCEEEQT0QFCADQX82AhwMAQsgAyADKAIYIAMpAxAgAygCDCADKAIIEGo2AhwLIAMoAhwhACADQSBqJAAgAAt9ACACQQFGBEAgASAAKAIIIAAoAgRrrH0hAQsCQCAAKAIUIAAoAhxLBEAgAEEAQQAgACgCJBEBABogACgCFEUNAQsgAEEANgIcIABCADcDECAAIAEgAiAAKAIoEQ8AQgBTDQAgAEIANwIEIAAgACgCAEFvcTYCAEEADwtBfwvhAgECfyMAQSBrIgMkAAJ/AkACQEGnEiABLAAAEKIBRQRAQbSbAUEcNgIADAELQZgJEBgiAg0BC0EADAELIAJBAEGQARAzIAFBKxCiAUUEQCACQQhBBCABLQAAQfIARhs2AgALAkAgAS0AAEHhAEcEQCACKAIAIQEMAQsgAEEDQQAQBCIBQYAIcUUEQCADIAFBgAhyNgIQIABBBCADQRBqEAQaCyACIAIoAgBBgAFyIgE2AgALIAJB/wE6AEsgAkGACDYCMCACIAA2AjwgAiACQZgBajYCLAJAIAFBCHENACADIANBGGo2AgAgAEGTqAEgAxAODQAgAkEKOgBLCyACQRo2AiggAkEbNgIkIAJBHDYCICACQR02AgxB6J8BKAIARQRAIAJBfzYCTAsgAkGsoAEoAgA2AjhBrKABKAIAIgAEQCAAIAI2AjQLQaygASACNgIAIAILIQAgA0EgaiQAIAAL8AEBAn8CfwJAIAFB/wFxIgMEQCAAQQNxBEADQCAALQAAIgJFDQMgAiABQf8BcUYNAyAAQQFqIgBBA3ENAAsLAkAgACgCACICQX9zIAJBgYKECGtxQYCBgoR4cQ0AIANBgYKECGwhAwNAIAIgA3MiAkF/cyACQYGChAhrcUGAgYKEeHENASAAKAIEIQIgAEEEaiEAIAJBgYKECGsgAkF/c3FBgIGChHhxRQ0ACwsDQCAAIgItAAAiAwRAIAJBAWohACADIAFB/wFxRw0BCwsgAgwCCyAAEC4gAGoMAQsgAAsiAEEAIAAtAAAgAUH/AXFGGwsYACAAKAJMQX9MBEAgABCkAQ8LIAAQpAELYAIBfgJ/IAAoAighAkEBIQMgAEIAIAAtAABBgAFxBH9BAkEBIAAoAhQgACgCHEsbBUEBCyACEQ8AIgFCAFkEfiAAKAIUIAAoAhxrrCABIAAoAgggACgCBGusfXwFIAELC2sBAX8gAARAIAAoAkxBf0wEQCAAEG4PCyAAEG4PC0GwoAEoAgAEQEGwoAEoAgAQpQEhAQtBrKABKAIAIgAEQANAIAAoAkwaIAAoAhQgACgCHEsEQCAAEG4gAXIhAQsgACgCOCIADQALCyABCyIAIAAgARACIgBBgWBPBH9BtJsBQQAgAGs2AgBBfwUgAAsLUwEDfwJAIAAoAgAsAABBMGtBCk8NAANAIAAoAgAiAiwAACEDIAAgAkEBajYCACABIANqQTBrIQEgAiwAAUEwa0EKTw0BIAFBCmwhAQwACwALIAELuwIAAkAgAUEUSw0AAkACQAJAAkACQAJAAkACQAJAAkAgAUEJaw4KAAECAwQFBgcICQoLIAIgAigCACIBQQRqNgIAIAAgASgCADYCAA8LIAIgAigCACIBQQRqNgIAIAAgATQCADcDAA8LIAIgAigCACIBQQRqNgIAIAAgATUCADcDAA8LIAIgAigCAEEHakF4cSIBQQhqNgIAIAAgASkDADcDAA8LIAIgAigCACIBQQRqNgIAIAAgATIBADcDAA8LIAIgAigCACIBQQRqNgIAIAAgATMBADcDAA8LIAIgAigCACIBQQRqNgIAIAAgATAAADcDAA8LIAIgAigCACIBQQRqNgIAIAAgATEAADcDAA8LIAIgAigCAEEHakF4cSIBQQhqNgIAIAAgASsDADkDAA8LIAAgAkEYEQQACwt/AgF/AX4gAL0iA0I0iKdB/w9xIgJB/w9HBHwgAkUEQCABIABEAAAAAAAAAABhBH9BAAUgAEQAAAAAAADwQ6IgARCpASEAIAEoAgBBQGoLNgIAIAAPCyABIAJB/gdrNgIAIANC/////////4eAf4NCgICAgICAgPA/hL8FIAALC5sCACAARQRAQQAPCwJ/AkAgAAR/IAFB/wBNDQECQEGQmQEoAgAoAgBFBEAgAUGAf3FBgL8DRg0DDAELIAFB/w9NBEAgACABQT9xQYABcjoAASAAIAFBBnZBwAFyOgAAQQIMBAsgAUGAsANPQQAgAUGAQHFBgMADRxtFBEAgACABQT9xQYABcjoAAiAAIAFBDHZB4AFyOgAAIAAgAUEGdkE/cUGAAXI6AAFBAwwECyABQYCABGtB//8/TQRAIAAgAUE/cUGAAXI6AAMgACABQRJ2QfABcjoAACAAIAFBBnZBP3FBgAFyOgACIAAgAUEMdkE/cUGAAXI6AAFBBAwECwtBtJsBQRk2AgBBfwVBAQsMAQsgACABOgAAQQELC+MBAQJ/IAJBAEchAwJAAkACQCAAQQNxRQ0AIAJFDQAgAUH/AXEhBANAIAAtAAAgBEYNAiACQQFrIgJBAEchAyAAQQFqIgBBA3FFDQEgAg0ACwsgA0UNAQsCQCAALQAAIAFB/wFxRg0AIAJBBEkNACABQf8BcUGBgoQIbCEDA0AgACgCACADcyIEQX9zIARBgYKECGtxQYCBgoR4cQ0BIABBBGohACACQQRrIgJBA0sNAAsLIAJFDQAgAUH/AXEhAQNAIAEgAC0AAEYEQCAADwsgAEEBaiEAIAJBAWsiAg0ACwtBAAtaAQF/IwBBEGsiASAANgIIAkACQCABKAIIKAIAQQBOBEAgASgCCCgCAEGAFCgCAEgNAQsgAUEANgIMDAELIAEgASgCCCgCAEECdEGQFGooAgA2AgwLIAEoAgwL+QIBAX8jAEEgayIEJAAgBCAANgIYIAQgATcDECAEIAI2AgwgBCADNgIIIAQgBCgCGCAEKAIYIAQpAxAgBCgCDCAEKAIIEK4BIgA2AgACQCAARQRAIARBADYCHAwBCyAEKAIAEEhBAEgEQCAEKAIYQQhqIAQoAgAQFyAEKAIAEBsgBEEANgIcDAELIAQoAhghAiMAQRBrIgAkACAAIAI2AgggAEEYEBgiAjYCBAJAIAJFBEAgACgCCEEIakEOQQAQFCAAQQA2AgwMAQsgACgCBCAAKAIINgIAIwBBEGsiAiAAKAIEQQRqNgIMIAIoAgxBADYCACACKAIMQQA2AgQgAigCDEEANgIIIAAoAgRBADoAECAAKAIEQQA2AhQgACAAKAIENgIMCyAAKAIMIQIgAEEQaiQAIAQgAjYCBCACRQRAIAQoAgAQGyAEQQA2AhwMAQsgBCgCBCAEKAIANgIUIAQgBCgCBDYCHAsgBCgCHCEAIARBIGokACAAC7cOAgN/AX4jAEHAAWsiBSQAIAUgADYCuAEgBSABNgK0ASAFIAI3A6gBIAUgAzYCpAEgBUIANwOYASAFQgA3A5ABIAUgBDYCjAECQCAFKAK4AUUEQCAFQQA2ArwBDAELAkAgBSgCtAEEQCAFKQOoASAFKAK0ASkDMFQNAQsgBSgCuAFBCGpBEkEAEBQgBUEANgK8AQwBCwJAIAUoAqQBQQhxDQAgBSgCtAEoAkAgBSkDqAGnQQR0aigCCEUEQCAFKAK0ASgCQCAFKQOoAadBBHRqLQAMQQFxRQ0BCyAFKAK4AUEIakEPQQAQFCAFQQA2ArwBDAELIAUoArQBIAUpA6gBIAUoAqQBQQhyIAVByABqEH5BAEgEQCAFKAK4AUEIakEUQQAQFCAFQQA2ArwBDAELIAUoAqQBQSBxBEAgBSAFKAKkAUEEcjYCpAELAkAgBSkDmAFQBEAgBSkDkAFQDQELIAUoAqQBQQRxRQ0AIAUoArgBQQhqQRJBABAUIAVBADYCvAEMAQsCQCAFKQOYAVAEQCAFKQOQAVANAQsgBSkDmAEgBSkDmAEgBSkDkAF8WARAIAUpA2AgBSkDmAEgBSkDkAF8Wg0BCyAFKAK4AUEIakESQQAQFCAFQQA2ArwBDAELIAUpA5ABUARAIAUgBSkDYCAFKQOYAX03A5ABCyAFIAUpA5ABIAUpA2BUOgBHIAUgBSgCpAFBIHEEf0EABSAFLwF6QQBHC0EBcToARSAFIAUoAqQBQQRxBH9BAAUgBS8BeEEARwtBAXE6AEQgBQJ/IAUoAqQBQQRxBEBBACAFLwF4DQEaCyAFLQBHQX9zC0EBcToARiAFLQBFQQFxBEAgBSgCjAFFBEAgBSAFKAK4ASgCHDYCjAELIAUoAowBRQRAIAUoArgBQQhqQRpBABAUIAVBADYCvAEMAgsLIAUpA2hQBEAgBSAFKAK4AUEAQgBBABB9NgK8AQwBCwJAAkAgBS0AR0EBcUUNACAFLQBFQQFxDQAgBS0AREEBcQ0AIAUgBSkDkAE3AyAgBSAFKQOQATcDKCAFQQA7ATggBSAFKAJwNgIwIAVC3AA3AwggBSAFKAK0ASgCACAFKQOYASAFKQOQASAFQQhqQQAgBSgCtAEgBSkDqAEgBSgCuAFBCGoQXyIANgKIAQwBCyAFIAUoArQBIAUpA6gBIAUoAqQBIAUoArgBQQhqED8iADYCBCAARQRAIAVBADYCvAEMAgsgBSAFKAK0ASgCAEIAIAUpA2ggBUHIAGogBSgCBC8BDEEBdkEDcSAFKAK0ASAFKQOoASAFKAK4AUEIahBfIgA2AogBCyAARQRAIAVBADYCvAEMAQsCfyAFKAKIASEAIAUoArQBIQMjAEEQayIBJAAgASAANgIMIAEgAzYCCCABKAIMIAEoAgg2AiwgASgCCCEDIAEoAgwhBCMAQSBrIgAkACAAIAM2AhggACAENgIUAkAgACgCGCgCSCAAKAIYKAJEQQFqTQRAIAAgACgCGCgCSEEKajYCDCAAIAAoAhgoAkwgACgCDEECdBBONgIQIAAoAhBFBEAgACgCGEEIakEOQQAQFCAAQX82AhwMAgsgACgCGCAAKAIMNgJIIAAoAhggACgCEDYCTAsgACgCFCEEIAAoAhgoAkwhBiAAKAIYIgcoAkQhAyAHIANBAWo2AkQgA0ECdCAGaiAENgIAIABBADYCHAsgACgCHCEDIABBIGokACABQRBqJAAgA0EASAsEQCAFKAKIARAbIAVBADYCvAEMAQsgBS0ARUEBcQRAIAUgBS8BekEAEHsiADYCACAARQRAIAUoArgBQQhqQRhBABAUIAVBADYCvAEMAgsgBSAFKAK4ASAFKAKIASAFLwF6QQAgBSgCjAEgBSgCABEFADYChAEgBSgCiAEQGyAFKAKEAUUEQCAFQQA2ArwBDAILIAUgBSgChAE2AogBCyAFLQBEQQFxBEAgBSAFKAK4ASAFKAKIASAFLwF4ELABNgKEASAFKAKIARAbIAUoAoQBRQRAIAVBADYCvAEMAgsgBSAFKAKEATYCiAELIAUtAEZBAXEEQCAFIAUoArgBIAUoAogBQQEQrwE2AoQBIAUoAogBEBsgBSgChAFFBEAgBUEANgK8AQwCCyAFIAUoAoQBNgKIAQsCQCAFLQBHQQFxRQ0AIAUtAEVBAXFFBEAgBS0AREEBcUUNAQsgBSgCuAEhASAFKAKIASEDIAUpA5gBIQIgBSkDkAEhCCMAQSBrIgAkACAAIAE2AhwgACADNgIYIAAgAjcDECAAIAg3AwggACgCGCAAKQMQIAApAwhBAEEAQQBCACAAKAIcQQhqEF8hASAAQSBqJAAgBSABNgKEASAFKAKIARAbIAUoAoQBRQRAIAVBADYCvAEMAgsgBSAFKAKEATYCiAELIAUgBSgCiAE2ArwBCyAFKAK8ASEAIAVBwAFqJAAgAAuEAgEBfyMAQSBrIgMkACADIAA2AhggAyABNgIUIAMgAjYCEAJAIAMoAhRFBEAgAygCGEEIakESQQAQFCADQQA2AhwMAQsgA0E4EBgiADYCDCAARQRAIAMoAhhBCGpBDkEAEBQgA0EANgIcDAELIwBBEGsiACADKAIMQQhqNgIMIAAoAgxBADYCACAAKAIMQQA2AgQgACgCDEEANgIIIAMoAgwgAygCEDYCACADKAIMQQA2AgQgAygCDEIANwMoQQBBAEEAEBohACADKAIMIAA2AjAgAygCDEIANwMYIAMgAygCGCADKAIUQRQgAygCDBBhNgIcCyADKAIcIQAgA0EgaiQAIAALQwEBfyMAQRBrIgMkACADIAA2AgwgAyABNgIIIAMgAjYCBCADKAIMIAMoAgggAygCBEEAQQAQsgEhACADQRBqJAAgAAtJAQF/IwBBEGsiASQAIAEgADYCDCABKAIMBEAgASgCDCgCrEAgASgCDCgCqEAoAgQRAgAgASgCDBA4IAEoAgwQFQsgAUEQaiQAC5QFAQF/IwBBMGsiBSQAIAUgADYCKCAFIAE2AiQgBSACNgIgIAUgAzoAHyAFIAQ2AhggBUEANgIMAkAgBSgCJEUEQCAFKAIoQQhqQRJBABAUIAVBADYCLAwBCyAFIAUoAiAgBS0AH0EBcRCzASIANgIMIABFBEAgBSgCKEEIakEQQQAQFCAFQQA2AiwMAQsgBSgCICEBIAUtAB9BAXEhAiAFKAIYIQMgBSgCDCEEIwBBIGsiACQAIAAgATYCGCAAIAI6ABcgACADNgIQIAAgBDYCDCAAQbDAABAYIgE2AggCQCABRQRAIABBADYCHAwBCyMAQRBrIgEgACgCCDYCDCABKAIMQQA2AgAgASgCDEEANgIEIAEoAgxBADYCCCAAKAIIAn8gAC0AF0EBcQRAIAAoAhhBf0cEfyAAKAIYQX5GBUEBC0EBcQwBC0EAC0EARzoADiAAKAIIIAAoAgw2AqhAIAAoAgggACgCGDYCFCAAKAIIIAAtABdBAXE6ABAgACgCCEEAOgAMIAAoAghBADoADSAAKAIIQQA6AA8gACgCCCgCqEAoAgAhAQJ/AkAgACgCGEF/RwRAIAAoAhhBfkcNAQtBCAwBCyAAKAIYC0H//wNxIAAoAhAgACgCCCABEQEAIQEgACgCCCABNgKsQCABRQRAIAAoAggQOCAAKAIIEBUgAEEANgIcDAELIAAgACgCCDYCHAsgACgCHCEBIABBIGokACAFIAE2AhQgAUUEQCAFKAIoQQhqQQ5BABAUIAVBADYCLAwBCyAFIAUoAiggBSgCJEETIAUoAhQQYSIANgIQIABFBEAgBSgCFBCxASAFQQA2AiwMAQsgBSAFKAIQNgIsCyAFKAIsIQAgBUEwaiQAIAALzAEBAX8jAEEgayICIAA2AhggAiABOgAXIAICfwJAIAIoAhhBf0cEQCACKAIYQX5HDQELQQgMAQsgAigCGAs7AQ4gAkEANgIQAkADQCACKAIQQdSXASgCAEkEQCACKAIQQQxsQdiXAWovAQAgAi8BDkYEQCACLQAXQQFxBEAgAiACKAIQQQxsQdiXAWooAgQ2AhwMBAsgAiACKAIQQQxsQdiXAWooAgg2AhwMAwUgAiACKAIQQQFqNgIQDAILAAsLIAJBADYCHAsgAigCHAvkAQEBfyMAQSBrIgMkACADIAA6ABsgAyABNgIUIAMgAjYCECADQcgAEBgiADYCDAJAIABFBEAgAygCEEEBQbSbASgCABAUIANBADYCHAwBCyADKAIMIAMoAhA2AgAgAygCDCADLQAbQQFxOgAEIAMoAgwgAygCFDYCCAJAIAMoAgwoAghBAU4EQCADKAIMKAIIQQlMDQELIAMoAgxBCTYCCAsgAygCDEEAOgAMIAMoAgxBADYCMCADKAIMQQA2AjQgAygCDEEANgI4IAMgAygCDDYCHAsgAygCHCEAIANBIGokACAACzgBAX8jAEEQayIBIAA2AgwgASgCDEEANgIAIAEoAgxBADYCBCABKAIMQQA2AgggASgCDEEAOgAMC+MIAQF/IwBBQGoiAiAANgI4IAIgATYCNCACIAIoAjgoAnw2AjAgAiACKAI4KAI4IAIoAjgoAmxqNgIsIAIgAigCOCgCeDYCICACIAIoAjgoApABNgIcIAICfyACKAI4KAJsIAIoAjgoAixBhgJrSwRAIAIoAjgoAmwgAigCOCgCLEGGAmtrDAELQQALNgIYIAIgAigCOCgCQDYCFCACIAIoAjgoAjQ2AhAgAiACKAI4KAI4IAIoAjgoAmxqQYICajYCDCACIAIoAiwgAigCIEEBa2otAAA6AAsgAiACKAIsIAIoAiBqLQAAOgAKIAIoAjgoAnggAigCOCgCjAFPBEAgAiACKAIwQQJ2NgIwCyACKAIcIAIoAjgoAnRLBEAgAiACKAI4KAJ0NgIcCwNAAkAgAiACKAI4KAI4IAIoAjRqNgIoAkAgAigCKCACKAIgai0AACACLQAKRw0AIAIoAiggAigCIEEBa2otAAAgAi0AC0cNACACKAIoLQAAIAIoAiwtAABHDQAgAiACKAIoIgBBAWo2AiggAC0AASACKAIsLQABRwRADAELIAIgAigCLEECajYCLCACIAIoAihBAWo2AigDQCACIAIoAiwiAEEBajYCLCAALQABIQEgAiACKAIoIgBBAWo2AigCf0EAIAAtAAEgAUcNABogAiACKAIsIgBBAWo2AiwgAC0AASEBIAIgAigCKCIAQQFqNgIoQQAgAC0AASABRw0AGiACIAIoAiwiAEEBajYCLCAALQABIQEgAiACKAIoIgBBAWo2AihBACAALQABIAFHDQAaIAIgAigCLCIAQQFqNgIsIAAtAAEhASACIAIoAigiAEEBajYCKEEAIAAtAAEgAUcNABogAiACKAIsIgBBAWo2AiwgAC0AASEBIAIgAigCKCIAQQFqNgIoQQAgAC0AASABRw0AGiACIAIoAiwiAEEBajYCLCAALQABIQEgAiACKAIoIgBBAWo2AihBACAALQABIAFHDQAaIAIgAigCLCIAQQFqNgIsIAAtAAEhASACIAIoAigiAEEBajYCKEEAIAAtAAEgAUcNABogAiACKAIsIgBBAWo2AiwgAC0AASEBIAIgAigCKCIAQQFqNgIoQQAgAC0AASABRw0AGiACKAIsIAIoAgxJC0EBcQ0ACyACQYICIAIoAgwgAigCLGtrNgIkIAIgAigCDEGCAms2AiwgAigCJCACKAIgSgRAIAIoAjggAigCNDYCcCACIAIoAiQ2AiAgAigCJCACKAIcTg0CIAIgAigCLCACKAIgQQFrai0AADoACyACIAIoAiwgAigCIGotAAA6AAoLCyACIAIoAhQgAigCNCACKAIQcUEBdGovAQAiATYCNEEAIQAgASACKAIYSwR/IAIgAigCMEEBayIANgIwIABBAEcFQQALQQFxDQELCwJAIAIoAiAgAigCOCgCdE0EQCACIAIoAiA2AjwMAQsgAiACKAI4KAJ0NgI8CyACKAI8C5IQAQF/IwBBMGsiAiQAIAIgADYCKCACIAE2AiQgAgJ/IAIoAigoAiwgAigCKCgCDEEFa0kEQCACKAIoKAIsDAELIAIoAigoAgxBBWsLNgIgIAJBADYCECACIAIoAigoAgAoAgQ2AgwDQAJAIAJB//8DNgIcIAIgAigCKCgCvC1BKmpBA3U2AhQgAigCKCgCACgCECACKAIUSQ0AIAIgAigCKCgCACgCECACKAIUazYCFCACIAIoAigoAmwgAigCKCgCXGs2AhggAigCHCACKAIYIAIoAigoAgAoAgRqSwRAIAIgAigCGCACKAIoKAIAKAIEajYCHAsgAigCHCACKAIUSwRAIAIgAigCFDYCHAsCQCACKAIcIAIoAiBPDQACQCACKAIcRQRAIAIoAiRBBEcNAQsgAigCJEUNACACKAIcIAIoAhggAigCKCgCACgCBGpGDQELDAELQQAhACACIAIoAiRBBEYEfyACKAIcIAIoAhggAigCKCgCACgCBGpGBUEAC0EBcTYCECACKAIoQQBBACACKAIQEF0gAigCKCgCCCACKAIoKAIUQQRraiACKAIcOgAAIAIoAigoAgggAigCKCgCFEEDa2ogAigCHEEIdjoAACACKAIoKAIIIAIoAigoAhRBAmtqIAIoAhxBf3M6AAAgAigCKCgCCCACKAIoKAIUQQFraiACKAIcQX9zQQh2OgAAIAIoAigoAgAQHCACKAIYBEAgAigCGCACKAIcSwRAIAIgAigCHDYCGAsgAigCKCgCACgCDCACKAIoKAI4IAIoAigoAlxqIAIoAhgQGRogAigCKCgCACIAIAIoAhggACgCDGo2AgwgAigCKCgCACIAIAAoAhAgAigCGGs2AhAgAigCKCgCACIAIAIoAhggACgCFGo2AhQgAigCKCIAIAIoAhggACgCXGo2AlwgAiACKAIcIAIoAhhrNgIcCyACKAIcBEAgAigCKCgCACACKAIoKAIAKAIMIAIoAhwQdhogAigCKCgCACIAIAIoAhwgACgCDGo2AgwgAigCKCgCACIAIAAoAhAgAigCHGs2AhAgAigCKCgCACIAIAIoAhwgACgCFGo2AhQLIAIoAhBFDQELCyACIAIoAgwgAigCKCgCACgCBGs2AgwgAigCDARAAkAgAigCDCACKAIoKAIsTwRAIAIoAihBAjYCsC0gAigCKCgCOCACKAIoKAIAKAIAIAIoAigoAixrIAIoAigoAiwQGRogAigCKCACKAIoKAIsNgJsDAELIAIoAgwgAigCKCgCPCACKAIoKAJsa08EQCACKAIoIgAgACgCbCACKAIoKAIsazYCbCACKAIoKAI4IAIoAigoAjggAigCKCgCLGogAigCKCgCbBAZGiACKAIoKAKwLUECSQRAIAIoAigiACAAKAKwLUEBajYCsC0LCyACKAIoKAI4IAIoAigoAmxqIAIoAigoAgAoAgAgAigCDGsgAigCDBAZGiACKAIoIgAgAigCDCAAKAJsajYCbAsgAigCKCACKAIoKAJsNgJcIAIoAigiAQJ/IAIoAgwgAigCKCgCLCACKAIoKAK0LWtLBEAgAigCKCgCLCACKAIoKAK0LWsMAQsgAigCDAsgASgCtC1qNgK0LQsgAigCKCgCwC0gAigCKCgCbEkEQCACKAIoIAIoAigoAmw2AsAtCwJAIAIoAhAEQCACQQM2AiwMAQsCQCACKAIkRQ0AIAIoAiRBBEYNACACKAIoKAIAKAIEDQAgAigCKCgCbCACKAIoKAJcRw0AIAJBATYCLAwBCyACIAIoAigoAjwgAigCKCgCbGtBAWs2AhQCQCACKAIoKAIAKAIEIAIoAhRNDQAgAigCKCgCXCACKAIoKAIsSA0AIAIoAigiACAAKAJcIAIoAigoAixrNgJcIAIoAigiACAAKAJsIAIoAigoAixrNgJsIAIoAigoAjggAigCKCgCOCACKAIoKAIsaiACKAIoKAJsEBkaIAIoAigoArAtQQJJBEAgAigCKCIAIAAoArAtQQFqNgKwLQsgAiACKAIoKAIsIAIoAhRqNgIUCyACKAIUIAIoAigoAgAoAgRLBEAgAiACKAIoKAIAKAIENgIUCyACKAIUBEAgAigCKCgCACACKAIoKAI4IAIoAigoAmxqIAIoAhQQdhogAigCKCIAIAIoAhQgACgCbGo2AmwLIAIoAigoAsAtIAIoAigoAmxJBEAgAigCKCACKAIoKAJsNgLALQsgAiACKAIoKAK8LUEqakEDdTYCFCACIAIoAigoAgwgAigCFGtB//8DSwR/Qf//AwUgAigCKCgCDCACKAIUaws2AhQgAgJ/IAIoAhQgAigCKCgCLEsEQCACKAIoKAIsDAELIAIoAhQLNgIgIAIgAigCKCgCbCACKAIoKAJcazYCGAJAIAIoAhggAigCIEkEQCACKAIYRQRAIAIoAiRBBEcNAgsgAigCJEUNASACKAIoKAIAKAIEDQEgAigCGCACKAIUSw0BCyACAn8gAigCGCACKAIUSwRAIAIoAhQMAQsgAigCGAs2AhwgAgJ/QQAgAigCJEEERw0AGkEAIAIoAigoAgAoAgQNABogAigCHCACKAIYRgtBAXE2AhAgAigCKCACKAIoKAI4IAIoAigoAlxqIAIoAhwgAigCEBBdIAIoAigiACACKAIcIAAoAlxqNgJcIAIoAigoAgAQHAsgAkECQQAgAigCEBs2AiwLIAIoAiwhACACQTBqJAAgAAuyAgEBfyMAQRBrIgEkACABIAA2AggCQCABKAIIEHgEQCABQX42AgwMAQsgASABKAIIKAIcKAIENgIEIAEoAggoAhwoAggEQCABKAIIKAIoIAEoAggoAhwoAgggASgCCCgCJBEEAAsgASgCCCgCHCgCRARAIAEoAggoAiggASgCCCgCHCgCRCABKAIIKAIkEQQACyABKAIIKAIc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DQAgAiEAIANBAWsiAw0ACwsgBCgCFBogASACNgKgAQwCCyMAQRBrIgAgASgCqAEoAgQ2AgwgAUEAIAAoAgxrQQJ0QajZAGooAgA2AqABDAELIAFBADYCoAELCwJAIAEoAqABRQRAIAEgASgCpAE2AqwBDAELIAEgASgCoAEQLgJ/IAEoAqQBBEAgASgCpAEQLkECagwBC0EAC2pBAWoQGCIANgIcIABFBEAgAUG4EygCADYCrAEMAQsgASgCHCEAAn8gASgCpAEEQCABKAKkAQwBC0H6EgshA0HfEkH6EiABKAKkARshAiABIAEoAqABNgIIIAEgAjYCBCABIAM2AgAgAEG+CiABEG8gASgCqAEgASgCHDYCCCABIAEoAhw2AqwBCyABKAKsASEAIAFBsAFqJAAgAAsIAEEBQTgQfwszAQF/IAAoAhQiAyABIAIgACgCECADayIBIAEgAksbIgEQGRogACAAKAIUIAFqNgIUIAILjwUCBn4BfyABIAEoAgBBD2pBcHEiAUEQajYCACAAAnwgASkDACEDIAEpAwghBiMAQSBrIggkAAJAIAZC////////////AIMiBEKAgICAgIDAgDx9IARCgICAgICAwP/DAH1UBEAgBkIEhiADQjyIhCEEIANC//////////8PgyIDQoGAgICAgICACFoEQCAEQoGAgICAgICAwAB8IQIMAgsgBEKAgICAgICAgEB9IQIgA0KAgICAgICAgAiFQgBSDQEgAiAEQgGDfCECDAELIANQIARCgICAgICAwP//AFQgBEKAgICAgIDA//8AURtFBEAgBkIEhiADQjyIhEL/////////A4NCgICAgICAgPz/AIQhAgwBC0KAgICAgICA+P8AIQIgBEL///////+//8MAVg0AQgAhAiAEQjCIpyIAQZH3AEkNACADIQIgBkL///////8/g0KAgICAgIDAAIQiBSEHAkAgAEGB9wBrIgFBwABxBEAgAiABQUBqrYYhB0IAIQIMAQsgAUUNACAHIAGtIgSGIAJBwAAgAWutiIQhByACIASGIQILIAggAjcDECAIIAc3AxgCQEGB+AAgAGsiAEHAAHEEQCAFIABBQGqtiCEDQgAhBQwBCyAARQ0AIAVBwAAgAGuthiADIACtIgKIhCEDIAUgAoghBQsgCCADNwMAIAggBTcDCCAIKQMIQgSGIAgpAwAiA0I8iIQhAiAIKQMQIAgpAxiEQgBSrSADQv//////////D4OEIgNCgYCAgICAgIAIWgRAIAJCAXwhAgwBCyADQoCAgICAgICACIVCAFINACACQgGDIAJ8IQILIAhBIGokACACIAZCgICAgICAgICAf4OEvws5AwALrRcDEn8CfgF8IwBBsARrIgkkACAJQQA2AiwCQCABvSIYQn9XBEBBASESQa4IIRMgAZoiAb0hGAwBCyAEQYAQcQRAQQEhEkGxCCETDAELQbQIQa8IIARBAXEiEhshEyASRSEXCwJAIBhCgICAgICAgPj/AINCgICAgICAgPj/AFEEQCAAQSAgAiASQQNqIg0gBEH//3txECYgACATIBIQIiAAQeQLQbUSIAVBIHEiAxtBjw1BuRIgAxsgASABYhtBAxAiDAELIAlBEGohEAJAAn8CQCABIAlBLGoQqQEiASABoCIBRAAAAAAAAAAAYgRAIAkgCSgCLCIGQQFrNgIsIAVBIHIiFEHhAEcNAQwDCyAFQSByIhRB4QBGDQIgCSgCLCELQQYgAyADQQBIGwwBCyAJIAZBHWsiCzYCLCABRAAAAAAAALBBoiEBQQYgAyADQQBIGwshCiAJQTBqIAlB0AJqIAtBAEgbIg4hBwNAIAcCfyABRAAAAAAAAPBBYyABRAAAAAAAAAAAZnEEQCABqwwBC0EACyIDNgIAIAdBBGohByABIAO4oUQAAAAAZc3NQaIiAUQAAAAAAAAAAGINAAsCQCALQQFIBEAgCyEDIAchBiAOIQgMAQsgDiEIIAshAwNAIANBHSADQR1IGyEMAkAgB0EEayIGIAhJDQAgDK0hGUIAIRgDQCAGIAY1AgAgGYYgGHwiGCAYQoCU69wDgCIYQoCU69wDfn0+AgAgCCAGQQRrIgZNBEAgGEL/////D4MhGAwBCwsgGKciA0UNACAIQQRrIgggAzYCAAsDQCAIIAciBkkEQCAGQQRrIgcoAgBFDQELCyAJIAkoAiwgDGsiAzYCLCAGIQcgA0EASg0ACwsgCkEZakEJbSEHIANBf0wEQCAHQQFqIQ0gFEHmAEYhFQNAQQlBACADayADQXdIGyEWAkAgBiAISwRAQYCU69wDIBZ2IQ9BfyAWdEF/cyERQQAhAyAIIQcDQCAHIAMgBygCACIMIBZ2ajYCACAMIBFxIA9sIQMgB0EEaiIHIAZJDQALIAggCEEEaiAIKAIAGyEIIANFDQEgBiADNgIAIAZBBGohBgwBCyAIIAhBBGogCCgCABshCAsgCSAJKAIsIBZqIgM2AiwgDiAIIBUbIgcgDUECdGogBiAGIAdrQQJ1IA1KGyEGIANBAEgNAAsLQQAhBwJAIAYgCE0NACAOIAhrQQJ1QQlsIQcgCCgCACIMQQpJDQBB5AAhAwNAIAdBAWohByADIAxLDQEgA0EKbCEDDAALAAsgCkEAIAcgFEHmAEYbayAUQecARiAKQQBHcWsiAyAGIA5rQQJ1QQlsQQlrSARAIANBgMgAaiIRQQltIgxBAnQgCUEwakEEciAJQdQCaiALQQBIG2pBgCBrIQ1BCiEDAkAgESAMQQlsayIMQQdKDQBB5AAhAwNAIAxBAWoiDEEIRg0BIANBCmwhAwwACwALAkAgDSgCACIRIBEgA24iDCADbGsiD0EBIA1BBGoiCyAGRhtFDQBEAAAAAAAA4D9EAAAAAAAA8D9EAAAAAAAA+D8gBiALRhtEAAAAAAAA+D8gDyADQQF2IgtGGyALIA9LGyEaRAEAAAAAAEBDRAAAAAAAAEBDIAxBAXEbIQECQCAXDQAgEy0AAEEtRw0AIBqaIRogAZohAQsgDSARIA9rIgs2AgAgASAaoCABYQ0AIA0gAyALaiIDNgIAIANBgJTr3ANPBEADQCANQQA2AgAgCCANQQRrIg1LBEAgCEEEayIIQQA2AgALIA0gDSgCAEEBaiIDNgIAIANB/5Pr3ANLDQALCyAOIAhrQQJ1QQlsIQcgCCgCACILQQpJDQBB5AAhAwNAIAdBAWohByADIAtLDQEgA0EKbCEDDAALAAsgDUEEaiIDIAYgAyAGSRshBgsDQCAGIgsgCE0iDEUEQCALQQRrIgYoAgBFDQELCwJAIBRB5wBHBEAgBEEIcSEPDAELIAdBf3NBfyAKQQEgChsiBiAHSiAHQXtKcSIDGyAGaiEKQX9BfiADGyAFaiEFIARBCHEiDw0AQXchBgJAIAwNACALQQRrKAIAIgNFDQBBACEGIANBCnANAEEAIQxB5AAhBgNAIAMgBnBFBEAgDEEBaiEMIAZBCmwhBgwBCwsgDEF/cyEGCyALIA5rQQJ1QQlsIQMgBUFfcUHGAEYEQEEAIQ8gCiADIAZqQQlrIgNBACADQQBKGyIDIAMgCkobIQoMAQtBACEPIAogAyAHaiAGakEJayIDQQAgA0EAShsiAyADIApKGyEKCyAKIA9yQQBHIREgAEEgIAIgBUFfcSIMQcYARgR/IAdBACAHQQBKGwUgECAHIAdBH3UiA2ogA3OtIBAQRCIGa0EBTARAA0AgBkEBayIGQTA6AAAgECAGa0ECSA0ACwsgBkECayIVIAU6AAAgBkEBa0EtQSsgB0EASBs6AAAgECAVawsgCiASaiARampBAWoiDSAEECYgACATIBIQIiAAQTAgAiANIARBgIAEcxAmAkACQAJAIAxBxgBGBEAgCUEQakEIciEDIAlBEGpBCXIhByAOIAggCCAOSxsiBSEIA0AgCDUCACAHEEQhBgJAIAUgCEcEQCAGIAlBEGpNDQEDQCAGQQFrIgZBMDoAACAGIAlBEGpLDQALDAELIAYgB0cNACAJQTA6ABggAyEGCyAAIAYgByAGaxAiIAhBBGoiCCAOTQ0AC0EAIQYgEUUNAiAAQdYSQQEQIiAIIAtPDQEgCkEBSA0BA0AgCDUCACAHEEQiBiAJQRBqSwRAA0AgBkEBayIGQTA6AAAgBiAJQRBqSw0ACwsgACAGIApBCSAKQQlIGxAiIApBCWshBiAIQQRqIgggC08NAyAKQQlKIQMgBiEKIAMNAAsMAgsCQCAKQQBIDQAgCyAIQQRqIAggC0kbIQUgCUEQakEJciELIAlBEGpBCHIhAyAIIQcDQCALIAc1AgAgCxBEIgZGBEAgCUEwOgAYIAMhBgsCQCAHIAhHBEAgBiAJQRBqTQ0BA0AgBkEBayIGQTA6AAAgBiAJQRBqSw0ACwwBCyAAIAZBARAiIAZBAWohBkEAIApBAEwgDxsNACAAQdYSQQEQIgsgACAGIAsgBmsiBiAKIAYgCkgbECIgCiAGayEKIAdBBGoiByAFTw0BIApBf0oNAAsLIABBMCAKQRJqQRJBABAmIAAgFSAQIBVrECIMAgsgCiEGCyAAQTAgBkEJakEJQQAQJgsMAQsgE0EJaiATIAVBIHEiCxshCgJAIANBC0sNAEEMIANrIgZFDQBEAAAAAAAAIEAhGgNAIBpEAAAAAAAAMECiIRogBkEBayIGDQALIAotAABBLUYEQCAaIAGaIBqhoJohAQwBCyABIBqgIBqhIQELIBAgCSgCLCIGIAZBH3UiBmogBnOtIBAQRCIGRgRAIAlBMDoADyAJQQ9qIQYLIBJBAnIhDiAJKAIsIQcgBkECayIMIAVBD2o6AAAgBkEBa0EtQSsgB0EASBs6AAAgBEEIcSEHIAlBEGohCANAIAgiBQJ/IAGZRAAAAAAAAOBBYwRAIAGqDAELQYCAgIB4CyIGQYCHAWotAAAgC3I6AAAgASAGt6FEAAAAAAAAMECiIQECQCAFQQFqIgggCUEQamtBAUcNAAJAIAFEAAAAAAAAAABiDQAgA0EASg0AIAdFDQELIAVBLjoAASAFQQJqIQgLIAFEAAAAAAAAAABiDQALIABBICACIA4CfwJAIANFDQAgCCAJa0ESayADTg0AIAMgEGogDGtBAmoMAQsgECAJQRBqIAxqayAIagsiA2oiDSAEECYgACAKIA4QIiAAQTAgAiANIARBgIAEcxAmIAAgCUEQaiAIIAlBEGprIgUQIiAAQTAgAyAFIBAgDGsiA2prQQBBABAmIAAgDCADECILIABBICACIA0gBEGAwABzECYgCUGwBGokACACIA0gAiANShsLBgBB4J8BCwYAQdyfAQsGAEHUnwELGAEBfyMAQRBrIgEgADYCDCABKAIMQQRqCxgBAX8jAEEQayIBIAA2AgwgASgCDEEIagtpAQF/IwBBEGsiASQAIAEgADYCDCABKAIMKAIUBEAgASgCDCgCFBAbCyABQQA2AgggASgCDCgCBARAIAEgASgCDCgCBDYCCAsgASgCDEEEahA4IAEoAgwQFSABKAIIIQAgAUEQaiQAIAALqQEBA38CQCAALQAAIgJFDQADQCABLQAAIgRFBEAgAiEDDAILAkAgAiAERg0AIAJBIHIgAiACQcEAa0EaSRsgAS0AACICQSByIAIgAkHBAGtBGkkbRg0AIAAtAAAhAwwCCyABQQFqIQEgAC0AASECIABBAWohACACDQALCyADQf8BcSIAQSByIAAgAEHBAGtBGkkbIAEtAAAiAEEgciAAIABBwQBrQRpJG2sLiAEBAX8jAEEQayICJAAgAiAANgIMIAIgATYCCCMAQRBrIgAgAigCDDYCDCAAKAIMQQA2AgAgACgCDEEANgIEIAAoAgxBADYCCCACKAIMIAIoAgg2AgACQCACKAIMEKwBQQFGBEAgAigCDEG0mwEoAgA2AgQMAQsgAigCDEEANgIECyACQRBqJAAL2AkBAX8jAEGwAWsiBSQAIAUgADYCpAEgBSABNgKgASAFIAI2ApwBIAUgAzcDkAEgBSAENgKMASAFIAUoAqABNgKIAQJAAkACQAJAAkACQAJAAkACQAJAAkAgBSgCjAEODwABAgMEBQcICQkJCQkJBgkLIAUoAogBQgA3AyAgBUIANwOoAQwJCyAFIAUoAqQBIAUoApwBIAUpA5ABECsiAzcDgAEgA0IAUwRAIAUoAogBQQhqIAUoAqQBEBcgBUJ/NwOoAQwJCwJAIAUpA4ABUARAIAUoAogBKQMoIAUoAogBKQMgUQRAIAUoAogBQQE2AgQgBSgCiAEgBSgCiAEpAyA3AxggBSgCiAEoAgAEQCAFKAKkASAFQcgAahA5QQBIBEAgBSgCiAFBCGogBSgCpAEQFyAFQn83A6gBDA0LAkAgBSkDSEIgg1ANACAFKAJ0IAUoAogBKAIwRg0AIAUoAogBQQhqQQdBABAUIAVCfzcDqAEMDQsCQCAFKQNIQgSDUA0AIAUpA2AgBSgCiAEpAxhRDQAgBSgCiAFBCGpBFUEAEBQgBUJ/NwOoAQwNCwsLDAELAkAgBSgCiAEoAgQNACAFKAKIASkDICAFKAKIASkDKFYNACAFIAUoAogBKQMoIAUoAogBKQMgfTcDQANAIAUpA0AgBSkDgAFUBEAgBSAFKQOAASAFKQNAfUL/////D1YEfkL/////DwUgBSkDgAEgBSkDQH0LNwM4IAUoAogBKAIwIAUoApwBIAUpA0CnaiAFKQM4pxAaIQAgBSgCiAEgADYCMCAFKAKIASIAIAUpAzggACkDKHw3AyggBSAFKQM4IAUpA0B8NwNADAELCwsLIAUoAogBIgAgBSkDgAEgACkDIHw3AyAgBSAFKQOAATcDqAEMCAsgBUIANwOoAQwHCyAFIAUoApwBNgI0IAUoAogBKAIEBEAgBSgCNCAFKAKIASkDGDcDGCAFKAI0IAUoAogBKAIwNgIsIAUoAjQgBSgCiAEpAxg3AyAgBSgCNEEAOwEwIAUoAjRBADsBMiAFKAI0IgAgACkDAELsAYQ3AwALIAVCADcDqAEMBgsgBSAFKAKIAUEIaiAFKAKcASAFKQOQARBDNwOoAQwFCyAFKAKIARAVIAVCADcDqAEMBAsjAEEQayIAIAUoAqQBNgIMIAUgACgCDCkDGDcDKCAFKQMoQgBTBEAgBSgCiAFBCGogBSgCpAEQFyAFQn83A6gBDAQLIAUpAyghAyAFQX82AhggBUEQNgIUIAVBDzYCECAFQQ02AgwgBUEMNgIIIAVBCjYCBCAFQQk2AgAgBUEIIAUQNEJ/hSADgzcDqAEMAwsgBQJ/IAUpA5ABQhBUBEAgBSgCiAFBCGpBEkEAEBRBAAwBCyAFKAKcAQs2AhwgBSgCHEUEQCAFQn83A6gBDAMLAkAgBSgCpAEgBSgCHCkDACAFKAIcKAIIECdBAE4EQCAFIAUoAqQBEEkiAzcDICADQgBZDQELIAUoAogBQQhqIAUoAqQBEBcgBUJ/NwOoAQwDCyAFKAKIASAFKQMgNwMgIAVCADcDqAEMAgsgBSAFKAKIASkDIDcDqAEMAQsgBSgCiAFBCGpBHEEAEBQgBUJ/NwOoAQsgBSkDqAEhAyAFQbABaiQAIAMLnAwBAX8jAEEwayIFJAAgBSAANgIkIAUgATYCICAFIAI2AhwgBSADNwMQIAUgBDYCDCAFIAUoAiA2AggCQAJAAkACQAJAAkACQAJAAkACQCAFKAIMDhEAAQIDBQYICAgICAgICAcIBAgLIAUoAghCADcDGCAFKAIIQQA6AAwgBSgCCEEAOgANIAUoAghBADoADyAFKAIIQn83AyAgBSgCCCgCrEAgBSgCCCgCqEAoAgwRAABBAXFFBEAgBUJ/NwMoDAkLIAVCADcDKAwICyAFKAIkIQEgBSgCCCECIAUoAhwhBCAFKQMQIQMjAEFAaiIAJAAgACABNgI0IAAgAjYCMCAAIAQ2AiwgACADNwMgAkACfyMAQRBrIgEgACgCMDYCDCABKAIMKAIACwRAIABCfzcDOAwBCwJAIAApAyBQRQRAIAAoAjAtAA1BAXFFDQELIABCADcDOAwBCyAAQgA3AwggAEEAOgAbA0AgAC0AG0EBcQR/QQAFIAApAwggACkDIFQLQQFxBEAgACAAKQMgIAApAwh9NwMAIAAgACgCMCgCrEAgACgCLCAAKQMIp2ogACAAKAIwKAKoQCgCHBEBADYCHCAAKAIcQQJHBEAgACAAKQMAIAApAwh8NwMICwJAAkACQAJAIAAoAhxBAWsOAwACAQMLIAAoAjBBAToADQJAIAAoAjAtAAxBAXENAAsgACgCMCkDIEIAUwRAIAAoAjBBFEEAEBQgAEEBOgAbDAMLAkAgACgCMC0ADkEBcUUNACAAKAIwKQMgIAApAwhWDQAgACgCMEEBOgAPIAAoAjAgACgCMCkDIDcDGCAAKAIsIAAoAjBBKGogACgCMCkDGKcQGRogACAAKAIwKQMYNwM4DAYLIABBAToAGwwCCyAAKAIwLQAMQQFxBEAgAEEBOgAbDAILIAAgACgCNCAAKAIwQShqQoDAABArIgM3AxAgA0IAUwRAIAAoAjAgACgCNBAXIABBAToAGwwCCwJAIAApAxBQBEAgACgCMEEBOgAMIAAoAjAoAqxAIAAoAjAoAqhAKAIYEQIAIAAoAjApAyBCAFMEQCAAKAIwQgA3AyALDAELAkAgACgCMCkDIEIAWQRAIAAoAjBBADoADgwBCyAAKAIwIAApAxA3AyALIAAoAjAoAqxAIAAoAjBBKGogACkDECAAKAIwKAKoQCgCFBEQABoLDAELAn8jAEEQayIBIAAoAjA2AgwgASgCDCgCAEULBEAgACgCMEEUQQAQFAsgAEEBOgAbCwwBCwsgACkDCEIAUgRAIAAoAjBBADoADiAAKAIwIgEgACkDCCABKQMYfDcDGCAAIAApAwg3AzgMAQsgAEF/QQACfyMAQRBrIgEgACgCMDYCDCABKAIMKAIACxusNwM4CyAAKQM4IQMgAEFAayQAIAUgAzcDKAwHCyAFKAIIKAKsQCAFKAIIKAKoQCgCEBEAAEEBcUUEQCAFQn83AygMBwsgBUIANwMoDAYLIAUgBSgCHDYCBAJAIAUoAggtABBBAXEEQCAFKAIILQANQQFxBEAgBSgCBCAFKAIILQAPQQFxBH9BAAUCfwJAIAUoAggoAhRBf0cEQCAFKAIIKAIUQX5HDQELQQgMAQsgBSgCCCgCFAtB//8DcQs7ATAgBSgCBCAFKAIIKQMYNwMgIAUoAgQiACAAKQMAQsgAhDcDAAwCCyAFKAIEIgAgACkDAEK3////D4M3AwAMAQsgBSgCBEEAOwEwIAUoAgQiACAAKQMAQsAAhDcDAAJAIAUoAggtAA1BAXEEQCAFKAIEIAUoAggpAxg3AxggBSgCBCIAIAApAwBCBIQ3AwAMAQsgBSgCBCIAIAApAwBC+////w+DNwMACwsgBUIANwMoDAULIAUgBSgCCC0AD0EBcQR/QQAFIAUoAggoAqxAIAUoAggoAqhAKAIIEQAAC6w3AygMBAsgBSAFKAIIIAUoAhwgBSkDEBBDNwMoDAMLIAUoAggQsQEgBUIANwMoDAILIAVBfzYCACAFQRAgBRA0Qj+ENwMoDAELIAUoAghBFEEAEBQgBUJ/NwMoCyAFKQMoIQMgBUEwaiQAIAMLPAEBfyMAQRBrIgMkACADIAA7AQ4gAyABNgIIIAMgAjYCBEEAIAMoAgggAygCBBC0ASEAIANBEGokACAAC46nAQEEfyMAQSBrIgUkACAFIAA2AhggBSABNgIUIAUgAjYCECAFIAUoAhg2AgwgBSgCDCAFKAIQKQMAQv////8PVgR+Qv////8PBSAFKAIQKQMACz4CICAFKAIMIAUoAhQ2AhwCQCAFKAIMLQAEQQFxBEAgBSgCDEEQaiEBQQRBACAFKAIMLQAMQQFxGyECIwBBQGoiACQAIAAgATYCOCAAIAI2AjQCQAJAAkAgACgCOBB4DQAgACgCNEEFSg0AIAAoAjRBAE4NAQsgAEF+NgI8DAELIAAgACgCOCgCHDYCLAJAAkAgACgCOCgCDEUNACAAKAI4KAIEBEAgACgCOCgCAEUNAQsgACgCLCgCBEGaBUcNASAAKAI0QQRGDQELIAAoAjhBsNkAKAIANgIYIABBfjYCPAwBCyAAKAI4KAIQRQRAIAAoAjhBvNkAKAIANgIYIABBezYCPAwBCyAAIAAoAiwoAig2AjAgACgCLCAAKAI0NgIoAkAgACgCLCgCFARAIAAoAjgQHCAAKAI4KAIQRQRAIAAoAixBfzYCKCAAQQA2AjwMAwsMAQsCQCAAKAI4KAIEDQAgACgCNEEBdEEJQQAgACgCNEEEShtrIAAoAjBBAXRBCUEAIAAoAjBBBEoba0oNACAAKAI0QQRGDQAgACgCOEG82QAoAgA2AhggAEF7NgI8DAILCwJAIAAoAiwoAgRBmgVHDQAgACgCOCgCBEUNACAAKAI4QbzZACgCADYCGCAAQXs2AjwMAQsgACgCLCgCBEEqRgRAIAAgACgCLCgCMEEEdEH4AGtBCHQ2AigCQAJAIAAoAiwoAogBQQJIBEAgACgCLCgChAFBAk4NAQsgAEEANgIkDAELAkAgACgCLCgChAFBBkgEQCAAQQE2AiQMAQsCQCAAKAIsKAKEAUEGRgRAIABBAjYCJAwBCyAAQQM2AiQLCwsgACAAKAIoIAAoAiRBBnRyNgIoIAAoAiwoAmwEQCAAIAAoAihBIHI2AigLIAAgACgCKEEfIAAoAihBH3BrajYCKCAAKAIsIAAoAigQSyAAKAIsKAJsBEAgACgCLCAAKAI4KAIwQRB2EEsgACgCLCAAKAI4KAIwQf//A3EQSwtBAEEAQQAQPSEBIAAoAjggATYCMCAAKAIsQfEANgIEIAAoAjgQHCAAKAIsKAIUBEAgACgCLEF/NgIoIABBADYCPAwCCwsgACgCLCgCBEE5RgRAQQBBAEEAEBohASAAKAI4IAE2AjAgACgCLCgCCCECIAAoAiwiAygCFCEBIAMgAUEBajYCFCABIAJqQR86AAAgACgCLCgCCCECIAAoAiwiAygCFCEBIAMgAUEBajYCFCABIAJqQYsBOgAAIAAoAiwoAgghAiAAKAIsIgMoAhQhASADIAFBAWo2AhQgASACakEIOgAAAkAgACgCLCgCHEUEQCAAKAIsKAIIIQIgACgCLCIDKAIUIQEgAyABQQFqNgIUIAEgAmpBADoAACAAKAIsKAIIIQIgACgCLCIDKAIUIQEgAyABQQFqNgIUIAEgAmpBADoAACAAKAIsKAIIIQIgACgCLCIDKAIUIQEgAyABQQFqNgIUIAEgAmpBADoAACAAKAIsKAIIIQIgACgCLCIDKAIUIQEgAyABQQFqNgIUIAEgAmpBADoAACAAKAIsKAIIIQIgACgCLCIDKAIUIQEgAyABQQFqNgIUIAEgAmpBADoAACAAKAIsKAKEAUEJRgR/QQIFQQRBACAAKAIsKAKIAUECSAR/IAAoAiwoAoQBQQJIBUEBC0EBcRsLIQIgACgCLCgCCCEDIAAoAiwiBCgCFCEBIAQgAUEBajYCFCABIANqIAI6AAAgACgCLCgCCCECIAAoAiwiAygCFCEBIAMgAUEBajYCFCABIAJqQQM6AAAgACgCLEHxADYCBCAAKAI4EBwgACgCLCgCFARAIAAoAixBfzYCKCAAQQA2AjwMBAsMAQsgACgCLCgCHCgCAEVFQQJBACAAKAIsKAIcKAIsG2pBBEEAIAAoAiwoAhwoAhAbakEIQQAgACgCLCgCHCgCHBtqQRBBACAAKAIsKAIcKAIkG2ohAiAAKAIsKAIIIQMgACgCLCIEKAIUIQEgBCABQQFqNgIUIAEgA2ogAjoAACAAKAIsKAIcKAIEQf8BcSECIAAoAiwoAgghAyAAKAIsIgQoAhQhASAEIAFBAWo2AhQgASADaiACOgAAIAAoAiwoAhwoAgRBCHZB/wFxIQIgACgCLCgCCCEDIAAoAiwiBCgCFCEBIAQgAUEBajYCFCABIANqIAI6AAAgACgCLCgCHCgCBEEQdkH/AXEhAiAAKAIsKAIIIQMgACgCLCIEKAIUIQEgBCABQQFqNgIUIAEgA2ogAjoAACAAKAIsKAIcKAIEQRh2IQIgACgCLCgCCCEDIAAoAiwiBCgCFCEBIAQgAUEBajYCFCABIANqIAI6AAAgACgCLCgChAFBCUYEf0ECBUEEQQAgACgCLCgCiAFBAkgEfyAAKAIsKAKEAUECSAVBAQtBAXEbCyECIAAoAiwoAgghAyAAKAIsIgQoAhQhASAEIAFBAWo2AhQgASADaiACOgAAIAAoAiwoAhwoAgxB/wFxIQIgACgCLCgCCCEDIAAoAiwiBCgCFCEBIAQgAUEBajYCFCABIANqIAI6AAAgACgCLCgCHCgCEARAIAAoAiwoAhwoAhRB/wFxIQIgACgCLCgCCCEDIAAoAiwiBCgCFCEBIAQgAUEBajYCFCABIANqIAI6AAAgACgCLCgCHCgCFEEIdkH/AXEhAiAAKAIsKAIIIQMgACgCLCIEKAIUIQEgBCABQQFqNgIUIAEgA2ogAjoAAAsgACgCLCgCHCgCLARAIAAoAjgoAjAgACgCLCgCCCAAKAIsKAIUEBohASAAKAI4IAE2AjALIAAoAixBADYCICAAKAIsQcUANgIECwsgACgCLCgCBEHFAEYEQCAAKAIsKAIcKAIQBEAgACAAKAIsKAIUNgIgIAAgACgCLCgCHCgCFEH//wNxIAAoAiwoAiBrNgIcA0AgACgCLCgCDCAAKAIsKAIUIAAoAhxqSQRAIAAgACgCLCgCDCAAKAIsKAIUazYCGCAAKAIsKAIIIAAoAiwoAhRqIAAoAiwoAhwoAhAgACgCLCgCIGogACgCGBAZGiAAKAIsIAAoAiwoAgw2AhQCQCAAKAIsKAIcKAIsRQ0AIAAoAiwoAhQgACgCIE0NACAAKAI4KAIwIAAoAiwoAgggACgCIGogACgCLCgCFCAAKAIgaxAaIQEgACgCOCABNgIwCyAAKAIsIgEgACgCGCABKAIgajYCICAAKAI4EBwgACgCLCgCFARAIAAoAixBfzYCKCAAQQA2AjwMBQUgAEEANgIgIAAgACgCHCAAKAIYazYCHAwCCwALCyAAKAIsKAIIIAAoAiwoAhRqIAAoAiwoAhwoAhAgACgCLCgCIGogACgCHBAZGiAAKAIsIgEgACgCHCABKAIUajYCFAJAIAAoAiwoAhwoAixFDQAgACgCLCgCFCAAKAIgTQ0AIAAoAjgoAjAgACgCLCgCCCAAKAIgaiAAKAIsKAIUIAAoAiBrEBohASAAKAI4IAE2AjALIAAoAixBADYCIAsgACgCLEHJADYCBAsgACgCLCgCBEHJAEYEQCAAKAIsKAIcKAIcBEAgACAAKAIsKAIUNgIUA0AgACgCLCgCFCAAKAIsKAIMRgRAAkAgACgCLCgCHCgCLEUNACAAKAIsKAIUIAAoAhRNDQAgACgCOCgCMCAAKAIsKAIIIAAoAhRqIAAoAiwoAhQgACgCFGsQGiEBIAAoAjggATYCMAsgACgCOBAcIAAoAiwoAhQEQCAAKAIsQX82AiggAEEANgI8DAULIABBADYCFAsgACgCLCgCHCgCHCECIAAoAiwiAygCICEBIAMgAUEBajYCICAAIAEgAmotAAA2AhAgACgCECECIAAoAiwoAgghAyAAKAIsIgQoAhQhASAEIAFBAWo2AhQgASADaiACOgAAIAAoAhANAAsCQCAAKAIsKAIcKAIsRQ0AIAAoAiwoAhQgACgCFE0NACAAKAI4KAIwIAAoAiwoAgggACgCFGogACgCLCgCFCAAKAIUaxAaIQEgACgCOCABNgIwCyAAKAIsQQA2AiALIAAoAixB2wA2AgQLIAAoAiwoAgRB2wBGBEAgACgCLCgCHCgCJARAIAAgACgCLCgCFDYCDANAIAAoAiwoAhQgACgCLCgCDEYEQAJAIAAoAiwoAhwoAixFDQAgACgCLCgCFCAAKAIMTQ0AIAAoAjgoAjAgACgCLCgCCCAAKAIMaiAAKAIsKAIUIAAoAgxrEBohASAAKAI4IAE2AjALIAAoAjgQHCAAKAIsKAIUBEAgACgCLEF/NgIoIABBADYCPAwFCyAAQQA2AgwLIAAoAiwoAhwoAiQhAiAAKAIsIgMoAiAhASADIAFBAWo2AiAgACABIAJqLQAANgIIIAAoAgghAiAAKAIsKAIIIQMgACgCLCIEKAIUIQEgBCABQQFqNgIUIAEgA2ogAjoAACAAKAIIDQALAkAgACgCLCgCHCgCLEUNACAAKAIsKAIUIAAoAgxNDQAgACgCOCgCMCAAKAIsKAIIIAAoAgxqIAAoAiwoAhQgACgCDGsQGiEBIAAoAjggATYCMAsLIAAoAixB5wA2AgQLIAAoAiwoAgRB5wBGBEAgACgCLCgCHCgCLARAIAAoAiwoAgwgACgCLCgCFEECakkEQCAAKAI4EBwgACgCLCgCFARAIAAoAixBfzYCKCAAQQA2AjwMBAsLIAAoAjgoAjBB/wFxIQIgACgCLCgCCCEDIAAoAiwiBCgCFCEBIAQgAUEBajYCFCABIANqIAI6AAAgACgCOCgCMEEIdkH/AXEhAiAAKAIsKAIIIQMgACgCLCIEKAIUIQEgBCABQQFqNgIUIAEgA2ogAjoAAEEAQQBBABAaIQEgACgCOCABNgIwCyAAKAIsQfEANgIEIAAoAjgQHCAAKAIsKAIUBEAgACgCLEF/NgIoIABBADYCPAwCCwsCQAJAIAAoAjgoAgQNACAAKAIsKAJ0DQAgACgCNEUNASAAKAIsKAIEQZoFRg0BCyAAAn8gACgCLCgChAFFBEAgACgCLCAAKAI0ELcBDAELAn8gACgCLCgCiAFBAkYEQCAAKAIsIQIgACgCNCEDIwBBIGsiASQAIAEgAjYCGCABIAM2AhQCQANAAkAgASgCGCgCdEUEQCABKAIYEFwgASgCGCgCdEUEQCABKAIURQRAIAFBADYCHAwFCwwCCwsgASgCGEEANgJgIAEgASgCGCICKAI4IAIoAmxqLQAAOgAPIAEoAhgiAigCpC0gAigCoC1BAXRqQQA7AQAgAS0ADyEDIAEoAhgiAigCmC0hBCACIAIoAqAtIgJBAWo2AqAtIAIgBGogAzoAACABKAIYIAEtAA9BAnRqIgIgAi8BlAFBAWo7AZQBIAEgASgCGCgCoC0gASgCGCgCnC1BAWtGNgIQIAEoAhgiAiACKAJ0QQFrNgJ0IAEoAhgiAiACKAJsQQFqNgJsIAEoAhAEQCABKAIYAn8gASgCGCgCXEEATgRAIAEoAhgoAjggASgCGCgCXGoMAQtBAAsgASgCGCgCbCABKAIYKAJca0EAECggASgCGCABKAIYKAJsNgJcIAEoAhgoAgAQHCABKAIYKAIAKAIQRQRAIAFBADYCHAwECwsMAQsLIAEoAhhBADYCtC0gASgCFEEERgRAIAEoAhgCfyABKAIYKAJcQQBOBEAgASgCGCgCOCABKAIYKAJcagwBC0EACyABKAIYKAJsIAEoAhgoAlxrQQEQKCABKAIYIAEoAhgoAmw2AlwgASgCGCgCABAcIAEoAhgoAgAoAhBFBEAgAUECNgIcDAILIAFBAzYCHAwBCyABKAIYKAKgLQRAIAEoAhgCfyABKAIYKAJcQQBOBEAgASgCGCgCOCABKAIYKAJcagwBC0EACyABKAIYKAJsIAEoAhgoAlxrQQAQKCABKAIYIAEoAhgoAmw2AlwgASgCGCgCABAcIAEoAhgoAgAoAhBFBEAgAUEANgIcDAILCyABQQE2AhwLIAEoAhwhAiABQSBqJAAgAgwBCwJ/IAAoAiwoAogBQQNGBEAgACgCLCECIAAoAjQhAyMAQTBrIgEkACABIAI2AiggASADNgIkAkADQAJAIAEoAigoAnRBggJNBEAgASgCKBBcAkAgASgCKCgCdEGCAksNACABKAIkDQAgAUEANgIsDAQLIAEoAigoAnRFDQELIAEoAihBADYCYAJAIAEoAigoAnRBA0kNACABKAIoKAJsRQ0AIAEgASgCKCgCOCABKAIoKAJsakEBazYCGCABIAEoAhgtAAA2AhwgASgCHCECIAEgASgCGCIDQQFqNgIYAkAgAy0AASACRw0AIAEoAhwhAiABIAEoAhgiA0EBajYCGCADLQABIAJHDQAgASgCHCECIAEgASgCGCIDQQFqNgIYIAMtAAEgAkcNACABIAEoAigoAjggASgCKCgCbGpBggJqNgIUA0AgASgCHCECIAEgASgCGCIDQQFqNgIYAn9BACADLQABIAJHDQAaIAEoAhwhAiABIAEoAhgiA0EBajYCGEEAIAMtAAEgAkcNABogASgCHCECIAEgASgCGCIDQQFqNgIYQQAgAy0AASACRw0AGiABKAIcIQIgASABKAIYIgNBAWo2AhhBACADLQABIAJHDQAaIAEoAhwhAiABIAEoAhgiA0EBajYCGEEAIAMtAAEgAkcNABogASgCHCECIAEgASgCGCIDQQFqNgIYQQAgAy0AASACRw0AGiABKAIcIQIgASABKAIYIgNBAWo2AhhBACADLQABIAJHDQAaIAEoAhwhAiABIAEoAhgiA0EBajYCGEEAIAMtAAEgAkcNABog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AS8BEiECIAEgASgCSCIDQQFqNgJIIAMgAjoAAAwCCyABKAIMQRBxBEAgASABLwESNgIIIAEgASgCDEEPcTYCDCABKAIMBEAgASgCKCABKAIMSQRAIAEgASgCUCICQQFqNgJQIAEgASgCLCACLQAAIAEoAih0ajYCLCABIAEoAihBCGo2AigLIAEgASgCCCABKAIsQQEgASgCDHRBAWtxajYCCCABIAEoAiwgASgCDHY2AiwgASABKAIoIAEoAgxrNgIoCyABKAIoQQ9JBEAgASABKAJQIgJBAWo2AlAgASABKAIsIAItAAAgASgCKHRqNgIsIAEgASgCKEEIajYCKCABIAEoAlAiAkEBajYCUCABIAEoAiwgAi0AACABKAIodGo2AiwgASABKAIoQQhqNgIoCyABIAEoAiAgASgCLCABKAIYcUECdGooAQA2ARACQANAIAEgAS0AETYCDCABIAEoAiwgASgCDHY2AiwgASABKAIoIAEoAgxrNgIoIAEgAS0AEDYCDCABKAIMQRBxBEAgASABLwESNgIEIAEgASgCDEEPcTYCDCABKAIoIAEoAgxJBEAgASABKAJQIgJBAWo2AlAgASABKAIsIAItAAAgASgCKHRqNgIsIAEgASgCKEEIajYCKCABKAIoIAEoAgxJBEAgASABKAJQIgJBAWo2AlAgASABKAIsIAItAAAgASgCKHRqNgIsIAEgASgCKEEIajYCKAsLIAEgASgCBCABKAIsQQEgASgCDHRBAWtxajYCBCABIAEoAiwgASgCDHY2AiwgASABKAIoIAEoAgxrNgIoIAEgASgCSCABKAJEazYCDAJAIAEoAgQgASgCDEsEQCABIAEoAgQgASgCDGs2AgwgASgCDCABKAI4SwRAIAEoAlQoAsQ3BEAgASgCXEHdDDYCGCABKAJUQdH+ADYCBAwKCwsgASABKAIwNgIAAkAgASgCNEUEQCABIAEoAgAgASgCPCABKAIMa2o2AgAgASgCDCABKAIISQRAIAEgASgCCCABKAIMazYCCANAIAEgASgCACICQQFqNgIAIAItAAAhAiABIAEoAkgiA0EBajYCSCADIAI6AAAgASABKAIMQQFrIgI2AgwgAg0ACyABIAEoAkggASgCBGs2AgALDAELAkAgASgCNCABKAIMSQRAIAEgASgCACABKAI8IAEoAjRqIAEoAgxrajYCACABIAEoAgwgASgCNGs2AgwgASgCDCABKAIISQRAIAEgASgCCCABKAIMazYCCANAIAEgASgCACICQQFqNgIAIAItAAAhAiABIAEoAkgiA0EBajYCSCADIAI6AAAgASABKAIMQQFrIgI2AgwgAg0ACyABIAEoAjA2AgAgASgCNCABKAIISQRAIAEgASgCNDYCDCABIAEoAgggASgCDGs2AggDQCABIAEoAgAiAkEBajYCACACLQAAIQIgASABKAJIIgNBAWo2AkggAyACOgAAIAEgASgCDEEBayICNgIMIAINAAsgASABKAJIIAEoAgRrNgIACwsMAQsgASABKAIAIAEoAjQgASgCDGtqNgIAIAEoAgwgASgCCEkEQCABIAEoAgggASgCDGs2AggDQCABIAEoAgAiAkEBajYCACACLQAAIQIgASABKAJIIgNBAWo2AkggAyACOgAAIAEgASgCDEEBayICNgIMIAINAAsgASABKAJIIAEoAgRrNgIACwsLA0AgASgCCEECSwRAIAEgASgCACICQQFqNgIAIAItAAAhAiABIAEoAkgiA0EBajYCSCADIAI6AAAgASABKAIAIgJBAWo2AgAgAi0AACECIAEgASgCSCIDQQFqNgJIIAMgAjoAACABIAEoAgAiAkEBajYCACACLQAAIQIgASABKAJIIgNBAWo2AkggAyACOgAAIAEgASgCCEEDazYCCAwBCwsMAQsgASABKAJIIAEoAgRrNgIAA0AgASABKAIAIgJBAWo2AgAgAi0AACECIAEgASgCSCIDQQFqNgJIIAMgAjoAACABIAEoAgAiAkEBajYCACACLQAAIQIgASABKAJIIgNBAWo2AkggAyACOgAAIAEgASgCACICQQFqNgIAIAItAAAhAiABIAEoAkgiA0EBajYCSCADIAI6AAAgASABKAIIQQNrNgIIIAEoAghBAksNAAsLIAEoAggEQCABIAEoAgAiAkEBajYCACACLQAAIQIgASABKAJIIgNBAWo2AkggAyACOgAAIAEoAghBAUsEQCABIAEoAgAiAkEBajYCACACLQAAIQIgASABKAJIIgNBAWo2AkggAyACOgAACwsMAgsgASgCDEHAAHFFBEAgASABKAIgIAEvARIgASgCLEEBIAEoAgx0QQFrcWpBAnRqKAEANgEQDAELCyAB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AG5hbgAvZGV2L3VyYW5kb20AaW52YWxpZCBjb2RlIC0tIG1pc3NpbmcgZW5kLW9mLWJsb2NrAGluY29ycmVjdCBoZWFkZXIgY2hlY2sAaW5jb3JyZWN0IGxlbmd0aCBjaGVjawBpbmNvcnJlY3QgZGF0YSBjaGVjawBpbnZhbGlkIGRpc3RhbmNlIHRvbyBmYXIgYmFjawBoZWFkZXIgY3JjIG1pc21hdGNoAGluZgBpbnZhbGlkIHdpbmRvdyBzaXplAFJlYWQtb25seSBhcmNoaXZlAE5vdCBhIHppcCBhcmNoaXZlAFJlc291cmNlIHN0aWxsIGluIHVzZQBNYWxsb2MgZmFpbHVyZQBpbnZhbGlkIGJsb2NrIHR5cGUARmFpbHVyZSB0byBjcmVhdGUgdGVtcG9yYXJ5IGZpbGUAQ2FuJ3Qgb3BlbiBmaWxlAE5vIHN1Y2ggZmlsZQBQcmVtYXR1cmUgZW5kIG9mIGZpbGUAQ2FuJ3QgcmVtb3ZlIGZpbGUAaW52YWxpZCBsaXRlcmFsL2xlbmd0aCBjb2RlAGludmFsaWQgZGlzdGFuY2UgY29kZQB1bmtub3duIGNvbXByZXNzaW9uIG1ldGhvZABzdHJlYW0gZW5kAENvbXByZXNzZWQgZGF0YSBpbnZhbGlkAE11bHRpLWRpc2sgemlwIGFyY2hpdmVzIG5vdCBzdXBwb3J0ZWQAT3BlcmF0aW9uIG5vdCBzdXBwb3J0ZWQARW5jcnlwdGlvbiBtZXRob2Qgbm90IHN1cHBvcnRlZABDb21wcmVzc2lvbiBtZXRob2Qgbm90IHN1cHBvcnRlZABFbnRyeSBoYXMgYmVlbiBkZWxldGVkAENvbnRhaW5pbmcgemlwIGFyY2hpdmUgd2FzIGNsb3NlZABDbG9zaW5nIHppcCBhcmNoaXZlIGZhaWxlZABSZW5hbWluZyB0ZW1wb3JhcnkgZmlsZSBmYWlsZWQARW50cnkgaGFzIGJlZW4gY2hhbmdlZABObyBwYXNzd29yZCBwcm92aWRlZABXcm9uZyBwYXNzd29yZCBwcm92aWRlZABVbmtub3duIGVycm9yICVkAHJiAHIrYgByd2EAJXMuWFhYWFhYAE5BTgBJTkYAQUUAMS4yLjExAC9wcm9jL3NlbGYvZmQvAC4AKG51bGwpADogAFBLBgcA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0gAIADIACACyAAgAcgAIAPIACAAKAAgAigAIAEoACADKAAgAKgAIAKoACABqAAgA6gAIABoACACaAAgAWgAIANoACAA6AAgAugAIAHoACAD6AAgABgAIAIYACABGAAgAxgAIACYACACmAAgAZgAIAOYACAAWAAgAlgAIAFYACADWAAgANgAIALYACAB2AAgA9gAIAA4ACACOAAgATgAIAM4ACAAuAAgArgAIAG4ACADuAAgAHgAIAJ4ACABeAAgA3gAIAD4ACAC+AAgAfgAIAP4ACAABAAgAgQAIAEEACADBAAgAIQAIAKEACABhAAgA4QAIABEACACRAAgAUQAIANEACAAxAAgAsQAIAHEACADxAAgACQAIAIkACABJAAgAyQAIACkACACpAAgAaQAIAOkACAAZAAgAmQAIAFkACADZAAgAOQAIALkACAB5AAgA+QAIAAUACACFAAgARQAIAMUACAAlAAgApQAIAGUACADlAAgAFQAIAJUACABVAAgA1QAIADUACAC1AAgAdQAIAPUACAANAAgAjQAIAE0ACADNAAgALQAIAK0ACABtAAgA7QAIAB0ACACdAAgAXQAIAN0ACAA9AAgAvQAIAH0ACAD9AAgAEwAJABMBCQCTAAkAkwEJAFMACQBTAQkA0wAJANMBCQAzAAkAMwEJALMACQCzAQkAcwAJAHMBCQDzAAkA8wEJAAsACQALAQkAiwAJAIsBCQBLAAkASwEJAMsACQDLAQkAKwAJACsBCQCrAAkAqwEJAGsACQBrAQkA6wAJAOsBCQAbAAkAGwEJAJsACQCbAQkAWwAJAFsBCQDbAAkA2wEJADsACQA7AQkAuwAJALsBCQB7AAkAewEJAPsACQD7AQkABwAJAAcBCQCHAAkAhwEJAEcACQBHAQkAxwAJAMcBCQAnAAkAJwEJAKcACQCnAQkAZwAJAGcBCQDnAAkA5wEJABcACQAXAQkAlwAJAJcBCQBXAAkAVwEJANcACQDXAQkANwAJADcBCQC3AAkAtwEJAHcACQB3AQkA9wAJAPcBCQAPAAkADwEJAI8ACQCPAQkATwAJAE8BCQDPAAkAzwEJAC8ACQAvAQkArwAJAK8BCQBvAAkAbwEJAO8ACQDvAQkAHwAJAB8BCQCfAAkAnwEJAF8ACQBfAQkA3wAJAN8BCQA/AAkAPwEJAL8ACQC/AQkAfwAJAH8BCQD/AAkA/wEJAAAABwBAAAcAIAAHAGAABwAQAAcAUAAHADAABwBwAAcACAAHAEgABwAoAAcAaAAHABgABwBYAAcAOAAHAHgABwAEAAcARAAHACQABwBkAAcAFAAHAFQABwA0AAcAdAAHAAMACACDAAgAQwAIAMMACAAjAAgAowAIAGMACADjAAgAAAAFABAABQAIAAUAGAAFAAQABQAUAAUADAAFABwABQACAAUAEgAFAAoABQAaAAUABgAFABYABQAOAAUAHgAFAAEABQARAAUACQAFABkABQAFAAUAFQAFAA0ABQAdAAUAAwAFABMABQALAAUAGwAFAAcABQAXAAUAQbDqAAtNAQAAAAEAAAABAAAAAQAAAAIAAAACAAAAAgAAAAIAAAADAAAAAwAAAAMAAAADAAAABAAAAAQAAAAEAAAABAAAAAUAAAAFAAAABQAAAAUAQaDrAAtlAQAAAAEAAAACAAAAAgAAAAMAAAADAAAABAAAAAQAAAAFAAAABQAAAAYAAAAGAAAABwAAAAcAAAAIAAAACAAAAAkAAAAJAAAACgAAAAoAAAALAAAACwAAAAwAAAAMAAAADQAAAA0AQdDsAAsjAgAAAAMAAAAHAAAAAAAAABAREgAIBwkGCgULBAwDDQIOAQ8AQYTtAAtpAQAAAAIAAAADAAAABAAAAAUAAAAGAAAABwAAAAgAAAAKAAAADAAAAA4AAAAQAAAAFAAAABgAAAAcAAAAIAAAACgAAAAwAAAAOAAAAEAAAABQAAAAYAAAAHAAAACAAAAAoAAAAMAAAADgAEGE7gALegEAAAACAAAAAwAAAAQAAAAGAAAACAAAAAwAAAAQAAAAGAAAACAAAAAwAAAAQAAAAGAAAACAAAAAwAAAAAABAACAAQAAAAIAAAADAAAABAAAAAYAAAAIAAAADAAAABAAAAAYAAAAIAAAADAAAABAAAAAYAAAMS4yLjExAEGI7wALbQcAAAAEAAQACAAEAAgAAAAEAAUAEAAIAAgAAAAEAAYAIAAgAAgAAAAEAAQAEAAQAAkAAAAIABAAIAAgAAkAAAAIABAAgACAAAkAAAAIACAAgAAAAQkAAAAgAIAAAgEABAkAAAAgAAIBAgEAEAkAQYDwAAulAgMABAAFAAYABwAIAAkACgALAA0ADwARABMAFwAbAB8AIwArADMAOwBDAFMAYwBzAIMAowDDAOMAAgEAAAAAAAAQABAAEAAQABAAEAAQABAAEQARABEAEQASABIAEgASABMAEwATABMAFAAUABQAFAAVABUAFQAVABAATQDKAAAAAQACAAMABAAFAAcACQANABEAGQAhADEAQQBhAIEAwQABAYEBAQIBAwEEAQYBCAEMARABGAEgATABQAFgAAAAABAAEAAQABAAEQARABIAEgATABMAFAAUABUAFQAWABYAFwAXABgAGAAZABkAGgAaABsAGwAcABwAHQAdAEAAQAAQABEAEgAAAAgABwAJAAYACgAFAAsABAAMAAMADQACAA4AAQAPAEGw8gALwRFgBwAAAAhQAAAIEAAUCHMAEgcfAAAIcAAACDAAAAnAABAHCgAACGAAAAggAAAJoAAACAAAAAiAAAAIQAAACeAAEAcGAAAIWAAACBgAAAmQABMHOwAACHgAAAg4AAAJ0AARBxEAAAhoAAAIKAAACbAAAAgIAAAIiAAACEgAAAnwABAHBAAACFQAAAgUABUI4wATBysAAAh0AAAINAAACcgAEQcNAAAIZAAACCQAAAmoAAAIBAAACIQAAAhEAAAJ6AAQBwgAAAhcAAAIHAAACZgAFAdTAAAIfAAACDwAAAnYABIHFwAACGwAAAgsAAAJuAAACAwAAAiMAAAITAAACfgAEAcDAAAIUgAACBIAFQijABMHIwAACHIAAAgyAAAJxAARBwsAAAhiAAAIIgAACaQAAAgCAAAIggAACEIAAAnkABAHBwAACFoAAAgaAAAJlAAUB0MAAAh6AAAIOgAACdQAEgcTAAAIagAACCoAAAm0AAAICgAACIoAAAhKAAAJ9AAQBwUAAAhWAAAIFgBACAAAEwczAAAIdgAACDYAAAnMABEHDwAACGYAAAgmAAAJrAAACAYAAAiGAAAIRgAACewAEAcJAAAIXgAACB4AAAmcABQHYwAACH4AAAg+AAAJ3AASBxsAAAhuAAAILgAACbwAAAgOAAAIjgAACE4AAAn8AGAHAAAACFEAAAgRABUIgwASBx8AAAhxAAAIMQAACcIAEAcKAAAIYQAACCEAAAmiAAAIAQAACIEAAAhBAAAJ4gAQBwYAAAhZAAAIGQAACZIAEwc7AAAIeQAACDkAAAnSABEHEQAACGkAAAgpAAAJsgAACAkAAAiJAAAISQAACfIAEAcEAAAIVQAACBUAEAgCARMHKwAACHUAAAg1AAAJygARBw0AAAhlAAAIJQAACaoAAAgFAAAIhQAACEUAAAnqABAHCAAACF0AAAgdAAAJmgAUB1MAAAh9AAAIPQAACdoAEgcXAAAIbQAACC0AAAm6AAAIDQAACI0AAAhNAAAJ+gAQBwMAAAhTAAAIEwAVCMMAEwcjAAAIcwAACDMAAAnGABEHCwAACGMAAAgjAAAJpgAACAMAAAiDAAAIQwAACeYAEAcHAAAIWwAACBsAAAmWABQHQwAACHsAAAg7AAAJ1gASBxMAAAhrAAAIKwAACbYAAAgLAAAIiwAACEsAAAn2ABAHBQAACFcAAAgXAEAIAAATBzMAAAh3AAAINwAACc4AEQcPAAAIZwAACCcAAAmuAAAIBwAACIcAAAhHAAAJ7gAQBwkAAAhfAAAIHwAACZ4AFAdjAAAIfwAACD8AAAneABIHGwAACG8AAAgvAAAJvgAACA8AAAiPAAAITwAACf4AYAcAAAAIUAAACBAAFAhzABIHHwAACHAAAAgwAAAJwQAQBwoAAAhgAAAIIAAACaEAAAgAAAAIgAAACEAAAAnhABAHBgAACFgAAAgYAAAJkQATBzsAAAh4AAAIOAAACdEAEQcRAAAIaAAACCgAAAmxAAAICAAACIgAAAhIAAAJ8QAQBwQAAAhUAAAIFAAVCOMAEwcrAAAIdAAACDQAAAnJABEHDQAACGQAAAgkAAAJqQAACAQAAAiEAAAIRAAACekAEAcIAAAIXAAACBwAAAmZABQHUwAACHwAAAg8AAAJ2QASBxcAAAhsAAAILAAACbkAAAgMAAAIjAAACEwAAAn5ABAHAwAACFIAAAgSABUIowATByMAAAhyAAAIMgAACcUAEQcLAAAIYgAACCIAAAmlAAAIAgAACIIAAAhCAAAJ5QAQBwcAAAhaAAAIGgAACZUAFAdDAAAIegAACDoAAAnVABIHEwAACGoAAAgqAAAJtQAACAoAAAiKAAAISgAACfUAEAcFAAAIVgAACBYAQAgAABMHMwAACHYAAAg2AAAJzQARBw8AAAhmAAAIJgAACa0AAAgGAAAIhgAACEYAAAntABAHCQAACF4AAAgeAAAJnQAUB2MAAAh+AAAIPgAACd0AEgcbAAAIbgAACC4AAAm9AAAIDgAACI4AAAhOAAAJ/QBgBwAAAAhRAAAIEQAVCIMAEgcfAAAIcQAACDEAAAnDABAHCgAACGEAAAghAAAJowAACAEAAAiBAAAIQQAACeMAEAcGAAAIWQAACBkAAAmTABMHOwAACHkAAAg5AAAJ0wARBxEAAAhpAAAIKQAACbMAAAgJAAAIiQAACEkAAAnzABAHBAAACFUAAAgVABAIAgETBysAAAh1AAAINQAACcsAEQcNAAAIZQAACCUAAAmrAAAIBQAACIUAAAhFAAAJ6wAQBwgAAAhdAAAIHQAACZsAFAdTAAAIfQAACD0AAAnbABIHFwAACG0AAAgtAAAJuwAACA0AAAiNAAAITQAACfsAEAcDAAAIUwAACBMAFQjDABMHIwAACHMAAAgzAAAJxwARBwsAAAhjAAAIIwAACacAAAgDAAAIgwAACEMAAAnnABAHBwAACFsAAAgbAAAJlwAUB0MAAAh7AAAIOwAACdcAEgcTAAAIawAACCsAAAm3AAAICwAACIsAAAhLAAAJ9wAQBwUAAAhXAAAIFwBACAAAEwczAAAIdwAACDcAAAnPABEHDwAACGcAAAgnAAAJrwAACAcAAAiHAAAIRwAACe8AEAcJAAAIXwAACB8AAAmfABQHYwAACH8AAAg/AAAJ3wASBxsAAAhvAAAILwAACb8AAAgPAAAIjwAACE8AAAn/ABAFAQAXBQEBEwURABsFARARBQUAGQUBBBUFQQAdBQFAEAUDABgFAQIUBSEAHAUBIBIFCQAaBQEIFgWBAEAFAAAQBQIAFwWBARMFGQAbBQEYEQUHABkFAQYVBWEAHQUBYBAFBAAYBQEDFAUxABwFATASBQ0AGgUBDBYFwQBABQAAEQAKABEREQAAAAAFAAAAAAAACQAAAAALAAAAAAAAAAARAA8KERERAwoHAAEACQsLAAAJBgsAAAsABhEAAAAREREAQYGEAQshCwAAAAAAAAAAEQAKChEREQAKAAACAAkLAAAACQALAAALAEG7hAELAQwAQceEAQsVDAAAAAAMAAAAAAkMAAAAAAAMAAAMAEH1hAELAQ4AQYGFAQsVDQAAAAQNAAAAAAkOAAAAAAAOAAAOAEGvhQELARAAQbuFAQseDwAAAAAPAAAAAAkQAAAAAAAQAAAQAAASAAAAEhISAEHyhQELDhIAAAASEhIAAAAAAAAJAEGjhgELAQsAQa+GAQsVCgAAAAAKAAAAAAkLAAAAAAALAAALAEHdhgELAQwAQemGAQsnDAAAAAAMAAAAAAkMAAAAAAAMAAAMAAAwMTIzNDU2Nzg5QUJDREVGAEG0hwELARkAQduHAQsF//////8AQaCIAQtXGRJEOwI/LEcUPTMwChsGRktFNw9JDo4XA0AdPGkrNh9KLRwBICUpIQgMFRYiLhA4Pgs0MRhkdHV2L0EJfzkRI0MyQomKiwUEJignDSoeNYwHGkiTE5SVAEGAiQELig5JbGxlZ2FsIGJ5dGUgc2VxdWVuY2UARG9tYWluIGVycm9yAFJlc3VsdCBub3QgcmVwcmVzZW50YWJsZQBOb3QgYSB0dHkAUGVybWlzc2lvbiBkZW5pZWQAT3BlcmF0aW9uIG5vdCBwZXJtaXR0ZWQATm8gc3VjaCBmaWxlIG9yIGRpcmVjdG9yeQBObyBzdWNoIHByb2Nlc3MARmlsZSBleGlzdHMAVmFsdWUgdG9vIGxhcmdlIGZvciBkYXRhIHR5cGUATm8gc3BhY2UgbGVmdCBvbiBkZXZpY2UAT3V0IG9mIG1lbW9yeQBSZXNvdXJjZSBidXN5AEludGVycnVwdGVkIHN5c3RlbSBjYWxsAFJlc291cmNlIHRlbXBvcmFyaWx5IHVuYXZhaWxhYmxlAEludmFsaWQgc2VlawBDcm9zcy1kZXZpY2UgbGluawBSZWFkLW9ubHkgZmlsZSBzeXN0ZW0ARGlyZWN0b3J5IG5vdCBlbXB0eQBDb25uZWN0aW9uIHJlc2V0IGJ5IHBlZXIAT3BlcmF0aW9uIHRpbWVkIG91dABDb25uZWN0aW9uIHJlZnVzZWQASG9zdCBpcyBkb3duAEhvc3QgaXMgdW5yZWFjaGFibGUAQWRkcmVzcyBpbiB1c2UAQnJva2VuIHBpcGUASS9PIGVycm9yAE5vIHN1Y2ggZGV2aWNlIG9yIGFkZHJlc3MAQmxvY2sgZGV2aWNlIHJlcXVpcmVkAE5vIHN1Y2ggZGV2aWNlAE5vdCBhIGRpcmVjdG9yeQBJcyBhIGRpcmVjdG9yeQBUZXh0IGZpbGUgYnVzeQBFeGVjIGZvcm1hdCBlcnJvcgBJbnZhbGlkIGFyZ3VtZW50AEFyZ3VtZW50IGxpc3QgdG9vIGxvbmcAU3ltYm9saWMgbGluayBsb29wAEZpbGVuYW1lIHRvbyBsb25nAFRvbyBtYW55IG9wZW4gZmlsZXMgaW4gc3lzdGVtAE5vIGZpbGUgZGVzY3JpcHRvcnMgYXZhaWxhYmxlAEJhZCBmaWxlIGRlc2NyaXB0b3IATm8gY2hpbGQgcHJvY2VzcwBCYWQgYWRkcmVzcwBGaWxlIHRvbyBsYXJnZQBUb28gbWFueSBsaW5rcwBObyBsb2NrcyBhdmFpbGFibGUAUmVzb3VyY2UgZGVhZGxvY2sgd291bGQgb2NjdXIAU3RhdGUgbm90IHJlY292ZXJhYmxlAFByZXZpb3VzIG93bmVyIGRpZWQAT3BlcmF0aW9uIGNhbmNlbGVkAEZ1bmN0aW9uIG5vdCBpbXBsZW1lbnRlZABObyBtZXNzYWdlIG9mIGRlc2lyZWQgdHlwZQBJZGVudGlmaWVyIHJlbW92ZWQARGV2aWNlIG5vdCBhIHN0cmVhbQBObyBkYXRhIGF2YWlsYWJsZQBEZXZpY2UgdGltZW91dABPdXQgb2Ygc3RyZWFtcyByZXNvdXJjZXMATGluayBoYXMgYmVlbiBzZXZlcmVkAFByb3RvY29sIGVycm9yAEJhZCBtZXNzYWdlAEZpbGUgZGVzY3JpcHRvciBpbiBiYWQgc3RhdGUATm90IGEgc29ja2V0AERlc3RpbmF0aW9uIGFkZHJlc3MgcmVxdWlyZWQATWVzc2FnZSB0b28gbGFyZ2UAUHJvdG9jb2wgd3JvbmcgdHlwZSBmb3Igc29ja2V0AFByb3RvY29sIG5vdCBhdmFpbGFibGUAUHJvdG9jb2wgbm90IHN1cHBvcnRlZABTb2NrZXQgdHlwZSBub3Qgc3VwcG9ydGVkAE5vdCBzdXBwb3J0ZWQAUHJvdG9jb2wgZmFtaWx5IG5vdCBzdXBwb3J0ZWQAQWRkcmVzcyBmYW1pbHkgbm90IHN1cHBvcnRlZCBieSBwcm90b2NvbABBZGRyZXNzIG5vdCBhdmFpbGFibGUATmV0d29yayBpcyBkb3duAE5ldHdvcmsgdW5yZWFjaGFibGUAQ29ubmVjdGlvbiByZXNldCBieSBuZXR3b3JrAENvbm5lY3Rpb24gYWJvcnRlZABObyBidWZmZXIgc3BhY2UgYXZhaWxhYmxlAFNvY2tldCBpcyBjb25uZWN0ZWQAU29ja2V0IG5vdCBjb25uZWN0ZWQAQ2Fubm90IHNlbmQgYWZ0ZXIgc29ja2V0IHNodXRkb3duAE9wZXJhdGlvbiBhbHJlYWR5IGluIHByb2dyZXNzAE9wZXJhdGlvbiBpbiBwcm9ncmVzcwBTdGFsZSBmaWxlIGhhbmRsZQBSZW1vdGUgSS9PIGVycm9yAFF1b3RhIGV4Y2VlZGVkAE5vIG1lZGl1bSBmb3VuZABXcm9uZyBtZWRpdW0gdHlwZQBObyBlcnJvciBpbmZvcm1hdGlvbgBBkJcBC1JQUFAACgAAAAsAAAAMAAAADQAAAA4AAAAPAAAAEAAAABEAAAASAAAACwAAAAwAAAANAAAADgAAAA8AAAAQAAAAEQAAAAEAAAAIAAAAlEsAALRLAEGQmQELAgxQAEHImQELCR8AAADkTAAAAwBB5JkBC4wBLfRRWM+MscBG9rXLKTEDxwRbcDC0Xf0geH+LmthZKVBoSImrp1YDbP+3zYg/1He0K6WjcPG65Kj8QYP92W/hinovLXSWBx8NCV4Ddixw90ClLKdvV0GoqnTfoFhkA0rHxDxTrq9fGAQVseNtKIarDKS/Q/DpUIE5VxZSN/////////////////////8=";Tu(xo)||(xo=h(xo));function Ou(d){try{if(d==xo&&_)return new Uint8Array(_);var E=xa(d);if(E)return E;if(m)return m(d);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(I){vr(I)}}function Sh(d,E){var I,D,M;try{M=Ou(d),D=new WebAssembly.Module(M),I=new WebAssembly.Instance(D,E)}catch(ie){var z=ie.toString();throw x("failed to compile wasm module: "+z),(z.includes("imported Memory")||z.includes("memory import"))&&x("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)."),ie}return[I,D]}function vh(){var d={a:ka};function E(M,z){var ie=M.exports;t.asm=ie,A=t.asm.u,Ei(A.buffer),Qr=t.asm.pa,DA(t.asm.v),NA("wasm-instantiate")}if(FA("wasm-instantiate"),t.instantiateWasm)try{var I=t.instantiateWasm(d,E);return I}catch(M){return x("Module.instantiateWasm callback failed with error: "+M),!1}var D=Sh(xo,d);return E(D[0]),t.asm}var Dr,Ae;function ko(d){for(;d.length>0;){var E=d.shift();if(typeof E=="function"){E(t);continue}var I=E.func;typeof I=="number"?E.arg===void 0?Qr.get(I)():Qr.get(I)(E.arg):I(E.arg===void 0?null:E.arg)}}function Gn(d,E){var I=new Date(fe[d>>2]*1e3);fe[E>>2]=I.getUTCSeconds(),fe[E+4>>2]=I.getUTCMinutes(),fe[E+8>>2]=I.getUTCHours(),fe[E+12>>2]=I.getUTCDate(),fe[E+16>>2]=I.getUTCMonth(),fe[E+20>>2]=I.getUTCFullYear()-1900,fe[E+24>>2]=I.getUTCDay(),fe[E+36>>2]=0,fe[E+32>>2]=0;var D=Date.UTC(I.getUTCFullYear(),0,1,0,0,0,0),M=(I.getTime()-D)/(1e3*60*60*24)|0;return fe[E+28>>2]=M,Gn.GMTString||(Gn.GMTString=Fe("GMT")),fe[E+40>>2]=Gn.GMTString,E}function Mu(d,E){return Gn(d,E)}var St={splitPath:function(d){var E=/^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/;return E.exec(d).slice(1)},normalizeArray:function(d,E){for(var I=0,D=d.length-1;D>=0;D--){var M=d[D];M==="."?d.splice(D,1):M===".."?(d.splice(D,1),I++):I&&(d.splice(D,1),I--)}if(E)for(;I;I--)d.unshift("..");return d},normalize:function(d){var E=d.charAt(0)==="/",I=d.substr(-1)==="/";return d=St.normalizeArray(d.split("/").filter(function(D){return!!D}),!E).join("/"),!d&&!E&&(d="."),d&&I&&(d+="/"),(E?"/":"")+d},dirname:function(d){var E=St.splitPath(d),I=E[0],D=E[1];return!I&&!D?".":(D&&(D=D.substr(0,D.length-1)),I+D)},basename:function(d){if(d==="/")return"/";d=St.normalize(d),d=d.replace(/\/$/,"");var E=d.lastIndexOf("/");return E===-1?d:d.substr(E+1)},extname:function(d){return St.splitPath(d)[3]},join:function(){var d=Array.prototype.slice.call(arguments,0);return St.normalize(d.join("/"))},join2:function(d,E){return St.normalize(d+"/"+E)}};function _l(){if(typeof crypto=="object"&&typeof crypto.getRandomValues=="function"){var d=new Uint8Array(1);return function(){return crypto.getRandomValues(d),d[0]}}else if(g)try{var E=require("crypto");return function(){return E.randomBytes(1)[0]}}catch(I){}return function(){vr("randomDevice")}}var Yn={resolve:function(){for(var d="",E=!1,I=arguments.length-1;I>=-1&&!E;I--){var D=I>=0?arguments[I]:S.cwd();if(typeof D!="string")throw new TypeError("Arguments to path.resolve must be strings");if(!D)return"";d=D+"/"+d,E=D.charAt(0)==="/"}return d=St.normalizeArray(d.split("/").filter(function(M){return!!M}),!E).join("/"),(E?"/":"")+d||"."},relative:function(d,E){d=Yn.resolve(d).substr(1),E=Yn.resolve(E).substr(1);function I(_e){for(var ot=0;ot<_e.length&&_e[ot]==="";ot++);for(var Bt=_e.length-1;Bt>=0&&_e[Bt]==="";Bt--);return ot>Bt?[]:_e.slice(ot,Bt-ot+1)}for(var D=I(d.split("/")),M=I(E.split("/")),z=Math.min(D.length,M.length),ie=z,we=0;we0?E=D.slice(0,M).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;d.input=TA(E,!0)}return d.input.shift()},put_char:function(d,E){E===null||E===10?(v(je(d.output,0)),d.output=[]):E!=0&&d.output.push(E)},flush:function(d){d.output&&d.output.length>0&&(v(je(d.output,0)),d.output=[])}},default_tty1_ops:{put_char:function(d,E){E===null||E===10?(x(je(d.output,0)),d.output=[]):E!=0&&d.output.push(E)},flush:function(d){d.output&&d.output.length>0&&(x(je(d.output,0)),d.output=[])}}};function ds(d){for(var E=q(d,65536),I=Et(E);d=E)){var D=1024*1024;E=Math.max(E,I*(I>>0),I!=0&&(E=Math.max(E,256));var M=d.contents;d.contents=new Uint8Array(E),d.usedBytes>0&&d.contents.set(M.subarray(0,d.usedBytes),0)}},resizeFileStorage:function(d,E){if(d.usedBytes!=E)if(E==0)d.contents=null,d.usedBytes=0;else{var I=d.contents;d.contents=new Uint8Array(E),I&&d.contents.set(I.subarray(0,Math.min(E,d.usedBytes))),d.usedBytes=E}},node_ops:{getattr:function(d){var E={};return E.dev=S.isChrdev(d.mode)?d.id:1,E.ino=d.id,E.mode=d.mode,E.nlink=1,E.uid=0,E.gid=0,E.rdev=d.rdev,S.isDir(d.mode)?E.size=4096:S.isFile(d.mode)?E.size=d.usedBytes:S.isLink(d.mode)?E.size=d.link.length:E.size=0,E.atime=new Date(d.timestamp),E.mtime=new Date(d.timestamp),E.ctime=new Date(d.timestamp),E.blksize=4096,E.blocks=Math.ceil(E.size/E.blksize),E},setattr:function(d,E){E.mode!==void 0&&(d.mode=E.mode),E.timestamp!==void 0&&(d.timestamp=E.timestamp),E.size!==void 0&&pt.resizeFileStorage(d,E.size)},lookup:function(d,E){throw S.genericErrors[44]},mknod:function(d,E,I,D){return pt.createNode(d,E,I,D)},rename:function(d,E,I){if(S.isDir(d.mode)){var D;try{D=S.lookupNode(E,I)}catch(z){}if(D)for(var M in D.contents)throw new S.ErrnoError(55)}delete d.parent.contents[d.name],d.parent.timestamp=Date.now(),d.name=I,E.contents[I]=d,E.timestamp=d.parent.timestamp,d.parent=E},unlink:function(d,E){delete d.contents[E],d.timestamp=Date.now()},rmdir:function(d,E){var I=S.lookupNode(d,E);for(var D in I.contents)throw new S.ErrnoError(55);delete d.contents[E],d.timestamp=Date.now()},readdir:function(d){var E=[".",".."];for(var I in d.contents)!d.contents.hasOwnProperty(I)||E.push(I);return E},symlink:function(d,E,I){var D=pt.createNode(d,E,511|40960,0);return D.link=I,D},readlink:function(d){if(!S.isLink(d.mode))throw new S.ErrnoError(28);return d.link}},stream_ops:{read:function(d,E,I,D,M){var z=d.node.contents;if(M>=d.node.usedBytes)return 0;var ie=Math.min(d.node.usedBytes-M,D);if(ie>8&&z.subarray)E.set(z.subarray(M,M+ie),I);else for(var we=0;we0||D+I>2)}catch(I){throw I.code?new S.ErrnoError(lt.convertNodeCode(I)):I}return E.mode},realPath:function(d){for(var E=[];d.parent!==d;)E.push(d.name),d=d.parent;return E.push(d.mount.opts.root),E.reverse(),St.join.apply(null,E)},flagsForNode:function(d){d&=~2097152,d&=~2048,d&=~32768,d&=~524288;var E=0;for(var I in lt.flagsForNodeMap)d&I&&(E|=lt.flagsForNodeMap[I],d^=I);if(d)throw new S.ErrnoError(28);return E},node_ops:{getattr:function(d){var E=lt.realPath(d),I;try{I=Oe.lstatSync(E)}catch(D){throw D.code?new S.ErrnoError(lt.convertNodeCode(D)):D}return lt.isWindows&&!I.blksize&&(I.blksize=4096),lt.isWindows&&!I.blocks&&(I.blocks=(I.size+I.blksize-1)/I.blksize|0),{dev:I.dev,ino:I.ino,mode:I.mode,nlink:I.nlink,uid:I.uid,gid:I.gid,rdev:I.rdev,size:I.size,atime:I.atime,mtime:I.mtime,ctime:I.ctime,blksize:I.blksize,blocks:I.blocks}},setattr:function(d,E){var I=lt.realPath(d);try{if(E.mode!==void 0&&(Oe.chmodSync(I,E.mode),d.mode=E.mode),E.timestamp!==void 0){var D=new Date(E.timestamp);Oe.utimesSync(I,D,D)}E.size!==void 0&&Oe.truncateSync(I,E.size)}catch(M){throw M.code?new S.ErrnoError(lt.convertNodeCode(M)):M}},lookup:function(d,E){var I=St.join2(lt.realPath(d),E),D=lt.getMode(I);return lt.createNode(d,E,D)},mknod:function(d,E,I,D){var M=lt.createNode(d,E,I,D),z=lt.realPath(M);try{S.isDir(M.mode)?Oe.mkdirSync(z,M.mode):Oe.writeFileSync(z,"",{mode:M.mode})}catch(ie){throw ie.code?new S.ErrnoError(lt.convertNodeCode(ie)):ie}return M},rename:function(d,E,I){var D=lt.realPath(d),M=St.join2(lt.realPath(E),I);try{Oe.renameSync(D,M)}catch(z){throw z.code?new S.ErrnoError(lt.convertNodeCode(z)):z}d.name=I},unlink:function(d,E){var I=St.join2(lt.realPath(d),E);try{Oe.unlinkSync(I)}catch(D){throw D.code?new S.ErrnoError(lt.convertNodeCode(D)):D}},rmdir:function(d,E){var I=St.join2(lt.realPath(d),E);try{Oe.rmdirSync(I)}catch(D){throw D.code?new S.ErrnoError(lt.convertNodeCode(D)):D}},readdir:function(d){var E=lt.realPath(d);try{return Oe.readdirSync(E)}catch(I){throw I.code?new S.ErrnoError(lt.convertNodeCode(I)):I}},symlink:function(d,E,I){var D=St.join2(lt.realPath(d),E);try{Oe.symlinkSync(I,D)}catch(M){throw M.code?new S.ErrnoError(lt.convertNodeCode(M)):M}},readlink:function(d){var E=lt.realPath(d);try{return E=Oe.readlinkSync(E),E=Hu.relative(Hu.resolve(d.mount.opts.root),E),E}catch(I){throw I.code?new S.ErrnoError(lt.convertNodeCode(I)):I}}},stream_ops:{open:function(d){var E=lt.realPath(d.node);try{S.isFile(d.node.mode)&&(d.nfd=Oe.openSync(E,lt.flagsForNode(d.flags)))}catch(I){throw I.code?new S.ErrnoError(lt.convertNodeCode(I)):I}},close:function(d){try{S.isFile(d.node.mode)&&d.nfd&&Oe.closeSync(d.nfd)}catch(E){throw E.code?new S.ErrnoError(lt.convertNodeCode(E)):E}},read:function(d,E,I,D,M){if(D===0)return 0;try{return Oe.readSync(d.nfd,lt.bufferFrom(E.buffer),I,D,M)}catch(z){throw new S.ErrnoError(lt.convertNodeCode(z))}},write:function(d,E,I,D,M){try{return Oe.writeSync(d.nfd,lt.bufferFrom(E.buffer),I,D,M)}catch(z){throw new S.ErrnoError(lt.convertNodeCode(z))}},llseek:function(d,E,I){var D=E;if(I===1)D+=d.position;else if(I===2&&S.isFile(d.node.mode))try{var M=Oe.fstatSync(d.nfd);D+=M.size}catch(z){throw new S.ErrnoError(lt.convertNodeCode(z))}if(D<0)throw new S.ErrnoError(28);return D},mmap:function(d,E,I,D,M,z){if(E!==0)throw new S.ErrnoError(28);if(!S.isFile(d.node.mode))throw new S.ErrnoError(43);var ie=ds(I);return lt.stream_ops.read(d,pe,ie,I,D),{ptr:ie,allocated:!0}},msync:function(d,E,I,D,M){if(!S.isFile(d.node.mode))throw new S.ErrnoError(43);if(M&2)return 0;var z=lt.stream_ops.write(d,E,0,D,I,!1);return 0}}},mn={lookupPath:function(d){return{path:d,node:{mode:lt.getMode(d)}}},createStandardStreams:function(){S.streams[0]={fd:0,nfd:0,position:0,path:"",flags:0,tty:!0,seekable:!1};for(var d=1;d<3;d++)S.streams[d]={fd:d,nfd:d,position:0,path:"",flags:577,tty:!0,seekable:!1}},cwd:function(){return process.cwd()},chdir:function(){process.chdir.apply(void 0,arguments)},mknod:function(d,E){S.isDir(d)?Oe.mkdirSync(d,E):Oe.writeFileSync(d,"",{mode:E})},mkdir:function(){Oe.mkdirSync.apply(void 0,arguments)},symlink:function(){Oe.symlinkSync.apply(void 0,arguments)},rename:function(){Oe.renameSync.apply(void 0,arguments)},rmdir:function(){Oe.rmdirSync.apply(void 0,arguments)},readdir:function(){Oe.readdirSync.apply(void 0,arguments)},unlink:function(){Oe.unlinkSync.apply(void 0,arguments)},readlink:function(){return Oe.readlinkSync.apply(void 0,arguments)},stat:function(){return Oe.statSync.apply(void 0,arguments)},lstat:function(){return Oe.lstatSync.apply(void 0,arguments)},chmod:function(){Oe.chmodSync.apply(void 0,arguments)},fchmod:function(){Oe.fchmodSync.apply(void 0,arguments)},chown:function(){Oe.chownSync.apply(void 0,arguments)},fchown:function(){Oe.fchownSync.apply(void 0,arguments)},truncate:function(){Oe.truncateSync.apply(void 0,arguments)},ftruncate:function(d,E){if(E<0)throw new S.ErrnoError(28);Oe.ftruncateSync.apply(void 0,arguments)},utime:function(){Oe.utimesSync.apply(void 0,arguments)},open:function(d,E,I,D){typeof E=="string"&&(E=$s.modeStringToFlags(E));var M=Oe.openSync(d,lt.flagsForNode(E),I),z=D!=null?D:S.nextfd(M),ie={fd:z,nfd:M,position:0,path:d,flags:E,seekable:!0};return S.streams[z]=ie,ie},close:function(d){d.stream_ops||Oe.closeSync(d.nfd),S.closeStream(d.fd)},llseek:function(d,E,I){if(d.stream_ops)return $s.llseek(d,E,I);var D=E;if(I===1)D+=d.position;else if(I===2)D+=Oe.fstatSync(d.nfd).size;else if(I!==0)throw new S.ErrnoError(Po.EINVAL);if(D<0)throw new S.ErrnoError(Po.EINVAL);return d.position=D,D},read:function(d,E,I,D,M){if(d.stream_ops)return $s.read(d,E,I,D,M);var z=typeof M!="undefined";!z&&d.seekable&&(M=d.position);var ie=Oe.readSync(d.nfd,lt.bufferFrom(E.buffer),I,D,M);return z||(d.position+=ie),ie},write:function(d,E,I,D,M){if(d.stream_ops)return $s.write(d,E,I,D,M);d.flags&+"1024"&&S.llseek(d,0,+"2");var z=typeof M!="undefined";!z&&d.seekable&&(M=d.position);var ie=Oe.writeSync(d.nfd,lt.bufferFrom(E.buffer),I,D,M);return z||(d.position+=ie),ie},allocate:function(){throw new S.ErrnoError(Po.EOPNOTSUPP)},mmap:function(d,E,I,D,M,z){if(d.stream_ops)return $s.mmap(d,E,I,D,M,z);if(E!==0)throw new S.ErrnoError(28);var ie=ds(I);return S.read(d,pe,ie,I,D),{ptr:ie,allocated:!0}},msync:function(d,E,I,D,M){return d.stream_ops?$s.msync(d,E,I,D,M):(M&2||S.write(d,E,0,D,I),0)},munmap:function(){return 0},ioctl:function(){throw new S.ErrnoError(Po.ENOTTY)}},S={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(d,E){if(d=Yn.resolve(S.cwd(),d),E=E||{},!d)return{path:"",node:null};var I={follow_mount:!0,recurse_count:0};for(var D in I)E[D]===void 0&&(E[D]=I[D]);if(E.recurse_count>8)throw new S.ErrnoError(32);for(var M=St.normalizeArray(d.split("/").filter(function(ut){return!!ut}),!1),z=S.root,ie="/",we=0;we40)throw new S.ErrnoError(32)}}return{path:ie,node:z}},getPath:function(d){for(var E;;){if(S.isRoot(d)){var I=d.mount.mountpoint;return E?I[I.length-1]!=="/"?I+"/"+E:I+E:I}E=E?d.name+"/"+E:d.name,d=d.parent}},hashName:function(d,E){for(var I=0,D=0;D>>0)%S.nameTable.length},hashAddNode:function(d){var E=S.hashName(d.parent.id,d.name);d.name_next=S.nameTable[E],S.nameTable[E]=d},hashRemoveNode:function(d){var E=S.hashName(d.parent.id,d.name);if(S.nameTable[E]===d)S.nameTable[E]=d.name_next;else for(var I=S.nameTable[E];I;){if(I.name_next===d){I.name_next=d.name_next;break}I=I.name_next}},lookupNode:function(d,E){var I=S.mayLookup(d);if(I)throw new S.ErrnoError(I,d);for(var D=S.hashName(d.id,E),M=S.nameTable[D];M;M=M.name_next){var z=M.name;if(M.parent.id===d.id&&z===E)return M}return S.lookup(d,E)},createNode:function(d,E,I,D){var M=new S.FSNode(d,E,I,D);return S.hashAddNode(M),M},destroyNode:function(d){S.hashRemoveNode(d)},isRoot:function(d){return d===d.parent},isMountpoint:function(d){return!!d.mounted},isFile:function(d){return(d&61440)==32768},isDir:function(d){return(d&61440)==16384},isLink:function(d){return(d&61440)==40960},isChrdev:function(d){return(d&61440)==8192},isBlkdev:function(d){return(d&61440)==24576},isFIFO:function(d){return(d&61440)==4096},isSocket:function(d){return(d&49152)==49152},flagModes:{r:0,"r+":2,w:577,"w+":578,a:1089,"a+":1090},modeStringToFlags:function(d){var E=S.flagModes[d];if(typeof E=="undefined")throw new Error("Unknown file open mode: "+d);return E},flagsToPermissionString:function(d){var E=["r","w","rw"][d&3];return d&512&&(E+="w"),E},nodePermissions:function(d,E){return S.ignorePermissions?0:E.includes("r")&&!(d.mode&292)||E.includes("w")&&!(d.mode&146)||E.includes("x")&&!(d.mode&73)?2:0},mayLookup:function(d){var E=S.nodePermissions(d,"x");return E||(d.node_ops.lookup?0:2)},mayCreate:function(d,E){try{var I=S.lookupNode(d,E);return 20}catch(D){}return S.nodePermissions(d,"wx")},mayDelete:function(d,E,I){var D;try{D=S.lookupNode(d,E)}catch(z){return z.errno}var M=S.nodePermissions(d,"wx");if(M)return M;if(I){if(!S.isDir(D.mode))return 54;if(S.isRoot(D)||S.getPath(D)===S.cwd())return 10}else if(S.isDir(D.mode))return 31;return 0},mayOpen:function(d,E){return d?S.isLink(d.mode)?32:S.isDir(d.mode)&&(S.flagsToPermissionString(E)!=="r"||E&512)?31:S.nodePermissions(d,S.flagsToPermissionString(E)):44},MAX_OPEN_FDS:4096,nextfd:function(d,E){d=d||0,E=E||S.MAX_OPEN_FDS;for(var I=d;I<=E;I++)if(!S.streams[I])return I;throw new S.ErrnoError(33)},getStream:function(d){return S.streams[d]},createStream:function(d,E,I){S.FSStream||(S.FSStream=function(){},S.FSStream.prototype={object:{get:function(){return this.node},set:function(ie){this.node=ie}},isRead:{get:function(){return(this.flags&2097155)!=1}},isWrite:{get:function(){return(this.flags&2097155)!=0}},isAppend:{get:function(){return this.flags&1024}}});var D=new S.FSStream;for(var M in d)D[M]=d[M];d=D;var z=S.nextfd(E,I);return d.fd=z,S.streams[z]=d,d},closeStream:function(d){S.streams[d]=null},chrdev_stream_ops:{open:function(d){var E=S.getDevice(d.node.rdev);d.stream_ops=E.stream_ops,d.stream_ops.open&&d.stream_ops.open(d)},llseek:function(){throw new S.ErrnoError(70)}},major:function(d){return d>>8},minor:function(d){return d&255},makedev:function(d,E){return d<<8|E},registerDevice:function(d,E){S.devices[d]={stream_ops:E}},getDevice:function(d){return S.devices[d]},getMounts:function(d){for(var E=[],I=[d];I.length;){var D=I.pop();E.push(D),I.push.apply(I,D.mounts)}return E},syncfs:function(d,E){typeof d=="function"&&(E=d,d=!1),S.syncFSRequests++,S.syncFSRequests>1&&x("warning: "+S.syncFSRequests+" FS.syncfs operations in flight at once, probably just doing extra work");var I=S.getMounts(S.root.mount),D=0;function M(ie){return S.syncFSRequests--,E(ie)}function z(ie){if(ie)return z.errored?void 0:(z.errored=!0,M(ie));++D>=I.length&&M(null)}I.forEach(function(ie){if(!ie.type.syncfs)return z(null);ie.type.syncfs(ie,d,z)})},mount:function(d,E,I){var D=I==="/",M=!I,z;if(D&&S.root)throw new S.ErrnoError(10);if(!D&&!M){var ie=S.lookupPath(I,{follow_mount:!1});if(I=ie.path,z=ie.node,S.isMountpoint(z))throw new S.ErrnoError(10);if(!S.isDir(z.mode))throw new S.ErrnoError(54)}var we={type:d,opts:E,mountpoint:I,mounts:[]},me=d.mount(we);return me.mount=we,we.root=me,D?S.root=me:z&&(z.mounted=we,z.mount&&z.mount.mounts.push(we)),me},unmount:function(d){var E=S.lookupPath(d,{follow_mount:!1});if(!S.isMountpoint(E.node))throw new S.ErrnoError(28);var I=E.node,D=I.mounted,M=S.getMounts(D);Object.keys(S.nameTable).forEach(function(ie){for(var we=S.nameTable[ie];we;){var me=we.name_next;M.includes(we.mount)&&S.destroyNode(we),we=me}}),I.mounted=null;var z=I.mount.mounts.indexOf(D);I.mount.mounts.splice(z,1)},lookup:function(d,E){return d.node_ops.lookup(d,E)},mknod:function(d,E,I){var D=S.lookupPath(d,{parent:!0}),M=D.node,z=St.basename(d);if(!z||z==="."||z==="..")throw new S.ErrnoError(28);var ie=S.mayCreate(M,z);if(ie)throw new S.ErrnoError(ie);if(!M.node_ops.mknod)throw new S.ErrnoError(63);return M.node_ops.mknod(M,z,E,I)},create:function(d,E){return E=E!==void 0?E:438,E&=4095,E|=32768,S.mknod(d,E,0)},mkdir:function(d,E){return E=E!==void 0?E:511,E&=511|512,E|=16384,S.mknod(d,E,0)},mkdirTree:function(d,E){for(var I=d.split("/"),D="",M=0;Mthis.length-1||ut<0)){var st=ut%this.chunkSize,yt=ut/this.chunkSize|0;return this.getter(yt)[st]}},z.prototype.setDataGetter=function(ut){this.getter=ut},z.prototype.cacheLength=function(){var ut=new XMLHttpRequest;if(ut.open("HEAD",I,!1),ut.send(null),!(ut.status>=200&&ut.status<300||ut.status===304))throw new Error("Couldn't load "+I+". Status: "+ut.status);var st=Number(ut.getResponseHeader("Content-length")),yt,xe=(yt=ut.getResponseHeader("Accept-Ranges"))&&yt==="bytes",Wn=(yt=ut.getResponseHeader("Content-Encoding"))&&yt==="gzip",Mi=1024*1024;xe||(Mi=st);var HA=function(Cs,Pa){if(Cs>Pa)throw new Error("invalid range ("+Cs+", "+Pa+") or no bytes requested!");if(Pa>st-1)throw new Error("only "+st+" bytes available! programmer error!");var qr=new XMLHttpRequest;if(qr.open("GET",I,!1),st!==Mi&&qr.setRequestHeader("Range","bytes="+Cs+"-"+Pa),typeof Uint8Array!="undefined"&&(qr.responseType="arraybuffer"),qr.overrideMimeType&&qr.overrideMimeType("text/plain; charset=x-user-defined"),qr.send(null),!(qr.status>=200&&qr.status<300||qr.status===304))throw new Error("Couldn't load "+I+". Status: "+qr.status);return qr.response!==void 0?new Uint8Array(qr.response||[]):TA(qr.responseText||"",!0)},Yr=this;Yr.setDataGetter(function(Cs){var Pa=Cs*Mi,qr=(Cs+1)*Mi-1;if(qr=Math.min(qr,st-1),typeof Yr.chunks[Cs]=="undefined"&&(Yr.chunks[Cs]=HA(Pa,qr)),typeof Yr.chunks[Cs]=="undefined")throw new Error("doXHR failed!");return Yr.chunks[Cs]}),(Wn||!st)&&(Mi=st=1,st=this.getter(0).length,Mi=st,v("LazyFiles on gzip forces download of the whole file when length is accessed")),this._length=st,this._chunkSize=Mi,this.lengthKnown=!0},typeof XMLHttpRequest!="undefined"){if(!u)throw"Cannot do synchronous binary XHRs outside webworkers in modern browsers. Use --embed-file or --preload-file in emcc";var ie=new z;Object.defineProperties(ie,{length:{get:function(){return this.lengthKnown||this.cacheLength(),this._length}},chunkSize:{get:function(){return this.lengthKnown||this.cacheLength(),this._chunkSize}}});var we={isDevice:!1,contents:ie}}else var we={isDevice:!1,url:I};var me=S.createFile(d,E,we,D,M);we.contents?me.contents=we.contents:we.url&&(me.contents=null,me.url=we.url),Object.defineProperties(me,{usedBytes:{get:function(){return this.contents.length}}});var _e={},ot=Object.keys(me.stream_ops);return ot.forEach(function(Bt){var ut=me.stream_ops[Bt];_e[Bt]=function(){return S.forceLoadFile(me),ut.apply(null,arguments)}}),_e.read=function(ut,st,yt,xe,Wn){S.forceLoadFile(me);var Mi=ut.node.contents;if(Wn>=Mi.length)return 0;var HA=Math.min(Mi.length-Wn,xe);if(Mi.slice)for(var Yr=0;Yr>2]=D.dev,fe[I+4>>2]=0,fe[I+8>>2]=D.ino,fe[I+12>>2]=D.mode,fe[I+16>>2]=D.nlink,fe[I+20>>2]=D.uid,fe[I+24>>2]=D.gid,fe[I+28>>2]=D.rdev,fe[I+32>>2]=0,Ae=[D.size>>>0,(Dr=D.size,+Math.abs(Dr)>=1?Dr>0?(Math.min(+Math.floor(Dr/4294967296),4294967295)|0)>>>0:~~+Math.ceil((Dr-+(~~Dr>>>0))/4294967296)>>>0:0)],fe[I+40>>2]=Ae[0],fe[I+44>>2]=Ae[1],fe[I+48>>2]=4096,fe[I+52>>2]=D.blocks,fe[I+56>>2]=D.atime.getTime()/1e3|0,fe[I+60>>2]=0,fe[I+64>>2]=D.mtime.getTime()/1e3|0,fe[I+68>>2]=0,fe[I+72>>2]=D.ctime.getTime()/1e3|0,fe[I+76>>2]=0,Ae=[D.ino>>>0,(Dr=D.ino,+Math.abs(Dr)>=1?Dr>0?(Math.min(+Math.floor(Dr/4294967296),4294967295)|0)>>>0:~~+Math.ceil((Dr-+(~~Dr>>>0))/4294967296)>>>0:0)],fe[I+80>>2]=Ae[0],fe[I+84>>2]=Ae[1],0},doMsync:function(d,E,I,D,M){var z=V.slice(d,d+I);S.msync(E,z,M,I,D)},doMkdir:function(d,E){return d=St.normalize(d),d[d.length-1]==="/"&&(d=d.substr(0,d.length-1)),S.mkdir(d,E,0),0},doMknod:function(d,E,I){switch(E&61440){case 32768:case 8192:case 24576:case 4096:case 49152:break;default:return-28}return S.mknod(d,E,I),0},doReadlink:function(d,E,I){if(I<=0)return-28;var D=S.readlink(d),M=Math.min(I,he(D)),z=pe[E+M];return be(D,E,I+1),pe[E+M]=z,M},doAccess:function(d,E){if(E&~7)return-28;var I,D=S.lookupPath(d,{follow:!0});if(I=D.node,!I)return-44;var M="";return E&4&&(M+="r"),E&2&&(M+="w"),E&1&&(M+="x"),M&&S.nodePermissions(I,M)?-2:0},doDup:function(d,E,I){var D=S.getStream(I);return D&&S.close(D),S.open(d,E,0,I,I).fd},doReadv:function(d,E,I,D){for(var M=0,z=0;z>2],we=fe[E+(z*8+4)>>2],me=S.read(d,pe,ie,we,D);if(me<0)return-1;if(M+=me,me>2],we=fe[E+(z*8+4)>>2],me=S.write(d,pe,ie,we,D);if(me<0)return-1;M+=me}return M},varargs:void 0,get:function(){Tt.varargs+=4;var d=fe[Tt.varargs-4>>2];return d},getStr:function(d){var E=re(d);return E},getStreamFromFD:function(d){var E=S.getStream(d);if(!E)throw new S.ErrnoError(8);return E},get64:function(d,E){return d}};function Ku(d,E){try{return d=Tt.getStr(d),S.chmod(d,E),0}catch(I){return(typeof S=="undefined"||!(I instanceof S.ErrnoError))&&vr(I),-I.errno}}function Vl(d){return fe[Rt()>>2]=d,d}function xh(d,E,I){Tt.varargs=I;try{var D=Tt.getStreamFromFD(d);switch(E){case 0:{var M=Tt.get();if(M<0)return-28;var z;return z=S.open(D.path,D.flags,0,M),z.fd}case 1:case 2:return 0;case 3:return D.flags;case 4:{var M=Tt.get();return D.flags|=M,0}case 12:{var M=Tt.get(),ie=0;return Qe[M+ie>>1]=2,0}case 13:case 14:return 0;case 16:case 8:return-28;case 9:return Vl(28),-1;default:return-28}}catch(we){return(typeof S=="undefined"||!(we instanceof S.ErrnoError))&&vr(we),-we.errno}}function kh(d,E){try{var I=Tt.getStreamFromFD(d);return Tt.doStat(S.stat,I.path,E)}catch(D){return(typeof S=="undefined"||!(D instanceof S.ErrnoError))&&vr(D),-D.errno}}function Ph(d,E,I){Tt.varargs=I;try{var D=Tt.getStreamFromFD(d);switch(E){case 21509:case 21505:return D.tty?0:-59;case 21510:case 21511:case 21512:case 21506:case 21507:case 21508:return D.tty?0:-59;case 21519:{if(!D.tty)return-59;var M=Tt.get();return fe[M>>2]=0,0}case 21520:return D.tty?-28:-59;case 21531:{var M=Tt.get();return S.ioctl(D,E,M)}case 21523:return D.tty?0:-59;case 21524:return D.tty?0:-59;default:vr("bad ioctl syscall "+E)}}catch(z){return(typeof S=="undefined"||!(z instanceof S.ErrnoError))&&vr(z),-z.errno}}function Dh(d,E,I){Tt.varargs=I;try{var D=Tt.getStr(d),M=I?Tt.get():0,z=S.open(D,E,M);return z.fd}catch(ie){return(typeof S=="undefined"||!(ie instanceof S.ErrnoError))&&vr(ie),-ie.errno}}function Rh(d,E){try{return d=Tt.getStr(d),E=Tt.getStr(E),S.rename(d,E),0}catch(I){return(typeof S=="undefined"||!(I instanceof S.ErrnoError))&&vr(I),-I.errno}}function j(d){try{return d=Tt.getStr(d),S.rmdir(d),0}catch(E){return(typeof S=="undefined"||!(E instanceof S.ErrnoError))&&vr(E),-E.errno}}function wt(d,E){try{return d=Tt.getStr(d),Tt.doStat(S.stat,d,E)}catch(I){return(typeof S=="undefined"||!(I instanceof S.ErrnoError))&&vr(I),-I.errno}}function LA(d){try{return d=Tt.getStr(d),S.unlink(d),0}catch(E){return(typeof S=="undefined"||!(E instanceof S.ErrnoError))&&vr(E),-E.errno}}function $i(d,E,I){V.copyWithin(d,E,E+I)}function Xl(d){try{return A.grow(d-ve.byteLength+65535>>>16),Ei(A.buffer),1}catch(E){}}function $e(d){var E=V.length;d=d>>>0;var I=2147483648;if(d>I)return!1;for(var D=1;D<=4;D*=2){var M=E*(1+.2/D);M=Math.min(M,d+100663296);var z=Math.min(I,ke(Math.max(d,M),65536)),ie=Xl(z);if(ie)return!0}return!1}function Sa(d){try{var E=Tt.getStreamFromFD(d);return S.close(E),0}catch(I){return(typeof S=="undefined"||!(I instanceof S.ErrnoError))&&vr(I),I.errno}}function Uu(d,E){try{var I=Tt.getStreamFromFD(d),D=I.tty?2:S.isDir(I.mode)?3:S.isLink(I.mode)?7:4;return pe[E>>0]=D,0}catch(M){return(typeof S=="undefined"||!(M instanceof S.ErrnoError))&&vr(M),M.errno}}function yE(d,E,I,D){try{var M=Tt.getStreamFromFD(d),z=Tt.doReadv(M,E,I);return fe[D>>2]=z,0}catch(ie){return(typeof S=="undefined"||!(ie instanceof S.ErrnoError))&&vr(ie),ie.errno}}function Fh(d,E,I,D,M){try{var z=Tt.getStreamFromFD(d),ie=4294967296,we=I*ie+(E>>>0),me=9007199254740992;return we<=-me||we>=me?-61:(S.llseek(z,we,D),Ae=[z.position>>>0,(Dr=z.position,+Math.abs(Dr)>=1?Dr>0?(Math.min(+Math.floor(Dr/4294967296),4294967295)|0)>>>0:~~+Math.ceil((Dr-+(~~Dr>>>0))/4294967296)>>>0:0)],fe[M>>2]=Ae[0],fe[M+4>>2]=Ae[1],z.getdents&&we===0&&D===0&&(z.getdents=null),0)}catch(_e){return(typeof S=="undefined"||!(_e instanceof S.ErrnoError))&&vr(_e),_e.errno}}function wE(d,E,I,D){try{var M=Tt.getStreamFromFD(d),z=Tt.doWritev(M,E,I);return fe[D>>2]=z,0}catch(ie){return(typeof S=="undefined"||!(ie instanceof S.ErrnoError))&&vr(ie),ie.errno}}function gr(d){$(d)}function qn(d){var E=Date.now()/1e3|0;return d&&(fe[d>>2]=E),E}function Zl(){if(Zl.called)return;Zl.called=!0;var d=new Date().getFullYear(),E=new Date(d,0,1),I=new Date(d,6,1),D=E.getTimezoneOffset(),M=I.getTimezoneOffset(),z=Math.max(D,M);fe[zb()>>2]=z*60,fe[Wb()>>2]=Number(D!=M);function ie(Bt){var ut=Bt.toTimeString().match(/\(([A-Za-z ]+)\)$/);return ut?ut[1]:"GMT"}var we=ie(E),me=ie(I),_e=Fe(we),ot=Fe(me);M>2]=_e,fe[Wu()+4>>2]=ot):(fe[Wu()>>2]=ot,fe[Wu()+4>>2]=_e)}function Nh(d){Zl();var E=Date.UTC(fe[d+20>>2]+1900,fe[d+16>>2],fe[d+12>>2],fe[d+8>>2],fe[d+4>>2],fe[d>>2],0),I=new Date(E);fe[d+24>>2]=I.getUTCDay();var D=Date.UTC(I.getUTCFullYear(),0,1,0,0,0,0),M=(I.getTime()-D)/(1e3*60*60*24)|0;return fe[d+28>>2]=M,I.getTime()/1e3|0}var Zs=function(d,E,I,D){d||(d=this),this.parent=d,this.mount=d.mount,this.mounted=null,this.id=S.nextInode++,this.name=E,this.mode=I,this.node_ops={},this.stream_ops={},this.rdev=D},va=292|73,En=146;if(Object.defineProperties(Zs.prototype,{read:{get:function(){return(this.mode&va)===va},set:function(d){d?this.mode|=va:this.mode&=~va}},write:{get:function(){return(this.mode&En)===En},set:function(d){d?this.mode|=En:this.mode&=~En}},isFolder:{get:function(){return S.isDir(this.mode)}},isDevice:{get:function(){return S.isChrdev(this.mode)}}}),S.FSNode=Zs,S.staticInit(),g){var Oe=v5,Hu=require("path");lt.staticInit()}if(g){var $l=function(d){return function(){try{return d.apply(this,arguments)}catch(E){throw E.code?new S.ErrnoError(Po[E.code]):E}}},$s=Object.assign({},S);for(var ec in mn)S[ec]=$l(mn[ec])}else throw new Error("NODERAWFS is currently only supported on Node.js environment.");function TA(d,E,I){var D=I>0?I:he(d)+1,M=new Array(D),z=se(d,M,0,M.length);return E&&(M.length=z),M}var ju=typeof atob=="function"?atob:function(d){var E="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",I="",D,M,z,ie,we,me,_e,ot=0;d=d.replace(/[^A-Za-z0-9\+\/\=]/g,"");do ie=E.indexOf(d.charAt(ot++)),we=E.indexOf(d.charAt(ot++)),me=E.indexOf(d.charAt(ot++)),_e=E.indexOf(d.charAt(ot++)),D=ie<<2|we>>4,M=(we&15)<<4|me>>2,z=(me&3)<<6|_e,I=I+String.fromCharCode(D),me!==64&&(I=I+String.fromCharCode(M)),_e!==64&&(I=I+String.fromCharCode(z));while(ot0||(Sr(),hs>0))return;function E(){Ue||(Ue=!0,t.calledRun=!0,!oe&&(jn(),i(t),t.onRuntimeInitialized&&t.onRuntimeInitialized(),fs()))}t.setStatus?(t.setStatus("Running..."),setTimeout(function(){setTimeout(function(){t.setStatus("")},1),E()},1)):E()}if(t.run=UA,t.preInit)for(typeof t.preInit=="function"&&(t.preInit=[t.preInit]);t.preInit.length>0;)t.preInit.pop()();return UA(),e}}();typeof Gw=="object"&&typeof jP=="object"?jP.exports=GP:typeof define=="function"&&define.amd?define([],function(){return GP}):typeof Gw=="object"&&(Gw.createModule=GP)});var $5=w((Nst,Z5)=>{function KPe(r,e){for(var t=-1,i=r==null?0:r.length,n=Array(i);++t{var UPe=Array.isArray;e9.exports=UPe});var o9=w((Tst,t9)=>{var r9=Jc(),HPe=$5(),jPe=Ks(),GPe=Id(),YPe=1/0,i9=r9?r9.prototype:void 0,n9=i9?i9.toString:void 0;function s9(r){if(typeof r=="string")return r;if(jPe(r))return HPe(r,s9)+"";if(GPe(r))return n9?n9.call(r):"";var e=r+"";return e=="0"&&1/r==-YPe?"-0":e}t9.exports=s9});var lf=w((Ost,a9)=>{var qPe=o9();function JPe(r){return r==null?"":qPe(r)}a9.exports=JPe});var VP=w((Mst,A9)=>{function WPe(r,e,t){var i=-1,n=r.length;e<0&&(e=-e>n?0:n+e),t=t>n?n:t,t<0&&(t+=n),n=e>t?0:t-e>>>0,e>>>=0;for(var s=Array(n);++i{var zPe=VP();function _Pe(r,e,t){var i=r.length;return t=t===void 0?i:t,!e&&t>=i?r:zPe(r,e,t)}l9.exports=_Pe});var XP=w((Ust,u9)=>{var VPe="\\ud800-\\udfff",XPe="\\u0300-\\u036f",ZPe="\\ufe20-\\ufe2f",$Pe="\\u20d0-\\u20ff",eDe=XPe+ZPe+$Pe,tDe="\\ufe0e\\ufe0f",rDe="\\u200d",iDe=RegExp("["+rDe+VPe+eDe+tDe+"]");function nDe(r){return iDe.test(r)}u9.exports=nDe});var f9=w((Hst,g9)=>{function sDe(r){return r.split("")}g9.exports=sDe});var y9=w((jst,h9)=>{var p9="\\ud800-\\udfff",oDe="\\u0300-\\u036f",aDe="\\ufe20-\\ufe2f",ADe="\\u20d0-\\u20ff",lDe=oDe+aDe+ADe,cDe="\\ufe0e\\ufe0f",uDe="["+p9+"]",ZP="["+lDe+"]",$P="\\ud83c[\\udffb-\\udfff]",gDe="(?:"+ZP+"|"+$P+")",d9="[^"+p9+"]",C9="(?:\\ud83c[\\udde6-\\uddff]){2}",m9="[\\ud800-\\udbff][\\udc00-\\udfff]",fDe="\\u200d",E9=gDe+"?",I9="["+cDe+"]?",hDe="(?:"+fDe+"(?:"+[d9,C9,m9].join("|")+")"+I9+E9+")*",pDe=I9+E9+hDe,dDe="(?:"+[d9+ZP+"?",ZP,C9,m9,uDe].join("|")+")",CDe=RegExp($P+"(?="+$P+")|"+dDe+pDe,"g");function mDe(r){return r.match(CDe)||[]}h9.exports=mDe});var B9=w((Gst,w9)=>{var EDe=f9(),IDe=XP(),yDe=y9();function wDe(r){return IDe(r)?yDe(r):EDe(r)}w9.exports=wDe});var Q9=w((Yst,b9)=>{var BDe=c9(),bDe=XP(),QDe=B9(),SDe=lf();function vDe(r){return function(e){e=SDe(e);var t=bDe(e)?QDe(e):void 0,i=t?t[0]:e.charAt(0),n=t?BDe(t,1).join(""):e.slice(1);return i[r]()+n}}b9.exports=vDe});var v9=w((qst,S9)=>{var xDe=Q9(),kDe=xDe("toUpperCase");S9.exports=kDe});var Zw=w((Jst,x9)=>{var PDe=lf(),DDe=v9();function RDe(r){return DDe(PDe(r).toLowerCase())}x9.exports=RDe});var k9=w((Wst,$w)=>{function FDe(){var r=0,e=1,t=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,m=15,y=16,b=17,v=0,x=1,T=2,q=3,Y=4;function $(A,oe){return 55296<=A.charCodeAt(oe)&&A.charCodeAt(oe)<=56319&&56320<=A.charCodeAt(oe+1)&&A.charCodeAt(oe+1)<=57343}function _(A,oe){oe===void 0&&(oe=0);var ce=A.charCodeAt(oe);if(55296<=ce&&ce<=56319&&oe=1){var Z=A.charCodeAt(oe-1),O=ce;return 55296<=Z&&Z<=56319?(Z-55296)*1024+(O-56320)+65536:O}return ce}function ne(A,oe,ce){var Z=[A].concat(oe).concat([ce]),O=Z[Z.length-2],L=ce,de=Z.lastIndexOf(p);if(de>1&&Z.slice(1,de).every(function(re){return re==i})&&[i,h,b].indexOf(A)==-1)return T;var Be=Z.lastIndexOf(n);if(Be>0&&Z.slice(1,Be).every(function(re){return re==n})&&[f,n].indexOf(O)==-1)return Z.filter(function(re){return re==n}).length%2==1?q:Y;if(O==r&&L==e)return v;if(O==t||O==r||O==e)return L==p&&oe.every(function(re){return re==i})?T:x;if(L==t||L==r||L==e)return x;if(O==o&&(L==o||L==a||L==c||L==u))return v;if((O==c||O==a)&&(L==a||L==l))return v;if((O==u||O==l)&&L==l)return v;if(L==i||L==m)return v;if(L==s)return v;if(O==f)return v;var je=Z.indexOf(i)!=-1?Z.lastIndexOf(i)-1:Z.length-2;return[h,b].indexOf(Z[je])!=-1&&Z.slice(je+1,-1).every(function(re){return re==i})&&L==p||O==m&&[y,b].indexOf(L)!=-1?v:oe.indexOf(n)!=-1?T:O==n&&L==n?v:x}this.nextBreak=function(A,oe){if(oe===void 0&&(oe=0),oe<0)return 0;if(oe>=A.length-1)return A.length;for(var ce=ee(_(A,oe)),Z=[],O=oe+1;O{var NDe=/^(.*?)(\x1b\[[^m]+m|\x1b\]8;;.*?(\x1b\\|\u0007))/,eB;function LDe(){if(eB)return eB;if(typeof Intl.Segmenter!="undefined"){let r=new Intl.Segmenter("en",{granularity:"grapheme"});return eB=e=>Array.from(r.segment(e),({segment:t})=>t)}else{let r=k9(),e=new r;return eB=t=>e.splitGraphemes(t)}}P9.exports=(r,e=0,t=r.length)=>{if(e<0||t<0)throw new RangeError("Negative indices aren't supported by this implementation");let i=t-e,n="",s=0,o=0;for(;r.length>0;){let a=r.match(NDe)||[r,r,void 0],l=LDe()(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]),r=r.slice(a[0].length)}return n}});var cf=w((Bot,q9)=>{"use strict";var J9=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"]]),wot=q9.exports=r=>r?Object.keys(r).map(e=>[J9.has(e)?J9.get(e):e,r[e]]).reduce((e,t)=>(e[t[0]]=t[1],e),Object.create(null)):{}});var uf=w((bot,W9)=>{"use strict";var zDe=require("events"),z9=require("stream"),qd=Bp(),_9=require("string_decoder").StringDecoder,lA=Symbol("EOF"),Jd=Symbol("maybeEmitEnd"),Il=Symbol("emittedEnd"),oB=Symbol("emittingEnd"),aB=Symbol("closed"),V9=Symbol("read"),iD=Symbol("flush"),X9=Symbol("flushChunk"),Nn=Symbol("encoding"),cA=Symbol("decoder"),AB=Symbol("flowing"),Wd=Symbol("paused"),zd=Symbol("resume"),pn=Symbol("bufferLength"),Z9=Symbol("bufferPush"),nD=Symbol("bufferShift"),_i=Symbol("objectMode"),Vi=Symbol("destroyed"),$9=global._MP_NO_ITERATOR_SYMBOLS_!=="1",_De=$9&&Symbol.asyncIterator||Symbol("asyncIterator not implemented"),VDe=$9&&Symbol.iterator||Symbol("iterator not implemented"),e_=r=>r==="end"||r==="finish"||r==="prefinish",XDe=r=>r instanceof ArrayBuffer||typeof r=="object"&&r.constructor&&r.constructor.name==="ArrayBuffer"&&r.byteLength>=0,ZDe=r=>!Buffer.isBuffer(r)&&ArrayBuffer.isView(r);W9.exports=class t_ extends z9{constructor(e){super();this[AB]=!1,this[Wd]=!1,this.pipes=new qd,this.buffer=new qd,this[_i]=e&&e.objectMode||!1,this[_i]?this[Nn]=null:this[Nn]=e&&e.encoding||null,this[Nn]==="buffer"&&(this[Nn]=null),this[cA]=this[Nn]?new _9(this[Nn]):null,this[lA]=!1,this[Il]=!1,this[oB]=!1,this[aB]=!1,this.writable=!0,this.readable=!0,this[pn]=0,this[Vi]=!1}get bufferLength(){return this[pn]}get encoding(){return this[Nn]}set encoding(e){if(this[_i])throw new Error("cannot set encoding in objectMode");if(this[Nn]&&e!==this[Nn]&&(this[cA]&&this[cA].lastNeed||this[pn]))throw new Error("cannot change encoding");this[Nn]!==e&&(this[cA]=e?new _9(e):null,this.buffer.length&&(this.buffer=this.buffer.map(t=>this[cA].write(t)))),this[Nn]=e}setEncoding(e){this.encoding=e}get objectMode(){return this[_i]}set objectMode(e){this[_i]=this[_i]||!!e}write(e,t,i){if(this[lA])throw new Error("write after end");return this[Vi]?(this.emit("error",Object.assign(new Error("Cannot call write after a stream was destroyed"),{code:"ERR_STREAM_DESTROYED"})),!0):(typeof t=="function"&&(i=t,t="utf8"),t||(t="utf8"),!this[_i]&&!Buffer.isBuffer(e)&&(ZDe(e)?e=Buffer.from(e.buffer,e.byteOffset,e.byteLength):XDe(e)?e=Buffer.from(e):typeof e!="string"&&(this.objectMode=!0)),!this.objectMode&&!e.length?(this[pn]!==0&&this.emit("readable"),i&&i(),this.flowing):(typeof e=="string"&&!this[_i]&&!(t===this[Nn]&&!this[cA].lastNeed)&&(e=Buffer.from(e,t)),Buffer.isBuffer(e)&&this[Nn]&&(e=this[cA].write(e)),this.flowing?(this[pn]!==0&&this[iD](!0),this.emit("data",e)):this[Z9](e),this[pn]!==0&&this.emit("readable"),i&&i(),this.flowing))}read(e){if(this[Vi])return null;try{return this[pn]===0||e===0||e>this[pn]?null:(this[_i]&&(e=null),this.buffer.length>1&&!this[_i]&&(this.encoding?this.buffer=new qd([Array.from(this.buffer).join("")]):this.buffer=new qd([Buffer.concat(Array.from(this.buffer),this[pn])])),this[V9](e||null,this.buffer.head.value))}finally{this[Jd]()}}[V9](e,t){return e===t.length||e===null?this[nD]():(this.buffer.head.value=t.slice(e),t=t.slice(0,e),this[pn]-=e),this.emit("data",t),!this.buffer.length&&!this[lA]&&this.emit("drain"),t}end(e,t,i){return typeof e=="function"&&(i=e,e=null),typeof t=="function"&&(i=t,t="utf8"),e&&this.write(e,t),i&&this.once("end",i),this[lA]=!0,this.writable=!1,(this.flowing||!this[Wd])&&this[Jd](),this}[zd](){this[Vi]||(this[Wd]=!1,this[AB]=!0,this.emit("resume"),this.buffer.length?this[iD]():this[lA]?this[Jd]():this.emit("drain"))}resume(){return this[zd]()}pause(){this[AB]=!1,this[Wd]=!0}get destroyed(){return this[Vi]}get flowing(){return this[AB]}get paused(){return this[Wd]}[Z9](e){return this[_i]?this[pn]+=1:this[pn]+=e.length,this.buffer.push(e)}[nD](){return this.buffer.length&&(this[_i]?this[pn]-=1:this[pn]-=this.buffer.head.value.length),this.buffer.shift()}[iD](e){do;while(this[X9](this[nD]()));!e&&!this.buffer.length&&!this[lA]&&this.emit("drain")}[X9](e){return e?(this.emit("data",e),this.flowing):!1}pipe(e,t){if(this[Vi])return;let i=this[Il];t=t||{},e===process.stdout||e===process.stderr?t.end=!1:t.end=t.end!==!1;let n={dest:e,opts:t,ondrain:s=>this[zd]()};return this.pipes.push(n),e.on("drain",n.ondrain),this[zd](),i&&n.opts.end&&n.dest.end(),e}addListener(e,t){return this.on(e,t)}on(e,t){try{return super.on(e,t)}finally{e==="data"&&!this.pipes.length&&!this.flowing?this[zd]():e_(e)&&this[Il]&&(super.emit(e),this.removeAllListeners(e))}}get emittedEnd(){return this[Il]}[Jd](){!this[oB]&&!this[Il]&&!this[Vi]&&this.buffer.length===0&&this[lA]&&(this[oB]=!0,this.emit("end"),this.emit("prefinish"),this.emit("finish"),this[aB]&&this.emit("close"),this[oB]=!1)}emit(e,t){if(e!=="error"&&e!=="close"&&e!==Vi&&this[Vi])return;if(e==="data"){if(!t)return;this.pipes.length&&this.pipes.forEach(n=>n.dest.write(t)===!1&&this.pause())}else if(e==="end"){if(this[Il]===!0)return;this[Il]=!0,this.readable=!1,this[cA]&&(t=this[cA].end(),t&&(this.pipes.forEach(n=>n.dest.write(t)),super.emit("data",t))),this.pipes.forEach(n=>{n.dest.removeListener("drain",n.ondrain),n.opts.end&&n.dest.end()})}else if(e==="close"&&(this[aB]=!0,!this[Il]&&!this[Vi]))return;let i=new Array(arguments.length);if(i[0]=e,i[1]=t,arguments.length>2)for(let n=2;n{e.push(i),this[_i]||(e.dataLength+=i.length)}),t.then(()=>e)}concat(){return this[_i]?Promise.reject(new Error("cannot concat in objectMode")):this.collect().then(e=>this[_i]?Promise.reject(new Error("cannot concat in objectMode")):this[Nn]?e.join(""):Buffer.concat(e,e.dataLength))}promise(){return new Promise((e,t)=>{this.on(Vi,()=>t(new Error("stream destroyed"))),this.on("end",()=>e()),this.on("error",i=>t(i))})}[_De](){return{next:()=>{let t=this.read();if(t!==null)return Promise.resolve({done:!1,value:t});if(this[lA])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[lA]})},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(Vi,l),this.once("error",s),this.once("end",a),this.once("data",o)})}}}[VDe](){return{next:()=>{let t=this.read();return{value:t,done:t===null}}}}destroy(e){return this[Vi]?(e?this.emit("error",e):this.emit(Vi),this):(this[Vi]=!0,this.buffer=new qd,this[pn]=0,typeof this.close=="function"&&!this[aB]&&this.close(),e?this.emit("error",e):this.emit(Vi),this)}static isStream(e){return!!e&&(e instanceof t_||e instanceof z9||e instanceof zDe&&(typeof e.pipe=="function"||typeof e.write=="function"&&typeof e.end=="function"))}}});var i_=w((Qot,r_)=>{var $De=require("zlib").constants||{ZLIB_VERNUM:4736};r_.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},$De))});var fD=w(as=>{"use strict";var sD=require("assert"),yl=require("buffer").Buffer,n_=require("zlib"),Zc=as.constants=i_(),eRe=uf(),s_=yl.concat,$c=Symbol("_superWrite"),_d=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"}},tRe=Symbol("opts"),Vd=Symbol("flushFlag"),o_=Symbol("finishFlushFlag"),oD=Symbol("fullFlushFlag"),pr=Symbol("handle"),lB=Symbol("onError"),gf=Symbol("sawError"),aD=Symbol("level"),AD=Symbol("strategy"),lD=Symbol("ended"),Sot=Symbol("_defaultFullFlush"),cD=class extends eRe{constructor(e,t){if(!e||typeof e!="object")throw new TypeError("invalid options for ZlibBase constructor");super(e);this[gf]=!1,this[lD]=!1,this[tRe]=e,this[Vd]=e.flush,this[o_]=e.finishFlush;try{this[pr]=new n_[t](e)}catch(i){throw new _d(i)}this[lB]=i=>{this[gf]||(this[gf]=!0,this.close(),this.emit("error",i))},this[pr].on("error",i=>this[lB](new _d(i))),this.once("end",()=>this.close)}close(){this[pr]&&(this[pr].close(),this[pr]=null,this.emit("close"))}reset(){if(!this[gf])return sD(this[pr],"zlib binding closed"),this[pr].reset()}flush(e){this.ended||(typeof e!="number"&&(e=this[oD]),this.write(Object.assign(yl.alloc(0),{[Vd]:e})))}end(e,t,i){return e&&this.write(e,t),this.flush(this[o_]),this[lD]=!0,super.end(null,null,i)}get ended(){return this[lD]}write(e,t,i){if(typeof t=="function"&&(i=t,t="utf8"),typeof e=="string"&&(e=yl.from(e,t)),this[gf])return;sD(this[pr],"zlib binding closed");let n=this[pr]._handle,s=n.close;n.close=()=>{};let o=this[pr].close;this[pr].close=()=>{},yl.concat=c=>c;let a;try{let c=typeof e[Vd]=="number"?e[Vd]:this[Vd];a=this[pr]._processChunk(e,c),yl.concat=s_}catch(c){yl.concat=s_,this[lB](new _d(c))}finally{this[pr]&&(this[pr]._handle=n,n.close=s,this[pr].close=o,this[pr].removeAllListeners("error"))}this[pr]&&this[pr].on("error",c=>this[lB](new _d(c)));let l;if(a)if(Array.isArray(a)&&a.length>0){l=this[$c](yl.from(a[0]));for(let c=1;c{this.flush(n),s()};try{this[pr].params(e,t)}finally{this[pr].flush=i}this[pr]&&(this[aD]=e,this[AD]=t)}}}},a_=class extends wl{constructor(e){super(e,"Deflate")}},A_=class extends wl{constructor(e){super(e,"Inflate")}},uD=Symbol("_portable"),l_=class extends wl{constructor(e){super(e,"Gzip");this[uD]=e&&!!e.portable}[$c](e){return this[uD]?(this[uD]=!1,e[9]=255,super[$c](e)):super[$c](e)}},c_=class extends wl{constructor(e){super(e,"Gunzip")}},u_=class extends wl{constructor(e){super(e,"DeflateRaw")}},g_=class extends wl{constructor(e){super(e,"InflateRaw")}},f_=class extends wl{constructor(e){super(e,"Unzip")}},gD=class extends cD{constructor(e,t){e=e||{},e.flush=e.flush||Zc.BROTLI_OPERATION_PROCESS,e.finishFlush=e.finishFlush||Zc.BROTLI_OPERATION_FINISH,super(e,t),this[oD]=Zc.BROTLI_OPERATION_FLUSH}},h_=class extends gD{constructor(e){super(e,"BrotliCompress")}},p_=class extends gD{constructor(e){super(e,"BrotliDecompress")}};as.Deflate=a_;as.Inflate=A_;as.Gzip=l_;as.Gunzip=c_;as.DeflateRaw=u_;as.InflateRaw=g_;as.Unzip=f_;typeof n_.BrotliCompress=="function"?(as.BrotliCompress=h_,as.BrotliDecompress=p_):as.BrotliCompress=as.BrotliDecompress=class{constructor(){throw new Error("Brotli is not supported in this version of Node.js")}}});var Xd=w(cB=>{"use strict";cB.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"]]);cB.code=new Map(Array.from(cB.name).map(r=>[r[1],r[0]]))});var Zd=w((Dot,d_)=>{"use strict";var kot=Xd(),rRe=uf(),hD=Symbol("slurp");d_.exports=class extends rRe{constructor(e,t,i){super();switch(this.pause(),this.extended=t,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,t&&this[hD](t),i&&this[hD](i,!0)}write(e){let t=e.length;if(t>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-t),this.blockRemain=Math.max(0,n-t),this.ignore?!0:i>=t?super.write(e):super.write(e.slice(0,i))}[hD](e,t){for(let i in e)e[i]!==null&&e[i]!==void 0&&!(t&&i==="path")&&(this[i]=e[i])}}});var E_=w(pD=>{"use strict";var Rot=pD.encode=(r,e)=>{if(Number.isSafeInteger(r))r<0?nRe(r,e):iRe(r,e);else throw Error("cannot encode number outside of javascript safe integer range");return e},iRe=(r,e)=>{e[0]=128;for(var t=e.length;t>1;t--)e[t-1]=r&255,r=Math.floor(r/256)},nRe=(r,e)=>{e[0]=255;var t=!1;r=r*-1;for(var i=e.length;i>1;i--){var n=r&255;r=Math.floor(r/256),t?e[i-1]=C_(n):n===0?e[i-1]=0:(t=!0,e[i-1]=m_(n))}},Fot=pD.parse=r=>{var e=r[r.length-1],t=r[0],i;if(t===128)i=oRe(r.slice(1,r.length));else if(t===255)i=sRe(r);else throw Error("invalid base256 encoding");if(!Number.isSafeInteger(i))throw Error("parsed number outside of javascript safe integer range");return i},sRe=r=>{for(var e=r.length,t=0,i=!1,n=e-1;n>-1;n--){var s=r[n],o;i?o=C_(s):s===0?o=s:(i=!0,o=m_(s)),o!==0&&(t-=o*Math.pow(256,e-n-1))}return t},oRe=r=>{for(var e=r.length,t=0,i=e-1;i>-1;i--){var n=r[i];n!==0&&(t+=n*Math.pow(256,e-i-1))}return t},C_=r=>(255^r)&255,m_=r=>(255^r)+1&255});var hf=w((Lot,I_)=>{"use strict";var dD=Xd(),ff=require("path").posix,y_=E_(),CD=Symbol("slurp"),As=Symbol("type"),w_=class{constructor(e,t,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[As]="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,t||0,i,n):e&&this.set(e)}decode(e,t,i,n){if(t||(t=0),!e||!(e.length>=t+512))throw new Error("need 512 bytes for header");if(this.path=eu(e,t,100),this.mode=Bl(e,t+100,8),this.uid=Bl(e,t+108,8),this.gid=Bl(e,t+116,8),this.size=Bl(e,t+124,12),this.mtime=mD(e,t+136,12),this.cksum=Bl(e,t+148,12),this[CD](i),this[CD](n,!0),this[As]=eu(e,t+156,1),this[As]===""&&(this[As]="0"),this[As]==="0"&&this.path.substr(-1)==="/"&&(this[As]="5"),this[As]==="5"&&(this.size=0),this.linkpath=eu(e,t+157,100),e.slice(t+257,t+265).toString()==="ustar\x0000")if(this.uname=eu(e,t+265,32),this.gname=eu(e,t+297,32),this.devmaj=Bl(e,t+329,8),this.devmin=Bl(e,t+337,8),e[t+475]!==0){let o=eu(e,t+345,155);this.path=o+"/"+this.path}else{let o=eu(e,t+345,130);o&&(this.path=o+"/"+this.path),this.atime=mD(e,t+476,12),this.ctime=mD(e,t+488,12)}let s=8*32;for(let o=t;o=t+512))throw new Error("need 512 bytes for header");let i=this.ctime||this.atime?130:155,n=aRe(this.path||"",i),s=n[0],o=n[1];this.needPax=n[2],this.needPax=tu(e,t,100,s)||this.needPax,this.needPax=bl(e,t+100,8,this.mode)||this.needPax,this.needPax=bl(e,t+108,8,this.uid)||this.needPax,this.needPax=bl(e,t+116,8,this.gid)||this.needPax,this.needPax=bl(e,t+124,12,this.size)||this.needPax,this.needPax=ED(e,t+136,12,this.mtime)||this.needPax,e[t+156]=this[As].charCodeAt(0),this.needPax=tu(e,t+157,100,this.linkpath)||this.needPax,e.write("ustar\x0000",t+257,8),this.needPax=tu(e,t+265,32,this.uname)||this.needPax,this.needPax=tu(e,t+297,32,this.gname)||this.needPax,this.needPax=bl(e,t+329,8,this.devmaj)||this.needPax,this.needPax=bl(e,t+337,8,this.devmin)||this.needPax,this.needPax=tu(e,t+345,i,o)||this.needPax,e[t+475]!==0?this.needPax=tu(e,t+345,155,o)||this.needPax:(this.needPax=tu(e,t+345,130,o)||this.needPax,this.needPax=ED(e,t+476,12,this.atime)||this.needPax,this.needPax=ED(e,t+488,12,this.ctime)||this.needPax);let a=8*32;for(let l=t;l{let t=100,i=r,n="",s,o=ff.parse(r).root||".";if(Buffer.byteLength(i)t&&Buffer.byteLength(n)<=e?s=[i.substr(0,t-1),n,!0]:(i=ff.join(ff.basename(n),i),n=ff.dirname(n));while(n!==o&&!s);s||(s=[r.substr(0,t-1),"",!0])}return s},eu=(r,e,t)=>r.slice(e,e+t).toString("utf8").replace(/\0.*/,""),mD=(r,e,t)=>ARe(Bl(r,e,t)),ARe=r=>r===null?null:new Date(r*1e3),Bl=(r,e,t)=>r[e]&128?y_.parse(r.slice(e,e+t)):lRe(r,e,t),cRe=r=>isNaN(r)?null:r,lRe=(r,e,t)=>cRe(parseInt(r.slice(e,e+t).toString("utf8").replace(/\0.*$/,"").trim(),8)),uRe={12:8589934591,8:2097151},bl=(r,e,t,i)=>i===null?!1:i>uRe[t]||i<0?(y_.encode(i,r.slice(e,e+t)),!0):(gRe(r,e,t,i),!1),gRe=(r,e,t,i)=>r.write(fRe(i,t),e,t,"ascii"),fRe=(r,e)=>hRe(Math.floor(r).toString(8),e),hRe=(r,e)=>(r.length===e-1?r:new Array(e-r.length-1).join("0")+r+" ")+"\0",ED=(r,e,t,i)=>i===null?!1:bl(r,e,t,i.getTime()/1e3),pRe=new Array(156).join("\0"),tu=(r,e,t,i)=>i===null?!1:(r.write(i+pRe,e,t,"utf8"),i.length!==Buffer.byteLength(i)||i.length>t);I_.exports=w_});var gB=w((Tot,B_)=>{"use strict";var dRe=hf(),CRe=require("path"),uB=class{constructor(e,t){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=t||!1}encode(){let e=this.encodeBody();if(e==="")return null;let t=Buffer.byteLength(e),i=512*Math.ceil(1+t/512),n=Buffer.allocUnsafe(i);for(let s=0;s<512;s++)n[s]=0;new dRe({path:("PaxHeader/"+CRe.basename(this.path)).slice(0,99),mode:this.mode||420,uid:this.uid||null,gid:this.gid||null,size:t,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,t,"utf8");for(let s=t+512;s=Math.pow(10,s)&&(s+=1),s+n+i}};uB.parse=(r,e,t)=>new uB(mRe(ERe(r),e),t);var mRe=(r,e)=>e?Object.keys(r).reduce((t,i)=>(t[i]=r[i],t),e):r,ERe=r=>r.replace(/\n$/,"").split(` -`).reduce(IRe,Object.create(null)),IRe=(r,e)=>{let t=parseInt(e,10);if(t!==Buffer.byteLength(e)+1)return r;e=e.substr((t+" ").length);let i=e.split("="),n=i.shift().replace(/^SCHILY\.(dev|ino|nlink)/,"$1");if(!n)return r;let s=i.join("=");return r[n]=/^([A-Z]+\.)?([mac]|birth|creation)time$/.test(n)?new Date(s*1e3):/^[0-9]+$/.test(s)?+s:s,r};B_.exports=uB});var fB=w((Oot,b_)=>{"use strict";b_.exports=r=>class extends r{warn(e,t,i={}){this.file&&(i.file=this.file),this.cwd&&(i.cwd=this.cwd),i.code=t instanceof Error&&t.code||e,i.tarCode=e,!this.strict&&i.recoverable!==!1?(t instanceof Error&&(i=Object.assign(t,i),t=t.message),this.emit("warn",i.tarCode,t,i)):t instanceof Error?this.emit("error",Object.assign(t,i)):this.emit("error",Object.assign(new Error(`${e}: ${t}`),i))}}});var yD=w((Mot,Q_)=>{"use strict";var hB=["|","<",">","?",":"],ID=hB.map(r=>String.fromCharCode(61440+r.charCodeAt(0))),yRe=new Map(hB.map((r,e)=>[r,ID[e]])),wRe=new Map(ID.map((r,e)=>[r,hB[e]]));Q_.exports={encode:r=>hB.reduce((e,t)=>e.split(t).join(yRe.get(t)),r),decode:r=>ID.reduce((e,t)=>e.split(t).join(wRe.get(t)),r)}});var v_=w((Kot,S_)=>{"use strict";S_.exports=(r,e,t)=>(r&=4095,t&&(r=(r|384)&~18),e&&(r&256&&(r|=64),r&32&&(r|=8),r&4&&(r|=1)),r)});var xD=w((Yot,x_)=>{"use strict";var k_=uf(),P_=gB(),D_=hf(),Uot=Zd(),sa=require("fs"),pf=require("path"),Hot=Xd(),BRe=16*1024*1024,R_=Symbol("process"),F_=Symbol("file"),N_=Symbol("directory"),wD=Symbol("symlink"),L_=Symbol("hardlink"),$d=Symbol("header"),pB=Symbol("read"),BD=Symbol("lstat"),dB=Symbol("onlstat"),bD=Symbol("onread"),QD=Symbol("onreadlink"),SD=Symbol("openfile"),vD=Symbol("onopenfile"),ru=Symbol("close"),CB=Symbol("mode"),T_=fB(),bRe=yD(),O_=v_(),mB=T_(class extends k_{constructor(e,t){if(t=t||{},super(t),typeof e!="string")throw new TypeError("path is required");this.path=e,this.portable=!!t.portable,this.myuid=process.getuid&&process.getuid(),this.myuser=process.env.USER||"",this.maxReadSize=t.maxReadSize||BRe,this.linkCache=t.linkCache||new Map,this.statCache=t.statCache||new Map,this.preservePaths=!!t.preservePaths,this.cwd=t.cwd||process.cwd(),this.strict=!!t.strict,this.noPax=!!t.noPax,this.noMtime=!!t.noMtime,this.mtime=t.mtime||null,typeof t.onwarn=="function"&&this.on("warn",t.onwarn);let i=!1;if(!this.preservePaths&&pf.win32.isAbsolute(e)){let n=pf.win32.parse(e);this.path=e.substr(n.root.length),i=n.root}this.win32=!!t.win32||process.platform==="win32",this.win32&&(this.path=bRe.decode(this.path.replace(/\\/g,"/")),e=e.replace(/\\/g,"/")),this.absolute=t.absolute||pf.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[dB](this.statCache.get(this.absolute)):this[BD]()}[BD](){sa.lstat(this.absolute,(e,t)=>{if(e)return this.emit("error",e);this[dB](t)})}[dB](e){this.statCache.set(this.absolute,e),this.stat=e,e.isFile()||(e.size=0),this.type=QRe(e),this.emit("stat",e),this[R_]()}[R_](){switch(this.type){case"File":return this[F_]();case"Directory":return this[N_]();case"SymbolicLink":return this[wD]();default:return this.end()}}[CB](e){return O_(e,this.type==="Directory",this.portable)}[$d](){this.type==="Directory"&&this.portable&&(this.noMtime=!0),this.header=new D_({path:this.path,linkpath:this.linkpath,mode:this[CB](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 P_({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)}[N_](){this.path.substr(-1)!=="/"&&(this.path+="/"),this.stat.size=0,this[$d](),this.end()}[wD](){sa.readlink(this.absolute,(e,t)=>{if(e)return this.emit("error",e);this[QD](t)})}[QD](e){this.linkpath=e.replace(/\\/g,"/"),this[$d](),this.end()}[L_](e){this.type="Link",this.linkpath=pf.relative(this.cwd,e).replace(/\\/g,"/"),this.stat.size=0,this[$d](),this.end()}[F_](){if(this.stat.nlink>1){let e=this.stat.dev+":"+this.stat.ino;if(this.linkCache.has(e)){let t=this.linkCache.get(e);if(t.indexOf(this.cwd)===0)return this[L_](t)}this.linkCache.set(e,this.absolute)}if(this[$d](),this.stat.size===0)return this.end();this[SD]()}[SD](){sa.open(this.absolute,"r",(e,t)=>{if(e)return this.emit("error",e);this[vD](t)})}[vD](e){let t=512*Math.ceil(this.stat.size/512),i=Math.min(t,this.maxReadSize),n=Buffer.allocUnsafe(i);this[pB](e,n,0,n.length,0,this.stat.size,t)}[pB](e,t,i,n,s,o,a){sa.read(e,t,i,n,s,(l,c)=>{if(l)return this[ru](e,()=>this.emit("error",l));this[bD](e,t,i,n,s,o,a,c)})}[ru](e,t){sa.close(e,t)}[bD](e,t,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[ru](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[ru](e,()=>this.emit("error",u))}if(l===o)for(let u=l;uu?this.emit("error",u):this.end());i>=n&&(t=Buffer.allocUnsafe(n),i=0),n=t.length-i,this[pB](e,t,i,n,s,o,a)}}),M_=class extends mB{constructor(e,t){super(e,t)}[BD](){this[dB](sa.lstatSync(this.absolute))}[wD](){this[QD](sa.readlinkSync(this.absolute))}[SD](){this[vD](sa.openSync(this.absolute,"r"))}[pB](e,t,i,n,s,o,a){let l=!0;try{let c=sa.readSync(e,t,i,n,s);this[bD](e,t,i,n,s,o,a,c),l=!1}finally{if(l)try{this[ru](e,()=>{})}catch(c){}}}[ru](e,t){sa.closeSync(e),t()}},SRe=T_(class extends k_{constructor(e,t){t=t||{},super(t),this.preservePaths=!!t.preservePaths,this.portable=!!t.portable,this.strict=!!t.strict,this.noPax=!!t.noPax,this.noMtime=!!t.noMtime,this.readEntry=e,this.type=e.type,this.type==="Directory"&&this.portable&&(this.noMtime=!0),this.path=e.path,this.mode=this[CB](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:t.mtime||e.mtime,this.atime=this.portable?null:e.atime,this.ctime=this.portable?null:e.ctime,this.linkpath=e.linkpath,typeof t.onwarn=="function"&&this.on("warn",t.onwarn);let i=!1;if(pf.isAbsolute(this.path)&&!this.preservePaths){let n=pf.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 D_({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 P_({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)}[CB](e){return O_(e,this.type==="Directory",this.portable)}write(e){let t=e.length;if(t>this.blockRemain)throw new Error("writing more to entry than is appropriate");return this.blockRemain-=t,super.write(e)}end(){return this.blockRemain&&this.write(Buffer.alloc(this.blockRemain)),super.end()}});mB.Sync=M_;mB.Tar=SRe;var QRe=r=>r.isFile()?"File":r.isDirectory()?"Directory":r.isSymbolicLink()?"SymbolicLink":"Unsupported";x_.exports=mB});var SB=w((Jot,K_)=>{"use strict";var kD=class{constructor(e,t){this.path=e||"./",this.absolute=t,this.entry=null,this.stat=null,this.readdir=null,this.pending=!1,this.ignore=!1,this.piped=!1}},vRe=uf(),xRe=fD(),kRe=Zd(),PD=xD(),PRe=PD.Sync,DRe=PD.Tar,RRe=Bp(),U_=Buffer.alloc(1024),EB=Symbol("onStat"),IB=Symbol("ended"),oa=Symbol("queue"),df=Symbol("current"),iu=Symbol("process"),yB=Symbol("processing"),H_=Symbol("processJob"),aa=Symbol("jobs"),DD=Symbol("jobDone"),wB=Symbol("addFSEntry"),j_=Symbol("addTarEntry"),RD=Symbol("stat"),FD=Symbol("readdir"),BB=Symbol("onreaddir"),bB=Symbol("pipe"),G_=Symbol("entry"),ND=Symbol("entryOpt"),LD=Symbol("writeEntryClass"),Y_=Symbol("write"),TD=Symbol("ondrain"),QB=require("fs"),q_=require("path"),FRe=fB(),OD=FRe(class extends vRe{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 xRe.Gzip(e.gzip),this.zip.on("data",t=>super.write(t)),this.zip.on("end",t=>super.end()),this.zip.on("drain",t=>this[TD]()),this.on("resume",t=>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:t=>!0,this[oa]=new RRe,this[aa]=0,this.jobs=+e.jobs||4,this[yB]=!1,this[IB]=!1}[Y_](e){return super.write(e)}add(e){return this.write(e),this}end(e){return e&&this.write(e),this[IB]=!0,this[iu](),this}write(e){if(this[IB])throw new Error("write after end");return e instanceof kRe?this[j_](e):this[wB](e),this.flowing}[j_](e){let t=q_.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,t,!1);i.entry=new DRe(e,this[ND](i)),i.entry.on("end",n=>this[DD](i)),this[aa]+=1,this[oa].push(i)}this[iu]()}[wB](e){let t=q_.resolve(this.cwd,e);this.prefix&&(e=this.prefix+"/"+e.replace(/^\.(\/+|$)/,"")),this[oa].push(new kD(e,t)),this[iu]()}[RD](e){e.pending=!0,this[aa]+=1;let t=this.follow?"stat":"lstat";QB[t](e.absolute,(i,n)=>{e.pending=!1,this[aa]-=1,i?this.emit("error",i):this[EB](e,n)})}[EB](e,t){this.statCache.set(e.absolute,t),e.stat=t,this.filter(e.path,t)||(e.ignore=!0),this[iu]()}[FD](e){e.pending=!0,this[aa]+=1,QB.readdir(e.absolute,(t,i)=>{if(e.pending=!1,this[aa]-=1,t)return this.emit("error",t);this[BB](e,i)})}[BB](e,t){this.readdirCache.set(e.absolute,t),e.readdir=t,this[iu]()}[iu](){if(!this[yB]){this[yB]=!0;for(let e=this[oa].head;e!==null&&this[aa]this.warn(t,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}}[G_](e){this[aa]+=1;try{return new this[LD](e.path,this[ND](e)).on("end",()=>this[DD](e)).on("error",t=>this.emit("error",t))}catch(t){this.emit("error",t)}}[TD](){this[df]&&this[df].entry&&this[df].entry.resume()}[bB](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[wB](o+n)});let t=e.entry,i=this.zip;i?t.on("data",n=>{i.write(n)||t.pause()}):t.on("data",n=>{super.write(n)||t.pause()})}pause(){return this.zip&&this.zip.pause(),super.pause()}}),J_=class extends OD{constructor(e){super(e);this[LD]=PRe}pause(){}resume(){}[RD](e){let t=this.follow?"statSync":"lstatSync";this[EB](e,QB[t](e.absolute))}[FD](e,t){this[BB](e,QB.readdirSync(e.absolute))}[bB](e){let t=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[wB](o+n)}),i?t.on("data",n=>{i.write(n)}):t.on("data",n=>{super[Y_](n)})}};OD.Sync=J_;K_.exports=OD});var wf=w(eC=>{"use strict";var NRe=uf(),LRe=require("events").EventEmitter,Us=require("fs"),vB=process.binding("fs"),Wot=vB.writeBuffers,TRe=vB.FSReqWrap||vB.FSReqCallback,Cf=Symbol("_autoClose"),Aa=Symbol("_close"),tC=Symbol("_ended"),or=Symbol("_fd"),W_=Symbol("_finished"),nu=Symbol("_flags"),MD=Symbol("_flush"),KD=Symbol("_handleChunk"),UD=Symbol("_makeBuf"),HD=Symbol("_mode"),xB=Symbol("_needDrain"),mf=Symbol("_onerror"),Ef=Symbol("_onopen"),jD=Symbol("_onread"),su=Symbol("_onwrite"),Ql=Symbol("_open"),Sl=Symbol("_path"),ou=Symbol("_pos"),la=Symbol("_queue"),If=Symbol("_read"),z_=Symbol("_readSize"),vl=Symbol("_reading"),kB=Symbol("_remain"),__=Symbol("_size"),PB=Symbol("_write"),yf=Symbol("_writing"),DB=Symbol("_defaultFlag"),GD=class extends NRe{constructor(e,t){if(t=t||{},super(t),this.writable=!1,typeof e!="string")throw new TypeError("path must be a string");this[or]=typeof t.fd=="number"?t.fd:null,this[Sl]=e,this[z_]=t.readSize||16*1024*1024,this[vl]=!1,this[__]=typeof t.size=="number"?t.size:Infinity,this[kB]=this[__],this[Cf]=typeof t.autoClose=="boolean"?t.autoClose:!0,typeof this[or]=="number"?this[If]():this[Ql]()}get fd(){return this[or]}get path(){return this[Sl]}write(){throw new TypeError("this is a readable stream")}end(){throw new TypeError("this is a readable stream")}[Ql](){Us.open(this[Sl],"r",(e,t)=>this[Ef](e,t))}[Ef](e,t){e?this[mf](e):(this[or]=t,this.emit("open",t),this[If]())}[UD](){return Buffer.allocUnsafe(Math.min(this[z_],this[kB]))}[If](){if(!this[vl]){this[vl]=!0;let e=this[UD]();if(e.length===0)return process.nextTick(()=>this[jD](null,0,e));Us.read(this[or],e,0,e.length,null,(t,i,n)=>this[jD](t,i,n))}}[jD](e,t,i){this[vl]=!1,e?this[mf](e):this[KD](t,i)&&this[If]()}[Aa](){this[Cf]&&typeof this[or]=="number"&&(Us.close(this[or],e=>this.emit("close")),this[or]=null)}[mf](e){this[vl]=!0,this[Aa](),this.emit("error",e)}[KD](e,t){let i=!1;return this[kB]-=e,e>0&&(i=super.write(ethis[Ef](e,t))}[Ef](e,t){this[DB]&&this[nu]==="r+"&&e&&e.code==="ENOENT"?(this[nu]="w",this[Ql]()):e?this[mf](e):(this[or]=t,this.emit("open",t),this[MD]())}end(e,t){e&&this.write(e,t),this[tC]=!0,!this[yf]&&!this[la].length&&typeof this[or]=="number"&&this[su](null,0)}write(e,t){return typeof e=="string"&&(e=new Buffer(e,t)),this[tC]?(this.emit("error",new Error("write() after end()")),!1):this[or]===null||this[yf]||this[la].length?(this[la].push(e),this[xB]=!0,!1):(this[yf]=!0,this[PB](e),!0)}[PB](e){Us.write(this[or],e,0,e.length,this[ou],(t,i)=>this[su](t,i))}[su](e,t){e?this[mf](e):(this[ou]!==null&&(this[ou]+=t),this[la].length?this[MD]():(this[yf]=!1,this[tC]&&!this[W_]?(this[W_]=!0,this[Aa](),this.emit("finish")):this[xB]&&(this[xB]=!1,this.emit("drain"))))}[MD](){if(this[la].length===0)this[tC]&&this[su](null,0);else if(this[la].length===1)this[PB](this[la].pop());else{let e=this[la];this[la]=[],ORe(this[or],e,this[ou],(t,i)=>this[su](t,i))}}[Aa](){this[Cf]&&typeof this[or]=="number"&&(Us.close(this[or],e=>this.emit("close")),this[or]=null)}},X_=class extends YD{[Ql](){let e;try{e=Us.openSync(this[Sl],this[nu],this[HD])}catch(t){if(this[DB]&&this[nu]==="r+"&&t&&t.code==="ENOENT")return this[nu]="w",this[Ql]();throw t}this[Ef](null,e)}[Aa](){if(this[Cf]&&typeof this[or]=="number"){try{Us.closeSync(this[or])}catch(e){}this[or]=null,this.emit("close")}}[PB](e){try{this[su](null,Us.writeSync(this[or],e,0,e.length,this[ou]))}catch(t){this[su](t,0)}}},ORe=(r,e,t,i)=>{let n=(o,a)=>i(o,a,e),s=new TRe;s.oncomplete=n,vB.writeBuffers(r,e,t,s)};eC.ReadStream=GD;eC.ReadStreamSync=V_;eC.WriteStream=YD;eC.WriteStreamSync=X_});var nC=w((Xot,Z_)=>{"use strict";var MRe=fB(),_ot=require("path"),KRe=hf(),URe=require("events"),HRe=Bp(),jRe=1024*1024,GRe=Zd(),$_=gB(),YRe=fD(),qD=Buffer.from([31,139]),Hs=Symbol("state"),au=Symbol("writeEntry"),uA=Symbol("readEntry"),JD=Symbol("nextEntry"),eV=Symbol("processEntry"),js=Symbol("extendedHeader"),rC=Symbol("globalExtendedHeader"),xl=Symbol("meta"),tV=Symbol("emitMeta"),yr=Symbol("buffer"),gA=Symbol("queue"),Au=Symbol("ended"),rV=Symbol("emittedEnd"),lu=Symbol("emit"),Ln=Symbol("unzip"),RB=Symbol("consumeChunk"),FB=Symbol("consumeChunkSub"),WD=Symbol("consumeBody"),iV=Symbol("consumeMeta"),nV=Symbol("consumeHeader"),NB=Symbol("consuming"),zD=Symbol("bufferConcat"),_D=Symbol("maybeEnd"),iC=Symbol("writing"),kl=Symbol("aborted"),LB=Symbol("onDone"),cu=Symbol("sawValidEntry"),TB=Symbol("sawNullBlock"),OB=Symbol("sawEOF"),qRe=r=>!0;Z_.exports=MRe(class extends URe{constructor(e){e=e||{},super(e),this.file=e.file||"",this[cu]=null,this.on(LB,t=>{(this[Hs]==="begin"||this[cu]===!1)&&this.warn("TAR_BAD_ARCHIVE","Unrecognized archive format")}),e.ondone?this.on(LB,e.ondone):this.on(LB,t=>{this.emit("prefinish"),this.emit("finish"),this.emit("end"),this.emit("close")}),this.strict=!!e.strict,this.maxMetaEntrySize=e.maxMetaEntrySize||jRe,this.filter=typeof e.filter=="function"?e.filter:qRe,this.writable=!0,this.readable=!1,this[gA]=new HRe,this[yr]=null,this[uA]=null,this[au]=null,this[Hs]="begin",this[xl]="",this[js]=null,this[rC]=null,this[Au]=!1,this[Ln]=null,this[kl]=!1,this[TB]=!1,this[OB]=!1,typeof e.onwarn=="function"&&this.on("warn",e.onwarn),typeof e.onentry=="function"&&this.on("entry",e.onentry)}[nV](e,t){this[cu]===null&&(this[cu]=!1);let i;try{i=new KRe(e,t,this[js],this[rC])}catch(n){return this.warn("TAR_ENTRY_INVALID",n)}if(i.nullBlock)this[TB]?(this[OB]=!0,this[Hs]==="begin"&&(this[Hs]="header"),this[lu]("eof")):(this[TB]=!0,this[lu]("nullBlock"));else if(this[TB]=!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[au]=new GRe(i,this[js],this[rC]);if(!this[cu])if(s.remain){let o=()=>{s.invalid||(this[cu]=!0)};s.on("end",o)}else this[cu]=!0;s.meta?s.size>this.maxMetaEntrySize?(s.ignore=!0,this[lu]("ignoredEntry",s),this[Hs]="ignore",s.resume()):s.size>0&&(this[xl]="",s.on("data",o=>this[xl]+=o),this[Hs]="meta"):(this[js]=null,s.ignore=s.ignore||!this.filter(s.path,s),s.ignore?(this[lu]("ignoredEntry",s),this[Hs]=s.remain?"ignore":"header",s.resume()):(s.remain?this[Hs]="body":(this[Hs]="header",s.end()),this[uA]?this[gA].push(s):(this[gA].push(s),this[JD]())))}}}[eV](e){let t=!0;return e?Array.isArray(e)?this.emit.apply(this,e):(this[uA]=e,this.emit("entry",e),e.emittedEnd||(e.on("end",i=>this[JD]()),t=!1)):(this[uA]=null,t=!1),t}[JD](){do;while(this[eV](this[gA].shift()));if(!this[gA].length){let e=this[uA];!e||e.flowing||e.size===e.remain?this[iC]||this.emit("drain"):e.once("drain",i=>this.emit("drain"))}}[WD](e,t){let i=this[au],n=i.blockRemain,s=n>=e.length&&t===0?e:e.slice(t,t+n);return i.write(s),i.blockRemain||(this[Hs]="header",this[au]=null,i.end()),s.length}[iV](e,t){let i=this[au],n=this[WD](e,t);return this[au]||this[tV](i),n}[lu](e,t,i){!this[gA].length&&!this[uA]?this.emit(e,t,i):this[gA].push([e,t,i])}[tV](e){switch(this[lu]("meta",this[xl]),e.type){case"ExtendedHeader":case"OldExtendedHeader":this[js]=$_.parse(this[xl],this[js],!1);break;case"GlobalExtendedHeader":this[rC]=$_.parse(this[xl],this[rC],!0);break;case"NextFileHasLongPath":case"OldGnuLongPath":this[js]=this[js]||Object.create(null),this[js].path=this[xl].replace(/\0.*/,"");break;case"NextFileHasLongLinkpath":this[js]=this[js]||Object.create(null),this[js].linkpath=this[xl].replace(/\0.*/,"");break;default:throw new Error("unknown meta: "+e.type)}}abort(e){this[kl]=!0,this.emit("abort",e),this.warn("TAR_ABORT",e,{recoverable:!1})}write(e){if(this[kl])return;if(this[Ln]===null&&e){if(this[yr]&&(e=Buffer.concat([this[yr],e]),this[yr]=null),e.lengththis[RB](s)),this[Ln].on("error",s=>this.abort(s)),this[Ln].on("end",s=>{this[Au]=!0,this[RB]()}),this[iC]=!0;let n=this[Ln][i?"end":"write"](e);return this[iC]=!1,n}}this[iC]=!0,this[Ln]?this[Ln].write(e):this[RB](e),this[iC]=!1;let t=this[gA].length?!1:this[uA]?this[uA].flowing:!0;return!t&&!this[gA].length&&this[uA].once("drain",i=>this.emit("drain")),t}[zD](e){e&&!this[kl]&&(this[yr]=this[yr]?Buffer.concat([this[yr],e]):e)}[_D](){if(this[Au]&&!this[rV]&&!this[kl]&&!this[NB]){this[rV]=!0;let e=this[au];if(e&&e.blockRemain){let t=this[yr]?this[yr].length:0;this.warn("TAR_BAD_ARCHIVE",`Truncated input (needed ${e.blockRemain} more bytes, only ${t} available)`,{entry:e}),this[yr]&&e.write(this[yr]),e.end()}this[lu](LB)}}[RB](e){if(this[NB])this[zD](e);else if(!e&&!this[yr])this[_D]();else{if(this[NB]=!0,this[yr]){this[zD](e);let t=this[yr];this[yr]=null,this[FB](t)}else this[FB](e);for(;this[yr]&&this[yr].length>=512&&!this[kl]&&!this[OB];){let t=this[yr];this[yr]=null,this[FB](t)}this[NB]=!1}(!this[yr]||this[Au])&&this[_D]()}[FB](e){let t=0,i=e.length;for(;t+512<=i&&!this[kl]&&!this[OB];)switch(this[Hs]){case"begin":case"header":this[nV](e,t),t+=512;break;case"ignore":case"body":t+=this[WD](e,t);break;case"meta":t+=this[iV](e,t);break;default:throw new Error("invalid state: "+this[Hs])}t{"use strict";var JRe=cf(),oV=nC(),Bf=require("fs"),WRe=wf(),aV=require("path"),Zot=sV.exports=(r,e,t)=>{typeof r=="function"?(t=r,e=null,r={}):Array.isArray(r)&&(e=r,r={}),typeof e=="function"&&(t=e,e=null),e?e=Array.from(e):e=[];let i=JRe(r);if(i.sync&&typeof t=="function")throw new TypeError("callback not supported for sync tar functions");if(!i.file&&typeof t=="function")throw new TypeError("callback only supported with file option");return e.length&&_Re(i,e),i.noResume||zRe(i),i.file&&i.sync?VRe(i):i.file?XRe(i,t):AV(i)},zRe=r=>{let e=r.onentry;r.onentry=e?t=>{e(t),t.resume()}:t=>t.resume()},_Re=(r,e)=>{let t=new Map(e.map(s=>[s.replace(/\/+$/,""),!0])),i=r.filter,n=(s,o)=>{let a=o||aV.parse(s).root||".",l=s===a?!1:t.has(s)?t.get(s):n(aV.dirname(s),a);return t.set(s,l),l};r.filter=i?(s,o)=>i(s,o)&&n(s.replace(/\/+$/,"")):s=>n(s.replace(/\/+$/,""))},VRe=r=>{let e=AV(r),t=r.file,i=!0,n;try{let s=Bf.statSync(t),o=r.maxReadSize||16*1024*1024;if(s.size{let t=new oV(r),i=r.maxReadSize||16*1024*1024,n=r.file,s=new Promise((o,a)=>{t.on("error",a),t.on("end",o),Bf.stat(n,(l,c)=>{if(l)a(l);else{let u=new WRe.ReadStream(n,{readSize:i,size:c.size});u.on("error",a),u.pipe(t)}})});return e?s.then(e,e):s},AV=r=>new oV(r)});var hV=w((rat,lV)=>{"use strict";var ZRe=cf(),KB=SB(),eat=require("fs"),cV=wf(),uV=MB(),gV=require("path"),tat=lV.exports=(r,e,t)=>{if(typeof e=="function"&&(t=e),Array.isArray(r)&&(e=r,r={}),!e||!Array.isArray(e)||!e.length)throw new TypeError("no files or directories specified");e=Array.from(e);let i=ZRe(r);if(i.sync&&typeof t=="function")throw new TypeError("callback not supported for sync tar functions");if(!i.file&&typeof t=="function")throw new TypeError("callback only supported with file option");return i.file&&i.sync?$Re(i,e):i.file?eFe(i,e,t):i.sync?tFe(i,e):rFe(i,e)},$Re=(r,e)=>{let t=new KB.Sync(r),i=new cV.WriteStreamSync(r.file,{mode:r.mode||438});t.pipe(i),fV(t,e)},eFe=(r,e,t)=>{let i=new KB(r),n=new cV.WriteStream(r.file,{mode:r.mode||438});i.pipe(n);let s=new Promise((o,a)=>{n.on("error",a),n.on("close",o),i.on("error",a)});return VD(i,e),t?s.then(t,t):s},fV=(r,e)=>{e.forEach(t=>{t.charAt(0)==="@"?uV({file:gV.resolve(r.cwd,t.substr(1)),sync:!0,noResume:!0,onentry:i=>r.add(i)}):r.add(t)}),r.end()},VD=(r,e)=>{for(;e.length;){let t=e.shift();if(t.charAt(0)==="@")return uV({file:gV.resolve(r.cwd,t.substr(1)),noResume:!0,onentry:i=>r.add(i)}).then(i=>VD(r,e));r.add(t)}r.end()},tFe=(r,e)=>{let t=new KB.Sync(r);return fV(t,e),t},rFe=(r,e)=>{let t=new KB(r);return VD(t,e),t}});var XD=w((sat,pV)=>{"use strict";var iFe=cf(),dV=SB(),iat=nC(),Gs=require("fs"),CV=wf(),mV=MB(),EV=require("path"),IV=hf(),nat=pV.exports=(r,e,t)=>{let i=iFe(r);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?nFe(i,e):sFe(i,e,t)},nFe=(r,e)=>{let t=new dV.Sync(r),i=!0,n,s;try{try{n=Gs.openSync(r.file,"r+")}catch(l){if(l.code==="ENOENT")n=Gs.openSync(r.file,"w+");else throw l}let o=Gs.fstatSync(n),a=Buffer.alloc(512);e:for(s=0;so.size)break;s+=c,r.mtimeCache&&r.mtimeCache.set(l.path,l.mtime)}i=!1,oFe(r,t,s,n,e)}finally{if(i)try{Gs.closeSync(n)}catch(o){}}},oFe=(r,e,t,i,n)=>{let s=new CV.WriteStreamSync(r.file,{fd:i,start:t});e.pipe(s),aFe(e,n)},sFe=(r,e,t)=>{e=Array.from(e);let i=new dV(r),n=(o,a,l)=>{let c=(p,m)=>{p?Gs.close(o,y=>l(p)):l(null,m)},u=0;if(a===0)return c(null,0);let g=0,f=Buffer.alloc(512),h=(p,m)=>{if(p)return c(p);if(g+=m,g<512&&m)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 y=new IV(f);if(!y.cksumValid)return c(null,u);let b=512*Math.ceil(y.size/512);if(u+b+512>a||(u+=b+512,u>=a))return c(null,u);r.mtimeCache&&r.mtimeCache.set(y.path,y.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(r.file,l,c);if(u)return a(u);Gs.fstat(g,(f,h)=>{if(f)return a(f);n(g,h.size,(p,m)=>{if(p)return a(p);let y=new CV.WriteStream(r.file,{fd:g,start:m});i.pipe(y),y.on("error",a),y.on("close",o),yV(i,e)})})};Gs.open(r.file,l,c)});return t?s.then(t,t):s},aFe=(r,e)=>{e.forEach(t=>{t.charAt(0)==="@"?mV({file:EV.resolve(r.cwd,t.substr(1)),sync:!0,noResume:!0,onentry:i=>r.add(i)}):r.add(t)}),r.end()},yV=(r,e)=>{for(;e.length;){let t=e.shift();if(t.charAt(0)==="@")return mV({file:EV.resolve(r.cwd,t.substr(1)),noResume:!0,onentry:i=>r.add(i)}).then(i=>yV(r,e));r.add(t)}r.end()}});var BV=w((aat,wV)=>{"use strict";var AFe=cf(),lFe=XD(),oat=wV.exports=(r,e,t)=>{let i=AFe(r);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),cFe(i),lFe(i,e,t)},cFe=r=>{let e=r.filter;r.mtimeCache||(r.mtimeCache=new Map),r.filter=e?(t,i)=>e(t,i)&&!(r.mtimeCache.get(t)>i.mtime):(t,i)=>!(r.mtimeCache.get(t)>i.mtime)}});var SV=w((Aat,bV)=>{var{promisify:QV}=require("util"),Pl=require("fs"),uFe=r=>{if(!r)r={mode:511,fs:Pl};else if(typeof r=="object")r=N({mode:511,fs:Pl},r);else if(typeof r=="number")r={mode:r,fs:Pl};else if(typeof r=="string")r={mode:parseInt(r,8),fs:Pl};else throw new TypeError("invalid options argument");return r.mkdir=r.mkdir||r.fs.mkdir||Pl.mkdir,r.mkdirAsync=QV(r.mkdir),r.stat=r.stat||r.fs.stat||Pl.stat,r.statAsync=QV(r.stat),r.statSync=r.statSync||r.fs.statSync||Pl.statSync,r.mkdirSync=r.mkdirSync||r.fs.mkdirSync||Pl.mkdirSync,r};bV.exports=uFe});var xV=w((lat,vV)=>{var gFe=process.env.__TESTING_MKDIRP_PLATFORM__||process.platform,{resolve:fFe,parse:hFe}=require("path"),pFe=r=>{if(/\0/.test(r))throw Object.assign(new TypeError("path must be a string without null bytes"),{path:r,code:"ERR_INVALID_ARG_VALUE"});if(r=fFe(r),gFe==="win32"){let e=/[*|"<>?:]/,{root:t}=hFe(r);if(e.test(r.substr(t.length)))throw Object.assign(new Error("Illegal characters in path."),{path:r,code:"EINVAL"})}return r};vV.exports=pFe});var FV=w((cat,kV)=>{var{dirname:PV}=require("path"),DV=(r,e,t=void 0)=>t===e?Promise.resolve():r.statAsync(e).then(i=>i.isDirectory()?t:void 0,i=>i.code==="ENOENT"?DV(r,PV(e),e):void 0),RV=(r,e,t=void 0)=>{if(t!==e)try{return r.statSync(e).isDirectory()?t:void 0}catch(i){return i.code==="ENOENT"?RV(r,PV(e),e):void 0}};kV.exports={findMade:DV,findMadeSync:RV}});var eR=w((uat,NV)=>{var{dirname:LV}=require("path"),ZD=(r,e,t)=>{e.recursive=!1;let i=LV(r);return i===r?e.mkdirAsync(r,e).catch(n=>{if(n.code!=="EISDIR")throw n}):e.mkdirAsync(r,e).then(()=>t||r,n=>{if(n.code==="ENOENT")return ZD(i,e).then(s=>ZD(r,e,s));if(n.code!=="EEXIST"&&n.code!=="EROFS")throw n;return e.statAsync(r).then(s=>{if(s.isDirectory())return t;throw n},()=>{throw n})})},$D=(r,e,t)=>{let i=LV(r);if(e.recursive=!1,i===r)try{return e.mkdirSync(r,e)}catch(n){if(n.code!=="EISDIR")throw n;return}try{return e.mkdirSync(r,e),t||r}catch(n){if(n.code==="ENOENT")return $D(r,e,$D(i,e,t));if(n.code!=="EEXIST"&&n.code!=="EROFS")throw n;try{if(!e.statSync(r).isDirectory())throw n}catch(s){throw n}}};NV.exports={mkdirpManual:ZD,mkdirpManualSync:$D}});var MV=w((gat,TV)=>{var{dirname:OV}=require("path"),{findMade:dFe,findMadeSync:CFe}=FV(),{mkdirpManual:mFe,mkdirpManualSync:EFe}=eR(),IFe=(r,e)=>(e.recursive=!0,OV(r)===r?e.mkdirAsync(r,e):dFe(e,r).then(i=>e.mkdirAsync(r,e).then(()=>i).catch(n=>{if(n.code==="ENOENT")return mFe(r,e);throw n}))),yFe=(r,e)=>{if(e.recursive=!0,OV(r)===r)return e.mkdirSync(r,e);let i=CFe(e,r);try{return e.mkdirSync(r,e),i}catch(n){if(n.code==="ENOENT")return EFe(r,e);throw n}};TV.exports={mkdirpNative:IFe,mkdirpNativeSync:yFe}});var jV=w((fat,KV)=>{var UV=require("fs"),wFe=process.env.__TESTING_MKDIRP_NODE_VERSION__||process.version,tR=wFe.replace(/^v/,"").split("."),HV=+tR[0]>10||+tR[0]==10&&+tR[1]>=12,BFe=HV?r=>r.mkdir===UV.mkdir:()=>!1,bFe=HV?r=>r.mkdirSync===UV.mkdirSync:()=>!1;KV.exports={useNative:BFe,useNativeSync:bFe}});var zV=w((hat,GV)=>{var bf=SV(),Qf=xV(),{mkdirpNative:YV,mkdirpNativeSync:qV}=MV(),{mkdirpManual:JV,mkdirpManualSync:WV}=eR(),{useNative:QFe,useNativeSync:SFe}=jV(),Sf=(r,e)=>(r=Qf(r),e=bf(e),QFe(e)?YV(r,e):JV(r,e)),vFe=(r,e)=>(r=Qf(r),e=bf(e),SFe(e)?qV(r,e):WV(r,e));Sf.sync=vFe;Sf.native=(r,e)=>YV(Qf(r),bf(e));Sf.manual=(r,e)=>JV(Qf(r),bf(e));Sf.nativeSync=(r,e)=>qV(Qf(r),bf(e));Sf.manualSync=(r,e)=>WV(Qf(r),bf(e));GV.exports=Sf});var t6=w((pat,_V)=>{"use strict";var Ys=require("fs"),uu=require("path"),xFe=Ys.lchown?"lchown":"chown",kFe=Ys.lchownSync?"lchownSync":"chownSync",VV=Ys.lchown&&!process.version.match(/v1[1-9]+\./)&&!process.version.match(/v10\.[6-9]/),XV=(r,e,t)=>{try{return Ys[kFe](r,e,t)}catch(i){if(i.code!=="ENOENT")throw i}},PFe=(r,e,t)=>{try{return Ys.chownSync(r,e,t)}catch(i){if(i.code!=="ENOENT")throw i}},DFe=VV?(r,e,t,i)=>n=>{!n||n.code!=="EISDIR"?i(n):Ys.chown(r,e,t,i)}:(r,e,t,i)=>i,rR=VV?(r,e,t)=>{try{return XV(r,e,t)}catch(i){if(i.code!=="EISDIR")throw i;PFe(r,e,t)}}:(r,e,t)=>XV(r,e,t),RFe=process.version,ZV=(r,e,t)=>Ys.readdir(r,e,t),FFe=(r,e)=>Ys.readdirSync(r,e);/^v4\./.test(RFe)&&(ZV=(r,e,t)=>Ys.readdir(r,t));var UB=(r,e,t,i)=>{Ys[xFe](r,e,t,DFe(r,e,t,n=>{i(n&&n.code!=="ENOENT"?n:null)}))},$V=(r,e,t,i,n)=>{if(typeof e=="string")return Ys.lstat(uu.resolve(r,e),(s,o)=>{if(s)return n(s.code!=="ENOENT"?s:null);o.name=e,$V(r,o,t,i,n)});if(e.isDirectory())iR(uu.resolve(r,e.name),t,i,s=>{if(s)return n(s);let o=uu.resolve(r,e.name);UB(o,t,i,n)});else{let s=uu.resolve(r,e.name);UB(s,t,i,n)}},iR=(r,e,t,i)=>{ZV(r,{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 UB(r,e,t,i);let o=s.length,a=null,l=c=>{if(!a){if(c)return i(a=c);if(--o==0)return UB(r,e,t,i)}};s.forEach(c=>$V(r,c,e,t,l))})},NFe=(r,e,t,i)=>{if(typeof e=="string")try{let n=Ys.lstatSync(uu.resolve(r,e));n.name=e,e=n}catch(n){if(n.code==="ENOENT")return;throw n}e.isDirectory()&&e6(uu.resolve(r,e.name),t,i),rR(uu.resolve(r,e.name),t,i)},e6=(r,e,t)=>{let i;try{i=FFe(r,{withFileTypes:!0})}catch(n){if(n.code==="ENOENT")return;if(n.code==="ENOTDIR"||n.code==="ENOTSUP")return rR(r,e,t);throw n}return i&&i.length&&i.forEach(n=>NFe(r,n,e,t)),rR(r,e,t)};_V.exports=iR;iR.sync=e6});var s6=w((mat,nR)=>{"use strict";var r6=zV(),qs=require("fs"),HB=require("path"),i6=t6(),sR=class extends Error{constructor(e,t){super("Cannot extract through symbolic link");this.path=t,this.symlink=e}get name(){return"SylinkError"}},sC=class extends Error{constructor(e,t){super(t+": Cannot cd into '"+e+"'");this.path=e,this.code=t}get name(){return"CwdError"}},dat=nR.exports=(r,e,t)=>{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=(y,b)=>{y?t(y):(g.set(r,!0),b&&l?i6(b,o,a,v=>h(v)):s?qs.chmod(r,n,t):t())};if(g&&g.get(r)===!0)return h();if(r===f)return qs.stat(r,(y,b)=>{(y||!b.isDirectory())&&(y=new sC(r,y&&y.code||"ENOTDIR")),h(y)});if(c)return r6(r,{mode:n}).then(y=>h(null,y),h);let m=HB.relative(f,r).split(/\/|\\/);jB(f,m,n,g,u,f,null,h)},jB=(r,e,t,i,n,s,o,a)=>{if(!e.length)return a(null,o);let l=e.shift(),c=r+"/"+l;if(i.get(c))return jB(c,e,t,i,n,s,o,a);qs.mkdir(c,t,n6(c,e,t,i,n,s,o,a))},n6=(r,e,t,i,n,s,o,a)=>l=>{if(l){if(l.path&&HB.dirname(l.path)===s&&(l.code==="ENOTDIR"||l.code==="ENOENT"))return a(new sC(s,l.code));qs.lstat(r,(c,u)=>{if(c)a(c);else if(u.isDirectory())jB(r,e,t,i,n,s,o,a);else if(n)qs.unlink(r,g=>{if(g)return a(g);qs.mkdir(r,t,n6(r,e,t,i,n,s,o,a))});else{if(u.isSymbolicLink())return a(new sR(r,r+"/"+e.join("/")));a(l)}})}else o=o||r,jB(r,e,t,i,n,s,o,a)},Cat=nR.exports.sync=(r,e)=>{let t=e.umask,i=e.mode|448,n=(i&t)!=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=y=>{u.set(r,!0),y&&a&&i6.sync(y,s,o),n&&qs.chmodSync(r,i)};if(u&&u.get(r)===!0)return f();if(r===g){let y=!1,b="ENOTDIR";try{y=qs.statSync(r).isDirectory()}catch(v){b=v.code}finally{if(!y)throw new sC(r,b)}f();return}if(l)return f(r6.sync(r,i));let p=HB.relative(g,r).split(/\/|\\/),m=null;for(let y=p.shift(),b=g;y&&(b+="/"+y);y=p.shift())if(!u.get(b))try{qs.mkdirSync(b,i),m=m||b,u.set(b,!0)}catch(v){if(v.path&&HB.dirname(v.path)===g&&(v.code==="ENOTDIR"||v.code==="ENOENT"))return new sC(g,v.code);let x=qs.lstatSync(b);if(x.isDirectory()){u.set(b,!0);continue}else if(c){qs.unlinkSync(b),qs.mkdirSync(b,i),m=m||b,u.set(b,!0);continue}else if(x.isSymbolicLink())return new sR(b,b+"/"+p.join("/"))}return f(m)}});var A6=w((Eat,o6)=>{var a6=require("assert");o6.exports=()=>{let r=new Map,e=new Map,{join:t}=require("path"),i=u=>t(u).split(/[\\\/]/).slice(0,-1).reduce((g,f)=>g.length?g.concat(t(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=>r.get(f)),dirs:[...g.dirs].map(f=>r.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 m=r.get(p);a6.equal(m[0],u),m.length===1?r.delete(p):(m.shift(),typeof m[0]=="function"?h.add(m[0]):m[0].forEach(y=>h.add(y)))}),f.forEach(p=>{let m=r.get(p);a6(m[0]instanceof Set),m[0].size===1&&m.length===1?r.delete(p):m[0].size===1?(m.shift(),h.add(m[0])):m[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=r.get(h);p?p.push(g):r.set(h,[g])}),f.forEach(h=>{let p=r.get(h);p?p[p.length-1]instanceof Set?p[p.length-1].add(g):p.push(new Set([g])):r.set(h,[new Set([g])])}),a(g)}}}});var u6=w((Iat,l6)=>{var LFe=process.env.__FAKE_PLATFORM__||process.platform,TFe=LFe==="win32",OFe=global.__FAKE_TESTING_FS__||require("fs"),{O_CREAT:MFe,O_TRUNC:KFe,O_WRONLY:UFe,UV_FS_O_FILEMAP:c6=0}=OFe.constants,HFe=TFe&&!!c6,jFe=512*1024,GFe=c6|KFe|MFe|UFe;l6.exports=HFe?r=>r"w"});var hR=w((bat,g6)=>{"use strict";var YFe=require("assert"),yat=require("events").EventEmitter,qFe=nC(),$t=require("fs"),JFe=wf(),fA=require("path"),oR=s6(),wat=oR.sync,f6=yD(),WFe=A6(),h6=Symbol("onEntry"),aR=Symbol("checkFs"),p6=Symbol("checkFs2"),AR=Symbol("isReusable"),hA=Symbol("makeFs"),lR=Symbol("file"),cR=Symbol("directory"),GB=Symbol("link"),d6=Symbol("symlink"),C6=Symbol("hardlink"),m6=Symbol("unsupported"),Bat=Symbol("unknown"),E6=Symbol("checkPath"),vf=Symbol("mkdir"),dn=Symbol("onError"),YB=Symbol("pending"),I6=Symbol("pend"),xf=Symbol("unpend"),uR=Symbol("ended"),gR=Symbol("maybeClose"),fR=Symbol("skip"),oC=Symbol("doChown"),aC=Symbol("uid"),AC=Symbol("gid"),y6=require("crypto"),w6=u6(),qB=()=>{throw new Error("sync function called cb somehow?!?")},zFe=(r,e)=>{if(process.platform!=="win32")return $t.unlink(r,e);let t=r+".DELETE."+y6.randomBytes(16).toString("hex");$t.rename(r,t,i=>{if(i)return e(i);$t.unlink(t,e)})},_Fe=r=>{if(process.platform!=="win32")return $t.unlinkSync(r);let e=r+".DELETE."+y6.randomBytes(16).toString("hex");$t.renameSync(r,e),$t.unlinkSync(e)},B6=(r,e,t)=>r===r>>>0?r:e===e>>>0?e:t,JB=class extends qFe{constructor(e){if(e||(e={}),e.ondone=t=>{this[uR]=!0,this[gR]()},super(e),this.reservations=WFe(),this.transform=typeof e.transform=="function"?e.transform:null,this.writable=!0,this.readable=!1,this[YB]=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=fA.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",t=>this[h6](t))}warn(e,t,i={}){return(e==="TAR_BAD_ARCHIVE"||e==="TAR_ABORT")&&(i.recoverable=!1),super.warn(e,t,i)}[gR](){this[uR]&&this[YB]===0&&(this.emit("prefinish"),this.emit("finish"),this.emit("end"),this.emit("close"))}[E6](e){if(this.strip){let t=e.path.split(/\/|\\/);if(t.length=this.strip&&(e.linkpath=i.slice(this.strip).join("/"))}}if(!this.preservePaths){let t=e.path;if(t.match(/(^|\/|\\)\.\.(\\|\/|$)/))return this.warn("TAR_ENTRY_ERROR","path contains '..'",{entry:e,path:t}),!1;if(fA.win32.isAbsolute(t)){let i=fA.win32.parse(t);e.path=t.substr(i.root.length);let n=i.root;this.warn("TAR_ENTRY_INFO",`stripping ${n} from absolute path`,{entry:e,path:t})}}if(this.win32){let t=fA.win32.parse(e.path);e.path=t.root===""?f6.encode(e.path):t.root+f6.encode(e.path.substr(t.root.length))}return fA.isAbsolute(e.path)?e.absolute=e.path:e.absolute=fA.resolve(this.cwd,e.path),!0}[h6](e){if(!this[E6](e))return e.resume();switch(YFe.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[m6](e)}}[dn](e,t){e.name==="CwdError"?this.emit("error",e):(this.warn("TAR_ENTRY_ERROR",e,{entry:t}),this[xf](),t.resume())}[vf](e,t,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:t},i)}[oC](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}[aC](e){return B6(this.uid,e.uid,this.processUid)}[AC](e){return B6(this.gid,e.gid,this.processGid)}[lR](e,t){let i=e.mode&4095||this.fmode,n=new JFe.WriteStream(e.absolute,{flags:w6(e.size),mode:i,autoClose:!1});n.on("error",l=>this[dn](l,e));let s=1,o=l=>{if(l)return this[dn](l,e);--s==0&&$t.close(n.fd,c=>{t(),c?this[dn](c,e):this[xf]()})};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;$t.futimes(u,g,f,h=>h?$t.utimes(c,g,f,p=>o(p&&h)):o())}if(this[oC](e)){s++;let g=this[aC](e),f=this[AC](e);$t.fchown(u,g,f,h=>h?$t.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[dn](l,e)),e.pipe(a)),a.pipe(n)}[cR](e,t){let i=e.mode&4095||this.dmode;this[vf](e.absolute,i,n=>{if(n)return t(),this[dn](n,e);let s=1,o=a=>{--s==0&&(t(),this[xf](),e.resume())};e.mtime&&!this.noMtime&&(s++,$t.utimes(e.absolute,e.atime||new Date,e.mtime,o)),this[oC](e)&&(s++,$t.chown(e.absolute,this[aC](e),this[AC](e),o)),o()})}[m6](e){e.unsupported=!0,this.warn("TAR_ENTRY_UNSUPPORTED",`unsupported entry type: ${e.type}`,{entry:e}),e.resume()}[d6](e,t){this[GB](e,e.linkpath,"symlink",t)}[C6](e,t){this[GB](e,fA.resolve(this.cwd,e.linkpath),"link",t)}[I6](){this[YB]++}[xf](){this[YB]--,this[gR]()}[fR](e){this[xf](),e.resume()}[AR](e,t){return e.type==="File"&&!this.unlink&&t.isFile()&&t.nlink<=1&&process.platform!=="win32"}[aR](e){this[I6]();let t=[e.path];e.linkpath&&t.push(e.linkpath),this.reservations.reserve(t,i=>this[p6](e,i))}[p6](e,t){this[vf](fA.dirname(e.absolute),this.dmode,i=>{if(i)return t(),this[dn](i,e);$t.lstat(e.absolute,(n,s)=>{s&&(this.keep||this.newer&&s.mtime>e.mtime)?(this[fR](e),t()):n||this[AR](e,s)?this[hA](null,e,t):s.isDirectory()?e.type==="Directory"?!e.mode||(s.mode&4095)===e.mode?this[hA](null,e,t):$t.chmod(e.absolute,e.mode,o=>this[hA](o,e,t)):$t.rmdir(e.absolute,o=>this[hA](o,e,t)):zFe(e.absolute,o=>this[hA](o,e,t))})})}[hA](e,t,i){if(e)return this[dn](e,t);switch(t.type){case"File":case"OldFile":case"ContiguousFile":return this[lR](t,i);case"Link":return this[C6](t,i);case"SymbolicLink":return this[d6](t,i);case"Directory":case"GNUDumpDir":return this[cR](t,i)}}[GB](e,t,i,n){$t[i](t,e.absolute,s=>{if(s)return this[dn](s,e);n(),this[xf](),e.resume()})}},b6=class extends JB{constructor(e){super(e)}[aR](e){let t=this[vf](fA.dirname(e.absolute),this.dmode,qB);if(t)return this[dn](t,e);try{let i=$t.lstatSync(e.absolute);if(this.keep||this.newer&&i.mtime>e.mtime)return this[fR](e);if(this[AR](e,i))return this[hA](null,e,qB);try{return i.isDirectory()?e.type==="Directory"?e.mode&&(i.mode&4095)!==e.mode&&$t.chmodSync(e.absolute,e.mode):$t.rmdirSync(e.absolute):_Fe(e.absolute),this[hA](null,e,qB)}catch(n){return this[dn](n,e)}}catch(i){return this[hA](null,e,qB)}}[lR](e,t){let i=e.mode&4095||this.fmode,n=l=>{let c;try{$t.closeSync(o)}catch(u){c=u}(l||c)&&this[dn](l||c,e)},s,o;try{o=$t.openSync(e.absolute,w6(e.size),i)}catch(l){return n(l)}let a=this.transform&&this.transform(e)||e;a!==e&&(a.on("error",l=>this[dn](l,e)),e.pipe(a)),a.on("data",l=>{try{$t.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{$t.futimesSync(o,u,g)}catch(f){try{$t.utimesSync(e.absolute,u,g)}catch(h){c=f}}}if(this[oC](e)){let u=this[aC](e),g=this[AC](e);try{$t.fchownSync(o,u,g)}catch(f){try{$t.chownSync(e.absolute,u,g)}catch(h){c=c||f}}}n(c)})}[cR](e,t){let i=e.mode&4095||this.dmode,n=this[vf](e.absolute,i);if(n)return this[dn](n,e);if(e.mtime&&!this.noMtime)try{$t.utimesSync(e.absolute,e.atime||new Date,e.mtime)}catch(s){}if(this[oC](e))try{$t.chownSync(e.absolute,this[aC](e),this[AC](e))}catch(s){}e.resume()}[vf](e,t){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:t})}catch(i){return i}}[GB](e,t,i,n){try{$t[i+"Sync"](t,e.absolute),e.resume()}catch(s){return this[dn](s,e)}}};JB.Sync=b6;g6.exports=JB});var k6=w((Sat,Q6)=>{"use strict";var VFe=cf(),WB=hR(),S6=require("fs"),v6=wf(),x6=require("path"),Qat=Q6.exports=(r,e,t)=>{typeof r=="function"?(t=r,e=null,r={}):Array.isArray(r)&&(e=r,r={}),typeof e=="function"&&(t=e,e=null),e?e=Array.from(e):e=[];let i=VFe(r);if(i.sync&&typeof t=="function")throw new TypeError("callback not supported for sync tar functions");if(!i.file&&typeof t=="function")throw new TypeError("callback only supported with file option");return e.length&&XFe(i,e),i.file&&i.sync?ZFe(i):i.file?$Fe(i,t):i.sync?eNe(i):tNe(i)},XFe=(r,e)=>{let t=new Map(e.map(s=>[s.replace(/\/+$/,""),!0])),i=r.filter,n=(s,o)=>{let a=o||x6.parse(s).root||".",l=s===a?!1:t.has(s)?t.get(s):n(x6.dirname(s),a);return t.set(s,l),l};r.filter=i?(s,o)=>i(s,o)&&n(s.replace(/\/+$/,"")):s=>n(s.replace(/\/+$/,""))},ZFe=r=>{let e=new WB.Sync(r),t=r.file,i=!0,n,s=S6.statSync(t),o=r.maxReadSize||16*1024*1024;new v6.ReadStreamSync(t,{readSize:o,size:s.size}).pipe(e)},$Fe=(r,e)=>{let t=new WB(r),i=r.maxReadSize||16*1024*1024,n=r.file,s=new Promise((o,a)=>{t.on("error",a),t.on("close",o),S6.stat(n,(l,c)=>{if(l)a(l);else{let u=new v6.ReadStream(n,{readSize:i,size:c.size});u.on("error",a),u.pipe(t)}})});return e?s.then(e,e):s},eNe=r=>new WB.Sync(r),tNe=r=>new WB(r)});var P6=w(pi=>{"use strict";pi.c=pi.create=hV();pi.r=pi.replace=XD();pi.t=pi.list=MB();pi.u=pi.update=BV();pi.x=pi.extract=k6();pi.Pack=SB();pi.Unpack=hR();pi.Parse=nC();pi.ReadEntry=Zd();pi.WriteEntry=xD();pi.Header=hf();pi.Pax=gB();pi.types=Xd()});var L6=w((kat,N6)=>{var dR;N6.exports.getContent=()=>(typeof dR=="undefined"&&(dR=require("zlib").brotliDecompressSync(Buffer.from("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","base64")).toString()),dR)});var H6=w((CR,U6)=>{(function(r,e){typeof CR=="object"?U6.exports=e():typeof define=="function"&&define.amd?define(e):r.treeify=e()})(CR,function(){function r(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 t(n,s,o,a,l,c,u){var g="",f=0,h,p,m=a.slice(0);if(m.push([s,o])&&a.length>0&&(a.forEach(function(b,v){v>0&&(g+=(b[1]?" ":"\u2502")+" "),!p&&b[0]===s&&(p=!0)}),g+=r(n,o)+n,l&&(typeof s!="object"||s instanceof Date)&&(g+=": "+s),p&&(g+=" (circular ref.)"),u(g)),!p&&typeof s=="object"){var y=e(s,c);y.forEach(function(b){h=++f===y.length,t(b,s[b],h,m,l,c,u)})}}var i={};return i.asLines=function(n,s,o,a){var l=typeof o!="function"?o:!1;t(".",n,!1,[],s,l,a||o)},i.asTree=function(n,s,o){var a="";return t(".",n,!1,[],s,o,function(l){a+=l+` -`}),a},i})});var _B=w((sAt,X6)=>{var ENe=Ks(),INe=Id(),yNe=/\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,wNe=/^\w*$/;function BNe(r,e){if(ENe(r))return!1;var t=typeof r;return t=="number"||t=="symbol"||t=="boolean"||r==null||INe(r)?!0:wNe.test(r)||!yNe.test(r)||e!=null&&r in Object(e)}X6.exports=BNe});var VB=w((oAt,Z6)=>{var bNe=Wc(),QNe=Rn(),SNe="[object AsyncFunction]",vNe="[object Function]",xNe="[object GeneratorFunction]",kNe="[object Proxy]";function PNe(r){if(!QNe(r))return!1;var e=bNe(r);return e==vNe||e==xNe||e==SNe||e==kNe}Z6.exports=PNe});var e7=w((aAt,$6)=>{var DNe=Ns(),RNe=DNe["__core-js_shared__"];$6.exports=RNe});var i7=w((AAt,t7)=>{var QR=e7(),r7=function(){var r=/[^.]+$/.exec(QR&&QR.keys&&QR.keys.IE_PROTO||"");return r?"Symbol(src)_1."+r:""}();function FNe(r){return!!r7&&r7 in r}t7.exports=FNe});var SR=w((lAt,n7)=>{var NNe=Function.prototype,LNe=NNe.toString;function TNe(r){if(r!=null){try{return LNe.call(r)}catch(e){}try{return r+""}catch(e){}}return""}n7.exports=TNe});var o7=w((cAt,s7)=>{var ONe=VB(),MNe=i7(),KNe=Rn(),UNe=SR(),HNe=/[\\^$.*+?()[\]{}|]/g,jNe=/^\[object .+?Constructor\]$/,GNe=Function.prototype,YNe=Object.prototype,qNe=GNe.toString,JNe=YNe.hasOwnProperty,WNe=RegExp("^"+qNe.call(JNe).replace(HNe,"\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g,"$1.*?")+"$");function zNe(r){if(!KNe(r)||MNe(r))return!1;var e=ONe(r)?WNe:jNe;return e.test(UNe(r))}s7.exports=zNe});var A7=w((uAt,a7)=>{function _Ne(r,e){return r==null?void 0:r[e]}a7.exports=_Ne});var Rl=w((gAt,l7)=>{var VNe=o7(),XNe=A7();function ZNe(r,e){var t=XNe(r,e);return VNe(t)?t:void 0}l7.exports=ZNe});var cC=w((fAt,c7)=>{var $Ne=Rl(),eLe=$Ne(Object,"create");c7.exports=eLe});var f7=w((hAt,u7)=>{var g7=cC();function tLe(){this.__data__=g7?g7(null):{},this.size=0}u7.exports=tLe});var p7=w((pAt,h7)=>{function rLe(r){var e=this.has(r)&&delete this.__data__[r];return this.size-=e?1:0,e}h7.exports=rLe});var C7=w((dAt,d7)=>{var iLe=cC(),nLe="__lodash_hash_undefined__",sLe=Object.prototype,oLe=sLe.hasOwnProperty;function aLe(r){var e=this.__data__;if(iLe){var t=e[r];return t===nLe?void 0:t}return oLe.call(e,r)?e[r]:void 0}d7.exports=aLe});var E7=w((CAt,m7)=>{var ALe=cC(),lLe=Object.prototype,cLe=lLe.hasOwnProperty;function uLe(r){var e=this.__data__;return ALe?e[r]!==void 0:cLe.call(e,r)}m7.exports=uLe});var y7=w((mAt,I7)=>{var gLe=cC(),fLe="__lodash_hash_undefined__";function hLe(r,e){var t=this.__data__;return this.size+=this.has(r)?0:1,t[r]=gLe&&e===void 0?fLe:e,this}I7.exports=hLe});var B7=w((EAt,w7)=>{var pLe=f7(),dLe=p7(),CLe=C7(),mLe=E7(),ELe=y7();function kf(r){var e=-1,t=r==null?0:r.length;for(this.clear();++e{function ILe(){this.__data__=[],this.size=0}b7.exports=ILe});var Pf=w((yAt,S7)=>{function yLe(r,e){return r===e||r!==r&&e!==e}S7.exports=yLe});var uC=w((wAt,v7)=>{var wLe=Pf();function BLe(r,e){for(var t=r.length;t--;)if(wLe(r[t][0],e))return t;return-1}v7.exports=BLe});var k7=w((BAt,x7)=>{var bLe=uC(),QLe=Array.prototype,SLe=QLe.splice;function vLe(r){var e=this.__data__,t=bLe(e,r);if(t<0)return!1;var i=e.length-1;return t==i?e.pop():SLe.call(e,t,1),--this.size,!0}x7.exports=vLe});var D7=w((bAt,P7)=>{var xLe=uC();function kLe(r){var e=this.__data__,t=xLe(e,r);return t<0?void 0:e[t][1]}P7.exports=kLe});var F7=w((QAt,R7)=>{var PLe=uC();function DLe(r){return PLe(this.__data__,r)>-1}R7.exports=DLe});var L7=w((SAt,N7)=>{var RLe=uC();function FLe(r,e){var t=this.__data__,i=RLe(t,r);return i<0?(++this.size,t.push([r,e])):t[i][1]=e,this}N7.exports=FLe});var gC=w((vAt,T7)=>{var NLe=Q7(),LLe=k7(),TLe=D7(),OLe=F7(),MLe=L7();function Df(r){var e=-1,t=r==null?0:r.length;for(this.clear();++e{var KLe=Rl(),ULe=Ns(),HLe=KLe(ULe,"Map");O7.exports=HLe});var U7=w((kAt,M7)=>{var K7=B7(),jLe=gC(),GLe=XB();function YLe(){this.size=0,this.__data__={hash:new K7,map:new(GLe||jLe),string:new K7}}M7.exports=YLe});var j7=w((PAt,H7)=>{function qLe(r){var e=typeof r;return e=="string"||e=="number"||e=="symbol"||e=="boolean"?r!=="__proto__":r===null}H7.exports=qLe});var fC=w((DAt,G7)=>{var JLe=j7();function WLe(r,e){var t=r.__data__;return JLe(e)?t[typeof e=="string"?"string":"hash"]:t.map}G7.exports=WLe});var q7=w((RAt,Y7)=>{var zLe=fC();function _Le(r){var e=zLe(this,r).delete(r);return this.size-=e?1:0,e}Y7.exports=_Le});var W7=w((FAt,J7)=>{var VLe=fC();function XLe(r){return VLe(this,r).get(r)}J7.exports=XLe});var _7=w((NAt,z7)=>{var ZLe=fC();function $Le(r){return ZLe(this,r).has(r)}z7.exports=$Le});var X7=w((LAt,V7)=>{var eTe=fC();function tTe(r,e){var t=eTe(this,r),i=t.size;return t.set(r,e),this.size+=t.size==i?0:1,this}V7.exports=tTe});var ZB=w((TAt,Z7)=>{var rTe=U7(),iTe=q7(),nTe=W7(),sTe=_7(),oTe=X7();function Rf(r){var e=-1,t=r==null?0:r.length;for(this.clear();++e{var eX=ZB(),aTe="Expected a function";function vR(r,e){if(typeof r!="function"||e!=null&&typeof e!="function")throw new TypeError(aTe);var t=function(){var i=arguments,n=e?e.apply(this,i):i[0],s=t.cache;if(s.has(n))return s.get(n);var o=r.apply(this,i);return t.cache=s.set(n,o)||s,o};return t.cache=new(vR.Cache||eX),t}vR.Cache=eX;$7.exports=vR});var iX=w((MAt,rX)=>{var ATe=tX(),lTe=500;function cTe(r){var e=ATe(r,function(i){return t.size===lTe&&t.clear(),i}),t=e.cache;return e}rX.exports=cTe});var sX=w((KAt,nX)=>{var uTe=iX(),gTe=/[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g,fTe=/\\(\\)?/g,hTe=uTe(function(r){var e=[];return r.charCodeAt(0)===46&&e.push(""),r.replace(gTe,function(t,i,n,s){e.push(n?s.replace(fTe,"$1"):i||t)}),e});nX.exports=hTe});var Ff=w((UAt,oX)=>{var pTe=Ks(),dTe=_B(),CTe=sX(),mTe=lf();function ETe(r,e){return pTe(r)?r:dTe(r,e)?[r]:CTe(mTe(r))}oX.exports=ETe});var gu=w((HAt,aX)=>{var ITe=Id(),yTe=1/0;function wTe(r){if(typeof r=="string"||ITe(r))return r;var e=r+"";return e=="0"&&1/r==-yTe?"-0":e}aX.exports=wTe});var hC=w((jAt,AX)=>{var BTe=Ff(),bTe=gu();function QTe(r,e){e=BTe(e,r);for(var t=0,i=e.length;r!=null&&t{var STe=Rl(),vTe=function(){try{var r=STe(Object,"defineProperty");return r({},"",{}),r}catch(e){}}();lX.exports=vTe});var Nf=w((YAt,cX)=>{var uX=xR();function xTe(r,e,t){e=="__proto__"&&uX?uX(r,e,{configurable:!0,enumerable:!0,value:t,writable:!0}):r[e]=t}cX.exports=xTe});var $B=w((qAt,gX)=>{var kTe=Nf(),PTe=Pf(),DTe=Object.prototype,RTe=DTe.hasOwnProperty;function FTe(r,e,t){var i=r[e];(!(RTe.call(r,e)&&PTe(i,t))||t===void 0&&!(e in r))&&kTe(r,e,t)}gX.exports=FTe});var pC=w((JAt,fX)=>{var NTe=9007199254740991,LTe=/^(?:0|[1-9]\d*)$/;function TTe(r,e){var t=typeof r;return e=e==null?NTe:e,!!e&&(t=="number"||t!="symbol"&<e.test(r))&&r>-1&&r%1==0&&r{var OTe=$B(),MTe=Ff(),KTe=pC(),pX=Rn(),UTe=gu();function HTe(r,e,t,i){if(!pX(r))return r;e=MTe(e,r);for(var n=-1,s=e.length,o=s-1,a=r;a!=null&&++n{var jTe=hC(),GTe=kR(),YTe=Ff();function qTe(r,e,t){for(var i=-1,n=e.length,s={};++i{function JTe(r,e){return r!=null&&e in Object(r)}mX.exports=JTe});var yX=w((VAt,IX)=>{var WTe=Wc(),zTe=ta(),_Te="[object Arguments]";function VTe(r){return zTe(r)&&WTe(r)==_Te}IX.exports=VTe});var dC=w((XAt,wX)=>{var BX=yX(),XTe=ta(),bX=Object.prototype,ZTe=bX.hasOwnProperty,$Te=bX.propertyIsEnumerable,eOe=BX(function(){return arguments}())?BX:function(r){return XTe(r)&&ZTe.call(r,"callee")&&!$Te.call(r,"callee")};wX.exports=eOe});var e0=w((ZAt,QX)=>{var tOe=9007199254740991;function rOe(r){return typeof r=="number"&&r>-1&&r%1==0&&r<=tOe}QX.exports=rOe});var PR=w(($At,SX)=>{var iOe=Ff(),nOe=dC(),sOe=Ks(),oOe=pC(),aOe=e0(),AOe=gu();function lOe(r,e,t){e=iOe(e,r);for(var i=-1,n=e.length,s=!1;++i{var cOe=EX(),uOe=PR();function gOe(r,e){return r!=null&&uOe(r,e,cOe)}vX.exports=gOe});var kX=w((tlt,xX)=>{var fOe=CX(),hOe=DR();function pOe(r,e){return fOe(r,e,function(t,i){return hOe(r,i)})}xX.exports=pOe});var t0=w((rlt,PX)=>{function dOe(r,e){for(var t=-1,i=e.length,n=r.length;++t{var RX=Jc(),COe=dC(),mOe=Ks(),FX=RX?RX.isConcatSpreadable:void 0;function EOe(r){return mOe(r)||COe(r)||!!(FX&&r&&r[FX])}DX.exports=EOe});var OX=w((nlt,LX)=>{var IOe=t0(),yOe=NX();function TX(r,e,t,i,n){var s=-1,o=r.length;for(t||(t=yOe),n||(n=[]);++s0&&t(a)?e>1?TX(a,e-1,t,i,n):IOe(n,a):i||(n[n.length]=a)}return n}LX.exports=TX});var KX=w((slt,MX)=>{var wOe=OX();function BOe(r){var e=r==null?0:r.length;return e?wOe(r,1):[]}MX.exports=BOe});var HX=w((olt,UX)=>{function bOe(r,e,t){switch(t.length){case 0:return r.call(e);case 1:return r.call(e,t[0]);case 2:return r.call(e,t[0],t[1]);case 3:return r.call(e,t[0],t[1],t[2])}return r.apply(e,t)}UX.exports=bOe});var RR=w((alt,jX)=>{var QOe=HX(),GX=Math.max;function SOe(r,e,t){return e=GX(e===void 0?r.length-1:e,0),function(){for(var i=arguments,n=-1,s=GX(i.length-e,0),o=Array(s);++n{function vOe(r){return function(){return r}}YX.exports=vOe});var r0=w((llt,JX)=>{function xOe(r){return r}JX.exports=xOe});var _X=w((clt,WX)=>{var kOe=qX(),zX=xR(),POe=r0(),DOe=zX?function(r,e){return zX(r,"toString",{configurable:!0,enumerable:!1,value:kOe(e),writable:!0})}:POe;WX.exports=DOe});var XX=w((ult,VX)=>{var ROe=800,FOe=16,NOe=Date.now;function LOe(r){var e=0,t=0;return function(){var i=NOe(),n=FOe-(i-t);if(t=i,n>0){if(++e>=ROe)return arguments[0]}else e=0;return r.apply(void 0,arguments)}}VX.exports=LOe});var FR=w((glt,ZX)=>{var TOe=_X(),OOe=XX(),MOe=OOe(TOe);ZX.exports=MOe});var eZ=w((flt,$X)=>{var KOe=KX(),UOe=RR(),HOe=FR();function jOe(r){return HOe(UOe(r,void 0,KOe),r+"")}$X.exports=jOe});var rZ=w((hlt,tZ)=>{var GOe=kX(),YOe=eZ(),qOe=YOe(function(r,e){return r==null?{}:GOe(r,e)});tZ.exports=qOe});var hZ=w((uut,uZ)=>{"use strict";var GR;try{GR=Map}catch(r){}var YR;try{YR=Set}catch(r){}function gZ(r,e,t){if(!r||typeof r!="object"||typeof r=="function")return r;if(r.nodeType&&"cloneNode"in r)return r.cloneNode(!0);if(r instanceof Date)return new Date(r.getTime());if(r instanceof RegExp)return new RegExp(r);if(Array.isArray(r))return r.map(fZ);if(GR&&r instanceof GR)return new Map(Array.from(r.entries()));if(YR&&r instanceof YR)return new Set(Array.from(r.values()));if(r instanceof Object){e.push(r);var i=Object.create(r);t.push(i);for(var n in r){var s=e.findIndex(function(o){return o===r[n]});i[n]=s>-1?t[s]:gZ(r[n],e,t)}return i}return r}function fZ(r){return gZ(r,[],[])}uZ.exports=fZ});var IC=w(qR=>{"use strict";Object.defineProperty(qR,"__esModule",{value:!0});qR.default=eMe;var tMe=Object.prototype.toString,rMe=Error.prototype.toString,iMe=RegExp.prototype.toString,nMe=typeof Symbol!="undefined"?Symbol.prototype.toString:()=>"",sMe=/^Symbol\((.*)\)(.*)$/;function oMe(r){return r!=+r?"NaN":r===0&&1/r<0?"-0":""+r}function pZ(r,e=!1){if(r==null||r===!0||r===!1)return""+r;let t=typeof r;if(t==="number")return oMe(r);if(t==="string")return e?`"${r}"`:r;if(t==="function")return"[Function "+(r.name||"anonymous")+"]";if(t==="symbol")return nMe.call(r).replace(sMe,"Symbol($1)");let i=tMe.call(r).slice(8,-1);return i==="Date"?isNaN(r.getTime())?""+r:r.toISOString(r):i==="Error"||r instanceof Error?"["+rMe.call(r)+"]":i==="RegExp"?iMe.call(r):null}function eMe(r,e){let t=pZ(r,e);return t!==null?t:JSON.stringify(r,function(i,n){let s=pZ(this[i],e);return s!==null?s:n},2)}});var CA=w(bi=>{"use strict";Object.defineProperty(bi,"__esModule",{value:!0});bi.default=bi.array=bi.object=bi.boolean=bi.date=bi.number=bi.string=bi.mixed=void 0;var dZ=aMe(IC());function aMe(r){return r&&r.__esModule?r:{default:r}}var CZ={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:r,type:e,value:t,originalValue:i})=>{let n=i!=null&&i!==t,s=`${r} must be a \`${e}\` type, but the final value was: \`${(0,dZ.default)(t,!0)}\``+(n?` (cast from the value \`${(0,dZ.default)(i,!0)}\`).`:".");return t===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"};bi.mixed=CZ;var mZ={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"};bi.string=mZ;var EZ={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"};bi.number=EZ;var IZ={min:"${path} field must be later than ${min}",max:"${path} field must be at earlier than ${max}"};bi.date=IZ;var yZ={isValue:"${path} field must be ${value}"};bi.boolean=yZ;var wZ={noUnknown:"${path} field has unspecified keys: ${unknown}"};bi.object=wZ;var BZ={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"};bi.array=BZ;var AMe=Object.assign(Object.create(null),{mixed:CZ,string:mZ,number:EZ,date:IZ,object:wZ,array:BZ,boolean:yZ});bi.default=AMe});var QZ=w((hut,bZ)=>{var lMe=Object.prototype,cMe=lMe.hasOwnProperty;function uMe(r,e){return r!=null&&cMe.call(r,e)}bZ.exports=uMe});var yC=w((put,SZ)=>{var gMe=QZ(),fMe=PR();function hMe(r,e){return r!=null&&fMe(r,e,gMe)}SZ.exports=hMe});var Tf=w(o0=>{"use strict";Object.defineProperty(o0,"__esModule",{value:!0});o0.default=void 0;var pMe=r=>r&&r.__isYupSchema__;o0.default=pMe});var kZ=w(a0=>{"use strict";Object.defineProperty(a0,"__esModule",{value:!0});a0.default=void 0;var dMe=vZ(yC()),CMe=vZ(Tf());function vZ(r){return r&&r.__esModule?r:{default:r}}var xZ=class{constructor(e,t){if(this.refs=e,this.refs=e,typeof t=="function"){this.fn=t;return}if(!(0,dMe.default)(t,"is"))throw new TypeError("`is:` is required for `when()` conditions");if(!t.then&&!t.otherwise)throw new TypeError("either `then:` or `otherwise:` is required for `when()` conditions");let{is:i,then:n,otherwise:s}=t,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,t){let i=this.refs.map(s=>s.getValue(t==null?void 0:t.value,t==null?void 0:t.parent,t==null?void 0:t.context)),n=this.fn.apply(e,i.concat(e,t));if(n===void 0||n===e)return e;if(!(0,CMe.default)(n))throw new TypeError("conditions must return a schema object");return n.resolve(t)}},mMe=xZ;a0.default=mMe});var WR=w(JR=>{"use strict";Object.defineProperty(JR,"__esModule",{value:!0});JR.default=EMe;function EMe(r){return r==null?[]:[].concat(r)}});var fu=w(A0=>{"use strict";Object.defineProperty(A0,"__esModule",{value:!0});A0.default=void 0;var IMe=PZ(IC()),yMe=PZ(WR());function PZ(r){return r&&r.__esModule?r:{default:r}}function zR(){return zR=Object.assign||function(r){for(var e=1;e(0,IMe.default)(t[s])):typeof e=="function"?e(t):e}static isError(e){return e&&e.name==="ValidationError"}constructor(e,t,i,n){super();this.name="ValidationError",this.value=t,this.path=i,this.type=n,this.errors=[],this.inner=[],(0,yMe.default)(e).forEach(s=>{wC.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,wC)}};A0.default=wC});var l0=w(_R=>{"use strict";Object.defineProperty(_R,"__esModule",{value:!0});_R.default=BMe;var VR=bMe(fu());function bMe(r){return r&&r.__esModule?r:{default:r}}var QMe=r=>{let e=!1;return(...t)=>{e||(e=!0,r(...t))}};function BMe(r,e){let{endEarly:t,tests:i,args:n,value:s,errors:o,sort:a,path:l}=r,c=QMe(e),u=i.length,g=[];if(o=o||[],!u)return o.length?c(new VR.default(o,s,l)):c(null,s);for(let f=0;f{function SMe(r){return function(e,t,i){for(var n=-1,s=Object(e),o=i(e),a=o.length;a--;){var l=o[r?a:++n];if(t(s[l],l,s)===!1)break}return e}}DZ.exports=SMe});var XR=w((wut,FZ)=>{var vMe=RZ(),xMe=vMe();FZ.exports=xMe});var LZ=w((But,NZ)=>{function kMe(r,e){for(var t=-1,i=Array(r);++t{function PMe(){return!1}TZ.exports=PMe});var bC=w((BC,Of)=>{var DMe=Ns(),RMe=OZ(),MZ=typeof BC=="object"&&BC&&!BC.nodeType&&BC,KZ=MZ&&typeof Of=="object"&&Of&&!Of.nodeType&&Of,FMe=KZ&&KZ.exports===MZ,UZ=FMe?DMe.Buffer:void 0,NMe=UZ?UZ.isBuffer:void 0,LMe=NMe||RMe;Of.exports=LMe});var jZ=w((Qut,HZ)=>{var TMe=Wc(),OMe=e0(),MMe=ta(),KMe="[object Arguments]",UMe="[object Array]",HMe="[object Boolean]",jMe="[object Date]",GMe="[object Error]",YMe="[object Function]",qMe="[object Map]",JMe="[object Number]",WMe="[object Object]",zMe="[object RegExp]",_Me="[object Set]",VMe="[object String]",XMe="[object WeakMap]",ZMe="[object ArrayBuffer]",$Me="[object DataView]",e1e="[object Float32Array]",t1e="[object Float64Array]",r1e="[object Int8Array]",i1e="[object Int16Array]",n1e="[object Int32Array]",s1e="[object Uint8Array]",o1e="[object Uint8ClampedArray]",a1e="[object Uint16Array]",A1e="[object Uint32Array]",wr={};wr[e1e]=wr[t1e]=wr[r1e]=wr[i1e]=wr[n1e]=wr[s1e]=wr[o1e]=wr[a1e]=wr[A1e]=!0;wr[KMe]=wr[UMe]=wr[ZMe]=wr[HMe]=wr[$Me]=wr[jMe]=wr[GMe]=wr[YMe]=wr[qMe]=wr[JMe]=wr[WMe]=wr[zMe]=wr[_Me]=wr[VMe]=wr[XMe]=!1;function l1e(r){return MMe(r)&&OMe(r.length)&&!!wr[TMe(r)]}HZ.exports=l1e});var c0=w((Sut,GZ)=>{function c1e(r){return function(e){return r(e)}}GZ.exports=c1e});var u0=w((QC,Mf)=>{var u1e=rk(),YZ=typeof QC=="object"&&QC&&!QC.nodeType&&QC,SC=YZ&&typeof Mf=="object"&&Mf&&!Mf.nodeType&&Mf,g1e=SC&&SC.exports===YZ,ZR=g1e&&u1e.process,f1e=function(){try{var r=SC&&SC.require&&SC.require("util").types;return r||ZR&&ZR.binding&&ZR.binding("util")}catch(e){}}();Mf.exports=f1e});var g0=w((vut,qZ)=>{var h1e=jZ(),p1e=c0(),JZ=u0(),WZ=JZ&&JZ.isTypedArray,d1e=WZ?p1e(WZ):h1e;qZ.exports=d1e});var $R=w((xut,zZ)=>{var C1e=LZ(),m1e=dC(),E1e=Ks(),I1e=bC(),y1e=pC(),w1e=g0(),B1e=Object.prototype,b1e=B1e.hasOwnProperty;function Q1e(r,e){var t=E1e(r),i=!t&&m1e(r),n=!t&&!i&&I1e(r),s=!t&&!i&&!n&&w1e(r),o=t||i||n||s,a=o?C1e(r.length,String):[],l=a.length;for(var c in r)(e||b1e.call(r,c))&&!(o&&(c=="length"||n&&(c=="offset"||c=="parent")||s&&(c=="buffer"||c=="byteLength"||c=="byteOffset")||y1e(c,l)))&&a.push(c);return a}zZ.exports=Q1e});var f0=w((kut,_Z)=>{var S1e=Object.prototype;function v1e(r){var e=r&&r.constructor,t=typeof e=="function"&&e.prototype||S1e;return r===t}_Z.exports=v1e});var eF=w((Put,VZ)=>{function x1e(r,e){return function(t){return r(e(t))}}VZ.exports=x1e});var ZZ=w((Dut,XZ)=>{var k1e=eF(),P1e=k1e(Object.keys,Object);XZ.exports=P1e});var e$=w((Rut,$Z)=>{var D1e=f0(),R1e=ZZ(),F1e=Object.prototype,N1e=F1e.hasOwnProperty;function L1e(r){if(!D1e(r))return R1e(r);var e=[];for(var t in Object(r))N1e.call(r,t)&&t!="constructor"&&e.push(t);return e}$Z.exports=L1e});var vC=w((Fut,t$)=>{var T1e=VB(),O1e=e0();function M1e(r){return r!=null&&O1e(r.length)&&!T1e(r)}t$.exports=M1e});var Kf=w((Nut,r$)=>{var K1e=$R(),U1e=e$(),H1e=vC();function j1e(r){return H1e(r)?K1e(r):U1e(r)}r$.exports=j1e});var tF=w((Lut,i$)=>{var G1e=XR(),Y1e=Kf();function q1e(r,e){return r&&G1e(r,e,Y1e)}i$.exports=q1e});var s$=w((Tut,n$)=>{var J1e=gC();function W1e(){this.__data__=new J1e,this.size=0}n$.exports=W1e});var a$=w((Out,o$)=>{function z1e(r){var e=this.__data__,t=e.delete(r);return this.size=e.size,t}o$.exports=z1e});var l$=w((Mut,A$)=>{function _1e(r){return this.__data__.get(r)}A$.exports=_1e});var u$=w((Kut,c$)=>{function V1e(r){return this.__data__.has(r)}c$.exports=V1e});var f$=w((Uut,g$)=>{var X1e=gC(),Z1e=XB(),$1e=ZB(),eKe=200;function tKe(r,e){var t=this.__data__;if(t instanceof X1e){var i=t.__data__;if(!Z1e||i.length{var rKe=gC(),iKe=s$(),nKe=a$(),sKe=l$(),oKe=u$(),aKe=f$();function Uf(r){var e=this.__data__=new rKe(r);this.size=e.size}Uf.prototype.clear=iKe;Uf.prototype.delete=nKe;Uf.prototype.get=sKe;Uf.prototype.has=oKe;Uf.prototype.set=aKe;h$.exports=Uf});var d$=w((jut,p$)=>{var AKe="__lodash_hash_undefined__";function lKe(r){return this.__data__.set(r,AKe),this}p$.exports=lKe});var m$=w((Gut,C$)=>{function cKe(r){return this.__data__.has(r)}C$.exports=cKe});var I$=w((Yut,E$)=>{var uKe=ZB(),gKe=d$(),fKe=m$();function h0(r){var e=-1,t=r==null?0:r.length;for(this.__data__=new uKe;++e{function hKe(r,e){for(var t=-1,i=r==null?0:r.length;++t{function pKe(r,e){return r.has(e)}B$.exports=pKe});var rF=w((Wut,Q$)=>{var dKe=I$(),CKe=w$(),mKe=b$(),EKe=1,IKe=2;function yKe(r,e,t,i,n,s){var o=t&EKe,a=r.length,l=e.length;if(a!=l&&!(o&&l>a))return!1;var c=s.get(r),u=s.get(e);if(c&&u)return c==e&&u==r;var g=-1,f=!0,h=t&IKe?new dKe:void 0;for(s.set(r,e),s.set(e,r);++g{var wKe=Ns(),BKe=wKe.Uint8Array;S$.exports=BKe});var x$=w((_ut,v$)=>{function bKe(r){var e=-1,t=Array(r.size);return r.forEach(function(i,n){t[++e]=[n,i]}),t}v$.exports=bKe});var P$=w((Vut,k$)=>{function QKe(r){var e=-1,t=Array(r.size);return r.forEach(function(i){t[++e]=i}),t}k$.exports=QKe});var L$=w((Xut,D$)=>{var R$=Jc(),F$=iF(),SKe=Pf(),vKe=rF(),xKe=x$(),kKe=P$(),PKe=1,DKe=2,RKe="[object Boolean]",FKe="[object Date]",NKe="[object Error]",LKe="[object Map]",TKe="[object Number]",OKe="[object RegExp]",MKe="[object Set]",KKe="[object String]",UKe="[object Symbol]",HKe="[object ArrayBuffer]",jKe="[object DataView]",N$=R$?R$.prototype:void 0,nF=N$?N$.valueOf:void 0;function GKe(r,e,t,i,n,s,o){switch(t){case jKe:if(r.byteLength!=e.byteLength||r.byteOffset!=e.byteOffset)return!1;r=r.buffer,e=e.buffer;case HKe:return!(r.byteLength!=e.byteLength||!s(new F$(r),new F$(e)));case RKe:case FKe:case TKe:return SKe(+r,+e);case NKe:return r.name==e.name&&r.message==e.message;case OKe:case KKe:return r==e+"";case LKe:var a=xKe;case MKe:var l=i&PKe;if(a||(a=kKe),r.size!=e.size&&!l)return!1;var c=o.get(r);if(c)return c==e;i|=DKe,o.set(r,e);var u=vKe(a(r),a(e),i,n,s,o);return o.delete(r),u;case UKe:if(nF)return nF.call(r)==nF.call(e)}return!1}D$.exports=GKe});var sF=w((Zut,T$)=>{var YKe=t0(),qKe=Ks();function JKe(r,e,t){var i=e(r);return qKe(r)?i:YKe(i,t(r))}T$.exports=JKe});var M$=w(($ut,O$)=>{function WKe(r,e){for(var t=-1,i=r==null?0:r.length,n=0,s=[];++t{function zKe(){return[]}K$.exports=zKe});var p0=w((tgt,U$)=>{var _Ke=M$(),VKe=oF(),XKe=Object.prototype,ZKe=XKe.propertyIsEnumerable,H$=Object.getOwnPropertySymbols,$Ke=H$?function(r){return r==null?[]:(r=Object(r),_Ke(H$(r),function(e){return ZKe.call(r,e)}))}:VKe;U$.exports=$Ke});var aF=w((rgt,j$)=>{var eUe=sF(),tUe=p0(),rUe=Kf();function iUe(r){return eUe(r,rUe,tUe)}j$.exports=iUe});var q$=w((igt,G$)=>{var Y$=aF(),nUe=1,sUe=Object.prototype,oUe=sUe.hasOwnProperty;function aUe(r,e,t,i,n,s){var o=t&nUe,a=Y$(r),l=a.length,c=Y$(e),u=c.length;if(l!=u&&!o)return!1;for(var g=l;g--;){var f=a[g];if(!(o?f in e:oUe.call(e,f)))return!1}var h=s.get(r),p=s.get(e);if(h&&p)return h==e&&p==r;var m=!0;s.set(r,e),s.set(e,r);for(var y=o;++g{var AUe=Rl(),lUe=Ns(),cUe=AUe(lUe,"DataView");J$.exports=cUe});var _$=w((sgt,z$)=>{var uUe=Rl(),gUe=Ns(),fUe=uUe(gUe,"Promise");z$.exports=fUe});var X$=w((ogt,V$)=>{var hUe=Rl(),pUe=Ns(),dUe=hUe(pUe,"Set");V$.exports=dUe});var $$=w((agt,Z$)=>{var CUe=Rl(),mUe=Ns(),EUe=CUe(mUe,"WeakMap");Z$.exports=EUe});var kC=w((Agt,eee)=>{var AF=W$(),lF=XB(),cF=_$(),uF=X$(),gF=$$(),tee=Wc(),Hf=SR(),ree="[object Map]",IUe="[object Object]",iee="[object Promise]",nee="[object Set]",see="[object WeakMap]",oee="[object DataView]",yUe=Hf(AF),wUe=Hf(lF),BUe=Hf(cF),bUe=Hf(uF),QUe=Hf(gF),hu=tee;(AF&&hu(new AF(new ArrayBuffer(1)))!=oee||lF&&hu(new lF)!=ree||cF&&hu(cF.resolve())!=iee||uF&&hu(new uF)!=nee||gF&&hu(new gF)!=see)&&(hu=function(r){var e=tee(r),t=e==IUe?r.constructor:void 0,i=t?Hf(t):"";if(i)switch(i){case yUe:return oee;case wUe:return ree;case BUe:return iee;case bUe:return nee;case QUe:return see}return e});eee.exports=hu});var hee=w((lgt,aee)=>{var fF=xC(),SUe=rF(),vUe=L$(),xUe=q$(),Aee=kC(),lee=Ks(),cee=bC(),kUe=g0(),PUe=1,uee="[object Arguments]",gee="[object Array]",d0="[object Object]",DUe=Object.prototype,fee=DUe.hasOwnProperty;function RUe(r,e,t,i,n,s){var o=lee(r),a=lee(e),l=o?gee:Aee(r),c=a?gee:Aee(e);l=l==uee?d0:l,c=c==uee?d0:c;var u=l==d0,g=c==d0,f=l==c;if(f&&cee(r)){if(!cee(e))return!1;o=!0,u=!1}if(f&&!u)return s||(s=new fF),o||kUe(r)?SUe(r,e,t,i,n,s):vUe(r,e,l,t,i,n,s);if(!(t&PUe)){var h=u&&fee.call(r,"__wrapped__"),p=g&&fee.call(e,"__wrapped__");if(h||p){var m=h?r.value():r,y=p?e.value():e;return s||(s=new fF),n(m,y,t,i,s)}}return f?(s||(s=new fF),xUe(r,e,t,i,n,s)):!1}aee.exports=RUe});var hF=w((cgt,pee)=>{var FUe=hee(),dee=ta();function Cee(r,e,t,i,n){return r===e?!0:r==null||e==null||!dee(r)&&!dee(e)?r!==r&&e!==e:FUe(r,e,t,i,Cee,n)}pee.exports=Cee});var Eee=w((ugt,mee)=>{var NUe=xC(),LUe=hF(),TUe=1,OUe=2;function MUe(r,e,t,i){var n=t.length,s=n,o=!i;if(r==null)return!s;for(r=Object(r);n--;){var a=t[n];if(o&&a[2]?a[1]!==r[a[0]]:!(a[0]in r))return!1}for(;++n{var KUe=Rn();function UUe(r){return r===r&&!KUe(r)}Iee.exports=UUe});var wee=w((fgt,yee)=>{var HUe=pF(),jUe=Kf();function GUe(r){for(var e=jUe(r),t=e.length;t--;){var i=e[t],n=r[i];e[t]=[i,n,HUe(n)]}return e}yee.exports=GUe});var dF=w((hgt,Bee)=>{function YUe(r,e){return function(t){return t==null?!1:t[r]===e&&(e!==void 0||r in Object(t))}}Bee.exports=YUe});var Qee=w((pgt,bee)=>{var qUe=Eee(),JUe=wee(),WUe=dF();function zUe(r){var e=JUe(r);return e.length==1&&e[0][2]?WUe(e[0][0],e[0][1]):function(t){return t===r||qUe(t,r,e)}}bee.exports=zUe});var C0=w((dgt,See)=>{var _Ue=hC();function VUe(r,e,t){var i=r==null?void 0:_Ue(r,e);return i===void 0?t:i}See.exports=VUe});var xee=w((Cgt,vee)=>{var XUe=hF(),ZUe=C0(),$Ue=DR(),e2e=_B(),t2e=pF(),r2e=dF(),i2e=gu(),n2e=1,s2e=2;function o2e(r,e){return e2e(r)&&t2e(e)?r2e(i2e(r),e):function(t){var i=ZUe(t,r);return i===void 0&&i===e?$Ue(t,r):XUe(e,i,n2e|s2e)}}vee.exports=o2e});var Pee=w((mgt,kee)=>{function a2e(r){return function(e){return e==null?void 0:e[r]}}kee.exports=a2e});var Ree=w((Egt,Dee)=>{var A2e=hC();function l2e(r){return function(e){return A2e(e,r)}}Dee.exports=l2e});var Nee=w((Igt,Fee)=>{var c2e=Pee(),u2e=Ree(),g2e=_B(),f2e=gu();function h2e(r){return g2e(r)?c2e(f2e(r)):u2e(r)}Fee.exports=h2e});var CF=w((ygt,Lee)=>{var p2e=Qee(),d2e=xee(),C2e=r0(),m2e=Ks(),E2e=Nee();function I2e(r){return typeof r=="function"?r:r==null?C2e:typeof r=="object"?m2e(r)?d2e(r[0],r[1]):p2e(r):E2e(r)}Lee.exports=I2e});var mF=w((wgt,Tee)=>{var y2e=Nf(),w2e=tF(),B2e=CF();function b2e(r,e){var t={};return e=B2e(e,3),w2e(r,function(i,n,s){y2e(t,n,e(i,n,s))}),t}Tee.exports=b2e});var PC=w((Bgt,Oee)=>{"use strict";function pu(r){this._maxSize=r,this.clear()}pu.prototype.clear=function(){this._size=0,this._values=Object.create(null)};pu.prototype.get=function(r){return this._values[r]};pu.prototype.set=function(r,e){return this._size>=this._maxSize&&this.clear(),r in this._values||this._size++,this._values[r]=e};var Q2e=/[^.^\]^[]+|(?=\[\]|\.\.)/g,Mee=/^\d+$/,S2e=/^\d/,v2e=/[~`!#$%\^&*+=\-\[\]\\';,/{}|\\":<>\?]/g,x2e=/^\s*(['"]?)(.*?)(\1)\s*$/,EF=512,Kee=new pu(EF),Uee=new pu(EF),Hee=new pu(EF);Oee.exports={Cache:pu,split:yF,normalizePath:IF,setter:function(r){var e=IF(r);return Uee.get(r)||Uee.set(r,function(i,n){for(var s=0,o=e.length,a=i;s{"use strict";Object.defineProperty(DC,"__esModule",{value:!0});DC.create=F2e;DC.default=void 0;var N2e=PC(),m0={context:"$",value:"."};function F2e(r,e){return new E0(r,e)}var E0=class{constructor(e,t={}){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]===m0.context,this.isValue=this.key[0]===m0.value,this.isSibling=!this.isContext&&!this.isValue;let i=this.isContext?m0.context:this.isValue?m0.value:"";this.path=this.key.slice(i.length),this.getter=this.path&&(0,N2e.getter)(this.path,!0),this.map=t.map}getValue(e,t,i){let n=this.isContext?i:this.isValue?e:t;return this.getter&&(n=this.getter(n||{})),this.map&&(n=this.map(n)),n}cast(e,t){return this.getValue(e,t==null?void 0:t.parent,t==null?void 0:t.context)}resolve(){return this}describe(){return{type:"ref",key:this.key}}toString(){return`Ref(${this.key})`}static isRef(e){return e&&e.__isYupRef}};DC.default=E0;E0.prototype.__isYupRef=!0});var jee=w(BF=>{"use strict";Object.defineProperty(BF,"__esModule",{value:!0});BF.default=L2e;var T2e=bF(mF()),I0=bF(fu()),O2e=bF(du());function bF(r){return r&&r.__esModule?r:{default:r}}function y0(){return y0=Object.assign||function(r){for(var e=1;e=0)&&(t[n]=r[n]);return t}function L2e(r){function e(t,i){let{value:n,path:s="",label:o,options:a,originalValue:l,sync:c}=t,u=M2e(t,["value","path","label","options","originalValue","sync"]),{name:g,test:f,params:h,message:p}=r,{parent:m,context:y}=a;function b(Y){return O2e.default.isRef(Y)?Y.getValue(n,m,y):Y}function v(Y={}){let $=(0,T2e.default)(y0({value:n,originalValue:l,label:o,path:Y.path||s},h,Y.params),b),_=new I0.default(I0.default.formatError(Y.message||p,$),n,$.path,Y.type||g);return _.params=$,_}let x=y0({path:s,parent:m,type:g,createError:v,resolve:b,options:a,originalValue:l},u);if(!c){try{Promise.resolve(f.call(x,n,x)).then(Y=>{I0.default.isError(Y)?i(Y):Y?i(null,Y):i(v())})}catch(Y){i(Y)}return}let T;try{var q;if(T=f.call(x,n,x),typeof((q=T)==null?void 0:q.then)=="function")throw new Error(`Validation test of type: "${x.type}" returned a Promise during a synchronous validate. This test will finish after the validate call has returned`)}catch(Y){i(Y);return}I0.default.isError(T)?i(T):T?i(null,T):i(v())}return e.OPTIONS=r,e}});var QF=w(RC=>{"use strict";Object.defineProperty(RC,"__esModule",{value:!0});RC.getIn=Gee;RC.default=void 0;var K2e=PC(),U2e=r=>r.substr(0,r.length-1).substr(1);function Gee(r,e,t,i=t){let n,s,o;return e?((0,K2e.forEach)(e,(a,l,c)=>{let u=l?U2e(a):a;if(r=r.resolve({context:i,parent:n,value:t}),r.innerType){let g=c?parseInt(u,10):0;if(t&&g>=t.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=t,t=t&&t[g],r=r.innerType}if(!c){if(!r.fields||!r.fields[u])throw new Error(`The schema does not contain the path: ${e}. (failed at: ${o} which is a type: "${r._type}")`);n=t,t=t&&t[u],r=r.fields[u]}s=u,o=l?"["+a+"]":"."+a}),{schema:r,parent:n,parentPath:s}):{parent:n,parentPath:e,schema:r}}var H2e=(r,e,t,i)=>Gee(r,e,t,i).schema,j2e=H2e;RC.default=j2e});var qee=w(w0=>{"use strict";Object.defineProperty(w0,"__esModule",{value:!0});w0.default=void 0;var Yee=G2e(du());function G2e(r){return r&&r.__esModule?r:{default:r}}var B0=class{constructor(){this.list=new Set,this.refs=new Map}get size(){return this.list.size+this.refs.size}describe(){let e=[];for(let t of this.list)e.push(t);for(let[,t]of this.refs)e.push(t.describe());return e}toArray(){return Array.from(this.list).concat(Array.from(this.refs.values()))}add(e){Yee.default.isRef(e)?this.refs.set(e.key,e):this.list.add(e)}delete(e){Yee.default.isRef(e)?this.refs.delete(e.key):this.list.delete(e)}has(e,t){if(this.list.has(e))return!0;let i,n=this.refs.values();for(;i=n.next(),!i.done;)if(t(i.value)===e)return!0;return!1}clone(){let e=new B0;return e.list=new Set(this.list),e.refs=new Map(this.refs),e}merge(e,t){let i=this.clone();return e.list.forEach(n=>i.add(n)),e.refs.forEach(n=>i.add(n)),t.list.forEach(n=>i.delete(n)),t.refs.forEach(n=>i.delete(n)),i}};w0.default=B0});var EA=w(b0=>{"use strict";Object.defineProperty(b0,"__esModule",{value:!0});b0.default=void 0;var Jee=mA(hZ()),jf=CA(),Y2e=mA(kZ()),Wee=mA(l0()),Q0=mA(jee()),zee=mA(IC()),q2e=mA(du()),J2e=QF(),W2e=mA(WR()),_ee=mA(fu()),Vee=mA(qee());function mA(r){return r&&r.__esModule?r:{default:r}}function Js(){return Js=Object.assign||function(r){for(var e=1;e{this.typeError(jf.mixed.notType)}),this.type=(e==null?void 0:e.type)||"mixed",this.spec=Js({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 t=Object.create(Object.getPrototypeOf(this));return t.type=this.type,t._typeError=this._typeError,t._whitelistError=this._whitelistError,t._blacklistError=this._blacklistError,t._whitelist=this._whitelist.clone(),t._blacklist=this._blacklist.clone(),t.exclusiveTests=Js({},this.exclusiveTests),t.deps=[...this.deps],t.conditions=[...this.conditions],t.tests=[...this.tests],t.transforms=[...this.transforms],t.spec=(0,Jee.default)(Js({},this.spec,e)),t}label(e){var t=this.clone();return t.spec.label=e,t}meta(...e){if(e.length===0)return this.spec.meta;let t=this.clone();return t.spec.meta=Object.assign(t.spec.meta||{},e[0]),t}withMutation(e){let t=this._mutate;this._mutate=!0;let i=e(this);return this._mutate=t,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 t=this,i=e.clone(),n=Js({},t.spec,i.spec);return i.spec=n,i._typeError||(i._typeError=t._typeError),i._whitelistError||(i._whitelistError=t._whitelistError),i._blacklistError||(i._blacklistError=t._blacklistError),i._whitelist=t._whitelist.merge(e._whitelist,e._blacklist),i._blacklist=t._blacklist.merge(e._blacklist,e._whitelist),i.tests=t.tests,i.exclusiveTests=t.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 t=this;if(t.conditions.length){let i=t.conditions;t=t.clone(),t.conditions=[],t=i.reduce((n,s)=>s.resolve(n,e),t),t=t.resolve(e)}return t}cast(e,t={}){let i=this.resolve(Js({value:e},t)),n=i._cast(e,t);if(e!==void 0&&t.assert!==!1&&i.isType(n)!==!0){let s=(0,zee.default)(e),o=(0,zee.default)(n);throw new TypeError(`The value of ${t.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,t){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,t={},i){let{sync:n,path:s,from:o=[],originalValue:a=e,strict:l=this.spec.strict,abortEarly:c=this.spec.abortEarly}=t,u=e;l||(u=this._cast(u,Js({assert:!1},t)));let g={value:u,path:s,options:t,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,Wee.default)({args:g,value:u,path:s,sync:n,tests:f,endEarly:c},h=>{if(h)return void i(h,u);(0,Wee.default)({tests:this.tests,args:g,path:s,sync:n,value:u,endEarly:c},i)})}validate(e,t,i){let n=this.resolve(Js({},t,{value:e}));return typeof i=="function"?n._validate(e,t,i):new Promise((s,o)=>n._validate(e,t,(a,l)=>{a?o(a):s(l)}))}validateSync(e,t){let i=this.resolve(Js({},t,{value:e})),n;return i._validate(e,Js({},t,{sync:!0}),(s,o)=>{if(s)throw s;n=o}),n}isValid(e,t){return this.validate(e,t).then(()=>!0,i=>{if(_ee.default.isError(i))return!1;throw i})}isValidSync(e,t){try{return this.validateSync(e,t),!0}catch(i){if(_ee.default.isError(i))return!1;throw i}}_getDefault(){let e=this.spec.default;return e==null?e:typeof e=="function"?e.call(this):(0,Jee.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 t=this.clone();return t.spec.strict=e,t}_isPresent(e){return e!=null}defined(e=jf.mixed.defined){return this.test({message:e,name:"defined",exclusive:!0,test(t){return t!==void 0}})}required(e=jf.mixed.required){return this.clone({presence:"required"}).withMutation(t=>t.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(t=>t.OPTIONS.name!=="required"),e}nullable(e=!0){var t=this.clone({nullable:e!==!1});return t}transform(e){var t=this.clone();return t.transforms.push(e),t}test(...e){let t;if(e.length===1?typeof e[0]=="function"?t={test:e[0]}:t=e[0]:e.length===2?t={name:e[0],test:e[1]}:t={name:e[0],message:e[1],test:e[2]},t.message===void 0&&(t.message=jf.mixed.default),typeof t.test!="function")throw new TypeError("`test` is a required parameters");let i=this.clone(),n=(0,Q0.default)(t),s=t.exclusive||t.name&&i.exclusiveTests[t.name]===!0;if(t.exclusive&&!t.name)throw new TypeError("Exclusive tests must provide a unique `name` identifying the test");return t.name&&(i.exclusiveTests[t.name]=!!t.exclusive),i.tests=i.tests.filter(o=>!(o.OPTIONS.name===t.name&&(s||o.OPTIONS.test===n.OPTIONS.test))),i.tests.push(n),i}when(e,t){!Array.isArray(e)&&typeof e!="string"&&(t=e,e=".");let i=this.clone(),n=(0,W2e.default)(e).map(s=>new q2e.default(s));return n.forEach(s=>{s.isSibling&&i.deps.push(s.key)}),i.conditions.push(new Y2e.default(n,t)),i}typeError(e){var t=this.clone();return t._typeError=(0,Q0.default)({message:e,name:"typeError",test(i){return i!==void 0&&!this.schema.isType(i)?this.createError({params:{type:this.schema._type}}):!0}}),t}oneOf(e,t=jf.mixed.oneOf){var i=this.clone();return e.forEach(n=>{i._whitelist.add(n),i._blacklist.delete(n)}),i._whitelistError=(0,Q0.default)({message:t,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,t=jf.mixed.notOneOf){var i=this.clone();return e.forEach(n=>{i._blacklist.add(n),i._whitelist.delete(n)}),i._blacklistError=(0,Q0.default)({message:t,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 t=this.clone();return t.spec.strip=e,t}describe(){let e=this.clone(),{label:t,meta:i}=e.spec;return{meta:i,label:t,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)}}};b0.default=ua;ua.prototype.__isYupSchema__=!0;for(let r of["validate","validateSync"])ua.prototype[`${r}At`]=function(e,t,i={}){let{parent:n,parentPath:s,schema:o}=(0,J2e.getIn)(this,e,t,i.context);return o[r](n&&n[s],Js({},i,{parent:n,path:e}))};for(let r of["equals","is"])ua.prototype[r]=ua.prototype.oneOf;for(let r of["not","nope"])ua.prototype[r]=ua.prototype.notOneOf;ua.prototype.optional=ua.prototype.notRequired});var Zee=w(FC=>{"use strict";Object.defineProperty(FC,"__esModule",{value:!0});FC.create=Xee;FC.default=void 0;var _2e=z2e(EA());function z2e(r){return r&&r.__esModule?r:{default:r}}var SF=_2e.default,V2e=SF;FC.default=V2e;function Xee(){return new SF}Xee.prototype=SF.prototype});var Gf=w(S0=>{"use strict";Object.defineProperty(S0,"__esModule",{value:!0});S0.default=void 0;var X2e=r=>r==null;S0.default=X2e});var ite=w(NC=>{"use strict";Object.defineProperty(NC,"__esModule",{value:!0});NC.create=$ee;NC.default=void 0;var Z2e=ete(EA()),tte=CA(),rte=ete(Gf());function ete(r){return r&&r.__esModule?r:{default:r}}function $ee(){return new v0}var v0=class extends Z2e.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=tte.boolean.isValue){return this.test({message:e,name:"is-value",exclusive:!0,params:{value:"true"},test(t){return(0,rte.default)(t)||t===!0}})}isFalse(e=tte.boolean.isValue){return this.test({message:e,name:"is-value",exclusive:!0,params:{value:"false"},test(t){return(0,rte.default)(t)||t===!1}})}};NC.default=v0;$ee.prototype=v0.prototype});var ote=w(LC=>{"use strict";Object.defineProperty(LC,"__esModule",{value:!0});LC.create=nte;LC.default=void 0;var ga=CA(),IA=ste(Gf()),$2e=ste(EA());function ste(r){return r&&r.__esModule?r:{default:r}}var eHe=/^((([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,tHe=/^((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,rHe=/^(?:[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,iHe=r=>(0,IA.default)(r)||r===r.trim(),nHe={}.toString();function nte(){return new x0}var x0=class extends $2e.default{constructor(){super({type:"string"});this.withMutation(()=>{this.transform(function(e){if(this.isType(e)||Array.isArray(e))return e;let t=e!=null&&e.toString?e.toString():e;return t===nHe?e:t})})}_typeCheck(e){return e instanceof String&&(e=e.valueOf()),typeof e=="string"}_isPresent(e){return super._isPresent(e)&&!!e.length}length(e,t=ga.string.length){return this.test({message:t,name:"length",exclusive:!0,params:{length:e},test(i){return(0,IA.default)(i)||i.length===this.resolve(e)}})}min(e,t=ga.string.min){return this.test({message:t,name:"min",exclusive:!0,params:{min:e},test(i){return(0,IA.default)(i)||i.length>=this.resolve(e)}})}max(e,t=ga.string.max){return this.test({name:"max",exclusive:!0,message:t,params:{max:e},test(i){return(0,IA.default)(i)||i.length<=this.resolve(e)}})}matches(e,t){let i=!1,n,s;return t&&(typeof t=="object"?{excludeEmptyString:i=!1,message:n,name:s}=t:n=t),this.test({name:s||"matches",message:n||ga.string.matches,params:{regex:e},test:o=>(0,IA.default)(o)||o===""&&i||o.search(e)!==-1})}email(e=ga.string.email){return this.matches(eHe,{name:"email",message:e,excludeEmptyString:!0})}url(e=ga.string.url){return this.matches(tHe,{name:"url",message:e,excludeEmptyString:!0})}uuid(e=ga.string.uuid){return this.matches(rHe,{name:"uuid",message:e,excludeEmptyString:!1})}ensure(){return this.default("").transform(e=>e===null?"":e)}trim(e=ga.string.trim){return this.transform(t=>t!=null?t.trim():t).test({message:e,name:"trim",test:iHe})}lowercase(e=ga.string.lowercase){return this.transform(t=>(0,IA.default)(t)?t:t.toLowerCase()).test({message:e,name:"string_case",exclusive:!0,test:t=>(0,IA.default)(t)||t===t.toLowerCase()})}uppercase(e=ga.string.uppercase){return this.transform(t=>(0,IA.default)(t)?t:t.toUpperCase()).test({message:e,name:"string_case",exclusive:!0,test:t=>(0,IA.default)(t)||t===t.toUpperCase()})}};LC.default=x0;nte.prototype=x0.prototype});var lte=w(TC=>{"use strict";Object.defineProperty(TC,"__esModule",{value:!0});TC.create=ate;TC.default=void 0;var Cu=CA(),mu=Ate(Gf()),sHe=Ate(EA());function Ate(r){return r&&r.__esModule?r:{default:r}}var oHe=r=>r!=+r;function ate(){return new k0}var k0=class extends sHe.default{constructor(){super({type:"number"});this.withMutation(()=>{this.transform(function(e){let t=e;if(typeof t=="string"){if(t=t.replace(/\s/g,""),t==="")return NaN;t=+t}return this.isType(t)?t:parseFloat(t)})})}_typeCheck(e){return e instanceof Number&&(e=e.valueOf()),typeof e=="number"&&!oHe(e)}min(e,t=Cu.number.min){return this.test({message:t,name:"min",exclusive:!0,params:{min:e},test(i){return(0,mu.default)(i)||i>=this.resolve(e)}})}max(e,t=Cu.number.max){return this.test({message:t,name:"max",exclusive:!0,params:{max:e},test(i){return(0,mu.default)(i)||i<=this.resolve(e)}})}lessThan(e,t=Cu.number.lessThan){return this.test({message:t,name:"max",exclusive:!0,params:{less:e},test(i){return(0,mu.default)(i)||ithis.resolve(e)}})}positive(e=Cu.number.positive){return this.moreThan(0,e)}negative(e=Cu.number.negative){return this.lessThan(0,e)}integer(e=Cu.number.integer){return this.test({name:"integer",message:e,test:t=>(0,mu.default)(t)||Number.isInteger(t)})}truncate(){return this.transform(e=>(0,mu.default)(e)?e:e|0)}round(e){var t,i=["ceil","floor","round","trunc"];if(e=((t=e)==null?void 0:t.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,mu.default)(n)?n:Math[e](n))}};TC.default=k0;ate.prototype=k0.prototype});var cte=w(vF=>{"use strict";Object.defineProperty(vF,"__esModule",{value:!0});vF.default=aHe;var AHe=/^(\d{4}|[+\-]\d{6})(?:-?(\d{2})(?:-?(\d{2}))?)?(?:[ T]?(\d{2}):?(\d{2})(?::?(\d{2})(?:[,\.](\d{1,}))?)?(?:(Z)|([+\-])(\d{2})(?::?(\d{2}))?)?)?$/;function aHe(r){var e=[1,4,5,6,7,10,11],t=0,i,n;if(n=AHe.exec(r)){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&&(t=n[10]*60+n[11],n[9]==="+"&&(t=0-t)),i=Date.UTC(n[1],n[2],n[3],n[4],n[5]+t,n[6],n[7]))}else i=Date.parse?Date.parse(r):NaN;return i}});var fte=w(OC=>{"use strict";Object.defineProperty(OC,"__esModule",{value:!0});OC.create=xF;OC.default=void 0;var lHe=P0(cte()),ute=CA(),gte=P0(Gf()),cHe=P0(du()),uHe=P0(EA());function P0(r){return r&&r.__esModule?r:{default:r}}var kF=new Date(""),gHe=r=>Object.prototype.toString.call(r)==="[object Date]";function xF(){return new MC}var MC=class extends uHe.default{constructor(){super({type:"date"});this.withMutation(()=>{this.transform(function(e){return this.isType(e)?e:(e=(0,lHe.default)(e),isNaN(e)?kF:new Date(e))})})}_typeCheck(e){return gHe(e)&&!isNaN(e.getTime())}prepareParam(e,t){let i;if(cHe.default.isRef(e))i=e;else{let n=this.cast(e);if(!this._typeCheck(n))throw new TypeError(`\`${t}\` must be a Date or a value that can be \`cast()\` to a Date`);i=n}return i}min(e,t=ute.date.min){let i=this.prepareParam(e,"min");return this.test({message:t,name:"min",exclusive:!0,params:{min:e},test(n){return(0,gte.default)(n)||n>=this.resolve(i)}})}max(e,t=ute.date.max){var i=this.prepareParam(e,"max");return this.test({message:t,name:"max",exclusive:!0,params:{max:e},test(n){return(0,gte.default)(n)||n<=this.resolve(i)}})}};OC.default=MC;MC.INVALID_DATE=kF;xF.prototype=MC.prototype;xF.INVALID_DATE=kF});var pte=w((Tgt,hte)=>{function fHe(r,e,t,i){var n=-1,s=r==null?0:r.length;for(i&&s&&(t=r[++n]);++n{function hHe(r){return function(e){return r==null?void 0:r[e]}}dte.exports=hHe});var Ete=w((Mgt,mte)=>{var pHe=Cte(),dHe={\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"},CHe=pHe(dHe);mte.exports=CHe});var yte=w((Kgt,Ite)=>{var mHe=Ete(),EHe=lf(),IHe=/[\xc0-\xd6\xd8-\xf6\xf8-\xff\u0100-\u017f]/g,yHe="\\u0300-\\u036f",wHe="\\ufe20-\\ufe2f",BHe="\\u20d0-\\u20ff",bHe=yHe+wHe+BHe,QHe="["+bHe+"]",SHe=RegExp(QHe,"g");function vHe(r){return r=EHe(r),r&&r.replace(IHe,mHe).replace(SHe,"")}Ite.exports=vHe});var Bte=w((Ugt,wte)=>{var xHe=/[^\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f]+/g;function kHe(r){return r.match(xHe)||[]}wte.exports=kHe});var Qte=w((Hgt,bte)=>{var PHe=/[a-z][A-Z]|[A-Z]{2}[a-z]|[0-9][a-zA-Z]|[a-zA-Z][0-9]|[^a-zA-Z0-9 ]/;function DHe(r){return PHe.test(r)}bte.exports=DHe});var Yte=w((jgt,Ste)=>{var vte="\\ud800-\\udfff",RHe="\\u0300-\\u036f",FHe="\\ufe20-\\ufe2f",NHe="\\u20d0-\\u20ff",LHe=RHe+FHe+NHe,xte="\\u2700-\\u27bf",kte="a-z\\xdf-\\xf6\\xf8-\\xff",THe="\\xac\\xb1\\xd7\\xf7",OHe="\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf",MHe="\\u2000-\\u206f",KHe=" \\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",Pte="A-Z\\xc0-\\xd6\\xd8-\\xde",UHe="\\ufe0e\\ufe0f",Dte=THe+OHe+MHe+KHe,Rte="['\u2019]",Fte="["+Dte+"]",HHe="["+LHe+"]",Nte="\\d+",jHe="["+xte+"]",Lte="["+kte+"]",Tte="[^"+vte+Dte+Nte+xte+kte+Pte+"]",GHe="\\ud83c[\\udffb-\\udfff]",YHe="(?:"+HHe+"|"+GHe+")",qHe="[^"+vte+"]",Ote="(?:\\ud83c[\\udde6-\\uddff]){2}",Mte="[\\ud800-\\udbff][\\udc00-\\udfff]",Yf="["+Pte+"]",JHe="\\u200d",Kte="(?:"+Lte+"|"+Tte+")",WHe="(?:"+Yf+"|"+Tte+")",Ute="(?:"+Rte+"(?:d|ll|m|re|s|t|ve))?",Hte="(?:"+Rte+"(?:D|LL|M|RE|S|T|VE))?",jte=YHe+"?",Gte="["+UHe+"]?",zHe="(?:"+JHe+"(?:"+[qHe,Ote,Mte].join("|")+")"+Gte+jte+")*",_He="\\d*(?:1st|2nd|3rd|(?![123])\\dth)(?=\\b|[A-Z_])",VHe="\\d*(?:1ST|2ND|3RD|(?![123])\\dTH)(?=\\b|[a-z_])",XHe=Gte+jte+zHe,ZHe="(?:"+[jHe,Ote,Mte].join("|")+")"+XHe,$He=RegExp([Yf+"?"+Lte+"+"+Ute+"(?="+[Fte,Yf,"$"].join("|")+")",WHe+"+"+Hte+"(?="+[Fte,Yf+Kte,"$"].join("|")+")",Yf+"?"+Kte+"+"+Ute,Yf+"+"+Hte,VHe,_He,Nte,ZHe].join("|"),"g");function eje(r){return r.match($He)||[]}Ste.exports=eje});var Jte=w((Ggt,qte)=>{var tje=Bte(),rje=Qte(),ije=lf(),nje=Yte();function sje(r,e,t){return r=ije(r),e=t?void 0:e,e===void 0?rje(r)?nje(r):tje(r):r.match(e)||[]}qte.exports=sje});var PF=w((Ygt,Wte)=>{var oje=pte(),aje=yte(),Aje=Jte(),lje="['\u2019]",cje=RegExp(lje,"g");function uje(r){return function(e){return oje(Aje(aje(e).replace(cje,"")),r,"")}}Wte.exports=uje});var _te=w((qgt,zte)=>{var gje=PF(),fje=gje(function(r,e,t){return r+(t?"_":"")+e.toLowerCase()});zte.exports=fje});var Xte=w((Jgt,Vte)=>{var hje=Zw(),pje=PF(),dje=pje(function(r,e,t){return e=e.toLowerCase(),r+(t?hje(e):e)});Vte.exports=dje});var $te=w((Wgt,Zte)=>{var Cje=Nf(),mje=tF(),Eje=CF();function Ije(r,e){var t={};return e=Eje(e,3),mje(r,function(i,n,s){Cje(t,e(i,n,s),i)}),t}Zte.exports=Ije});var tre=w((zgt,DF)=>{DF.exports=function(r){return ere(yje(r),r)};DF.exports.array=ere;function ere(r,e){var t=r.length,i=new Array(t),n={},s=t,o=wje(e),a=Bje(r);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(r[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(m){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[--t]=c}}}function yje(r){for(var e=new Set,t=0,i=r.length;t{"use strict";Object.defineProperty(RF,"__esModule",{value:!0});RF.default=bje;var Qje=D0(yC()),Sje=D0(tre()),vje=PC(),xje=D0(du()),kje=D0(Tf());function D0(r){return r&&r.__esModule?r:{default:r}}function bje(r,e=[]){let t=[],i=[];function n(s,o){var a=(0,vje.split)(s)[0];~i.indexOf(a)||i.push(a),~e.indexOf(`${o}-${a}`)||t.push([o,a])}for(let s in r)if((0,Qje.default)(r,s)){let o=r[s];~i.indexOf(s)||i.push(s),xje.default.isRef(o)&&o.isSibling?n(o.path,s):(0,kje.default)(o)&&"deps"in o&&o.deps.forEach(a=>n(a,s))}return Sje.default.array(i,t).reverse()}});var nre=w(FF=>{"use strict";Object.defineProperty(FF,"__esModule",{value:!0});FF.default=Pje;function ire(r,e){let t=Infinity;return r.some((i,n)=>{var s;if(((s=e.path)==null?void 0:s.indexOf(i))!==-1)return t=n,!0}),t}function Pje(r){return(e,t)=>ire(r,e)-ire(r,t)}});var ure=w(KC=>{"use strict";Object.defineProperty(KC,"__esModule",{value:!0});KC.create=sre;KC.default=void 0;var ore=fa(yC()),are=fa(_te()),Dje=fa(Xte()),Rje=fa($te()),Fje=fa(mF()),Nje=PC(),Are=CA(),Lje=fa(rre()),lre=fa(nre()),Tje=fa(l0()),Oje=fa(fu()),NF=fa(EA());function fa(r){return r&&r.__esModule?r:{default:r}}function qf(){return qf=Object.assign||function(r){for(var e=1;eObject.prototype.toString.call(r)==="[object Object]";function Mje(r,e){let t=Object.keys(r.fields);return Object.keys(e).filter(i=>t.indexOf(i)===-1)}var Kje=(0,lre.default)([]),R0=class extends NF.default{constructor(e){super({type:"object"});this.fields=Object.create(null),this._sortErrors=Kje,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 cre(e)||typeof e=="function"}_cast(e,t={}){var i;let n=super._cast(e,t);if(n===void 0)return this.getDefault();if(!this._typeCheck(n))return n;let s=this.fields,o=(i=t.stripUnknown)!=null?i:this.spec.noUnknown,a=this._nodes.concat(Object.keys(n).filter(g=>this._nodes.indexOf(g)===-1)),l={},c=qf({},t,{parent:l,__validating:t.__validating||!1}),u=!1;for(let g of a){let f=s[g],h=(0,ore.default)(n,g);if(f){let p,m=n[g];c.path=(t.path?`${t.path}.`:"")+g,f=f.resolve({value:m,context:t.context,parent:l});let y="spec"in f?f.spec:void 0,b=y==null?void 0:y.strict;if(y==null?void 0:y.strip){u=u||g in n;continue}p=!t.__validating||!b?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,t={},i){let n=[],{sync:s,from:o=[],originalValue:a=e,abortEarly:l=this.spec.abortEarly,recursive:c=this.spec.recursive}=t;o=[{schema:this,value:a},...o],t.__validating=!0,t.originalValue=a,t.from=o,super._validate(e,t,(u,g)=>{if(u){if(!Oje.default.isError(u)||l)return void i(u,g);n.push(u)}if(!c||!cre(g)){i(n[0]||null,g);return}a=a||g;let f=this._nodes.map(h=>(p,m)=>{let y=h.indexOf(".")===-1?(t.path?`${t.path}.`:"")+h:`${t.path||""}["${h}"]`,b=this.fields[h];if(b&&"validate"in b){b.validate(g[h],qf({},t,{path:y,from:o,strict:!0,parent:g,originalValue:a[h]}),m);return}m(null)});(0,Tje.default)({sync:s,tests:f,value:g,errors:n,endEarly:l,sort:this._sortErrors,path:t.path},i)})}clone(e){let t=super.clone(e);return t.fields=qf({},this.fields),t._nodes=this._nodes,t._excludedEdges=this._excludedEdges,t._sortErrors=this._sortErrors,t}concat(e){let t=super.concat(e),i=t.fields;for(let[n,s]of Object.entries(this.fields)){let o=i[n];o===void 0?i[n]=s:o instanceof NF.default&&s instanceof NF.default&&(i[n]=s.concat(o))}return t.withMutation(()=>t.shape(i))}getDefaultFromShape(){let e={};return this._nodes.forEach(t=>{let i=this.fields[t];e[t]="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,t=[]){let i=this.clone(),n=Object.assign(i.fields,e);if(i.fields=n,i._sortErrors=(0,lre.default)(Object.keys(n)),t.length){Array.isArray(t[0])||(t=[t]);let s=t.map(([o,a])=>`${o}-${a}`);i._excludedEdges=i._excludedEdges.concat(s)}return i._nodes=(0,Lje.default)(n,i._excludedEdges),i}pick(e){let t={};for(let i of e)this.fields[i]&&(t[i]=this.fields[i]);return this.clone().withMutation(i=>(i.fields={},i.shape(t)))}omit(e){let t=this.clone(),i=t.fields;t.fields={};for(let n of e)delete i[n];return t.withMutation(()=>t.shape(i))}from(e,t,i){let n=(0,Nje.getter)(e,!0);return this.transform(s=>{if(s==null)return s;let o=s;return(0,ore.default)(s,e)&&(o=qf({},s),i||delete o[e],o[t]=n(s)),o})}noUnknown(e=!0,t=Are.object.noUnknown){typeof e=="string"&&(t=e,e=!0);let i=this.test({name:"noUnknown",exclusive:!0,message:t,test(n){if(n==null)return!0;let s=Mje(this.schema,n);return!e||s.length===0||this.createError({params:{unknown:s.join(", ")}})}});return i.spec.noUnknown=e,i}unknown(e=!0,t=Are.object.noUnknown){return this.noUnknown(!e,t)}transformKeys(e){return this.transform(t=>t&&(0,Rje.default)(t,(i,n)=>e(n)))}camelCase(){return this.transformKeys(Dje.default)}snakeCase(){return this.transformKeys(are.default)}constantCase(){return this.transformKeys(e=>(0,are.default)(e).toUpperCase())}describe(){let e=super.describe();return e.fields=(0,Fje.default)(this.fields,t=>t.describe()),e}};KC.default=R0;function sre(r){return new R0(r)}sre.prototype=R0.prototype});var fre=w(UC=>{"use strict";Object.defineProperty(UC,"__esModule",{value:!0});UC.create=gre;UC.default=void 0;var LF=Jf(Gf()),Uje=Jf(Tf()),Hje=Jf(IC()),TF=CA(),jje=Jf(l0()),Gje=Jf(fu()),Yje=Jf(EA());function Jf(r){return r&&r.__esModule?r:{default:r}}function F0(){return F0=Object.assign||function(r){for(var e=1;e{this.transform(function(t){if(typeof t=="string")try{t=JSON.parse(t)}catch(i){t=null}return this.isType(t)?t:null})})}_typeCheck(e){return Array.isArray(e)}get _subType(){return this.innerType}_cast(e,t){let i=super._cast(e,t);if(!this._typeCheck(i)||!this.innerType)return i;let n=!1,s=i.map((o,a)=>{let l=this.innerType.cast(o,F0({},t,{path:`${t.path||""}[${a}]`}));return l!==o&&(n=!0),l});return n?s:i}_validate(e,t={},i){var n,s;let o=[],a=t.sync,l=t.path,c=this.innerType,u=(n=t.abortEarly)!=null?n:this.spec.abortEarly,g=(s=t.recursive)!=null?s:this.spec.recursive,f=t.originalValue!=null?t.originalValue:e;super._validate(e,t,(h,p)=>{if(h){if(!Gje.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 m=new Array(p.length);for(let y=0;yc.validate(b,x,q)}(0,jje.default)({sync:a,path:l,value:p,errors:o,endEarly:u,tests:m},i)})}clone(e){let t=super.clone(e);return t.innerType=this.innerType,t}concat(e){let t=super.concat(e);return t.innerType=this.innerType,e.innerType&&(t.innerType=t.innerType?t.innerType.concat(e.innerType):e.innerType),t}of(e){let t=this.clone();if(!(0,Uje.default)(e))throw new TypeError("`array.of()` sub-schema must be a valid yup schema not: "+(0,Hje.default)(e));return t.innerType=e,t}length(e,t=TF.array.length){return this.test({message:t,name:"length",exclusive:!0,params:{length:e},test(i){return(0,LF.default)(i)||i.length===this.resolve(e)}})}min(e,t){return t=t||TF.array.min,this.test({message:t,name:"min",exclusive:!0,params:{min:e},test(i){return(0,LF.default)(i)||i.length>=this.resolve(e)}})}max(e,t){return t=t||TF.array.max,this.test({message:t,name:"max",exclusive:!0,params:{max:e},test(i){return(0,LF.default)(i)||i.length<=this.resolve(e)}})}ensure(){return this.default(()=>[]).transform((e,t)=>this._typeCheck(e)?e:t==null?[]:[].concat(t))}compact(e){let t=e?(i,n,s)=>!e(i,n,s):i=>!!i;return this.transform(i=>i!=null?i.filter(t):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)}};UC.default=N0;gre.prototype=N0.prototype});var hre=w(HC=>{"use strict";Object.defineProperty(HC,"__esModule",{value:!0});HC.create=qje;HC.default=void 0;var Wje=Jje(Tf());function Jje(r){return r&&r.__esModule?r:{default:r}}function qje(r){return new OF(r)}var OF=class{constructor(e){this.type="lazy",this.__isYupSchema__=!0,this._resolve=(t,i={})=>{let n=this.builder(t,i);if(!(0,Wje.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,t){return this._resolve(e,t).cast(e,t)}validate(e,t,i){return this._resolve(e,t).validate(e,t,i)}validateSync(e,t){return this._resolve(e,t).validateSync(e,t)}validateAt(e,t,i){return this._resolve(t,i).validateAt(e,t,i)}validateSyncAt(e,t,i){return this._resolve(t,i).validateSyncAt(e,t,i)}describe(){return null}isValid(e,t){return this._resolve(e,t).isValid(e,t)}isValidSync(e,t){return this._resolve(e,t).isValidSync(e,t)}},zje=OF;HC.default=zje});var pre=w(MF=>{"use strict";Object.defineProperty(MF,"__esModule",{value:!0});MF.default=_je;var Xje=Vje(CA());function Vje(r){return r&&r.__esModule?r:{default:r}}function _je(r){Object.keys(r).forEach(e=>{Object.keys(r[e]).forEach(t=>{Xje.default[e][t]=r[e][t]})})}});var UF=w(Br=>{"use strict";Object.defineProperty(Br,"__esModule",{value:!0});Br.addMethod=Zje;Object.defineProperty(Br,"MixedSchema",{enumerable:!0,get:function(){return dre.default}});Object.defineProperty(Br,"mixed",{enumerable:!0,get:function(){return dre.create}});Object.defineProperty(Br,"BooleanSchema",{enumerable:!0,get:function(){return KF.default}});Object.defineProperty(Br,"bool",{enumerable:!0,get:function(){return KF.create}});Object.defineProperty(Br,"boolean",{enumerable:!0,get:function(){return KF.create}});Object.defineProperty(Br,"StringSchema",{enumerable:!0,get:function(){return Cre.default}});Object.defineProperty(Br,"string",{enumerable:!0,get:function(){return Cre.create}});Object.defineProperty(Br,"NumberSchema",{enumerable:!0,get:function(){return mre.default}});Object.defineProperty(Br,"number",{enumerable:!0,get:function(){return mre.create}});Object.defineProperty(Br,"DateSchema",{enumerable:!0,get:function(){return Ere.default}});Object.defineProperty(Br,"date",{enumerable:!0,get:function(){return Ere.create}});Object.defineProperty(Br,"ObjectSchema",{enumerable:!0,get:function(){return Ire.default}});Object.defineProperty(Br,"object",{enumerable:!0,get:function(){return Ire.create}});Object.defineProperty(Br,"ArraySchema",{enumerable:!0,get:function(){return yre.default}});Object.defineProperty(Br,"array",{enumerable:!0,get:function(){return yre.create}});Object.defineProperty(Br,"ref",{enumerable:!0,get:function(){return $je.create}});Object.defineProperty(Br,"lazy",{enumerable:!0,get:function(){return eGe.create}});Object.defineProperty(Br,"ValidationError",{enumerable:!0,get:function(){return tGe.default}});Object.defineProperty(Br,"reach",{enumerable:!0,get:function(){return rGe.default}});Object.defineProperty(Br,"isSchema",{enumerable:!0,get:function(){return wre.default}});Object.defineProperty(Br,"setLocale",{enumerable:!0,get:function(){return iGe.default}});Object.defineProperty(Br,"BaseSchema",{enumerable:!0,get:function(){return nGe.default}});var dre=Eu(Zee()),KF=Eu(ite()),Cre=Eu(ote()),mre=Eu(lte()),Ere=Eu(fte()),Ire=Eu(ure()),yre=Eu(fre()),$je=du(),eGe=hre(),tGe=jC(fu()),rGe=jC(QF()),wre=jC(Tf()),iGe=jC(pre()),nGe=jC(EA());function jC(r){return r&&r.__esModule?r:{default:r}}function Bre(){if(typeof WeakMap!="function")return null;var r=new WeakMap;return Bre=function(){return r},r}function Eu(r){if(r&&r.__esModule)return r;if(r===null||typeof r!="object"&&typeof r!="function")return{default:r};var e=Bre();if(e&&e.has(r))return e.get(r);var t={},i=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var n in r)if(Object.prototype.hasOwnProperty.call(r,n)){var s=i?Object.getOwnPropertyDescriptor(r,n):null;s&&(s.get||s.set)?Object.defineProperty(t,n,s):t[n]=r[n]}return t.default=r,e&&e.set(r,t),t}function Zje(r,e,t){if(!r||!(0,wre.default)(r.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 t!="function")throw new TypeError("Method function must be provided");r.prototype[e]=t}});var xre=w((hft,YC)=>{"use strict";var aGe=process.env.TERM_PROGRAM==="Hyper",AGe=process.platform==="win32",Qre=process.platform==="linux",HF={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"},Sre=Object.assign({},HF,{check:"\u221A",cross:"\xD7",ellipsisLarge:"...",ellipsis:"...",info:"i",question:"?",questionSmall:"?",pointer:">",pointerSmall:"\xBB",radioOff:"( )",radioOn:"(*)",warning:"\u203C"}),vre=Object.assign({},HF,{ballotCross:"\u2718",check:"\u2714",cross:"\u2716",ellipsisLarge:"\u22EF",ellipsis:"\u2026",info:"\u2139",question:"?",questionFull:"\uFF1F",questionSmall:"\uFE56",pointer:Qre?"\u25B8":"\u276F",pointerSmall:Qre?"\u2023":"\u203A",radioOff:"\u25EF",radioOn:"\u25C9",warning:"\u26A0"});YC.exports=AGe&&!aGe?Sre:vre;Reflect.defineProperty(YC.exports,"common",{enumerable:!1,value:HF});Reflect.defineProperty(YC.exports,"windows",{enumerable:!1,value:Sre});Reflect.defineProperty(YC.exports,"other",{enumerable:!1,value:vre})});var Eo=w((pft,jF)=>{"use strict";var lGe=r=>r!==null&&typeof r=="object"&&!Array.isArray(r),cGe=/[\u001b\u009b][[\]#;?()]*(?:(?:(?:[^\W_]*;?[^\W_]*)\u0007)|(?:(?:[0-9]{1,4}(;[0-9]{0,4})*)?[~0-9=<>cf-nqrtyA-PRZ]))/g,kre=()=>{let r={enabled:!0,visible:!0,styles:{},keys:{}};"FORCE_COLOR"in process.env&&(r.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},t=(s,o,a)=>typeof s=="function"?s(o):s.wrap(o,a),i=(s,o)=>{if(s===""||s==null)return"";if(r.enabled===!1)return s;if(r.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=t(r.styles[o[c]],a,l);return a},n=(s,o,a)=>{r.styles[s]=e({name:s,codes:o}),(r.keys[a]||(r.keys[a]=[])).push(s),Reflect.defineProperty(r,s,{configurable:!0,enumerable:!0,set(c){r.alias(s,c)},get(){let c=u=>i(u,c.stack);return Reflect.setPrototypeOf(c,r),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"),r.ansiRegex=cGe,r.hasColor=r.hasAnsi=s=>(r.ansiRegex.lastIndex=0,typeof s=="string"&&s!==""&&r.ansiRegex.test(s)),r.alias=(s,o)=>{let a=typeof o=="string"?r[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}),r.styles[s]=a,a.stack=[s]),Reflect.defineProperty(r,s,{configurable:!0,enumerable:!0,set(l){r.alias(s,l)},get(){let l=c=>i(c,l.stack);return Reflect.setPrototypeOf(l,r),l.stack=this.stack?this.stack.concat(a.stack):a.stack,l}})},r.theme=s=>{if(!lGe(s))throw new TypeError("Expected theme to be an object");for(let o of Object.keys(s))r.alias(o,s[o]);return r},r.alias("unstyle",s=>typeof s=="string"&&s!==""?(r.ansiRegex.lastIndex=0,s.replace(r.ansiRegex,"")):""),r.alias("noop",s=>s),r.none=r.clear=r.noop,r.stripColor=r.unstyle,r.symbols=xre(),r.define=n,r};jF.exports=kre();jF.exports.create=kre});var Xi=w(Lt=>{"use strict";var uGe=Object.prototype.toString,Ws=Eo(),Pre=!1,GF=[],Dre={yellow:"blue",cyan:"red",green:"magenta",black:"white",blue:"yellow",red:"cyan",magenta:"green",white:"black"};Lt.longest=(r,e)=>r.reduce((t,i)=>Math.max(t,e?i[e].length:i.length),0);Lt.hasColor=r=>!!r&&Ws.hasColor(r);var T0=Lt.isObject=r=>r!==null&&typeof r=="object"&&!Array.isArray(r);Lt.nativeType=r=>uGe.call(r).slice(8,-1).toLowerCase().replace(/\s/g,"");Lt.isAsyncFn=r=>Lt.nativeType(r)==="asyncfunction";Lt.isPrimitive=r=>r!=null&&typeof r!="object"&&typeof r!="function";Lt.resolve=(r,e,...t)=>typeof e=="function"?e.call(r,...t):e;Lt.scrollDown=(r=[])=>[...r.slice(1),r[0]];Lt.scrollUp=(r=[])=>[r.pop(),...r];Lt.reorder=(r=[])=>{let e=r.slice();return e.sort((t,i)=>t.index>i.index?1:t.index{let i=r.length,n=t===i?0:t<0?i-1:t,s=r[e];r[e]=r[n],r[n]=s};Lt.width=(r,e=80)=>{let t=r&&r.columns?r.columns:e;return r&&typeof r.getWindowSize=="function"&&(t=r.getWindowSize()[0]),process.platform==="win32"?t-1:t};Lt.height=(r,e=20)=>{let t=r&&r.rows?r.rows:e;return r&&typeof r.getWindowSize=="function"&&(t=r.getWindowSize()[1]),t};Lt.wordWrap=(r,e={})=>{if(!r)return r;typeof e=="number"&&(e={width:e});let{indent:t="",newline:i=` -`+t,width:n=80}=e;n-=((i+t).match(/[^\S\n]/g)||[]).length;let o=`.{1,${n}}([\\s\\u200B]+|$)|[^\\s\\u200B]+?([\\s\\u200B]+|$)`,a=r.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," "))),t+c.join(i)};Lt.unmute=r=>{let e=r.stack.find(i=>Ws.keys.color.includes(i));return e?Ws[e]:r.stack.find(i=>i.slice(2)==="bg")?Ws[e.slice(2)]:i=>i};Lt.pascal=r=>r?r[0].toUpperCase()+r.slice(1):"";Lt.inverse=r=>{if(!r||!r.stack)return r;let e=r.stack.find(i=>Ws.keys.color.includes(i));if(e){let i=Ws["bg"+Lt.pascal(e)];return i?i.black:r}let t=r.stack.find(i=>i.slice(0,2)==="bg");return t?Ws[t.slice(2).toLowerCase()]||r:Ws.none};Lt.complement=r=>{if(!r||!r.stack)return r;let e=r.stack.find(i=>Ws.keys.color.includes(i)),t=r.stack.find(i=>i.slice(0,2)==="bg");if(e&&!t)return Ws[Dre[e]||e];if(t){let i=t.slice(2).toLowerCase(),n=Dre[i];return n&&Ws["bg"+Lt.pascal(n)]||r}return Ws.none};Lt.meridiem=r=>{let e=r.getHours(),t=r.getMinutes(),i=e>=12?"pm":"am";e=e%12;let n=e===0?12:e,s=t<10?"0"+t:t;return n+":"+s+" "+i};Lt.set=(r={},e="",t)=>e.split(".").reduce((i,n,s,o)=>{let a=o.length-1>s?i[n]||{}:t;return!Lt.isObject(a)&&s{let i=r[e]==null?e.split(".").reduce((n,s)=>n&&n[s],r):r[e];return i==null?t:i};Lt.mixin=(r,e)=>{if(!T0(r))return e;if(!T0(e))return r;for(let t of Object.keys(e)){let i=Object.getOwnPropertyDescriptor(e,t);if(i.hasOwnProperty("value"))if(r.hasOwnProperty(t)&&T0(i.value)){let n=Object.getOwnPropertyDescriptor(r,t);T0(n.value)?r[t]=Lt.merge({},r[t],e[t]):Reflect.defineProperty(r,t,i)}else Reflect.defineProperty(r,t,i);else Reflect.defineProperty(r,t,i)}return r};Lt.merge=(...r)=>{let e={};for(let t of r)Lt.mixin(e,t);return e};Lt.mixinEmitter=(r,e)=>{let t=e.constructor.prototype;for(let i of Object.keys(t)){let n=t[i];typeof n=="function"?Lt.define(r,i,n.bind(e)):Lt.define(r,i,n)}};Lt.onExit=r=>{let e=(t,i)=>{Pre||(Pre=!0,GF.forEach(n=>n()),t===!0&&process.exit(128+i))};GF.length===0&&(process.once("SIGTERM",e.bind(null,!0,15)),process.once("SIGINT",e.bind(null,!0,2)),process.once("exit",e)),GF.push(r)};Lt.define=(r,e,t)=>{Reflect.defineProperty(r,e,{value:t})};Lt.defineExport=(r,e,t)=>{let i;Reflect.defineProperty(r,e,{enumerable:!0,configurable:!0,set(n){i=n},get(){return i?i():t()}})}});var Rre=w(zf=>{"use strict";zf.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"};zf.shift={up:"shiftUp",down:"shiftDown",left:"shiftLeft",right:"shiftRight",tab:"prev"};zf.fn={up:"pageUp",down:"pageDown",left:"pageLeft",right:"pageRight",delete:"deleteForward"};zf.option={b:"backward",f:"forward",d:"cutRight",left:"cutLeft",up:"altUp",down:"altDown"};zf.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 Lre=w((mft,Fre)=>{"use strict";var Nre=require("readline"),gGe=Rre(),fGe=/^(?:\x1b)([a-zA-Z0-9])$/,hGe=/^(?:\x1b+)(O|N|\[|\[\[)(?:(\d+)(?:;(\d+))?([~^$])|(?:1;)?(\d+)?([a-zA-Z]))/,pGe={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 dGe(r){return["[a","[b","[c","[d","[e","[2$","[3$","[5$","[6$","[7$","[8$","[Z"].includes(r)}function CGe(r){return["Oa","Ob","Oc","Od","Oe","[2^","[3^","[5^","[6^","[7^","[8^"].includes(r)}var O0=(r="",e={})=>{let t,i=N({name:e.name,ctrl:!1,meta:!1,shift:!1,option:!1,sequence:r,raw:r},e);if(Buffer.isBuffer(r)?r[0]>127&&r[1]===void 0?(r[0]-=128,r=""+String(r)):r=String(r):r!==void 0&&typeof r!="string"?r=String(r):r||(r=i.sequence||""),i.sequence=i.sequence||r||i.name,r==="\r")i.raw=void 0,i.name="return";else if(r===` -`)i.name="enter";else if(r===" ")i.name="tab";else if(r==="\b"||r==="\x7F"||r==="\x7F"||r==="\b")i.name="backspace",i.meta=r.charAt(0)==="";else if(r===""||r==="")i.name="escape",i.meta=r.length===2;else if(r===" "||r===" ")i.name="space",i.meta=r.length===2;else if(r<="")i.name=String.fromCharCode(r.charCodeAt(0)+"a".charCodeAt(0)-1),i.ctrl=!0;else if(r.length===1&&r>="0"&&r<="9")i.name="number";else if(r.length===1&&r>="a"&&r<="z")i.name=r;else if(r.length===1&&r>="A"&&r<="Z")i.name=r.toLowerCase(),i.shift=!0;else if(t=fGe.exec(r))i.meta=!0,i.shift=/^[A-Z]$/.test(t[1]);else if(t=hGe.exec(r)){let n=[...r];n[0]===""&&n[1]===""&&(i.option=!0);let s=[t[1],t[2],t[4],t[6]].filter(Boolean).join(""),o=(t[3]||t[5]||1)-1;i.ctrl=!!(o&4),i.meta=!!(o&10),i.shift=!!(o&1),i.code=s,i.name=pGe[s],i.shift=dGe(s)||i.shift,i.ctrl=CGe(s)||i.ctrl}return i};O0.listen=(r={},e)=>{let{stdin:t}=r;if(!t||t!==process.stdin&&!t.isTTY)throw new Error("Invalid stream passed");let i=Nre.createInterface({terminal:!0,input:t});Nre.emitKeypressEvents(t,i);let n=(a,l)=>e(a,O0(a,l),i),s=t.isRaw;return t.isTTY&&t.setRawMode(!0),t.on("keypress",n),i.resume(),()=>{t.isTTY&&t.setRawMode(s),t.removeListener("keypress",n),i.pause(),i.close()}};O0.action=(r,e,t)=>{let i=N(N({},gGe),t);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)};Fre.exports=O0});var Ore=w((Eft,Tre)=>{"use strict";Tre.exports=r=>{r.timers=r.timers||{};let e=r.options.timers;if(!!e)for(let t of Object.keys(e)){let i=e[t];typeof i=="number"&&(i={interval:i}),mGe(r,t,i)}};function mGe(r,e,t={}){let i=r.timers[e]={name:e,start:Date.now(),ms:0,tick:0},n=t.interval||120;i.frames=t.frames||[],i.loading=!0;let s=setInterval(()=>{i.ms=Date.now()-i.start,i.tick++,r.render()},n);return i.stop=()=>{i.loading=!1,clearInterval(s)},Reflect.defineProperty(i,"interval",{value:s}),r.once("close",()=>i.stop()),i.stop}});var Ure=w((Ift,Mre)=>{"use strict";var{define:EGe,width:IGe}=Xi(),Kre=class{constructor(e){let t=e.options;EGe(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=IGe(t.stdout||process.stdout),Object.assign(this,t),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=N({},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 t=this._color||e[this.status];return typeof t=="function"?t: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"}};Mre.exports=Kre});var jre=w((yft,Hre)=>{"use strict";var YF=Xi(),Ni=Eo(),qF={default:Ni.noop,noop:Ni.noop,set inverse(r){this._inverse=r},get inverse(){return this._inverse||YF.inverse(this.primary)},set complement(r){this._complement=r},get complement(){return this._complement||YF.complement(this.primary)},primary:Ni.cyan,success:Ni.green,danger:Ni.magenta,strong:Ni.bold,warning:Ni.yellow,muted:Ni.dim,disabled:Ni.gray,dark:Ni.dim.gray,underline:Ni.underline,set info(r){this._info=r},get info(){return this._info||this.primary},set em(r){this._em=r},get em(){return this._em||this.primary.underline},set heading(r){this._heading=r},get heading(){return this._heading||this.muted.underline},set pending(r){this._pending=r},get pending(){return this._pending||this.primary},set submitted(r){this._submitted=r},get submitted(){return this._submitted||this.success},set cancelled(r){this._cancelled=r},get cancelled(){return this._cancelled||this.danger},set typing(r){this._typing=r},get typing(){return this._typing||this.dim},set placeholder(r){this._placeholder=r},get placeholder(){return this._placeholder||this.primary.dim},set highlight(r){this._highlight=r},get highlight(){return this._highlight||this.inverse}};qF.merge=(r={})=>{r.styles&&typeof r.styles.enabled=="boolean"&&(Ni.enabled=r.styles.enabled),r.styles&&typeof r.styles.visible=="boolean"&&(Ni.visible=r.styles.visible);let e=YF.merge({},qF,r.styles);delete e.merge;for(let t of Object.keys(Ni))e.hasOwnProperty(t)||Reflect.defineProperty(e,t,{get:()=>Ni[t]});for(let t of Object.keys(Ni.styles))e.hasOwnProperty(t)||Reflect.defineProperty(e,t,{get:()=>Ni[t]});return e};Hre.exports=qF});var Yre=w((wft,Gre)=>{"use strict";var JF=process.platform==="win32",yA=Eo(),yGe=Xi(),WF=te(N({},yA.symbols),{upDownDoubleArrow:"\u21D5",upDownDoubleArrow2:"\u2B0D",upDownArrow:"\u2195",asterisk:"*",asterism:"\u2042",bulletWhite:"\u25E6",electricArrow:"\u2301",ellipsisLarge:"\u22EF",ellipsisSmall:"\u2026",fullBlock:"\u2588",identicalTo:"\u2261",indicator:yA.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:yA.symbols.question,submitted:yA.symbols.check,cancelled:yA.symbols.cross},separator:{pending:yA.symbols.pointerSmall,submitted:yA.symbols.middot,cancelled:yA.symbols.middot},radio:{off:JF?"( )":"\u25EF",on:JF?"(*)":"\u25C9",disabled:JF?"(|)":"\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"]});WF.merge=r=>{let e=yGe.merge({},yA.symbols,WF,r.symbols);return delete e.merge,e};Gre.exports=WF});var Jre=w((Bft,qre)=>{"use strict";var wGe=jre(),BGe=Yre(),bGe=Xi();qre.exports=r=>{r.options=bGe.merge({},r.options.theme,r.options),r.symbols=BGe.merge(r.options),r.styles=wGe.merge(r.options)}});var Xre=w((Wre,zre)=>{"use strict";var _re=process.env.TERM_PROGRAM==="Apple_Terminal",QGe=Eo(),zF=Xi(),Io=zre.exports=Wre,Lr="[",Vre="\x07",_F=!1,Fl=Io.code={bell:Vre,beep:Vre,beginning:`${Lr}G`,down:`${Lr}J`,esc:Lr,getPosition:`${Lr}6n`,hide:`${Lr}?25l`,line:`${Lr}2K`,lineEnd:`${Lr}K`,lineStart:`${Lr}1K`,restorePosition:Lr+(_re?"8":"u"),savePosition:Lr+(_re?"7":"s"),screen:`${Lr}2J`,show:`${Lr}?25h`,up:`${Lr}1J`},Iu=Io.cursor={get hidden(){return _F},hide(){return _F=!0,Fl.hide},show(){return _F=!1,Fl.show},forward:(r=1)=>`${Lr}${r}C`,backward:(r=1)=>`${Lr}${r}D`,nextLine:(r=1)=>`${Lr}E`.repeat(r),prevLine:(r=1)=>`${Lr}F`.repeat(r),up:(r=1)=>r?`${Lr}${r}A`:"",down:(r=1)=>r?`${Lr}${r}B`:"",right:(r=1)=>r?`${Lr}${r}C`:"",left:(r=1)=>r?`${Lr}${r}D`:"",to(r,e){return e?`${Lr}${e+1};${r+1}H`:`${Lr}${r+1}G`},move(r=0,e=0){let t="";return t+=r<0?Iu.left(-r):r>0?Iu.right(r):"",t+=e<0?Iu.up(-e):e>0?Iu.down(e):"",t},restore(r={}){let{after:e,cursor:t,initial:i,input:n,prompt:s,size:o,value:a}=r;if(i=zF.isPrimitive(i)?String(i):"",n=zF.isPrimitive(n)?String(n):"",a=zF.isPrimitive(a)?String(a):"",o){let l=Io.cursor.up(o)+Io.cursor.to(s.length),c=n.length-t;return c>0&&(l+=Io.cursor.left(c)),l}if(a||e){let l=!n&&!!i?-i.length:-n.length+t;return e&&(l-=e.length),n===""&&i&&!s.includes(i)&&(l+=i.length),Io.cursor.move(l)}}},VF=Io.erase={screen:Fl.screen,up:Fl.up,down:Fl.down,line:Fl.line,lineEnd:Fl.lineEnd,lineStart:Fl.lineStart,lines(r){let e="";for(let t=0;t{if(!e)return VF.line+Iu.to(0);let t=s=>[...QGe.unstyle(s)].length,i=r.split(/\r?\n/),n=0;for(let s of i)n+=1+Math.floor(Math.max(t(s)-1,0)/e);return(VF.line+Iu.prevLine()).repeat(n-1)+VF.line+Iu.to(0)}});var _f=w((bft,Zre)=>{"use strict";var SGe=require("events"),$re=Eo(),XF=Lre(),vGe=Ore(),xGe=Ure(),kGe=Jre(),Tn=Xi(),yu=Xre(),M0=class extends SGe{constructor(e={}){super();this.name=e.name,this.type=e.type,this.options=e,kGe(this),vGe(this),this.state=new xGe(this),this.initial=[e.initial,e.default].find(t=>t!=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=DGe(this.options.margin),this.setMaxListeners(0),PGe(this)}async keypress(e,t={}){this.keypressed=!0;let i=XF.action(e,XF(e,t),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(yu.code.beep)}cursorHide(){this.stdout.write(yu.cursor.hide()),Tn.onExit(()=>this.cursorShow())}cursorShow(){this.stdout.write(yu.cursor.show())}write(e){!e||(this.stdout&&this.state.show!==!1&&this.stdout.write(e),this.state.buffer+=e)}clear(e=0){let t=this.state.buffer;this.state.buffer="",!(!t&&!e||this.options.show===!1)&&this.stdout.write(yu.cursor.down(e)+yu.clear(t,this.width))}restore(){if(this.state.closed||this.options.show===!1)return;let{prompt:e,after:t,rest:i}=this.sections(),{cursor:n,initial:s="",input:o="",value:a=""}=this,l=this.state.size=i.length,c={after:t,cursor:n,initial:s,input:o,prompt:e,size:l,value:a},u=yu.cursor.restore(c);u&&this.stdout.write(u)}sections(){let{buffer:e,input:t,prompt:i}=this.state;i=$re.unstyle(i);let n=$re.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+(t?" "+t:"")).length,h=fe.call(this,this.value),this.result=()=>i.call(this,this.value),typeof t.initial=="function"&&(this.initial=await t.initial.call(this,this)),typeof t.onRun=="function"&&await t.onRun.call(this,this),typeof t.onSubmit=="function"){let n=t.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,t)=>{if(this.once("submit",e),this.once("cancel",t),await this.skip())return this.render=()=>{},this.submit();await this.initialize(),this.emit("run")})}async element(e,t,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=t&&t[e]!=null?t[e]:await c;if(u==="")return u;let g=await this.resolve(u,s,t,i);return!g&&t&&t[e]?this.resolve(c,s,t,i):g}async prefix(){let e=await this.element("prefix")||this.symbols,t=this.timers&&this.timers.prefix,i=this.state;return i.timer=t,Tn.isObject(e)&&(e=e[i.status]||e.pending),Tn.hasColor(e)?e:(this.styles[i.status]||this.styles.pending)(e)}async message(){let e=await this.element("message");return Tn.hasColor(e)?e:this.styles.strong(e)}async separator(){let e=await this.element("separator")||this.symbols,t=this.timers&&this.timers.separator,i=this.state;i.timer=t;let n=e[i.status]||e.pending||i.separator,s=await this.resolve(n,i);return Tn.isObject(s)&&(s=s[i.status]||s.pending),Tn.hasColor(s)?s:this.styles.muted(s)}async pointer(e,t){let i=await this.element("pointer",e,t);if(typeof i=="string"&&Tn.hasColor(i))return i;if(i){let n=this.styles,s=this.index===t,o=s?n.primary:c=>c,a=await this.resolve(i[s?"on":"off"]||i,this.state),l=Tn.hasColor(a)?a:o(a);return s?l:" ".repeat(a.length)}}async indicator(e,t){let i=await this.element("indicator",e,t);if(typeof i=="string"&&Tn.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 Tn.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 Tn.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,...t){return Tn.resolve(this,e,...t)}get base(){return M0.prototype}get style(){return this.styles[this.state.status]}get height(){return this.options.rows||Tn.height(this.stdout,25)}get width(){return this.options.columns||Tn.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:t}=this.state,i=[t,e].find(this.isValue.bind(this));return this.isValue(i)?i:this.initial}static get prompt(){return e=>new this(e).run()}};function PGe(r){let e=n=>r[n]===void 0||typeof r[n]=="function",t=["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(r.options)){if(t.includes(n)||/^on[A-Z]/.test(n))continue;let s=r.options[n];typeof s=="function"&&e(n)?i.includes(n)||(r[n]=s.bind(r)):typeof r[n]!="function"&&(r[n]=s)}}function DGe(r){typeof r=="number"&&(r=[r,r,r,r]);let e=[].concat(r||[]),t=n=>n%2==0?` -`:" ",i=[];for(let n=0;n<4;n++){let s=t(n);e[n]?i.push(s.repeat(e[n])):i.push("")}return i}Zre.exports=M0});var rie=w((Qft,eie)=>{"use strict";var RGe=Xi(),tie={default(r,e){return e},checkbox(r,e){throw new Error("checkbox role is not implemented yet")},editable(r,e){throw new Error("editable role is not implemented yet")},expandable(r,e){throw new Error("expandable role is not implemented yet")},heading(r,e){return e.disabled="",e.indicator=[e.indicator," "].find(t=>t!=null),e.message=e.message||"",e},input(r,e){throw new Error("input role is not implemented yet")},option(r,e){return tie.default(r,e)},radio(r,e){throw new Error("radio role is not implemented yet")},separator(r,e){return e.disabled="",e.indicator=[e.indicator," "].find(t=>t!=null),e.message=e.message||r.symbols.line.repeat(5),e},spacer(r,e){return e}};eie.exports=(r,e={})=>{let t=RGe.merge({},tie,e.roles);return t[r]||t.default}});var qC=w((Sft,iie)=>{"use strict";var FGe=Eo(),NGe=_f(),LGe=rie(),K0=Xi(),{reorder:ZF,scrollUp:TGe,scrollDown:OGe,isObject:nie,swap:MGe}=K0,sie=class extends NGe{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:t,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");nie(t)&&(t=Object.keys(t)),Array.isArray(t)?(i!=null&&(this.index=this.findIndex(i)),t.forEach(s=>this.enable(this.find(s))),await this.render()):(i!=null&&(t=i),typeof t=="string"&&(t=this.findIndex(t)),typeof t=="number"&&t>-1&&(this.index=Math.max(0,Math.min(t,this.choices.length)),this.enable(this.find(this.index)))),this.isDisabled(this.focused)&&await this.down()}async toChoices(e,t){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,t,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=LGe(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=t,e.cursor=0,K0.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,FGe.unstyle(e.message).length));let o=N({},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,t)),e}async onChoice(e,t){this.emit("choice",e,t,this),typeof e.onChoice=="function"&&await e.onChoice.call(this,this.state,e,t)}async addChoice(e,t,i){let n=await this.toChoice(e,t,i);return this.choices.push(n),this.index=this.choices.length-1,this.limit=this.choices.length,n}async newItem(e,t,i){let n=N({name:"New choice name?",editable:!0,newChoice:!0},e),s=await this.addChoice(n,t,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,t){if(this.multiple&&this[t.name])return this[t.name]();this.alert()}focus(e,t){return typeof t!="boolean"&&(t=e.enabled),t&&!e.enabled&&this.selected.length>=this.maxSelected?this.alert():(this.index=e.index,e.enabled=t&&!this.isDisabled(e),e)}space(){return this.multiple?(this.toggle(this.focused),this.render()):this.alert()}a(){if(this.maxSelectedt.enabled);return this.choices.forEach(t=>t.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(t=>!!t.parent)?(this.toggle(e.parent&&!e.choices?e.parent:e),this.render()):this.a()}toggle(e,t){if(!e.enabled&&this.selected.length>=this.maxSelected)return this.alert();typeof t!="boolean"&&(t=!e.enabled),e.enabled=t,e.choices&&e.choices.forEach(n=>this.toggle(n,t));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 oie(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 t=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=ZF(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=t(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=ZF(this.choices),this.index=0,this.render()}end(){let e=this.choices.length-this.limit,t=ZF(this.choices);return this.choices=t.slice(e).concat(t.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,t=this.visible.length,i=this.index;return this.options.scroll===!1&&i===0?this.alert():e>t&&i===0?this.scrollUp():(this.index=(i-1%e+e)%e,this.isDisabled()?this.up():this.render())}down(){let e=this.choices.length,t=this.visible.length,i=this.index;return this.options.scroll===!1&&i===t-1?this.alert():e>t&&i===t-1?this.scrollDown():(this.index=(i+1)%e,this.isDisabled()?this.down():this.render())}scrollUp(e=0){return this.choices=TGe(this.choices),this.index=e,this.isDisabled()?this.up():this.render()}scrollDown(e=this.visible.length-1){return this.choices=OGe(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){MGe(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(t=>this.isEnabled(t));if(e.choices){let t=e.choices.filter(i=>!this.isDisabled(i));return e.enabled&&t.every(i=>this.isEnabled(i))}return e.enabled&&!this.isDisabled(e)}isChoice(e,t){return e.name===t||e.index===Number(t)}isSelected(e){return Array.isArray(this.initial)?this.initial.some(t=>this.isChoice(e,t)):this.isChoice(e,this.initial)}map(e=[],t="value"){return[].concat(e||[]).reduce((i,n)=>(i[n]=this.find(n,t),i),{})}filter(e,t){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 t?o.map(a=>a[t]):o}find(e,t){if(nie(e))return t?e[t]:e;let i=(o,a)=>[o.name,a].includes(e),n=typeof e=="function"?e:i,s=this.choices.find(n);if(s)return t?s[t]: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:t,sort:i}=this.options,n=this.multiple===!0,s=this.selected;return s===void 0?this.alert():(Array.isArray(s)&&t!==!1&&i!==!0&&(s=K0.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 t of e)this.state._choices.some(i=>i.name===t.name)||this.state._choices.push(t);if(!this._initial&&this.options.initial){this._initial=!0;let t=this.initial;if(typeof t=="string"||typeof t=="number"){let i=this.find(t);i&&(this.initial=i.index,this.focus(i,!0))}}}get choices(){return oie(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:t,choices:i}=this,n=e.limit||this._limit||t.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 oie(r,e){if(e instanceof Promise)return e;if(typeof e=="function"){if(K0.isAsyncFn(e))return e;e=e.call(r,r)}for(let t of e){if(Array.isArray(t.choices)){let i=t.choices.filter(n=>!r.isDisabled(n));t.enabled=i.every(n=>n.enabled===!0)}r.isDisabled(t)===!0&&delete t.enabled}return e}iie.exports=sie});var Nl=w((vft,aie)=>{"use strict";var KGe=qC(),$F=Xi(),Aie=class extends KGe{constructor(e){super(e);this.emptyError=this.options.emptyError||"No items were selected"}async dispatch(e,t){if(this.multiple)return this[t.name]?await this[t.name](e,t):await super.dispatch(e,t);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,t){return!this.multiple||this.options.pointer?super.pointer(e,t):""}indicator(e,t){return this.multiple?super.indicator(e,t):""}choiceMessage(e,t){let i=this.resolve(e.message,this.state,e,t);return e.role==="heading"&&!$F.hasColor(i)&&(i=this.styles.strong(i)),this.resolve(i,this.state,e,t)}choiceSeparator(){return":"}async renderChoice(e,t){await this.onChoice(e,t);let i=this.index===t,n=await this.pointer(e,t),s=await this.indicator(e,t)+(e.pad||""),o=await this.resolve(e.hint,this.state,e,t);o&&!$F.hasColor(o)&&(o=this.styles.muted(o));let a=this.indent(e),l=await this.choiceMessage(e,t),c=()=>[this.margin[3],a+n+s,l,this.margin[1],o].filter(Boolean).join(" ");return e.role==="heading"?c():e.disabled?($F.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)),t=await Promise.all(e);t.length||t.push(this.styles.danger("No matching choices"));let i=this.margin[0]+t.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:t}=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(t),this.write([n,i,u,g].filter(Boolean).join(` -`)),this.write(this.margin[2]),this.restore()}};aie.exports=Aie});var uie=w((xft,lie)=>{"use strict";var UGe=Nl(),HGe=(r,e)=>{let t=r.toLowerCase();return i=>{let s=i.toLowerCase().indexOf(t),o=e(i.slice(s,s+t.length));return s>=0?i.slice(0,s)+o+i.slice(s+t.length):i}},cie=class extends UGe{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:t,input:i}=this.state;return this.input=i.slice(0,t)+e+i.slice(t),this.moveCursor(1),this.complete()}delete(){let{cursor:e,input:t}=this.state;return t?(this.input=t.slice(0,e-1)+t.slice(e),this.moveCursor(-1),this.complete()):this.alert()}deleteForward(){let{cursor:e,input:t}=this.state;return t[e]===void 0?this.alert():(this.input=`${t}`.slice(0,e)+`${t}`.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,t=this.state._choices){if(typeof this.options.suggest=="function")return this.options.suggest.call(this,e,t);let i=e.toLowerCase();return t.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,t=HGe(this.input,e),i=this.choices;this.choices=i.map(n=>te(N({},n),{message:t(n.message)})),await super.render(),this.choices=i}submit(){return this.options.multiple&&(this.value=this.selected.map(e=>e.name)),super.submit()}};lie.exports=cie});var tN=w((kft,gie)=>{"use strict";var eN=Xi();gie.exports=(r,e={})=>{r.cursorHide();let{input:t="",initial:i="",pos:n,showCursor:s=!0,color:o}=e,a=o||r.styles.placeholder,l=eN.inverse(r.styles.primary),c=m=>l(r.styles.black(m)),u=t,g=" ",f=c(g);if(r.blink&&r.blink.off===!0&&(c=m=>m,f=""),s&&n===0&&i===""&&t==="")return c(g);if(s&&n===0&&(t===i||t===""))return c(i[0])+a(i.slice(1));i=eN.isPrimitive(i)?`${i}`:"",t=eN.isPrimitive(t)?`${t}`:"";let h=i&&i.startsWith(t)&&i!==t,p=h?c(i[t.length]):f;if(n!==t.length&&s===!0&&(u=t.slice(0,n)+c(t[n])+t.slice(n+1),p=""),s===!1&&(p=""),h){let m=r.styles.unstyle(u+p);return u+p+a(i.slice(m.length))}return u+p}});var U0=w((Pft,fie)=>{"use strict";var jGe=Eo(),GGe=Nl(),YGe=tN(),hie=class extends GGe{constructor(e){super(te(N({},e),{multiple:!0}));this.type="form",this.initial=this.options.initial,this.align=[this.options.align,"right"].find(t=>t!=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(t=>t.reset&&t.reset()),this.render()}dispatch(e){return!!e&&this.append(e)}append(e){let t=this.focused;if(!t)return this.alert();let{cursor:i,input:n}=t;return t.value=t.input=n.slice(0,i)+e+n.slice(i),t.cursor++,this.render()}delete(){let e=this.focused;if(!e||e.cursor<=0)return this.alert();let{cursor:t,input:i}=e;return e.value=e.input=i.slice(0,t-1)+i.slice(t),e.cursor--,this.render()}deleteForward(){let e=this.focused;if(!e)return this.alert();let{cursor:t,input:i}=e;if(i[t]===void 0)return this.alert();let n=`${i}`.slice(0,t)+`${i}`.slice(t+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,t){return this.dispatch(e,t)}number(e,t){return this.dispatch(e,t)}next(){let e=this.focused;if(!e)return this.alert();let{initial:t,input:i}=e;return t&&t.startsWith(i)&&i!==t?(e.value=e.input=t,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,t){let i=await this.resolve(e.separator,this.state,e,t)||":";return i?" "+this.styles.disabled(i):""}async renderChoice(e,t){await this.onChoice(e,t);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,m=this.index===t,y=e.validate||(()=>!0),b=await this.choiceSeparator(e,t),v=e.message;this.align==="right"&&(v=v.padStart(this.longest+1," ")),this.align==="left"&&(v=v.padEnd(this.longest+1," "));let x=this.values[a]=c||o,T=c?"success":"dark";await y.call(e,x,this.state)!==!0&&(T="danger");let Y=n[T](await this.indicator(e,t))+(e.pad||""),$=this.indent(e),_=()=>[$,Y,v+b,c,p].filter(Boolean).join(" ");if(i.submitted)return v=jGe.unstyle(v),c=g(c),p="",_();if(e.format)c=await e.format.call(this,c,e,t);else{let ne=this.styles.muted;c=YGe(this,{input:c,initial:o,pos:s,showCursor:m,color:ne})}return this.isValue(c)||(c=this.styles.muted(this.symbols.ellipsis)),e.result&&(this.values[a]=await e.result.call(this,x,e,t)),m&&(v=f(v)),e.error?c+=(c?" ":"")+h(e.error.trim()):e.hint&&(c+=(c?" ":"")+u(e.hint.trim())),_()}async submit(){return this.value=this.values,super.base.submit.call(this)}};fie.exports=hie});var rN=w((Dft,pie)=>{"use strict";var qGe=U0(),JGe=()=>{throw new Error("expected prompt to have a custom authenticate method")},die=(r=JGe)=>{class e extends qGe{constructor(i){super(i)}async submit(){this.value=await r.call(this,this.values,this.state),super.base.submit.call(this)}static create(i){return die(i)}}return e};pie.exports=die()});var Eie=w((Rft,Cie)=>{"use strict";var WGe=rN();function zGe(r,e){return r.username===this.options.username&&r.password===this.options.password}var mie=(r=zGe)=>{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 t extends WGe.create(r){constructor(n){super(te(N({},n),{choices:e}))}static create(n){return mie(n)}}return t};Cie.exports=mie()});var H0=w((Fft,Iie)=>{"use strict";var _Ge=_f(),{isPrimitive:VGe,hasColor:XGe}=Xi(),yie=class extends _Ge{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:t,state:i}=this;return i.submitted?t.success(e):t.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 VGe(e)&&(this.isTrue(e)||this.isFalse(e))}async hint(){if(this.state.status==="pending"){let e=await this.element("hint");return XGe(e)?e:this.styles.muted(e)}}async render(){let{input:e,size:t}=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(t),this.write([l,a,f].filter(Boolean).join(` -`)),this.restore()}set value(e){super.value=e}get value(){return this.cast(super.value)}};Iie.exports=yie});var bie=w((Nft,wie)=>{"use strict";var ZGe=H0(),Bie=class extends ZGe{constructor(e){super(e);this.default=this.options.default||(this.initial?"(Y/n)":"(y/N)")}};wie.exports=Bie});var vie=w((Lft,Qie)=>{"use strict";var $Ge=Nl(),eYe=U0(),Vf=eYe.prototype,Sie=class extends $Ge{constructor(e){super(te(N({},e),{multiple:!0}));this.align=[this.options.align,"left"].find(t=>t!=null),this.emptyError="",this.values={}}dispatch(e,t){let i=this.focused,n=i.parent||{};return!i.editable&&!n.editable&&(e==="a"||e==="i")?super[e]():Vf.dispatch.call(this,e,t)}append(e,t){return Vf.append.call(this,e,t)}delete(e,t){return Vf.delete.call(this,e,t)}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?Vf.next.call(this):super.next()}prev(){return this.focused.editable?Vf.prev.call(this):super.prev()}async indicator(e,t){let i=e.indicator||"",n=e.editable?i:super.indicator(e,t);return await this.resolve(n,this.state,e,t)||""}indent(e){return e.role==="heading"?"":e.editable?" ":" "}async renderChoice(e,t){return e.indent="",e.editable?Vf.renderChoice.call(this,e,t):super.renderChoice(e,t)}error(){return""}footer(){return this.state.error}async validate(){let e=!0;for(let t of this.choices){if(typeof t.validate!="function"||t.role==="heading")continue;let i=t.parent?this.value[t.parent.name]:this.value;if(t.editable?i=t.value===t.name?t.initial||"":t.value:this.isDisabled(t)||(i=t.enabled===!0),e=await t.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 t=e.parent?this.value[e.parent.name]:this.value;if(e.role==="heading"){this.value[e.name]={};continue}e.editable?t[e.name]=e.value===e.name?e.initial||"":e.value:this.isDisabled(e)||(t[e.name]=e.enabled===!0)}return this.base.submit.call(this)}};Qie.exports=Sie});var wu=w((Tft,xie)=>{"use strict";var tYe=_f(),rYe=tN(),{isPrimitive:iYe}=Xi(),kie=class extends tYe{constructor(e){super(e);this.initial=iYe(this.initial)?String(this.initial):"",this.initial&&this.cursorHide(),this.state.prevCursor=0,this.state.clipboard=[]}async keypress(e,t={}){let i=this.state.prevKeypress;return this.state.prevKeypress=t,this.options.multiline===!0&&t.name==="return"&&(!i||i.name!=="return")?this.append(` -`,t):super.keypress(e,t)}moveCursor(e){this.cursor+=e}reset(){return this.input=this.value="",this.cursor=0,this.render()}dispatch(e,t){if(!e||t.ctrl||t.code)return this.alert();this.append(e)}append(e){let{cursor:t,input:i}=this.state;this.input=`${i}`.slice(0,t)+e+`${i}`.slice(t),this.moveCursor(String(e).length),this.render()}insert(e){this.append(e)}delete(){let{cursor:e,input:t}=this.state;if(e<=0)return this.alert();this.input=`${t}`.slice(0,e-1)+`${t}`.slice(e),this.moveCursor(-1),this.render()}deleteForward(){let{cursor:e,input:t}=this.state;if(t[e]===void 0)return this.alert();this.input=`${t}`.slice(0,e)+`${t}`.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 t=this.input.slice(0,e),i=this.input.slice(e),n=t.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 t=await this.resolve(this.initial,this.state);return this.state.submitted?this.styles.submitted(e||t):rYe(this,{input:e,initial:t,pos:this.cursor})}async render(){let e=this.state.size,t=await this.prefix(),i=await this.separator(),n=await this.message(),s=[t,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()}};xie.exports=kie});var Die=w((Oft,Pie)=>{"use strict";var nYe=r=>r.filter((e,t)=>r.lastIndexOf(e)===t),j0=r=>nYe(r).filter(Boolean);Pie.exports=(r,e={},t="")=>{let{past:i=[],present:n=""}=e,s,o;switch(r){case"prev":case"undo":return s=i.slice(0,i.length-1),o=i[i.length-1]||"",{past:j0([t,...s]),present:o};case"next":case"redo":return s=i.slice(1),o=i[0]||"",{past:j0([...s,t]),present:o};case"save":return{past:j0([...i,t]),present:""};case"remove":return o=j0(i.filter(a=>a!==t)),n="",o.length&&(n=o.pop()),{past:o,present:n};default:throw new Error(`Invalid action: "${r}"`)}}});var iN=w((Mft,Rie)=>{"use strict";var sYe=wu(),Fie=Die(),Nie=class extends sYe{constructor(e){super(e);let t=this.options.history;if(t&&t.store){let i=t.values||this.initial;this.autosave=!!t.autosave,this.store=t.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=Fie(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=Fie("save",this.data,this.input),this.store.set("values",this.data))}submit(){return this.store&&this.autosave===!0&&this.save(),super.submit()}};Rie.exports=Nie});var Oie=w((Kft,Lie)=>{"use strict";var oYe=wu(),Tie=class extends oYe{format(){return""}};Lie.exports=Tie});var Uie=w((Uft,Mie)=>{"use strict";var aYe=wu(),Kie=class extends aYe{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:t=>t;return this.list.map(e).join(", ")}async submit(e){let t=this.state.error||await this.validate(this.list,this.state);return t!==!0?(this.state.error=t,super.submit()):(this.value=this.list,super.submit())}get list(){return this.split()}};Mie.exports=Kie});var Gie=w((Hft,Hie)=>{"use strict";var AYe=Nl(),jie=class extends AYe{constructor(e){super(te(N({},e),{multiple:!0}))}};Hie.exports=jie});var nN=w((jft,Yie)=>{"use strict";var lYe=wu(),qie=class extends lYe{constructor(e={}){super(N({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 t=e||this.minor,i=this.toNumber(this.input);return i>this.max+t?this.alert():(this.input=`${i+t}`,this.render())}down(e){let t=e||this.minor,i=this.toNumber(this.input);return ithis.isValue(t));return this.value=this.toNumber(e||0),super.submit()}};Yie.exports=qie});var Wie=w((Gft,Jie)=>{Jie.exports=nN()});var Vie=w((Yft,zie)=>{"use strict";var cYe=wu(),_ie=class extends cYe{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)):""}};zie.exports=_ie});var ene=w((qft,Xie)=>{"use strict";var uYe=Eo(),gYe=qC(),Zie=Xi(),$ie=class extends gYe{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 t=e.startNumber||1;typeof this.scale=="number"&&(this.scaleKey=!1,this.scale=Array(this.scale).fill(0).map((i,n)=>({name:n+t})))}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 t of this.choices){e=Math.max(e,t.message.length),t.scaleIndex=t.initial||2,t.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(t=>this.styles.info(t.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 t=this.scale.map(l=>l.name);typeof this.options.renderScaleHeading=="function"&&(t=this.options.renderScaleHeading.call(this,e));let i=this.scaleLength-t.join("").length,n=Math.round(i/(t.length-1)),o=t.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,t,i){if(typeof this.options.scaleIndicator=="function")return this.options.scaleIndicator.call(this,e,t,i);let n=e.scaleIndex===t.index;return t.disabled?this.styles.hint(this.symbols.radio.disabled):n?this.styles.success(this.symbols.radio.on):this.symbols.radio.off}renderScale(e,t){let i=e.scale.map(s=>this.scaleIndicator(e,s,t)),n=this.term==="Hyper"?"":" ";return i.join(n+this.symbols.line.repeat(this.edgeLength))}async renderChoice(e,t){await this.onChoice(e,t);let i=this.index===t,n=await this.pointer(e,t),s=await e.hint;s&&!Zie.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,t),u=await this.renderScale(e,t),g=this.margin[1]+this.margin[3];this.scaleLength=uYe.unstyle(u).length,this.widths[0]=Math.min(this.widths[0],this.width-this.scaleLength-g.length);let h=Zie.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)),t=await Promise.all(e),i=await this.renderScaleHeading();return this.margin[0]+[i,...t.map(n=>n.join(" "))].join(` -`)}async render(){let{submitted:e,size:t}=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(t),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)}};Xie.exports=$ie});var nne=w((Jft,tne)=>{"use strict";var rne=Eo(),fYe=(r="")=>typeof r=="string"?r.replace(/^['"]|['"]$/g,""):"",ine=class{constructor(e){this.name=e.key,this.field=e.field||{},this.value=fYe(e.initial||this.field.initial||""),this.message=e.message||this.name,this.cursor=0,this.input="",this.lines=[]}},hYe=async(r={},e={},t=i=>i)=>{let i=new Set,n=r.fields||[],s=r.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:""});uT.name===b.key);b.field=n.find(T=>T.name===b.key),x||(x=new ine(b),a.push(x)),x.lines.push(b.line-1);continue}let m=o[o.length-1];m.type==="text"&&m.line===c?m.value+=p:h({type:"text",value:p})}return h({type:"eos",value:""}),{input:s,tabstops:o,unique:i,keys:l,items:a}};tne.exports=async r=>{let e=r.options,t=new Set(e.required===!0?[]:e.required||[]),i=N(N({},e.values),e.initial),{tabstops:n,items:s,keys:o}=await hYe(e,i),a=sN("result",r,e),l=sN("format",r,e),c=sN("validate",r,e,!0),u=r.isValue.bind(r);return async(g={},f=!1)=>{let h=0;g.required=t,g.items=s,g.keys=o,g.output="";let p=async(v,x,T,q)=>{let Y=await c(v,x,T,q);return Y===!1?"Invalid field "+T.name:Y};for(let v of n){let x=v.value,T=v.key;if(v.type!=="template"){x&&(g.output+=x);continue}if(v.type==="template"){let q=s.find(ee=>ee.name===T);e.required===!0&&g.required.add(q.name);let Y=[q.input,g.values[q.value],q.value,x].find(u),_=(q.field||{}).message||v.inner;if(f){let ee=await p(g.values[T],g,q,h);if(ee&&typeof ee=="string"||ee===!1){g.invalid.set(T,ee);continue}g.invalid.delete(T);let A=await a(g.values[T],g,q,h);g.output+=rne.unstyle(A);continue}q.placeholder=!1;let ne=x;x=await l(x,g,q,h),Y!==x?(g.values[T]=Y,x=r.styles.typing(Y),g.missing.delete(_)):(g.values[T]=void 0,Y=`<${_}>`,x=r.styles.primary(Y),q.placeholder=!0,g.required.has(T)&&g.missing.add(_)),g.missing.has(_)&&g.validating&&(x=r.styles.warning(Y)),g.invalid.has(T)&&g.validating&&(x=r.styles.danger(Y)),h===g.index&&(ne!==x?x=r.styles.underline(x):x=r.styles.heading(rne.unstyle(x))),h++}x&&(g.output+=x)}let m=g.output.split(` -`).map(v=>" "+v),y=s.length,b=0;for(let v of s)g.invalid.has(v.name)&&v.lines.forEach(x=>{m[x][0]===" "&&(m[x]=g.styles.danger(g.symbols.bullet)+m[x].slice(1))}),r.isValue(g.values[v.name])&&b++;return g.completed=(b/y*100).toFixed(0),g.output=m.join(` -`),g.output}};function sN(r,e,t,i){return(n,s,o,a)=>typeof o.field[r]=="function"?o.field[r].call(e,n,s,o,a):[i,n].find(l=>e.isValue(l))}});var ane=w((Wft,sne)=>{"use strict";var pYe=Eo(),dYe=nne(),CYe=_f(),one=class extends CYe{constructor(e){super(e);this.cursorHide(),this.reset(!0)}async initialize(){this.interpolate=await dYe(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 t=this.getItem();this.cursor+=e,t.cursor+=e}dispatch(e,t){if(!t.code&&!t.ctrl&&e!=null&&this.getItem()){this.append(e,t);return}this.alert()}append(e,t){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 t=e.input.slice(this.cursor),i=e.input.slice(0,this.cursor-1);this.input=e.input=`${i}${t}`,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 t=this.state.completed<100?this.styles.warning:this.styles.success;return this.state.submitted===!0&&this.state.completed!==100&&(t=this.styles.danger),t(`${this.state.completed}% completed`)}async render(){let{index:e,keys:t=[],submitted:i,size:n}=this.state,s=[this.options.newline,` -`].find(v=>v!=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=t[e]||"",m=await this.format(p),y=await this.footer();m&&(c+=" "+m),f&&!m&&this.state.completed===0&&(c+=" "+f),this.clear(n);let b=[u,c,h,y,g.trim()];this.write(b.filter(Boolean).join(s)),this.restore()}getItem(e){let{items:t,keys:i,index:n}=this.state,s=t.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:t,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(t.size)return this.state.error="Required: "+[...t.keys()].join(", "),super.submit();let o=pYe.unstyle(i).split(` -`).map(a=>a.slice(1)).join(` -`);return this.value={values:n,result:o},super.submit()}};sne.exports=one});var cne=w((zft,Ane)=>{"use strict";var mYe="(Use + to sort)",EYe=Nl(),lne=class extends EYe{constructor(e){super(te(N({},e),{reorder:!1,sort:!0,multiple:!0}));this.state.hint=[this.options.hint,mYe].find(this.isValue.bind(this))}indicator(){return""}async renderChoice(e,t){let i=await super.renderChoice(e,t),n=this.symbols.identicalTo+" ",s=this.index===t&&this.sorting?this.styles.muted(n):" ";return this.options.drag===!1&&(s=""),this.options.numbered===!0?s+`${t+1} - `+i:s+i}get selected(){return this.choices}submit(){return this.value=this.choices.map(e=>e.value),super.submit()}};Ane.exports=lne});var fne=w((_ft,une)=>{"use strict";var IYe=qC(),gne=class extends IYe{constructor(e={}){super(e);if(this.emptyError=e.emptyError||"No items were selected",this.term=process.env.TERM_PROGRAM,!this.options.header){let t=["","4 - Strongly Agree","3 - Agree","2 - Neutral","1 - Disagree","0 - Strongly Disagree",""];t=t.map(i=>this.styles.muted(i)),this.state.header=t.join(` - `)}}async toChoices(...e){if(this.createdScales)return!1;this.createdScales=!0;let t=await super.toChoices(...e);for(let i of t)i.scale=yYe(5,this.options),i.scaleIdx=2;return t}dispatch(){this.alert()}space(){let e=this.focused,t=e.scale[e.scaleIdx],i=t.selected;return e.scale.forEach(n=>n.selected=!1),t.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,t){await this.onChoice(e,t);let i=this.index===t,n=this.term==="Hyper",s=n?9:8,o=n?"":" ",a=this.symbols.line.repeat(s),l=" ".repeat(s+(n?0:1)),c=x=>(x?this.styles.success("\u25C9"):"\u25EF")+o,u=t+1+".",g=i?this.styles.heading:this.styles.noop,f=await this.resolve(e.message,this.state,e,t),h=this.indent(e),p=h+e.scale.map((x,T)=>c(T===e.scaleIdx)).join(a),m=x=>x===e.scaleIdx?g(x):x,y=h+e.scale.map((x,T)=>m(T)).join(l),b=()=>[u,f].filter(Boolean).join(" "),v=()=>[b(),p,y," "].filter(Boolean).join(` -`);return i&&(p=this.styles.cyan(p),y=this.styles.cyan(y)),v()}async renderChoices(){if(this.state.submitted)return"";let e=this.visible.map(async(i,n)=>await this.renderChoice(i,n)),t=await Promise.all(e);return t.length||t.push(this.styles.danger("No matching choices")),t.join(` -`)}format(){return this.state.submitted?this.choices.map(t=>this.styles.info(t.scaleIdx)).join(", "):""}async render(){let{submitted:e,size:t}=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(t),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 yYe(r,e={}){if(Array.isArray(e.scale))return e.scale.map(i=>N({},i));let t=[];for(let i=1;i{hne.exports=iN()});var mne=w((Xft,dne)=>{"use strict";var wYe=H0(),Cne=class extends wYe{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="",t){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,t=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([t,c,l].filter(Boolean).join(` -`)),this.write(this.margin[2]),this.restore()}};dne.exports=Cne});var yne=w((Zft,Ene)=>{"use strict";var BYe=Nl(),Ine=class extends BYe{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,t){let i=await super.toChoices(e,t);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)}}};Ene.exports=Ine});var Bne=w(oN=>{"use strict";var wne=Xi(),mi=(r,e)=>{wne.defineExport(oN,r,e),wne.defineExport(oN,r.toLowerCase(),e)};mi("AutoComplete",()=>uie());mi("BasicAuth",()=>Eie());mi("Confirm",()=>bie());mi("Editable",()=>vie());mi("Form",()=>U0());mi("Input",()=>iN());mi("Invisible",()=>Oie());mi("List",()=>Uie());mi("MultiSelect",()=>Gie());mi("Numeral",()=>Wie());mi("Password",()=>Vie());mi("Scale",()=>ene());mi("Select",()=>Nl());mi("Snippet",()=>ane());mi("Sort",()=>cne());mi("Survey",()=>fne());mi("Text",()=>pne());mi("Toggle",()=>mne());mi("Quiz",()=>yne())});var Qne=w((eht,bne)=>{bne.exports={ArrayPrompt:qC(),AuthPrompt:rN(),BooleanPrompt:H0(),NumberPrompt:nN(),StringPrompt:wu()}});var WC=w((tht,Sne)=>{"use strict";var vne=require("assert"),aN=require("events"),Ll=Xi(),ha=class extends aN{constructor(e,t){super();this.options=Ll.merge({},e),this.answers=N({},t)}register(e,t){if(Ll.isObject(e)){for(let n of Object.keys(e))this.register(n,e[n]);return this}vne.equal(typeof t,"function","expected a function");let i=e.toLowerCase();return t.prototype instanceof this.Prompt?this.prompts[i]=t:this.prompts[i]=t(this.Prompt,this),this}async prompt(e=[]){for(let t of[].concat(e))try{typeof t=="function"&&(t=await t.call(this)),await this.ask(Ll.merge({},this.options,t))}catch(i){return Promise.reject(i)}return this.answers}async ask(e){typeof e=="function"&&(e=await e.call(this));let t=Ll.merge({},this.options,e),{type:i,name:n}=e,{set:s,get:o}=Ll;if(typeof i=="function"&&(i=await i.call(this,e,this.answers)),!i)return this.answers[n];vne(this.prompts[i],`Prompt "${i}" is not registered`);let a=new this.prompts[i](t),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),t.autofill&&l!=null?(a.value=a.input=l,t.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||_f()}static get prompts(){return Bne()}static get types(){return Qne()}static get prompt(){let e=(t,...i)=>{let n=new this(...i),s=n.emit.bind(n);return n.emit=(...o)=>(e.emit(...o),s(...o)),n.prompt(t)};return Ll.mixinEmitter(e,new aN),e}};Ll.mixinEmitter(ha,new aN);var AN=ha.prompts;for(let r of Object.keys(AN)){let e=r.toLowerCase(),t=i=>new AN[r](i).run();ha.prompt[e]=t,ha[e]=t,ha[r]||Reflect.defineProperty(ha,r,{get:()=>AN[r]})}var JC=r=>{Ll.defineExport(ha,r,()=>ha.types[r])};JC("ArrayPrompt");JC("AuthPrompt");JC("BooleanPrompt");JC("NumberPrompt");JC("StringPrompt");Sne.exports=ha});var Une=w((Yht,Kne)=>{function xYe(r,e){for(var t=-1,i=r==null?0:r.length;++t{var kYe=$B(),PYe=Nf();function DYe(r,e,t,i){var n=!t;t||(t={});for(var s=-1,o=e.length;++s{var RYe=Zf(),FYe=Kf();function NYe(r,e){return r&&RYe(e,FYe(e),r)}jne.exports=NYe});var qne=w((Wht,Yne)=>{function LYe(r){var e=[];if(r!=null)for(var t in Object(r))e.push(t);return e}Yne.exports=LYe});var Wne=w((zht,Jne)=>{var TYe=Rn(),OYe=f0(),MYe=qne(),KYe=Object.prototype,UYe=KYe.hasOwnProperty;function HYe(r){if(!TYe(r))return MYe(r);var e=OYe(r),t=[];for(var i in r)i=="constructor"&&(e||!UYe.call(r,i))||t.push(i);return t}Jne.exports=HYe});var $f=w((_ht,zne)=>{var jYe=$R(),GYe=Wne(),YYe=vC();function qYe(r){return YYe(r)?jYe(r,!0):GYe(r)}zne.exports=qYe});var Vne=w((Vht,_ne)=>{var JYe=Zf(),WYe=$f();function zYe(r,e){return r&&JYe(e,WYe(e),r)}_ne.exports=zYe});var hN=w((em,eh)=>{var _Ye=Ns(),Xne=typeof em=="object"&&em&&!em.nodeType&&em,Zne=Xne&&typeof eh=="object"&&eh&&!eh.nodeType&&eh,VYe=Zne&&Zne.exports===Xne,$ne=VYe?_Ye.Buffer:void 0,ese=$ne?$ne.allocUnsafe:void 0;function XYe(r,e){if(e)return r.slice();var t=r.length,i=ese?ese(t):new r.constructor(t);return r.copy(i),i}eh.exports=XYe});var pN=w((Xht,tse)=>{function ZYe(r,e){var t=-1,i=r.length;for(e||(e=Array(i));++t{var $Ye=Zf(),eqe=p0();function tqe(r,e){return $Ye(r,eqe(r),e)}rse.exports=tqe});var G0=w(($ht,nse)=>{var rqe=eF(),iqe=rqe(Object.getPrototypeOf,Object);nse.exports=iqe});var dN=w((ept,sse)=>{var nqe=t0(),sqe=G0(),oqe=p0(),aqe=oF(),Aqe=Object.getOwnPropertySymbols,lqe=Aqe?function(r){for(var e=[];r;)nqe(e,oqe(r)),r=sqe(r);return e}:aqe;sse.exports=lqe});var ase=w((tpt,ose)=>{var cqe=Zf(),uqe=dN();function gqe(r,e){return cqe(r,uqe(r),e)}ose.exports=gqe});var lse=w((rpt,Ase)=>{var fqe=sF(),hqe=dN(),pqe=$f();function dqe(r){return fqe(r,pqe,hqe)}Ase.exports=dqe});var use=w((ipt,cse)=>{var Cqe=Object.prototype,mqe=Cqe.hasOwnProperty;function Eqe(r){var e=r.length,t=new r.constructor(e);return e&&typeof r[0]=="string"&&mqe.call(r,"index")&&(t.index=r.index,t.input=r.input),t}cse.exports=Eqe});var Y0=w((npt,gse)=>{var fse=iF();function Iqe(r){var e=new r.constructor(r.byteLength);return new fse(e).set(new fse(r)),e}gse.exports=Iqe});var pse=w((spt,hse)=>{var yqe=Y0();function wqe(r,e){var t=e?yqe(r.buffer):r.buffer;return new r.constructor(t,r.byteOffset,r.byteLength)}hse.exports=wqe});var Cse=w((opt,dse)=>{var Bqe=/\w*$/;function bqe(r){var e=new r.constructor(r.source,Bqe.exec(r));return e.lastIndex=r.lastIndex,e}dse.exports=bqe});var wse=w((apt,mse)=>{var Ese=Jc(),Ise=Ese?Ese.prototype:void 0,yse=Ise?Ise.valueOf:void 0;function Qqe(r){return yse?Object(yse.call(r)):{}}mse.exports=Qqe});var CN=w((Apt,Bse)=>{var Sqe=Y0();function vqe(r,e){var t=e?Sqe(r.buffer):r.buffer;return new r.constructor(t,r.byteOffset,r.length)}Bse.exports=vqe});var Qse=w((lpt,bse)=>{var xqe=Y0(),kqe=pse(),Pqe=Cse(),Dqe=wse(),Rqe=CN(),Fqe="[object Boolean]",Nqe="[object Date]",Lqe="[object Map]",Tqe="[object Number]",Oqe="[object RegExp]",Mqe="[object Set]",Kqe="[object String]",Uqe="[object Symbol]",Hqe="[object ArrayBuffer]",jqe="[object DataView]",Gqe="[object Float32Array]",Yqe="[object Float64Array]",qqe="[object Int8Array]",Jqe="[object Int16Array]",Wqe="[object Int32Array]",zqe="[object Uint8Array]",_qe="[object Uint8ClampedArray]",Vqe="[object Uint16Array]",Xqe="[object Uint32Array]";function Zqe(r,e,t){var i=r.constructor;switch(e){case Hqe:return xqe(r);case Fqe:case Nqe:return new i(+r);case jqe:return kqe(r,t);case Gqe:case Yqe:case qqe:case Jqe:case Wqe:case zqe:case _qe:case Vqe:case Xqe:return Rqe(r,t);case Lqe:return new i;case Tqe:case Kqe:return new i(r);case Oqe:return Pqe(r);case Mqe:return new i;case Uqe:return Dqe(r)}}bse.exports=Zqe});var xse=w((cpt,Sse)=>{var $qe=Rn(),vse=Object.create,eJe=function(){function r(){}return function(e){if(!$qe(e))return{};if(vse)return vse(e);r.prototype=e;var t=new r;return r.prototype=void 0,t}}();Sse.exports=eJe});var mN=w((upt,kse)=>{var tJe=xse(),rJe=G0(),iJe=f0();function nJe(r){return typeof r.constructor=="function"&&!iJe(r)?tJe(rJe(r)):{}}kse.exports=nJe});var Dse=w((gpt,Pse)=>{var sJe=kC(),oJe=ta(),aJe="[object Map]";function AJe(r){return oJe(r)&&sJe(r)==aJe}Pse.exports=AJe});var Lse=w((fpt,Rse)=>{var lJe=Dse(),cJe=c0(),Fse=u0(),Nse=Fse&&Fse.isMap,uJe=Nse?cJe(Nse):lJe;Rse.exports=uJe});var Ose=w((hpt,Tse)=>{var gJe=kC(),fJe=ta(),hJe="[object Set]";function pJe(r){return fJe(r)&&gJe(r)==hJe}Tse.exports=pJe});var Hse=w((ppt,Mse)=>{var dJe=Ose(),CJe=c0(),Kse=u0(),Use=Kse&&Kse.isSet,mJe=Use?CJe(Use):dJe;Mse.exports=mJe});var Jse=w((dpt,jse)=>{var EJe=xC(),IJe=Une(),yJe=$B(),wJe=Gne(),BJe=Vne(),bJe=hN(),QJe=pN(),SJe=ise(),vJe=ase(),xJe=aF(),kJe=lse(),PJe=kC(),DJe=use(),RJe=Qse(),FJe=mN(),NJe=Ks(),LJe=bC(),TJe=Lse(),OJe=Rn(),MJe=Hse(),KJe=Kf(),UJe=$f(),HJe=1,jJe=2,GJe=4,Gse="[object Arguments]",YJe="[object Array]",qJe="[object Boolean]",JJe="[object Date]",WJe="[object Error]",Yse="[object Function]",zJe="[object GeneratorFunction]",_Je="[object Map]",VJe="[object Number]",qse="[object Object]",XJe="[object RegExp]",ZJe="[object Set]",$Je="[object String]",e3e="[object Symbol]",t3e="[object WeakMap]",r3e="[object ArrayBuffer]",i3e="[object DataView]",n3e="[object Float32Array]",s3e="[object Float64Array]",o3e="[object Int8Array]",a3e="[object Int16Array]",A3e="[object Int32Array]",l3e="[object Uint8Array]",c3e="[object Uint8ClampedArray]",u3e="[object Uint16Array]",g3e="[object Uint32Array]",dr={};dr[Gse]=dr[YJe]=dr[r3e]=dr[i3e]=dr[qJe]=dr[JJe]=dr[n3e]=dr[s3e]=dr[o3e]=dr[a3e]=dr[A3e]=dr[_Je]=dr[VJe]=dr[qse]=dr[XJe]=dr[ZJe]=dr[$Je]=dr[e3e]=dr[l3e]=dr[c3e]=dr[u3e]=dr[g3e]=!0;dr[WJe]=dr[Yse]=dr[t3e]=!1;function q0(r,e,t,i,n,s){var o,a=e&HJe,l=e&jJe,c=e&GJe;if(t&&(o=n?t(r,i,n,s):t(r)),o!==void 0)return o;if(!OJe(r))return r;var u=NJe(r);if(u){if(o=DJe(r),!a)return QJe(r,o)}else{var g=PJe(r),f=g==Yse||g==zJe;if(LJe(r))return bJe(r,a);if(g==qse||g==Gse||f&&!n){if(o=l||f?{}:FJe(r),!a)return l?vJe(r,BJe(o,r)):SJe(r,wJe(o,r))}else{if(!dr[g])return n?r:{};o=RJe(r,g,a)}}s||(s=new EJe);var h=s.get(r);if(h)return h;s.set(r,o),MJe(r)?r.forEach(function(y){o.add(q0(y,e,t,y,r,s))}):TJe(r)&&r.forEach(function(y,b){o.set(b,q0(y,e,t,b,r,s))});var p=c?l?kJe:xJe:l?UJe:KJe,m=u?void 0:p(r);return IJe(m||r,function(y,b){m&&(b=y,y=r[b]),yJe(o,b,q0(y,e,t,b,r,s))}),o}jse.exports=q0});var EN=w((Cpt,Wse)=>{var f3e=Jse(),h3e=1,p3e=4;function d3e(r){return f3e(r,h3e|p3e)}Wse.exports=d3e});var _se=w((mpt,zse)=>{var C3e=kR();function m3e(r,e,t){return r==null?r:C3e(r,e,t)}zse.exports=m3e});var toe=w((bpt,eoe)=>{function E3e(r){var e=r==null?0:r.length;return e?r[e-1]:void 0}eoe.exports=E3e});var ioe=w((Qpt,roe)=>{var I3e=hC(),y3e=VP();function w3e(r,e){return e.length<2?r:I3e(r,y3e(e,0,-1))}roe.exports=w3e});var soe=w((Spt,noe)=>{var B3e=Ff(),b3e=toe(),Q3e=ioe(),S3e=gu();function v3e(r,e){return e=B3e(e,r),r=Q3e(r,e),r==null||delete r[S3e(b3e(e))]}noe.exports=v3e});var aoe=w((vpt,ooe)=>{var x3e=soe();function k3e(r,e){return r==null?!0:x3e(r,e)}ooe.exports=k3e});var doe=w((idt,poe)=>{poe.exports={name:"@yarnpkg/cli",version:"3.2.2",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.2.0-rc.4",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"},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 DN=w((LEt,rae)=>{"use strict";rae.exports=function(e,t){t===!0&&(t=0);var i=e.indexOf("://"),n=e.substring(0,i).split("+").filter(Boolean);return typeof t=="number"?n[t]:n}});var RN=w((TEt,iae)=>{"use strict";var V3e=DN();function nae(r){if(Array.isArray(r))return r.indexOf("ssh")!==-1||r.indexOf("rsync")!==-1;if(typeof r!="string")return!1;var e=V3e(r);return r=r.substring(r.indexOf("://")+3),nae(e)?!0:r.indexOf("@"){"use strict";var X3e=DN(),Z3e=RN(),$3e=require("querystring");function eWe(r){r=(r||"").trim();var e={protocols:X3e(r),protocol:null,port:null,resource:"",user:"",pathname:"",hash:"",search:"",href:r,query:Object.create(null)},t=r.indexOf("://"),i=-1,n=null,s=null;r.startsWith(".")&&(r.startsWith("./")&&(r=r.substring(2)),e.pathname=r,e.protocol="file");var o=r.charAt(1);return e.protocol||(e.protocol=e.protocols[0],e.protocol||(Z3e(r)?e.protocol="ssh":((o==="/"||o==="~")&&(r=r.substring(2)),e.protocol="file"))),t!==-1&&(r=r.substring(t+3)),s=r.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=$3e.parse(e.search),e.href=e.href.replace(/\/$/,""),e.pathname=e.pathname.replace(/\/$/,""),e}sae.exports=eWe});var lae=w((MEt,aae)=>{"use strict";var tWe="text/plain",rWe="us-ascii",Aae=(r,e)=>e.some(t=>t instanceof RegExp?t.test(r):t===r),iWe=(r,{stripHash:e})=>{let t=/^data:(?[^,]*?),(?[^#]*?)(?:#(?.*))?$/.exec(r);if(!t)throw new Error(`Invalid URL: ${r}`);let{type:i,data:n,hash:s}=t.groups,o=i.split(";");s=e?"":s;let a=!1;o[o.length-1]==="base64"&&(o.pop(),a=!0);let l=(o.shift()||"").toLowerCase(),u=[...o.map(g=>{let[f,h=""]=g.split("=").map(p=>p.trim());return f==="charset"&&(h=h.toLowerCase(),h===rWe)?"":`${f}${h?`=${h}`:""}`}).filter(Boolean)];return a&&u.push("base64"),(u.length!==0||l&&l!==tWe)&&u.unshift(l),`data:${u.join(";")},${a?n.trim():n}${s?`#${s}`:""}`},nWe=(r,e)=>{if(e=N({defaultProtocol:"http:",normalizeProtocol:!0,forceHttp:!1,forceHttps:!1,stripAuthentication:!0,stripHash:!1,stripTextFragment:!0,stripWWW:!0,removeQueryParameters:[/^utm_\w+/i],removeTrailingSlash:!0,removeSingleSlash:!0,removeDirectoryIndex:!1,sortQueryParameters:!0},e),r=r.trim(),/^data:/i.test(r))return iWe(r,e);if(/^view-source:/i.test(r))throw new Error("`view-source:` is not supported as it is a non-standard protocol");let t=r.startsWith("//");!t&&/^\.*\//.test(r)||(r=r.replace(/^(?!(?:\w+:)?\/\/)|^\/\//,e.defaultProtocol));let n=new URL(r);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="":e.stripTextFragment&&(n.hash=n.hash.replace(/#?:~:text.*?$/i,"")),n.pathname&&(n.pathname=n.pathname.replace(/(?0){let o=n.pathname.split("/"),a=o[o.length-1];Aae(a,e.removeDirectoryIndex)&&(o=o.slice(0,o.length-1),n.pathname=o.slice(1).join("/")+"/")}if(n.hostname&&(n.hostname=n.hostname.replace(/\.$/,""),e.stripWWW&&/^www\.(?!www\.)(?:[a-z\-\d]{1,63})\.(?:[a-z.\-\d]{2,63})$/.test(n.hostname)&&(n.hostname=n.hostname.replace(/^www\./,""))),Array.isArray(e.removeQueryParameters))for(let o of[...n.searchParams.keys()])Aae(o,e.removeQueryParameters)&&n.searchParams.delete(o);e.removeQueryParameters===!0&&(n.search=""),e.sortQueryParameters&&n.searchParams.sort(),e.removeTrailingSlash&&(n.pathname=n.pathname.replace(/\/$/,""));let s=r;return r=n.toString(),!e.removeSingleSlash&&n.pathname==="/"&&!s.endsWith("/")&&n.hash===""&&(r=r.replace(/\/$/,"")),(e.removeTrailingSlash||n.pathname==="/")&&n.hash===""&&e.removeSingleSlash&&(r=r.replace(/\/$/,"")),t&&!e.normalizeProtocol&&(r=r.replace(/^http:\/\//,"//")),e.stripProtocol&&(r=r.replace(/^(?:https?:)?\/\//,"")),r};aae.exports=nWe});var uae=w((KEt,cae)=>{"use strict";var sWe=typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?function(r){return typeof r}:function(r){return r&&typeof Symbol=="function"&&r.constructor===Symbol&&r!==Symbol.prototype?"symbol":typeof r},oWe=oae(),aWe=lae();function AWe(r){var e=arguments.length>1&&arguments[1]!==void 0?arguments[1]:!1;if(typeof r!="string"||!r.trim())throw new Error("Invalid url.");e&&((typeof e=="undefined"?"undefined":sWe(e))!=="object"&&(e={stripHash:!1}),r=aWe(r,e));var t=oWe(r);return t}cae.exports=AWe});var hae=w((UEt,gae)=>{"use strict";var lWe=uae(),fae=RN();function cWe(r){var e=lWe(r);e.token="";var t=e.user.split(":");return t.length===2&&(t[1]==="x-oauth-basic"?e.token=t[0]:t[0]==="x-token-auth"&&(e.token=t[1])),fae(e.protocols)||fae(r)?e.protocol="ssh":e.protocols.length?e.protocol=e.protocols[0]:e.protocol="file",e.href=e.href.replace(/\/$/,""),e}gae.exports=cWe});var dae=w((HEt,pae)=>{"use strict";var uWe=hae();function FN(r){if(typeof r!="string")throw new Error("The url must be a string.");var e=uWe(r),t=e.resource.split("."),i=null;switch(e.toString=function(l){return FN.stringify(this,l)},e.source=t.length>2?t.slice(1-t.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=t[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}FN.stringify=function(r,e){e=e||(r.protocols&&r.protocols.length?r.protocols.join("+"):r.protocol);var t=r.port?":"+r.port:"",i=r.user||"git",n=r.git_suffix?".git":"";switch(e){case"ssh":return t?"ssh://"+i+"@"+r.resource+t+"/"+r.full_name+n:i+"@"+r.resource+":"+r.full_name+n;case"git+ssh":case"ssh+git":case"ftp":case"ftps":return e+"://"+i+"@"+r.resource+t+"/"+r.full_name+n;case"http":case"https":var s=r.token?gWe(r):r.user&&(r.protocols.includes("http")||r.protocols.includes("https"))?r.user+"@":"";return e+"://"+s+r.resource+t+"/"+r.full_name+n;default:return r.href}};function gWe(r){switch(r.source){case"bitbucket.org":return"x-token-auth:"+r.token+"@";default:return r.token+"@"}}pae.exports=FN});var cL=w((Vwt,Mae)=>{var DWe=Nf(),RWe=Pf();function FWe(r,e,t){(t!==void 0&&!RWe(r[e],t)||t===void 0&&!(e in r))&&DWe(r,e,t)}Mae.exports=FWe});var Uae=w((Xwt,Kae)=>{var NWe=vC(),LWe=ta();function TWe(r){return LWe(r)&&NWe(r)}Kae.exports=TWe});var Gae=w((Zwt,Hae)=>{var OWe=Wc(),MWe=G0(),KWe=ta(),UWe="[object Object]",HWe=Function.prototype,jWe=Object.prototype,jae=HWe.toString,GWe=jWe.hasOwnProperty,YWe=jae.call(Object);function qWe(r){if(!KWe(r)||OWe(r)!=UWe)return!1;var e=MWe(r);if(e===null)return!0;var t=GWe.call(e,"constructor")&&e.constructor;return typeof t=="function"&&t instanceof t&&jae.call(t)==YWe}Hae.exports=qWe});var uL=w(($wt,Yae)=>{function JWe(r,e){if(!(e==="constructor"&&typeof r[e]=="function")&&e!="__proto__")return r[e]}Yae.exports=JWe});var Jae=w((eBt,qae)=>{var WWe=Zf(),zWe=$f();function _We(r){return WWe(r,zWe(r))}qae.exports=_We});var Zae=w((tBt,Wae)=>{var zae=cL(),VWe=hN(),XWe=CN(),ZWe=pN(),$We=mN(),_ae=dC(),Vae=Ks(),e4e=Uae(),t4e=bC(),r4e=VB(),i4e=Rn(),n4e=Gae(),s4e=g0(),Xae=uL(),o4e=Jae();function a4e(r,e,t,i,n,s,o){var a=Xae(r,t),l=Xae(e,t),c=o.get(l);if(c){zae(r,t,c);return}var u=s?s(a,l,t+"",r,e,o):void 0,g=u===void 0;if(g){var f=Vae(l),h=!f&&t4e(l),p=!f&&!h&&s4e(l);u=l,f||h||p?Vae(a)?u=a:e4e(a)?u=ZWe(a):h?(g=!1,u=VWe(l,!0)):p?(g=!1,u=XWe(l,!0)):u=[]:n4e(l)||_ae(l)?(u=a,_ae(a)?u=o4e(a):(!i4e(a)||r4e(a))&&(u=$We(l))):g=!1}g&&(o.set(l,u),n(u,l,i,s,o),o.delete(l)),zae(r,t,u)}Wae.exports=a4e});var tAe=w((rBt,$ae)=>{var A4e=xC(),l4e=cL(),c4e=XR(),u4e=Zae(),g4e=Rn(),f4e=$f(),h4e=uL();function eAe(r,e,t,i,n){r!==e&&c4e(e,function(s,o){if(n||(n=new A4e),g4e(s))u4e(r,e,o,t,eAe,i,n);else{var a=i?i(h4e(r,o),s,o+"",r,e,n):void 0;a===void 0&&(a=s),l4e(r,o,a)}},f4e)}$ae.exports=eAe});var iAe=w((iBt,rAe)=>{var p4e=r0(),d4e=RR(),C4e=FR();function m4e(r,e){return C4e(d4e(r,e,p4e),r+"")}rAe.exports=m4e});var sAe=w((nBt,nAe)=>{var E4e=Pf(),I4e=vC(),y4e=pC(),w4e=Rn();function B4e(r,e,t){if(!w4e(t))return!1;var i=typeof e;return(i=="number"?I4e(t)&&y4e(e,t.length):i=="string"&&e in t)?E4e(t[e],r):!1}nAe.exports=B4e});var aAe=w((sBt,oAe)=>{var b4e=iAe(),Q4e=sAe();function S4e(r){return b4e(function(e,t){var i=-1,n=t.length,s=n>1?t[n-1]:void 0,o=n>2?t[2]:void 0;for(s=r.length>3&&typeof s=="function"?(n--,s):void 0,o&&Q4e(t[0],t[1],o)&&(s=n<3?void 0:s,n=1),e=Object(e);++i{var v4e=tAe(),x4e=aAe(),k4e=x4e(function(r,e,t){v4e(r,e,t)});AAe.exports=k4e});var QAe=w((u0t,bAe)=>{var QL;bAe.exports=()=>(typeof QL=="undefined"&&(QL=require("zlib").brotliDecompressSync(Buffer.from("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","base64")).toString()),QL)});var TAe=w((Y0t,LAe)=>{var kL;LAe.exports=()=>(typeof kL=="undefined"&&(kL=require("zlib").brotliDecompressSync(Buffer.from("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","base64")).toString()),kL)});var YAe=w((TL,OL)=>{(function(r){TL&&typeof TL=="object"&&typeof OL!="undefined"?OL.exports=r():typeof define=="function"&&define.amd?define([],r):typeof window!="undefined"?window.isWindows=r():typeof global!="undefined"?global.isWindows=r():typeof self!="undefined"?self.isWindows=r():this.isWindows=r()})(function(){"use strict";return function(){return process&&(process.platform==="win32"||/^(msys|cygwin)$/.test(process.env.OSTYPE))}})});var zAe=w((Vbt,qAe)=>{"use strict";ML.ifExists=C8e;var ah=require("util"),zs=require("path"),JAe=YAe(),m8e=/^#!\s*(?:\/usr\/bin\/env)?\s*([^ \t]+)(.*)$/,E8e={createPwshFile:!0,createCmdFile:JAe(),fs:require("fs")},I8e=new Map([[".js","node"],[".cjs","node"],[".mjs","node"],[".cmd","cmd"],[".bat","cmd"],[".ps1","pwsh"],[".sh","sh"]]);function WAe(r){let e=N(N({},E8e),r),t=e.fs;return e.fs_={chmod:t.chmod?ah.promisify(t.chmod):async()=>{},mkdir:ah.promisify(t.mkdir),readFile:ah.promisify(t.readFile),stat:ah.promisify(t.stat),unlink:ah.promisify(t.unlink),writeFile:ah.promisify(t.writeFile)},e}async function ML(r,e,t){let i=WAe(t);await i.fs_.stat(r),await y8e(r,e,i)}function C8e(r,e,t){return ML(r,e,t).catch(()=>{})}function w8e(r,e){return e.fs_.unlink(r).catch(()=>{})}async function y8e(r,e,t){let i=await Q8e(r,t);return await B8e(e,t),b8e(r,e,i,t)}function B8e(r,e){return e.fs_.mkdir(zs.dirname(r),{recursive:!0})}function b8e(r,e,t,i){let n=WAe(i),s=[{generator:x8e,extension:""}];return n.createCmdFile&&s.push({generator:v8e,extension:".cmd"}),n.createPwshFile&&s.push({generator:k8e,extension:".ps1"}),Promise.all(s.map(o=>S8e(r,e+o.extension,t,o.generator,n)))}function P8e(r,e){return w8e(r,e)}function R8e(r,e){return D8e(r,e)}async function Q8e(r,e){let n=(await e.fs_.readFile(r,"utf8")).trim().split(/\r*\n/)[0].match(m8e);if(!n){let s=zs.extname(r).toLowerCase();return{program:I8e.get(s)||null,additionalArgs:""}}return{program:n[1],additionalArgs:n[2]}}async function S8e(r,e,t,i,n){let s=n.preserveSymlinks?"--preserve-symlinks":"",o=[t.additionalArgs,s].filter(a=>a).join(" ");return n=Object.assign({},n,{prog:t.program,args:o}),await P8e(e,n),await n.fs_.writeFile(e,i(r,e,n),"utf8"),R8e(e,n)}function v8e(r,e,t){let n=zs.relative(zs.dirname(e),r).split("/").join("\\"),s=zs.isAbsolute(n)?`"${n}"`:`"%~dp0\\${n}"`,o,a=t.prog,l=t.args||"",c=KL(t.nodePath).win32;a?(o=`"%~dp0\\${a}.exe"`,n=s):(a=s,l="",n="");let u=t.progArgs?`${t.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 x8e(r,e,t){let i=zs.relative(zs.dirname(e),r),n=t.prog&&t.prog.split("\\").join("/"),s;i=i.split("\\").join("/");let o=zs.isAbsolute(i)?`"${i}"`:`"$basedir/${i}"`,a=t.args||"",l=KL(t.nodePath).posix;n?(s=`"$basedir/${t.prog}"`,i=o):(n=o,a="",i="");let c=t.progArgs?`${t.progArgs.join(" ")} `:"",u=`#!/bin/sh -basedir=$(dirname "$(echo "$0" | sed -e 's,\\\\,/,g')") - -case \`uname\` in - *CYGWIN*) basedir=\`cygpath -w "$basedir"\`;; -esac - -`,g=t.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 k8e(r,e,t){let i=zs.relative(zs.dirname(e),r),n=t.prog&&t.prog.split("\\").join("/"),s=n&&`"${n}$exe"`,o;i=i.split("\\").join("/");let a=zs.isAbsolute(i)?`"${i}"`:`"$basedir/${i}"`,l=t.args||"",c=KL(t.nodePath),u=c.win32,g=c.posix;s?(o=`"$basedir/${t.prog}$exe"`,i=a):(s=a,l="",i="");let f=t.progArgs?`${t.progArgs.join(" ")} `:"",h=`#!/usr/bin/env pwsh -$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent - -$exe="" -${t.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 t.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 -} -${t.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 -} -${t.nodePath?`$env:NODE_PATH=$env_node_path -`:""}exit $LASTEXITCODE -`,h}function D8e(r,e){return e.fs_.chmod(r,493)}function KL(r){if(!r)return{win32:"",posix:""};let e=typeof r=="string"?r.split(zs.delimiter):Array.from(r),t={};for(let i=0;i`/mnt/${a.toLowerCase()}`):e[i];t.win32=t.win32?`${t.win32};${n}`:n,t.posix=t.posix?`${t.posix}:${s}`:s,t[i]={win32:n,posix:s}}return t}qAe.exports=ML});var eT=w((RSt,hle)=>{hle.exports=require("stream")});var mle=w((FSt,ple)=>{"use strict";function dle(r,e){var t=Object.keys(r);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(r);e&&(i=i.filter(function(n){return Object.getOwnPropertyDescriptor(r,n).enumerable})),t.push.apply(t,i)}return t}function Z8e(r){for(var e=1;e0?this.tail.next=i:this.head=i,this.tail=i,++this.length}},{key:"unshift",value:function(t){var i={data:t,next:this.head};this.length===0&&(this.tail=i),this.head=i,++this.length}},{key:"shift",value:function(){if(this.length!==0){var t=this.head.data;return this.length===1?this.head=this.tail=null:this.head=this.head.next,--this.length,t}}},{key:"clear",value:function(){this.head=this.tail=null,this.length=0}},{key:"join",value:function(t){if(this.length===0)return"";for(var i=this.head,n=""+i.data;i=i.next;)n+=t+i.data;return n}},{key:"concat",value:function(t){if(this.length===0)return lb.alloc(0);for(var i=lb.allocUnsafe(t>>>0),n=this.head,s=0;n;)nze(n.data,i,s),s+=n.data.length,n=n.next;return i}},{key:"consume",value:function(t,i){var n;return to.length?o.length:t;if(a===o.length?s+=o:s+=o.slice(0,t),t-=a,t===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(t){var i=lb.allocUnsafe(t),n=this.head,s=1;for(n.data.copy(i),t-=n.data.length;n=n.next;){var o=n.data,a=t>o.length?o.length:t;if(o.copy(i,i.length-t,0,a),t-=a,t===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:ize,value:function(t,i){return tT(this,Z8e({},i,{depth:0,customInspect:!1}))}}]),r}()});var iT=w((NSt,Ele)=>{"use strict";function sze(r,e){var t=this,i=this._readableState&&this._readableState.destroyed,n=this._writableState&&this._writableState.destroyed;return i||n?(e?e(r):r&&(this._writableState?this._writableState.errorEmitted||(this._writableState.errorEmitted=!0,process.nextTick(rT,this,r)):process.nextTick(rT,this,r)),this):(this._readableState&&(this._readableState.destroyed=!0),this._writableState&&(this._writableState.destroyed=!0),this._destroy(r||null,function(s){!e&&s?t._writableState?t._writableState.errorEmitted?process.nextTick(cb,t):(t._writableState.errorEmitted=!0,process.nextTick(Ile,t,s)):process.nextTick(Ile,t,s):e?(process.nextTick(cb,t),e(s)):process.nextTick(cb,t)}),this)}function Ile(r,e){rT(r,e),cb(r)}function cb(r){r._writableState&&!r._writableState.emitClose||r._readableState&&!r._readableState.emitClose||r.emit("close")}function oze(){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(r,e){r.emit("error",e)}function aze(r,e){var t=r._readableState,i=r._writableState;t&&t.autoDestroy||i&&i.autoDestroy?r.destroy(e):r.emit("error",e)}Ele.exports={destroy:sze,undestroy:oze,errorOrDestroy:aze}});var Ul=w((LSt,yle)=>{"use strict";var wle={};function _s(r,e,t){t||(t=Error);function i(s,o,a){return typeof e=="string"?e:e(s,o,a)}class n extends t{constructor(o,a,l){super(i(o,a,l))}}n.prototype.name=t.name,n.prototype.code=r,wle[r]=n}function Ble(r,e){if(Array.isArray(r)){let t=r.length;return r=r.map(i=>String(i)),t>2?`one of ${e} ${r.slice(0,t-1).join(", ")}, or `+r[t-1]:t===2?`one of ${e} ${r[0]} or ${r[1]}`:`of ${e} ${r[0]}`}else return`of ${e} ${String(r)}`}function Aze(r,e,t){return r.substr(!t||t<0?0:+t,e.length)===e}function lze(r,e,t){return(t===void 0||t>r.length)&&(t=r.length),r.substring(t-e.length,t)===e}function cze(r,e,t){return typeof t!="number"&&(t=0),t+e.length>r.length?!1:r.indexOf(e,t)!==-1}_s("ERR_INVALID_OPT_VALUE",function(r,e){return'The value "'+e+'" is invalid for option "'+r+'"'},TypeError);_s("ERR_INVALID_ARG_TYPE",function(r,e,t){let i;typeof e=="string"&&Aze(e,"not ")?(i="must not be",e=e.replace(/^not /,"")):i="must be";let n;if(lze(r," argument"))n=`The ${r} ${i} ${Ble(e,"type")}`;else{let s=cze(r,".")?"property":"argument";n=`The "${r}" ${s} ${i} ${Ble(e,"type")}`}return n+=`. Received type ${typeof t}`,n},TypeError);_s("ERR_STREAM_PUSH_AFTER_EOF","stream.push() after EOF");_s("ERR_METHOD_NOT_IMPLEMENTED",function(r){return"The "+r+" method is not implemented"});_s("ERR_STREAM_PREMATURE_CLOSE","Premature close");_s("ERR_STREAM_DESTROYED",function(r){return"Cannot call "+r+" after a stream was destroyed"});_s("ERR_MULTIPLE_CALLBACK","Callback called multiple times");_s("ERR_STREAM_CANNOT_PIPE","Cannot pipe, not readable");_s("ERR_STREAM_WRITE_AFTER_END","write after end");_s("ERR_STREAM_NULL_VALUES","May not write null values to stream",TypeError);_s("ERR_UNKNOWN_ENCODING",function(r){return"Unknown encoding: "+r},TypeError);_s("ERR_STREAM_UNSHIFT_AFTER_END_EVENT","stream.unshift() after end event");yle.exports.codes=wle});var nT=w((TSt,ble)=>{"use strict";var uze=Ul().codes.ERR_INVALID_OPT_VALUE;function gze(r,e,t){return r.highWaterMark!=null?r.highWaterMark:e?r[t]:null}function fze(r,e,t,i){var n=gze(e,i,t);if(n!=null){if(!(isFinite(n)&&Math.floor(n)===n)||n<0){var s=i?t:"highWaterMark";throw new uze(s,n)}return Math.floor(n)}return r.objectMode?16:16*1024}ble.exports={getHighWaterMark:fze}});var Qle=w((OSt,sT)=>{typeof Object.create=="function"?sT.exports=function(e,t){t&&(e.super_=t,e.prototype=Object.create(t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}))}:sT.exports=function(e,t){if(t){e.super_=t;var i=function(){};i.prototype=t.prototype,e.prototype=new i,e.prototype.constructor=e}}});var Hl=w((MSt,oT)=>{try{if(aT=require("util"),typeof aT.inherits!="function")throw"";oT.exports=aT.inherits}catch(r){oT.exports=Qle()}var aT});var vle=w((KSt,Sle)=>{Sle.exports=require("util").deprecate});var cT=w((USt,xle)=>{"use strict";xle.exports=Gr;function kle(r){var e=this;this.next=null,this.entry=null,this.finish=function(){hze(e,r)}}var ch;Gr.WritableState=Gm;var pze={deprecate:vle()},Ple=eT(),ub=require("buffer").Buffer,dze=global.Uint8Array||function(){};function Cze(r){return ub.from(r)}function mze(r){return ub.isBuffer(r)||r instanceof dze}var AT=iT(),Eze=nT(),Ize=Eze.getHighWaterMark,jl=Ul().codes,yze=jl.ERR_INVALID_ARG_TYPE,wze=jl.ERR_METHOD_NOT_IMPLEMENTED,Bze=jl.ERR_MULTIPLE_CALLBACK,bze=jl.ERR_STREAM_CANNOT_PIPE,Qze=jl.ERR_STREAM_DESTROYED,Sze=jl.ERR_STREAM_NULL_VALUES,vze=jl.ERR_STREAM_WRITE_AFTER_END,xze=jl.ERR_UNKNOWN_ENCODING,uh=AT.errorOrDestroy;Hl()(Gr,Ple);function kze(){}function Gm(r,e,t){ch=ch||ku(),r=r||{},typeof t!="boolean"&&(t=e instanceof ch),this.objectMode=!!r.objectMode,t&&(this.objectMode=this.objectMode||!!r.writableObjectMode),this.highWaterMark=Ize(this,r,"writableHighWaterMark",t),this.finalCalled=!1,this.needDrain=!1,this.ending=!1,this.ended=!1,this.finished=!1,this.destroyed=!1;var i=r.decodeStrings===!1;this.decodeStrings=!i,this.defaultEncoding=r.defaultEncoding||"utf8",this.length=0,this.writing=!1,this.corked=0,this.sync=!0,this.bufferProcessing=!1,this.onwrite=function(n){Pze(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=r.emitClose!==!1,this.autoDestroy=!!r.autoDestroy,this.bufferedRequestCount=0,this.corkedRequestsFree=new kle(this)}Gm.prototype.getBuffer=function(){for(var e=this.bufferedRequest,t=[];e;)t.push(e),e=e.next;return t};(function(){try{Object.defineProperty(Gm.prototype,"buffer",{get:pze.deprecate(function(){return this.getBuffer()},"_writableState.buffer is deprecated. Use _writableState.getBuffer instead.","DEP0003")})}catch(r){}})();var gb;typeof Symbol=="function"&&Symbol.hasInstance&&typeof Function.prototype[Symbol.hasInstance]=="function"?(gb=Function.prototype[Symbol.hasInstance],Object.defineProperty(Gr,Symbol.hasInstance,{value:function(e){return gb.call(this,e)?!0:this!==Gr?!1:e&&e._writableState instanceof Gm}})):gb=function(e){return e instanceof this};function Gr(r){ch=ch||ku();var e=this instanceof ch;if(!e&&!gb.call(Gr,this))return new Gr(r);this._writableState=new Gm(r,this,e),this.writable=!0,r&&(typeof r.write=="function"&&(this._write=r.write),typeof r.writev=="function"&&(this._writev=r.writev),typeof r.destroy=="function"&&(this._destroy=r.destroy),typeof r.final=="function"&&(this._final=r.final)),Ple.call(this)}Gr.prototype.pipe=function(){uh(this,new bze)};function Dze(r,e){var t=new vze;uh(r,t),process.nextTick(e,t)}function Rze(r,e,t,i){var n;return t===null?n=new Sze:typeof t!="string"&&!e.objectMode&&(n=new yze("chunk",["string","Buffer"],t)),n?(uh(r,n),process.nextTick(i,n),!1):!0}Gr.prototype.write=function(r,e,t){var i=this._writableState,n=!1,s=!i.objectMode&&mze(r);return s&&!ub.isBuffer(r)&&(r=Cze(r)),typeof e=="function"&&(t=e,e=null),s?e="buffer":e||(e=i.defaultEncoding),typeof t!="function"&&(t=kze),i.ending?Dze(this,t):(s||Rze(this,i,r,t))&&(i.pendingcb++,n=Fze(this,i,s,r,e,t)),n};Gr.prototype.cork=function(){this._writableState.corked++};Gr.prototype.uncork=function(){var r=this._writableState;r.corked&&(r.corked--,!r.writing&&!r.corked&&!r.bufferProcessing&&r.bufferedRequest&&Dle(this,r))};Gr.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 xze(e);return this._writableState.defaultEncoding=e,this};Object.defineProperty(Gr.prototype,"writableBuffer",{enumerable:!1,get:function(){return this._writableState&&this._writableState.getBuffer()}});function Nze(r,e,t){return!r.objectMode&&r.decodeStrings!==!1&&typeof e=="string"&&(e=ub.from(e,t)),e}Object.defineProperty(Gr.prototype,"writableHighWaterMark",{enumerable:!1,get:function(){return this._writableState.highWaterMark}});function Fze(r,e,t,i,n,s){if(!t){var o=Nze(e,i,n);i!==o&&(t=!0,n="buffer",i=o)}var a=e.objectMode?1:i.length;e.length+=a;var l=e.length{"use strict";var Hze=Object.keys||function(r){var e=[];for(var t in r)e.push(t);return e};Nle.exports=Ea;var Lle=uT(),gT=cT();Hl()(Ea,Lle);for(fT=Hze(gT.prototype),fb=0;fb{var pb=require("buffer"),vA=pb.Buffer;function Ole(r,e){for(var t in r)e[t]=r[t]}vA.from&&vA.alloc&&vA.allocUnsafe&&vA.allocUnsafeSlow?Tle.exports=pb:(Ole(pb,hT),hT.Buffer=gh);function gh(r,e,t){return vA(r,e,t)}Ole(vA,gh);gh.from=function(r,e,t){if(typeof r=="number")throw new TypeError("Argument must not be a number");return vA(r,e,t)};gh.alloc=function(r,e,t){if(typeof r!="number")throw new TypeError("Argument must be a number");var i=vA(r);return e!==void 0?typeof t=="string"?i.fill(e,t):i.fill(e):i.fill(0),i};gh.allocUnsafe=function(r){if(typeof r!="number")throw new TypeError("Argument must be a number");return vA(r)};gh.allocUnsafeSlow=function(r){if(typeof r!="number")throw new TypeError("Argument must be a number");return pb.SlowBuffer(r)}});var CT=w(Kle=>{"use strict";var pT=Mle().Buffer,Ule=pT.isEncoding||function(r){switch(r=""+r,r&&r.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 Yze(r){if(!r)return"utf8";for(var e;;)switch(r){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 r;default:if(e)return;r=(""+r).toLowerCase(),e=!0}}function qze(r){var e=Yze(r);if(typeof e!="string"&&(pT.isEncoding===Ule||!Ule(r)))throw new Error("Unknown encoding: "+r);return e||r}Kle.StringDecoder=qm;function qm(r){this.encoding=qze(r);var e;switch(this.encoding){case"utf16le":this.text=Wze,this.end=zze,e=4;break;case"utf8":this.fillLast=Jze,e=4;break;case"base64":this.text=_ze,this.end=Vze,e=3;break;default:this.write=Xze,this.end=Zze;return}this.lastNeed=0,this.lastTotal=0,this.lastChar=pT.allocUnsafe(e)}qm.prototype.write=function(r){if(r.length===0)return"";var e,t;if(this.lastNeed){if(e=this.fillLast(r),e===void 0)return"";t=this.lastNeed,this.lastNeed=0}else t=0;return t>5==6?2:r>>4==14?3:r>>3==30?4:r>>6==2?-1:-2}function t5e(r,e,t){var i=e.length-1;if(i=0?(n>0&&(r.lastNeed=n-1),n):--i=0?(n>0&&(r.lastNeed=n-2),n):--i=0?(n>0&&(n===2?n=0:r.lastNeed=n-3),n):0))}function r5e(r,e,t){if((e[0]&192)!=128)return r.lastNeed=0,"\uFFFD";if(r.lastNeed>1&&e.length>1){if((e[1]&192)!=128)return r.lastNeed=1,"\uFFFD";if(r.lastNeed>2&&e.length>2&&(e[2]&192)!=128)return r.lastNeed=2,"\uFFFD"}}function Jze(r){var e=this.lastTotal-this.lastNeed,t=r5e(this,r,e);if(t!==void 0)return t;if(this.lastNeed<=r.length)return r.copy(this.lastChar,e,0,this.lastNeed),this.lastChar.toString(this.encoding,0,this.lastTotal);r.copy(this.lastChar,e,0,r.length),this.lastNeed-=r.length}function e5e(r,e){var t=t5e(this,r,e);if(!this.lastNeed)return r.toString("utf8",e);this.lastTotal=t;var i=r.length-(t-this.lastNeed);return r.copy(this.lastChar,0,i),r.toString("utf8",e,i)}function $ze(r){var e=r&&r.length?this.write(r):"";return this.lastNeed?e+"\uFFFD":e}function Wze(r,e){if((r.length-e)%2==0){var t=r.toString("utf16le",e);if(t){var i=t.charCodeAt(t.length-1);if(i>=55296&&i<=56319)return this.lastNeed=2,this.lastTotal=4,this.lastChar[0]=r[r.length-2],this.lastChar[1]=r[r.length-1],t.slice(0,-1)}return t}return this.lastNeed=1,this.lastTotal=2,this.lastChar[0]=r[r.length-1],r.toString("utf16le",e,r.length-1)}function zze(r){var e=r&&r.length?this.write(r):"";if(this.lastNeed){var t=this.lastTotal-this.lastNeed;return e+this.lastChar.toString("utf16le",0,t)}return e}function _ze(r,e){var t=(r.length-e)%3;return t===0?r.toString("base64",e):(this.lastNeed=3-t,this.lastTotal=3,t===1?this.lastChar[0]=r[r.length-1]:(this.lastChar[0]=r[r.length-2],this.lastChar[1]=r[r.length-1]),r.toString("base64",e,r.length-t))}function Vze(r){var e=r&&r.length?this.write(r):"";return this.lastNeed?e+this.lastChar.toString("base64",0,3-this.lastNeed):e}function Xze(r){return r.toString(this.encoding)}function Zze(r){return r&&r.length?this.write(r):""}});var db=w((GSt,Hle)=>{"use strict";var jle=Ul().codes.ERR_STREAM_PREMATURE_CLOSE;function i5e(r){var e=!1;return function(){if(!e){e=!0;for(var t=arguments.length,i=new Array(t),n=0;n{"use strict";var Cb;function Gl(r,e,t){return e in r?Object.defineProperty(r,e,{value:t,enumerable:!0,configurable:!0,writable:!0}):r[e]=t,r}var o5e=db(),Yl=Symbol("lastResolve"),Pu=Symbol("lastReject"),Jm=Symbol("error"),mb=Symbol("ended"),Du=Symbol("lastPromise"),mT=Symbol("handlePromise"),Ru=Symbol("stream");function ql(r,e){return{value:r,done:e}}function a5e(r){var e=r[Yl];if(e!==null){var t=r[Ru].read();t!==null&&(r[Du]=null,r[Yl]=null,r[Pu]=null,e(ql(t,!1)))}}function A5e(r){process.nextTick(a5e,r)}function l5e(r,e){return function(t,i){r.then(function(){if(e[mb]){t(ql(void 0,!0));return}e[mT](t,i)},i)}}var c5e=Object.getPrototypeOf(function(){}),u5e=Object.setPrototypeOf((Cb={get stream(){return this[Ru]},next:function(){var e=this,t=this[Jm];if(t!==null)return Promise.reject(t);if(this[mb])return Promise.resolve(ql(void 0,!0));if(this[Ru].destroyed)return new Promise(function(o,a){process.nextTick(function(){e[Jm]?a(e[Jm]):o(ql(void 0,!0))})});var i=this[Du],n;if(i)n=new Promise(l5e(i,this));else{var s=this[Ru].read();if(s!==null)return Promise.resolve(ql(s,!1));n=new Promise(this[mT])}return this[Du]=n,n}},Gl(Cb,Symbol.asyncIterator,function(){return this}),Gl(Cb,"return",function(){var e=this;return new Promise(function(t,i){e[Ru].destroy(null,function(n){if(n){i(n);return}t(ql(void 0,!0))})})}),Cb),c5e),g5e=function(e){var t,i=Object.create(u5e,(t={},Gl(t,Ru,{value:e,writable:!0}),Gl(t,Yl,{value:null,writable:!0}),Gl(t,Pu,{value:null,writable:!0}),Gl(t,Jm,{value:null,writable:!0}),Gl(t,mb,{value:e._readableState.endEmitted,writable:!0}),Gl(t,mT,{value:function(s,o){var a=i[Ru].read();a?(i[Du]=null,i[Yl]=null,i[Pu]=null,s(ql(a,!1))):(i[Yl]=s,i[Pu]=o)},writable:!0}),t));return i[Du]=null,o5e(e,function(n){if(n&&n.code!=="ERR_STREAM_PREMATURE_CLOSE"){var s=i[Pu];s!==null&&(i[Du]=null,i[Yl]=null,i[Pu]=null,s(n)),i[Jm]=n;return}var o=i[Yl];o!==null&&(i[Du]=null,i[Yl]=null,i[Pu]=null,o(ql(void 0,!0))),i[mb]=!0}),e.on("readable",A5e.bind(null,i)),i};Yle.exports=g5e});var _le=w((qSt,Jle)=>{"use strict";function Wle(r,e,t,i,n,s,o){try{var a=r[s](o),l=a.value}catch(c){t(c);return}a.done?e(l):Promise.resolve(l).then(i,n)}function f5e(r){return function(){var e=this,t=arguments;return new Promise(function(i,n){var s=r.apply(e,t);function o(l){Wle(s,i,n,o,a,"next",l)}function a(l){Wle(s,i,n,o,a,"throw",l)}o(void 0)})}}function zle(r,e){var t=Object.keys(r);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(r);e&&(i=i.filter(function(n){return Object.getOwnPropertyDescriptor(r,n).enumerable})),t.push.apply(t,i)}return t}function p5e(r){for(var e=1;e{"use strict";Vle.exports=Ut;var fh;Ut.ReadableState=Xle;var JSt=require("events").EventEmitter,Zle=function(e,t){return e.listeners(t).length},Wm=eT(),Eb=require("buffer").Buffer,m5e=global.Uint8Array||function(){};function E5e(r){return Eb.from(r)}function I5e(r){return Eb.isBuffer(r)||r instanceof m5e}var ET=require("util"),Pt;ET&&ET.debuglog?Pt=ET.debuglog("stream"):Pt=function(){};var y5e=mle(),IT=iT(),w5e=nT(),B5e=w5e.getHighWaterMark,Ib=Ul().codes,b5e=Ib.ERR_INVALID_ARG_TYPE,Q5e=Ib.ERR_STREAM_PUSH_AFTER_EOF,S5e=Ib.ERR_METHOD_NOT_IMPLEMENTED,v5e=Ib.ERR_STREAM_UNSHIFT_AFTER_END_EVENT,hh,yT,wT;Hl()(Ut,Wm);var zm=IT.errorOrDestroy,BT=["error","close","destroy","pause","resume"];function x5e(r,e,t){if(typeof r.prependListener=="function")return r.prependListener(e,t);!r._events||!r._events[e]?r.on(e,t):Array.isArray(r._events[e])?r._events[e].unshift(t):r._events[e]=[t,r._events[e]]}function Xle(r,e,t){fh=fh||ku(),r=r||{},typeof t!="boolean"&&(t=e instanceof fh),this.objectMode=!!r.objectMode,t&&(this.objectMode=this.objectMode||!!r.readableObjectMode),this.highWaterMark=B5e(this,r,"readableHighWaterMark",t),this.buffer=new y5e,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=r.emitClose!==!1,this.autoDestroy=!!r.autoDestroy,this.destroyed=!1,this.defaultEncoding=r.defaultEncoding||"utf8",this.awaitDrain=0,this.readingMore=!1,this.decoder=null,this.encoding=null,r.encoding&&(hh||(hh=CT().StringDecoder),this.decoder=new hh(r.encoding),this.encoding=r.encoding)}function Ut(r){if(fh=fh||ku(),!(this instanceof Ut))return new Ut(r);var e=this instanceof fh;this._readableState=new Xle(r,this,e),this.readable=!0,r&&(typeof r.read=="function"&&(this._read=r.read),typeof r.destroy=="function"&&(this._destroy=r.destroy)),Wm.call(this)}Object.defineProperty(Ut.prototype,"destroyed",{enumerable:!1,get:function(){return this._readableState===void 0?!1:this._readableState.destroyed},set:function(e){!this._readableState||(this._readableState.destroyed=e)}});Ut.prototype.destroy=IT.destroy;Ut.prototype._undestroy=IT.undestroy;Ut.prototype._destroy=function(r,e){e(r)};Ut.prototype.push=function(r,e){var t=this._readableState,i;return t.objectMode?i=!0:typeof r=="string"&&(e=e||t.defaultEncoding,e!==t.encoding&&(r=Eb.from(r,e),e=""),i=!0),$le(this,r,e,!1,i)};Ut.prototype.unshift=function(r){return $le(this,r,null,!0,!1)};function $le(r,e,t,i,n){Pt("readableAddChunk",e);var s=r._readableState;if(e===null)s.reading=!1,P5e(r,s);else{var o;if(n||(o=k5e(s,e)),o)zm(r,o);else if(s.objectMode||e&&e.length>0)if(typeof e!="string"&&!s.objectMode&&Object.getPrototypeOf(e)!==Eb.prototype&&(e=E5e(e)),i)s.endEmitted?zm(r,new v5e):bT(r,s,e,!0);else if(s.ended)zm(r,new Q5e);else{if(s.destroyed)return!1;s.reading=!1,s.decoder&&!t?(e=s.decoder.write(e),s.objectMode||e.length!==0?bT(r,s,e,!1):QT(r,s)):bT(r,s,e,!1)}else i||(s.reading=!1,QT(r,s))}return!s.ended&&(s.length=ece?r=ece:(r--,r|=r>>>1,r|=r>>>2,r|=r>>>4,r|=r>>>8,r|=r>>>16,r++),r}function tce(r,e){return r<=0||e.length===0&&e.ended?0:e.objectMode?1:r!==r?e.flowing&&e.length?e.buffer.head.data.length:e.length:(r>e.highWaterMark&&(e.highWaterMark=D5e(r)),r<=e.length?r:e.ended?e.length:(e.needReadable=!0,0))}Ut.prototype.read=function(r){Pt("read",r),r=parseInt(r,10);var e=this._readableState,t=r;if(r!==0&&(e.emittedReadable=!1),r===0&&e.needReadable&&((e.highWaterMark!==0?e.length>=e.highWaterMark:e.length>0)||e.ended))return Pt("read: emitReadable",e.length,e.ended),e.length===0&&e.ended?ST(this):yb(this),null;if(r=tce(r,e),r===0&&e.ended)return e.length===0&&ST(this),null;var i=e.needReadable;Pt("need readable",i),(e.length===0||e.length-r0?n=rce(r,e):n=null,n===null?(e.needReadable=e.length<=e.highWaterMark,r=0):(e.length-=r,e.awaitDrain=0),e.length===0&&(e.ended||(e.needReadable=!0),t!==r&&e.ended&&ST(this)),n!==null&&this.emit("data",n),n};function P5e(r,e){if(Pt("onEofChunk"),!e.ended){if(e.decoder){var t=e.decoder.end();t&&t.length&&(e.buffer.push(t),e.length+=e.objectMode?1:t.length)}e.ended=!0,e.sync?yb(r):(e.needReadable=!1,e.emittedReadable||(e.emittedReadable=!0,ice(r)))}}function yb(r){var e=r._readableState;Pt("emitReadable",e.needReadable,e.emittedReadable),e.needReadable=!1,e.emittedReadable||(Pt("emitReadable",e.flowing),e.emittedReadable=!0,process.nextTick(ice,r))}function ice(r){var e=r._readableState;Pt("emitReadable_",e.destroyed,e.length,e.ended),!e.destroyed&&(e.length||e.ended)&&(r.emit("readable"),e.emittedReadable=!1),e.needReadable=!e.flowing&&!e.ended&&e.length<=e.highWaterMark,vT(r)}function QT(r,e){e.readingMore||(e.readingMore=!0,process.nextTick(R5e,r,e))}function R5e(r,e){for(;!e.reading&&!e.ended&&(e.length1&&nce(i.pipes,r)!==-1)&&!c&&(Pt("false write response, pause",i.awaitDrain),i.awaitDrain++),t.pause())}function f(y){Pt("onerror",y),m(),r.removeListener("error",f),Zle(r,"error")===0&&zm(r,y)}x5e(r,"error",f);function h(){r.removeListener("finish",p),m()}r.once("close",h);function p(){Pt("onfinish"),r.removeListener("close",h),m()}r.once("finish",p);function m(){Pt("unpipe"),t.unpipe(r)}return r.emit("pipe",t),i.flowing||(Pt("pipe resume"),t.resume()),r};function F5e(r){return function(){var t=r._readableState;Pt("pipeOnDrain",t.awaitDrain),t.awaitDrain&&t.awaitDrain--,t.awaitDrain===0&&Zle(r,"data")&&(t.flowing=!0,vT(r))}}Ut.prototype.unpipe=function(r){var e=this._readableState,t={hasUnpiped:!1};if(e.pipesCount===0)return this;if(e.pipesCount===1)return r&&r!==e.pipes?this:(r||(r=e.pipes),e.pipes=null,e.pipesCount=0,e.flowing=!1,r&&r.emit("unpipe",this,t),this);if(!r){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()):r==="readable"&&!i.endEmitted&&!i.readableListening&&(i.readableListening=i.needReadable=!0,i.flowing=!1,i.emittedReadable=!1,Pt("on readable",i.length,i.reading),i.length?yb(this):i.reading||process.nextTick(N5e,this)),t};Ut.prototype.addListener=Ut.prototype.on;Ut.prototype.removeListener=function(r,e){var t=Wm.prototype.removeListener.call(this,r,e);return r==="readable"&&process.nextTick(sce,this),t};Ut.prototype.removeAllListeners=function(r){var e=Wm.prototype.removeAllListeners.apply(this,arguments);return(r==="readable"||r===void 0)&&process.nextTick(sce,this),e};function sce(r){var e=r._readableState;e.readableListening=r.listenerCount("readable")>0,e.resumeScheduled&&!e.paused?e.flowing=!0:r.listenerCount("data")>0&&r.resume()}function N5e(r){Pt("readable nexttick read 0"),r.read(0)}Ut.prototype.resume=function(){var r=this._readableState;return r.flowing||(Pt("resume"),r.flowing=!r.readableListening,L5e(this,r)),r.paused=!1,this};function L5e(r,e){e.resumeScheduled||(e.resumeScheduled=!0,process.nextTick(T5e,r,e))}function T5e(r,e){Pt("resume",e.reading),e.reading||r.read(0),e.resumeScheduled=!1,r.emit("resume"),vT(r),e.flowing&&!e.reading&&r.read(0)}Ut.prototype.pause=function(){return Pt("call pause flowing=%j",this._readableState.flowing),this._readableState.flowing!==!1&&(Pt("pause"),this._readableState.flowing=!1,this.emit("pause")),this._readableState.paused=!0,this};function vT(r){var e=r._readableState;for(Pt("flow",e.flowing);e.flowing&&r.read()!==null;);}Ut.prototype.wrap=function(r){var e=this,t=this._readableState,i=!1;r.on("end",function(){if(Pt("wrapped end"),t.decoder&&!t.ended){var o=t.decoder.end();o&&o.length&&e.push(o)}e.push(null)}),r.on("data",function(o){if(Pt("wrapped data"),t.decoder&&(o=t.decoder.write(o)),!(t.objectMode&&o==null)&&!(!t.objectMode&&(!o||!o.length))){var a=e.push(o);a||(i=!0,r.pause())}});for(var n in r)this[n]===void 0&&typeof r[n]=="function"&&(this[n]=function(a){return function(){return r[a].apply(r,arguments)}}(n));for(var s=0;s=e.length?(e.decoder?t=e.buffer.join(""):e.buffer.length===1?t=e.buffer.first():t=e.buffer.concat(e.length),e.buffer.clear()):t=e.buffer.consume(r,e.decoder),t}function ST(r){var e=r._readableState;Pt("endReadable",e.endEmitted),e.endEmitted||(e.ended=!0,process.nextTick(O5e,e,r))}function O5e(r,e){if(Pt("endReadableNT",r.endEmitted,r.length),!r.endEmitted&&r.length===0&&(r.endEmitted=!0,e.readable=!1,e.emit("end"),r.autoDestroy)){var t=e._writableState;(!t||t.autoDestroy&&t.finished)&&e.destroy()}}typeof Symbol=="function"&&(Ut.from=function(r,e){return wT===void 0&&(wT=_le()),wT(Ut,r,e)});function nce(r,e){for(var t=0,i=r.length;t{"use strict";oce.exports=xA;var wb=Ul().codes,M5e=wb.ERR_METHOD_NOT_IMPLEMENTED,K5e=wb.ERR_MULTIPLE_CALLBACK,U5e=wb.ERR_TRANSFORM_ALREADY_TRANSFORMING,H5e=wb.ERR_TRANSFORM_WITH_LENGTH_0,Bb=ku();Hl()(xA,Bb);function j5e(r,e){var t=this._transformState;t.transforming=!1;var i=t.writecb;if(i===null)return this.emit("error",new K5e);t.writechunk=null,t.writecb=null,e!=null&&this.push(e),i(r);var n=this._readableState;n.reading=!1,(n.needReadable||n.length{"use strict";Ace.exports=_m;var lce=xT();Hl()(_m,lce);function _m(r){if(!(this instanceof _m))return new _m(r);lce.call(this,r)}_m.prototype._transform=function(r,e,t){t(null,r)}});var pce=w((VSt,uce)=>{"use strict";var kT;function Y5e(r){var e=!1;return function(){e||(e=!0,r.apply(void 0,arguments))}}var gce=Ul().codes,q5e=gce.ERR_MISSING_ARGS,J5e=gce.ERR_STREAM_DESTROYED;function fce(r){if(r)throw r}function W5e(r){return r.setHeader&&typeof r.abort=="function"}function z5e(r,e,t,i){i=Y5e(i);var n=!1;r.on("close",function(){n=!0}),kT===void 0&&(kT=db()),kT(r,{readable:e,writable:t},function(o){if(o)return i(o);n=!0,i()});var s=!1;return function(o){if(!n&&!s){if(s=!0,W5e(r))return r.abort();if(typeof r.destroy=="function")return r.destroy();i(o||new J5e("pipe"))}}}function hce(r){r()}function _5e(r,e){return r.pipe(e)}function V5e(r){return!r.length||typeof r[r.length-1]!="function"?fce:r.pop()}function X5e(){for(var r=arguments.length,e=new Array(r),t=0;t0;return z5e(o,l,c,function(u){n||(n=u),u&&s.forEach(hce),!l&&(s.forEach(hce),i(n))})});return e.reduce(_5e)}uce.exports=X5e});var ph=w((Vs,Vm)=>{var Xm=require("stream");process.env.READABLE_STREAM==="disable"&&Xm?(Vm.exports=Xm.Readable,Object.assign(Vm.exports,Xm),Vm.exports.Stream=Xm):(Vs=Vm.exports=uT(),Vs.Stream=Xm||Vs,Vs.Readable=Vs,Vs.Writable=cT(),Vs.Duplex=ku(),Vs.Transform=xT(),Vs.PassThrough=cce(),Vs.finished=db(),Vs.pipeline=pce())});var mce=w((XSt,dce)=>{"use strict";var{Buffer:So}=require("buffer"),Cce=Symbol.for("BufferList");function mr(r){if(!(this instanceof mr))return new mr(r);mr._init.call(this,r)}mr._init=function(e){Object.defineProperty(this,Cce,{value:!0}),this._bufs=[],this.length=0,e&&this.append(e)};mr.prototype._new=function(e){return new mr(e)};mr.prototype._offset=function(e){if(e===0)return[0,0];let t=0;for(let i=0;ithis.length||e<0)return;let t=this._offset(e);return this._bufs[t[0]][t[1]]};mr.prototype.slice=function(e,t){return typeof e=="number"&&e<0&&(e+=this.length),typeof t=="number"&&t<0&&(t+=this.length),this.copy(null,0,e,t)};mr.prototype.copy=function(e,t,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||So.alloc(0);let s=!!e,o=this._offset(i),a=n-i,l=a,c=s&&t||0,u=o[1];if(i===0&&n===this.length){if(!s)return this._bufs.length===1?this._bufs[0]:So.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};mr.prototype.shallowSlice=function(e,t){if(e=e||0,t=typeof t!="number"?this.length:t,e<0&&(e+=this.length),t<0&&(t+=this.length),e===t)return this._new();let i=this._offset(e),n=this._offset(t),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)};mr.prototype.toString=function(e,t,i){return this.slice(t,i).toString(e)};mr.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};mr.prototype.duplicate=function(){let e=this._new();for(let t=0;tthis.length?this.length:e;let i=this._offset(e),n=i[0],s=i[1];for(;n=r.length){let l=o.indexOf(r,s);if(l!==-1)return this._reverseOffset([n,l]);s=o.length-r.length+1}else{let l=this._reverseOffset([n,s]);if(this._match(l,r))return l;s++}s=0}return-1};mr.prototype._match=function(r,e){if(this.length-r{"use strict";var PT=ph().Duplex,Z5e=Hl(),Zm=mce();function Zi(r){if(!(this instanceof Zi))return new Zi(r);if(typeof r=="function"){this._callback=r;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)}),r=null}Zm._init.call(this,r),PT.call(this)}Z5e(Zi,PT);Object.assign(Zi.prototype,Zm.prototype);Zi.prototype._new=function(e){return new Zi(e)};Zi.prototype._write=function(e,t,i){this._appendBuffer(e),typeof i=="function"&&i()};Zi.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)};Zi.prototype.end=function(e){PT.prototype.end.call(this,e),this._callback&&(this._callback(null,this.slice()),this._callback=null)};Zi.prototype._destroy=function(e,t){this._bufs.length=0,this.length=0,t(e)};Zi.prototype._isBufferList=function(e){return e instanceof Zi||e instanceof Zm||Zi.isBufferList(e)};Zi.isBufferList=Zm.isBufferList;bb.exports=Zi;bb.exports.BufferListStream=Zi;bb.exports.BufferList=Zm});var FT=w(dh=>{var $5e=Buffer.alloc,e9e="0000000000000000000",t9e="7777777777777777777",Ice="0".charCodeAt(0),yce=Buffer.from("ustar\0","binary"),r9e=Buffer.from("00","binary"),i9e=Buffer.from("ustar ","binary"),n9e=Buffer.from(" \0","binary"),s9e=parseInt("7777",8),$m=257,DT=263,o9e=function(r,e,t){return typeof r!="number"?t:(r=~~r,r>=e?e:r>=0||(r+=e,r>=0)?r:0)},a9e=function(r){switch(r){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},A9e=function(r){switch(r){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},wce=function(r,e,t,i){for(;te?t9e.slice(0,e)+" ":e9e.slice(0,e-r.length)+r+" "};function l9e(r){var e;if(r[0]===128)e=!0;else if(r[0]===255)e=!1;else return null;for(var t=[],i=r.length-1;i>0;i--){var n=r[i];e?t.push(n):t.push(255-n)}var s=0,o=t.length;for(i=0;i=Math.pow(10,t)&&t++,e+t+r};dh.decodeLongPath=function(r,e){return Ch(r,0,r.length,e)};dh.encodePax=function(r){var e="";r.name&&(e+=RT(" path="+r.name+` -`)),r.linkname&&(e+=RT(" linkpath="+r.linkname+` -`));var t=r.pax;if(t)for(var i in t)e+=RT(" "+i+"="+t[i]+` -`);return Buffer.from(e)};dh.decodePax=function(r){for(var e={};r.length;){for(var t=0;t100;){var n=t.indexOf("/");if(n===-1)return null;i+=i?"/"+t.slice(0,n):t.slice(0,n),t=t.slice(n+1)}return Buffer.byteLength(t)>100||Buffer.byteLength(i)>155||r.linkname&&Buffer.byteLength(r.linkname)>100?null:(e.write(t),e.write(Jl(r.mode&s9e,6),100),e.write(Jl(r.uid,6),108),e.write(Jl(r.gid,6),116),e.write(Jl(r.size,11),124),e.write(Jl(r.mtime.getTime()/1e3|0,11),136),e[156]=Ice+A9e(r.type),r.linkname&&e.write(r.linkname,157),yce.copy(e,$m),r9e.copy(e,DT),r.uname&&e.write(r.uname,265),r.gname&&e.write(r.gname,297),e.write(Jl(r.devmajor||0,6),329),e.write(Jl(r.devminor||0,6),337),i&&e.write(i,345),e.write(Jl(Bce(e),6),148),e)};dh.decode=function(r,e,t){var i=r[156]===0?0:r[156]-Ice,n=Ch(r,0,100,e),s=Wl(r,100,8),o=Wl(r,108,8),a=Wl(r,116,8),l=Wl(r,124,12),c=Wl(r,136,12),u=a9e(i),g=r[157]===0?null:Ch(r,157,100,e),f=Ch(r,265,32),h=Ch(r,297,32),p=Wl(r,329,8),m=Wl(r,337,8),y=Bce(r);if(y===8*32)return null;if(y!==Wl(r,148,8))throw new Error("Invalid tar header. Maybe the tar is corrupted or it needs to be gunzipped?");if(yce.compare(r,$m,$m+6)===0)r[345]&&(n=Ch(r,345,155,e)+"/"+n);else if(!(i9e.compare(r,$m,$m+6)===0&&n9e.compare(r,DT,DT+2)===0)){if(!t)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:m}}});var Pce=w((evt,bce)=>{var Qce=require("util"),c9e=Ece(),eE=FT(),Sce=ph().Writable,vce=ph().PassThrough,xce=function(){},kce=function(r){return r&=511,r&&512-r},u9e=function(r,e){var t=new Qb(r,e);return t.end(),t},g9e=function(r,e){return e.path&&(r.name=e.path),e.linkpath&&(r.linkname=e.linkpath),e.size&&(r.size=parseInt(e.size,10)),r.pax=e,r},Qb=function(r,e){this._parent=r,this.offset=e,vce.call(this,{autoDestroy:!1})};Qce.inherits(Qb,vce);Qb.prototype.destroy=function(r){this._parent.destroy(r)};var kA=function(r){if(!(this instanceof kA))return new kA(r);Sce.call(this,r),r=r||{},this._offset=0,this._buffer=c9e(),this._missing=0,this._partial=!1,this._onparse=xce,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,t=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=kce(e._header.size);f?e._parse(f,o):e._parse(512,g),e._locked||i()},o=function(){e._buffer.consume(kce(e._header.size)),e._parse(512,g),i()},a=function(){var f=e._header.size;e._paxGlobal=eE.decodePax(t.slice(0,f)),t.consume(f),s()},l=function(){var f=e._header.size;e._pax=eE.decodePax(t.slice(0,f)),e._paxGlobal&&(e._pax=Object.assign({},e._paxGlobal,e._pax)),t.consume(f),s()},c=function(){var f=e._header.size;this._gnuLongPath=eE.decodeLongPath(t.slice(0,f),r.filenameEncoding),t.consume(f),s()},u=function(){var f=e._header.size;this._gnuLongLinkPath=eE.decodeLongPath(t.slice(0,f),r.filenameEncoding),t.consume(f),s()},g=function(){var f=e._offset,h;try{h=e._header=eE.decode(t.slice(0,512),r.filenameEncoding,r.allowUnknownFormat)}catch(p){e.emit("error",p)}if(t.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=g9e(h,e._pax),e._pax=null),e._locked=!0,!h.size||h.type==="directory"){e._parse(512,g),e.emit("entry",h,u9e(e,f),n);return}e._stream=new Qb(e,f),e.emit("entry",h,e._stream,n),e._parse(h.size,s),i()};this._onheader=g,this._parse(512,g)};Qce.inherits(kA,Sce);kA.prototype.destroy=function(r){this._destroyed||(this._destroyed=!0,r&&this.emit("error",r),this.emit("close"),this._stream&&this._stream.emit("close"))};kA.prototype._parse=function(r,e){this._destroyed||(this._offset+=r,this._missing=r,e===this._onheader&&(this._partial=!1),this._onparse=e)};kA.prototype._continue=function(){if(!this._destroyed){var r=this._cb;this._cb=xce,this._overflow?this._write(this._overflow,void 0,r):r()}};kA.prototype._write=function(r,e,t){if(!this._destroyed){var i=this._stream,n=this._buffer,s=this._missing;if(r.length&&(this._partial=!0),r.lengths&&(o=r.slice(s),r=r.slice(0,s)),i?i.end(r):n.append(r),this._overflow=o,this._onparse()}};kA.prototype._final=function(r){if(this._partial)return this.destroy(new Error("Unexpected end of data"));r()};bce.exports=kA});var Rce=w((tvt,Dce)=>{Dce.exports=require("fs").constants||require("constants")});var Oce=w((rvt,Fce)=>{var mh=Rce(),Nce=Mk(),Sb=Hl(),f9e=Buffer.alloc,Lce=ph().Readable,Eh=ph().Writable,h9e=require("string_decoder").StringDecoder,vb=FT(),p9e=parseInt("755",8),d9e=parseInt("644",8),Tce=f9e(1024),NT=function(){},LT=function(r,e){e&=511,e&&r.push(Tce.slice(0,512-e))};function C9e(r){switch(r&mh.S_IFMT){case mh.S_IFBLK:return"block-device";case mh.S_IFCHR:return"character-device";case mh.S_IFDIR:return"directory";case mh.S_IFIFO:return"fifo";case mh.S_IFLNK:return"symlink"}return"file"}var xb=function(r){Eh.call(this),this.written=0,this._to=r,this._destroyed=!1};Sb(xb,Eh);xb.prototype._write=function(r,e,t){if(this.written+=r.length,this._to.push(r))return t();this._to._drain=t};xb.prototype.destroy=function(){this._destroyed||(this._destroyed=!0,this.emit("close"))};var kb=function(){Eh.call(this),this.linkname="",this._decoder=new h9e("utf-8"),this._destroyed=!1};Sb(kb,Eh);kb.prototype._write=function(r,e,t){this.linkname+=this._decoder.write(r),t()};kb.prototype.destroy=function(){this._destroyed||(this._destroyed=!0,this.emit("close"))};var tE=function(){Eh.call(this),this._destroyed=!1};Sb(tE,Eh);tE.prototype._write=function(r,e,t){t(new Error("No body allowed for this entry"))};tE.prototype.destroy=function(){this._destroyed||(this._destroyed=!0,this.emit("close"))};var Ia=function(r){if(!(this instanceof Ia))return new Ia(r);Lce.call(this,r),this._drain=NT,this._finalized=!1,this._finalizing=!1,this._destroyed=!1,this._stream=null};Sb(Ia,Lce);Ia.prototype.entry=function(r,e,t){if(this._stream)throw new Error("already piping an entry");if(!(this._finalized||this._destroyed)){typeof e=="function"&&(t=e,e=null),t||(t=NT);var i=this;if((!r.size||r.type==="symlink")&&(r.size=0),r.type||(r.type=C9e(r.mode)),r.mode||(r.mode=r.type==="directory"?p9e:d9e),r.uid||(r.uid=0),r.gid||(r.gid=0),r.mtime||(r.mtime=new Date),typeof e=="string"&&(e=Buffer.from(e)),Buffer.isBuffer(e)){r.size=e.length,this._encode(r);var n=this.push(e);return LT(i,r.size),n?process.nextTick(t):this._drain=t,new tE}if(r.type==="symlink"&&!r.linkname){var s=new kb;return Nce(s,function(a){if(a)return i.destroy(),t(a);r.linkname=s.linkname,i._encode(r),t()}),s}if(this._encode(r),r.type!=="file"&&r.type!=="contiguous-file")return process.nextTick(t),new tE;var o=new xb(this);return this._stream=o,Nce(o,function(a){if(i._stream=null,a)return i.destroy(),t(a);if(o.written!==r.size)return i.destroy(),t(new Error("size mismatch"));LT(i,r.size),i._finalizing&&i.finalize(),t()}),o}};Ia.prototype.finalize=function(){if(this._stream){this._finalizing=!0;return}this._finalized||(this._finalized=!0,this.push(Tce),this.push(null))};Ia.prototype.destroy=function(r){this._destroyed||(this._destroyed=!0,r&&this.emit("error",r),this.emit("close"),this._stream&&this._stream.destroy&&this._stream.destroy())};Ia.prototype._encode=function(r){if(!r.pax){var e=vb.encode(r);if(e){this.push(e);return}}this._encodePax(r)};Ia.prototype._encodePax=function(r){var e=vb.encodePax({name:r.name,linkname:r.linkname,pax:r.pax}),t={name:"PaxHeader",mode:r.mode,uid:r.uid,gid:r.gid,size:e.length,mtime:r.mtime,type:"pax-header",linkname:r.linkname&&"PaxHeader",uname:r.uname,gname:r.gname,devmajor:r.devmajor,devminor:r.devminor};this.push(vb.encode(t)),this.push(e),LT(this,e.length),t.size=r.size,t.type=r.type,this.push(vb.encode(t))};Ia.prototype._read=function(r){var e=this._drain;this._drain=NT,e()};Fce.exports=Ia});var Mce=w(TT=>{TT.extract=Pce();TT.pack=Oce()});var Xce=w((Qvt,Wce)=>{"use strict";var Ih=class{constructor(e,t,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=t||{},this.__providers=_ce(i.filter(n=>n!=null&&typeof n=="object")),this.__isFiggyPudding=!0}get(e){return jT(this,e,!0)}get[Symbol.toStringTag](){return"FiggyPudding"}forEach(e,t=this){for(let[i,n]of this.entries())e.call(t,n,i,this)}toJSON(){let e={};return this.forEach((t,i)=>{e[i]=t}),e}*entries(e){for(let i of Object.keys(this.__specs))yield[i,this.get(i)];let t=e||this.__opts.other;if(t){let i=new Set;for(let n of this.__providers){let s=n.entries?n.entries(t):P9e(n);for(let[o,a]of s)t(o)&&!i.has(o)&&(i.add(o),yield[o,a])}}}*[Symbol.iterator](){for(let[e,t]of this.entries())yield[e,t]}*keys(){for(let[e]of this.entries())yield e}*values(){for(let[,e]of this.entries())yield e}concat(...e){return new Proxy(new Ih(this.__specs,this.__opts,_ce(this.__providers).concat(e)),zce)}};try{let r=require("util");Ih.prototype[r.inspect.custom]=function(e,t){return this[Symbol.toStringTag]+" "+r.inspect(this.toJSON(),t)}}catch(r){}function D9e(r){throw Object.assign(new Error(`invalid config key requested: ${r}`),{code:"EBADKEY"})}function jT(r,e,t){let i=r.__specs[e];if(t&&!i&&(!r.__opts.other||!r.__opts.other(e)))D9e(e);else{i||(i={});let n;for(let s of r.__providers){if(n=Vce(e,s),n===void 0&&i.aliases&&i.aliases.length){for(let o of i.aliases)if(o!==e&&(n=Vce(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(r):i.default:n}}function Vce(r,e){let t;return e.__isFiggyPudding?t=jT(e,r,!1):typeof e.get=="function"?t=e.get(r):t=e[r],t}var zce={has(r,e){return e in r.__specs&&jT(r,e,!1)!==void 0},ownKeys(r){return Object.keys(r.__specs)},get(r,e){return typeof e=="symbol"||e.slice(0,2)==="__"||e in Ih.prototype?r[e]:r.get(e)},set(r,e,t){if(typeof e=="symbol"||e.slice(0,2)==="__")return r[e]=t,!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.")}};Wce.exports=R9e;function R9e(r,e){function t(...i){return new Proxy(new Ih(r,e,i),zce)}return t}function _ce(r){let e=[];return r.forEach(t=>e.unshift(t)),e}function P9e(r){return Object.keys(r).map(e=>[e,r[e]])}});var eue=w((Svt,ya)=>{"use strict";var iE=require("crypto"),F9e=Xce(),N9e=require("stream").Transform,Zce=["sha256","sha384","sha512"],L9e=/^[a-z0-9+/]+(?:=?=?)$/i,T9e=/^([^-]+)-([^?]+)([?\S*]*)$/,O9e=/^([^-]+)-([A-Za-z0-9+/=]{44,88})(\?[\x21-\x7E]*)*$/,M9e=/^[\x21-\x7E]+$/,Cn=F9e({algorithms:{default:["sha512"]},error:{default:!1},integrity:{},options:{default:[]},pickAlgorithm:{default:()=>K9e},Promise:{default:()=>Promise},sep:{default:" "},single:{default:!1},size:{},strict:{default:!1}}),Fu=class{get isHash(){return!0}constructor(e,t){t=Cn(t);let i=!!t.strict;this.source=e.trim();let n=this.source.match(i?O9e:T9e);if(!n||i&&!Zce.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=Cn(e),e.strict&&!(Zce.some(i=>i===this.algorithm)&&this.digest.match(L9e)&&(this.options||[]).every(i=>i.match(M9e))))return"";let t=this.options&&this.options.length?`?${this.options.join("?")}`:"";return`${this.algorithm}-${this.digest}${t}`}},yh=class{get isIntegrity(){return!0}toJSON(){return this.toString()}toString(e){e=Cn(e);let t=e.sep||" ";return e.strict&&(t=t.replace(/\S+/g," ")),Object.keys(this).map(i=>this[i].map(n=>Fu.prototype.toString.call(n,e)).filter(n=>n.length).join(t)).filter(i=>i.length).join(t)}concat(e,t){t=Cn(t);let i=typeof e=="string"?e:nE(e,t);return wa(`${this.toString(t)} ${i}`,t)}hexDigest(){return wa(this,{single:!0}).hexDigest()}match(e,t){t=Cn(t);let i=wa(e,t),n=i.pickAlgorithm(t);return this[n]&&i[n]&&this[n].find(s=>i[n].find(o=>s.digest===o.digest))||!1}pickAlgorithm(e){e=Cn(e);let t=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)=>t(n,s)||n)}};ya.exports.parse=wa;function wa(r,e){if(e=Cn(e),typeof r=="string")return GT(r,e);if(r.algorithm&&r.digest){let t=new yh;return t[r.algorithm]=[r],GT(nE(t,e),e)}else return GT(nE(r,e),e)}function GT(r,e){return e.single?new Fu(r,e):r.trim().split(/\s+/).reduce((t,i)=>{let n=new Fu(i,e);if(n.algorithm&&n.digest){let s=n.algorithm;t[s]||(t[s]=[]),t[s].push(n)}return t},new yh)}ya.exports.stringify=nE;function nE(r,e){return e=Cn(e),r.algorithm&&r.digest?Fu.prototype.toString.call(r,e):typeof r=="string"?nE(wa(r,e),e):yh.prototype.toString.call(r,e)}ya.exports.fromHex=U9e;function U9e(r,e,t){t=Cn(t);let i=t.options&&t.options.length?`?${t.options.join("?")}`:"";return wa(`${e}-${Buffer.from(r,"hex").toString("base64")}${i}`,t)}ya.exports.fromData=H9e;function H9e(r,e){e=Cn(e);let t=e.algorithms,i=e.options&&e.options.length?`?${e.options.join("?")}`:"";return t.reduce((n,s)=>{let o=iE.createHash(s).update(r).digest("base64"),a=new Fu(`${s}-${o}${i}`,e);if(a.algorithm&&a.digest){let l=a.algorithm;n[l]||(n[l]=[]),n[l].push(a)}return n},new yh)}ya.exports.fromStream=j9e;function j9e(r,e){e=Cn(e);let t=e.Promise||Promise,i=YT(e);return new t((n,s)=>{r.pipe(i),r.on("error",s),i.on("error",s);let o;i.on("integrity",a=>{o=a}),i.on("end",()=>n(o)),i.on("data",()=>{})})}ya.exports.checkData=G9e;function G9e(r,e,t){if(t=Cn(t),e=wa(e,t),!Object.keys(e).length){if(t.error)throw Object.assign(new Error("No valid integrity hashes to check against"),{code:"EINTEGRITY"});return!1}let i=e.pickAlgorithm(t),n=iE.createHash(i).update(r).digest("base64"),s=wa({algorithm:i,digest:n}),o=s.match(e,t);if(o||!t.error)return o;if(typeof t.size=="number"&&r.length!==t.size){let a=new Error(`data size mismatch when checking ${e}. - Wanted: ${t.size} - Found: ${r.length}`);throw a.code="EBADSIZE",a.found=r.length,a.expected=t.size,a.sri=e,a}else{let a=new Error(`Integrity checksum failed when using ${i}: Wanted ${e}, but got ${s}. (${r.length} bytes)`);throw a.code="EINTEGRITY",a.found=s,a.expected=e,a.algorithm=i,a.sri=e,a}}ya.exports.checkStream=Y9e;function Y9e(r,e,t){t=Cn(t);let i=t.Promise||Promise,n=YT(t.concat({integrity:e}));return new i((s,o)=>{r.pipe(n),r.on("error",o),n.on("error",o);let a;n.on("verified",l=>{a=l}),n.on("end",()=>s(a)),n.on("data",()=>{})})}ya.exports.integrityStream=YT;function YT(r){r=Cn(r);let e=r.integrity&&wa(r.integrity,r),t=e&&Object.keys(e).length,i=t&&e.pickAlgorithm(r),n=t&&e[i],s=Array.from(new Set(r.algorithms.concat(i?[i]:[]))),o=s.map(iE.createHash),a=0,l=new N9e({transform(c,u,g){a+=c.length,o.forEach(f=>f.update(c,u)),g(null,c,u)}}).on("end",()=>{let c=r.options&&r.options.length?`?${r.options.join("?")}`:"",u=wa(o.map((f,h)=>`${s[h]}-${f.digest("base64")}${c}`).join(" "),r),g=t&&u.match(e,r);if(typeof r.size=="number"&&a!==r.size){let f=new Error(`stream size mismatch when checking ${e}. - Wanted: ${r.size} - Found: ${a}`);f.code="EBADSIZE",f.found=a,f.expected=r.size,f.sri=e,l.emit("error",f)}else if(r.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}ya.exports.create=q9e;function q9e(r){r=Cn(r);let e=r.algorithms,t=r.options.length?`?${r.options.join("?")}`:"",i=e.map(iE.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 Fu(`${a}-${l}${t}`,r);if(c.algorithm&&c.digest){let u=c.algorithm;o[u]||(o[u]=[]),o[u].push(c)}return o},new yh)}}}var J9e=new Set(iE.getHashes()),$ce=["md5","whirlpool","sha1","sha224","sha256","sha384","sha512","sha3","sha3-256","sha3-384","sha3-512","sha3_256","sha3_384","sha3_512"].filter(r=>J9e.has(r));function K9e(r,e){return $ce.indexOf(r.toLowerCase())>=$ce.indexOf(e.toLowerCase())?r:e}});var EC={};ft(EC,{BuildType:()=>cs,Cache:()=>Nt,Configuration:()=>ye,DEFAULT_LOCK_FILENAME:()=>fk,DEFAULT_RC_FILENAME:()=>gk,FormatType:()=>Ri,InstallMode:()=>Ci,LightReport:()=>pA,LinkType:()=>Qt,Manifest:()=>At,MessageName:()=>X,MultiFetcher:()=>yd,PackageExtensionStatus:()=>qi,PackageExtensionType:()=>wi,Project:()=>ze,ProjectLookup:()=>ul,Report:()=>Ji,ReportError:()=>ct,SettingsType:()=>Ie,StreamReport:()=>Je,TAG_REGEXP:()=>zg,TelemetryManager:()=>mC,ThrowReport:()=>di,VirtualFetcher:()=>Bd,Workspace:()=>CC,WorkspaceFetcher:()=>bd,WorkspaceResolver:()=>oi,YarnVersion:()=>Ur,execUtils:()=>Nr,folderUtils:()=>sk,formatUtils:()=>ae,hashUtils:()=>Dn,httpUtils:()=>ir,miscUtils:()=>Se,nodeUtils:()=>Vg,parseMessageName:()=>II,scriptUtils:()=>Zt,semverUtils:()=>Wt,stringifyMessageName:()=>_A,structUtils:()=>P,tgzUtils:()=>Bi,treeUtils:()=>ls});var Nr={};ft(Nr,{EndStrategy:()=>ss,ExecError:()=>Ik,PipeError:()=>ww,execvp:()=>pve,pipevp:()=>ra});var Zh={};ft(Zh,{AliasFS:()=>Na,CwdFS:()=>_t,DEFAULT_COMPRESSION_LEVEL:()=>lc,FakeFS:()=>YA,Filename:()=>kt,JailFS:()=>La,LazyFS:()=>_h,LinkStrategy:()=>Gh,NoFS:()=>jE,NodeFS:()=>ar,PortablePath:()=>Me,PosixFS:()=>Vh,ProxiedFS:()=>Qi,VirtualFS:()=>Wr,ZipFS:()=>li,ZipOpenFS:()=>Is,constants:()=>Rr,extendFs:()=>WE,normalizeLineEndings:()=>sc,npath:()=>H,opendir:()=>KE,patchFs:()=>pQ,ppath:()=>k,statUtils:()=>rQ,toFilename:()=>Jr,xfs:()=>K});var Rr={};ft(Rr,{SAFE_TIME:()=>tQ,S_IFDIR:()=>Da,S_IFLNK:()=>Fa,S_IFMT:()=>_n,S_IFREG:()=>Ra});var _n=61440,Da=16384,Ra=32768,Fa=40960,tQ=456789e3;var rQ={};ft(rQ,{BigIntStatsEntry:()=>Uh,DEFAULT_MODE:()=>Kh,DirEntry:()=>KO,StatEntry:()=>jA,areStatsEqual:()=>nQ,clearStats:()=>RE,convertToBigIntStats:()=>FE,makeDefaultStats:()=>Hh,makeEmptyStats:()=>fge});var iQ=ge(require("util"));var Kh=Ra|420,KO=class{constructor(){this.name="";this.mode=0}isBlockDevice(){return!1}isCharacterDevice(){return!1}isDirectory(){return(this.mode&_n)===Da}isFIFO(){return!1}isFile(){return(this.mode&_n)===Ra}isSocket(){return!1}isSymbolicLink(){return(this.mode&_n)===Fa}},jA=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=Kh;this.nlink=1;this.rdev=0;this.blocks=1}isBlockDevice(){return!1}isCharacterDevice(){return!1}isDirectory(){return(this.mode&_n)===Da}isFIFO(){return!1}isFile(){return(this.mode&_n)===Ra}isSocket(){return!1}isSymbolicLink(){return(this.mode&_n)===Fa}},Uh=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(Kh);this.nlink=BigInt(1);this.rdev=BigInt(0);this.blocks=BigInt(1)}isBlockDevice(){return!1}isCharacterDevice(){return!1}isDirectory(){return(this.mode&BigInt(_n))===BigInt(Da)}isFIFO(){return!1}isFile(){return(this.mode&BigInt(_n))===BigInt(Ra)}isSocket(){return!1}isSymbolicLink(){return(this.mode&BigInt(_n))===BigInt(Fa)}};function Hh(){return new jA}function fge(){return RE(Hh())}function RE(r){for(let e in r)if(Object.prototype.hasOwnProperty.call(r,e)){let t=r[e];typeof t=="number"?r[e]=0:typeof t=="bigint"?r[e]=BigInt(0):iQ.types.isDate(t)&&(r[e]=new Date(0))}return r}function FE(r){let e=new Uh;for(let t in r)if(Object.prototype.hasOwnProperty.call(r,t)){let i=r[t];typeof i=="number"?e[t]=BigInt(i):iQ.types.isDate(i)&&(e[t]=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 nQ(r,e){if(r.atimeMs!==e.atimeMs||r.birthtimeMs!==e.birthtimeMs||r.blksize!==e.blksize||r.blocks!==e.blocks||r.ctimeMs!==e.ctimeMs||r.dev!==e.dev||r.gid!==e.gid||r.ino!==e.ino||r.isBlockDevice()!==e.isBlockDevice()||r.isCharacterDevice()!==e.isCharacterDevice()||r.isDirectory()!==e.isDirectory()||r.isFIFO()!==e.isFIFO()||r.isFile()!==e.isFile()||r.isSocket()!==e.isSocket()||r.isSymbolicLink()!==e.isSymbolicLink()||r.mode!==e.mode||r.mtimeMs!==e.mtimeMs||r.nlink!==e.nlink||r.rdev!==e.rdev||r.size!==e.size||r.uid!==e.uid)return!1;let t=r,i=e;return!(t.atimeNs!==i.atimeNs||t.mtimeNs!==i.mtimeNs||t.ctimeNs!==i.ctimeNs||t.birthtimeNs!==i.birthtimeNs)}var LE=ge(require("fs"));var jh=ge(require("path")),UO;(function(i){i[i.File=0]="File",i[i.Portable=1]="Portable",i[i.Native=2]="Native"})(UO||(UO={}));var Me={root:"/",dot:"."},kt={nodeModules:"node_modules",manifest:"package.json",lockfile:"yarn.lock",virtual:"__virtual__",pnpJs:".pnp.js",pnpCjs:".pnp.cjs",rc:".yarnrc.yml"},H=Object.create(jh.default),k=Object.create(jh.default.posix);H.cwd=()=>process.cwd();k.cwd=()=>sQ(process.cwd());k.resolve=(...r)=>r.length>0&&k.isAbsolute(r[0])?jh.default.posix.resolve(...r):jh.default.posix.resolve(k.cwd(),...r);var HO=function(r,e,t){return e=r.normalize(e),t=r.normalize(t),e===t?".":(e.endsWith(r.sep)||(e=e+r.sep),t.startsWith(e)?t.slice(e.length):null)};H.fromPortablePath=jO;H.toPortablePath=sQ;H.contains=(r,e)=>HO(H,r,e);k.contains=(r,e)=>HO(k,r,e);var hge=/^([a-zA-Z]:.*)$/,pge=/^\/\/(\.\/)?(.*)$/,dge=/^\/([a-zA-Z]:.*)$/,Cge=/^\/unc\/(\.dot\/)?(.*)$/;function jO(r){if(process.platform!=="win32")return r;let e,t;if(e=r.match(dge))r=e[1];else if(t=r.match(Cge))r=`\\\\${t[1]?".\\":""}${t[2]}`;else return r;return r.replace(/\//g,"\\")}function sQ(r){if(process.platform!=="win32")return r;r=r.replace(/\\/g,"/");let e,t;return(e=r.match(hge))?r=`/${e[1]}`:(t=r.match(pge))&&(r=`/unc/${t[1]?".dot/":""}${t[2]}`),r}function NE(r,e){return r===H?jO(e):sQ(e)}function Jr(r){if(H.parse(r).dir!==""||k.parse(r).dir!=="")throw new Error(`Invalid filename: "${r}"`);return r}var TE=new Date(tQ*1e3),Gh;(function(t){t.Allow="allow",t.ReadOnly="readOnly"})(Gh||(Gh={}));async function GO(r,e,t,i,n){let s=r.pathUtils.normalize(e),o=t.pathUtils.normalize(i),a=[],l=[],{atime:c,mtime:u}=n.stableTime?{atime:TE,mtime:TE}:await t.lstatPromise(o);await r.mkdirpPromise(r.pathUtils.dirname(e),{utimes:[c,u]});let g=typeof r.lutimesPromise=="function"?r.lutimesPromise.bind(r):r.utimesPromise.bind(r);await oQ(a,l,g,r,s,t,o,te(N({},n),{didParentExist:!0}));for(let f of a)await f();await Promise.all(l.map(f=>f()))}async function oQ(r,e,t,i,n,s,o,a){var h,p;let l=a.didParentExist?await mge(i,n):null,c=await s.lstatPromise(o),{atime:u,mtime:g}=a.stableTime?{atime:TE,mtime:TE}:c,f;switch(!0){case c.isDirectory():f=await Ege(r,e,t,i,n,l,s,o,c,a);break;case c.isFile():f=await Ige(r,e,t,i,n,l,s,o,c,a);break;case c.isSymbolicLink():f=await yge(r,e,t,i,n,l,s,o,c,a);break;default:throw new Error(`Unsupported file type (${c.mode})`)}return(f||((h=l==null?void 0:l.mtime)==null?void 0:h.getTime())!==g.getTime()||((p=l==null?void 0:l.atime)==null?void 0:p.getTime())!==u.getTime())&&(e.push(()=>t(n,u,g)),f=!0),(l===null||(l.mode&511)!=(c.mode&511))&&(e.push(()=>i.chmodPromise(n,c.mode&511)),f=!0),f}async function mge(r,e){try{return await r.lstatPromise(e)}catch(t){return null}}async function Ege(r,e,t,i,n,s,o,a,l,c){if(s!==null&&!s.isDirectory())if(c.overwrite)r.push(async()=>i.removePromise(n)),s=null;else return!1;let u=!1;s===null&&(r.push(async()=>{try{await i.mkdirPromise(n,{mode:l.mode})}catch(h){if(h.code!=="EEXIST")throw h}}),u=!0);let g=await o.readdirPromise(a),f=c.didParentExist&&!s?te(N({},c),{didParentExist:!1}):c;if(c.stableSort)for(let h of g.sort())await oQ(r,e,t,i,i.pathUtils.join(n,h),o,o.pathUtils.join(a,h),f)&&(u=!0);else(await Promise.all(g.map(async p=>{await oQ(r,e,t,i,i.pathUtils.join(n,p),o,o.pathUtils.join(a,p),f)}))).some(p=>p)&&(u=!0);return u}var aQ=new WeakMap;function AQ(r,e,t,i,n){return async()=>{await r.linkPromise(t,e),n===Gh.ReadOnly&&(i.mode&=~146,await r.chmodPromise(e,i.mode))}}function wge(r,e,t,i,n){let s=aQ.get(r);return typeof s=="undefined"?async()=>{try{await r.copyFilePromise(t,e,LE.default.constants.COPYFILE_FICLONE_FORCE),aQ.set(r,!0)}catch(o){if(o.code==="ENOSYS"||o.code==="ENOTSUP")aQ.set(r,!1),await AQ(r,e,t,i,n)();else throw o}}:s?async()=>r.copyFilePromise(t,e,LE.default.constants.COPYFILE_FICLONE_FORCE):AQ(r,e,t,i,n)}async function Ige(r,e,t,i,n,s,o,a,l,c){var f;if(s!==null)if(c.overwrite)r.push(async()=>i.removePromise(n)),s=null;else return!1;let u=(f=c.linkStrategy)!=null?f:null,g=i===o?u!==null?wge(i,n,a,l,u):async()=>i.copyFilePromise(a,n,LE.default.constants.COPYFILE_FICLONE):u!==null?AQ(i,n,a,l,u):async()=>i.writeFilePromise(n,await o.readFilePromise(a));return r.push(async()=>g()),!0}async function yge(r,e,t,i,n,s,o,a,l,c){if(s!==null)if(c.overwrite)r.push(async()=>i.removePromise(n)),s=null;else return!1;return r.push(async()=>{await i.symlinkPromise(NE(i.pathUtils,await o.readlinkPromise(a)),n)}),!0}function Es(r,e){return Object.assign(new Error(`${r}: ${e}`),{code:r})}function OE(r){return Es("EBUSY",r)}function Yh(r,e){return Es("ENOSYS",`${r}, ${e}`)}function GA(r){return Es("EINVAL",`invalid argument, ${r}`)}function Ai(r){return Es("EBADF",`bad file descriptor, ${r}`)}function io(r){return Es("ENOENT",`no such file or directory, ${r}`)}function Ro(r){return Es("ENOTDIR",`not a directory, ${r}`)}function qh(r){return Es("EISDIR",`illegal operation on a directory, ${r}`)}function ME(r){return Es("EEXIST",`file already exists, ${r}`)}function In(r){return Es("EROFS",`read-only filesystem, ${r}`)}function YO(r){return Es("ENOTEMPTY",`directory not empty, ${r}`)}function qO(r){return Es("EOPNOTSUPP",`operation not supported, ${r}`)}function JO(){return Es("ERR_DIR_CLOSED","Directory handle was closed")}var lQ=class extends Error{constructor(e,t){super(e);this.name="Libzip Error",this.code=t}};var WO=class{constructor(e,t,i={}){this.path=e;this.nextDirent=t;this.opts=i;this.closed=!1}throwIfClosed(){if(this.closed)throw JO()}async*[Symbol.asyncIterator](){try{let e;for(;(e=await this.read())!==null;)yield e}finally{await this.close()}}read(e){let t=this.readSync();return typeof e!="undefined"?e(null,t):Promise.resolve(t)}readSync(){return this.throwIfClosed(),this.nextDirent()}close(e){return this.closeSync(),typeof e!="undefined"?e(null):Promise.resolve()}closeSync(){var e,t;this.throwIfClosed(),(t=(e=this.opts).onClose)==null||t.call(e),this.closed=!0}};function KE(r,e,t,i){let n=()=>{let s=t.shift();return typeof s=="undefined"?null:Object.assign(r.statSync(r.pathUtils.join(e,s)),{name:s})};return new WO(e,n,i)}var zO=ge(require("os"));var YA=class{constructor(e){this.pathUtils=e}async*genTraversePromise(e,{stableSort:t=!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(t)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:t=!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(t){let s=await this.readdirPromise(e);await Promise.all(s.map(o=>this.removePromise(this.pathUtils.resolve(e,o))))}for(let s=0;s<=i;s++)try{await this.rmdirPromise(e);break}catch(o){if(o.code!=="EBUSY"&&o.code!=="ENOTEMPTY")throw o;ssetTimeout(a,s*100))}}else await this.unlinkPromise(e)}removeSync(e,{recursive:t=!0}={}){let i;try{i=this.lstatSync(e)}catch(n){if(n.code==="ENOENT")return;throw n}if(i.isDirectory()){if(t)for(let n of this.readdirSync(e))this.removeSync(this.pathUtils.resolve(e,n));this.rmdirSync(e)}else this.unlinkSync(e)}async mkdirpPromise(e,{chmod:t,utimes:i}={}){if(e=this.resolve(e),e===this.pathUtils.dirname(e))return;let n=e.split(this.pathUtils.sep),s;for(let o=2;o<=n.length;++o){let a=n.slice(0,o).join(this.pathUtils.sep);if(!this.existsSync(a)){try{await this.mkdirPromise(a)}catch(l){if(l.code==="EEXIST")continue;throw l}if(s!=null||(s=a),t!=null&&await this.chmodPromise(a,t),i!=null)await this.utimesPromise(a,i[0],i[1]);else{let l=await this.statPromise(this.pathUtils.dirname(a));await this.utimesPromise(a,l.atime,l.mtime)}}}return s}mkdirpSync(e,{chmod:t,utimes:i}={}){if(e=this.resolve(e),e===this.pathUtils.dirname(e))return;let n=e.split(this.pathUtils.sep),s;for(let o=2;o<=n.length;++o){let a=n.slice(0,o).join(this.pathUtils.sep);if(!this.existsSync(a)){try{this.mkdirSync(a)}catch(l){if(l.code==="EEXIST")continue;throw l}if(s!=null||(s=a),t!=null&&this.chmodSync(a,t),i!=null)this.utimesSync(a,i[0],i[1]);else{let l=this.statSync(this.pathUtils.dirname(a));this.utimesSync(a,l.atime,l.mtime)}}}return s}async copyPromise(e,t,{baseFs:i=this,overwrite:n=!0,stableSort:s=!1,stableTime:o=!1,linkStrategy:a=null}={}){return await GO(this,e,i,t,{overwrite:n,stableSort:s,stableTime:o,linkStrategy:a})}copySync(e,t,{baseFs:i=this,overwrite:n=!0}={}){let s=i.lstatSync(t),o=this.existsSync(e);if(s.isDirectory()){this.mkdirpSync(e);let l=i.readdirSync(t);for(let c of l)this.copySync(this.pathUtils.join(e,c),i.pathUtils.join(t,c),{baseFs:i,overwrite:n})}else if(s.isFile()){if(!o||n){o&&this.removeSync(e);let l=i.readFileSync(t);this.writeFileSync(e,l)}}else if(s.isSymbolicLink()){if(!o||n){o&&this.removeSync(e);let l=i.readlinkSync(t);this.symlinkSync(NE(this.pathUtils,l),e)}}else throw new Error(`Unsupported file type (file: ${t}, mode: 0o${s.mode.toString(8).padStart(6,"0")})`);let a=s.mode&511;this.chmodSync(e,a)}async changeFilePromise(e,t,i={}){return Buffer.isBuffer(t)?this.changeFileBufferPromise(e,t,i):this.changeFileTextPromise(e,t,i)}async changeFileBufferPromise(e,t,{mode:i}={}){let n=Buffer.alloc(0);try{n=await this.readFilePromise(e)}catch(s){}Buffer.compare(n,t)!==0&&await this.writeFilePromise(e,t,{mode:i})}async changeFileTextPromise(e,t,{automaticNewlines:i,mode:n}={}){let s="";try{s=await this.readFilePromise(e,"utf8")}catch(a){}let o=i?sc(s,t):t;s!==o&&await this.writeFilePromise(e,o,{mode:n})}changeFileSync(e,t,i={}){return Buffer.isBuffer(t)?this.changeFileBufferSync(e,t,i):this.changeFileTextSync(e,t,i)}changeFileBufferSync(e,t,{mode:i}={}){let n=Buffer.alloc(0);try{n=this.readFileSync(e)}catch(s){}Buffer.compare(n,t)!==0&&this.writeFileSync(e,t,{mode:i})}changeFileTextSync(e,t,{automaticNewlines:i=!1,mode:n}={}){let s="";try{s=this.readFileSync(e,"utf8")}catch(a){}let o=i?sc(s,t):t;s!==o&&this.writeFileSync(e,o,{mode:n})}async movePromise(e,t){try{await this.renamePromise(e,t)}catch(i){if(i.code==="EXDEV")await this.copyPromise(t,e),await this.removePromise(e);else throw i}}moveSync(e,t){try{this.renameSync(e,t)}catch(i){if(i.code==="EXDEV")this.copySync(t,e),this.removeSync(e);else throw i}}async lockPromise(e,t){let i=`${e}.flock`,n=1e3/60,s=Date.now(),o=null,a=async()=>{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 t()}finally{try{await this.closePromise(o),await this.unlinkPromise(i)}catch(l){}}}async readJsonPromise(e){let t=await this.readFilePromise(e,"utf8");try{return JSON.parse(t)}catch(i){throw i.message+=` (in ${e})`,i}}readJsonSync(e){let t=this.readFileSync(e,"utf8");try{return JSON.parse(t)}catch(i){throw i.message+=` (in ${e})`,i}}async writeJsonPromise(e,t){return await this.writeFilePromise(e,`${JSON.stringify(t,null,2)} -`)}writeJsonSync(e,t){return this.writeFileSync(e,`${JSON.stringify(t,null,2)} -`)}async preserveTimePromise(e,t){let i=await this.lstatPromise(e),n=await t();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,t){let i=this.lstatSync(e),n=t();typeof n!="undefined"&&(e=n),this.lutimesSync?this.lutimesSync(e,i.atime,i.mtime):i.isSymbolicLink()||this.utimesSync(e,i.atime,i.mtime)}},oc=class extends YA{constructor(){super(k)}};function Bge(r){let e=r.match(/\r?\n/g);if(e===null)return zO.EOL;let t=e.filter(n=>n===`\r -`).length,i=e.length-t;return t>i?`\r -`:` -`}function sc(r,e){return e.replace(/\r?\n/g,Bge(r))}var zu=ge(require("fs")),cQ=ge(require("stream")),ZO=ge(require("util")),uQ=ge(require("zlib"));var _O=ge(require("fs"));var ar=class extends oc{constructor(e=_O.default){super();this.realFs=e,typeof this.realFs.lutimes!="undefined"&&(this.lutimesPromise=this.lutimesPromiseImpl,this.lutimesSync=this.lutimesSyncImpl)}getExtractHint(){return!1}getRealPath(){return Me.root}resolve(e){return k.resolve(e)}async openPromise(e,t,i){return await new Promise((n,s)=>{this.realFs.open(H.fromPortablePath(e),t,i,this.makeCallback(n,s))})}openSync(e,t,i){return this.realFs.openSync(H.fromPortablePath(e),t,i)}async opendirPromise(e,t){return await new Promise((i,n)=>{typeof t!="undefined"?this.realFs.opendir(H.fromPortablePath(e),t,this.makeCallback(i,n)):this.realFs.opendir(H.fromPortablePath(e),this.makeCallback(i,n))}).then(i=>Object.defineProperty(i,"path",{value:e,configurable:!0,writable:!0}))}opendirSync(e,t){let i=typeof t!="undefined"?this.realFs.opendirSync(H.fromPortablePath(e),t):this.realFs.opendirSync(H.fromPortablePath(e));return Object.defineProperty(i,"path",{value:e,configurable:!0,writable:!0})}async readPromise(e,t,i=0,n=0,s=-1){return await new Promise((o,a)=>{this.realFs.read(e,t,i,n,s,(l,c)=>{l?a(l):o(c)})})}readSync(e,t,i,n,s){return this.realFs.readSync(e,t,i,n,s)}async writePromise(e,t,i,n,s){return await new Promise((o,a)=>typeof t=="string"?this.realFs.write(e,t,i,this.makeCallback(o,a)):this.realFs.write(e,t,i,n,s,this.makeCallback(o,a)))}writeSync(e,t,i,n,s){return typeof t=="string"?this.realFs.writeSync(e,t,i):this.realFs.writeSync(e,t,i,n,s)}async closePromise(e){await new Promise((t,i)=>{this.realFs.close(e,this.makeCallback(t,i))})}closeSync(e){this.realFs.closeSync(e)}createReadStream(e,t){let i=e!==null?H.fromPortablePath(e):e;return this.realFs.createReadStream(i,t)}createWriteStream(e,t){let i=e!==null?H.fromPortablePath(e):e;return this.realFs.createWriteStream(i,t)}async realpathPromise(e){return await new Promise((t,i)=>{this.realFs.realpath(H.fromPortablePath(e),{},this.makeCallback(t,i))}).then(t=>H.toPortablePath(t))}realpathSync(e){return H.toPortablePath(this.realFs.realpathSync(H.fromPortablePath(e),{}))}async existsPromise(e){return await new Promise(t=>{this.realFs.exists(H.fromPortablePath(e),t)})}accessSync(e,t){return this.realFs.accessSync(H.fromPortablePath(e),t)}async accessPromise(e,t){return await new Promise((i,n)=>{this.realFs.access(H.fromPortablePath(e),t,this.makeCallback(i,n))})}existsSync(e){return this.realFs.existsSync(H.fromPortablePath(e))}async statPromise(e,t){return await new Promise((i,n)=>{t?this.realFs.stat(H.fromPortablePath(e),t,this.makeCallback(i,n)):this.realFs.stat(H.fromPortablePath(e),this.makeCallback(i,n))})}statSync(e,t){return t?this.realFs.statSync(H.fromPortablePath(e),t):this.realFs.statSync(H.fromPortablePath(e))}async fstatPromise(e,t){return await new Promise((i,n)=>{t?this.realFs.fstat(e,t,this.makeCallback(i,n)):this.realFs.fstat(e,this.makeCallback(i,n))})}fstatSync(e,t){return t?this.realFs.fstatSync(e,t):this.realFs.fstatSync(e)}async lstatPromise(e,t){return await new Promise((i,n)=>{t?this.realFs.lstat(H.fromPortablePath(e),t,this.makeCallback(i,n)):this.realFs.lstat(H.fromPortablePath(e),this.makeCallback(i,n))})}lstatSync(e,t){return t?this.realFs.lstatSync(H.fromPortablePath(e),t):this.realFs.lstatSync(H.fromPortablePath(e))}async fchmodPromise(e,t){return await new Promise((i,n)=>{this.realFs.fchmod(e,t,this.makeCallback(i,n))})}fchmodSync(e,t){return this.realFs.fchmodSync(e,t)}async chmodPromise(e,t){return await new Promise((i,n)=>{this.realFs.chmod(H.fromPortablePath(e),t,this.makeCallback(i,n))})}chmodSync(e,t){return this.realFs.chmodSync(H.fromPortablePath(e),t)}async chownPromise(e,t,i){return await new Promise((n,s)=>{this.realFs.chown(H.fromPortablePath(e),t,i,this.makeCallback(n,s))})}chownSync(e,t,i){return this.realFs.chownSync(H.fromPortablePath(e),t,i)}async renamePromise(e,t){return await new Promise((i,n)=>{this.realFs.rename(H.fromPortablePath(e),H.fromPortablePath(t),this.makeCallback(i,n))})}renameSync(e,t){return this.realFs.renameSync(H.fromPortablePath(e),H.fromPortablePath(t))}async copyFilePromise(e,t,i=0){return await new Promise((n,s)=>{this.realFs.copyFile(H.fromPortablePath(e),H.fromPortablePath(t),i,this.makeCallback(n,s))})}copyFileSync(e,t,i=0){return this.realFs.copyFileSync(H.fromPortablePath(e),H.fromPortablePath(t),i)}async appendFilePromise(e,t,i){return await new Promise((n,s)=>{let o=typeof e=="string"?H.fromPortablePath(e):e;i?this.realFs.appendFile(o,t,i,this.makeCallback(n,s)):this.realFs.appendFile(o,t,this.makeCallback(n,s))})}appendFileSync(e,t,i){let n=typeof e=="string"?H.fromPortablePath(e):e;i?this.realFs.appendFileSync(n,t,i):this.realFs.appendFileSync(n,t)}async writeFilePromise(e,t,i){return await new Promise((n,s)=>{let o=typeof e=="string"?H.fromPortablePath(e):e;i?this.realFs.writeFile(o,t,i,this.makeCallback(n,s)):this.realFs.writeFile(o,t,this.makeCallback(n,s))})}writeFileSync(e,t,i){let n=typeof e=="string"?H.fromPortablePath(e):e;i?this.realFs.writeFileSync(n,t,i):this.realFs.writeFileSync(n,t)}async unlinkPromise(e){return await new Promise((t,i)=>{this.realFs.unlink(H.fromPortablePath(e),this.makeCallback(t,i))})}unlinkSync(e){return this.realFs.unlinkSync(H.fromPortablePath(e))}async utimesPromise(e,t,i){return await new Promise((n,s)=>{this.realFs.utimes(H.fromPortablePath(e),t,i,this.makeCallback(n,s))})}utimesSync(e,t,i){this.realFs.utimesSync(H.fromPortablePath(e),t,i)}async lutimesPromiseImpl(e,t,i){let n=this.realFs.lutimes;if(typeof n=="undefined")throw Yh("unavailable Node binding",`lutimes '${e}'`);return await new Promise((s,o)=>{n.call(this.realFs,H.fromPortablePath(e),t,i,this.makeCallback(s,o))})}lutimesSyncImpl(e,t,i){let n=this.realFs.lutimesSync;if(typeof n=="undefined")throw Yh("unavailable Node binding",`lutimes '${e}'`);n.call(this.realFs,H.fromPortablePath(e),t,i)}async mkdirPromise(e,t){return await new Promise((i,n)=>{this.realFs.mkdir(H.fromPortablePath(e),t,this.makeCallback(i,n))})}mkdirSync(e,t){return this.realFs.mkdirSync(H.fromPortablePath(e),t)}async rmdirPromise(e,t){return await new Promise((i,n)=>{t?this.realFs.rmdir(H.fromPortablePath(e),t,this.makeCallback(i,n)):this.realFs.rmdir(H.fromPortablePath(e),this.makeCallback(i,n))})}rmdirSync(e,t){return this.realFs.rmdirSync(H.fromPortablePath(e),t)}async linkPromise(e,t){return await new Promise((i,n)=>{this.realFs.link(H.fromPortablePath(e),H.fromPortablePath(t),this.makeCallback(i,n))})}linkSync(e,t){return this.realFs.linkSync(H.fromPortablePath(e),H.fromPortablePath(t))}async symlinkPromise(e,t,i){return await new Promise((n,s)=>{this.realFs.symlink(H.fromPortablePath(e.replace(/\/+$/,"")),H.fromPortablePath(t),i,this.makeCallback(n,s))})}symlinkSync(e,t,i){return this.realFs.symlinkSync(H.fromPortablePath(e.replace(/\/+$/,"")),H.fromPortablePath(t),i)}async readFilePromise(e,t){return await new Promise((i,n)=>{let s=typeof e=="string"?H.fromPortablePath(e):e;this.realFs.readFile(s,t,this.makeCallback(i,n))})}readFileSync(e,t){let i=typeof e=="string"?H.fromPortablePath(e):e;return this.realFs.readFileSync(i,t)}async readdirPromise(e,t){return await new Promise((i,n)=>{(t==null?void 0:t.withFileTypes)?this.realFs.readdir(H.fromPortablePath(e),{withFileTypes:!0},this.makeCallback(i,n)):this.realFs.readdir(H.fromPortablePath(e),this.makeCallback(s=>i(s),n))})}readdirSync(e,t){return(t==null?void 0:t.withFileTypes)?this.realFs.readdirSync(H.fromPortablePath(e),{withFileTypes:!0}):this.realFs.readdirSync(H.fromPortablePath(e))}async readlinkPromise(e){return await new Promise((t,i)=>{this.realFs.readlink(H.fromPortablePath(e),this.makeCallback(t,i))}).then(t=>H.toPortablePath(t))}readlinkSync(e){return H.toPortablePath(this.realFs.readlinkSync(H.fromPortablePath(e)))}async truncatePromise(e,t){return await new Promise((i,n)=>{this.realFs.truncate(H.fromPortablePath(e),t,this.makeCallback(i,n))})}truncateSync(e,t){return this.realFs.truncateSync(H.fromPortablePath(e),t)}async ftruncatePromise(e,t){return await new Promise((i,n)=>{this.realFs.ftruncate(e,t,this.makeCallback(i,n))})}ftruncateSync(e,t){return this.realFs.ftruncateSync(e,t)}watch(e,t,i){return this.realFs.watch(H.fromPortablePath(e),t,i)}watchFile(e,t,i){return this.realFs.watchFile(H.fromPortablePath(e),t,i)}unwatchFile(e,t){return this.realFs.unwatchFile(H.fromPortablePath(e),t)}makeCallback(e,t){return(i,n)=>{i?t(i):e(n)}}};var VO=ge(require("events"));var ac;(function(t){t.Change="change",t.Stop="stop"})(ac||(ac={}));var Ac;(function(i){i.Ready="ready",i.Running="running",i.Stopped="stopped"})(Ac||(Ac={}));function XO(r,e){if(r!==e)throw new Error(`Invalid StatWatcher status: expected '${e}', got '${r}'`)}var Jh=class extends VO.EventEmitter{constructor(e,t,{bigint:i=!1}={}){super();this.status=Ac.Ready;this.changeListeners=new Map;this.startTimeout=null;this.fakeFs=e,this.path=t,this.bigint=i,this.lastStats=this.stat()}static create(e,t,i){let n=new Jh(e,t,i);return n.start(),n}start(){XO(this.status,Ac.Ready),this.status=Ac.Running,this.startTimeout=setTimeout(()=>{this.startTimeout=null,this.fakeFs.existsSync(this.path)||this.emit(ac.Change,this.lastStats,this.lastStats)},3)}stop(){XO(this.status,Ac.Running),this.status=Ac.Stopped,this.startTimeout!==null&&(clearTimeout(this.startTimeout),this.startTimeout=null),this.emit(ac.Stop)}stat(){try{return this.fakeFs.statSync(this.path,{bigint:this.bigint})}catch(e){let t=this.bigint?new Uh:new jA;return RE(t)}}makeInterval(e){let t=setInterval(()=>{let i=this.stat(),n=this.lastStats;nQ(i,n)||(this.lastStats=i,this.emit(ac.Change,i,n))},e.interval);return e.persistent?t:t.unref()}registerChangeListener(e,t){this.addListener(ac.Change,e),this.changeListeners.set(e,this.makeInterval(t))}unregisterChangeListener(e){this.removeListener(ac.Change,e);let t=this.changeListeners.get(e);typeof t!="undefined"&&clearInterval(t),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 UE=new WeakMap;function HE(r,e,t,i){let n,s,o,a;switch(typeof t){case"function":n=!1,s=!0,o=5007,a=t;break;default:({bigint:n=!1,persistent:s=!0,interval:o=5007}=t),a=i;break}let l=UE.get(r);typeof l=="undefined"&&UE.set(r,l=new Map);let c=l.get(e);return typeof c=="undefined"&&(c=Jh.create(r,e,{bigint:n}),l.set(e,c)),c.registerChangeListener(a,{persistent:s,interval:o}),c}function Wh(r,e,t){let i=UE.get(r);if(typeof i=="undefined")return;let n=i.get(e);typeof n!="undefined"&&(typeof t=="undefined"?n.unregisterAllChangeListeners():n.unregisterChangeListener(t),n.hasChangeListeners()||(n.stop(),i.delete(e)))}function zh(r){let e=UE.get(r);if(typeof e!="undefined")for(let t of e.keys())Wh(r,t)}var lc="mixed";function bge(r){if(typeof r=="string"&&String(+r)===r)return+r;if(Number.isFinite(r))return r<0?Date.now()/1e3:r;if(ZO.types.isDate(r))return r.getTime()/1e3;throw new Error("Invalid time")}function $O(){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 li=class extends oc{constructor(e,t){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=t.libzip;let i=t;if(this.level=typeof i.level!="undefined"?i.level:lc,e!=null||(e=$O()),typeof e=="string"){let{baseFs:o=new ar}=i;this.baseFs=o,this.path=e}else this.path=null,this.baseFs=null;if(t.stats)this.stats=t.stats;else if(typeof e=="string")try{this.stats=this.baseFs.statSync(e)}catch(o){if(o.code==="ENOENT"&&i.create)this.stats=Hh();else throw o}else this.stats=Hh();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),t.readOnly&&(o|=this.libzip.ZIP_RDONLY,this.readOnly=!0),typeof e=="string")this.zip=this.libzip.open(H.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(Me.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(t,t+e);return Buffer.from(n)}finally{this.libzip.free(t)}}finally{this.libzip.source.close(this.lzSource),this.libzip.source.free(this.lzSource),this.ready=!1}}prepareClose(){if(!this.ready)throw OE("archive closed, close");zh(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===Kh?void 0:this.stats.mode;if(this.entries.size===0)this.discardAndClose(),this.baseFs.writeFileSync(this.path,$O(),{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 k.resolve(Me.root,e)}async openPromise(e,t,i){return this.openSync(e,t,i)}openSync(e,t,i){let n=this.nextFd++;return this.fds.set(n,{cursor:0,p:e}),n}hasOpenFileHandles(){return!!this.fds.size}async opendirPromise(e,t){return this.opendirSync(e,t)}opendirSync(e,t={}){let i=this.resolveFilename(`opendir '${e}'`,e);if(!this.entries.has(i)&&!this.listings.has(i))throw io(`opendir '${e}'`);let n=this.listings.get(i);if(!n)throw Ro(`opendir '${e}'`);let s=[...n],o=this.openSync(i,"r");return KE(this,i,s,{onClose:()=>{this.closeSync(o)}})}async readPromise(e,t,i,n,s){return this.readSync(e,t,i,n,s)}readSync(e,t,i=0,n=t.byteLength,s=-1){let o=this.fds.get(e);if(typeof o=="undefined")throw Ai("read");let a=s===-1||s===null?o.cursor:s,l=this.readFileSync(o.p);l.copy(t,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,t,i,n,s){return typeof t=="string"?this.writeSync(e,t,s):this.writeSync(e,t,i,n,s)}writeSync(e,t,i,n,s){throw typeof this.fds.get(e)=="undefined"?Ai("read"):new Error("Unimplemented")}async closePromise(e){return this.closeSync(e)}closeSync(e){if(typeof this.fds.get(e)=="undefined")throw Ai("read");this.fds.delete(e)}createReadStream(e,{encoding:t}={}){if(e===null)throw new Error("Unimplemented");let i=this.openSync(e,"r"),n=Object.assign(new cQ.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,t);n.bytesRead=o.length,n.end(o)}catch(o){n.destroy(o)}});return n}createWriteStream(e,{encoding:t}={}){if(this.readOnly)throw In(`open '${e}'`);if(e===null)throw new Error("Unimplemented");let i=[],n=this.openSync(e,"w"),s=Object.assign(new cQ.PassThrough({autoDestroy:!0,emitClose:!0,destroy:(o,a)=>{try{o?a(o):(this.writeFileSync(e,Buffer.concat(i),t),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 t=this.resolveFilename(`lstat '${e}'`,e);if(!this.entries.has(t)&&!this.listings.has(t))throw io(`lstat '${e}'`);return t}async existsPromise(e){return this.existsSync(e)}existsSync(e){if(!this.ready)throw OE(`archive closed, existsSync '${e}'`);if(this.symlinkCount===0){let i=k.resolve(Me.root,e);return this.entries.has(i)||this.listings.has(i)}let t;try{t=this.resolveFilename(`stat '${e}'`,e,void 0,!1)}catch(i){return!1}return t===void 0?!1:this.entries.has(t)||this.listings.has(t)}async accessPromise(e,t){return this.accessSync(e,t)}accessSync(e,t=zu.constants.F_OK){let i=this.resolveFilename(`access '${e}'`,e);if(!this.entries.has(i)&&!this.listings.has(i))throw io(`access '${e}'`);if(this.readOnly&&t&zu.constants.W_OK)throw In(`access '${e}'`)}async statPromise(e,t={bigint:!1}){return t.bigint?this.statSync(e,{bigint:!0}):this.statSync(e)}statSync(e,t={bigint:!1,throwIfNoEntry:!0}){let i=this.resolveFilename(`stat '${e}'`,e,void 0,t.throwIfNoEntry);if(i!==void 0){if(!this.entries.has(i)&&!this.listings.has(i)){if(t.throwIfNoEntry===!1)return;throw io(`stat '${e}'`)}if(e[e.length-1]==="/"&&!this.listings.has(i))throw Ro(`stat '${e}'`);return this.statImpl(`stat '${e}'`,i,t)}}async fstatPromise(e,t){return this.fstatSync(e,t)}fstatSync(e,t){let i=this.fds.get(e);if(typeof i=="undefined")throw Ai("fstatSync");let{p:n}=i,s=this.resolveFilename(`stat '${n}'`,n);if(!this.entries.has(s)&&!this.listings.has(s))throw io(`stat '${n}'`);if(n[n.length-1]==="/"&&!this.listings.has(s))throw Ro(`stat '${n}'`);return this.statImpl(`fstat '${n}'`,s,t)}async lstatPromise(e,t={bigint:!1}){return t.bigint?this.lstatSync(e,{bigint:!0}):this.lstatSync(e)}lstatSync(e,t={bigint:!1,throwIfNoEntry:!0}){let i=this.resolveFilename(`lstat '${e}'`,e,!1,t.throwIfNoEntry);if(i!==void 0){if(!this.entries.has(i)&&!this.listings.has(i)){if(t.throwIfNoEntry===!1)return;throw io(`lstat '${e}'`)}if(e[e.length-1]==="/"&&!this.listings.has(i))throw Ro(`lstat '${e}'`);return this.statImpl(`lstat '${e}'`,i,t)}}statImpl(e,t,i={}){let n=this.entries.get(t);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,m=f,y=new Date(h),b=new Date(p),v=new Date(m),x=new Date(f),T=this.listings.has(t)?Da:this.isSymbolicLink(n)?Fa:Ra,q=T===Da?493:420,Y=T|this.getUnixMode(n,q)&511,$=this.libzip.struct.statCrc(s),_=Object.assign(new jA,{uid:a,gid:l,size:c,blksize:u,blocks:g,atime:y,birthtime:b,ctime:v,mtime:x,atimeMs:h,birthtimeMs:p,ctimeMs:m,mtimeMs:f,mode:Y,crc:$});return i.bigint===!0?FE(_):_}if(this.listings.has(t)){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),m=new Date(g),y=new Date(f),b=new Date(h),v=Da|493,x=0,T=Object.assign(new jA,{uid:s,gid:o,size:a,blksize:l,blocks:c,atime:p,birthtime:m,ctime:y,mtime:b,atimeMs:u,birthtimeMs:g,ctimeMs:f,mtimeMs:h,mode:v,crc:x});return i.bigint===!0?FE(T):T}throw new Error("Unreachable")}getUnixMode(e,t){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?t:this.libzip.getValue(this.libzip.uint32S,"i32")>>>16}registerListing(e){let t=this.listings.get(e);if(t)return t;this.registerListing(k.dirname(e)).add(k.basename(e));let n=new Set;return this.listings.set(e,n),n}registerEntry(e,t){this.registerListing(k.dirname(e)).add(k.basename(e)),this.entries.set(e,t)}unregisterListing(e){this.listings.delete(e);let t=this.listings.get(k.dirname(e));t==null||t.delete(k.basename(e))}unregisterEntry(e){this.unregisterListing(e);let t=this.entries.get(e);this.entries.delete(e),typeof t!="undefined"&&(this.fileSources.delete(t),this.isSymbolicLink(t)&&this.symlinkCount--)}deleteEntry(e,t){if(this.unregisterEntry(e),this.libzip.delete(this.zip,t)===-1)throw this.makeLibzipError(this.libzip.getError(this.zip))}resolveFilename(e,t,i=!0,n=!0){if(!this.ready)throw OE(`archive closed, ${e}`);let s=k.resolve(Me.root,t);if(s==="/")return Me.root;let o=this.entries.get(s);if(i&&o!==void 0)if(this.symlinkCount!==0&&this.isSymbolicLink(o)){let a=this.getFileSource(o).toString();return this.resolveFilename(e,k.resolve(k.dirname(s),a),!0,n)}else return s;for(;;){let a=this.resolveFilename(e,k.dirname(s),!0,n);if(a===void 0)return a;let l=this.listings.has(a),c=this.entries.has(a);if(!l&&!c){if(n===!1)return;throw io(e)}if(!l)throw Ro(e);if(s=k.resolve(a,k.basename(s)),!i||this.symlinkCount===0)break;let u=this.libzip.name.locate(this.zip,s.slice(1));if(u===-1)break;if(this.isSymbolicLink(u)){let g=this.getFileSource(u).toString();s=k.resolve(k.dirname(s),g)}else break}return s}allocateBuffer(e){Buffer.isBuffer(e)||(e=Buffer.from(e));let t=this.libzip.malloc(e.byteLength);if(!t)throw new Error("Couldn't allocate enough memory");return new Uint8Array(this.libzip.HEAPU8.buffer,t,e.byteLength).set(e),{buffer:t,byteLength:e.byteLength}}allocateUnattachedSource(e){let t=this.libzip.struct.errorS(),{buffer:i,byteLength:n}=this.allocateBuffer(e),s=this.libzip.source.fromUnattachedBuffer(i,n,0,!0,t);if(s===0)throw this.libzip.free(t),this.makeLibzipError(t);return s}allocateSource(e){let{buffer:t,byteLength:i}=this.allocateBuffer(e),n=this.libzip.source.fromBuffer(this.zip,t,i,0,!0);if(n===0)throw this.libzip.free(t),this.makeLibzipError(this.libzip.getError(this.zip));return n}setFileSource(e,t){let i=Buffer.isBuffer(t)?t:Buffer.from(t),n=k.relative(Me.root,e),s=this.allocateSource(t);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=this.level===0?this.libzip.ZIP_CM_STORE:this.libzip.ZIP_CM_DEFLATE;if(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&_n)===Fa}getFileSource(e,t={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(t.asyncDecompress)return new Promise((h,p)=>{uQ.default.inflateRaw(f,(m,y)=>{m?p(m):(this.fileSources.set(e,y),h(y))})});{let h=uQ.default.inflateRawSync(f);return this.fileSources.set(e,h),h}}finally{this.libzip.fclose(c)}}finally{this.libzip.free(l)}}async fchmodPromise(e,t){return this.chmodPromise(this.fdToPath(e,"fchmod"),t)}fchmodSync(e,t){return this.chmodSync(this.fdToPath(e,"fchmodSync"),t)}async chmodPromise(e,t){return this.chmodSync(e,t)}chmodSync(e,t){if(this.readOnly)throw In(`chmod '${e}'`);t&=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,Ra|0)&~511|t;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,t,i){return this.chownSync(e,t,i)}chownSync(e,t,i){throw new Error("Unimplemented")}async renamePromise(e,t){return this.renameSync(e,t)}renameSync(e,t){throw new Error("Unimplemented")}async copyFilePromise(e,t,i){let{indexSource:n,indexDest:s,resolvedDestP:o}=this.prepareCopyFile(e,t,i),a=await this.getFileSource(n,{asyncDecompress:!0}),l=this.setFileSource(o,a);l!==s&&this.registerEntry(o,l)}copyFileSync(e,t,i=0){let{indexSource:n,indexDest:s,resolvedDestP:o}=this.prepareCopyFile(e,t,i),a=this.getFileSource(n),l=this.setFileSource(o,a);l!==s&&this.registerEntry(o,l)}prepareCopyFile(e,t,i=0){if(this.readOnly)throw In(`copyfile '${e} -> '${t}'`);if((i&zu.constants.COPYFILE_FICLONE_FORCE)!=0)throw Yh("unsupported clone operation",`copyfile '${e}' -> ${t}'`);let n=this.resolveFilename(`copyfile '${e} -> ${t}'`,e),s=this.entries.get(n);if(typeof s=="undefined")throw GA(`copyfile '${e}' -> '${t}'`);let o=this.resolveFilename(`copyfile '${e}' -> ${t}'`,t),a=this.entries.get(o);if((i&(zu.constants.COPYFILE_EXCL|zu.constants.COPYFILE_FICLONE_FORCE))!=0&&typeof a!="undefined")throw ME(`copyfile '${e}' -> '${t}'`);return{indexSource:s,resolvedDestP:o,indexDest:a}}async appendFilePromise(e,t,i){if(this.readOnly)throw In(`open '${e}'`);return typeof i=="undefined"?i={flag:"a"}:typeof i=="string"?i={flag:"a",encoding:i}:typeof i.flag=="undefined"&&(i=N({flag:"a"},i)),this.writeFilePromise(e,t,i)}appendFileSync(e,t,i={}){if(this.readOnly)throw In(`open '${e}'`);return typeof i=="undefined"?i={flag:"a"}:typeof i=="string"?i={flag:"a",encoding:i}:typeof i.flag=="undefined"&&(i=N({flag:"a"},i)),this.writeFileSync(e,t,i)}fdToPath(e,t){var n;let i=(n=this.fds.get(e))==null?void 0:n.p;if(typeof i=="undefined")throw Ai(t);return i}async writeFilePromise(e,t,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")&&(t=Buffer.concat([await this.getFileSource(o,{asyncDecompress:!0}),Buffer.from(t)])),n!==null&&(t=t.toString(n));let l=this.setFileSource(a,t);l!==o&&this.registerEntry(a,l),s!==null&&await this.chmodPromise(a,s)}writeFileSync(e,t,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")&&(t=Buffer.concat([this.getFileSource(o),Buffer.from(t)])),n!==null&&(t=t.toString(n));let l=this.setFileSource(a,t);l!==o&&this.registerEntry(a,l),s!==null&&this.chmodSync(a,s)}prepareWriteFile(e,t){if(typeof e=="number"&&(e=this.fdToPath(e,"read")),this.readOnly)throw In(`open '${e}'`);let i=this.resolveFilename(`open '${e}'`,e);if(this.listings.has(i))throw qh(`open '${e}'`);let n=null,s=null;typeof t=="string"?n=t:typeof t=="object"&&({encoding:n=null,mode:s=null}=t);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 In(`unlink '${e}'`);let t=this.resolveFilename(`unlink '${e}'`,e);if(this.listings.has(t))throw qh(`unlink '${e}'`);let i=this.entries.get(t);if(typeof i=="undefined")throw GA(`unlink '${e}'`);this.deleteEntry(t,i)}async utimesPromise(e,t,i){return this.utimesSync(e,t,i)}utimesSync(e,t,i){if(this.readOnly)throw In(`utimes '${e}'`);let n=this.resolveFilename(`utimes '${e}'`,e);this.utimesImpl(n,i)}async lutimesPromise(e,t,i){return this.lutimesSync(e,t,i)}lutimesSync(e,t,i){if(this.readOnly)throw In(`lutimes '${e}'`);let n=this.resolveFilename(`utimes '${e}'`,e,!1);this.utimesImpl(n,i)}utimesImpl(e,t){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,bge(t),0)===-1)throw this.makeLibzipError(this.libzip.getError(this.zip))}async mkdirPromise(e,t){return this.mkdirSync(e,t)}mkdirSync(e,{mode:t=493,recursive:i=!1}={}){if(i)return this.mkdirpSync(e,{chmod:t});if(this.readOnly)throw In(`mkdir '${e}'`);let n=this.resolveFilename(`mkdir '${e}'`,e);if(this.entries.has(n)||this.listings.has(n))throw ME(`mkdir '${e}'`);this.hydrateDirectory(n),this.chmodSync(n,t)}async rmdirPromise(e,t){return this.rmdirSync(e,t)}rmdirSync(e,{recursive:t=!1}={}){if(this.readOnly)throw In(`rmdir '${e}'`);if(t){this.removeSync(e);return}let i=this.resolveFilename(`rmdir '${e}'`,e),n=this.listings.get(i);if(!n)throw Ro(`rmdir '${e}'`);if(n.size>0)throw YO(`rmdir '${e}'`);let s=this.entries.get(i);if(typeof s=="undefined")throw GA(`rmdir '${e}'`);this.deleteEntry(e,s)}hydrateDirectory(e){let t=this.libzip.dir.add(this.zip,k.relative(Me.root,e));if(t===-1)throw this.makeLibzipError(this.libzip.getError(this.zip));return this.registerListing(e),this.registerEntry(e,t),t}async linkPromise(e,t){return this.linkSync(e,t)}linkSync(e,t){throw qO(`link '${e}' -> '${t}'`)}async symlinkPromise(e,t){return this.symlinkSync(e,t)}symlinkSync(e,t){if(this.readOnly)throw In(`symlink '${e}' -> '${t}'`);let i=this.resolveFilename(`symlink '${e}' -> '${t}'`,t);if(this.listings.has(i))throw qh(`symlink '${e}' -> '${t}'`);if(this.entries.has(i))throw ME(`symlink '${e}' -> '${t}'`);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,(Fa|511)<<16)===-1)throw this.makeLibzipError(this.libzip.getError(this.zip));this.symlinkCount+=1}async readFilePromise(e,t){typeof t=="object"&&(t=t?t.encoding:void 0);let i=await this.readFileBuffer(e,{asyncDecompress:!0});return t?i.toString(t):i}readFileSync(e,t){typeof t=="object"&&(t=t?t.encoding:void 0);let i=this.readFileBuffer(e);return t?i.toString(t):i}readFileBuffer(e,t={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 io(`open '${e}'`);if(e[e.length-1]==="/"&&!this.listings.has(i))throw Ro(`open '${e}'`);if(this.listings.has(i))throw qh("read");let n=this.entries.get(i);if(n===void 0)throw new Error("Unreachable");return this.getFileSource(n,t)}async readdirPromise(e,t){return this.readdirSync(e,t)}readdirSync(e,t){let i=this.resolveFilename(`scandir '${e}'`,e);if(!this.entries.has(i)&&!this.listings.has(i))throw io(`scandir '${e}'`);let n=this.listings.get(i);if(!n)throw Ro(`scandir '${e}'`);let s=[...n];return(t==null?void 0:t.withFileTypes)?s.map(o=>Object.assign(this.statImpl("lstat",k.join(e,o)),{name:o})):s}async readlinkPromise(e){let t=this.prepareReadlink(e);return(await this.getFileSource(t,{asyncDecompress:!0})).toString()}readlinkSync(e){let t=this.prepareReadlink(e);return this.getFileSource(t).toString()}prepareReadlink(e){let t=this.resolveFilename(`readlink '${e}'`,e,!1);if(!this.entries.has(t)&&!this.listings.has(t))throw io(`readlink '${e}'`);if(e[e.length-1]==="/"&&!this.listings.has(t))throw Ro(`open '${e}'`);if(this.listings.has(t))throw GA(`readlink '${e}'`);let i=this.entries.get(t);if(i===void 0)throw new Error("Unreachable");if(!this.isSymbolicLink(i))throw GA(`readlink '${e}'`);return i}async truncatePromise(e,t=0){let i=this.resolveFilename(`open '${e}'`,e),n=this.entries.get(i);if(typeof n=="undefined")throw GA(`open '${e}'`);let s=await this.getFileSource(n,{asyncDecompress:!0}),o=Buffer.alloc(t,0);return s.copy(o),await this.writeFilePromise(e,o)}truncateSync(e,t=0){let i=this.resolveFilename(`open '${e}'`,e),n=this.entries.get(i);if(typeof n=="undefined")throw GA(`open '${e}'`);let s=this.getFileSource(n),o=Buffer.alloc(t,0);return s.copy(o),this.writeFileSync(e,o)}async ftruncatePromise(e,t){return this.truncatePromise(this.fdToPath(e,"ftruncate"),t)}ftruncateSync(e,t){return this.truncateSync(this.fdToPath(e,"ftruncateSync"),t)}watch(e,t,i){let n;switch(typeof t){case"function":case"string":case"undefined":n=!0;break;default:({persistent:n=!0}=t);break}if(!n)return{on:()=>{},close:()=>{}};let s=setInterval(()=>{},24*60*60*1e3);return{on:()=>{},close:()=>{clearInterval(s)}}}watchFile(e,t,i){let n=k.resolve(Me.root,e);return HE(this,n,t,i)}unwatchFile(e,t){let i=k.resolve(Me.root,e);return Wh(this,i,t)}};var Qi=class extends YA{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,t,i){return this.baseFs.openPromise(this.mapToBase(e),t,i)}openSync(e,t,i){return this.baseFs.openSync(this.mapToBase(e),t,i)}async opendirPromise(e,t){return Object.assign(await this.baseFs.opendirPromise(this.mapToBase(e),t),{path:e})}opendirSync(e,t){return Object.assign(this.baseFs.opendirSync(this.mapToBase(e),t),{path:e})}async readPromise(e,t,i,n,s){return await this.baseFs.readPromise(e,t,i,n,s)}readSync(e,t,i,n,s){return this.baseFs.readSync(e,t,i,n,s)}async writePromise(e,t,i,n,s){return typeof t=="string"?await this.baseFs.writePromise(e,t,i):await this.baseFs.writePromise(e,t,i,n,s)}writeSync(e,t,i,n,s){return typeof t=="string"?this.baseFs.writeSync(e,t,i):this.baseFs.writeSync(e,t,i,n,s)}async closePromise(e){return this.baseFs.closePromise(e)}closeSync(e){this.baseFs.closeSync(e)}createReadStream(e,t){return this.baseFs.createReadStream(e!==null?this.mapToBase(e):e,t)}createWriteStream(e,t){return this.baseFs.createWriteStream(e!==null?this.mapToBase(e):e,t)}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,t){return this.baseFs.accessSync(this.mapToBase(e),t)}async accessPromise(e,t){return this.baseFs.accessPromise(this.mapToBase(e),t)}async statPromise(e,t){return this.baseFs.statPromise(this.mapToBase(e),t)}statSync(e,t){return this.baseFs.statSync(this.mapToBase(e),t)}async fstatPromise(e,t){return this.baseFs.fstatPromise(e,t)}fstatSync(e,t){return this.baseFs.fstatSync(e,t)}lstatPromise(e,t){return this.baseFs.lstatPromise(this.mapToBase(e),t)}lstatSync(e,t){return this.baseFs.lstatSync(this.mapToBase(e),t)}async fchmodPromise(e,t){return this.baseFs.fchmodPromise(e,t)}fchmodSync(e,t){return this.baseFs.fchmodSync(e,t)}async chmodPromise(e,t){return this.baseFs.chmodPromise(this.mapToBase(e),t)}chmodSync(e,t){return this.baseFs.chmodSync(this.mapToBase(e),t)}async chownPromise(e,t,i){return this.baseFs.chownPromise(this.mapToBase(e),t,i)}chownSync(e,t,i){return this.baseFs.chownSync(this.mapToBase(e),t,i)}async renamePromise(e,t){return this.baseFs.renamePromise(this.mapToBase(e),this.mapToBase(t))}renameSync(e,t){return this.baseFs.renameSync(this.mapToBase(e),this.mapToBase(t))}async copyFilePromise(e,t,i=0){return this.baseFs.copyFilePromise(this.mapToBase(e),this.mapToBase(t),i)}copyFileSync(e,t,i=0){return this.baseFs.copyFileSync(this.mapToBase(e),this.mapToBase(t),i)}async appendFilePromise(e,t,i){return this.baseFs.appendFilePromise(this.fsMapToBase(e),t,i)}appendFileSync(e,t,i){return this.baseFs.appendFileSync(this.fsMapToBase(e),t,i)}async writeFilePromise(e,t,i){return this.baseFs.writeFilePromise(this.fsMapToBase(e),t,i)}writeFileSync(e,t,i){return this.baseFs.writeFileSync(this.fsMapToBase(e),t,i)}async unlinkPromise(e){return this.baseFs.unlinkPromise(this.mapToBase(e))}unlinkSync(e){return this.baseFs.unlinkSync(this.mapToBase(e))}async utimesPromise(e,t,i){return this.baseFs.utimesPromise(this.mapToBase(e),t,i)}utimesSync(e,t,i){return this.baseFs.utimesSync(this.mapToBase(e),t,i)}async mkdirPromise(e,t){return this.baseFs.mkdirPromise(this.mapToBase(e),t)}mkdirSync(e,t){return this.baseFs.mkdirSync(this.mapToBase(e),t)}async rmdirPromise(e,t){return this.baseFs.rmdirPromise(this.mapToBase(e),t)}rmdirSync(e,t){return this.baseFs.rmdirSync(this.mapToBase(e),t)}async linkPromise(e,t){return this.baseFs.linkPromise(this.mapToBase(e),this.mapToBase(t))}linkSync(e,t){return this.baseFs.linkSync(this.mapToBase(e),this.mapToBase(t))}async symlinkPromise(e,t,i){let n=this.mapToBase(t);if(this.pathUtils.isAbsolute(e))return this.baseFs.symlinkPromise(this.mapToBase(e),n,i);let s=this.mapToBase(this.pathUtils.join(this.pathUtils.dirname(t),e)),o=this.baseFs.pathUtils.relative(this.baseFs.pathUtils.dirname(n),s);return this.baseFs.symlinkPromise(o,n,i)}symlinkSync(e,t,i){let n=this.mapToBase(t);if(this.pathUtils.isAbsolute(e))return this.baseFs.symlinkSync(this.mapToBase(e),n,i);let s=this.mapToBase(this.pathUtils.join(this.pathUtils.dirname(t),e)),o=this.baseFs.pathUtils.relative(this.baseFs.pathUtils.dirname(n),s);return this.baseFs.symlinkSync(o,n,i)}async readFilePromise(e,t){return t==="utf8"?this.baseFs.readFilePromise(this.fsMapToBase(e),t):this.baseFs.readFilePromise(this.fsMapToBase(e),t)}readFileSync(e,t){return t==="utf8"?this.baseFs.readFileSync(this.fsMapToBase(e),t):this.baseFs.readFileSync(this.fsMapToBase(e),t)}async readdirPromise(e,t){return this.baseFs.readdirPromise(this.mapToBase(e),t)}readdirSync(e,t){return this.baseFs.readdirSync(this.mapToBase(e),t)}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,t){return this.baseFs.truncatePromise(this.mapToBase(e),t)}truncateSync(e,t){return this.baseFs.truncateSync(this.mapToBase(e),t)}async ftruncatePromise(e,t){return this.baseFs.ftruncatePromise(e,t)}ftruncateSync(e,t){return this.baseFs.ftruncateSync(e,t)}watch(e,t,i){return this.baseFs.watch(this.mapToBase(e),t,i)}watchFile(e,t,i){return this.baseFs.watchFile(this.mapToBase(e),t,i)}unwatchFile(e,t){return this.baseFs.unwatchFile(this.mapToBase(e),t)}fsMapToBase(e){return typeof e=="number"?e:this.mapToBase(e)}};var Na=class extends Qi{constructor(e,{baseFs:t,pathUtils:i}){super(i);this.target=e,this.baseFs=t}getRealPath(){return this.target}getBaseFs(){return this.baseFs}mapFromBase(e){return e}mapToBase(e){return e}};var _t=class extends Qi{constructor(e,{baseFs:t=new ar}={}){super(k);this.target=this.pathUtils.normalize(e),this.baseFs=t}getRealPath(){return this.pathUtils.resolve(this.baseFs.getRealPath(),this.target)}resolve(e){return this.pathUtils.isAbsolute(e)?k.normalize(e):this.baseFs.resolve(k.join(this.target,e))}mapFromBase(e){return e}mapToBase(e){return this.pathUtils.isAbsolute(e)?e:this.pathUtils.join(this.target,e)}};var eM=Me.root,La=class extends Qi{constructor(e,{baseFs:t=new ar}={}){super(k);this.target=this.pathUtils.resolve(Me.root,e),this.baseFs=t}getRealPath(){return this.pathUtils.resolve(this.baseFs.getRealPath(),this.pathUtils.relative(Me.root,this.target))}getTarget(){return this.target}getBaseFs(){return this.baseFs}mapToBase(e){let t=this.pathUtils.normalize(e);if(this.pathUtils.isAbsolute(e))return this.pathUtils.resolve(this.target,this.pathUtils.relative(eM,e));if(t.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(eM,this.pathUtils.relative(this.target,e))}};var _h=class extends Qi{constructor(e,t){super(t);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 et=()=>Object.assign(new Error("ENOSYS: unsupported filesystem access"),{code:"ENOSYS"}),gQ=class extends YA{constructor(){super(k)}getExtractHint(){throw et()}getRealPath(){throw et()}resolve(){throw et()}async openPromise(){throw et()}openSync(){throw et()}async opendirPromise(){throw et()}opendirSync(){throw et()}async readPromise(){throw et()}readSync(){throw et()}async writePromise(){throw et()}writeSync(){throw et()}async closePromise(){throw et()}closeSync(){throw et()}createWriteStream(){throw et()}createReadStream(){throw et()}async realpathPromise(){throw et()}realpathSync(){throw et()}async readdirPromise(){throw et()}readdirSync(){throw et()}async existsPromise(e){throw et()}existsSync(e){throw et()}async accessPromise(){throw et()}accessSync(){throw et()}async statPromise(){throw et()}statSync(){throw et()}async fstatPromise(e){throw et()}fstatSync(e){throw et()}async lstatPromise(e){throw et()}lstatSync(e){throw et()}async fchmodPromise(){throw et()}fchmodSync(){throw et()}async chmodPromise(){throw et()}chmodSync(){throw et()}async chownPromise(){throw et()}chownSync(){throw et()}async mkdirPromise(){throw et()}mkdirSync(){throw et()}async rmdirPromise(){throw et()}rmdirSync(){throw et()}async linkPromise(){throw et()}linkSync(){throw et()}async symlinkPromise(){throw et()}symlinkSync(){throw et()}async renamePromise(){throw et()}renameSync(){throw et()}async copyFilePromise(){throw et()}copyFileSync(){throw et()}async appendFilePromise(){throw et()}appendFileSync(){throw et()}async writeFilePromise(){throw et()}writeFileSync(){throw et()}async unlinkPromise(){throw et()}unlinkSync(){throw et()}async utimesPromise(){throw et()}utimesSync(){throw et()}async readFilePromise(){throw et()}readFileSync(){throw et()}async readlinkPromise(){throw et()}readlinkSync(){throw et()}async truncatePromise(){throw et()}truncateSync(){throw et()}async ftruncatePromise(e,t){throw et()}ftruncateSync(e,t){throw et()}watch(){throw et()}watchFile(){throw et()}unwatchFile(){throw et()}},jE=gQ;jE.instance=new gQ;var Vh=class extends Qi{constructor(e){super(H);this.baseFs=e}mapFromBase(e){return H.fromPortablePath(e)}mapToBase(e){return H.toPortablePath(e)}};var Qge=/^[0-9]+$/,fQ=/^(\/(?:[^/]+\/)*?(?:\$\$virtual|__virtual__))((?:\/((?:[^/]+-)?[a-f0-9]+)(?:\/([^/]+))?)?((?:\/.*)?))$/,Sge=/^([^/]+-)?[a-f0-9]+$/,Wr=class extends Qi{static makeVirtualPath(e,t,i){if(k.basename(e)!=="__virtual__")throw new Error('Assertion failed: Virtual folders must be named "__virtual__"');if(!k.basename(t).match(Sge))throw new Error("Assertion failed: Virtual components must be ended by an hexadecimal hash");let s=k.relative(k.dirname(e),i).split("/"),o=0;for(;o{let t=r.indexOf(e);if(t<=0)return null;let i=t;for(;t>=0&&(i=t+e.length,r[i]!==k.sep);){if(r[t-1]===k.sep)return null;t=r.indexOf(e,i)}return r.length>i&&r[i]!==k.sep?null:r.slice(0,i)},Is=class extends oc{constructor({libzip:e,baseFs:t=new ar,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=t,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,t){let i=new Is(t);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(zh(this),this.zipInstances)for(let[e,{zipFs:t}]of this.zipInstances.entries())t.saveAndClose(),this.zipInstances.delete(e)}discardAndClose(){if(zh(this),this.zipInstances)for(let[e,{zipFs:t}]of this.zipInstances.entries())t.discardAndClose(),this.zipInstances.delete(e)}resolve(e){return this.baseFs.resolve(e)}remapFd(e,t){let i=this.nextFd++|Vn;return this.fdMap.set(i,[e,t]),i}async openPromise(e,t,i){return await this.makeCallPromise(e,async()=>await this.baseFs.openPromise(e,t,i),async(n,{subPath:s})=>this.remapFd(n,await n.openPromise(s,t,i)))}openSync(e,t,i){return this.makeCallSync(e,()=>this.baseFs.openSync(e,t,i),(n,{subPath:s})=>this.remapFd(n,n.openSync(s,t,i)))}async opendirPromise(e,t){return await this.makeCallPromise(e,async()=>await this.baseFs.opendirPromise(e,t),async(i,{subPath:n})=>await i.opendirPromise(n,t),{requireSubpath:!1})}opendirSync(e,t){return this.makeCallSync(e,()=>this.baseFs.opendirSync(e,t),(i,{subPath:n})=>i.opendirSync(n,t),{requireSubpath:!1})}async readPromise(e,t,i,n,s){if((e&Vn)==0)return await this.baseFs.readPromise(e,t,i,n,s);let o=this.fdMap.get(e);if(typeof o=="undefined")throw Ai("read");let[a,l]=o;return await a.readPromise(l,t,i,n,s)}readSync(e,t,i,n,s){if((e&Vn)==0)return this.baseFs.readSync(e,t,i,n,s);let o=this.fdMap.get(e);if(typeof o=="undefined")throw Ai("readSync");let[a,l]=o;return a.readSync(l,t,i,n,s)}async writePromise(e,t,i,n,s){if((e&Vn)==0)return typeof t=="string"?await this.baseFs.writePromise(e,t,i):await this.baseFs.writePromise(e,t,i,n,s);let o=this.fdMap.get(e);if(typeof o=="undefined")throw Ai("write");let[a,l]=o;return typeof t=="string"?await a.writePromise(l,t,i):await a.writePromise(l,t,i,n,s)}writeSync(e,t,i,n,s){if((e&Vn)==0)return typeof t=="string"?this.baseFs.writeSync(e,t,i):this.baseFs.writeSync(e,t,i,n,s);let o=this.fdMap.get(e);if(typeof o=="undefined")throw Ai("writeSync");let[a,l]=o;return typeof t=="string"?a.writeSync(l,t,i):a.writeSync(l,t,i,n,s)}async closePromise(e){if((e&Vn)==0)return await this.baseFs.closePromise(e);let t=this.fdMap.get(e);if(typeof t=="undefined")throw Ai("close");this.fdMap.delete(e);let[i,n]=t;return await i.closePromise(n)}closeSync(e){if((e&Vn)==0)return this.baseFs.closeSync(e);let t=this.fdMap.get(e);if(typeof t=="undefined")throw Ai("closeSync");this.fdMap.delete(e);let[i,n]=t;return i.closeSync(n)}createReadStream(e,t){return e===null?this.baseFs.createReadStream(e,t):this.makeCallSync(e,()=>this.baseFs.createReadStream(e,t),(i,{archivePath:n,subPath:s})=>{let o=i.createReadStream(s,t);return o.path=H.fromPortablePath(this.pathUtils.join(n,s)),o})}createWriteStream(e,t){return e===null?this.baseFs.createWriteStream(e,t):this.makeCallSync(e,()=>this.baseFs.createWriteStream(e,t),(i,{subPath:n})=>i.createWriteStream(n,t))}async realpathPromise(e){return await this.makeCallPromise(e,async()=>await this.baseFs.realpathPromise(e),async(t,{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(Me.root,await t.realpathPromise(n)))})}realpathSync(e){return this.makeCallSync(e,()=>this.baseFs.realpathSync(e),(t,{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(Me.root,t.realpathSync(n)))})}async existsPromise(e){return await this.makeCallPromise(e,async()=>await this.baseFs.existsPromise(e),async(t,{subPath:i})=>await t.existsPromise(i))}existsSync(e){return this.makeCallSync(e,()=>this.baseFs.existsSync(e),(t,{subPath:i})=>t.existsSync(i))}async accessPromise(e,t){return await this.makeCallPromise(e,async()=>await this.baseFs.accessPromise(e,t),async(i,{subPath:n})=>await i.accessPromise(n,t))}accessSync(e,t){return this.makeCallSync(e,()=>this.baseFs.accessSync(e,t),(i,{subPath:n})=>i.accessSync(n,t))}async statPromise(e,t){return await this.makeCallPromise(e,async()=>await this.baseFs.statPromise(e,t),async(i,{subPath:n})=>await i.statPromise(n,t))}statSync(e,t){return this.makeCallSync(e,()=>this.baseFs.statSync(e,t),(i,{subPath:n})=>i.statSync(n,t))}async fstatPromise(e,t){if((e&Vn)==0)return this.baseFs.fstatPromise(e,t);let i=this.fdMap.get(e);if(typeof i=="undefined")throw Ai("fstat");let[n,s]=i;return n.fstatPromise(s,t)}fstatSync(e,t){if((e&Vn)==0)return this.baseFs.fstatSync(e,t);let i=this.fdMap.get(e);if(typeof i=="undefined")throw Ai("fstatSync");let[n,s]=i;return n.fstatSync(s,t)}async lstatPromise(e,t){return await this.makeCallPromise(e,async()=>await this.baseFs.lstatPromise(e,t),async(i,{subPath:n})=>await i.lstatPromise(n,t))}lstatSync(e,t){return this.makeCallSync(e,()=>this.baseFs.lstatSync(e,t),(i,{subPath:n})=>i.lstatSync(n,t))}async fchmodPromise(e,t){if((e&Vn)==0)return this.baseFs.fchmodPromise(e,t);let i=this.fdMap.get(e);if(typeof i=="undefined")throw Ai("fchmod");let[n,s]=i;return n.fchmodPromise(s,t)}fchmodSync(e,t){if((e&Vn)==0)return this.baseFs.fchmodSync(e,t);let i=this.fdMap.get(e);if(typeof i=="undefined")throw Ai("fchmodSync");let[n,s]=i;return n.fchmodSync(s,t)}async chmodPromise(e,t){return await this.makeCallPromise(e,async()=>await this.baseFs.chmodPromise(e,t),async(i,{subPath:n})=>await i.chmodPromise(n,t))}chmodSync(e,t){return this.makeCallSync(e,()=>this.baseFs.chmodSync(e,t),(i,{subPath:n})=>i.chmodSync(n,t))}async chownPromise(e,t,i){return await this.makeCallPromise(e,async()=>await this.baseFs.chownPromise(e,t,i),async(n,{subPath:s})=>await n.chownPromise(s,t,i))}chownSync(e,t,i){return this.makeCallSync(e,()=>this.baseFs.chownSync(e,t,i),(n,{subPath:s})=>n.chownSync(s,t,i))}async renamePromise(e,t){return await this.makeCallPromise(e,async()=>await this.makeCallPromise(t,async()=>await this.baseFs.renamePromise(e,t),async()=>{throw Object.assign(new Error("EEXDEV: cross-device link not permitted"),{code:"EEXDEV"})}),async(i,{subPath:n})=>await this.makeCallPromise(t,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,t){return this.makeCallSync(e,()=>this.makeCallSync(t,()=>this.baseFs.renameSync(e,t),()=>{throw Object.assign(new Error("EEXDEV: cross-device link not permitted"),{code:"EEXDEV"})}),(i,{subPath:n})=>this.makeCallSync(t,()=>{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,t,i=0){let n=async(s,o,a,l)=>{if((i&Xh.constants.COPYFILE_FICLONE_FORCE)!=0)throw Object.assign(new Error(`EXDEV: cross-device clone not permitted, copyfile '${o}' -> ${l}'`),{code:"EXDEV"});if(i&Xh.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(t,async()=>await this.baseFs.copyFilePromise(e,t,i),async(s,{subPath:o})=>await n(this.baseFs,e,s,o)),async(s,{subPath:o})=>await this.makeCallPromise(t,async()=>await n(s,o,this.baseFs,t),async(a,{subPath:l})=>s!==a?await n(s,o,a,l):await s.copyFilePromise(o,l,i)))}copyFileSync(e,t,i=0){let n=(s,o,a,l)=>{if((i&Xh.constants.COPYFILE_FICLONE_FORCE)!=0)throw Object.assign(new Error(`EXDEV: cross-device clone not permitted, copyfile '${o}' -> ${l}'`),{code:"EXDEV"});if(i&Xh.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(t,()=>this.baseFs.copyFileSync(e,t,i),(s,{subPath:o})=>n(this.baseFs,e,s,o)),(s,{subPath:o})=>this.makeCallSync(t,()=>n(s,o,this.baseFs,t),(a,{subPath:l})=>s!==a?n(s,o,a,l):s.copyFileSync(o,l,i)))}async appendFilePromise(e,t,i){return await this.makeCallPromise(e,async()=>await this.baseFs.appendFilePromise(e,t,i),async(n,{subPath:s})=>await n.appendFilePromise(s,t,i))}appendFileSync(e,t,i){return this.makeCallSync(e,()=>this.baseFs.appendFileSync(e,t,i),(n,{subPath:s})=>n.appendFileSync(s,t,i))}async writeFilePromise(e,t,i){return await this.makeCallPromise(e,async()=>await this.baseFs.writeFilePromise(e,t,i),async(n,{subPath:s})=>await n.writeFilePromise(s,t,i))}writeFileSync(e,t,i){return this.makeCallSync(e,()=>this.baseFs.writeFileSync(e,t,i),(n,{subPath:s})=>n.writeFileSync(s,t,i))}async unlinkPromise(e){return await this.makeCallPromise(e,async()=>await this.baseFs.unlinkPromise(e),async(t,{subPath:i})=>await t.unlinkPromise(i))}unlinkSync(e){return this.makeCallSync(e,()=>this.baseFs.unlinkSync(e),(t,{subPath:i})=>t.unlinkSync(i))}async utimesPromise(e,t,i){return await this.makeCallPromise(e,async()=>await this.baseFs.utimesPromise(e,t,i),async(n,{subPath:s})=>await n.utimesPromise(s,t,i))}utimesSync(e,t,i){return this.makeCallSync(e,()=>this.baseFs.utimesSync(e,t,i),(n,{subPath:s})=>n.utimesSync(s,t,i))}async mkdirPromise(e,t){return await this.makeCallPromise(e,async()=>await this.baseFs.mkdirPromise(e,t),async(i,{subPath:n})=>await i.mkdirPromise(n,t))}mkdirSync(e,t){return this.makeCallSync(e,()=>this.baseFs.mkdirSync(e,t),(i,{subPath:n})=>i.mkdirSync(n,t))}async rmdirPromise(e,t){return await this.makeCallPromise(e,async()=>await this.baseFs.rmdirPromise(e,t),async(i,{subPath:n})=>await i.rmdirPromise(n,t))}rmdirSync(e,t){return this.makeCallSync(e,()=>this.baseFs.rmdirSync(e,t),(i,{subPath:n})=>i.rmdirSync(n,t))}async linkPromise(e,t){return await this.makeCallPromise(t,async()=>await this.baseFs.linkPromise(e,t),async(i,{subPath:n})=>await i.linkPromise(e,n))}linkSync(e,t){return this.makeCallSync(t,()=>this.baseFs.linkSync(e,t),(i,{subPath:n})=>i.linkSync(e,n))}async symlinkPromise(e,t,i){return await this.makeCallPromise(t,async()=>await this.baseFs.symlinkPromise(e,t,i),async(n,{subPath:s})=>await n.symlinkPromise(e,s))}symlinkSync(e,t,i){return this.makeCallSync(t,()=>this.baseFs.symlinkSync(e,t,i),(n,{subPath:s})=>n.symlinkSync(e,s))}async readFilePromise(e,t){return this.makeCallPromise(e,async()=>{switch(t){case"utf8":return await this.baseFs.readFilePromise(e,t);default:return await this.baseFs.readFilePromise(e,t)}},async(i,{subPath:n})=>await i.readFilePromise(n,t))}readFileSync(e,t){return this.makeCallSync(e,()=>{switch(t){case"utf8":return this.baseFs.readFileSync(e,t);default:return this.baseFs.readFileSync(e,t)}},(i,{subPath:n})=>i.readFileSync(n,t))}async readdirPromise(e,t){return await this.makeCallPromise(e,async()=>await this.baseFs.readdirPromise(e,t),async(i,{subPath:n})=>await i.readdirPromise(n,t),{requireSubpath:!1})}readdirSync(e,t){return this.makeCallSync(e,()=>this.baseFs.readdirSync(e,t),(i,{subPath:n})=>i.readdirSync(n,t),{requireSubpath:!1})}async readlinkPromise(e){return await this.makeCallPromise(e,async()=>await this.baseFs.readlinkPromise(e),async(t,{subPath:i})=>await t.readlinkPromise(i))}readlinkSync(e){return this.makeCallSync(e,()=>this.baseFs.readlinkSync(e),(t,{subPath:i})=>t.readlinkSync(i))}async truncatePromise(e,t){return await this.makeCallPromise(e,async()=>await this.baseFs.truncatePromise(e,t),async(i,{subPath:n})=>await i.truncatePromise(n,t))}truncateSync(e,t){return this.makeCallSync(e,()=>this.baseFs.truncateSync(e,t),(i,{subPath:n})=>i.truncateSync(n,t))}async ftruncatePromise(e,t){if((e&Vn)==0)return this.baseFs.ftruncatePromise(e,t);let i=this.fdMap.get(e);if(typeof i=="undefined")throw Ai("ftruncate");let[n,s]=i;return n.ftruncatePromise(s,t)}ftruncateSync(e,t){if((e&Vn)==0)return this.baseFs.ftruncateSync(e,t);let i=this.fdMap.get(e);if(typeof i=="undefined")throw Ai("ftruncateSync");let[n,s]=i;return n.ftruncateSync(s,t)}watch(e,t,i){return this.makeCallSync(e,()=>this.baseFs.watch(e,t,i),(n,{subPath:s})=>n.watch(s,t,i))}watchFile(e,t,i){return this.makeCallSync(e,()=>this.baseFs.watchFile(e,t,i),()=>HE(this,e,t,i))}unwatchFile(e,t){return this.makeCallSync(e,()=>this.baseFs.unwatchFile(e,t),()=>Wh(this,e,t))}async makeCallPromise(e,t,i,{requireSubpath:n=!0}={}){if(typeof e!="string")return await t();let s=this.resolve(e),o=this.findZip(s);return o?n&&o.subPath==="/"?await t():await this.getZipPromise(o.archivePath,async a=>await i(a,o)):await t()}makeCallSync(e,t,i,{requireSubpath:n=!0}={}){if(typeof e!="string")return t();let s=this.resolve(e),o=this.findZip(s);return!o||n&&o.subPath==="/"?t():this.getZipSync(o.archivePath,a=>i(a,o))}findZip(e){if(this.filter&&!this.filter.test(e))return null;let t="";for(;;){let i=e.substring(t.length),n;if(!this.fileExtensions)n=tM(i,".zip");else for(let s of this.fileExtensions)if(n=tM(i,s),n)break;if(!n)return null;if(t=this.pathUtils.join(t,n),this.isZip.has(t)===!1){if(this.notZip.has(t))continue;try{if(!this.baseFs.lstatSync(t).isFile()){this.notZip.add(t);continue}}catch{return null}this.isZip.add(t)}return{archivePath:t,subPath:this.pathUtils.join(Me.root,e.substring(t.length))}}}limitOpenFiles(e){if(this.zipInstances===null)return;let t=Date.now(),i=t+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(t>=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-t).unref())}async getZipPromise(e,t){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 li(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 t(n.zipFs)}finally{n.refCount-=1}}else{let n=new li(e,await i());try{return await t(n)}finally{n.saveAndClose()}}}getZipSync(e,t){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 li(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,t(n.zipFs)}else{let n=new li(e,i());try{return t(n)}finally{n.saveAndClose()}}}};var Vu=ge(require("util"));var GE=ge(require("url"));var hQ=class extends Qi{constructor(e){super(H);this.baseFs=e}mapFromBase(e){return e}mapToBase(e){return e instanceof GE.URL?(0,GE.fileURLToPath)(e):e}};var en=Symbol("kBaseFs"),Ta=Symbol("kFd"),qA=Symbol("kClosePromise"),YE=Symbol("kCloseResolve"),qE=Symbol("kCloseReject"),_u=Symbol("kRefs"),Fo=Symbol("kRef"),No=Symbol("kUnref"),Q6e,S6e,v6e,x6e,JE=class{constructor(e,t){this[Q6e]=1;this[S6e]=void 0;this[v6e]=void 0;this[x6e]=void 0;this[en]=t,this[Ta]=e}get fd(){return this[Ta]}async appendFile(e,t){var i;try{this[Fo](this.appendFile);let n=(i=typeof t=="string"?t:t==null?void 0:t.encoding)!=null?i:void 0;return await this[en].appendFilePromise(this.fd,e,n?{encoding:n}:void 0)}finally{this[No]()}}chown(e,t){throw new Error("Method not implemented.")}async chmod(e){try{return this[Fo](this.chmod),await this[en].fchmodPromise(this.fd,e)}finally{this[No]()}}createReadStream(e){return this[en].createReadStream(null,te(N({},e),{fd:this.fd}))}createWriteStream(e){return this[en].createWriteStream(null,te(N({},e),{fd:this.fd}))}datasync(){throw new Error("Method not implemented.")}sync(){throw new Error("Method not implemented.")}async read(e,t,i,n){var s,o,a;try{this[Fo](this.read);let l;return Buffer.isBuffer(e)?l=e:(e!=null||(e={}),l=(s=e.buffer)!=null?s:Buffer.alloc(16384),t=e.offset||0,i=(o=e.length)!=null?o:l.byteLength,n=(a=e.position)!=null?a:null),t!=null||(t=0),i!=null||(i=0),i===0?{bytesRead:i,buffer:l}:{bytesRead:await this[en].readPromise(this.fd,l,t,i,n),buffer:l}}finally{this[No]()}}async readFile(e){var t;try{this[Fo](this.readFile);let i=(t=typeof e=="string"?e:e==null?void 0:e.encoding)!=null?t:void 0;return await this[en].readFilePromise(this.fd,i)}finally{this[No]()}}async stat(e){try{return this[Fo](this.stat),await this[en].fstatPromise(this.fd,e)}finally{this[No]()}}async truncate(e){try{return this[Fo](this.truncate),await this[en].ftruncatePromise(this.fd,e)}finally{this[No]()}}utimes(e,t){throw new Error("Method not implemented.")}async writeFile(e,t){var i;try{this[Fo](this.writeFile);let n=(i=typeof t=="string"?t:t==null?void 0:t.encoding)!=null?i:void 0;await this[en].writeFilePromise(this.fd,e,n)}finally{this[No]()}}async write(...e){try{if(this[Fo](this.write),ArrayBuffer.isView(e[0])){let[t,i,n,s]=e;return{bytesWritten:await this[en].writePromise(this.fd,t,i!=null?i:void 0,n!=null?n:void 0,s!=null?s:void 0),buffer:t}}else{let[t,i,n]=e;return{bytesWritten:await this[en].writePromise(this.fd,t,i,n),buffer:t}}}finally{this[No]()}}async writev(e,t){try{this[Fo](this.writev);let i=0;if(typeof t!="undefined")for(let n of e){let s=await this.write(n,void 0,void 0,t);i+=s.bytesWritten,t+=s.bytesWritten}else for(let n of e)i+=(await this.write(n)).bytesWritten;return{buffers:e,bytesWritten:i}}finally{this[No]()}}readv(e,t){throw new Error("Method not implemented.")}close(){if(this[Ta]===-1)return Promise.resolve();if(this[qA])return this[qA];if(this[_u]--,this[_u]===0){let e=this[Ta];this[Ta]=-1,this[qA]=this[en].closePromise(e).finally(()=>{this[qA]=void 0})}else this[qA]=new Promise((e,t)=>{this[YE]=e,this[qE]=t}).finally(()=>{this[qA]=void 0,this[qE]=void 0,this[YE]=void 0});return this[qA]}[(en,Ta,Q6e=_u,S6e=qA,v6e=YE,x6e=qE,Fo)](e){if(this[Ta]===-1){let t=new Error("file closed");throw t.code="EBADF",t.syscall=e.name,t}this[_u]++}[No](){if(this[_u]--,this[_u]===0){let e=this[Ta];this[Ta]=-1,this[en].closePromise(e).then(this[YE],this[qE])}}};var vge=new Set(["accessSync","appendFileSync","createReadStream","createWriteStream","chmodSync","fchmodSync","chownSync","closeSync","copyFileSync","linkSync","lstatSync","fstatSync","lutimesSync","mkdirSync","openSync","opendirSync","readlinkSync","readFileSync","readdirSync","readlinkSync","realpathSync","renameSync","rmdirSync","statSync","symlinkSync","truncateSync","ftruncateSync","unlinkSync","unwatchFile","utimesSync","watch","watchFile","writeFileSync","writeSync"]),rM=new Set(["accessPromise","appendFilePromise","fchmodPromise","chmodPromise","chownPromise","closePromise","copyFilePromise","linkPromise","fstatPromise","lstatPromise","lutimesPromise","mkdirPromise","openPromise","opendirPromise","readdirPromise","realpathPromise","readFilePromise","readdirPromise","readlinkPromise","renamePromise","rmdirPromise","statPromise","symlinkPromise","truncatePromise","ftruncatePromise","unlinkPromise","utimesPromise","writeFilePromise","writeSync"]);function pQ(r,e){e=new hQ(e);let t=(i,n,s)=>{let o=i[n];i[n]=s,typeof(o==null?void 0:o[Vu.promisify.custom])!="undefined"&&(s[Vu.promisify.custom]=o[Vu.promisify.custom])};{t(r,"exists",(i,...n)=>{let o=typeof n[n.length-1]=="function"?n.pop():()=>{};process.nextTick(()=>{e.existsPromise(i).then(a=>{o(a)},()=>{o(!1)})})}),t(r,"read",(...i)=>{let[n,s,o,a,l,c]=i;if(i.length<=3){let u={};i.length<3?c=i[1]:(u=i[1],c=i[2]),{buffer:s=Buffer.alloc(16384),offset:o=0,length:a=s.byteLength,position:l}=u}if(o==null&&(o=0),a|=0,a===0){process.nextTick(()=>{c(null,0,s)});return}l==null&&(l=-1),process.nextTick(()=>{e.readPromise(n,s,o,a,l).then(u=>{c(null,u,s)},u=>{c(u,0,s)})})});for(let i of rM){let n=i.replace(/Promise$/,"");if(typeof r[n]=="undefined")continue;let s=e[i];if(typeof s=="undefined")continue;t(r,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)})})})}r.realpath.native=r.realpath}{t(r,"existsSync",i=>{try{return e.existsSync(i)}catch(n){return!1}}),t(r,"readSync",(...i)=>{let[n,s,o,a,l]=i;return i.length<=3&&({offset:o=0,length:a=s.byteLength,position:l}=i[2]||{}),o==null&&(o=0),a|=0,a===0?0:(l==null&&(l=-1),e.readSync(n,s,o,a,l))});for(let i of vge){let n=i;if(typeof r[n]=="undefined")continue;let s=e[i];typeof s!="undefined"&&t(r,n,s.bind(e))}r.realpathSync.native=r.realpathSync}{let i=process.emitWarning;process.emitWarning=()=>{};let n;try{n=r.promises}finally{process.emitWarning=i}if(typeof n!="undefined"){for(let s of rM){let o=s.replace(/Promise$/,"");if(typeof n[o]=="undefined")continue;let a=e[s];typeof a!="undefined"&&s!=="open"&&t(n,o,(l,...c)=>l instanceof JE?l[o].apply(l,c):a.call(e,l,...c))}t(n,"open",async(...s)=>{let o=await e.openPromise(...s);return new JE(o,e)})}}r.read[Vu.promisify.custom]=async(i,n,...s)=>({bytesRead:await e.readPromise(i,n,...s),buffer:n}),r.write[Vu.promisify.custom]=async(i,n,...s)=>({bytesWritten:await e.writePromise(i,n,...s),buffer:n})}function WE(r,e){let t=Object.create(r);return pQ(t,e),t}var iM=ge(require("os"));function nM(r){let e=Math.ceil(Math.random()*4294967296).toString(16).padStart(8,"0");return`${r}${e}`}var no=new Set,dQ=null;function sM(){if(dQ)return dQ;let r=H.toPortablePath(iM.default.tmpdir()),e=K.realpathSync(r);return process.once("exit",()=>{K.rmtempSync()}),dQ={tmpdir:r,realTmpdir:e}}var K=Object.assign(new ar,{detachTemp(r){no.delete(r)},mktempSync(r){let{tmpdir:e,realTmpdir:t}=sM();for(;;){let i=nM("xfs-");try{this.mkdirSync(k.join(e,i))}catch(s){if(s.code==="EEXIST")continue;throw s}let n=k.join(t,i);if(no.add(n),typeof r=="undefined")return n;try{return r(n)}finally{if(no.has(n)){no.delete(n);try{this.removeSync(n)}catch{}}}}},async mktempPromise(r){let{tmpdir:e,realTmpdir:t}=sM();for(;;){let i=nM("xfs-");try{await this.mkdirPromise(k.join(e,i))}catch(s){if(s.code==="EEXIST")continue;throw s}let n=k.join(t,i);if(no.add(n),typeof r=="undefined")return n;try{return await r(n)}finally{if(no.has(n)){no.delete(n);try{await this.removePromise(n)}catch{}}}}},async rmtempPromise(){await Promise.all(Array.from(no.values()).map(async r=>{try{await K.removePromise(r,{maxRetries:0}),no.delete(r)}catch{}}))},rmtempSync(){for(let r of no)try{K.removeSync(r),no.delete(r)}catch{}}});var mk=ge(SQ());var op={};ft(op,{parseResolution:()=>$E,parseShell:()=>_E,parseSyml:()=>Si,stringifyArgument:()=>PQ,stringifyArgumentSegment:()=>DQ,stringifyArithmeticExpression:()=>ZE,stringifyCommand:()=>kQ,stringifyCommandChain:()=>eg,stringifyCommandChainThen:()=>xQ,stringifyCommandLine:()=>VE,stringifyCommandLineThen:()=>vQ,stringifyEnvSegment:()=>XE,stringifyRedirectArgument:()=>$h,stringifyResolution:()=>eI,stringifyShell:()=>$u,stringifyShellLine:()=>$u,stringifySyml:()=>Ma,stringifyValueArgument:()=>uc});var _M=ge(zM());function _E(r,e={isGlobPattern:()=>!1}){try{return(0,_M.parse)(r,e)}catch(t){throw t.location&&(t.message=t.message.replace(/(\.)?$/,` (line ${t.location.start.line}, column ${t.location.start.column})$1`)),t}}function $u(r,{endSemicolon:e=!1}={}){return r.map(({command:t,type:i},n)=>`${VE(t)}${i===";"?n!==r.length-1||e?";":"":" &"}`).join(" ")}function VE(r){return`${eg(r.chain)}${r.then?` ${vQ(r.then)}`:""}`}function vQ(r){return`${r.type} ${VE(r.line)}`}function eg(r){return`${kQ(r)}${r.then?` ${xQ(r.then)}`:""}`}function xQ(r){return`${r.type} ${eg(r.chain)}`}function kQ(r){switch(r.type){case"command":return`${r.envs.length>0?`${r.envs.map(e=>XE(e)).join(" ")} `:""}${r.args.map(e=>PQ(e)).join(" ")}`;case"subshell":return`(${$u(r.subshell)})${r.args.length>0?` ${r.args.map(e=>$h(e)).join(" ")}`:""}`;case"group":return`{ ${$u(r.group,{endSemicolon:!0})} }${r.args.length>0?` ${r.args.map(e=>$h(e)).join(" ")}`:""}`;case"envs":return r.envs.map(e=>XE(e)).join(" ");default:throw new Error(`Unsupported command type: "${r.type}"`)}}function XE(r){return`${r.name}=${r.args[0]?uc(r.args[0]):""}`}function PQ(r){switch(r.type){case"redirection":return $h(r);case"argument":return uc(r);default:throw new Error(`Unsupported argument type: "${r.type}"`)}}function $h(r){return`${r.subtype} ${r.args.map(e=>uc(e)).join(" ")}`}function uc(r){return r.segments.map(e=>DQ(e)).join("")}function DQ(r){let e=(i,n)=>n?`"${i}"`:i,t=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(r.type){case"text":return t(r.text);case"glob":return r.pattern;case"shell":return e(`\${${$u(r.shell)}}`,r.quoted);case"variable":return e(typeof r.defaultValue=="undefined"?typeof r.alternativeValue=="undefined"?`\${${r.name}}`:r.alternativeValue.length===0?`\${${r.name}:+}`:`\${${r.name}:+${r.alternativeValue.map(i=>uc(i)).join(" ")}}`:r.defaultValue.length===0?`\${${r.name}:-}`:`\${${r.name}:-${r.defaultValue.map(i=>uc(i)).join(" ")}}`,r.quoted);case"arithmetic":return`$(( ${ZE(r.arithmetic)} ))`;default:throw new Error(`Unsupported argument segment type: "${r.type}"`)}}function ZE(r){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}"`)}},t=(n,s)=>s?`( ${n} )`:n,i=n=>t(ZE(n),!["number","variable"].includes(n.type));switch(r.type){case"number":return String(r.value);case"variable":return r.name;default:return`${i(r.left)} ${e(r.type)} ${i(r.right)}`}}var ZM=ge(XM());function $E(r){let e=r.match(/^\*{1,2}\/(.*)/);if(e)throw new Error(`The override for '${r}' 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,ZM.parse)(r)}catch(t){throw t.location&&(t.message=t.message.replace(/(\.)?$/,` (line ${t.location.start.line}, column ${t.location.start.column})$1`)),t}}function eI(r){let e="";return r.from&&(e+=r.from.fullName,r.from.description&&(e+=`@${r.from.description}`),e+="/"),e+=r.descriptor.fullName,r.descriptor.description&&(e+=`@${r.descriptor.description}`),e}var uI=ge(jK()),qK=ge(YK()),Tpe=/^(?![-?:,\][{}#&*!|>'"%@` \t\r\n]).([ \t]*(?![,\][{}:# \t\r\n]).)*$/,JK=["__metadata","version","resolution","dependencies","peerDependencies","dependenciesMeta","peerDependenciesMeta","binaries"],YQ=class{constructor(e){this.data=e}};function WK(r){return r.match(Tpe)?r:JSON.stringify(r)}function zK(r){return typeof r=="undefined"?!0:typeof r=="object"&&r!==null?Object.keys(r).every(e=>zK(r[e])):!1}function qQ(r,e,t){if(r===null)return`null -`;if(typeof r=="number"||typeof r=="boolean")return`${r.toString()} -`;if(typeof r=="string")return`${WK(r)} -`;if(Array.isArray(r)){if(r.length===0)return`[] -`;let i=" ".repeat(e);return` -${r.map(s=>`${i}- ${qQ(s,e+1,!1)}`).join("")}`}if(typeof r=="object"&&r){let i,n;r instanceof YQ?(i=r.data,n=!1):(i=r,n=!0);let s=" ".repeat(e),o=Object.keys(i);n&&o.sort((l,c)=>{let u=JK.indexOf(l),g=JK.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=>!zK(i[l])).map((l,c)=>{let u=i[l],g=WK(l),f=qQ(u,e+1,!0),h=c>0||t?s:"",p=g.length>1024?`? ${g} -${h}:`:`${g}:`,m=f.startsWith(` -`)?f:` ${f}`;return`${h}${p}${m}`}).join(e===0?` -`:"")||` -`;return t?` -${a}`:`${a}`}throw new Error(`Unsupported value type (${r})`)}function Ma(r){try{let e=qQ(r,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}}Ma.PreserveOrdering=YQ;function Ope(r){return r.endsWith(` -`)||(r+=` -`),(0,qK.parse)(r)}var Mpe=/^(#.*(\r?\n))*?#\s+yarn\s+lockfile\s+v1\r?\n/i;function Kpe(r){if(Mpe.test(r))return Ope(r);let e=(0,uI.safeLoad)(r,{schema:uI.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 Si(r){return Kpe(r)}var T4=ge(VK()),mw=ge(Ic());var Cp={};ft(Cp,{Builtins:()=>oS,Cli:()=>ws,Command:()=>Re,Option:()=>J,UsageError:()=>Pe,formatMarkdownish:()=>Ui});var yc=0,ap=1,tn=2,WQ="",vi="\0",lg=-1,zQ=/^(-h|--help)(?:=([0-9]+))?$/,gI=/^(--[a-z]+(?:-[a-z]+)*|-[a-zA-Z]+)$/,tU=/^-[a-zA-Z]{2,}$/,_Q=/^([^=]+)=([\s\S]*)$/,VQ=process.env.DEBUG_CLI==="1";var Pe=class extends Error{constructor(e){super(e);this.clipanion={type:"usage"},this.name="UsageError"}},Ap=class extends Error{constructor(e,t){super();if(this.input=e,this.candidates=t,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===t[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} -${XQ(e)}`}else this.message=`Command not found; did you mean one of: - -${this.candidates.map(({usage:i},n)=>`${`${n}.`.padStart(4)} ${i}`).join(` -`)} - -${XQ(e)}`}},ZQ=class extends Error{constructor(e,t){super();this.input=e,this.usages=t,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(` -`)} - -${XQ(e)}`}},XQ=r=>`While running ${r.filter(e=>e!==vi).map(e=>{let t=JSON.stringify(e);return e.match(/\s/)||e.length===0||t!==`"${e}"`?t:e}).join(" ")}`;var lp=Symbol("clipanion/isOption");function rn(r){return te(N({},r),{[lp]:!0})}function Oo(r,e){return typeof r=="undefined"?[r,e]:typeof r=="object"&&r!==null&&!Array.isArray(r)?[void 0,r]:[r,e]}function fI(r,e=!1){let t=r.replace(/^\.: /,"");return e&&(t=t[0].toLowerCase()+t.slice(1)),t}function cp(r,e){return e.length===1?new Pe(`${r}: ${fI(e[0],!0)}`):new Pe(`${r}: -${e.map(t=>` -- ${fI(t)}`).join("")}`)}function up(r,e,t){if(typeof t=="undefined")return e;let i=[],n=[],s=a=>{let l=e;return e=a,s.bind(null,l)};if(!t(e,{errors:i,coercions:n,coercion:s}))throw cp(`Invalid value for ${r}`,i);for(let[,a]of n)a();return e}var Re=class{constructor(){this.help=!1}static Usage(e){return e}async catch(e){throw e}async validateAndExecute(){let t=this.constructor.schema;if(Array.isArray(t)){let{isDict:n,isUnknown:s,applyCascade:o}=await Promise.resolve().then(()=>(ys(),cg)),a=o(n(s()),t),l=[],c=[];if(!a(this,{errors:l,coercions:c}))throw cp("Invalid option schema",l);for(let[,g]of c)g()}else if(t!=null)throw new Error("Invalid command schema");let i=await this.execute();return typeof i!="undefined"?i:0}};Re.isOption=lp;Re.Default=[];var uU=80,tS=Array(uU).fill("\u2501");for(let r=0;r<=24;++r)tS[tS.length-r]=`[38;5;${232+r}m\u2501`;var rS={header:r=>`\u2501\u2501\u2501 ${r}${r.length`${r}`,error:r=>`${r}`,code:r=>`${r}`},gU={header:r=>r,bold:r=>r,error:r=>r,code:r=>r};function yde(r){let e=r.split(` -`),t=e.filter(n=>n.match(/\S/)),i=t.length>0?t.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 Ui(r,{format:e,paragraphs:t}){return r=r.replace(/\r\n?/g,` -`),r=yde(r),r=r.replace(/^\n+|\n+$/g,""),r=r.replace(/^(\s*)-([^\n]*?)\n+/gm,`$1-$2 - -`),r=r.replace(/\n(\n)?\n*/g,"$1"),t&&(r=r.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(` - -`)),r=r.replace(/(`+)((?:.|[\n])*?)\1/g,(i,n,s)=>e.code(n+s+n)),r=r.replace(/(\*\*)((?:.|[\n])*?)\1/g,(i,n,s)=>e.bold(n+s+n)),r?`${r} -`:""}var sS=ge(require("tty"));function wn(r){VQ&&console.log(r)}var fU={candidateUsage:null,requiredOptions:[],errorMessage:null,ignoreOptions:!1,path:[],positionals:[],options:[],remainder:null,selectedIndex:lg};function hU(){return{nodes:[sn(),sn(),sn()]}}function Bde(r){let e=hU(),t=[],i=e.nodes.length;for(let n of r){t.push(i);for(let s=0;s{if(e.has(i))return;e.add(i);let n=r.nodes[i];for(let o of Object.values(n.statics))for(let{to:a}of o)t(a);for(let[,{to:o}]of n.dynamics)t(o);for(let{to:o}of n.shortcuts)t(o);let s=new Set(n.shortcuts.map(({to:o})=>o));for(;n.shortcuts.length>0;){let{to:o}=n.shortcuts.shift(),a=r.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))}};t(yc)}function Qde(r,{prefix:e=""}={}){if(VQ){wn(`${e}Nodes are:`);for(let t=0;tl!==tn).map(({state:l})=>({usage:l.candidateUsage,reason:null})));if(a.every(({node:l})=>l===tn))throw new Ap(e,a.map(({state:l})=>({usage:l.candidateUsage,reason:l.errorMessage})));i=Sde(a)}if(i.length>0){wn(" Results:");for(let s of i)wn(` - ${s.node} -> ${JSON.stringify(s.state)}`)}else wn(" No results");return i}function vde(r,e){if(e.selectedIndex!==null)return!0;if(Object.prototype.hasOwnProperty.call(r.statics,vi)){for(let{to:t}of r.statics[vi])if(t===ap)return!0}return!1}function kde(r,e,t){let i=t&&e.length>0?[""]:[],n=dU(r,e,t),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 m=r.nodes[p],y=Object.keys(m.statics);for(let b of Object.keys(m.statics)){let v=y[0];for(let{to:x,reducer:T}of m.statics[v])T==="pushPath"&&(u||l.push(v),g.push(x))}}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=r.nodes[l],g=vde(u,c);for(let[f,h]of Object.entries(u.statics))(g&&f!==vi||!f.startsWith("-")&&h.some(({reducer:p})=>p==="pushPath"))&&a([...i,f],l);if(!!g)for(let[f,{to:h}]of u.dynamics){if(h===tn)continue;let p=xde(f,c);if(p!==null)for(let m of p)a([...i,m],l)}}return[...s].sort()}function Dde(r,e){let t=dU(r,[...e,vi]);return Pde(e,t.map(({state:i})=>i))}function Sde(r){let e=0;for(let{state:t}of r)t.path.length>e&&(e=t.path.length);return r.filter(({state:t})=>t.path.length===e)}function Pde(r,e){let t=e.filter(g=>g.selectedIndex!==null);if(t.length===0)throw new Error;let i=t.filter(g=>g.requiredOptions.every(f=>f.some(h=>g.options.find(p=>p.name===h))));if(i.length===0)throw new Ap(r,t.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=Rde(c);if(u.length>1)throw new ZQ(r,u.map(g=>g.candidateUsage));return u[0]}function Rde(r){let e=[],t=[];for(let i of r)i.selectedIndex===lg?t.push(i):e.push(i);return t.length>0&&e.push(te(N({},fU),{path:CU(...t.map(i=>i.path)),options:t.reduce((i,n)=>i.concat(n.options),[])})),e}function CU(r,e,...t){return e===void 0?Array.from(r):CU(r.filter((i,n)=>i===e[n]),...t)}function sn(){return{dynamics:[],shortcuts:[],statics:{}}}function pU(r){return r===ap||r===tn}function nS(r,e=0){return{to:pU(r.to)?r.to:r.to>2?r.to+e-2:r.to+e,reducer:r.reducer}}function wde(r,e=0){let t=sn();for(let[i,n]of r.dynamics)t.dynamics.push([i,nS(n,e)]);for(let i of r.shortcuts)t.shortcuts.push(nS(i,e));for(let[i,n]of Object.entries(r.statics))t.statics[i]=n.map(s=>nS(s,e));return t}function xi(r,e,t,i,n){r.nodes[e].dynamics.push([t,{to:i,reducer:n}])}function ug(r,e,t,i){r.nodes[e].shortcuts.push({to:t,reducer:i})}function Ka(r,e,t,i,n){(Object.prototype.hasOwnProperty.call(r.nodes[e].statics,t)?r.nodes[e].statics[t]:r.nodes[e].statics[t]=[]).push({to:i,reducer:n})}function pI(r,e,t,i){if(Array.isArray(e)){let[n,...s]=e;return r[n](t,i,...s)}else return r[e](t,i)}function xde(r,e){let t=Array.isArray(r)?dI[r[0]]:dI[r];if(typeof t.suggest=="undefined")return null;let i=Array.isArray(r)?r.slice(1):[];return t.suggest(e,...i)}var dI={always:()=>!0,isOptionLike:(r,e)=>!r.ignoreOptions&&e!=="-"&&e.startsWith("-"),isNotOptionLike:(r,e)=>r.ignoreOptions||e==="-"||!e.startsWith("-"),isOption:(r,e,t,i)=>!r.ignoreOptions&&e===t,isBatchOption:(r,e,t)=>!r.ignoreOptions&&tU.test(e)&&[...e.slice(1)].every(i=>t.includes(`-${i}`)),isBoundOption:(r,e,t,i)=>{let n=e.match(_Q);return!r.ignoreOptions&&!!n&&gI.test(n[1])&&t.includes(n[1])&&i.filter(s=>s.names.includes(n[1])).every(s=>s.allowBinding)},isNegatedOption:(r,e,t)=>!r.ignoreOptions&&e===`--no-${t.slice(2)}`,isHelp:(r,e)=>!r.ignoreOptions&&zQ.test(e),isUnsupportedOption:(r,e,t)=>!r.ignoreOptions&&e.startsWith("-")&&gI.test(e)&&!t.includes(e),isInvalidOption:(r,e)=>!r.ignoreOptions&&e.startsWith("-")&&!gI.test(e)};dI.isOption.suggest=(r,e,t=!0)=>t?null:[e];var iS={setCandidateState:(r,e,t)=>N(N({},r),t),setSelectedIndex:(r,e,t)=>te(N({},r),{selectedIndex:t}),pushBatch:(r,e)=>te(N({},r),{options:r.options.concat([...e.slice(1)].map(t=>({name:`-${t}`,value:!0})))}),pushBound:(r,e)=>{let[,t,i]=e.match(_Q);return te(N({},r),{options:r.options.concat({name:t,value:i})})},pushPath:(r,e)=>te(N({},r),{path:r.path.concat(e)}),pushPositional:(r,e)=>te(N({},r),{positionals:r.positionals.concat({value:e,extra:!1})}),pushExtra:(r,e)=>te(N({},r),{positionals:r.positionals.concat({value:e,extra:!0})}),pushExtraNoLimits:(r,e)=>te(N({},r),{positionals:r.positionals.concat({value:e,extra:Zn})}),pushTrue:(r,e,t=e)=>te(N({},r),{options:r.options.concat({name:e,value:!0})}),pushFalse:(r,e,t=e)=>te(N({},r),{options:r.options.concat({name:t,value:!1})}),pushUndefined:(r,e)=>te(N({},r),{options:r.options.concat({name:e,value:void 0})}),pushStringValue:(r,e)=>{var t;let i=te(N({},r),{options:[...r.options]}),n=r.options[r.options.length-1];return n.value=((t=n.value)!==null&&t!==void 0?t:[]).concat([e]),i},setStringValue:(r,e)=>{let t=te(N({},r),{options:[...r.options]}),i=r.options[r.options.length-1];return i.value=e,t},inhibateOptions:r=>te(N({},r),{ignoreOptions:!0}),useHelp:(r,e,t)=>{let[,,i]=e.match(zQ);return typeof i!="undefined"?te(N({},r),{options:[{name:"-c",value:String(t)},{name:"-i",value:i}]}):te(N({},r),{options:[{name:"-c",value:String(t)}]})},setError:(r,e,t)=>e===vi?te(N({},r),{errorMessage:`${t}.`}):te(N({},r),{errorMessage:`${t} ("${e}").`}),setOptionArityError:(r,e)=>{let t=r.options[r.options.length-1];return te(N({},r),{errorMessage:`Not enough arguments to option ${t.name}.`})}},Zn=Symbol(),mU=class{constructor(e,t){this.allOptionNames=[],this.arity={leading:[],trailing:[],extra:[],proxy:!1},this.options=[],this.paths=[],this.cliIndex=e,this.cliOpts=t}addPath(e){this.paths.push(e)}setArity({leading:e=this.arity.leading,trailing:t=this.arity.trailing,extra:i=this.arity.extra,proxy:n=this.arity.proxy}){Object.assign(this.arity,{leading:e,trailing:t,extra:i,proxy:n})}addPositional({name:e="arg",required:t=!0}={}){if(!t&&this.arity.extra===Zn)throw new Error("Optional parameters cannot be declared when using .rest() or .proxy()");if(!t&&this.arity.trailing.length>0)throw new Error("Optional parameters cannot be declared after the required trailing positional arguments");!t&&this.arity.extra!==Zn?this.arity.extra.push(e):this.arity.extra!==Zn&&this.arity.extra.length===0?this.arity.leading.push(e):this.arity.trailing.push(e)}addRest({name:e="arg",required:t=0}={}){if(this.arity.extra===Zn)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:t,arity:i,hidden:n,required:s,allowBinding:o})}setContext(e){this.context=e}usage({detailed:e=!0,inlineOptions:t=!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===Zn?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=hU(),t=yc,i=this.usage().usage,n=this.options.filter(a=>a.required).map(a=>a.names);t=so(e,sn()),Ka(e,yc,WQ,t,["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=t;if(a.length>0){let f=so(e,sn());ug(e,l,f),this.registerOptions(e,f),l=f}for(let f=0;f0||!this.arity.proxy){let f=so(e,sn());xi(e,l,"isHelp",f,["useHelp",this.cliIndex]),Ka(e,f,vi,ap,["setSelectedIndex",lg]),this.registerOptions(e,l)}this.arity.leading.length>0&&Ka(e,l,vi,tn,["setError","Not enough positional arguments"]);let c=l;for(let f=0;f0||f+1!==this.arity.leading.length)&&Ka(e,h,vi,tn,["setError","Not enough positional arguments"]),xi(e,c,"isNotOptionLike",h,"pushPositional"),c=h}let u=c;if(this.arity.extra===Zn||this.arity.extra.length>0){let f=so(e,sn());if(ug(e,c,f),this.arity.extra===Zn){let h=so(e,sn());this.arity.proxy||this.registerOptions(e,h),xi(e,c,s,h,"pushExtraNoLimits"),xi(e,h,s,h,"pushExtraNoLimits"),ug(e,h,f)}else for(let h=0;h0&&Ka(e,u,vi,tn,["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)xi(e,t,["isOption",s,i.hidden||s!==n],t,"pushTrue"),s.startsWith("--")&&!s.startsWith("--no-")&&xi(e,t,["isNegatedOption",s],t,["pushFalse",s]);else{let s=so(e,sn());for(let o of i.names)xi(e,t,["isOption",o,i.hidden||o!==n],s,"pushUndefined");for(let o=0;o=0&&eDde(i,n),suggest:(n,s)=>kde(i,n,s)}}};var dp=class extends Re{constructor(e){super();this.contexts=e,this.commands=[]}static from(e,t){let i=new dp(t);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 t=0;for(let i of this.commands)this.context.stdout.write(this.cli.usage(this.contexts[i].commandClass,{prefix:`${t++}. `.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 EU=Symbol("clipanion/errorCommand");function Fde(){return process.env.FORCE_COLOR==="0"?1:process.env.FORCE_COLOR==="1"||typeof process.stdout!="undefined"&&process.stdout.isTTY?8:1}var ws=class{constructor({binaryLabel:e,binaryName:t="...",binaryVersion:i,enableCapture:n=!1,enableColors:s}={}){this.registrations=new Map,this.builder=new pp({binaryName:t}),this.binaryLabel=e,this.binaryName=t,this.binaryVersion=i,this.enableCapture=n,this.enableColors=s}static from(e,t={}){let i=new ws(t);for(let n of e)i.register(n);return i}register(e){var t;let i=new Map,n=new e;for(let l in n){let c=n[l];typeof c=="object"&&c!==null&&c[Re.isOption]&&i.set(l,c)}let s=this.builder.command(),o=s.cliIndex,a=(t=e.paths)!==null&&t!==void 0?t: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:t,process:i}=this.builder.compile(),n=i(e);switch(n.selectedIndex){case lg:return dp.from(n,t);default:{let{commandClass:s}=t[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[EU]=a,l}}break}}async run(e,t){var i;let n,s=N(N({},ws.defaultContext),t),o=(i=this.enableColors)!==null&&i!==void 0?i:s.colorDepth>1;if(!Array.isArray(e))n=e;else try{n=this.process(e)}catch(c){return s.stdout.write(this.error(c,{colored:o})),1}if(n.help)return s.stdout.write(this.usage(n,{colored:o,detailed:!0})),0;n.context=s,n.cli={binaryLabel:this.binaryLabel,binaryName:this.binaryName,binaryVersion:this.binaryVersion,enableCapture:this.enableCapture,enableColors:this.enableColors,definitions:()=>this.definitions(),error:(c,u)=>this.error(c,u),format:c=>this.format(c),process:c=>this.process(c),run:(c,u)=>this.run(c,N(N({},s),u)),usage:(c,u)=>this.usage(c,u)};let a=this.enableCapture?Nde(s):IU,l;try{l=await a(()=>n.validateAndExecute().catch(c=>n.catch(c).then(()=>0)))}catch(c){return s.stdout.write(this.error(c,{colored:o,command:n})),1}return l}async runExit(e,t){process.exitCode=await this.run(e,t)}suggest(e,t){let{suggest:i}=this.builder.compile();return i(e,t)}definitions({colored:e=!1}={}){let t=[];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"?Ui(i.usage.category,{format:this.format(e),paragraphs:!1}):void 0,c=typeof i.usage.description!="undefined"?Ui(i.usage.description,{format:this.format(e),paragraphs:!1}):void 0,u=typeof i.usage.details!="undefined"?Ui(i.usage.details,{format:this.format(e),paragraphs:!0}):void 0,g=typeof i.usage.examples!="undefined"?i.usage.examples.map(([f,h])=>[Ui(f,{format:this.format(e),paragraphs:!1}),h.replace(/\$0/g,this.binaryName)]):void 0;t.push({path:s,usage:o,category:l,description:c,details:u,examples:g,options:a})}return t}usage(e=null,{colored:t,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 Re?e.constructor:e,a="";if(o)if(i){let{description:l="",details:c="",examples:u=[]}=o.usage||{};l!==""&&(a+=Ui(l,{format:this.format(t),paragraphs:!1}).replace(/^./,h=>h.toUpperCase()),a+=` -`),(c!==""||u.length>0)&&(a+=`${this.format(t).header("Usage")} -`,a+=` -`);let{usage:g,options:f}=this.getUsageByRegistration(o,{inlineOptions:!1});if(a+=`${this.format(t).bold(n)}${g} -`,f.length>0){a+=` -`,a+=`${rS.header("Options")} -`;let h=f.reduce((p,m)=>Math.max(p,m.definition.length),0);a+=` -`;for(let{definition:p,description:m}of f)a+=` ${this.format(t).bold(p.padEnd(h))} ${Ui(m,{format:this.format(t),paragraphs:!1})}`}if(c!==""&&(a+=` -`,a+=`${this.format(t).header("Details")} -`,a+=` -`,a+=Ui(c,{format:this.format(t),paragraphs:!0})),u.length>0){a+=` -`,a+=`${this.format(t).header("Examples")} -`;for(let[h,p]of u)a+=` -`,a+=Ui(h,{format:this.format(t),paragraphs:!1}),a+=`${p.replace(/^/m,` ${this.format(t).bold(n)}`).replace(/\$0/g,this.binaryName)} -`}}else{let{usage:l}=this.getUsageByRegistration(o);a+=`${this.format(t).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"?Ui(f.usage.category,{format:this.format(t),paragraphs:!1}):null,m=l.get(p);typeof m=="undefined"&&l.set(p,m=[]);let{usage:y}=this.getUsageByIndex(h);m.push({commandClass:f,usage:y})}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(t).header(`${this.binaryLabel} - ${this.binaryVersion}`)} - -`:u?a+=`${this.format(t).header(`${this.binaryLabel}`)} -`:a+=`${this.format(t).header(`${this.binaryVersion}`)} -`,a+=` ${this.format(t).bold(n)}${this.binaryName} -`):a+=`${this.format(t).bold(n)}${this.binaryName} -`;for(let f of c){let h=l.get(f).slice().sort((m,y)=>m.usage.localeCompare(y.usage,"en",{usage:"sort",caseFirst:"upper"})),p=f!==null?f.trim():"General commands";a+=` -`,a+=`${this.format(t).header(`${p}`)} -`;for(let{commandClass:m,usage:y}of h){let b=m.usage.description||"undocumented";a+=` -`,a+=` ${this.format(t).bold(y)} -`,a+=` ${Ui(b,{format:this.format(t),paragraphs:!1})}`}}a+=` -`,a+=Ui("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(t),paragraphs:!0})}return a}error(e,t){var i,{colored:n,command:s=(i=e[EU])!==null&&i!==void 0?i:null}=t===void 0?{}:t;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}format(e){var t;return((t=e!=null?e:this.enableColors)!==null&&t!==void 0?t:ws.defaultContext.colorDepth>1)?rS:gU}getUsageByRegistration(e,t){let i=this.registrations.get(e);if(typeof i=="undefined")throw new Error("Assertion failed: Unregistered command");return this.getUsageByIndex(i.index,t)}getUsageByIndex(e,t){return this.builder.getBuilderByIndex(e).usage(t)}};ws.defaultContext={stdin:process.stdin,stdout:process.stdout,stderr:process.stderr,colorDepth:"getColorDepth"in sS.default.WriteStream.prototype?sS.default.WriteStream.prototype.getColorDepth():Fde()};var yU;function Nde(r){let e=yU;if(typeof e=="undefined"){if(r.stdout===process.stdout&&r.stderr===process.stderr)return IU;let{AsyncLocalStorage:t}=require("async_hooks");e=yU=new t;let i=process.stdout._write;process.stdout._write=function(s,o,a){let l=e.getStore();return typeof l=="undefined"?i.call(this,s,o,a):l.stdout.write(s,o,a)};let n=process.stderr._write;process.stderr._write=function(s,o,a){let l=e.getStore();return typeof l=="undefined"?n.call(this,s,o,a):l.stderr.write(s,o,a)}}return t=>e.run(r,t)}function IU(r){return r()}var oS={};ft(oS,{DefinitionsCommand:()=>CI,HelpCommand:()=>mI,VersionCommand:()=>EI});var CI=class extends Re{async execute(){this.context.stdout.write(`${JSON.stringify(this.cli.definitions(),null,2)} -`)}};CI.paths=[["--clipanion=definitions"]];var mI=class extends Re{async execute(){this.context.stdout.write(this.cli.usage())}};mI.paths=[["-h"],["--help"]];var EI=class extends Re{async execute(){var e;this.context.stdout.write(`${(e=this.cli.binaryVersion)!==null&&e!==void 0?e:""} -`)}};EI.paths=[["-v"],["--version"]];var J={};ft(J,{Array:()=>wU,Boolean:()=>BU,Counter:()=>bU,Proxy:()=>QU,Rest:()=>SU,String:()=>vU,applyValidator:()=>up,cleanValidationError:()=>fI,formatError:()=>cp,isOptionSymbol:()=>lp,makeCommandOption:()=>rn,rerouteArguments:()=>Oo});function wU(r,e,t){let[i,n]=Oo(e,t!=null?t:{}),{arity:s=1}=n,o=r.split(","),a=new Set(o);return rn({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 BU(r,e,t){let[i,n]=Oo(e,t!=null?t:{}),s=r.split(","),o=new Set(s);return rn({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 bU(r,e,t){let[i,n]=Oo(e,t!=null?t:{}),s=r.split(","),o=new Set(s);return rn({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 QU(r={}){return rn({definition(e,t){var i;e.addProxy({name:(i=r.name)!==null&&i!==void 0?i:t,required:r.required})},transformer(e,t,i){return i.positionals.map(({value:n})=>n)}})}function SU(r={}){return rn({definition(e,t){var i;e.addRest({name:(i=r.name)!==null&&i!==void 0?i:t,required:r.required})},transformer(e,t,i){let n=o=>{let a=i.positionals[o];return a.extra===Zn||a.extra===!1&&oo)}})}function Lde(r,e,t){let[i,n]=Oo(e,t!=null?t:{}),{arity:s=1}=n,o=r.split(","),a=new Set(o);return rn({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"?up(g!=null?g:c,f,n.validator):f}})}function Tde(r={}){let{required:e=!0}=r;return rn({definition(t,i){var n;t.addPositional({name:(n=r.name)!==null&&n!==void 0?n:i,required:r.required})},transformer(t,i,n){var s;for(let o=0;oYW,areIdentsEqual:()=>fd,areLocatorsEqual:()=>hd,areVirtualPackagesEquivalent:()=>aSe,bindDescriptor:()=>sSe,bindLocator:()=>oSe,convertDescriptorToLocator:()=>Aw,convertLocatorToDescriptor:()=>_x,convertPackageToLocator:()=>nSe,convertToIdent:()=>iSe,convertToManifestRange:()=>cSe,copyPackage:()=>cd,devirtualizeDescriptor:()=>ud,devirtualizeLocator:()=>gd,getIdentVendorPath:()=>ek,isPackageCompatible:()=>gw,isVirtualDescriptor:()=>Al,isVirtualLocator:()=>ea,makeDescriptor:()=>rr,makeIdent:()=>$o,makeLocator:()=>cn,makeRange:()=>cw,parseDescriptor:()=>ll,parseFileStyleRange:()=>ASe,parseIdent:()=>An,parseLocator:()=>Yc,parseRange:()=>qg,prettyDependent:()=>Lv,prettyDescriptor:()=>sr,prettyIdent:()=>fi,prettyLocator:()=>It,prettyLocatorNoColors:()=>$x,prettyRange:()=>aw,prettyReference:()=>dd,prettyResolution:()=>Tv,prettyWorkspace:()=>Cd,renamePackage:()=>ld,slugifyIdent:()=>Zx,slugifyLocator:()=>Jg,sortDescriptors:()=>Wg,stringifyDescriptor:()=>Pn,stringifyIdent:()=>Ot,stringifyLocator:()=>Rs,tryParseDescriptor:()=>pd,tryParseIdent:()=>qW,tryParseLocator:()=>lw,virtualizeDescriptor:()=>Vx,virtualizePackage:()=>Xx});var Yg=ge(require("querystring")),HW=ge(ri()),jW=ge(nY());var ae={};ft(ae,{LogLevel:()=>ho,Style:()=>Tc,Type:()=>qe,addLogFilterSupport:()=>nd,applyColor:()=>ns,applyHyperlink:()=>Mg,applyStyle:()=>Ry,json:()=>Oc,jsonOrPretty:()=>KBe,mark:()=>Hv,pretty:()=>tt,prettyField:()=>_o,prettyList:()=>Uv,supportsColor:()=>Py,supportsHyperlinks:()=>Mv,tuple:()=>fo});var rd=ge(uv()),id=ge(Ic());var sJ=ge(is()),oJ=ge(Jq());var Se={};ft(Se,{AsyncActions:()=>$q,BufferStream:()=>Zq,CachingStrategy:()=>Lc,DefaultStream:()=>eJ,allSettledSafe:()=>go,assertNever:()=>Pv,bufferStream:()=>Tg,buildIgnorePattern:()=>LBe,convertMapsToIndexableObjects:()=>ky,dynamicRequire:()=>Og,escapeRegExp:()=>PBe,getArrayWithDefault:()=>Fg,getFactoryWithDefault:()=>_a,getMapWithDefault:()=>Ng,getSetWithDefault:()=>Nc,isIndexableObject:()=>Dv,isPathLike:()=>TBe,isTaggedYarnVersion:()=>kBe,mapAndFilter:()=>zo,mapAndFind:()=>$p,overrideType:()=>kv,parseBoolean:()=>td,parseOptionalBoolean:()=>nJ,prettifyAsyncErrors:()=>Lg,prettifySyncErrors:()=>Rv,releaseAfterUseAsync:()=>RBe,replaceEnvVariables:()=>Fv,sortMap:()=>kn,tryParseOptionalBoolean:()=>Nv,validateEnum:()=>DBe});var Wq=ge(is()),zq=ge(gg()),_q=ge(ri()),xv=ge(require("stream"));function kBe(r){return!!(_q.default.valid(r)&&r.match(/^[^-]+(-rc\.[0-9]+)?$/))}function PBe(r){return r.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function kv(r){}function Pv(r){throw new Error(`Assertion failed: Unexpected object '${r}'`)}function DBe(r,e){let t=Object.values(r);if(!t.includes(e))throw new Pe(`Invalid value for enumeration: ${JSON.stringify(e)} (expected one of ${t.map(i=>JSON.stringify(i)).join(", ")})`);return e}function zo(r,e){let t=[];for(let i of r){let n=e(i);n!==Vq&&t.push(n)}return t}var Vq=Symbol();zo.skip=Vq;function $p(r,e){for(let t of r){let i=e(t);if(i!==Xq)return i}}var Xq=Symbol();$p.skip=Xq;function Dv(r){return typeof r=="object"&&r!==null}async function go(r){let e=await Promise.allSettled(r),t=[];for(let i of e){if(i.status==="rejected")throw i.reason;t.push(i.value)}return t}function ky(r){if(r instanceof Map&&(r=Object.fromEntries(r)),Dv(r))for(let e of Object.keys(r)){let t=r[e];Dv(t)&&(r[e]=ky(t))}return r}function _a(r,e,t){let i=r.get(e);return typeof i=="undefined"&&r.set(e,i=t()),i}function Fg(r,e){let t=r.get(e);return typeof t=="undefined"&&r.set(e,t=[]),t}function Nc(r,e){let t=r.get(e);return typeof t=="undefined"&&r.set(e,t=new Set),t}function Ng(r,e){let t=r.get(e);return typeof t=="undefined"&&r.set(e,t=new Map),t}async function RBe(r,e){if(e==null)return await r();try{return await r()}finally{await e()}}async function Lg(r,e){try{return await r()}catch(t){throw t.message=e(t.message),t}}function Rv(r,e){try{return r()}catch(t){throw t.message=e(t.message),t}}async function Tg(r){return await new Promise((e,t)=>{let i=[];r.on("error",n=>{t(n)}),r.on("data",n=>{i.push(n)}),r.on("end",()=>{e(Buffer.concat(i))})})}var Zq=class extends xv.Transform{constructor(){super(...arguments);this.chunks=[]}_transform(e,t,i){if(t!=="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))}};function FBe(){let r,e;return{promise:new Promise((i,n)=>{r=i,e=n}),resolve:r,reject:e}}var $q=class{constructor(e){this.deferred=new Map;this.promises=new Map;this.limit=(0,zq.default)(e)}set(e,t){let i=this.deferred.get(e);typeof i=="undefined"&&this.deferred.set(e,i=FBe());let n=this.limit(()=>t());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,t){var n;let i=(n=this.promises.get(e))!=null?n:Promise.resolve();this.set(e,()=>t(i))}async wait(){await Promise.all(this.promises.values())}},eJ=class extends xv.Transform{constructor(e=Buffer.alloc(0)){super();this.active=!0;this.ifEmpty=e}_transform(e,t,i){if(t!=="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)}},ed=eval("require");function tJ(r){return ed(H.fromPortablePath(r))}function rJ(path){let physicalPath=H.fromPortablePath(path),currentCacheEntry=ed.cache[physicalPath];delete ed.cache[physicalPath];let result;try{result=tJ(physicalPath);let freshCacheEntry=ed.cache[physicalPath],dynamicModule=eval("module"),freshCacheIndex=dynamicModule.children.indexOf(freshCacheEntry);freshCacheIndex!==-1&&dynamicModule.children.splice(freshCacheIndex,1)}finally{ed.cache[physicalPath]=currentCacheEntry}return result}var iJ=new Map;function NBe(r){let e=iJ.get(r),t=K.statSync(r);if((e==null?void 0:e.mtime)===t.mtimeMs)return e.instance;let i=rJ(r);return iJ.set(r,{mtime:t.mtimeMs,instance:i}),i}var Lc;(function(i){i[i.NoCache=0]="NoCache",i[i.FsTime=1]="FsTime",i[i.Node=2]="Node"})(Lc||(Lc={}));function Og(r,{cachingStrategy:e=2}={}){switch(e){case 0:return rJ(r);case 1:return NBe(r);case 2:return tJ(r);default:throw new Error("Unsupported caching strategy")}}function kn(r,e){let t=Array.from(r);Array.isArray(e)||(e=[e]);let i=[];for(let s of e)i.push(t.map(o=>s(o)));let n=t.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=>t[s])}function LBe(r){return r.length===0?null:r.map(e=>`(${Wq.default.makeRe(e,{windows:!1,dot:!0}).source})`).join("|")}function Fv(r,{env:e}){let t=/\${(?[\d\w_]+)(?:)?(?:-(?[^}]*))?}/g;return r.replace(t,(...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 Pe(`Environment variable not found (${n})`)})}function td(r){switch(r){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 "${r}" as a boolean`)}}function nJ(r){return typeof r=="undefined"?r:td(r)}function Nv(r){try{return nJ(r)}catch{return null}}function TBe(r){return!!(H.isAbsolute(r)||r.match(/^(\.{1,2}|~)\//))}var Qt;(function(t){t.HARD="HARD",t.SOFT="SOFT"})(Qt||(Qt={}));var wi;(function(i){i.Dependency="Dependency",i.PeerDependency="PeerDependency",i.PeerDependencyMeta="PeerDependencyMeta"})(wi||(wi={}));var qi;(function(i){i.Inactive="inactive",i.Redundant="redundant",i.Active="active"})(qi||(qi={}));var qe={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",MARKDOWN:"MARKDOWN"},Tc;(function(e){e[e.BOLD=2]="BOLD"})(Tc||(Tc={}));var Ov=id.default.GITHUB_ACTIONS?{level:2}:rd.default.supportsColor?{level:rd.default.supportsColor.level}:{level:0},Py=Ov.level!==0,Mv=Py&&!id.default.GITHUB_ACTIONS&&!id.default.CIRCLE&&!id.default.GITLAB,Kv=new rd.default.Instance(Ov),OBe=new Map([[qe.NO_HINT,null],[qe.NULL,["#a853b5",129]],[qe.SCOPE,["#d75f00",166]],[qe.NAME,["#d7875f",173]],[qe.RANGE,["#00afaf",37]],[qe.REFERENCE,["#87afff",111]],[qe.NUMBER,["#ffd700",220]],[qe.PATH,["#d75fd7",170]],[qe.URL,["#d75fd7",170]],[qe.ADDED,["#5faf00",70]],[qe.REMOVED,["#d70000",160]],[qe.CODE,["#87afff",111]],[qe.SIZE,["#ffd700",220]]]),Fs=r=>r,Dy={[qe.NUMBER]:Fs({pretty:(r,e)=>`${e}`,json:r=>r}),[qe.IDENT]:Fs({pretty:(r,e)=>fi(r,e),json:r=>Ot(r)}),[qe.LOCATOR]:Fs({pretty:(r,e)=>It(r,e),json:r=>Rs(r)}),[qe.DESCRIPTOR]:Fs({pretty:(r,e)=>sr(r,e),json:r=>Pn(r)}),[qe.RESOLUTION]:Fs({pretty:(r,{descriptor:e,locator:t})=>Tv(r,e,t),json:({descriptor:r,locator:e})=>({descriptor:Pn(r),locator:e!==null?Rs(e):null})}),[qe.DEPENDENT]:Fs({pretty:(r,{locator:e,descriptor:t})=>Lv(r,e,t),json:({locator:r,descriptor:e})=>({locator:Rs(r),descriptor:Pn(e)})}),[qe.PACKAGE_EXTENSION]:Fs({pretty:(r,e)=>{switch(e.type){case wi.Dependency:return`${fi(r,e.parentDescriptor)} \u27A4 ${ns(r,"dependencies",qe.CODE)} \u27A4 ${fi(r,e.descriptor)}`;case wi.PeerDependency:return`${fi(r,e.parentDescriptor)} \u27A4 ${ns(r,"peerDependencies",qe.CODE)} \u27A4 ${fi(r,e.descriptor)}`;case wi.PeerDependencyMeta:return`${fi(r,e.parentDescriptor)} \u27A4 ${ns(r,"peerDependenciesMeta",qe.CODE)} \u27A4 ${fi(r,An(e.selector))} \u27A4 ${ns(r,e.key,qe.CODE)}`;default:throw new Error(`Assertion failed: Unsupported package extension type: ${e.type}`)}},json:r=>{switch(r.type){case wi.Dependency:return`${Ot(r.parentDescriptor)} > ${Ot(r.descriptor)}`;case wi.PeerDependency:return`${Ot(r.parentDescriptor)} >> ${Ot(r.descriptor)}`;case wi.PeerDependencyMeta:return`${Ot(r.parentDescriptor)} >> ${r.selector} / ${r.key}`;default:throw new Error(`Assertion failed: Unsupported package extension type: ${r.type}`)}}}),[qe.SETTING]:Fs({pretty:(r,e)=>(r.get(e),Mg(r,ns(r,e,qe.CODE),`https://yarnpkg.com/configuration/yarnrc#${e}`)),json:r=>r}),[qe.DURATION]:Fs({pretty:(r,e)=>{if(e>1e3*60){let t=Math.floor(e/1e3/60),i=Math.ceil((e-t*60*1e3)/1e3);return i===0?`${t}m`:`${t}m ${i}s`}else{let t=Math.floor(e/1e3),i=e-t*1e3;return i===0?`${t}s`:`${t}s ${i}ms`}},json:r=>r}),[qe.SIZE]:Fs({pretty:(r,e)=>{let t=["KB","MB","GB","TB"],i=t.length;for(;i>1&&e<1024**i;)i-=1;let n=1024**i,s=Math.floor(e*100/n)/100;return ns(r,`${s} ${t[i-1]}`,qe.NUMBER)},json:r=>r}),[qe.PATH]:Fs({pretty:(r,e)=>ns(r,H.fromPortablePath(e),qe.PATH),json:r=>H.fromPortablePath(r)}),[qe.MARKDOWN]:Fs({pretty:(r,{text:e,format:t,paragraphs:i})=>Ui(e,{format:t,paragraphs:i}),json:({text:r})=>r})};function fo(r,e){return[e,r]}function Ry(r,e,t){return r.get("enableColors")&&t&2&&(e=rd.default.bold(e)),e}function ns(r,e,t){if(!r.get("enableColors"))return e;let i=OBe.get(t);if(i===null)return e;let n=typeof i=="undefined"?t:Ov.level>=3?i[0]:i[1],s=typeof n=="number"?Kv.ansi256(n):n.startsWith("#")?Kv.hex(n):Kv[n];if(typeof s!="function")throw new Error(`Invalid format type ${n}`);return s(e)}var MBe=!!process.env.KONSOLE_VERSION;function Mg(r,e,t){return r.get("enableHyperlinks")?MBe?`]8;;${t}\\${e}]8;;\\`:`]8;;${t}\x07${e}]8;;\x07`:e}function tt(r,e,t){if(e===null)return ns(r,"null",qe.NULL);if(Object.prototype.hasOwnProperty.call(Dy,t))return Dy[t].pretty(r,e);if(typeof e!="string")throw new Error(`Assertion failed: Expected the value to be a string, got ${typeof e}`);return ns(r,e,t)}function Uv(r,e,t,{separator:i=", "}={}){return[...e].map(n=>tt(r,n,t)).join(i)}function Oc(r,e){if(r===null)return null;if(Object.prototype.hasOwnProperty.call(Dy,e))return kv(e),Dy[e].json(r);if(typeof r!="string")throw new Error(`Assertion failed: Expected the value to be a string, got ${typeof r}`);return r}function KBe(r,e,[t,i]){return r?Oc(t,i):tt(e,t,i)}function Hv(r){return{Check:ns(r,"\u2713","green"),Cross:ns(r,"\u2718","red"),Question:ns(r,"?","cyan")}}function _o(r,{label:e,value:[t,i]}){return`${tt(r,e,qe.CODE)}: ${tt(r,t,i)}`}var ho;(function(n){n.Error="error",n.Warning="warning",n.Info="info",n.Discard="discard"})(ho||(ho={}));function nd(r,{configuration:e}){let t=e.get("logFilters"),i=new Map,n=new Map,s=[];for(let g of t){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 m=g.get("pattern");typeof m!="undefined"&&s.push([sJ.default.matcher(m,{contains:!0}),f])}s.reverse();let o=(g,f,h)=>{if(g===null||g===X.UNNAMED)return h;let p=n.size>0||s.length>0?(0,oJ.default)(f):f;if(n.size>0){let m=n.get(p);if(typeof m!="undefined")return m!=null?m:h}if(s.length>0){for(let[m,y]of s)if(m(p))return y!=null?y:h}if(i.size>0){let m=i.get(_A(g));if(typeof m!="undefined")return m!=null?m:h}return h},a=r.reportInfo,l=r.reportWarning,c=r.reportError,u=function(g,f,h,p){switch(o(f,h,p)){case ho.Info:a.call(g,f,h);break;case ho.Warning:l.call(g,f!=null?f:X.UNNAMED,h);break;case ho.Error:c.call(g,f!=null?f:X.UNNAMED,h);break}};r.reportInfo=function(...g){return u(this,...g,ho.Info)},r.reportWarning=function(...g){return u(this,...g,ho.Warning)},r.reportError=function(...g){return u(this,...g,ho.Error)}}var Dn={};ft(Dn,{checksumFile:()=>sw,checksumPattern:()=>ow,makeHash:()=>ln});var nw=ge(require("crypto")),zx=ge(Wx());function ln(...r){let e=(0,nw.createHash)("sha512"),t="";for(let i of r)typeof i=="string"?t+=i:i&&(t&&(e.update(t),t=""),e.update(i));return t&&e.update(t),e.digest("hex")}async function sw(r,{baseFs:e,algorithm:t}={baseFs:K,algorithm:"sha512"}){let i=await e.openPromise(r,"r");try{let n=65536,s=Buffer.allocUnsafeSlow(n),o=(0,nw.createHash)(t),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 ow(r,{cwd:e}){let i=(await(0,zx.default)(r,{cwd:H.fromPortablePath(e),expandDirectories:!1,onlyDirectories:!0,unique:!0})).map(a=>`${a}/**/*`),n=await(0,zx.default)([r,...i],{cwd:H.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=H.toPortablePath(a),u=await K.lstatPromise(c);return u.isSymbolicLink()?l.push(Buffer.from(await K.readlinkPromise(c))):u.isFile()&&l.push(await K.readFilePromise(c)),l.join("\0")})),o=(0,nw.createHash)("sha512");for(let a of s)o.update(a);return o.digest("hex")}var Ad="virtual:",tSe=5,GW=/(os|cpu|libc)=([a-z0-9_-]+)/,rSe=(0,jW.makeParser)(GW);function $o(r,e){if(r==null?void 0:r.startsWith("@"))throw new Error("Invalid scope: don't prefix it with '@'");return{identHash:ln(r,e),scope:r,name:e}}function rr(r,e){return{identHash:r.identHash,scope:r.scope,name:r.name,descriptorHash:ln(r.identHash,e),range:e}}function cn(r,e){return{identHash:r.identHash,scope:r.scope,name:r.name,locatorHash:ln(r.identHash,e),reference:e}}function iSe(r){return{identHash:r.identHash,scope:r.scope,name:r.name}}function Aw(r){return{identHash:r.identHash,scope:r.scope,name:r.name,locatorHash:r.descriptorHash,reference:r.range}}function _x(r){return{identHash:r.identHash,scope:r.scope,name:r.name,descriptorHash:r.locatorHash,range:r.reference}}function nSe(r){return{identHash:r.identHash,scope:r.scope,name:r.name,locatorHash:r.locatorHash,reference:r.reference}}function ld(r,e){return{identHash:e.identHash,scope:e.scope,name:e.name,locatorHash:e.locatorHash,reference:e.reference,version:r.version,languageName:r.languageName,linkType:r.linkType,conditions:r.conditions,dependencies:new Map(r.dependencies),peerDependencies:new Map(r.peerDependencies),dependenciesMeta:new Map(r.dependenciesMeta),peerDependenciesMeta:new Map(r.peerDependenciesMeta),bin:new Map(r.bin)}}function cd(r){return ld(r,r)}function Vx(r,e){if(e.includes("#"))throw new Error("Invalid entropy");return rr(r,`virtual:${e}#${r.range}`)}function Xx(r,e){if(e.includes("#"))throw new Error("Invalid entropy");return ld(r,cn(r,`virtual:${e}#${r.reference}`))}function Al(r){return r.range.startsWith(Ad)}function ea(r){return r.reference.startsWith(Ad)}function ud(r){if(!Al(r))throw new Error("Not a virtual descriptor");return rr(r,r.range.replace(/^[^#]*#/,""))}function gd(r){if(!ea(r))throw new Error("Not a virtual descriptor");return cn(r,r.reference.replace(/^[^#]*#/,""))}function sSe(r,e){return r.range.includes("::")?r:rr(r,`${r.range}::${Yg.default.stringify(e)}`)}function oSe(r,e){return r.reference.includes("::")?r:cn(r,`${r.reference}::${Yg.default.stringify(e)}`)}function fd(r,e){return r.identHash===e.identHash}function YW(r,e){return r.descriptorHash===e.descriptorHash}function hd(r,e){return r.locatorHash===e.locatorHash}function aSe(r,e){if(!ea(r))throw new Error("Invalid package type");if(!ea(e))throw new Error("Invalid package type");if(!fd(r,e)||r.dependencies.size!==e.dependencies.size)return!1;for(let t of r.dependencies.values()){let i=e.dependencies.get(t.identHash);if(!i||!YW(t,i))return!1}return!0}function An(r){let e=qW(r);if(!e)throw new Error(`Invalid ident (${r})`);return e}function qW(r){let e=r.match(/^(?:@([^/]+?)\/)?([^/]+)$/);if(!e)return null;let[,t,i]=e,n=typeof t!="undefined"?t:null;return $o(n,i)}function ll(r,e=!1){let t=pd(r,e);if(!t)throw new Error(`Invalid descriptor (${r})`);return t}function pd(r,e=!1){let t=e?r.match(/^(?:@([^/]+?)\/)?([^/]+?)(?:@(.+))$/):r.match(/^(?:@([^/]+?)\/)?([^/]+?)(?:@(.+))?$/);if(!t)return null;let[,i,n,s]=t;if(s==="unknown")throw new Error(`Invalid range (${r})`);let o=typeof i!="undefined"?i:null,a=typeof s!="undefined"?s:"unknown";return rr($o(o,n),a)}function Yc(r,e=!1){let t=lw(r,e);if(!t)throw new Error(`Invalid locator (${r})`);return t}function lw(r,e=!1){let t=e?r.match(/^(?:@([^/]+?)\/)?([^/]+?)(?:@(.+))$/):r.match(/^(?:@([^/]+?)\/)?([^/]+?)(?:@(.+))?$/);if(!t)return null;let[,i,n,s]=t;if(s==="unknown")throw new Error(`Invalid reference (${r})`);let o=typeof i!="undefined"?i:null,a=typeof s!="undefined"?s:"unknown";return cn($o(o,n),a)}function qg(r,e){let t=r.match(/^([^#:]*:)?((?:(?!::)[^#])*)(?:#((?:(?!::).)*))?(?:::(.*))?$/);if(t===null)throw new Error(`Invalid range (${r})`);let i=typeof t[1]!="undefined"?t[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 t[3]!="undefined"?decodeURIComponent(t[2]):null;if((e==null?void 0:e.requireSource)&&n===null)throw new Error(`Missing source (${r})`);let s=typeof t[3]!="undefined"?decodeURIComponent(t[3]):decodeURIComponent(t[2]),o=(e==null?void 0:e.parseSelector)?Yg.default.parse(s):s,a=typeof t[4]!="undefined"?Yg.default.parse(t[4]):null;return{protocol:i,source:n,selector:o,params:a}}function ASe(r,{protocol:e}){let{selector:t,params:i}=qg(r,{requireProtocol:e,requireBindings:!0});if(typeof i.locator!="string")throw new Error(`Assertion failed: Invalid bindings for ${r}`);return{parentLocator:Yc(i.locator,!0),path:t}}function JW(r){return r=r.replace(/%/g,"%25"),r=r.replace(/:/g,"%3A"),r=r.replace(/#/g,"%23"),r}function lSe(r){return r===null?!1:Object.entries(r).length>0}function cw({protocol:r,source:e,selector:t,params:i}){let n="";return r!==null&&(n+=`${r}`),e!==null&&(n+=`${JW(e)}#`),n+=JW(t),lSe(i)&&(n+=`::${Yg.default.stringify(i)}`),n}function cSe(r){let{params:e,protocol:t,source:i,selector:n}=qg(r);for(let s in e)s.startsWith("__")&&delete e[s];return cw({protocol:t,source:i,params:e,selector:n})}function Ot(r){return r.scope?`@${r.scope}/${r.name}`:`${r.name}`}function Pn(r){return r.scope?`@${r.scope}/${r.name}@${r.range}`:`${r.name}@${r.range}`}function Rs(r){return r.scope?`@${r.scope}/${r.name}@${r.reference}`:`${r.name}@${r.reference}`}function Zx(r){return r.scope!==null?`@${r.scope}-${r.name}`:r.name}function Jg(r){let{protocol:e,selector:t}=qg(r.reference),i=e!==null?e.replace(/:$/,""):"exotic",n=HW.default.valid(t),s=n!==null?`${i}-${n}`:`${i}`,o=10,a=r.scope?`${Zx(r)}-${s}-${r.locatorHash.slice(0,o)}`:`${Zx(r)}-${s}-${r.locatorHash.slice(0,o)}`;return Jr(a)}function fi(r,e){return e.scope?`${tt(r,`@${e.scope}/`,qe.SCOPE)}${tt(r,e.name,qe.NAME)}`:`${tt(r,e.name,qe.NAME)}`}function uw(r){if(r.startsWith(Ad)){let e=uw(r.substring(r.indexOf("#")+1)),t=r.substring(Ad.length,Ad.length+tSe);return`${e} [${t}]`}else return r.replace(/\?.*/,"?[...]")}function aw(r,e){return`${tt(r,uw(e),qe.RANGE)}`}function sr(r,e){return`${fi(r,e)}${tt(r,"@",qe.RANGE)}${aw(r,e.range)}`}function dd(r,e){return`${tt(r,uw(e),qe.REFERENCE)}`}function It(r,e){return`${fi(r,e)}${tt(r,"@",qe.REFERENCE)}${dd(r,e.reference)}`}function $x(r){return`${Ot(r)}@${uw(r.reference)}`}function Wg(r){return kn(r,[e=>Ot(e),e=>e.range])}function Cd(r,e){return fi(r,e.locator)}function Tv(r,e,t){let i=Al(e)?ud(e):e;return t===null?`${sr(r,i)} \u2192 ${Hv(r).Cross}`:i.identHash===t.identHash?`${sr(r,i)} \u2192 ${dd(r,t.reference)}`:`${sr(r,i)} \u2192 ${It(r,t)}`}function Lv(r,e,t){return t===null?`${It(r,e)}`:`${It(r,e)} (via ${aw(r,t.range)})`}function ek(r){return`node_modules/${Ot(r)}`}function gw(r,e){return r.conditions?rSe(r.conditions,t=>{let[,i,n]=t.match(GW),s=e[i];return s?s.includes(n):!0}):!0}var WW={hooks:{reduceDependency:(r,e,t,i,{resolver:n,resolveOptions:s})=>{for(let{pattern:o,reference:a}of e.topLevelWorkspace.manifest.resolutions){if(o.from&&o.from.fullName!==Ot(t)||o.from&&o.from.description&&o.from.description!==t.reference||o.descriptor.fullName!==Ot(r)||o.descriptor.description&&o.descriptor.description!==r.range)continue;return n.bindDescriptor(rr(r,a),e.topLevelWorkspace.anchoredLocator,s)}return r},validateProject:async(r,e)=>{for(let t of r.workspaces){let i=Cd(r.configuration,t);await r.configuration.triggerHook(n=>n.validateWorkspace,t,{reportWarning:(n,s)=>e.reportWarning(n,`${i}: ${s}`),reportError:(n,s)=>e.reportError(n,`${i}: ${s}`)})}},validateWorkspace:async(r,e)=>{let{manifest:t}=r;t.resolutions.length&&r.cwd!==r.project.cwd&&t.errors.push(new Error("Resolutions field will be ignored"));for(let i of t.errors)e.reportWarning(X.INVALID_MANIFEST,i.message)}}};var XW=ge(ri());var md=class{supportsDescriptor(e,t){return!!(e.range.startsWith(md.protocol)||t.project.tryWorkspaceByDescriptor(e)!==null)}supportsLocator(e,t){return!!e.reference.startsWith(md.protocol)}shouldPersistResolution(e,t){return!1}bindDescriptor(e,t,i){return e}getResolutionDependencies(e,t){return[]}async getCandidates(e,t,i){return[i.project.getWorkspaceByDescriptor(e).anchoredLocator]}async getSatisfying(e,t,i){return null}async resolve(e,t){let i=t.project.getWorkspaceByCwd(e.reference.slice(md.protocol.length));return te(N({},e),{version:i.manifest.version||"0.0.0",languageName:"unknown",linkType:Qt.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})}},oi=md;oi.protocol="workspace:";var Wt={};ft(Wt,{SemVer:()=>zW.SemVer,clean:()=>gSe,satisfiesWithPrereleases:()=>qc,validRange:()=>po});var fw=ge(ri()),zW=ge(ri()),_W=new Map;function qc(r,e,t=!1){if(!r)return!1;let i=`${e}${t}`,n=_W.get(i);if(typeof n=="undefined")try{n=new fw.default.Range(e,{includePrerelease:!0,loose:t})}catch{return!1}finally{_W.set(i,n||null)}else if(n===null)return!1;let s;try{s=new fw.default.SemVer(r,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 VW=new Map;function po(r){if(r.indexOf(":")!==-1)return null;let e=VW.get(r);if(typeof e!="undefined")return e;try{e=new fw.default.Range(r)}catch{e=null}return VW.set(r,e),e}var uSe=/^(?:[\sv=]*?)((0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?)(?:\s*)$/;function gSe(r){let e=uSe.exec(r);return e?e[1]:null}var cl=class{constructor(){this.indent=" ";this.name=null;this.version=null;this.os=null;this.cpu=null;this.libc=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:t=new ar}={}){let i=k.join(e,"package.json");try{return await cl.fromFile(i,{baseFs:t})}catch(n){if(n.code==="ENOENT")return null;throw n}}static async find(e,{baseFs:t}={}){let i=await cl.tryFind(e,{baseFs:t});if(i===null)throw new Error("Manifest not found");return i}static async fromFile(e,{baseFs:t=new ar}={}){let i=new cl;return await i.loadFile(e,{baseFs:t}),i}static fromText(e){let t=new cl;return t.loadFromText(e),t}static isManifestFieldCompatible(e,t){if(e===null)return!0;let i=!0,n=!1;for(let s of e)if(s[0]==="!"){if(n=!0,t===s.slice(1))return!1}else if(i=!1,s===t)return!0;return n&&i}loadFromText(e){let t;try{t=JSON.parse($W(e)||"{}")}catch(i){throw i.message+=` (when parsing ${e})`,i}this.load(t),this.indent=ZW(e)}async loadFile(e,{baseFs:t=new ar}){let i=await t.readFilePromise(e,"utf8"),n;try{n=JSON.parse($W(i)||"{}")}catch(s){throw s.message+=` (when parsing ${e})`,s}this.load(n),this.indent=ZW(i)}load(e,{yamlCompatibilityMode:t=!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=An(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(Array.isArray(e.libc)){let s=[];this.libc=s;for(let o of e.libc)typeof o!="string"?i.push(new Error("Parsing failed for the 'libc' field")):s.push(o)}else this.libc=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=un(e.main):this.main=null,typeof e.module=="string"?this.module=un(e.module):this.module=null,e.browser!=null)if(typeof e.browser=="string")this.browser=un(e.browser);else{this.browser=new Map;for(let[s,o]of Object.entries(e.browser))this.browser.set(un(s),typeof o=="string"?un(o):o)}else this.browser=null;if(this.bin=new Map,typeof e.bin=="string")this.name!==null?this.bin.set(this.name.name,un(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}let a=An(s);this.bin.set(a.name,un(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=An(s)}catch(c){i.push(new Error(`Parsing failed for the dependency name '${s}'`));continue}let l=rr(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=An(s)}catch(c){i.push(new Error(`Parsing failed for the dependency name '${s}'`));continue}let l=rr(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=An(s)}catch(c){i.push(new Error(`Parsing failed for the dependency name '${s}'`));continue}(typeof o!="string"||!o.startsWith(oi.protocol)&&!po(o))&&(i.push(new Error(`Invalid dependency range for '${s}'`)),o="*");let l=rr(a,o);this.peerDependencies.set(l.identHash,l)}typeof e.workspaces=="object"&&e.workspaces!==null&&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=ll(s),l=this.ensureDependencyMeta(a),c=hw(o.built,{yamlCompatibilityMode:t});if(c===null){i.push(new Error(`Invalid built meta field for '${s}'`));continue}let u=hw(o.optional,{yamlCompatibilityMode:t});if(u===null){i.push(new Error(`Invalid optional meta field for '${s}'`));continue}let g=hw(o.unplugged,{yamlCompatibilityMode:t});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=ll(s),l=this.ensurePeerDependencyMeta(a),c=hw(o.optional,{yamlCompatibilityMode:t});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:$E(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=un(e.publishConfig.main)),typeof e.publishConfig.module=="string"&&(this.publishConfig.module=un(e.publishConfig.module)),e.publishConfig.browser!=null)if(typeof e.publishConfig.browser=="string")this.publishConfig.browser=un(e.publishConfig.browser);else{this.publishConfig.browser=new Map;for(let[s,o]of Object.entries(e.publishConfig.browser))this.publishConfig.browser.set(un(s),typeof o=="string"?un(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,un(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,un(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(un(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=An(s)}catch(g){i.push(new Error(`Parsing failed for the dependency name '${s}'`));continue}let l=rr(a,o);this.dependencies.set(l.identHash,l);let c=rr(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(tk("os",this.os)),this.cpu&&this.cpu.length>0&&e.push(tk("cpu",this.cpu)),this.libc&&this.libc.length>0&&e.push(tk("libc",this.libc)),e.length>0?e.join(" & "):null}isCompatibleWithOS(e){return cl.isManifestFieldCompatible(this.os,e)}isCompatibleWithCPU(e){return cl.isManifestFieldCompatible(this.cpu,e)}ensureDependencyMeta(e){if(e.range!=="unknown"&&!XW.default.valid(e.range))throw new Error(`Invalid meta field range for '${Pn(e)}'`);let t=Ot(e),i=e.range!=="unknown"?e.range:null,n=this.dependenciesMeta.get(t);n||this.dependenciesMeta.set(t,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 '${Pn(e)}'`);let t=Ot(e),i=this.peerDependenciesMeta.get(t);return i||this.peerDependenciesMeta.set(t,i={}),i}setRawField(e,t,{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]=t;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]=t,a=!0))}}exportTo(e,{compatibilityMode:t=!0}={}){var s;if(Object.assign(e,this.raw),this.name!==null?e.name=Ot(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=te(N({},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(Ot(o)),l=!1;if(t&&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({},...Wg(i).map(o=>({[Ot(o)]:o.range}))):delete e.dependencies,n.length>0?e.optionalDependencies=Object.assign({},...Wg(n).map(o=>({[Ot(o)]:o.range}))):delete e.optionalDependencies,this.devDependencies.size>0?e.devDependencies=Object.assign({},...Wg(this.devDependencies.values()).map(o=>({[Ot(o)]:o.range}))):delete e.devDependencies,this.peerDependencies.size>0?e.peerDependencies=Object.assign({},...Wg(this.peerDependencies.values()).map(o=>({[Ot(o)]:o.range}))):delete e.peerDependencies,e.dependenciesMeta={};for(let[o,a]of kn(this.dependenciesMeta.entries(),([l,c])=>l))for(let[l,c]of kn(a.entries(),([u,g])=>u!==null?`0${u}`:"1")){let u=l!==null?Pn(rr(An(o),l)):o,g=N({},c);t&&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({},...kn(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})=>({[eI(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}},At=cl;At.fileName="package.json",At.allDependencies=["dependencies","devDependencies","peerDependencies"],At.hardDependencies=["dependencies","devDependencies"];function ZW(r){let e=r.match(/^[ \t]+/m);return e?e[0]:" "}function $W(r){return r.charCodeAt(0)===65279?r.slice(1):r}function un(r){return r.replace(/\\/g,"/")}function hw(r,{yamlCompatibilityMode:e}){return e?Nv(r):typeof r=="undefined"||typeof r=="boolean"?r:null}function e4(r,e){let t=e.search(/[^!]/);if(t===-1)return"invalid";let i=t%2==0?"":"!",n=e.slice(t);return`${i}${r}=${n}`}function tk(r,e){return e.length===1?e4(r,e[0]):`(${e.map(t=>e4(r,t)).join(" | ")})`}var D4=ge(P4()),R4=ge(require("stream")),F4=ge(require("string_decoder"));var sve=15,ct=class extends Error{constructor(e,t,i){super(t);this.reportExtra=i;this.reportCode=e}};function ove(r){return typeof r.reportCode!="undefined"}var Ji=class{constructor(){this.reportedInfos=new Set;this.reportedWarnings=new Set;this.reportedErrors=new Set}static progressViaCounter(e){let t=0,i,n=new Promise(l=>{i=l}),s=l=>{let c=i;n=new Promise(u=>{i=u}),t=l,c()},o=(l=0)=>{s(t+1)},a=async function*(){for(;t{t=o}),n=(0,D4.default)(o=>{let a=t;i=new Promise(l=>{t=l}),e=o,a()},1e3/sve),s=async function*(){for(;;)await i,yield{title:e}}();return{[Symbol.asyncIterator](){return s},hasProgress:!1,hasTitle:!0,setTitle:n}}async startProgressPromise(e,t){let i=this.reportProgress(e);try{return await t(e)}finally{i.stop()}}startProgressSync(e,t){let i=this.reportProgress(e);try{return t(e)}finally{i.stop()}}reportInfoOnce(e,t,i){var s;let n=i&&i.key?i.key:t;this.reportedInfos.has(n)||(this.reportedInfos.add(n),this.reportInfo(e,t),(s=i==null?void 0:i.reportExtra)==null||s.call(i,this))}reportWarningOnce(e,t,i){var s;let n=i&&i.key?i.key:t;this.reportedWarnings.has(n)||(this.reportedWarnings.add(n),this.reportWarning(e,t),(s=i==null?void 0:i.reportExtra)==null||s.call(i,this))}reportErrorOnce(e,t,i){var s;let n=i&&i.key?i.key:t;this.reportedErrors.has(n)||(this.reportedErrors.add(n),this.reportError(e,t),(s=i==null?void 0:i.reportExtra)==null||s.call(i,this))}reportExceptionOnce(e){ove(e)?this.reportErrorOnce(e.reportCode,e.message,{key:e,reportExtra:e.reportExtra}):this.reportErrorOnce(X.EXCEPTION,e.stack||e.message,{key:e})}createStreamReporter(e=null){let t=new R4.PassThrough,i=new F4.StringDecoder,n="";return t.on("data",s=>{let o=i.write(s),a;do if(a=o.indexOf(` -`),a!==-1){let l=n+o.substring(0,a);o=o.substring(a+1),n="",e!==null?this.reportInfo(null,`${e} ${l}`):this.reportInfo(null,l)}while(a!==-1);n+=o}),t.on("end",()=>{let s=i.end();s!==""&&(e!==null?this.reportInfo(null,`${e} ${s}`):this.reportInfo(null,s))}),t}};var yd=class{constructor(e){this.fetchers=e}supports(e,t){return!!this.tryFetcher(e,t)}getLocalPath(e,t){return this.getFetcher(e,t).getLocalPath(e,t)}async fetch(e,t){return await this.getFetcher(e,t).fetch(e,t)}tryFetcher(e,t){let i=this.fetchers.find(n=>n.supports(e,t));return i||null}getFetcher(e,t){let i=this.fetchers.find(n=>n.supports(e,t));if(!i)throw new ct(X.FETCHER_NOT_FOUND,`${It(t.project.configuration,e)} isn't supported by any available fetcher`);return i}};var wd=class{constructor(e){this.resolvers=e.filter(t=>t)}supportsDescriptor(e,t){return!!this.tryResolverByDescriptor(e,t)}supportsLocator(e,t){return!!this.tryResolverByLocator(e,t)}shouldPersistResolution(e,t){return this.getResolverByLocator(e,t).shouldPersistResolution(e,t)}bindDescriptor(e,t,i){return this.getResolverByDescriptor(e,i).bindDescriptor(e,t,i)}getResolutionDependencies(e,t){return this.getResolverByDescriptor(e,t).getResolutionDependencies(e,t)}async getCandidates(e,t,i){return await this.getResolverByDescriptor(e,i).getCandidates(e,t,i)}async getSatisfying(e,t,i){return this.getResolverByDescriptor(e,i).getSatisfying(e,t,i)}async resolve(e,t){return await this.getResolverByLocator(e,t).resolve(e,t)}tryResolverByDescriptor(e,t){let i=this.resolvers.find(n=>n.supportsDescriptor(e,t));return i||null}getResolverByDescriptor(e,t){let i=this.resolvers.find(n=>n.supportsDescriptor(e,t));if(!i)throw new Error(`${sr(t.project.configuration,e)} isn't supported by any available resolver`);return i}tryResolverByLocator(e,t){let i=this.resolvers.find(n=>n.supportsLocator(e,t));return i||null}getResolverByLocator(e,t){let i=this.resolvers.find(n=>n.supportsLocator(e,t));if(!i)throw new Error(`${It(t.project.configuration,e)} isn't supported by any available resolver`);return i}};var N4=ge(ri());var zg=/^(?!v)[a-z0-9._-]+$/i,nk=class{supportsDescriptor(e,t){return!!(po(e.range)||zg.test(e.range))}supportsLocator(e,t){return!!(N4.default.valid(e.reference)||zg.test(e.reference))}shouldPersistResolution(e,t){return t.resolver.shouldPersistResolution(this.forwardLocator(e,t),t)}bindDescriptor(e,t,i){return i.resolver.bindDescriptor(this.forwardDescriptor(e,i),t,i)}getResolutionDependencies(e,t){return t.resolver.getResolutionDependencies(this.forwardDescriptor(e,t),t)}async getCandidates(e,t,i){return await i.resolver.getCandidates(this.forwardDescriptor(e,i),t,i)}async getSatisfying(e,t,i){return await i.resolver.getSatisfying(this.forwardDescriptor(e,i),t,i)}async resolve(e,t){let i=await t.resolver.resolve(this.forwardLocator(e,t),t);return ld(i,e)}forwardDescriptor(e,t){return rr(e,`${t.project.configuration.get("defaultProtocol")}${e.range}`)}forwardLocator(e,t){return cn(e,`${t.project.configuration.get("defaultProtocol")}${e.reference}`)}};var Bd=class{supports(e){return!!e.reference.startsWith("virtual:")}getLocalPath(e,t){let i=e.reference.indexOf("#");if(i===-1)throw new Error("Invalid virtual package reference");let n=e.reference.slice(i+1),s=cn(e,n);return t.fetcher.getLocalPath(s,t)}async fetch(e,t){let i=e.reference.indexOf("#");if(i===-1)throw new Error("Invalid virtual package reference");let n=e.reference.slice(i+1),s=cn(e,n),o=await t.fetcher.fetch(s,t);return await this.ensureVirtualLink(e,o,t)}getLocatorFilename(e){return Jg(e)}async ensureVirtualLink(e,t,i){let n=t.packageFs.getRealPath(),s=i.project.configuration.get("virtualFolder"),o=this.getLocatorFilename(e),a=Wr.makeVirtualPath(s,o,n),l=new Na(a,{baseFs:t.packageFs,pathUtils:k});return te(N({},t),{packageFs:l})}};var _g=class{static isVirtualDescriptor(e){return!!e.range.startsWith(_g.protocol)}static isVirtualLocator(e){return!!e.reference.startsWith(_g.protocol)}supportsDescriptor(e,t){return _g.isVirtualDescriptor(e)}supportsLocator(e,t){return _g.isVirtualLocator(e)}shouldPersistResolution(e,t){return!1}bindDescriptor(e,t,i){throw new Error('Assertion failed: calling "bindDescriptor" on a virtual descriptor is unsupported')}getResolutionDependencies(e,t){throw new Error('Assertion failed: calling "getResolutionDependencies" on a virtual descriptor is unsupported')}async getCandidates(e,t,i){throw new Error('Assertion failed: calling "getCandidates" on a virtual descriptor is unsupported')}async getSatisfying(e,t,i){throw new Error('Assertion failed: calling "getSatisfying" on a virtual descriptor is unsupported')}async resolve(e,t){throw new Error('Assertion failed: calling "resolve" on a virtual locator is unsupported')}},pw=_g;pw.protocol="virtual:";var bd=class{supports(e){return!!e.reference.startsWith(oi.protocol)}getLocalPath(e,t){return this.getWorkspace(e,t).cwd}async fetch(e,t){let i=this.getWorkspace(e,t).cwd;return{packageFs:new _t(i),prefixPath:Me.dot,localPath:i}}getWorkspace(e,t){return t.project.getWorkspaceByCwd(e.reference.slice(oi.protocol.length))}};var sk={};ft(sk,{getDefaultGlobalFolder:()=>ak,getHomeFolder:()=>Qd,isFolderInside:()=>Ak});var ok=ge(require("os"));function ak(){if(process.platform==="win32"){let r=H.toPortablePath(process.env.LOCALAPPDATA||H.join((0,ok.homedir)(),"AppData","Local"));return k.resolve(r,"Yarn/Berry")}if(process.env.XDG_DATA_HOME){let r=H.toPortablePath(process.env.XDG_DATA_HOME);return k.resolve(r,"yarn/berry")}return k.resolve(Qd(),".yarn/berry")}function Qd(){return H.toPortablePath((0,ok.homedir)()||"/usr/local/share")}function Ak(r,e){let t=k.relative(e,r);return t&&!t.startsWith("..")&&!k.isAbsolute(t)}var Vg={};ft(Vg,{builtinModules:()=>lk,getArchitecture:()=>Sd,getArchitectureName:()=>Ave,getArchitectureSet:()=>ck});var L4=ge(require("module"));function lk(){return new Set(L4.default.builtinModules||Object.keys(process.binding("natives")))}function ave(){var i,n,s,o;if(process.platform==="win32")return null;let e=(s=((n=(i=process.report)==null?void 0:i.getReport())!=null?n:{}).sharedObjects)!=null?s:[],t=/\/(?:(ld-linux-|[^/]+-linux-gnu\/)|(libc.musl-|ld-musl-))/;return(o=$p(e,a=>{let l=a.match(t);if(!l)return $p.skip;if(l[1])return"glibc";if(l[2])return"musl";throw new Error("Assertion failed: Expected the libc variant to have been detected")}))!=null?o:null}var dw,Cw;function Sd(){return dw=dw!=null?dw:{os:process.platform,cpu:process.arch,libc:ave()}}function Ave(r=Sd()){return r.libc?`${r.os}-${r.cpu}-${r.libc}`:`${r.os}-${r.cpu}`}function ck(){let r=Sd();return Cw=Cw!=null?Cw:{os:[r.os],cpu:[r.cpu],libc:r.libc?[r.libc]:[]}}var lve=new Set(["binFolder","version","flags","profile","gpg","ignoreNode","wrapOutput","home","confDir"]),Ew="yarn_",gk=".yarnrc.yml",fk="yarn.lock",cve="********",Ie;(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"})(Ie||(Ie={}));var Ri=qe,hk={lastUpdateCheck:{description:"Last timestamp we checked whether new Yarn versions were available",type:Ie.STRING,default:null},yarnPath:{description:"Path to the local executable that must be used over the global one",type:Ie.ABSOLUTE_PATH,default:null},ignorePath:{description:"If true, the local executable will be ignored when using the global one",type:Ie.BOOLEAN,default:!1},ignoreCwd:{description:"If true, the `--cwd` flag will be ignored",type:Ie.BOOLEAN,default:!1},cacheKeyOverride:{description:"A global cache key override; used only for test purposes",type:Ie.STRING,default:null},globalFolder:{description:"Folder where all system-global files are stored",type:Ie.ABSOLUTE_PATH,default:ak()},cacheFolder:{description:"Folder where the cache files must be written",type:Ie.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:Ie.NUMBER,values:["mixed",0,1,2,3,4,5,6,7,8,9],default:lc},virtualFolder:{description:"Folder where the virtual packages (cf doc) will be mapped on the disk (must be named __virtual__)",type:Ie.ABSOLUTE_PATH,default:"./.yarn/__virtual__"},lockfileFilename:{description:"Name of the files where the Yarn dependency tree entries must be stored",type:Ie.STRING,default:fk},installStatePath:{description:"Path of the file where the install state will be persisted",type:Ie.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:Ie.STRING,default:[],isArray:!0},rcFilename:{description:"Name of the files where the configuration can be found",type:Ie.STRING,default:Iw()},enableGlobalCache:{description:"If true, the system-wide cache folder will be used regardless of `cache-folder`",type:Ie.BOOLEAN,default:!1},enableColors:{description:"If true, the CLI is allowed to use colors in its output",type:Ie.BOOLEAN,default:Py,defaultText:""},enableHyperlinks:{description:"If true, the CLI is allowed to use hyperlinks in its output",type:Ie.BOOLEAN,default:Mv,defaultText:""},enableInlineBuilds:{description:"If true, the CLI will print the build output on the command line",type:Ie.BOOLEAN,default:mw.isCI,defaultText:""},enableMessageNames:{description:"If true, the CLI will prefix most messages with codes suitable for search engines",type:Ie.BOOLEAN,default:!0},enableProgressBars:{description:"If true, the CLI is allowed to show a progress bar for long-running events",type:Ie.BOOLEAN,default:!mw.isCI,defaultText:""},enableTimers:{description:"If true, the CLI is allowed to print the time spent executing commands",type:Ie.BOOLEAN,default:!0},preferAggregateCacheInfo:{description:"If true, the CLI will only print a one-line report of any cache changes",type:Ie.BOOLEAN,default:mw.isCI},preferInteractive:{description:"If true, the CLI will automatically use the interactive mode when called from a TTY",type:Ie.BOOLEAN,default:!1},preferTruncatedLines:{description:"If true, the CLI will truncate lines that would go beyond the size of the terminal",type:Ie.BOOLEAN,default:!1},progressBarStyle:{description:"Which style of progress bar should be used (only when progress bars are enabled)",type:Ie.STRING,default:void 0,defaultText:""},defaultLanguageName:{description:"Default language mode that should be used when a package doesn't offer any insight",type:Ie.STRING,default:"node"},defaultProtocol:{description:"Default resolution protocol used when resolving pure semver and tag ranges",type:Ie.STRING,default:"npm:"},enableTransparentWorkspaces:{description:"If false, Yarn won't automatically resolve workspace dependencies unless they use the `workspace:` protocol",type:Ie.BOOLEAN,default:!0},supportedArchitectures:{description:"Architectures that Yarn will fetch and inject into the resolver",type:Ie.SHAPE,properties:{os:{description:"Array of supported process.platform strings, or null to target them all",type:Ie.STRING,isArray:!0,isNullable:!0,default:["current"]},cpu:{description:"Array of supported process.arch strings, or null to target them all",type:Ie.STRING,isArray:!0,isNullable:!0,default:["current"]},libc:{description:"Array of supported libc libraries, or null to target them all",type:Ie.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:Ie.BOOLEAN,default:!0},enableNetwork:{description:"If false, the package manager will refuse to use the network if required to",type:Ie.BOOLEAN,default:!0},httpProxy:{description:"URL of the http proxy that must be used for outgoing http requests",type:Ie.STRING,default:null},httpsProxy:{description:"URL of the http proxy that must be used for outgoing https requests",type:Ie.STRING,default:null},unsafeHttpWhitelist:{description:"List of the hostnames for which http queries are allowed (glob patterns are supported)",type:Ie.STRING,default:[],isArray:!0},httpTimeout:{description:"Timeout of each http request in milliseconds",type:Ie.NUMBER,default:6e4},httpRetry:{description:"Retry times on http failure",type:Ie.NUMBER,default:3},networkConcurrency:{description:"Maximal number of concurrent requests",type:Ie.NUMBER,default:50},networkSettings:{description:"Network settings per hostname (glob patterns are supported)",type:Ie.MAP,valueDefinition:{description:"",type:Ie.SHAPE,properties:{caFilePath:{description:"Path to file containing one or multiple Certificate Authority signing certificates",type:Ie.ABSOLUTE_PATH,default:null},enableNetwork:{description:"If false, the package manager will refuse to use the network if required to",type:Ie.BOOLEAN,default:null},httpProxy:{description:"URL of the http proxy that must be used for outgoing http requests",type:Ie.STRING,default:null},httpsProxy:{description:"URL of the http proxy that must be used for outgoing https requests",type:Ie.STRING,default:null},httpsKeyFilePath:{description:"Path to file containing private key in PEM format",type:Ie.ABSOLUTE_PATH,default:null},httpsCertFilePath:{description:"Path to file containing certificate chain in PEM format",type:Ie.ABSOLUTE_PATH,default:null}}}},caFilePath:{description:"A path to a file containing one or multiple Certificate Authority signing certificates",type:Ie.ABSOLUTE_PATH,default:null},httpsKeyFilePath:{description:"Path to file containing private key in PEM format",type:Ie.ABSOLUTE_PATH,default:null},httpsCertFilePath:{description:"Path to file containing certificate chain in PEM format",type:Ie.ABSOLUTE_PATH,default:null},enableStrictSsl:{description:"If false, SSL certificate errors will be ignored",type:Ie.BOOLEAN,default:!0},logFilters:{description:"Overrides for log levels",type:Ie.SHAPE,isArray:!0,concatenateValues:!0,properties:{code:{description:"Code of the messages covered by this override",type:Ie.STRING,default:void 0},text:{description:"Code of the texts covered by this override",type:Ie.STRING,default:void 0},pattern:{description:"Code of the patterns covered by this override",type:Ie.STRING,default:void 0},level:{description:"Log level override, set to null to remove override",type:Ie.STRING,values:Object.values(ho),isNullable:!0,default:void 0}}},enableTelemetry:{description:"If true, telemetry will be periodically sent, following the rules in https://yarnpkg.com/advanced/telemetry",type:Ie.BOOLEAN,default:!0},telemetryInterval:{description:"Minimal amount of time between two telemetry uploads, in days",type:Ie.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:Ie.STRING,default:null},enableScripts:{description:"If true, packages are allowed to have install scripts by default",type:Ie.BOOLEAN,default:!0},enableStrictSettings:{description:"If true, unknown settings will cause Yarn to abort",type:Ie.BOOLEAN,default:!0},enableImmutableCache:{description:"If true, the cache is reputed immutable and actions that would modify it will throw",type:Ie.BOOLEAN,default:!1},checksumBehavior:{description:"Enumeration defining what to do when a checksum doesn't match expectations",type:Ie.STRING,default:"throw"},packageExtensions:{description:"Map of package corrections to apply on the dependency tree",type:Ie.MAP,valueDefinition:{description:"The extension that will be applied to any package whose version matches the specified range",type:Ie.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:Ie.MAP,valueDefinition:{description:"A range",type:Ie.STRING}},peerDependencies:{description:"Inherited dependencies - the consumer of the package will be tasked to provide them",type:Ie.MAP,valueDefinition:{description:"A semver range",type:Ie.STRING}},peerDependenciesMeta:{description:"Extra information related to the dependencies listed in the peerDependencies field",type:Ie.MAP,valueDefinition:{description:"The peerDependency meta",type:Ie.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:Ie.BOOLEAN,default:!1}}}}}}}};function dk(r,e,t,i,n){if(i.isArray||i.type===Ie.ANY&&Array.isArray(t))return Array.isArray(t)?t.map((s,o)=>pk(r,`${e}[${o}]`,s,i,n)):String(t).split(/,/).map(s=>pk(r,e,s,i,n));if(Array.isArray(t))throw new Error(`Non-array configuration settings "${e}" cannot be an array`);return pk(r,e,t,i,n)}function pk(r,e,t,i,n){var a;switch(i.type){case Ie.ANY:return t;case Ie.SHAPE:return uve(r,e,t,i,n);case Ie.MAP:return gve(r,e,t,i,n)}if(t===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(t))return t;let o=(()=>{if(i.type===Ie.BOOLEAN&&typeof t!="string")return td(t);if(typeof t!="string")throw new Error(`Expected value (${t}) to be a string`);let l=Fv(t,{env:process.env});switch(i.type){case Ie.ABSOLUTE_PATH:return k.resolve(n,H.toPortablePath(l));case Ie.LOCATOR_LOOSE:return Yc(l,!1);case Ie.NUMBER:return parseInt(l);case Ie.LOCATOR:return Yc(l);case Ie.BOOLEAN:return td(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 uve(r,e,t,i,n){if(typeof t!="object"||Array.isArray(t))throw new Pe(`Object configuration settings "${e}" must be an object`);let s=Ck(r,i,{ignoreArrays:!0});if(t===null)return s;for(let[o,a]of Object.entries(t)){let l=`${e}.${o}`;if(!i.properties[o])throw new Pe(`Unrecognized configuration settings found: ${e}.${o} - run "yarn config -v" to see the list of settings supported in Yarn`);s.set(o,dk(r,l,a,i.properties[o],n))}return s}function gve(r,e,t,i,n){let s=new Map;if(typeof t!="object"||Array.isArray(t))throw new Pe(`Map configuration settings "${e}" must be an object`);if(t===null)return s;for(let[o,a]of Object.entries(t)){let l=i.normalizeKeys?i.normalizeKeys(o):o,c=`${e}['${l}']`,u=i.valueDefinition;s.set(l,dk(r,c,a,u,n))}return s}function Ck(r,e,{ignoreArrays:t=!1}={}){switch(e.type){case Ie.SHAPE:{if(e.isArray&&!t)return[];let i=new Map;for(let[n,s]of Object.entries(e.properties))i.set(n,Ck(r,s));return i}break;case Ie.MAP:return e.isArray&&!t?[]:new Map;case Ie.ABSOLUTE_PATH:return e.default===null?null:r.projectCwd===null?k.isAbsolute(e.default)?k.normalize(e.default):e.isNullable?null:void 0:Array.isArray(e.default)?e.default.map(i=>k.resolve(r.projectCwd,i)):k.resolve(r.projectCwd,e.default);default:return e.default}}function yw(r,e,t){if(e.type===Ie.SECRET&&typeof r=="string"&&t.hideSecrets)return cve;if(e.type===Ie.ABSOLUTE_PATH&&typeof r=="string"&&t.getNativePaths)return H.fromPortablePath(r);if(e.isArray&&Array.isArray(r)){let i=[];for(let n of r)i.push(yw(n,e,t));return i}if(e.type===Ie.MAP&&r instanceof Map){let i=new Map;for(let[n,s]of r.entries())i.set(n,yw(s,e.valueDefinition,t));return i}if(e.type===Ie.SHAPE&&r instanceof Map){let i=new Map;for(let[n,s]of r.entries()){let o=e.properties[n];i.set(n,yw(s,o,t))}return i}return r}function fve(){let r={};for(let[e,t]of Object.entries(process.env))e=e.toLowerCase(),!!e.startsWith(Ew)&&(e=(0,T4.default)(e.slice(Ew.length)),r[e]=t);return r}function Iw(){let r=`${Ew}rc_filename`;for(let[e,t]of Object.entries(process.env))if(e.toLowerCase()===r&&typeof t=="string")return t;return gk}var ul;(function(i){i[i.LOCKFILE=0]="LOCKFILE",i[i.MANIFEST=1]="MANIFEST",i[i.NONE=2]="NONE"})(ul||(ul={}));var tA=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,t,i){let n=new tA(e);typeof t!="undefined"&&!(t instanceof Map)&&(n.projectCwd=t),n.importSettings(hk);let s=typeof i!="undefined"?i:t instanceof Map?t:new Map;for(let[o,a]of s)n.activatePlugin(o,a);return n}static async find(e,t,{lookup:i=0,strict:n=!0,usePath:s=!1,useRc:o=!0}={}){let a=fve();delete a.rcFilename;let l=await tA.findRcFiles(e),c=await tA.findHomeRcFile();if(c){let b=l.find(v=>v.path===c.path);b?b.strict=!1:l.push(te(N({},c),{strict:!1}))}let u=({ignoreCwd:b,yarnPath:v,ignorePath:x,lockfileFilename:T})=>({ignoreCwd:b,yarnPath:v,ignorePath:x,lockfileFilename:T}),g=Y=>{var $=Y,{ignoreCwd:b,yarnPath:v,ignorePath:x,lockfileFilename:T}=$,q=Or($,["ignoreCwd","yarnPath","ignorePath","lockfileFilename"]);return q},f=new tA(e);f.importSettings(u(hk)),f.useWithSource("",u(a),e,{strict:!1});for(let{path:b,cwd:v,data:x}of l)f.useWithSource(b,u(x),v,{strict:!1});if(s){let b=f.get("yarnPath"),v=f.get("ignorePath");if(b!==null&&!v)return f}let h=f.get("lockfileFilename"),p;switch(i){case 0:p=await tA.findProjectCwd(e,h);break;case 1:p=await tA.findProjectCwd(e,null);break;case 2:K.existsSync(k.join(e,"package.json"))?p=k.resolve(e):p=null;break}f.startingCwd=e,f.projectCwd=p,f.importSettings(g(hk));let m=new Map([["@@core",WW]]),y=b=>"default"in b?b.default:b;if(t!==null){for(let T of t.plugins.keys())m.set(T,y(t.modules.get(T)));let b=new Map;for(let T of lk())b.set(T,()=>Og(T));for(let[T,q]of t.modules)b.set(T,()=>q);let v=new Set,x=async(T,q)=>{let{factory:Y,name:$}=Og(T);if(v.has($))return;let _=new Map(b),ne=A=>{if(_.has(A))return _.get(A)();throw new Pe(`This plugin cannot access the package referenced via ${A} which is neither a builtin, nor an exposed entry`)},ee=await Lg(async()=>y(await Y(ne)),A=>`${A} (when initializing ${$}, defined in ${q})`);b.set($,()=>ee),v.add($),m.set($,ee)};if(a.plugins)for(let T of a.plugins.split(";")){let q=k.resolve(e,H.toPortablePath(T));await x(q,"")}for(let{path:T,cwd:q,data:Y}of l)if(!!o&&!!Array.isArray(Y.plugins))for(let $ of Y.plugins){let _=typeof $!="string"?$.path:$,ne=k.resolve(q,H.toPortablePath(_));await x(ne,T)}}for(let[b,v]of m)f.activatePlugin(b,v);f.useWithSource("",g(a),e,{strict:n});for(let{path:b,cwd:v,data:x,strict:T}of l)f.useWithSource(b,g(x),v,{strict:T!=null?T: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 t=Iw(),i=[],n=e,s=null;for(;n!==s;){s=n;let o=k.join(s,t);if(K.existsSync(o)){let a=await K.readFilePromise(o,"utf8"),l;try{l=Si(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 Pe(`Parse error when loading ${o}; please check it's proper Yaml${u}`)}i.push({path:o,cwd:s,data:l})}n=k.dirname(s)}return i}static async findHomeRcFile(){let e=Iw(),t=Qd(),i=k.join(t,e);if(K.existsSync(i)){let n=await K.readFilePromise(i,"utf8"),s=Si(n);return{path:i,cwd:t,data:s}}return null}static async findProjectCwd(e,t){let i=null,n=e,s=null;for(;n!==s;){if(s=n,K.existsSync(k.join(s,"package.json"))&&(i=s),t!==null){if(K.existsSync(k.join(s,t))){i=s;break}}else if(i!==null)break;n=k.dirname(s)}return i}static async updateConfiguration(e,t){let i=Iw(),n=k.join(e,i),s=K.existsSync(n)?Si(await K.readFilePromise(n,"utf8")):{},o=!1,a;if(typeof t=="function"){try{a=t(s)}catch{a=t({})}if(a===s)return}else{a=s;for(let l of Object.keys(t)){let c=s[l],u=t[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 K.changeFilePromise(n,Ma(a),{automaticNewlines:!0})}static async updateHomeConfiguration(e){let t=Qd();return await tA.updateConfiguration(t,e)}activatePlugin(e,t){this.plugins.set(e,t),typeof t.configuration!="undefined"&&this.importSettings(t.configuration)}importSettings(e){for(let[t,i]of Object.entries(e))if(i!=null){if(this.settings.has(t))throw new Error(`Cannot redefine settings "${t}"`);this.settings.set(t,i),this.values.set(t,Ck(this,i))}}useWithSource(e,t,i,n){try{this.use(e,t,i,n)}catch(s){throw s.message+=` (in ${tt(this,e,qe.PATH)})`,s}}use(e,t,i,{strict:n=!0,overwrite:s=!1}={}){n=n&&this.get("enableStrictSettings");for(let o of["enableStrictSettings",...Object.keys(t)]){if(typeof t[o]=="undefined"||o==="plugins"||e===""&&lve.has(o))continue;if(o==="rcFilename")throw new Pe(`The rcFilename settings can only be set via ${`${Ew}RC_FILENAME`.toUpperCase()}, not via a rc file`);let l=this.settings.get(o);if(!l){if(n)throw new Pe(`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===Ie.MAP||l.isArray&&l.concatenateValues))continue;let c;try{c=dk(this,o,t[o],l,i)}catch(u){throw u.message+=` in ${tt(this,e,qe.PATH)}`,u}if(o==="enableStrictSettings"&&e!==""){n=c;continue}if(l.type===Ie.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:t=!1,getNativePaths:i=!1}){let n=this.get(e),s=this.settings.get(e);if(typeof s=="undefined")throw new Pe(`Couldn't find a configuration settings named "${e}"`);return yw(n,s,{hideSecrets:t,getNativePaths:i})}getSubprocessStreams(e,{header:t,prefix:i,report:n}){let s,o,a=K.createWriteStream(e);if(this.get("enableInlineBuilds")){let l=n.createStreamReporter(`${i} ${tt(this,"STDOUT","green")}`),c=n.createStreamReporter(`${i} ${tt(this,"STDERR","red")}`);s=new uk.PassThrough,s.pipe(l),s.pipe(a),o=new uk.PassThrough,o.pipe(c),o.pipe(a)}else s=a,o=a,typeof t!="undefined"&&s.write(`${t} -`);return{stdout:s,stderr:o}}makeResolver(){let e=[];for(let t of this.plugins.values())for(let i of t.resolvers||[])e.push(new i);return new wd([new pw,new oi,new nk,...e])}makeFetcher(){let e=[];for(let t of this.plugins.values())for(let i of t.fetchers||[])e.push(new i);return new yd([new Bd,new bd,...e])}getLinkers(){let e=[];for(let t of this.plugins.values())for(let i of t.linkers||[])e.push(new i);return e}getSupportedArchitectures(){let e=Sd(),t=this.get("supportedArchitectures"),i=t.get("os");i!==null&&(i=i.map(o=>o==="current"?e.os:o));let n=t.get("cpu");n!==null&&(n=n.map(o=>o==="current"?e.cpu:o));let s=t.get("libc");return s!==null&&(s=zo(s,o=>{var a;return o==="current"?(a=e.libc)!=null?a:zo.skip:o})),{os:i,cpu:n,libc:s}}async refreshPackageExtensions(){this.packageExtensions=new Map;let e=this.packageExtensions,t=(i,n,{userProvided:s=!1}={})=>{if(!po(i.range))throw new Error("Only semver ranges are allowed as keys for the packageExtensions setting");let o=new At;o.load(n,{yamlCompatibilityMode:!0});let a=Fg(e,i.identHash),l=[];a.push([i.range,l]);let c={status:qi.Inactive,userProvided:s,parentDescriptor:i};for(let u of o.dependencies.values())l.push(te(N({},c),{type:wi.Dependency,descriptor:u}));for(let u of o.peerDependencies.values())l.push(te(N({},c),{type:wi.PeerDependency,descriptor:u}));for(let[u,g]of o.peerDependenciesMeta)for(let[f,h]of Object.entries(g))l.push(te(N({},c),{type:wi.PeerDependencyMeta,selector:u,key:f,value:h}))};await this.triggerHook(i=>i.registerPackageExtensions,this,t);for(let[i,n]of this.get("packageExtensions"))t(ll(i,!0),ky(n),{userProvided:!0})}normalizePackage(e){let t=cd(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(!!qc(s,o))for(let l of a)switch(l.status===qi.Inactive&&(l.status=qi.Redundant),l.type){case wi.Dependency:typeof t.dependencies.get(l.descriptor.identHash)=="undefined"&&(l.status=qi.Active,t.dependencies.set(l.descriptor.identHash,l.descriptor));break;case wi.PeerDependency:typeof t.peerDependencies.get(l.descriptor.identHash)=="undefined"&&(l.status=qi.Active,t.peerDependencies.set(l.descriptor.identHash,l.descriptor));break;case wi.PeerDependencyMeta:{let c=t.peerDependenciesMeta.get(l.selector);(typeof c=="undefined"||!Object.prototype.hasOwnProperty.call(c,l.key)||c[l.key]!==l.value)&&(l.status=qi.Active,_a(t.peerDependenciesMeta,l.selector,()=>({}))[l.key]=l.value)}break;default:Pv(l);break}}}let n=s=>s.scope?`${s.scope}__${s.name}`:`${s.name}`;for(let s of t.peerDependenciesMeta.keys()){let o=An(s);t.peerDependencies.has(o.identHash)||t.peerDependencies.set(o.identHash,rr(o,"*"))}for(let s of t.peerDependencies.values()){if(s.scope==="types")continue;let o=n(s),a=$o("types",o),l=Ot(a);t.peerDependencies.has(a.identHash)||t.peerDependenciesMeta.has(l)||(t.peerDependencies.set(a.identHash,rr(a,"*")),t.peerDependenciesMeta.set(l,{optional:!0}))}return t.dependencies=new Map(kn(t.dependencies,([,s])=>Pn(s))),t.peerDependencies=new Map(kn(t.peerDependencies,([,s])=>Pn(s))),t}getLimit(e){return _a(this.limits,e,()=>(0,O4.default)(this.get(e)))}async triggerHook(e,...t){for(let i of this.plugins.values()){let n=i.hooks;if(!n)continue;let s=e(n);!s||await s(...t)}}async triggerMultipleHooks(e,t){for(let i of t)await this.triggerHook(e,...i)}async reduceHook(e,t,...i){let n=t;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,...t){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(...t);if(typeof o!="undefined")return o}return null}},ye=tA;ye.telemetry=null;var ss;(function(i){i[i.Never=0]="Never",i[i.ErrorCode=1]="ErrorCode",i[i.Always=2]="Always"})(ss||(ss={}));var ww=class extends ct{constructor({fileName:e,code:t,signal:i}){let n=ye.create(k.cwd()),s=tt(n,e,qe.PATH);super(X.EXCEPTION,`Child ${s} reported an error`,o=>{hve(t,i,{configuration:n,report:o})});this.code=Ek(t,i)}},Ik=class extends ww{constructor({fileName:e,code:t,signal:i,stdout:n,stderr:s}){super({fileName:e,code:t,signal:i});this.stdout=n,this.stderr=s}};function zc(r){return r!==null&&typeof r.fd=="number"}var _c=new Set;function yk(){}function wk(){for(let r of _c)r.kill()}async function ra(r,e,{cwd:t,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":zc(s)&&(c[0]=s),zc(o)&&(c[1]=o),zc(a)&&(c[2]=a);let u=(0,mk.default)(r,e,{cwd:H.fromPortablePath(t),env:te(N({},i),{PWD:H.fromPortablePath(t)}),stdio:c});_c.add(u),_c.size===1&&(process.on("SIGINT",yk),process.on("SIGTERM",wk)),!zc(s)&&s!==null&&s.pipe(u.stdin),zc(o)||u.stdout.pipe(o,{end:!1}),zc(a)||u.stderr.pipe(a,{end:!1});let g=()=>{for(let f of new Set([o,a]))zc(f)||f.end()};return new Promise((f,h)=>{u.on("error",p=>{_c.delete(u),_c.size===0&&(process.off("SIGINT",yk),process.off("SIGTERM",wk)),(l===2||l===1)&&g(),h(p)}),u.on("close",(p,m)=>{_c.delete(u),_c.size===0&&(process.off("SIGINT",yk),process.off("SIGTERM",wk)),(l===2||l===1&&p>0)&&g(),p===0||!n?f({code:Ek(p,m)}):h(new ww({fileName:r,code:p,signal:m}))})})}async function pve(r,e,{cwd:t,env:i=process.env,encoding:n="utf8",strict:s=!1}){let o=["ignore","pipe","pipe"],a=[],l=[],c=H.fromPortablePath(t);typeof i.PWD!="undefined"&&(i=te(N({},i),{PWD:c}));let u=(0,mk.default)(r,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",h=>{let p=ye.create(t),m=tt(p,r,qe.PATH);f(new ct(X.EXCEPTION,`Process ${m} failed to spawn`,y=>{y.reportError(X.EXCEPTION,` ${_o(p,{label:"Thrown Error",value:fo(qe.NO_HINT,h.message)})}`)}))}),u.on("close",(h,p)=>{let m=n==="buffer"?Buffer.concat(a):Buffer.concat(a).toString(n),y=n==="buffer"?Buffer.concat(l):Buffer.concat(l).toString(n);h===0||!s?g({code:Ek(h,p),stdout:m,stderr:y}):f(new Ik({fileName:r,code:h,signal:p,stdout:m,stderr:y}))})})}var dve=new Map([["SIGINT",2],["SIGQUIT",3],["SIGKILL",9],["SIGTERM",15]]);function Ek(r,e){let t=dve.get(e);return typeof t!="undefined"?128+t:r!=null?r:1}function hve(r,e,{configuration:t,report:i}){i.reportError(X.EXCEPTION,` ${_o(t,r!==null?{label:"Exit Code",value:fo(qe.NUMBER,r)}:{label:"Exit Signal",value:fo(qe.CODE,e)})}`)}var ir={};ft(ir,{Method:()=>Cl,RequestError:()=>w5.RequestError,del:()=>xPe,get:()=>SPe,getNetworkSettings:()=>S5,post:()=>HP,put:()=>vPe,request:()=>Od});var E5=ge(Uw()),I5=ge(require("https")),y5=ge(require("http")),MP=ge(is()),KP=ge(m5()),Hw=ge(require("url"));var w5=ge(Uw()),B5=new Map,b5=new Map,wPe=new y5.Agent({keepAlive:!0}),BPe=new I5.Agent({keepAlive:!0});function Q5(r){let e=new Hw.URL(r),t={host:e.hostname,headers:{}};return e.port&&(t.port=Number(e.port)),{proxy:t}}async function UP(r){return _a(b5,r,()=>K.readFilePromise(r).then(e=>(b5.set(r,e),e)))}function bPe({statusCode:r,statusMessage:e},t){let i=tt(t,r,qe.NUMBER),n=`https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/${r}`;return Mg(t,`${i}${e?` (${e})`:""}`,n)}async function jw(r,{configuration:e,customErrorMessage:t}){var i,n;try{return await r}catch(s){if(s.name!=="HTTPError")throw s;let o=(n=t==null?void 0:t(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 E5.TimeoutError&&s.event==="socket"&&(o+=`(can be increased via ${tt(e,"httpTimeout",qe.SETTING)})`);let a=new ct(X.NETWORK_ERROR,o,l=>{s.response&&l.reportError(X.NETWORK_ERROR,` ${_o(e,{label:"Response Code",value:fo(qe.NO_HINT,bPe(s.response,e))})}`),s.request&&(l.reportError(X.NETWORK_ERROR,` ${_o(e,{label:"Request Method",value:fo(qe.NO_HINT,s.request.options.method)})}`),l.reportError(X.NETWORK_ERROR,` ${_o(e,{label:"Request URL",value:fo(qe.URL,s.request.requestUrl)})}`)),s.request.redirects.length>0&&l.reportError(X.NETWORK_ERROR,` ${_o(e,{label:"Request Redirects",value:fo(qe.NO_HINT,Uv(e,s.request.redirects,qe.URL))})}`),s.request.retryCount===s.request.options.retry.limit&&l.reportError(X.NETWORK_ERROR,` ${_o(e,{label:"Request Retry Count",value:fo(qe.NO_HINT,`${tt(e,s.request.retryCount,qe.NUMBER)} (can be increased via ${tt(e,"httpRetry",qe.SETTING)})`)})}`)});throw a.originalError=s,a}}function S5(r,e){let t=[...e.configuration.get("networkSettings")].sort(([o],[a])=>a.length-o.length),i={enableNetwork:void 0,caFilePath:void 0,httpProxy:void 0,httpsProxy:void 0,httpsKeyFilePath:void 0,httpsCertFilePath:void 0},n=Object.keys(i),s=typeof r=="string"?new Hw.URL(r):r;for(let[o,a]of t)if(MP.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 Cl;(function(n){n.GET="GET",n.PUT="PUT",n.POST="POST",n.DELETE="DELETE"})(Cl||(Cl={}));async function Od(r,e,{configuration:t,headers:i,jsonRequest:n,jsonResponse:s,method:o=Cl.GET}){let a=async()=>await QPe(r,e,{configuration:t,headers:i,jsonRequest:n,jsonResponse:s,method:o});return await(await t.reduceHook(c=>c.wrapNetworkRequest,a,{target:r,body:e,configuration:t,headers:i,jsonRequest:n,jsonResponse:s,method:o}))()}async function SPe(r,n){var s=n,{configuration:e,jsonResponse:t}=s,i=Or(s,["configuration","jsonResponse"]);let o=_a(B5,r,()=>jw(Od(r,null,N({configuration:e},i)),{configuration:e}).then(a=>(B5.set(r,a.body),a.body)));return Buffer.isBuffer(o)===!1&&(o=await o),t?JSON.parse(o.toString()):o}async function vPe(r,e,n){var s=n,{customErrorMessage:t}=s,i=Or(s,["customErrorMessage"]);return(await jw(Od(r,e,te(N({},i),{method:Cl.PUT})),i)).body}async function HP(r,e,n){var s=n,{customErrorMessage:t}=s,i=Or(s,["customErrorMessage"]);return(await jw(Od(r,e,te(N({},i),{method:Cl.POST})),i)).body}async function xPe(r,i){var n=i,{customErrorMessage:e}=n,t=Or(n,["customErrorMessage"]);return(await jw(Od(r,null,te(N({},t),{method:Cl.DELETE})),t)).body}async function QPe(r,e,{configuration:t,headers:i,jsonRequest:n,jsonResponse:s,method:o=Cl.GET}){let a=typeof r=="string"?new Hw.URL(r):r,l=S5(a,{configuration:t});if(l.enableNetwork===!1)throw new Error(`Request to '${a.href}' has been blocked because of your configuration settings`);if(a.protocol==="http:"&&!MP.default.isMatch(a.hostname,t.get("unsafeHttpWhitelist")))throw new Error(`Unsafe http requests must be explicitly whitelisted in your configuration (${a.hostname})`);let u={agent:{http:l.httpProxy?KP.default.httpOverHttp(Q5(l.httpProxy)):wPe,https:l.httpsProxy?KP.default.httpsOverHttp(Q5(l.httpsProxy)):BPe},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=t.get("httpTimeout"),f=t.get("httpRetry"),h=t.get("enableStrictSsl"),p=l.caFilePath,m=l.httpsCertFilePath,y=l.httpsKeyFilePath,{default:b}=await Promise.resolve().then(()=>ge(Uw())),v=p?await UP(p):void 0,x=m?await UP(m):void 0,T=y?await UP(y):void 0,q=b.extend(N({timeout:{socket:g},retry:f,https:{rejectUnauthorized:h,certificateAuthority:v,certificate:x,key:T}},u));return t.getLimit("networkConcurrency")(()=>q(a))}var Zt={};ft(Zt,{PackageManager:()=>hn,detectPackageManager:()=>K9,executePackageAccessibleBinary:()=>Y9,executePackageScript:()=>nB,executePackageShellcode:()=>rD,executeWorkspaceAccessibleBinary:()=>WDe,executeWorkspaceLifecycleScript:()=>G9,executeWorkspaceScript:()=>j9,getPackageAccessibleBinaries:()=>sB,getWorkspaceAccessibleBinaries:()=>H9,hasPackageScript:()=>YDe,hasWorkspaceScript:()=>tD,makeScriptEnv:()=>Yd,maybeExecuteWorkspaceLifecycleScript:()=>JDe,prepareExternalProject:()=>GDe});var Md={};ft(Md,{getLibzipPromise:()=>fn,getLibzipSync:()=>D5});var P5=ge(x5());var ml=["number","number"],YP;(function(L){L[L.ZIP_ER_OK=0]="ZIP_ER_OK",L[L.ZIP_ER_MULTIDISK=1]="ZIP_ER_MULTIDISK",L[L.ZIP_ER_RENAME=2]="ZIP_ER_RENAME",L[L.ZIP_ER_CLOSE=3]="ZIP_ER_CLOSE",L[L.ZIP_ER_SEEK=4]="ZIP_ER_SEEK",L[L.ZIP_ER_READ=5]="ZIP_ER_READ",L[L.ZIP_ER_WRITE=6]="ZIP_ER_WRITE",L[L.ZIP_ER_CRC=7]="ZIP_ER_CRC",L[L.ZIP_ER_ZIPCLOSED=8]="ZIP_ER_ZIPCLOSED",L[L.ZIP_ER_NOENT=9]="ZIP_ER_NOENT",L[L.ZIP_ER_EXISTS=10]="ZIP_ER_EXISTS",L[L.ZIP_ER_OPEN=11]="ZIP_ER_OPEN",L[L.ZIP_ER_TMPOPEN=12]="ZIP_ER_TMPOPEN",L[L.ZIP_ER_ZLIB=13]="ZIP_ER_ZLIB",L[L.ZIP_ER_MEMORY=14]="ZIP_ER_MEMORY",L[L.ZIP_ER_CHANGED=15]="ZIP_ER_CHANGED",L[L.ZIP_ER_COMPNOTSUPP=16]="ZIP_ER_COMPNOTSUPP",L[L.ZIP_ER_EOF=17]="ZIP_ER_EOF",L[L.ZIP_ER_INVAL=18]="ZIP_ER_INVAL",L[L.ZIP_ER_NOZIP=19]="ZIP_ER_NOZIP",L[L.ZIP_ER_INTERNAL=20]="ZIP_ER_INTERNAL",L[L.ZIP_ER_INCONS=21]="ZIP_ER_INCONS",L[L.ZIP_ER_REMOVE=22]="ZIP_ER_REMOVE",L[L.ZIP_ER_DELETED=23]="ZIP_ER_DELETED",L[L.ZIP_ER_ENCRNOTSUPP=24]="ZIP_ER_ENCRNOTSUPP",L[L.ZIP_ER_RDONLY=25]="ZIP_ER_RDONLY",L[L.ZIP_ER_NOPASSWD=26]="ZIP_ER_NOPASSWD",L[L.ZIP_ER_WRONGPASSWD=27]="ZIP_ER_WRONGPASSWD",L[L.ZIP_ER_OPNOTSUPP=28]="ZIP_ER_OPNOTSUPP",L[L.ZIP_ER_INUSE=29]="ZIP_ER_INUSE",L[L.ZIP_ER_TELL=30]="ZIP_ER_TELL",L[L.ZIP_ER_COMPRESSED_DATA=31]="ZIP_ER_COMPRESSED_DATA"})(YP||(YP={}));var k5=r=>({get HEAP8(){return r.HEAP8},get HEAPU8(){return r.HEAPU8},errors:YP,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:r._malloc(1),uint16S:r._malloc(2),uint32S:r._malloc(4),uint64S:r._malloc(8),malloc:r._malloc,free:r._free,getValue:r.getValue,open:r.cwrap("zip_open","number",["string","number","number"]),openFromSource:r.cwrap("zip_open_from_source","number",["number","number","number"]),close:r.cwrap("zip_close","number",["number"]),discard:r.cwrap("zip_discard",null,["number"]),getError:r.cwrap("zip_get_error","number",["number"]),getName:r.cwrap("zip_get_name","string",["number","number","number"]),getNumEntries:r.cwrap("zip_get_num_entries","number",["number","number"]),delete:r.cwrap("zip_delete","number",["number","number"]),stat:r.cwrap("zip_stat","number",["number","string","number","number"]),statIndex:r.cwrap("zip_stat_index","number",["number",...ml,"number","number"]),fopen:r.cwrap("zip_fopen","number",["number","string","number"]),fopenIndex:r.cwrap("zip_fopen_index","number",["number",...ml,"number"]),fread:r.cwrap("zip_fread","number",["number","number","number","number"]),fclose:r.cwrap("zip_fclose","number",["number"]),dir:{add:r.cwrap("zip_dir_add","number",["number","string"])},file:{add:r.cwrap("zip_file_add","number",["number","string","number","number"]),getError:r.cwrap("zip_file_get_error","number",["number"]),getExternalAttributes:r.cwrap("zip_file_get_external_attributes","number",["number",...ml,"number","number","number"]),setExternalAttributes:r.cwrap("zip_file_set_external_attributes","number",["number",...ml,"number","number","number"]),setMtime:r.cwrap("zip_file_set_mtime","number",["number",...ml,"number","number"]),setCompression:r.cwrap("zip_set_file_compression","number",["number",...ml,"number","number"])},ext:{countSymlinks:r.cwrap("zip_ext_count_symlinks","number",["number"])},error:{initWithCode:r.cwrap("zip_error_init_with_code",null,["number","number"]),strerror:r.cwrap("zip_error_strerror","string",["number"])},name:{locate:r.cwrap("zip_name_locate","number",["number","string","number"])},source:{fromUnattachedBuffer:r.cwrap("zip_source_buffer_create","number",["number","number","number","number"]),fromBuffer:r.cwrap("zip_source_buffer","number",["number","number",...ml,"number"]),free:r.cwrap("zip_source_free",null,["number"]),keep:r.cwrap("zip_source_keep",null,["number"]),open:r.cwrap("zip_source_open","number",["number"]),close:r.cwrap("zip_source_close","number",["number"]),seek:r.cwrap("zip_source_seek","number",["number",...ml,"number"]),tell:r.cwrap("zip_source_tell","number",["number"]),read:r.cwrap("zip_source_read","number",["number","number","number"]),error:r.cwrap("zip_source_error","number",["number"]),setMtime:r.cwrap("zip_source_set_mtime","number",["number","number"])},struct:{stat:r.cwrap("zipstruct_stat","number",[]),statS:r.cwrap("zipstruct_statS","number",[]),statName:r.cwrap("zipstruct_stat_name","string",["number"]),statIndex:r.cwrap("zipstruct_stat_index","number",["number"]),statSize:r.cwrap("zipstruct_stat_size","number",["number"]),statCompSize:r.cwrap("zipstruct_stat_comp_size","number",["number"]),statCompMethod:r.cwrap("zipstruct_stat_comp_method","number",["number"]),statMtime:r.cwrap("zipstruct_stat_mtime","number",["number"]),statCrc:r.cwrap("zipstruct_stat_crc","number",["number"]),error:r.cwrap("zipstruct_error","number",[]),errorS:r.cwrap("zipstruct_errorS","number",[]),errorCodeZip:r.cwrap("zipstruct_error_code_zip","number",["number"])}});var qP=null;function D5(){return qP===null&&(qP=k5((0,P5.default)())),qP}async function fn(){return D5()}var Ud={};ft(Ud,{ShellError:()=>Ms,execute:()=>Xw,globUtils:()=>Yw});var G5=ge(uv()),Y5=ge(require("os")),os=ge(require("stream")),q5=ge(require("util"));var Ms=class extends Error{constructor(e){super(e);this.name="ShellError"}};var Yw={};ft(Yw,{fastGlobOptions:()=>N5,isBraceExpansion:()=>L5,isGlobPattern:()=>kPe,match:()=>PPe,micromatchOptions:()=>Jw});var R5=ge(Zy()),F5=ge(require("fs")),qw=ge(is()),Jw={strictBrackets:!0},N5={onlyDirectories:!1,onlyFiles:!1};function kPe(r){if(!qw.default.scan(r,Jw).isGlob)return!1;try{qw.default.parse(r,Jw)}catch{return!1}return!0}function PPe(r,{cwd:e,baseFs:t}){return(0,R5.default)(r,te(N({},N5),{cwd:H.fromPortablePath(e),fs:WE(F5.default,new Vh(t))}))}function L5(r){return qw.default.scan(r,Jw).isBrace}var T5=ge(SQ()),na=ge(require("stream")),O5=ge(require("string_decoder")),Fn;(function(i){i[i.STDIN=0]="STDIN",i[i.STDOUT=1]="STDOUT",i[i.STDERR=2]="STDERR"})(Fn||(Fn={}));var Xc=new Set;function JP(){}function WP(){for(let r of Xc)r.kill()}function M5(r,e,t,i){return n=>{let s=n[0]instanceof na.Transform?"pipe":n[0],o=n[1]instanceof na.Transform?"pipe":n[1],a=n[2]instanceof na.Transform?"pipe":n[2],l=(0,T5.default)(r,e,te(N({},i),{stdio:[s,o,a]}));return Xc.add(l),Xc.size===1&&(process.on("SIGINT",JP),process.on("SIGTERM",WP)),n[0]instanceof na.Transform&&n[0].pipe(l.stdin),n[1]instanceof na.Transform&&l.stdout.pipe(n[1],{end:!1}),n[2]instanceof na.Transform&&l.stderr.pipe(n[2],{end:!1}),{stdin:l.stdin,promise:new Promise(c=>{l.on("error",u=>{switch(Xc.delete(l),Xc.size===0&&(process.off("SIGINT",JP),process.off("SIGTERM",WP)),u.code){case"ENOENT":n[2].write(`command not found: ${r} -`),c(127);break;case"EACCES":n[2].write(`permission denied: ${r} -`),c(128);break;default:n[2].write(`uncaught error: ${u.message} -`),c(1);break}}),l.on("close",u=>{Xc.delete(l),Xc.size===0&&(process.off("SIGINT",JP),process.off("SIGTERM",WP)),c(u!==null?u:129)})})}}}function K5(r){return e=>{let t=e[0]==="pipe"?new na.PassThrough:e[0];return{stdin:t,promise:Promise.resolve().then(()=>r({stdin:t,stdout:e[1],stderr:e[2]}))}}}var mo=class{constructor(e){this.stream=e}close(){}get(){return this.stream}},U5=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}},Kd=class{constructor(e,t){this.stdin=null;this.stdout=null;this.stderr=null;this.pipe=null;this.ancestor=e,this.implementation=t}static start(e,{stdin:t,stdout:i,stderr:n}){let s=new Kd(null,e);return s.stdin=t,s.stdout=i,s.stderr=n,s}pipeTo(e,t=1){let i=new Kd(this,e),n=new U5;return i.pipe=n,i.stdout=this.stdout,i.stderr=this.stderr,(t&1)==1?this.stdout=n:this.ancestor!==null&&(this.stderr=this.ancestor.stdout),(t&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 t;if(this.stdout===null)throw new Error("Assertion failed: No output stream registered");t=this.stdout,e[1]=t.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=>(t.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 Ww(r,e){return Kd.start(r,e)}function H5(r,e=null){let t=new na.PassThrough,i=new O5.StringDecoder,n="";return t.on("data",s=>{let o=i.write(s),a;do if(a=o.indexOf(` -`),a!==-1){let l=n+o.substring(0,a);o=o.substring(a+1),n="",r(e!==null?`${e} ${l}`:l)}while(a!==-1);n+=o}),t.on("end",()=>{let s=i.end();s!==""&&r(e!==null?`${e} ${s}`:s)}),t}function j5(r,{prefix:e}){return{stdout:H5(t=>r.stdout.write(`${t} -`),r.stdout.isTTY?e:null),stderr:H5(t=>r.stderr.write(`${t} -`),r.stderr.isTTY?e:null)}}var DPe=(0,q5.promisify)(setTimeout);var zi;(function(t){t[t.Readable=1]="Readable",t[t.Writable=2]="Writable"})(zi||(zi={}));function J5(r,e,t){let i=new os.PassThrough({autoDestroy:!0});switch(r){case Fn.STDIN:(e&1)==1&&t.stdin.pipe(i,{end:!1}),(e&2)==2&&t.stdin instanceof os.Writable&&i.pipe(t.stdin,{end:!1});break;case Fn.STDOUT:(e&1)==1&&t.stdout.pipe(i,{end:!1}),(e&2)==2&&i.pipe(t.stdout,{end:!1});break;case Fn.STDERR:(e&1)==1&&t.stderr.pipe(i,{end:!1}),(e&2)==2&&i.pipe(t.stderr,{end:!1});break;default:throw new Ms(`Bad file descriptor: "${r}"`)}return i}function zw(r,e={}){let t=N(N({},r),e);return t.environment=N(N({},r.environment),e.environment),t.variables=N(N({},r.variables),e.variables),t}var RPe=new Map([["cd",async([r=(0,Y5.homedir)(),...e],t,i)=>{let n=k.resolve(i.cwd,H.toPortablePath(r));if(!(await t.baseFs.statPromise(n).catch(o=>{throw o.code==="ENOENT"?new Ms(`cd: no such file or directory: ${r}`):o})).isDirectory())throw new Ms(`cd: not a directory: ${r}`);return i.cwd=n,0}],["pwd",async(r,e,t)=>(t.stdout.write(`${H.fromPortablePath(t.cwd)} -`),0)],[":",async(r,e,t)=>0],["true",async(r,e,t)=>0],["false",async(r,e,t)=>1],["exit",async([r,...e],t,i)=>i.exitCode=parseInt(r!=null?r:i.variables["?"],10)],["echo",async(r,e,t)=>(t.stdout.write(`${r.join(" ")} -`),0)],["sleep",async([r],e,t)=>{if(typeof r=="undefined")throw new Ms("sleep: missing operand");let i=Number(r);if(Number.isNaN(i))throw new Ms(`sleep: invalid time interval '${r}'`);return await DPe(1e3*i,0)}],["__ysh_run_procedure",async(r,e,t)=>{let i=t.procedures[r[0]];return await Ww(i,{stdin:new mo(t.stdin),stdout:new mo(t.stdout),stderr:new mo(t.stderr)}).run()}],["__ysh_set_redirects",async(r,e,t)=>{let i=t.stdin,n=t.stdout,s=t.stderr,o=[],a=[],l=[],c=0;for(;r[c]!=="--";){let g=r[c++],{type:f,fd:h}=JSON.parse(g),p=v=>{switch(h){case null:case 0:o.push(v);break;default:throw new Error(`Unsupported file descriptor: "${h}"`)}},m=v=>{switch(h){case null:case 1:a.push(v);break;case 2:l.push(v);break;default:throw new Error(`Unsupported file descriptor: "${h}"`)}},y=Number(r[c++]),b=c+y;for(let v=c;ve.baseFs.createReadStream(k.resolve(t.cwd,H.toPortablePath(r[v]))));break;case"<<<":p(()=>{let x=new os.PassThrough;return process.nextTick(()=>{x.write(`${r[v]} -`),x.end()}),x});break;case"<&":p(()=>J5(Number(r[v]),1,t));break;case">":case">>":{let x=k.resolve(t.cwd,H.toPortablePath(r[v]));m(x==="/dev/null"?new os.Writable({autoDestroy:!0,emitClose:!0,write(T,q,Y){setImmediate(Y)}}):e.baseFs.createWriteStream(x,f===">>"?{flags:"a"}:void 0))}break;case">&":m(J5(Number(r[v]),2,t));break;default:throw new Error(`Assertion failed: Unsupported redirection type: "${f}"`)}}if(o.length>0){let g=new os.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 os.PassThrough;n=g;for(let f of a)g.pipe(f)}if(l.length>0){let g=new os.PassThrough;s=g;for(let f of l)g.pipe(f)}let u=await Ww(Hd(r.slice(c+1),e,t),{stdin:new mo(i),stdout:new mo(n),stderr:new mo(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 FPe(r,e,t){let i=[],n=new os.PassThrough;return n.on("data",s=>i.push(s)),await _w(r,e,zw(t,{stdout:n})),Buffer.concat(i).toString().replace(/[\r\n]+$/,"")}async function W5(r,e,t){let i=r.map(async s=>{let o=await aA(s.args,e,t);return{name:s.name,value:o.join(" ")}});return(await Promise.all(i)).reduce((s,o)=>(s[o.name]=o.value,s),{})}function Vw(r){return r.match(/[^ \r\n\t]+/g)||[]}async function z5(r,e,t,i,n=i){switch(r.name){case"$":i(String(process.pid));break;case"#":i(String(e.args.length));break;case"@":if(r.quoted)for(let s of e.args)n(s);else for(let s of e.args){let o=Vw(s);for(let a=0;a=0&&sr+e,subtraction:(r,e)=>r-e,multiplication:(r,e)=>r*e,division:(r,e)=>Math.trunc(r/e)};async function jd(r,e,t){if(r.type==="number"){if(Number.isInteger(r.value))return r.value;throw new Error(`Invalid number: "${r.value}", only integers are allowed`)}else if(r.type==="variable"){let i=[];await z5(te(N({},r),{quoted:!0}),e,t,s=>i.push(s));let n=Number(i.join(" "));return Number.isNaN(n)?jd({type:"variable",name:i.join(" ")},e,t):jd({type:"number",value:n},e,t)}else return NPe[r.type](await jd(r.left,e,t),await jd(r.right,e,t))}async function aA(r,e,t){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 r){let g=!1;switch(u.type){case"redirection":{let f=await aA(u.args,e,t);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 FPe(f.shell,e,t);if(f.quoted)o(h);else{let p=Vw(h);for(let m=0;m0){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 Hd(r,e,t){e.builtins.has(r[0])||(r=["command",...r]);let i=H.fromPortablePath(t.cwd),n=t.environment;typeof n.PWD!="undefined"&&(n=te(N({},n),{PWD:i}));let[s,...o]=r;if(s==="command")return M5(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 K5(async({stdin:l,stdout:c,stderr:u})=>{let{stdin:g,stdout:f,stderr:h}=t;t.stdin=l,t.stdout=c,t.stderr=u;try{return await a(o,e,t)}finally{t.stdin=g,t.stdout=f,t.stderr=h}})}function LPe(r,e,t){return i=>{let n=new os.PassThrough,s=_w(r,e,zw(t,{stdin:n}));return{stdin:n,promise:s}}}function TPe(r,e,t){return i=>{let n=new os.PassThrough,s=_w(r,e,t);return{stdin:n,promise:s}}}function _5(r,e,t,i){if(e.length===0)return r;{let n;do n=String(Math.random());while(Object.prototype.hasOwnProperty.call(i.procedures,n));return i.procedures=N({},i.procedures),i.procedures[n]=r,Hd([...e,"__ysh_run_procedure",n],t,i)}}async function V5(r,e,t){let i=r,n=null,s=null;for(;i;){let o=i.then?N({},t):t,a;switch(i.type){case"command":{let l=await aA(i.args,e,t),c=await W5(i.envs,e,t);a=i.envs.length?Hd(l,e,zw(o,{environment:c})):Hd(l,e,o)}break;case"subshell":{let l=await aA(i.args,e,t),c=LPe(i.subshell,e,o);a=_5(c,l,e,o)}break;case"group":{let l=await aA(i.args,e,t),c=TPe(i.group,e,o);a=_5(c,l,e,o)}break;case"envs":{let l=await W5(i.envs,e,t);o.environment=N(N({},o.environment),l),a=Hd(["true"],e,o)}break}if(typeof a=="undefined")throw new Error("Assertion failed: An action should have been generated");if(n===null)s=Ww(a,{stdin:new mo(o.stdin),stdout:new mo(o.stdout),stderr:new mo(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,Fn.STDOUT);break;case"|&":s=s.pipeTo(a,Fn.STDOUT|Fn.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 OPe(r,e,t,{background:i=!1}={}){function n(s){let o=["#2E86AB","#A23B72","#F18F01","#C73E1D","#CCE2A3"],a=o[s%o.length];return G5.default.hex(a)}if(i){let s=t.nextBackgroundJobIndex++,o=n(s),a=`[${s}]`,l=o(a),{stdout:c,stderr:u}=j5(t,{prefix:l});return t.backgroundJobs.push(V5(r,e,zw(t,{stdout:c,stderr:u})).catch(g=>u.write(`${g.message} -`)).finally(()=>{t.stdout.isTTY&&t.stdout.write(`Job ${l}, '${o(eg(r))}' has ended -`)})),0}return await V5(r,e,t)}async function MPe(r,e,t,{background:i=!1}={}){let n,s=a=>{n=a,t.variables["?"]=String(a)},o=async a=>{try{return await OPe(a.chain,e,t,{background:i&&typeof a.then=="undefined"})}catch(l){if(!(l instanceof Ms))throw l;return t.stderr.write(`${l.message} -`),1}};for(s(await o(r));r.then;){if(t.exitCode!==null)return t.exitCode;switch(r.then.type){case"&&":n===0&&s(await o(r.then.line));break;case"||":n!==0&&s(await o(r.then.line));break;default:throw new Error(`Assertion failed: Unsupported command type: "${r.then.type}"`)}r=r.then.line}return n}async function _w(r,e,t){let i=t.backgroundJobs;t.backgroundJobs=[];let n=0;for(let{command:s,type:o}of r){if(n=await MPe(s,e,t,{background:o==="&"}),t.exitCode!==null)return t.exitCode;t.variables["?"]=String(n)}return await Promise.all(t.backgroundJobs),t.backgroundJobs=i,n}function X5(r){switch(r.type){case"variable":return r.name==="@"||r.name==="#"||r.name==="*"||Number.isFinite(parseInt(r.name,10))||"defaultValue"in r&&!!r.defaultValue&&r.defaultValue.some(e=>Gd(e))||"alternativeValue"in r&&!!r.alternativeValue&&r.alternativeValue.some(e=>Gd(e));case"arithmetic":return zP(r.arithmetic);case"shell":return _P(r.shell);default:return!1}}function Gd(r){switch(r.type){case"redirection":return r.args.some(e=>Gd(e));case"argument":return r.segments.some(e=>X5(e));default:throw new Error(`Assertion failed: Unsupported argument type: "${r.type}"`)}}function zP(r){switch(r.type){case"variable":return X5(r);case"number":return!1;default:return zP(r.left)||zP(r.right)}}function _P(r){return r.some(({command:e})=>{for(;e;){let t=e.chain;for(;t;){let i;switch(t.type){case"subshell":i=_P(t.subshell);break;case"command":i=t.envs.some(n=>n.args.some(s=>Gd(s)))||t.args.some(n=>Gd(n));break}if(i)return!0;if(!t.then)break;t=t.then.chain}if(!e.then)break;e=e.then.line}return!1})}async function Xw(r,e=[],{baseFs:t=new ar,builtins:i={},cwd:n=H.toPortablePath(process.cwd()),env:s=process.env,stdin:o=process.stdin,stdout:a=process.stdout,stderr:l=process.stderr,variables:c={},glob:u=Yw}={}){let g={};for(let[p,m]of Object.entries(s))typeof m!="undefined"&&(g[p]=m);let f=new Map(RPe);for(let[p,m]of Object.entries(i))f.set(p,m);o===null&&(o=new os.PassThrough,o.end());let h=_E(r,u);if(!_P(h)&&h.length>0&&e.length>0){let{command:p}=h[h.length-1];for(;p.then;)p=p.then.line;let m=p.chain;for(;m.then;)m=m.then.chain;m.type==="command"&&(m.args=m.args.concat(e.map(y=>({type:"argument",segments:[{type:"text",text:y}]}))))}return await _w(h,{args:e,baseFs:t,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 O9=ge(Zw()),M9=ge(gg()),El=ge(require("stream"));var R9=ge(D9()),tB=ge(Ic());var F9=["\u280B","\u2819","\u2839","\u2838","\u283C","\u2834","\u2826","\u2827","\u2807","\u280F"],N9=80,TDe=new Set([X.FETCH_NOT_CACHED,X.UNUSED_CACHE_ENTRY]),ODe=5,rB=tB.default.GITHUB_ACTIONS?{start:r=>`::group::${r} -`,end:r=>`::endgroup:: -`}:tB.default.TRAVIS?{start:r=>`travis_fold:start:${r} -`,end:r=>`travis_fold:end:${r} -`}:tB.default.GITLAB?{start:r=>`section_start:${Math.floor(Date.now()/1e3)}:${r.toLowerCase().replace(/\W+/g,"_")}[collapsed=true]\r${r} -`,end:r=>`section_end:${Math.floor(Date.now()/1e3)}:${r.toLowerCase().replace(/\W+/g,"_")}\r`}:null,L9=new Date,MDe=["iTerm.app","Apple_Terminal"].includes(process.env.TERM_PROGRAM)||!!process.env.WT_SESSION,KDe=r=>r,iB=KDe({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}}),UDe=MDe&&Object.keys(iB).find(r=>{let e=iB[r];return!(e.date&&(e.date[0]!==L9.getDate()||e.date[1]!==L9.getMonth()+1))})||"default";function T9(r,{configuration:e,json:t}){if(!e.get("enableMessageNames"))return"";let n=_A(r===null?0:r);return!t&&r===null?tt(e,n,"grey"):n}function eD(r,{configuration:e,json:t}){let i=T9(r,{configuration:e,json:t});if(!i||r===null||r===X.UNNAMED)return i;let n=X[r],s=`https://yarnpkg.com/advanced/error-codes#${i}---${n}`.toLowerCase();return Mg(e,i,s)}var Je=class extends Ji{constructor({configuration:e,stdout:t,json:i=!1,includeFooter:n=!0,includeLogs:s=!i,includeInfos:o=s,includeWarnings:a=s,forgettableBufferSize:l=ODe,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.progressStyle=null;this.progressMaxScaledSize=null;this.forgettableLines=[];if(nd(this,{configuration:e}),this.configuration=e,this.forgettableBufferSize=l,this.forgettableNames=new Set([...c,...TDe]),this.includeFooter=n,this.includeInfos=o,this.includeWarnings=a,this.json=i,this.stdout=t,e.get("enableProgressBars")&&!i&&t.isTTY&&t.columns>22){let u=e.get("progressBarStyle")||UDe;if(!Object.prototype.hasOwnProperty.call(iB,u))throw new Error("Assertion failed: Invalid progress bar style");this.progressStyle=iB[u];let g="\u27A4 YN0000: \u250C ".length,f=Math.max(0,Math.min(t.columns-g,80));this.progressMaxScaledSize=Math.floor(this.progressStyle.size*f/80)}}static async start(e,t){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(X.UNNAMED,a)};try{await t(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,t){this.lastCacheMiss=e,this.cacheMissCount+=1,typeof t!="undefined"&&!this.configuration.get("preferAggregateCacheInfo")&&this.reportInfo(X.FETCH_NOT_CACHED,t)}startSectionSync({reportHeader:e,reportFooter:t,skipIfEmpty:i},n){let s={committed:!1,action:()=>{e==null||e()}};i?this.uncommitted.add(s):(s.action(),s.committed=!0);let o=Date.now();try{return n()}catch(a){throw this.reportExceptionOnce(a),a}finally{let a=Date.now();this.uncommitted.delete(s),s.committed&&(t==null||t(a-o))}}async startSectionPromise({reportHeader:e,reportFooter:t,skipIfEmpty:i},n){let s={committed:!1,action:()=>{e==null||e()}};i?this.uncommitted.add(s):(s.action(),s.committed=!0);let o=Date.now();try{return await n()}catch(a){throw this.reportExceptionOnce(a),a}finally{let a=Date.now();this.uncommitted.delete(s),s.committed&&(t==null||t(a-o))}}startTimerImpl(e,t,i){let n=typeof t=="function"?{}:t;return{cb:typeof t=="function"?t:i,reportHeader:()=>{this.reportInfo(null,`\u250C ${e}`),this.indent+=1,rB!==null&&!this.json&&this.includeInfos&&this.stdout.write(rB.start(e))},reportFooter:o=>{this.indent-=1,rB!==null&&!this.json&&this.includeInfos&&this.stdout.write(rB.end(e)),this.configuration.get("enableTimers")&&o>200?this.reportInfo(null,`\u2514 Completed in ${tt(this.configuration,o,qe.DURATION)}`):this.reportInfo(null,"\u2514 Completed")},skipIfEmpty:n.skipIfEmpty}}startTimerSync(e,t,i){let o=this.startTimerImpl(e,t,i),{cb:n}=o,s=Or(o,["cb"]);return this.startSectionSync(s,n)}async startTimerPromise(e,t,i){let o=this.startTimerImpl(e,t,i),{cb:n}=o,s=Or(o,["cb"]);return this.startSectionPromise(s,n)}async startCacheReport(e){let t=this.configuration.get("preferAggregateCacheInfo")?{cacheHitCount:this.cacheHitCount,cacheMissCount:this.cacheMissCount}:null;try{return await e()}catch(i){throw this.reportExceptionOnce(i),i}finally{t!==null&&this.reportCacheChanges(t)}}reportSeparator(){this.indent===0?this.writeLineWithForgettableReset(""):this.reportInfo(null,"")}reportInfo(e,t){if(!this.includeInfos)return;this.commit();let i=this.formatNameWithHyperlink(e),n=i?`${i}: `:"",s=`${tt(this.configuration,"\u27A4","blueBright")} ${n}${this.formatIndent()}${t}`;if(this.json)this.reportJson({type:"info",name:e,displayName:this.formatName(e),indent:this.formatIndent(),data:t});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,t){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:t}):this.writeLineWithForgettableReset(`${tt(this.configuration,"\u27A4","yellowBright")} ${n}${this.formatIndent()}${t}`)}reportError(e,t){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:t}):this.writeLineWithForgettableReset(`${tt(this.configuration,"\u27A4","redBright")} ${n}${this.formatIndent()}${t}`,{truncate:!1})}reportProgress(e){if(this.progressStyle===null)return te(N({},Promise.resolve()),{stop:()=>{}});if(e.hasProgress&&e.hasTitle)throw new Error("Unimplemented: Progress bars can't have both progress and titles.");let t=!1,i=Promise.resolve().then(async()=>{let s={progress:e.hasProgress?0:void 0,title:e.hasTitle?"":void 0};this.progress.set(e,{definition:s,lastScaledSize:e.hasProgress?-1:void 0,lastTitle:void 0}),this.refreshProgress({delta:-1});for await(let{progress:o,title:a}of e)t||s.progress===o&&s.title===a||(s.progress=o,s.title=a,this.refreshProgress());n()}),n=()=>{t||(t=!0,this.progress.delete(e),this.refreshProgress({delta:1}))};return te(N({},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 t=tt(this.configuration,Date.now()-this.startTime,qe.DURATION),i=this.configuration.get("enableTimers")?`${e} in ${t}`:e;this.errorCount>0?this.reportError(X.UNNAMED,i):this.warningCount>0?this.reportWarning(X.UNNAMED,i):this.reportInfo(X.UNNAMED,i)}writeLine(e,{truncate:t}={}){this.clearProgress({clear:!0}),this.stdout.write(`${this.truncate(e,{truncate:t})} -`),this.writeProgress()}writeLineWithForgettableReset(e,{truncate:t}={}){this.forgettableLines=[],this.writeLine(e,{truncate:t})}writeLines(e,{truncate:t}={}){this.clearProgress({delta:e.length});for(let i of e)this.stdout.write(`${this.truncate(i,{truncate:t})} -`);this.writeProgress()}reportCacheChanges({cacheHitCount:e,cacheMissCount:t}){let i=this.cacheHitCount-e,n=this.cacheMissCount-t;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 (${It(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 (${It(this.configuration,this.lastCacheMiss)})`),this.reportInfo(X.FETCH_NOT_CACHED,s)}commit(){let e=this.uncommitted;this.uncommitted=new Set;for(let t of e)t.committed=!0,t.action()}clearProgress({delta:e=0,clear:t=!1}){this.progressStyle!==null&&this.progress.size+e>0&&(this.stdout.write(`[${this.progress.size+e}A`),(e>0||t)&&this.stdout.write(""))}writeProgress(){if(this.progressStyle===null||(this.progressTimeout!==null&&clearTimeout(this.progressTimeout),this.progressTimeout=null,this.progress.size===0))return;let e=Date.now();e-this.progressTime>N9&&(this.progressFrame=(this.progressFrame+1)%F9.length,this.progressTime=e);let t=F9[this.progressFrame];for(let i of this.progress.values()){let n="";if(typeof i.lastScaledSize!="undefined"){let l=this.progressStyle.chars[0].repeat(i.lastScaledSize),c=this.progressStyle.chars[1].repeat(this.progressMaxScaledSize-i.lastScaledSize);n=` ${l}${c}`}let s=this.formatName(null),o=s?`${s}: `:"",a=i.definition.title?` ${i.definition.title}`:"";this.stdout.write(`${tt(this.configuration,"\u27A4","blueBright")} ${o}${t}${n}${a} -`)}this.progressTimeout=setTimeout(()=>{this.refreshProgress({force:!0})},N9)}refreshProgress({delta:e=0,force:t=!1}={}){let i=!1,n=!1;if(t||this.progress.size===0)i=!0;else for(let s of this.progress.values()){let o=typeof s.definition.progress!="undefined"?Math.trunc(this.progressMaxScaledSize*s.definition.progress):void 0,a=s.lastScaledSize;s.lastScaledSize=o;let l=s.lastTitle;if(s.lastTitle=s.definition.title,o!==a||(n=l!==s.definition.title)){i=!0;break}}i&&(this.clearProgress({delta:e,clear:n}),this.writeProgress())}truncate(e,{truncate:t}={}){return this.progressStyle===null&&(t=!1),typeof t=="undefined"&&(t=this.configuration.get("preferTruncatedLines")),t&&(e=(0,R9.default)(e,0,this.stdout.columns-1)),e}formatName(e){return T9(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 Ur="3.2.2";var hn;(function(n){n.Yarn1="Yarn Classic",n.Yarn2="Yarn",n.Npm="npm",n.Pnpm="pnpm"})(hn||(hn={}));async function AA(r,e,t,i=[]){if(process.platform==="win32"){let n=`@goto #_undefined_# 2>NUL || @title %COMSPEC% & @setlocal & @"${t}" ${i.map(s=>`"${s.replace('"','""')}"`).join(" ")} %*`;await K.writeFilePromise(k.format({dir:r,name:e,ext:".cmd"}),n)}await K.writeFilePromise(k.join(r,e),`#!/bin/sh -exec "${t}" ${i.map(n=>`'${n.replace(/'/g,`'"'"'`)}'`).join(" ")} "$@" -`,{mode:493})}async function K9(r){let e=await At.tryFind(r);if(e==null?void 0:e.packageManager){let i=lw(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?hn.Yarn1:hn.Yarn2,reason:n};case"npm":return{packageManager:hn.Npm,reason:n};case"pnpm":return{packageManager:hn.Pnpm,reason:n}}}}let t;try{t=await K.readFilePromise(k.join(r,kt.lockfile),"utf8")}catch{}return t!==void 0?t.match(/^__metadata:$/m)?{packageManager:hn.Yarn2,reason:'"__metadata" key found in yarn.lock'}:{packageManager:hn.Yarn1,reason:'"__metadata" key not found in yarn.lock, must be a Yarn classic lockfile'}:K.existsSync(k.join(r,"package-lock.json"))?{packageManager:hn.Npm,reason:`found npm's "package-lock.json" lockfile`}:K.existsSync(k.join(r,"pnpm-lock.yaml"))?{packageManager:hn.Pnpm,reason:`found pnpm's "pnpm-lock.yaml" lockfile`}:null}async function Yd({project:r,locator:e,binFolder:t,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=H.fromPortablePath(t);n.BERRY_BIN_FOLDER=H.fromPortablePath(s);let o=process.env.COREPACK_ROOT?H.join(process.env.COREPACK_ROOT,"dist/yarn.js"):process.argv[1];if(await Promise.all([AA(t,"node",process.execPath),...Ur!==null?[AA(t,"run",process.execPath,[o,"run"]),AA(t,"yarn",process.execPath,[o]),AA(t,"yarnpkg",process.execPath,[o]),AA(t,"node-gyp",process.execPath,[o,"run","--top-level","node-gyp"])]:[]]),r&&(n.INIT_CWD=H.fromPortablePath(r.configuration.startingCwd),n.PROJECT_CWD=H.fromPortablePath(r.cwd)),n.PATH=n.PATH?`${s}${H.delimiter}${n.PATH}`:`${s}`,n.npm_execpath=`${s}${H.sep}yarn`,n.npm_node_execpath=`${s}${H.sep}node`,e){if(!r)throw new Error("Assertion failed: Missing project");let u=r.tryWorkspaceByLocator(e),g=u?(l=u.manifest.version)!=null?l:"":(c=r.storedPackages.get(e.locatorHash).version)!=null?c:"";n.npm_package_name=Ot(e),n.npm_package_version=g;let f;if(u)f=u.cwd;else{let h=r.storedPackages.get(e.locatorHash);if(!h)throw new Error(`Package for ${It(r.configuration,e)} not found in the project`);let p=r.configuration.getLinkers(),m={project:r,report:new Je({stdout:new El.PassThrough,configuration:r.configuration})},y=p.find(b=>b.supportsPackage(h,m));if(!y)throw new Error(`The package ${It(r.configuration,h)} isn't supported by any of the available linkers`);f=await y.findPackageLocation(h,m)}n.npm_package_json=H.fromPortablePath(k.join(f,kt.manifest))}let a=Ur!==null?`yarn/${Ur}`:`yarn/${Og("@yarnpkg/core").version}-core`;return n.npm_config_user_agent=`${a} npm/? node/${process.version} ${process.platform} ${process.arch}`,i&&(n.npm_lifecycle_event=i),r&&await r.configuration.triggerHook(u=>u.setupScriptEnvironment,r,n,async(u,g,f)=>await AA(t,Jr(u),g,f)),n}var HDe=2,jDe=(0,M9.default)(HDe);async function GDe(r,e,{configuration:t,report:i,workspace:n=null,locator:s=null}){await jDe(async()=>{await K.mktempPromise(async o=>{let a=k.join(o,"pack.log"),l=null,{stdout:c,stderr:u}=t.getSubprocessStreams(a,{prefix:H.fromPortablePath(r),report:i}),g=s&&ea(s)?gd(s):s,f=g?Rs(g):"an external project";c.write(`Packing ${f} from sources -`);let h=await K9(r),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=hn.Yarn2),await K.mktempPromise(async m=>{let y=await Yd({binFolder:m}),v=new Map([[hn.Yarn1,async()=>{let T=n!==null?["workspace",n]:[],q=await ra("yarn",["set","version","classic","--only-if-needed"],{cwd:r,env:y,stdin:l,stdout:c,stderr:u,end:ss.ErrorCode});if(q.code!==0)return q.code;await K.appendFilePromise(k.join(r,".npmignore"),`/.yarn -`),c.write(` -`),delete y.NODE_ENV;let Y=await ra("yarn",["install"],{cwd:r,env:y,stdin:l,stdout:c,stderr:u,end:ss.ErrorCode});if(Y.code!==0)return Y.code;c.write(` -`);let $=await ra("yarn",[...T,"pack","--filename",H.fromPortablePath(e)],{cwd:r,env:y,stdin:l,stdout:c,stderr:u});return $.code!==0?$.code:0}],[hn.Yarn2,async()=>{let T=n!==null?["workspace",n]:[];y.YARN_ENABLE_INLINE_BUILDS="1";let q=k.join(r,kt.lockfile);await K.existsPromise(q)||await K.writeFilePromise(q,"");let Y=await ra("yarn",[...T,"pack","--install-if-needed","--filename",H.fromPortablePath(e)],{cwd:r,env:y,stdin:l,stdout:c,stderr:u});return Y.code!==0?Y.code:0}],[hn.Npm,async()=>{if(n!==null){let A=new El.PassThrough,oe=Tg(A);A.pipe(c,{end:!1});let ce=await ra("npm",["--version"],{cwd:r,env:y,stdin:l,stdout:A,stderr:u,end:ss.Never});if(A.end(),ce.code!==0)return c.end(),u.end(),ce.code;let Z=(await oe).toString().trim();if(!qc(Z,">=7.x")){let O=$o(null,"npm"),L=rr(O,Z),de=rr(O,">=7.x");throw new Error(`Workspaces aren't supported by ${sr(t,L)}; please upgrade to ${sr(t,de)} (npm has been detected as the primary package manager for ${tt(t,r,qe.PATH)})`)}}let T=n!==null?["--workspace",n]:[];delete y.npm_config_user_agent,delete y.npm_config_production,delete y.NPM_CONFIG_PRODUCTION,delete y.NODE_ENV;let q=await ra("npm",["install"],{cwd:r,env:y,stdin:l,stdout:c,stderr:u,end:ss.ErrorCode});if(q.code!==0)return q.code;let Y=new El.PassThrough,$=Tg(Y);Y.pipe(c);let _=await ra("npm",["pack","--silent",...T],{cwd:r,env:y,stdin:l,stdout:Y,stderr:u});if(_.code!==0)return _.code;let ne=(await $).toString().trim().replace(/^.*\n/s,""),ee=k.resolve(r,H.toPortablePath(ne));return await K.renamePromise(ee,e),0}]]).get(p);if(typeof v=="undefined")throw new Error("Assertion failed: Unsupported workflow");let x=await v();if(!(x===0||typeof x=="undefined"))throw K.detachTemp(o),new ct(X.PACKAGE_PREPARATION_FAILED,`Packing the package failed (exit code ${x}, logs can be found here: ${tt(t,a,qe.PATH)})`)})})})}async function YDe(r,e,{project:t}){let i=t.tryWorkspaceByLocator(r);if(i!==null)return tD(i,e);let n=t.storedPackages.get(r.locatorHash);if(!n)throw new Error(`Package for ${It(t.configuration,r)} not found in the project`);return await Is.openPromise(async s=>{let o=t.configuration,a=t.configuration.getLinkers(),l={project:t,report:new Je({stdout:new El.PassThrough,configuration:o})},c=a.find(h=>h.supportsPackage(n,l));if(!c)throw new Error(`The package ${It(t.configuration,n)} isn't supported by any of the available linkers`);let u=await c.findPackageLocation(n,l),g=new _t(u,{baseFs:s});return(await At.find(Me.dot,{baseFs:g})).scripts.has(e)},{libzip:await fn()})}async function nB(r,e,t,{cwd:i,project:n,stdin:s,stdout:o,stderr:a}){return await K.mktempPromise(async l=>{let{manifest:c,env:u,cwd:g}=await U9(r,{project:n,binFolder:l,cwd:i,lifecycleScript:e}),f=c.scripts.get(e);if(typeof f=="undefined")return 1;let h=async()=>await Xw(f,t,{cwd:g,env:u,stdin:s,stdout:o,stderr:a});return await(await n.configuration.reduceHook(m=>m.wrapScriptExecution,h,n,r,e,{script:f,args:t,cwd:g,env:u,stdin:s,stdout:o,stderr:a}))()})}async function rD(r,e,t,{cwd:i,project:n,stdin:s,stdout:o,stderr:a}){return await K.mktempPromise(async l=>{let{env:c,cwd:u}=await U9(r,{project:n,binFolder:l,cwd:i});return await Xw(e,t,{cwd:u,env:c,stdin:s,stdout:o,stderr:a})})}async function qDe(r,{binFolder:e,cwd:t,lifecycleScript:i}){let n=await Yd({project:r.project,locator:r.anchoredLocator,binFolder:e,lifecycleScript:i});return await Promise.all(Array.from(await H9(r),([s,[,o]])=>AA(e,Jr(s),process.execPath,[o]))),typeof t=="undefined"&&(t=k.dirname(await K.realpathPromise(k.join(r.cwd,"package.json")))),{manifest:r.manifest,binFolder:e,env:n,cwd:t}}async function U9(r,{project:e,binFolder:t,cwd:i,lifecycleScript:n}){let s=e.tryWorkspaceByLocator(r);if(s!==null)return qDe(s,{binFolder:t,cwd:i,lifecycleScript:n});let o=e.storedPackages.get(r.locatorHash);if(!o)throw new Error(`Package for ${It(e.configuration,r)} not found in the project`);return await Is.openPromise(async a=>{let l=e.configuration,c=e.configuration.getLinkers(),u={project:e,report:new Je({stdout:new El.PassThrough,configuration:l})},g=c.find(y=>y.supportsPackage(o,u));if(!g)throw new Error(`The package ${It(e.configuration,o)} isn't supported by any of the available linkers`);let f=await Yd({project:e,locator:r,binFolder:t,lifecycleScript:n});await Promise.all(Array.from(await sB(r,{project:e}),([y,[,b]])=>AA(t,Jr(y),process.execPath,[b])));let h=await g.findPackageLocation(o,u),p=new _t(h,{baseFs:a}),m=await At.find(Me.dot,{baseFs:p});return typeof i=="undefined"&&(i=h),{manifest:m,binFolder:t,env:f,cwd:i}},{libzip:await fn()})}async function j9(r,e,t,{cwd:i,stdin:n,stdout:s,stderr:o}){return await nB(r.anchoredLocator,e,t,{cwd:i,project:r.project,stdin:n,stdout:s,stderr:o})}function tD(r,e){return r.manifest.scripts.has(e)}async function G9(r,e,{cwd:t,report:i}){let{configuration:n}=r.project,s=null;await K.mktempPromise(async o=>{let a=k.join(o,`${e}.log`),l=`# This file contains the result of Yarn calling the "${e}" lifecycle script inside a workspace ("${H.fromPortablePath(r.cwd)}") -`,{stdout:c,stderr:u}=n.getSubprocessStreams(a,{report:i,prefix:It(n,r.anchoredLocator),header:l});i.reportInfo(X.LIFECYCLE_SCRIPT,`Calling the "${e}" lifecycle script`);let g=await j9(r,e,[],{cwd:t,stdin:s,stdout:c,stderr:u});if(c.end(),u.end(),g!==0)throw K.detachTemp(o),new ct(X.LIFECYCLE_SCRIPT,`${(0,O9.default)(e)} script failed (exit code ${tt(n,g,qe.NUMBER)}, logs can be found here: ${tt(n,a,qe.PATH)}); run ${tt(n,`yarn ${e}`,qe.CODE)} to investigate`)})}async function JDe(r,e,t){tD(r,e)&&await G9(r,e,t)}async function sB(r,{project:e}){let t=e.configuration,i=new Map,n=e.storedPackages.get(r.locatorHash);if(!n)throw new Error(`Package for ${It(t,r)} not found in the project`);let s=new El.Writable,o=t.getLinkers(),a={project:e,report:new Je({configuration:t,stdout:s})},l=new Set([r.locatorHash]);for(let u of n.dependencies.values()){let g=e.storedResolutions.get(u.descriptorHash);if(!g)throw new Error(`Assertion failed: The resolution (${sr(t,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 zo.skip;let f=o.find(p=>p.supportsPackage(g,a));if(!f)return zo.skip;let h=null;try{h=await f.findPackageLocation(g,a)}catch(p){if(p.code==="LOCATOR_NOT_INSTALLED")return zo.skip;throw p}return{dependency:g,packageLocation:h}}));for(let u of c){if(u===zo.skip)continue;let{dependency:g,packageLocation:f}=u;for(let[h,p]of g.bin)i.set(h,[g,H.fromPortablePath(k.resolve(f,p))])}return i}async function H9(r){return await sB(r.anchoredLocator,{project:r.project})}async function Y9(r,e,t,{cwd:i,project:n,stdin:s,stdout:o,stderr:a,nodeArgs:l=[],packageAccessibleBinaries:c}){c!=null||(c=await sB(r,{project:n}));let u=c.get(e);if(!u)throw new Error(`Binary not found (${e}) for ${It(n.configuration,r)}`);return await K.mktempPromise(async g=>{let[,f]=u,h=await Yd({project:n,locator:r,binFolder:g});await Promise.all(Array.from(c,([m,[,y]])=>AA(h.BERRY_BIN_FOLDER,Jr(m),process.execPath,[y])));let p;try{p=await ra(process.execPath,[...l,f,...t],{cwd:i,env:h,stdin:s,stdout:o,stderr:a})}finally{await K.removePromise(h.BERRY_BIN_FOLDER)}return p.code})}async function WDe(r,e,t,{cwd:i,stdin:n,stdout:s,stderr:o,packageAccessibleBinaries:a}){return await Y9(r.anchoredLocator,e,t,{project:r.project,cwd:i,stdin:n,stdout:s,stderr:o,packageAccessibleBinaries:a})}var Bi={};ft(Bi,{convertToZip:()=>iNe,extractArchiveTo:()=>sNe,makeArchiveFromDirectory:()=>rNe});var T6=ge(require("stream")),O6=ge(P6());var D6=ge(require("os")),R6=ge(gg()),F6=ge(require("worker_threads")),Dl=Symbol("kTaskInfo"),pR=class{constructor(e){this.source=e;this.workers=[];this.limit=(0,R6.default)(Math.max(1,(0,D6.cpus)().length));this.cleanupInterval=setInterval(()=>{if(this.limit.pendingCount===0&&this.limit.activeCount===0){let t=this.workers.pop();t?t.terminate():clearInterval(this.cleanupInterval)}},5e3).unref()}createWorker(){this.cleanupInterval.refresh();let e=new F6.Worker(this.source,{eval:!0,execArgv:[...process.execArgv,"--unhandled-rejections=strict"]});return e.on("message",t=>{if(!e[Dl])throw new Error("Assertion failed: Worker sent a result without having a task assigned");e[Dl].resolve(t),e[Dl]=null,e.unref(),this.workers.push(e)}),e.on("error",t=>{var i;(i=e[Dl])==null||i.reject(t),e[Dl]=null}),e.on("exit",t=>{var i;t!==0&&((i=e[Dl])==null||i.reject(new Error(`Worker exited with code ${t}`))),e[Dl]=null}),e}run(e){return this.limit(()=>{var i;let t=(i=this.workers.pop())!=null?i:this.createWorker();return t.ref(),new Promise((n,s)=>{t[Dl]={resolve:n,reject:s},t.postMessage(e)})})}};var M6=ge(L6());async function rNe(r,{baseFs:e=new ar,prefixPath:t=Me.root,compressionLevel:i,inMemory:n=!1}={}){let s=await fn(),o;if(n)o=new li(null,{libzip:s,level:i});else{let l=await K.mktempPromise(),c=k.join(l,"archive.zip");o=new li(c,{create:!0,libzip:s,level:i})}let a=k.resolve(Me.root,t);return await o.copyPromise(a,r,{baseFs:e,stableTime:!0,stableSort:!0}),o}var K6;async function iNe(r,e){let t=await K.mktempPromise(),i=k.join(t,"archive.zip");return K6||(K6=new pR((0,M6.getContent)())),await K6.run({tmpFile:i,tgz:r,opts:e}),new li(i,{libzip:await fn(),level:e.compressionLevel})}async function*nNe(r){let e=new O6.default.Parse,t=new T6.PassThrough({objectMode:!0,autoDestroy:!0,emitClose:!0});e.on("entry",i=>{t.write(i)}),e.on("error",i=>{t.destroy(i)}),e.on("close",()=>{t.destroyed||t.end()}),e.end(r);for await(let i of t){let n=i;yield n,n.resume()}}async function sNe(r,e,{stripComponents:t=0,prefixPath:i=Me.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<=t)}for await(let a of nNe(r)){if(n(a))continue;let l=k.normalize(H.toPortablePath(a.path)).replace(/\/$/,"").split(/\//g);if(l.length<=t)continue;let c=l.slice(t).join("/"),u=k.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(k.dirname(u),{chmod:493,utimes:[Rr.SAFE_TIME,Rr.SAFE_TIME]}),e.mkdirSync(u,{mode:g}),e.utimesSync(u,Rr.SAFE_TIME,Rr.SAFE_TIME);break;case"OldFile":case"File":e.mkdirpSync(k.dirname(u),{chmod:493,utimes:[Rr.SAFE_TIME,Rr.SAFE_TIME]}),e.writeFileSync(u,await Tg(a),{mode:g}),e.utimesSync(u,Rr.SAFE_TIME,Rr.SAFE_TIME);break;case"SymbolicLink":e.mkdirpSync(k.dirname(u),{chmod:493,utimes:[Rr.SAFE_TIME,Rr.SAFE_TIME]}),e.symlinkSync(a.linkpath,u),(o=e.lutimesSync)==null||o.call(e,u,Rr.SAFE_TIME,Rr.SAFE_TIME);break}}return e}var ls={};ft(ls,{emitList:()=>oNe,emitTree:()=>q6,treeNodeToJson:()=>Y6,treeNodeToTreeify:()=>G6});var j6=ge(H6());function G6(r,{configuration:e}){let t={},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(Ry(e,l,Tc.BOLD)),typeof c!="undefined"&&g.push(tt(e,c[0],c[1])),g.length===0&&g.push(Ry(e,`${a}`,Tc.BOLD));let f=g.join(": "),h=s[f]={};typeof u!="undefined"&&i(u,h)}};if(typeof r.children=="undefined")throw new Error("The root node must only contain children");return i(r.children,t),t}function Y6(r){let e=t=>{var s;if(typeof t.children=="undefined"){if(typeof t.value=="undefined")throw new Error("Assertion failed: Expected a value to be set if the children are missing");return Oc(t.value[0],t.value[1])}let i=Array.isArray(t.children)?t.children.entries():Object.entries((s=t.children)!=null?s:{}),n=Array.isArray(t.children)?[]:{};for(let[o,a]of i)n[o]=e(a);return typeof t.value=="undefined"?n:{value:Oc(t.value[0],t.value[1]),children:n}};return e(r)}function oNe(r,{configuration:e,stdout:t,json:i}){let n=r.map(s=>({value:s}));q6({children:n},{configuration:e,stdout:t,json:i})}function q6(r,{configuration:e,stdout:t,json:i,separators:n=0}){var o;if(i){let a=Array.isArray(r.children)?r.children.values():Object.values((o=r.children)!=null?o:{});for(let l of a)t.write(`${JSON.stringify(Y6(l))} -`);return}let s=(0,j6.asTree)(G6(r,{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");t.write(s)}var J6=ge(require("crypto")),mR=ge(require("fs"));var aNe=8,Nt=class{constructor(e,{configuration:t,immutable:i=t.get("enableImmutableCache"),check:n=!1}){this.markedFiles=new Set;this.mutexes=new Map;this.cacheId=`-${(0,J6.randomBytes)(8).toString("hex")}.tmp`;this.configuration=t,this.cwd=e,this.immutable=i,this.check=n;let s=t.get("cacheKeyOverride");if(s!==null)this.cacheKey=`${s}`;else{let o=t.get("compressionLevel"),a=o!==lc?`c${o}`:"";this.cacheKey=[aNe,a].join("")}}static async find(e,{immutable:t,check:i}={}){let n=new Nt(e.get("cacheFolder"),{configuration:e,immutable:t,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`${Jg(e)}-${this.cacheKey}.zip`}getChecksumFilename(e,t){let n=ANe(t).slice(0,10);return`${Jg(e)}-${n}.zip`}getLocatorPath(e,t,i={}){var s;return this.mirrorCwd===null||((s=i.unstablePackages)==null?void 0:s.has(e.locatorHash))?k.resolve(this.cwd,this.getVersionFilename(e)):t===null||ER(t)!==this.cacheKey?null:k.resolve(this.cwd,this.getChecksumFilename(e,t))}getLocatorMirrorPath(e){let t=this.mirrorCwd;return t!==null?k.resolve(t,this.getVersionFilename(e)):null}async setup(){if(!this.configuration.get("enableGlobalCache"))if(this.immutable){if(!await K.existsPromise(this.cwd))throw new ct(X.IMMUTABLE_CACHE,"Cache path does not exist.")}else{await K.mkdirPromise(this.cwd,{recursive:!0});let e=k.resolve(this.cwd,".gitignore");await K.changeFilePromise(e,`/.gitignore -*.flock -*.tmp -`)}(this.mirrorCwd||!this.immutable)&&await K.mkdirPromise(this.mirrorCwd||this.cwd,{recursive:!0})}async fetchPackageFromCache(e,t,a){var l=a,{onHit:i,onMiss:n,loader:s}=l,o=Or(l,["onHit","onMiss","loader"]);var A;let c=this.getLocatorMirrorPath(e),u=new ar,g=()=>{let oe=new li(null,{libzip:q}),ce=k.join(Me.root,ek(e));return oe.mkdirSync(ce,{recursive:!0}),oe.writeJsonSync(k.join(ce,kt.manifest),{name:Ot(e),mocked:!0}),oe},f=async(oe,ce=null)=>{var O;if(ce===null&&((O=o.unstablePackages)==null?void 0:O.has(e.locatorHash)))return null;let Z=!o.skipIntegrityCheck||!t?`${this.cacheKey}/${await sw(oe)}`:t;if(ce!==null){let L=!o.skipIntegrityCheck||!t?`${this.cacheKey}/${await sw(ce)}`:t;if(Z!==L)throw new ct(X.CACHE_CHECKSUM_MISMATCH,"The remote archive doesn't match the local checksum - has the local cache been corrupted?")}if(t!==null&&Z!==t){let L;switch(this.check?L="throw":ER(t)!==ER(Z)?L="update":L=this.configuration.get("checksumBehavior"),L){case"ignore":return t;case"update":return Z;default:case"throw":throw new ct(X.CACHE_CHECKSUM_MISMATCH,"The remote archive doesn't match the expected checksum")}}return Z},h=async oe=>{if(!s)throw new Error(`Cache check required but no loader configured for ${It(this.configuration,e)}`);let ce=await s(),Z=ce.getRealPath();return ce.saveAndClose(),await K.chmodPromise(Z,420),await f(oe,Z)},p=async()=>{if(c===null||!await K.existsPromise(c)){let oe=await s(),ce=oe.getRealPath();return oe.saveAndClose(),{source:"loader",path:ce}}return{source:"mirror",path:c}},m=async()=>{if(!s)throw new Error(`Cache entry required but missing for ${It(this.configuration,e)}`);if(this.immutable)throw new ct(X.IMMUTABLE_CACHE,`Cache entry required but missing for ${It(this.configuration,e)}`);let{path:oe,source:ce}=await p(),Z=await f(oe),O=this.getLocatorPath(e,Z,o);if(!O)throw new Error("Assertion failed: Expected the cache path to be available");let L=[];ce!=="mirror"&&c!==null&&L.push(async()=>{let Be=`${c}${this.cacheId}`;await K.copyFilePromise(oe,Be,mR.default.constants.COPYFILE_FICLONE),await K.chmodPromise(Be,420),await K.renamePromise(Be,c)}),(!o.mirrorWriteOnly||c===null)&&L.push(async()=>{let Be=`${O}${this.cacheId}`;await K.copyFilePromise(oe,Be,mR.default.constants.COPYFILE_FICLONE),await K.chmodPromise(Be,420),await K.renamePromise(Be,O)});let de=o.mirrorWriteOnly&&c!=null?c:O;return await Promise.all(L.map(Be=>Be())),[!1,de,Z]},y=async()=>{let ce=(async()=>{var je;let Z=this.getLocatorPath(e,t,o),O=Z!==null?await u.existsPromise(Z):!1,L=!!((je=o.mockedPackages)==null?void 0:je.has(e.locatorHash))&&(!this.check||!O),de=L||O,Be=de?i:n;if(Be&&Be(),de){let re=null,se=Z;return L||(re=this.check?await h(se):await f(se)),[L,se,re]}else return m()})();this.mutexes.set(e.locatorHash,ce);try{return await ce}finally{this.mutexes.delete(e.locatorHash)}};for(let oe;oe=this.mutexes.get(e.locatorHash);)await oe;let[b,v,x]=await y();this.markedFiles.add(v);let T,q=await fn(),Y=b?()=>g():()=>new li(v,{baseFs:u,libzip:q,readOnly:!0}),$=new _h(()=>Rv(()=>T=Y(),oe=>`Failed to open the cache entry for ${It(this.configuration,e)}: ${oe}`),k),_=new Na(v,{baseFs:$,pathUtils:k}),ne=()=>{T==null||T.discardAndClose()},ee=((A=o.unstablePackages)==null?void 0:A.has(e.locatorHash))?null:x;return[_,ne,ee]}};function ER(r){let e=r.indexOf("/");return e!==-1?r.slice(0,e):null}function ANe(r){let e=r.indexOf("/");return e!==-1?r.slice(e+1):r}var cs;(function(t){t[t.SCRIPT=0]="SCRIPT",t[t.SHELLCODE=1]="SHELLCODE"})(cs||(cs={}));var pA=class extends Ji{constructor({configuration:e,stdout:t,suggestInstall:i=!0}){super();this.errorCount=0;nd(this,{configuration:e}),this.configuration=e,this.stdout=t,this.suggestInstall=i}static async start(e,t){let i=new this(e);try{await t(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){}startSectionSync(e,t){return t()}async startSectionPromise(e,t){return await t()}startTimerSync(e,t,i){return(typeof t=="function"?t:i)()}async startTimerPromise(e,t,i){return await(typeof t=="function"?t:i)()}async startCacheReport(e){return await e()}reportSeparator(){}reportInfo(e,t){}reportWarning(e,t){}reportError(e,t){this.errorCount+=1,this.stdout.write(`${tt(this.configuration,"\u27A4","redBright")} ${this.formatNameWithHyperlink(e)}: ${t} -`)}reportProgress(e){let t=Promise.resolve().then(async()=>{for await(let{}of e);}),i=()=>{};return te(N({},t),{stop:i})}reportJson(e){}async finalize(){this.errorCount>0&&(this.stdout.write(` -`),this.stdout.write(`${tt(this.configuration,"\u27A4","redBright")} Errors happened when preparing the environment required to run this command. -`),this.suggestInstall&&this.stdout.write(`${tt(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 i0=ge(require("crypto"));function dA(){}dA.prototype={diff:function(e,t){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(m){return n?(setTimeout(function(){n(void 0,m)},0),!0):m}e=this.castInput(e),t=this.castInput(t),e=this.removeEmpty(this.tokenize(e)),t=this.removeEmpty(this.tokenize(t));var a=t.length,l=e.length,c=1,u=a+l;i.maxEditLength&&(u=Math.min(u,i.maxEditLength));var g=[{newPos:-1,components:[]}],f=this.extractCommon(g[0],t,e,0);if(g[0].newPos+1>=a&&f+1>=l)return o([{value:this.join(t),count:t.length}]);function h(){for(var m=-1*c;m<=c;m+=2){var y=void 0,b=g[m-1],v=g[m+1],x=(v?v.newPos:0)-m;b&&(g[m-1]=void 0);var T=b&&b.newPos+1=a&&x+1>=l)return o(lNe(s,y.components,t,e,s.useLongestToken));g[m]=y}c++}if(n)(function m(){setTimeout(function(){if(c>u)return n();h()||m()},0)})();else for(;c<=u;){var p=h();if(p)return p}},pushComponent:function(e,t,i){var n=e[e.length-1];n&&n.added===t&&n.removed===i?e[e.length-1]={count:n.count+1,added:t,removed:i}:e.push({count:1,added:t,removed:i})},extractCommon:function(e,t,i,n){for(var s=t.length,o=i.length,a=e.newPos,l=a-n,c=0;a+1h.length?m:h}),c.value=r.join(u)}else c.value=r.join(t.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)&&r.equals("",f.value)&&(e[o-2].value+=f.value,e.pop()),e}function cNe(r){return{newPos:r.newPos,components:r.components.slice(0)}}var nAt=new dA;var W6=/^[A-Za-z\xC0-\u02C6\u02C8-\u02D7\u02DE-\u02FF\u1E00-\u1EFF]+$/,z6=/\S/,_6=new dA;_6.equals=function(r,e){return this.options.ignoreCase&&(r=r.toLowerCase(),e=e.toLowerCase()),r===e||this.options.ignoreWhitespace&&!z6.test(r)&&!z6.test(e)};_6.tokenize=function(r){for(var e=r.split(/([^\S\r\n]+|[()[\]{}'"\r\n]|\b)/),t=0;tr.length)&&(e=r.length);for(var t=0,i=new Array(e);t0?l(Y.lines.slice(-o.context)):[],u-=f.length,g-=f.length)}(q=f).push.apply(q,yR(T.map(function(Z){return(x.added?"+":"-")+Z}))),x.added?p+=T.length:h+=T.length}else{if(u)if(T.length<=o.context*2&&v=a.length-2&&T.length<=o.context){var A=/\n$/.test(t),oe=/\n$/.test(i),ce=T.length==0&&f.length>ee.oldLines;!A&&ce&&t.length>0&&f.splice(ee.oldLines,0,"\\ No newline at end of file"),(!A&&!ce||!oe)&&f.push("\\ No newline at end of file")}c.push(ee),u=0,g=0,f=[]}h+=T.length,p+=T.length}},y=0;y`${t}#commit=${i}`],[/^https:\/\/((?:[^/]+?)@)?codeload\.github\.com\/([^/]+\/[^/]+)\/tar\.gz\/([0-9a-f]+)$/,(r,e,t="",i,n)=>`https://${t}github.com/${i}.git#commit=${n}`],[/^https:\/\/((?:[^/]+?)@)?github\.com\/([^/]+\/[^/]+?)(?:\.git)?#([0-9a-f]+)$/,(r,e,t="",i,n)=>`https://${t}github.com/${i}.git#commit=${n}`],[/^https?:\/\/[^/]+\/(?:[^/]+\/)*(?:@.+(?:\/|(?:%2f)))?([^/]+)\/(?:-|download)\/\1-[^/]+\.tgz(?:#|$)/,r=>`npm:${r}`],[/^https:\/\/npm\.pkg\.github\.com\/download\/(?:@[^/]+)\/(?:[^/]+)\/(?:[^/]+)\/(?:[0-9a-f]+)(?:#|$)/,r=>`npm:${r}`],[/^https:\/\/npm\.fontawesome\.com\/(?:@[^/]+)\/([^/]+)\/-\/([^/]+)\/\1-\2.tgz(?:#|$)/,r=>`npm:${r}`],[/^https?:\/\/(?:[^\\.]+)\.jfrog\.io\/.*\/(@[^/]+)\/([^/]+)\/-\/\1\/\2-(?:[.\d\w-]+)\.tgz(?:#|$)/,(r,e)=>cw({protocol:"npm:",source:null,selector:r,params:{__archiveUrl:e}})],[/^[^/]+\.tgz#[0-9a-f]+$/,r=>`npm:${r}`]],NR=class{constructor(e){this.resolver=e;this.resolutions=null}async setup(e,{report:t}){let i=k.join(e.cwd,e.configuration.get("lockfileFilename"));if(!K.existsSync(i))return;let n=await K.readFilePromise(i,"utf8"),s=Si(n);if(Object.prototype.hasOwnProperty.call(s,"__metadata"))return;let o=this.resolutions=new Map;for(let a of Object.keys(s)){let l=pd(a);if(!l){t.reportWarning(X.YARN_IMPORT_FAILED,`Failed to parse the string "${a}" into a proper descriptor`);continue}po(l.range)&&(l=rr(l,`npm:${l.range}`));let{version:c,resolved:u}=s[a];if(!u)continue;let g;for(let[h,p]of JOe){let m=u.match(h);if(m){g=p(c,...m);break}}if(!g){t.reportWarning(X.YARN_IMPORT_FAILED,`${sr(e.configuration,l)}: Only some patterns can be imported from legacy lockfiles (not "${u}")`);continue}let f=l;try{let h=qg(l.range),p=pd(h.selector,!0);p&&(f=p)}catch{}o.set(l.descriptorHash,cn(f,g))}}supportsDescriptor(e,t){return this.resolutions?this.resolutions.has(e.descriptorHash):!1}supportsLocator(e,t){return!1}shouldPersistResolution(e,t){throw new Error("Assertion failed: This resolver doesn't support resolving locators to packages")}bindDescriptor(e,t,i){return e}getResolutionDependencies(e,t){return[]}async getCandidates(e,t,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 await this.resolver.getCandidates(_x(n),t,i)}async getSatisfying(e,t,i){return null}async resolve(e,t){throw new Error("Assertion failed: This resolver doesn't support resolving locators to packages")}};var LR=class{constructor(e){this.resolver=e}supportsDescriptor(e,t){return!!(t.project.storedResolutions.get(e.descriptorHash)||t.project.originalPackages.has(Aw(e).locatorHash))}supportsLocator(e,t){return!!(t.project.originalPackages.has(e.locatorHash)&&!t.project.lockfileNeedsRefresh)}shouldPersistResolution(e,t){throw new Error("The shouldPersistResolution method shouldn't be called on the lockfile resolver, which would always answer yes")}bindDescriptor(e,t,i){return e}getResolutionDependencies(e,t){return this.resolver.getResolutionDependencies(e,t)}async getCandidates(e,t,i){let n=i.project.originalPackages.get(Aw(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,t,i){return null}async resolve(e,t){let i=t.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 TR=class{constructor(e){this.resolver=e}supportsDescriptor(e,t){return this.resolver.supportsDescriptor(e,t)}supportsLocator(e,t){return this.resolver.supportsLocator(e,t)}shouldPersistResolution(e,t){return this.resolver.shouldPersistResolution(e,t)}bindDescriptor(e,t,i){return this.resolver.bindDescriptor(e,t,i)}getResolutionDependencies(e,t){return this.resolver.getResolutionDependencies(e,t)}async getCandidates(e,t,i){throw new ct(X.MISSING_LOCKFILE_ENTRY,`This package doesn't seem to be present in your lockfile; run "yarn install" to update the lockfile`)}async getSatisfying(e,t,i){throw new ct(X.MISSING_LOCKFILE_ENTRY,`This package doesn't seem to be present in your lockfile; run "yarn install" to update the lockfile`)}async resolve(e,t){throw new ct(X.MISSING_LOCKFILE_ENTRY,`This package doesn't seem to be present in your lockfile; run "yarn install" to update the lockfile`)}};var di=class extends Ji{reportCacheHit(e){}reportCacheMiss(e){}startSectionSync(e,t){return t()}async startSectionPromise(e,t){return await t()}startTimerSync(e,t,i){return(typeof t=="function"?t:i)()}async startTimerPromise(e,t,i){return await(typeof t=="function"?t:i)()}async startCacheReport(e){return await e()}reportSeparator(){}reportInfo(e,t){}reportWarning(e,t){}reportError(e,t){}reportProgress(e){let t=Promise.resolve().then(async()=>{for await(let{}of e);}),i=()=>{};return te(N({},t),{stop:i})}reportJson(e){}async finalize(){}};var iZ=ge(Wx());var CC=class{constructor(e,{project:t}){this.workspacesCwds=new Set;this.dependencies=new Map;this.project=t,this.cwd=e}async setup(){var s;this.manifest=(s=await At.tryFind(this.cwd))!=null?s:new At,this.relativeCwd=k.relative(this.project.cwd,this.cwd)||Me.dot;let e=this.manifest.name?this.manifest.name:$o(null,`${this.computeCandidateName()}-${ln(this.relativeCwd).substring(0,6)}`),t=this.manifest.version?this.manifest.version:"0.0.0";this.locator=cn(e,t),this.anchoredDescriptor=rr(this.locator,`${oi.protocol}${this.relativeCwd}`),this.anchoredLocator=cn(this.locator,`${oi.protocol}${this.relativeCwd}`);let i=this.manifest.workspaceDefinitions.map(({pattern:o})=>o),n=await(0,iZ.default)(i,{cwd:H.fromPortablePath(this.cwd),expandDirectories:!1,onlyDirectories:!0,onlyFiles:!1,ignore:["**/node_modules","**/.git","**/.yarn"]});n.sort();for(let o of n){let a=k.resolve(this.cwd,H.toPortablePath(o));K.existsSync(k.join(a,"package.json"))&&this.workspacesCwds.add(a)}}accepts(e){var o;let t=e.indexOf(":"),i=t!==-1?e.slice(0,t+1):null,n=t!==-1?e.slice(t+1):e;if(i===oi.protocol&&k.normalize(n)===this.relativeCwd||i===oi.protocol&&(n==="*"||n==="^"||n==="~"))return!0;let s=po(n);return s?i===oi.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":`${k.basename(this.cwd)}`||"unnamed-workspace"}getRecursiveWorkspaceDependencies({dependencies:e=At.hardDependencies}={}){let t=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||t.has(a)||(t.add(a),i(a))}};return i(this),t}getRecursiveWorkspaceDependents({dependencies:e=At.hardDependencies}={}){let t=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&&hd(c.anchoredLocator,n.anchoredLocator)}))&&!t.has(s)&&(t.add(s),i(s))};return i(this),t}getRecursiveWorkspaceChildren(){let e=[];for(let t of this.workspacesCwds){let i=this.project.workspacesByCwd.get(t);i&&e.push(i,...i.getRecursiveWorkspaceChildren())}return e}async persistManifest(){let e={};this.manifest.exportTo(e);let t=k.join(this.cwd,At.fileName),i=`${JSON.stringify(e,null,this.manifest.indent)} -`;await K.changeFilePromise(t,i,{automaticNewlines:!0}),this.manifest.raw=e}};var oZ=6,WOe=1,zOe=/ *, */g,aZ=/\/$/,_Oe=32,VOe=(0,OR.promisify)(KR.default.gzip),XOe=(0,OR.promisify)(KR.default.gunzip),Ci;(function(t){t.UpdateLockfile="update-lockfile",t.SkipBuild="skip-build"})(Ci||(Ci={}));var UR={restoreInstallersCustomData:["installersCustomData"],restoreResolutions:["accessibleLocators","conditionalLocators","disabledLocators","optionalBuilds","storedDescriptors","storedResolutions","storedPackages","lockFileChecksum"],restoreBuildState:["storedBuildState"]},AZ=r=>ln(`${WOe}`,r),ze=class{constructor(e,{configuration:t}){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=t,this.cwd=e}static async find(e,t){var p,m,y;if(!e.projectCwd)throw new Pe(`No project found in ${t}`);let i=e.projectCwd,n=t,s=null;for(;s!==e.projectCwd;){if(s=n,K.existsSync(k.join(s,kt.manifest))){i=s;break}n=k.dirname(s)}let o=new ze(e.projectCwd,{configuration:e});(p=ye.telemetry)==null||p.reportProject(o.cwd),await o.setupResolutions(),await o.setupWorkspaces(),(m=ye.telemetry)==null||m.reportWorkspaceCount(o.workspaces.length),(y=ye.telemetry)==null||y.reportDependencyCount(o.workspaces.reduce((b,v)=>b+v.manifest.dependencies.size+v.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};let c=tt(e,o.cwd,qe.PATH),u=tt(e,k.relative(o.cwd,i),qe.PATH),g=`- If ${c} isn't intended to be a project, remove any yarn.lock and/or package.json file there.`,f=`- If ${c} is intended to be a project, it might be that you forgot to list ${u} in its workspace configuration.`,h=`- Finally, if ${c} is fine and you intend ${u} to be treated as a completely separate project (not even a workspace), create an empty yarn.lock file in it.`;throw new Pe(`The nearest package directory (${tt(e,i,qe.PATH)}) doesn't seem to be part of the project declared in ${tt(e,o.cwd,qe.PATH)}. - -${[g,f,h].join(` -`)}`)}async setupResolutions(){var i;this.storedResolutions=new Map,this.storedDescriptors=new Map,this.storedPackages=new Map,this.lockFileChecksum=null;let e=k.join(this.cwd,this.configuration.get("lockfileFilename")),t=this.configuration.get("defaultLanguageName");if(K.existsSync(e)){let n=await K.readFilePromise(e,"utf8");this.lockFileChecksum=AZ(n);let s=Si(n);if(s.__metadata){let o=s.__metadata.version,a=s.__metadata.cacheKey;this.lockfileNeedsRefresh=o0;){let t=e;e=[];for(let i of t){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 t=new CC(e,{project:this});await t.setup();let i=this.workspacesByIdent.get(t.locator.identHash);if(typeof i!="undefined")throw new Error(`Duplicate workspace name ${fi(this.configuration,t.locator)}: ${H.fromPortablePath(e)} conflicts with ${H.fromPortablePath(i.cwd)}`);return this.workspaces.push(t),this.workspacesByCwd.set(e,t),this.workspacesByIdent.set(t.locator.identHash,t),t}get topLevelWorkspace(){return this.getWorkspaceByCwd(this.cwd)}tryWorkspaceByCwd(e){k.isAbsolute(e)||(e=k.resolve(this.cwd,e)),e=k.normalize(e).replace(/\/+$/,"");let t=this.workspacesByCwd.get(e);return t||null}getWorkspaceByCwd(e){let t=this.tryWorkspaceByCwd(e);if(!t)throw new Error(`Workspace not found (${e})`);return t}tryWorkspaceByFilePath(e){let t=null;for(let i of this.workspaces)k.relative(i.cwd,e).startsWith("../")||t&&t.cwd.length>=i.cwd.length||(t=i);return t||null}getWorkspaceByFilePath(e){let t=this.tryWorkspaceByFilePath(e);if(!t)throw new Error(`Workspace not found (${e})`);return t}tryWorkspaceByIdent(e){let t=this.workspacesByIdent.get(e.identHash);return typeof t=="undefined"?null:t}getWorkspaceByIdent(e){let t=this.tryWorkspaceByIdent(e);if(!t)throw new Error(`Workspace not found (${fi(this.configuration,e)})`);return t}tryWorkspaceByDescriptor(e){let t=this.tryWorkspaceByIdent(e);return t===null||(Al(e)&&(e=ud(e)),!t.accepts(e.range))?null:t}getWorkspaceByDescriptor(e){let t=this.tryWorkspaceByDescriptor(e);if(t===null)throw new Error(`Workspace not found (${sr(this.configuration,e)})`);return t}tryWorkspaceByLocator(e){let t=this.tryWorkspaceByIdent(e);return t===null||(ea(e)&&(e=gd(e)),t.locator.locatorHash!==e.locatorHash&&t.anchoredLocator.locatorHash!==e.locatorHash)?null:t}getWorkspaceByLocator(e){let t=this.tryWorkspaceByLocator(e);if(!t)throw new Error(`Workspace not found (${It(this.configuration,e)})`);return t}refreshWorkspaceDependencies(){for(let e of this.workspaces){let t=this.storedPackages.get(e.anchoredLocator.locatorHash);if(!t)throw new Error(`Assertion failed: Expected workspace ${Cd(this.configuration,e)} (${tt(this.configuration,k.join(e.cwd,kt.manifest),qe.PATH)}) to have been resolved. Run "yarn install" to update the lockfile`);e.dependencies=new Map(t.dependencies)}}forgetResolution(e){let t=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);t(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&&t(n)}}forgetTransientResolutions(){let e=this.configuration.makeResolver();for(let t of this.originalPackages.values()){let i;try{i=e.shouldPersistResolution(t,{project:this,resolver:e})}catch{i=!1}i||this.forgetResolution(t)}}forgetVirtualResolutions(){for(let e of this.storedPackages.values())for(let[t,i]of e.dependencies)Al(i)&&e.dependencies.set(t,ud(i))}getDependencyMeta(e,t){let i={},s=this.topLevelWorkspace.manifest.dependenciesMeta.get(Ot(e));if(!s)return i;let o=s.get(null);if(o&&Object.assign(i,o),t===null||!sZ.default.valid(t))return i;for(let[a,l]of s)a!==null&&a===t&&Object.assign(i,l);return i}async findLocatorForLocation(e,{strict:t=!1}={}){let i=new di,n=this.configuration.getLinkers(),s={project:this,report:i};for(let o of n){let a=await o.findPackageLocator(e,s);if(a){if(t&&(await o.findPackageLocation(a,s)).replace(aZ,"")!==e.replace(aZ,""))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 t=e.resolver||this.configuration.makeResolver(),i=new NR(t);await i.setup(this,{report:e.report});let n=e.lockfileOnly?[new TR(t)]:[i,t],s=new wd([new LR(t),...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,m=new Set,y=[],b=ck(),v=this.configuration.getSupportedArchitectures();await e.report.startProgressPromise(Ji.progressViaTitle(),async ne=>{let ee=async O=>{let L=await Lg(async()=>await s.resolve(O,a),je=>`${It(this.configuration,O)}: ${je}`);if(!hd(O,L))throw new Error(`Assertion failed: The locator cannot be changed by the resolver (went from ${It(this.configuration,O)} to ${It(this.configuration,L)})`);g.set(L.locatorHash,L);let de=this.configuration.normalizePackage(L);for(let[je,re]of de.dependencies){let se=await this.configuration.reduceHook(he=>he.reduceDependency,re,this,de,re,{resolver:s,resolveOptions:a});if(!fd(re,se))throw new Error("Assertion failed: The descriptor ident cannot be changed through aliases");let be=s.bindDescriptor(se,O,a);de.dependencies.set(je,be)}let Be=go([...de.dependencies.values()].map(je=>Z(je)));return y.push(Be),Be.catch(()=>{}),c.set(de.locatorHash,de),de},A=async O=>{let L=f.get(O.locatorHash);if(typeof L!="undefined")return L;let de=Promise.resolve().then(()=>ee(O));return f.set(O.locatorHash,de),de},oe=async(O,L)=>{let de=await Z(L);return l.set(O.descriptorHash,O),u.set(O.descriptorHash,de.locatorHash),de},ce=async O=>{ne.setTitle(sr(this.configuration,O));let L=this.resolutionAliases.get(O.descriptorHash);if(typeof L!="undefined")return oe(O,this.storedDescriptors.get(L));let de=s.getResolutionDependencies(O,a),Be=new Map(await go(de.map(async se=>{let be=s.bindDescriptor(se,p,a),he=await Z(be);return m.add(he.locatorHash),[se.descriptorHash,he]}))),re=(await Lg(async()=>await s.getCandidates(O,Be,a),se=>`${sr(this.configuration,O)}: ${se}`))[0];if(typeof re=="undefined")throw new Error(`${sr(this.configuration,O)}: No candidates found`);return l.set(O.descriptorHash,O),u.set(O.descriptorHash,re.locatorHash),A(re)},Z=O=>{let L=h.get(O.descriptorHash);if(typeof L!="undefined")return L;l.set(O.descriptorHash,O);let de=Promise.resolve().then(()=>ce(O));return h.set(O.descriptorHash,de),de};for(let O of this.workspaces){let L=O.anchoredDescriptor;y.push(Z(L))}for(;y.length>0;){let O=[...y];y.length=0,await go(O)}});let x=new Set(this.resolutionAliases.values()),T=new Set(c.keys()),q=new Set,Y=new Map;ZOe({project:this,report:e.report,accessibleLocators:q,volatileDescriptors:x,optionalBuilds:T,peerRequirements:Y,allDescriptors:l,allResolutions:u,allPackages:c});for(let ne of m)T.delete(ne);for(let ne of x)l.delete(ne),u.delete(ne);let $=new Set,_=new Set;for(let ne of c.values())ne.conditions!=null&&(!T.has(ne.locatorHash)||(gw(ne,v)||(gw(ne,b)&&e.report.reportWarningOnce(X.GHOST_ARCHITECTURE,`${It(this.configuration,ne)}: Your current architecture (${process.platform}-${process.arch}) is supported by this package, but is missing from the ${tt(this.configuration,"supportedArchitectures",Ri.SETTING)} setting`),_.add(ne.locatorHash)),$.add(ne.locatorHash)));this.storedResolutions=u,this.storedDescriptors=l,this.storedPackages=c,this.accessibleLocators=q,this.conditionalLocators=$,this.disabledLocators=_,this.originalPackages=g,this.optionalBuilds=T,this.peerRequirements=Y,this.refreshWorkspaceDependencies()}async fetchEverything({cache:e,report:t,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:t,cacheOptions:s},l=Array.from(new Set(kn(this.storedResolutions.values(),[f=>{let h=this.storedPackages.get(f);if(!h)throw new Error("Assertion failed: The locator should have been registered");return Rs(h)}])));n===Ci.UpdateLockfile&&(l=l.filter(f=>!this.storedChecksums.has(f)));let c=!1,u=Ji.progressViaCounter(l.length);t.reportProgress(u);let g=(0,nZ.default)(_Oe);if(await t.startCacheReport(async()=>{await go(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(ea(h))return;let p;try{p=await o.fetch(h,a)}catch(m){m.message=`${It(this.configuration,h)}: ${m.message}`,t.reportExceptionOnce(m),c=m;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:t,fetcher:i,mode:n}){var A,oe,ce;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:t,skipIntegrityCheck:!0,cacheOptions:s},l=this.configuration.getLinkers(),c={project:this,report:t},u=new Map(l.map(Z=>{let O=Z.makeInstaller(c),L=O.getCustomDataKey(),de=this.installersCustomData.get(L);return typeof de!="undefined"&&O.attachCustomData(de),[Z,O]})),g=new Map,f=new Map,h=new Map,p=new Map(await go([...this.accessibleLocators].map(async Z=>{let O=this.storedPackages.get(Z);if(!O)throw new Error("Assertion failed: The locator should have been registered");return[Z,await o.fetch(O,a)]}))),m=[];for(let Z of this.accessibleLocators){let O=this.storedPackages.get(Z);if(typeof O=="undefined")throw new Error("Assertion failed: The locator should have been registered");let L=p.get(O.locatorHash);if(typeof L=="undefined")throw new Error("Assertion failed: The fetch result should have been registered");let de=[],Be=re=>{de.push(re)},je=this.tryWorkspaceByLocator(O);if(je!==null){let re=[],{scripts:se}=je.manifest;for(let he of["preinstall","install","postinstall"])se.has(he)&&re.push([cs.SCRIPT,he]);try{for(let[he,Fe]of u)if(he.supportsPackage(O,c)&&(await Fe.installPackage(O,L,{holdFetchResult:Be})).buildDirective!==null)throw new Error("Assertion failed: Linkers can't return build directives for workspaces; this responsibility befalls to the Yarn core")}finally{de.length===0?(A=L.releaseFs)==null||A.call(L):m.push(go(de).catch(()=>{}).then(()=>{var he;(he=L.releaseFs)==null||he.call(L)}))}let be=k.join(L.packageFs.getRealPath(),L.prefixPath);f.set(O.locatorHash,be),!ea(O)&&re.length>0&&h.set(O.locatorHash,{directives:re,buildLocations:[be]})}else{let re=l.find(he=>he.supportsPackage(O,c));if(!re)throw new ct(X.LINKER_NOT_FOUND,`${It(this.configuration,O)} isn't supported by any available linker`);let se=u.get(re);if(!se)throw new Error("Assertion failed: The installer should have been registered");let be;try{be=await se.installPackage(O,L,{holdFetchResult:Be})}finally{de.length===0?(oe=L.releaseFs)==null||oe.call(L):m.push(go(de).then(()=>{}).then(()=>{var he;(he=L.releaseFs)==null||he.call(L)}))}g.set(O.locatorHash,re),f.set(O.locatorHash,be.packageLocation),be.buildDirective&&be.buildDirective.length>0&&be.packageLocation&&h.set(O.locatorHash,{directives:be.buildDirective,buildLocations:[be.packageLocation]})}}let y=new Map;for(let Z of this.accessibleLocators){let O=this.storedPackages.get(Z);if(!O)throw new Error("Assertion failed: The locator should have been registered");let L=this.tryWorkspaceByLocator(O)!==null,de=async(Be,je)=>{let re=f.get(O.locatorHash);if(typeof re=="undefined")throw new Error(`Assertion failed: The package (${It(this.configuration,O)}) should have been registered`);let se=[];for(let be of O.dependencies.values()){let he=this.storedResolutions.get(be.descriptorHash);if(typeof he=="undefined")throw new Error(`Assertion failed: The resolution (${sr(this.configuration,be)}, from ${It(this.configuration,O)})should have been registered`);let Fe=this.storedPackages.get(he);if(typeof Fe=="undefined")throw new Error(`Assertion failed: The package (${he}, resolved from ${sr(this.configuration,be)}) should have been registered`);let Ke=this.tryWorkspaceByLocator(Fe)===null?g.get(he):null;if(typeof Ke=="undefined")throw new Error(`Assertion failed: The package (${he}, resolved from ${sr(this.configuration,be)}) should have been registered`);Ke===Be||Ke===null?f.get(Fe.locatorHash)!==null&&se.push([be,Fe]):!L&&re!==null&&Fg(y,he).push(re)}re!==null&&await je.attachInternalDependencies(O,se)};if(L)for(let[Be,je]of u)Be.supportsPackage(O,c)&&await de(Be,je);else{let Be=g.get(O.locatorHash);if(!Be)throw new Error("Assertion failed: The linker should have been found");let je=u.get(Be);if(!je)throw new Error("Assertion failed: The installer should have been registered");await de(Be,je)}}for(let[Z,O]of y){let L=this.storedPackages.get(Z);if(!L)throw new Error("Assertion failed: The package should have been registered");let de=g.get(L.locatorHash);if(!de)throw new Error("Assertion failed: The linker should have been found");let Be=u.get(de);if(!Be)throw new Error("Assertion failed: The installer should have been registered");await Be.attachExternalDependents(L,O)}let b=new Map;for(let Z of u.values()){let O=await Z.finalizeInstall();for(let L of(ce=O==null?void 0:O.records)!=null?ce:[])h.set(L.locatorHash,{directives:L.buildDirective,buildLocations:L.buildLocations});typeof(O==null?void 0:O.customData)!="undefined"&&b.set(Z.getCustomDataKey(),O.customData)}if(this.installersCustomData=b,await go(m),n===Ci.SkipBuild)return;let v=new Set(this.storedPackages.keys()),x=new Set(h.keys());for(let Z of x)v.delete(Z);let T=(0,i0.createHash)("sha512");T.update(process.versions.node),await this.configuration.triggerHook(Z=>Z.globalHashGeneration,this,Z=>{T.update("\0"),T.update(Z)});let q=T.digest("hex"),Y=new Map,$=Z=>{let O=Y.get(Z.locatorHash);if(typeof O!="undefined")return O;let L=this.storedPackages.get(Z.locatorHash);if(typeof L=="undefined")throw new Error("Assertion failed: The package should have been registered");let de=(0,i0.createHash)("sha512");de.update(Z.locatorHash),Y.set(Z.locatorHash,"");for(let Be of L.dependencies.values()){let je=this.storedResolutions.get(Be.descriptorHash);if(typeof je=="undefined")throw new Error(`Assertion failed: The resolution (${sr(this.configuration,Be)}) should have been registered`);let re=this.storedPackages.get(je);if(typeof re=="undefined")throw new Error("Assertion failed: The package should have been registered");de.update($(re))}return O=de.digest("hex"),Y.set(Z.locatorHash,O),O},_=(Z,O)=>{let L=(0,i0.createHash)("sha512");L.update(q),L.update($(Z));for(let de of O)L.update(de);return L.digest("hex")},ne=new Map,ee=!1;for(;x.size>0;){let Z=x.size,O=[];for(let L of x){let de=this.storedPackages.get(L);if(!de)throw new Error("Assertion failed: The package should have been registered");let Be=!0;for(let se of de.dependencies.values()){let be=this.storedResolutions.get(se.descriptorHash);if(!be)throw new Error(`Assertion failed: The resolution (${sr(this.configuration,se)}) should have been registered`);if(x.has(be)){Be=!1;break}}if(!Be)continue;x.delete(L);let je=h.get(de.locatorHash);if(!je)throw new Error("Assertion failed: The build directive should have been registered");let re=_(de,je.buildLocations);if(this.storedBuildState.get(de.locatorHash)===re){ne.set(de.locatorHash,re);continue}ee||(await this.persistInstallStateFile(),ee=!0),this.storedBuildState.has(de.locatorHash)?t.reportInfo(X.MUST_REBUILD,`${It(this.configuration,de)} must be rebuilt because its dependency tree changed`):t.reportInfo(X.MUST_BUILD,`${It(this.configuration,de)} must be built because it never has been before or the last one failed`);for(let se of je.buildLocations){if(!k.isAbsolute(se))throw new Error(`Assertion failed: Expected the build location to be absolute (not ${se})`);O.push((async()=>{for(let[be,he]of je.directives){let Fe=`# This file contains the result of Yarn building a package (${Rs(de)}) -`;switch(be){case cs.SCRIPT:Fe+=`# Script name: ${he} -`;break;case cs.SHELLCODE:Fe+=`# Script code: ${he} -`;break}let Ke=null;if(!await K.mktempPromise(async ve=>{let pe=k.join(ve,"build.log"),{stdout:V,stderr:Qe}=this.configuration.getSubprocessStreams(pe,{header:Fe,prefix:It(this.configuration,de),report:t}),le;try{switch(be){case cs.SCRIPT:le=await nB(de,he,[],{cwd:se,project:this,stdin:Ke,stdout:V,stderr:Qe});break;case cs.SHELLCODE:le=await rD(de,he,[],{cwd:se,project:this,stdin:Ke,stdout:V,stderr:Qe});break}}catch(gt){Qe.write(gt.stack),le=1}if(V.end(),Qe.end(),le===0)return ne.set(de.locatorHash,re),!0;K.detachTemp(ve);let fe=`${It(this.configuration,de)} couldn't be built successfully (exit code ${tt(this.configuration,le,qe.NUMBER)}, logs can be found here: ${tt(this.configuration,pe,qe.PATH)})`;return this.optionalBuilds.has(de.locatorHash)?(t.reportInfo(X.BUILD_FAILED,fe),ne.set(de.locatorHash,re),!0):(t.reportError(X.BUILD_FAILED,fe),!1)}))return}})())}}if(await go(O),Z===x.size){let L=Array.from(x).map(de=>{let Be=this.storedPackages.get(de);if(!Be)throw new Error("Assertion failed: The package should have been registered");return It(this.configuration,Be)}).join(", ");t.reportError(X.CYCLIC_DEPENDENCIES,`Some packages have circular dependencies that make their build order unsatisfiable - as a result they won't be built (affected packages are: ${L})`);break}}this.storedBuildState=ne}async install(e){var a,l;let t=this.configuration.get("nodeLinker");(a=ye.telemetry)==null||a.reportInstall(t),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=qi.Inactive;let i=k.join(this.cwd,this.configuration.get("lockfileFilename")),n=null;if(e.immutable)try{n=await K.readFilePromise(i,"utf8")}catch(c){throw c.code==="ENOENT"?new ct(X.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=tt(this.configuration,g,qe.PACKAGE_EXTENSION);switch(g.status){case qi.Inactive:e.report.reportWarning(X.UNUSED_PACKAGE_EXTENSION,`${f}: No matching package in the dependency tree; you may not need this rule anymore.`);break;case qi.Redundant:e.report.reportWarning(X.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=sc(n,this.generateLockfile());if(c!==n){let u=V6(i,i,n,c,void 0,void 0,{maxEditLength:100});if(u){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(X.FROZEN_LOCKFILE_EXCEPTION,tt(this.configuration,f,qe.ADDED)):f.startsWith("-")?e.report.reportError(X.FROZEN_LOCKFILE_EXCEPTION,tt(this.configuration,f,qe.REMOVED)):e.report.reportInfo(null,tt(this.configuration,f,"grey"))}e.report.reportSeparator()}throw new ct(X.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===qi.Active&&((l=ye.telemetry)==null||l.reportPackageExtension(Oc(g,qe.PACKAGE_EXTENSION)));await e.report.startTimerPromise("Fetch step",async()=>{await this.fetchEverything(e),(typeof e.persistProject=="undefined"||e.persistProject)&&e.mode!==Ci.UpdateLockfile&&await this.cacheCleanup(e)});let s=e.immutable?[...new Set(this.configuration.get("immutablePatterns"))].sort():[],o=await Promise.all(s.map(async c=>ow(c,{cwd:this.cwd})));(typeof e.persistProject=="undefined"||e.persistProject)&&await this.persist(),await e.report.startTimerPromise("Link step",async()=>{if(e.mode===Ci.UpdateLockfile){e.report.reportWarning(X.UPDATE_LOCKFILE_ONLY_SKIP_LINK,`Skipped due to ${tt(this.configuration,"mode=update-lockfile",qe.CODE)}`);return}await this.linkEverything(e);let c=await Promise.all(s.map(async u=>ow(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 t={};t.__metadata={version:oZ,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=>Pn(f)).sort().join(", "),c=new At;c.version=o.linkType===Qt.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 t.__metadata.cacheKey=="undefined"&&(t.__metadata.cacheKey=h),h===t.__metadata.cacheKey?u=p:u=g}t[l]=te(N({},c.exportTo({},{compatibilityMode:!1})),{linkType:o.linkType.toLowerCase(),resolution:Rs(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("")} -`+Ma(t)}async persistLockfile(){let e=k.join(this.cwd,this.configuration.get("lockfileFilename")),t="";try{t=await K.readFilePromise(e,"utf8")}catch(s){}let i=this.generateLockfile(),n=sc(t,i);n!==t&&(await K.writeFilePromise(e,n),this.lockFileChecksum=AZ(n),this.lockfileNeedsRefresh=!1)}async persistInstallStateFile(){let e=[];for(let o of Object.values(UR))e.push(...o);let t=(0,n0.default)(this,e),i=MR.default.serialize(t),n=ln(i);if(this.installStateChecksum===n)return;let s=this.configuration.get("installStatePath");await K.mkdirPromise(k.dirname(s),{recursive:!0}),await K.writeFilePromise(s,await VOe(i)),this.installStateChecksum=n}async restoreInstallState({restoreInstallersCustomData:e=!0,restoreResolutions:t=!0,restoreBuildState:i=!0}={}){let n=this.configuration.get("installStatePath"),s;try{let o=await XOe(await K.readFilePromise(n));s=MR.default.deserialize(o),this.installStateChecksum=ln(o)}catch{t&&await this.applyLightResolution();return}e&&typeof s.installersCustomData!="undefined"&&(this.installersCustomData=s.installersCustomData),i&&Object.assign(this,(0,n0.default)(s,UR.restoreBuildState)),t&&(s.lockFileChecksum===this.lockFileChecksum?(Object.assign(this,(0,n0.default)(s,UR.restoreResolutions)),this.refreshWorkspaceDependencies()):await this.applyLightResolution())}async applyLightResolution(){await this.resolveEverything({lockfileOnly:!0,report:new di}),await this.persistInstallStateFile()}async persist(){await this.persistLockfile();for(let e of this.workspacesByCwd.values())await e.persistManifest()}async cacheCleanup({cache:e,report:t}){if(this.configuration.get("enableGlobalCache"))return;let i=new Set([".gitignore"]);if(!Ak(e.cwd,this.cwd)||!await K.existsPromise(e.cwd))return;let n=this.configuration.get("preferAggregateCacheInfo"),s=0,o=null;for(let a of await K.readdirPromise(e.cwd)){if(i.has(a))continue;let l=k.resolve(e.cwd,a);e.markedFiles.has(l)||(o=a,e.immutable?t.reportError(X.IMMUTABLE_CACHE,`${tt(this.configuration,k.basename(l),"magenta")} appears to be unused and would be marked for deletion, but the cache is immutable`):(n?s+=1:t.reportInfo(X.UNUSED_CACHE_ENTRY,`${tt(this.configuration,k.basename(l),"magenta")} appears to be unused - removing`),await K.removePromise(l)))}n&&s!==0&&t.reportInfo(X.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 ZOe({project:r,allDescriptors:e,allResolutions:t,allPackages:i,accessibleLocators:n=new Set,optionalBuilds:s=new Set,peerRequirements:o=new Map,volatileDescriptors:a=new Set,report:l,tolerateMissingPackages:c=!1}){var ne;let u=new Map,g=[],f=new Map,h=new Map,p=new Map,m=new Map,y=new Map,b=new Map(r.workspaces.map(ee=>{let A=ee.anchoredLocator.locatorHash,oe=i.get(A);if(typeof oe=="undefined"){if(c)return[A,null];throw new Error("Assertion failed: The workspace should have an associated package")}return[A,cd(oe)]})),v=()=>{let ee=K.mktempSync(),A=k.join(ee,"stacktrace.log"),oe=String(g.length+1).length,ce=g.map((Z,O)=>`${`${O+1}.`.padStart(oe," ")} ${Rs(Z)} -`).join("");throw K.writeFileSync(A,ce),K.detachTemp(ee),new ct(X.STACK_OVERFLOW_RESOLUTION,`Encountered a stack overflow when resolving peer dependencies; cf ${H.fromPortablePath(A)}`)},x=ee=>{let A=t.get(ee.descriptorHash);if(typeof A=="undefined")throw new Error("Assertion failed: The resolution should have been registered");let oe=i.get(A);if(!oe)throw new Error("Assertion failed: The package could not be found");return oe},T=(ee,A,oe,{top:ce,optional:Z})=>{g.length>1e3&&v(),g.push(A);let O=q(ee,A,oe,{top:ce,optional:Z});return g.pop(),O},q=(ee,A,oe,{top:ce,optional:Z})=>{if(n.has(A.locatorHash))return;n.add(A.locatorHash),Z||s.delete(A.locatorHash);let O=i.get(A.locatorHash);if(!O){if(c)return;throw new Error(`Assertion failed: The package (${It(r.configuration,A)}) should have been registered`)}let L=[],de=[],Be=[],je=[],re=[];for(let be of Array.from(O.dependencies.values())){if(O.peerDependencies.has(be.identHash)&&O.locatorHash!==ce)continue;if(Al(be))throw new Error("Assertion failed: Virtual packages shouldn't be encountered when virtualizing a branch");a.delete(be.descriptorHash);let he=Z;if(!he){let Qe=O.dependenciesMeta.get(Ot(be));if(typeof Qe!="undefined"){let le=Qe.get(null);typeof le!="undefined"&&le.optional&&(he=!0)}}let Fe=t.get(be.descriptorHash);if(!Fe){if(c)continue;throw new Error(`Assertion failed: The resolution (${sr(r.configuration,be)}) should have been registered`)}let Ke=b.get(Fe)||i.get(Fe);if(!Ke)throw new Error(`Assertion failed: The package (${Fe}, resolved from ${sr(r.configuration,be)}) should have been registered`);if(Ke.peerDependencies.size===0){T(be,Ke,new Map,{top:ce,optional:he});continue}let ke,ve,pe=new Set,V;de.push(()=>{ke=Vx(be,A.locatorHash),ve=Xx(Ke,A.locatorHash),O.dependencies.delete(be.identHash),O.dependencies.set(ke.identHash,ke),t.set(ke.descriptorHash,ve.locatorHash),e.set(ke.descriptorHash,ke),i.set(ve.locatorHash,ve),L.push([Ke,ke,ve])}),Be.push(()=>{var Qe;V=new Map;for(let le of ve.peerDependencies.values()){let fe=O.dependencies.get(le.identHash);if(!fe&&fd(A,le)&&(ee.identHash===A.identHash?fe=ee:(fe=rr(A,ee.range),e.set(fe.descriptorHash,fe),t.set(fe.descriptorHash,A.locatorHash),a.delete(fe.descriptorHash))),(!fe||fe.range==="missing:")&&ve.dependencies.has(le.identHash)){ve.peerDependencies.delete(le.identHash);continue}fe||(fe=rr(le,"missing:")),ve.dependencies.set(fe.identHash,fe),Al(fe)&&Nc(p,fe.descriptorHash).add(ve.locatorHash),f.set(fe.identHash,fe),fe.range==="missing:"&&pe.add(fe.identHash),V.set(le.identHash,(Qe=oe.get(le.identHash))!=null?Qe:ve.locatorHash)}ve.dependencies=new Map(kn(ve.dependencies,([le,fe])=>Ot(fe)))}),je.push(()=>{if(!i.has(ve.locatorHash))return;let Qe=u.get(Ke.locatorHash);typeof Qe=="number"&&Qe>=2&&v();let le=u.get(Ke.locatorHash),fe=typeof le!="undefined"?le+1:1;u.set(Ke.locatorHash,fe),T(ke,ve,V,{top:ce,optional:he}),u.set(Ke.locatorHash,fe-1)}),re.push(()=>{let Qe=O.dependencies.get(be.identHash);if(typeof Qe=="undefined")throw new Error("Assertion failed: Expected the peer dependency to have been turned into a dependency");let le=t.get(Qe.descriptorHash);if(typeof le=="undefined")throw new Error("Assertion failed: Expected the descriptor to be registered");if(Nc(y,le).add(A.locatorHash),!!i.has(ve.locatorHash)){for(let fe of ve.peerDependencies.values()){let gt=V.get(fe.identHash);if(typeof gt=="undefined")throw new Error("Assertion failed: Expected the peer dependency ident to be registered");Fg(Ng(m,gt),Ot(fe)).push(ve.locatorHash)}for(let fe of pe)ve.dependencies.delete(fe)}})}for(let be of[...de,...Be])be();let se;do{se=!0;for(let[be,he,Fe]of L){let Ke=Ng(h,be.locatorHash),ke=ln(...[...Fe.dependencies.values()].map(Qe=>{let le=Qe.range!=="missing:"?t.get(Qe.descriptorHash):"missing:";if(typeof le=="undefined")throw new Error(`Assertion failed: Expected the resolution for ${sr(r.configuration,Qe)} to have been registered`);return le===ce?`${le} (top)`:le}),he.identHash),ve=Ke.get(ke);if(typeof ve=="undefined"){Ke.set(ke,he);continue}if(ve===he)continue;i.delete(Fe.locatorHash),e.delete(he.descriptorHash),t.delete(he.descriptorHash),n.delete(Fe.locatorHash);let pe=p.get(he.descriptorHash)||[],V=[O.locatorHash,...pe];p.delete(he.descriptorHash);for(let Qe of V){let le=i.get(Qe);typeof le!="undefined"&&(le.dependencies.get(he.identHash).descriptorHash!==ve.descriptorHash&&(se=!1),le.dependencies.set(he.identHash,ve))}}}while(!se);for(let be of[...je,...re])be()};for(let ee of r.workspaces){let A=ee.anchoredLocator;a.delete(ee.anchoredDescriptor.descriptorHash),T(ee.anchoredDescriptor,A,new Map,{top:A.locatorHash,optional:!1})}var Y;(function(oe){oe[oe.NotProvided=0]="NotProvided",oe[oe.NotCompatible=1]="NotCompatible"})(Y||(Y={}));let $=[];for(let[ee,A]of y){let oe=i.get(ee);if(typeof oe=="undefined")throw new Error("Assertion failed: Expected the root to be registered");let ce=m.get(ee);if(typeof ce!="undefined")for(let Z of A){let O=i.get(Z);if(typeof O!="undefined")for(let[L,de]of ce){let Be=An(L);if(O.peerDependencies.has(Be.identHash))continue;let je=`p${ln(Z,L,ee).slice(0,5)}`;o.set(je,{subject:Z,requested:Be,rootRequester:ee,allRequesters:de});let re=oe.dependencies.get(Be.identHash);if(typeof re!="undefined"){let se=x(re),be=(ne=se.version)!=null?ne:"0.0.0",he=new Set;for(let Ke of de){let ke=i.get(Ke);if(typeof ke=="undefined")throw new Error("Assertion failed: Expected the link to be registered");let ve=ke.peerDependencies.get(Be.identHash);if(typeof ve=="undefined")throw new Error("Assertion failed: Expected the ident to be registered");he.add(ve.range)}[...he].every(Ke=>{if(Ke.startsWith(oi.protocol)){if(!r.tryWorkspaceByLocator(se))return!1;Ke=Ke.slice(oi.protocol.length),(Ke==="^"||Ke==="~")&&(Ke="*")}return qc(be,Ke)})||$.push({type:1,subject:O,requested:Be,requester:oe,version:be,hash:je,requirementCount:de.length})}else{let se=oe.peerDependenciesMeta.get(L);(se==null?void 0:se.optional)||$.push({type:0,subject:O,requested:Be,requester:oe,hash:je})}}}}let _=[ee=>$x(ee.subject),ee=>Ot(ee.requested),ee=>`${ee.type}`];l==null||l.startSectionSync({reportFooter:()=>{l.reportWarning(X.UNNAMED,`Some peer dependencies are incorrectly met; run ${tt(r.configuration,"yarn explain peer-requirements ",qe.CODE)} for details, where ${tt(r.configuration,"",qe.CODE)} is the six-letter p-prefixed code`)},skipIfEmpty:!0},()=>{for(let ee of kn($,_))switch(ee.type){case 0:l.reportWarning(X.MISSING_PEER_DEPENDENCY,`${It(r.configuration,ee.subject)} doesn't provide ${fi(r.configuration,ee.requested)} (${tt(r.configuration,ee.hash,qe.CODE)}), requested by ${fi(r.configuration,ee.requester)}`);break;case 1:{let A=ee.requirementCount>1?"and some of its descendants request":"requests";l.reportWarning(X.INCOMPATIBLE_PEER_DEPENDENCY,`${It(r.configuration,ee.subject)} provides ${fi(r.configuration,ee.requested)} (${tt(r.configuration,ee.hash,qe.CODE)}) with version ${dd(r.configuration,ee.version)}, which doesn't satisfy what ${fi(r.configuration,ee.requester)} ${A}`)}break}})}var ca;(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"})(ca||(ca={}));var mC=class{constructor(e,t){this.values=new Map;this.hits=new Map;this.enumerators=new Map;this.configuration=e;let i=this.getRegistryPath();this.isNew=!K.existsSync(i),this.sendReport(t),this.startBuffer()}reportVersion(e){this.reportValue(ca.VERSION,e.replace(/-git\..*/,"-git"))}reportCommandName(e){this.reportValue(ca.COMMAND_NAME,e||"")}reportPluginName(e){this.reportValue(ca.PLUGIN_NAME,e)}reportProject(e){this.reportEnumerator(ca.PROJECT_COUNT,e)}reportInstall(e){this.reportHit(ca.INSTALL_COUNT,e)}reportPackageExtension(e){this.reportValue(ca.EXTENSION,e)}reportWorkspaceCount(e){this.reportValue(ca.WORKSPACE_COUNT,String(e))}reportDependencyCount(e){this.reportValue(ca.DEPENDENCY_COUNT,String(e))}reportValue(e,t){Nc(this.values,e).add(t)}reportEnumerator(e,t){Nc(this.enumerators,e).add(ln(t))}reportHit(e,t="*"){let i=Ng(this.hits,e),n=_a(i,t,()=>0);i.set(t,n+1)}getRegistryPath(){let e=this.configuration.get("globalFolder");return k.join(e,"telemetry.json")}sendReport(e){var u,g,f;let t=this.getRegistryPath(),i;try{i=K.readJsonSync(t)}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{K.mkdirSync(k.dirname(t),{recursive:!0}),K.writeJsonSync(t,{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=>HP(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 m=p;m.userId=h,m.reportType="primary";for(let v of Object.keys((f=m.enumerators)!=null?f:{}))m.enumerators[v]=m.enumerators[v].length;c(m);let y=new Map,b=20;for(let[v,x]of Object.entries(m.values))x.length>0&&y.set(v,x.slice(0,b));for(;y.size>0;){let v={};v.userId=h,v.reportType="secondary",v.metrics={};for(let[x,T]of y)v.metrics[x]=T.shift(),T.length===0&&y.delete(x);c(v)}}}applyChanges(){var o,a,l,c,u,g,f,h,p;let e=this.getRegistryPath(),t;try{t=K.readJsonSync(e)}catch{t={}}let i=(o=this.configuration.get("telemetryUserId"))!=null?o:"*",n=t.blocks=(a=t.blocks)!=null?a:{},s=n[i]=(l=n[i])!=null?l:{};for(let m of this.hits.keys()){let y=s.hits=(c=s.hits)!=null?c:{},b=y[m]=(u=y[m])!=null?u:{};for(let[v,x]of this.hits.get(m))b[v]=((g=b[v])!=null?g:0)+x}for(let m of["values","enumerators"])for(let y of this[m].keys()){let b=s[m]=(f=s[m])!=null?f:{};b[y]=[...new Set([...(h=b[y])!=null?h:[],...(p=this[m].get(y))!=null?p:[]])]}K.mkdirSync(k.dirname(e),{recursive:!0}),K.writeJsonSync(e,t)}startBuffer(){process.on("exit",()=>{try{this.applyChanges()}catch{}})}};var HR=ge(require("child_process")),lZ=ge(Ic());var jR=ge(require("fs"));var Lf=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 $Oe(r){let e=H.fromPortablePath(r);process.on("SIGINT",()=>{}),e?(0,HR.execFileSync)(process.execPath,[e,...process.argv.slice(2)],{stdio:"inherit",env:te(N({},process.env),{YARN_IGNORE_PATH:"1",YARN_IGNORE_CWD:"1"})}):(0,HR.execFileSync)(e,process.argv.slice(2),{stdio:"inherit",env:te(N({},process.env),{YARN_IGNORE_PATH:"1",YARN_IGNORE_CWD:"1"})})}async function s0({binaryVersion:r,pluginConfiguration:e}){async function t(){let n=new ws({binaryLabel:"Yarn Package Manager",binaryName:"yarn",binaryVersion:r});try{await i(n)}catch(s){process.stdout.write(n.error(s)),process.exitCode=1}}async function i(n){var m,y,b,v,x;let s=process.versions.node,o=">=12 <14 || 14.2 - 14.9 || >14.10.0";if(!Se.parseOptionalBoolean(process.env.YARN_IGNORE_NODE)&&!Wt.satisfiesWithPrereleases(s,o))throw new Pe(`This tool requires a Node version compatible with ${o} (got ${s}). Upgrade Node, or set \`YARN_IGNORE_NODE=1\` in your environment.`);let l=await ye.find(H.toPortablePath(process.cwd()),e,{usePath:!0,strict:!1}),c=l.get("yarnPath"),u=l.get("ignorePath"),g=l.get("ignoreCwd"),f=H.toPortablePath(H.resolve(process.argv[1])),h=T=>K.readFilePromise(T).catch(()=>Buffer.of());if(!u&&!g&&await(async()=>c===f||Buffer.compare(...await Promise.all([h(c),h(f)]))===0)()){process.env.YARN_IGNORE_PATH="1",process.env.YARN_IGNORE_CWD="1",await i(n);return}else if(c!==null&&!u)if(!K.existsSync(c))process.stdout.write(n.error(new Error(`The "yarn-path" option has been set (in ${l.sources.get("yarnPath")}), but the specified location doesn't exist (${c}).`))),process.exitCode=1;else try{$Oe(c)}catch(T){process.exitCode=T.code||1}else{u&&delete process.env.YARN_IGNORE_PATH,l.get("enableTelemetry")&&!lZ.isCI&&process.stdout.isTTY&&(ye.telemetry=new mC(l,"puba9cdc10ec5790a2cf4969dd413a47270")),(m=ye.telemetry)==null||m.reportVersion(r);for(let[$,_]of l.plugins.entries()){Lf.has((b=(y=$.match(/^@yarnpkg\/plugin-(.*)$/))==null?void 0:y[1])!=null?b:"")&&((v=ye.telemetry)==null||v.reportPluginName($));for(let ne of _.commands||[])n.register(ne)}let q=n.process(process.argv.slice(2));q.help||(x=ye.telemetry)==null||x.reportCommandName(q.path.join(" "));let Y=q.cwd;if(typeof Y!="undefined"&&!g){let $=(0,jR.realpathSync)(process.cwd()),_=(0,jR.realpathSync)(Y);if($!==_){process.chdir(Y),await t();return}}await n.runExit(q,{cwd:H.toPortablePath(process.cwd()),plugins:e,quiet:!1,stdin:process.stdin,stdout:process.stdout,stderr:process.stderr})}}return t().catch(n=>{process.stdout.write(n.stack||n.message),process.exitCode=1}).finally(()=>K.rmtempPromise())}function cZ(r){r.Command.Path=(...e)=>t=>{t.paths=t.paths||[],t.paths.push(e)};for(let e of["Array","Boolean","String","Proxy","Rest","Counter"])r.Command[e]=(...t)=>(i,n)=>{let s=r.Option[e](...t);Object.defineProperty(i,`__${n}`,{configurable:!1,enumerable:!0,get(){return s},set(o){this[n]=o}})};return r}var GC={};ft(GC,{BaseCommand:()=>Le,WorkspaceRequiredError:()=>ht,getDynamicLibs:()=>bre,getPluginConfiguration:()=>L0,main:()=>s0,openWorkspace:()=>Wf,pluginCommands:()=>Lf});var Le=class extends Re{constructor(){super(...arguments);this.cwd=J.String("--cwd",{hidden:!0})}};var ht=class extends Pe{constructor(e,t){let i=k.relative(e,t),n=k.join(e,At.fileName);super(`This command can only be run from within a workspace of your project (${i} isn't a workspace of ${n}).`)}};var sGe=ge(ri());ys();var oGe=ge(UF()),bre=()=>new Map([["@yarnpkg/cli",GC],["@yarnpkg/core",EC],["@yarnpkg/fslib",Zh],["@yarnpkg/libzip",Md],["@yarnpkg/parsers",op],["@yarnpkg/shell",Ud],["clipanion",Cp],["semver",sGe],["typanion",cg],["yup",oGe]]);async function Wf(r,e){let{project:t,workspace:i}=await ze.find(r,e);if(!i)throw new ht(t.cwd,e);return i}var Q_e=ge(ri());ys();var S_e=ge(UF());var GN={};ft(GN,{dedupeUtils:()=>wN,default:()=>mWe,suggestUtils:()=>lN});var Sae=ge(Ic());var Fne=ge(WC());ys();var lN={};ft(lN,{Modifier:()=>pa,Strategy:()=>Vr,Target:()=>Hr,WorkspaceModifier:()=>Xf,applyModifier:()=>kne,extractDescriptorFromPath:()=>gN,extractRangeModifier:()=>xne,fetchDescriptorFrom:()=>uN,findProjectDescriptors:()=>Rne,getModifier:()=>zC,getSuggestedDescriptors:()=>_C,makeWorkspaceDescriptor:()=>Dne,toWorkspaceModifier:()=>Pne});var cN=ge(ri()),bYe="workspace:",Hr;(function(i){i.REGULAR="dependencies",i.DEVELOPMENT="devDependencies",i.PEER="peerDependencies"})(Hr||(Hr={}));var pa;(function(i){i.CARET="^",i.TILDE="~",i.EXACT=""})(pa||(pa={}));var Xf;(function(i){i.CARET="^",i.TILDE="~",i.EXACT="*"})(Xf||(Xf={}));var Vr;(function(s){s.KEEP="keep",s.REUSE="reuse",s.PROJECT="project",s.LATEST="latest",s.CACHE="cache"})(Vr||(Vr={}));function zC(r,e){return r.exact?pa.EXACT:r.caret?pa.CARET:r.tilde?pa.TILDE:e.configuration.get("defaultSemverRangePrefix")}var QYe=/^([\^~]?)[0-9]+(?:\.[0-9]+){0,2}(?:-\S+)?$/;function xne(r,{project:e}){let t=r.match(QYe);return t?t[1]:e.configuration.get("defaultSemverRangePrefix")}function kne(r,e){let{protocol:t,source:i,params:n,selector:s}=P.parseRange(r.range);return cN.default.valid(s)&&(s=`${e}${r.range}`),P.makeDescriptor(r,P.makeRange({protocol:t,source:i,params:n,selector:s}))}function Pne(r){switch(r){case pa.CARET:return Xf.CARET;case pa.TILDE:return Xf.TILDE;case pa.EXACT:return Xf.EXACT;default:throw new Error(`Assertion failed: Unknown modifier: "${r}"`)}}function Dne(r,e){return P.makeDescriptor(r.anchoredDescriptor,`${bYe}${Pne(e)}`)}async function Rne(r,{project:e,target:t}){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(t===Hr.PEER){let o=s.manifest.peerDependencies.get(r.identHash);o!==void 0&&n(o).locators.push(s.locator)}else{let o=s.manifest.dependencies.get(r.identHash),a=s.manifest.devDependencies.get(r.identHash);t===Hr.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 gN(r,{cwd:e,workspace:t}){return await SYe(async i=>{k.isAbsolute(r)||(r=k.relative(t.cwd,k.resolve(e,r)),r.match(/^\.{0,2}\//)||(r=`./${r}`));let{project:n}=t,s=await uN(P.makeIdent(null,"archive"),r,{project:t.project,cache:i,workspace:t});if(!s)throw new Error("Assertion failed: The descriptor should have been found");let o=new di,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,t.anchoredLocator,c),g=P.convertDescriptorToLocator(u),f=await l.fetch(g,c),h=await At.find(f.prefixPath,{baseFs:f.packageFs});if(!h.name)throw new Error("Target path doesn't have a name");return P.makeDescriptor(h.name,r)})}async function _C(r,{project:e,workspace:t,cache:i,target:n,modifier:s,strategies:o,maxResults:a=Infinity}){if(!(a>=0))throw new Error(`Invalid maxResults (${a})`);if(r.range!=="unknown")return{suggestions:[{descriptor:r,name:`Use ${P.prettyDescriptor(e.configuration,r)}`,reason:"(unambiguous explicit request)"}],rejections:[]};let l=typeof t!="undefined"&&t!==null&&t.manifest[n].get(r.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 Vr.KEEP:await g(async()=>{l&&c.push({descriptor:l,name:`Keep ${P.prettyDescriptor(e.configuration,l)}`,reason:"(no changes)"})});break;case Vr.REUSE:await g(async()=>{for(let{descriptor:h,locators:p}of(await Rne(r,{project:e,target:n})).values()){if(p.length===1&&p[0].locatorHash===t.anchoredLocator.locatorHash&&o.includes(Vr.KEEP))continue;let m=`(originally used by ${P.prettyLocator(e.configuration,p[0])}`;m+=p.length>1?` and ${p.length-1} other${p.length>2?"s":""})`:")",c.push({descriptor:h,name:`Reuse ${P.prettyDescriptor(e.configuration,h)}`,reason:m})}});break;case Vr.CACHE:await g(async()=>{for(let h of e.storedDescriptors.values())h.identHash===r.identHash&&c.push({descriptor:h,name:`Reuse ${P.prettyDescriptor(e.configuration,h)}`,reason:"(already used somewhere in the lockfile)"})});break;case Vr.PROJECT:await g(async()=>{if(t.manifest.name!==null&&r.identHash===t.manifest.name.identHash)return;let h=e.tryWorkspaceByIdent(r);if(h===null)return;let p=Dne(h,s);c.push({descriptor:p,name:`Attach ${P.prettyDescriptor(e.configuration,p)}`,reason:`(local workspace at ${ae.pretty(e.configuration,h.relativeCwd,ae.Type.PATH)})`})});break;case Vr.LATEST:await g(async()=>{if(r.range!=="unknown")c.push({descriptor:r,name:`Use ${P.prettyRange(e.configuration,r.range)}`,reason:"(explicit range requested)"});else if(n===Hr.PEER)c.push({descriptor:P.makeDescriptor(r,"*"),name:"Use *",reason:"(catch-all peer dependency pattern)"});else if(!e.configuration.get("enableNetwork"))c.push({descriptor:null,name:"Resolve from latest",reason:ae.pretty(e.configuration,"(unavailable because enableNetwork is toggled off)","grey")});else{let h=await uN(r,"latest",{project:e,cache:i,workspace:t,preserveModifier:!1});h&&(h=kne(h,s),c.push({descriptor:h,name:`Use ${P.prettyDescriptor(e.configuration,h)}`,reason:"(resolved from latest)"}))}});break}}return{suggestions:c.slice(0,a),rejections:u.slice(0,a)}}async function uN(r,e,{project:t,cache:i,workspace:n,preserveModifier:s=!0}){let o=P.makeDescriptor(r,e),a=new di,l=t.configuration.makeFetcher(),c=t.configuration.makeResolver(),u={project:t,fetcher:l,cache:i,checksums:t.storedChecksums,report:a,cacheOptions:{skipIntegrityCheck:!0},skipIntegrityCheck:!0},g=te(N({},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:m,source:y,params:b,selector:v}=P.parseRange(P.convertToManifestRange(p.reference));if(m===t.configuration.get("defaultProtocol")&&(m=null),cN.default.valid(v)&&s!==!1){let x=typeof s=="string"?s:o.range;v=xne(x,{project:t})+v}return P.makeDescriptor(p,P.makeRange({protocol:m,source:y,params:b,selector:v}))}async function SYe(r){return await K.mktempPromise(async e=>{let t=ye.create(e);return t.useWithSource(e,{enableMirror:!1,compressionLevel:0},e,{overwrite:!0}),await r(new Nt(e,{configuration:t,check:!1,immutable:!1}))})}var VC=class extends Le{constructor(){super(...arguments);this.json=J.Boolean("--json",!1,{description:"Format the output as an NDJSON stream"});this.exact=J.Boolean("-E,--exact",!1,{description:"Don't use any semver modifier on the resolved range"});this.tilde=J.Boolean("-T,--tilde",!1,{description:"Use the `~` semver modifier on the resolved range"});this.caret=J.Boolean("-C,--caret",!1,{description:"Use the `^` semver modifier on the resolved range"});this.dev=J.Boolean("-D,--dev",!1,{description:"Add a package as a dev dependency"});this.peer=J.Boolean("-P,--peer",!1,{description:"Add a package as a peer dependency"});this.optional=J.Boolean("-O,--optional",!1,{description:"Add / upgrade a package to an optional regular / peer dependency"});this.preferDev=J.Boolean("--prefer-dev",!1,{description:"Add / upgrade a package to a dev dependency"});this.interactive=J.Boolean("-i,--interactive",{description:"Reuse the specified package from other workspaces in the project"});this.cached=J.Boolean("--cached",!1,{description:"Reuse the highest version already used somewhere within the project"});this.mode=J.String("--mode",{description:"Change what artifacts installs generate",validator:nn(Ci)});this.silent=J.Boolean("--silent",{hidden:!0});this.packages=J.Rest()}async execute(){var m;let e=await ye.find(this.context.cwd,this.context.plugins),{project:t,workspace:i}=await ze.find(e,this.context.cwd),n=await Nt.find(e);if(!i)throw new ht(t.cwd,this.context.cwd);await t.restoreInstallState({restoreResolutions:!1});let s=(m=this.interactive)!=null?m:e.get("preferInteractive"),o=zC(this,t),a=[...s?[Vr.REUSE]:[],Vr.PROJECT,...this.cached?[Vr.CACHE]:[],Vr.LATEST],l=s?Infinity:1,c=await Promise.all(this.packages.map(async y=>{let b=y.match(/^\.{0,2}\//)?await gN(y,{cwd:this.context.cwd,workspace:i}):P.tryParseDescriptor(y),v=y.match(/^(https?:|git@github)/);if(v)throw new Pe(`It seems you are trying to add a package using a ${ae.pretty(e,`${v[0]}...`,Ri.RANGE)} url; we now require package names to be explicitly specified. -Try running the command again with the package name prefixed: ${ae.pretty(e,"yarn add",Ri.CODE)} ${ae.pretty(e,P.makeDescriptor(P.makeIdent(null,"my-package"),`${v[0]}...`),Ri.DESCRIPTOR)}`);if(!b)throw new Pe(`The ${ae.pretty(e,y,Ri.CODE)} string didn't match the required format (package-name@range). Did you perhaps forget to explicitly reference the package name?`);let x=vYe(i,b,{dev:this.dev,peer:this.peer,preferDev:this.preferDev,optional:this.optional}),T=await _C(b,{project:t,workspace:i,cache:n,target:x,modifier:o,strategies:a,maxResults:l});return[b,T,x]})),u=await pA.start({configuration:e,stdout:this.context.stdout,suggestInstall:!1},async y=>{for(let[b,{suggestions:v,rejections:x}]of c)if(v.filter(q=>q.descriptor!==null).length===0){let[q]=x;if(typeof q=="undefined")throw new Error("Assertion failed: Expected an error to have been set");t.configuration.get("enableNetwork")?y.reportError(X.CANT_SUGGEST_RESOLUTIONS,`${P.prettyDescriptor(e,b)} can't be resolved to a satisfying range`):y.reportError(X.CANT_SUGGEST_RESOLUTIONS,`${P.prettyDescriptor(e,b)} can't be resolved to a satisfying range (note: network resolution has been disabled)`),y.reportSeparator(),y.reportExceptionOnce(q)}});if(u.hasErrors())return u.exitCode();let g=!1,f=[],h=[];for(let[,{suggestions:y},b]of c){let v,x=y.filter($=>$.descriptor!==null),T=x[0].descriptor,q=x.every($=>P.areDescriptorsEqual($.descriptor,T));x.length===1||q?v=T:(g=!0,{answer:v}=await(0,Fne.prompt)({type:"select",name:"answer",message:"Which range do you want to use?",choices:y.map(({descriptor:$,name:_,reason:ne})=>$?{name:_,hint:ne,descriptor:$}:{name:_,hint:ne,disabled:!0}),onCancel:()=>process.exit(130),result($){return this.find($,"descriptor")},stdin:this.context.stdin,stdout:this.context.stdout}));let Y=i.manifest[b].get(v.identHash);(typeof Y=="undefined"||Y.descriptorHash!==v.descriptorHash)&&(i.manifest[b].set(v.identHash,v),this.optional&&(b==="dependencies"?i.manifest.ensureDependencyMeta(te(N({},v),{range:"unknown"})).optional=!0:b==="peerDependencies"&&(i.manifest.ensurePeerDependencyMeta(te(N({},v),{range:"unknown"})).optional=!0)),typeof Y=="undefined"?f.push([i,b,v,a]):h.push([i,b,Y,v]))}return await e.triggerMultipleHooks(y=>y.afterWorkspaceDependencyAddition,f),await e.triggerMultipleHooks(y=>y.afterWorkspaceDependencyReplacement,h),g&&this.context.stdout.write(` -`),(await Je.start({configuration:e,json:this.json,stdout:this.context.stdout,includeLogs:!this.context.quiet},async y=>{await t.install({cache:n,report:y,mode:this.mode})})).exitCode()}};VC.paths=[["add"]],VC.usage=Re.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 Nne=VC;function vYe(r,e,{dev:t,peer:i,preferDev:n,optional:s}){let o=r.manifest[Hr.REGULAR].has(e.identHash),a=r.manifest[Hr.DEVELOPMENT].has(e.identHash),l=r.manifest[Hr.PEER].has(e.identHash);if((t||i)&&o)throw new Pe(`Package "${P.prettyIdent(r.project.configuration,e)}" is already listed as a regular dependency - remove the -D,-P flags or remove it from your dependencies first`);if(!t&&!i&&l)throw new Pe(`Package "${P.prettyIdent(r.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 Pe(`Package "${P.prettyIdent(r.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 Pe(`Package "${P.prettyIdent(r.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((t||n)&&s)throw new Pe(`Package "${P.prettyIdent(r.project.configuration,e)}" cannot simultaneously be a dev dependency and an optional dependency`);return i?Hr.PEER:t||n?Hr.DEVELOPMENT:o?Hr.REGULAR:a?Hr.DEVELOPMENT:Hr.REGULAR}var XC=class extends Le{constructor(){super(...arguments);this.verbose=J.Boolean("-v,--verbose",!1,{description:"Print both the binary name and the locator of the package that provides the binary"});this.json=J.Boolean("--json",!1,{description:"Format the output as an NDJSON stream"});this.name=J.String({required:!1})}async execute(){let e=await ye.find(this.context.cwd,this.context.plugins),{project:t,locator:i}=await ze.find(e,this.context.cwd);if(await t.restoreInstallState(),this.name){let o=(await Zt.getPackageAccessibleBinaries(i,{project:t})).get(this.name);if(!o)throw new Pe(`Couldn't find a binary named "${this.name}" for package "${P.prettyLocator(e,i)}"`);let[,a]=o;return this.context.stdout.write(`${a} -`),0}return(await Je.start({configuration:e,json:this.json,stdout:this.context.stdout},async s=>{let o=await Zt.getPackageAccessibleBinaries(i,{project:t}),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:P.stringifyIdent(u),path:g});if(this.verbose)for(let[c,[u]]of o)s.reportInfo(null,`${c.padEnd(l," ")} ${P.prettyLocator(e,u)}`);else for(let c of o.keys())s.reportInfo(null,c)})).exitCode()}};XC.paths=[["bin"]],XC.usage=Re.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 Lne=XC;var ZC=class extends Le{constructor(){super(...arguments);this.mirror=J.Boolean("--mirror",!1,{description:"Remove the global cache files instead of the local cache files"});this.all=J.Boolean("--all",!1,{description:"Remove both the global cache files and the local cache files of the current project"})}async execute(){let e=await ye.find(this.context.cwd,this.context.plugins),t=await Nt.find(e);return(await Je.start({configuration:e,stdout:this.context.stdout},async()=>{let n=(this.all||this.mirror)&&t.mirrorCwd!==null,s=!this.mirror;n&&(await K.removePromise(t.mirrorCwd),await e.triggerHook(o=>o.cleanGlobalArtifacts,e)),s&&await K.removePromise(t.cwd)})).exitCode()}};ZC.paths=[["cache","clean"],["cache","clear"]],ZC.usage=Re.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 Tne=ZC;var One=ge(C0()),fN=ge(require("util")),$C=class extends Le{constructor(){super(...arguments);this.json=J.Boolean("--json",!1,{description:"Format the output as an NDJSON stream"});this.unsafe=J.Boolean("--no-redacted",!1,{description:"Don't redact secrets (such as tokens) from the output"});this.name=J.String()}async execute(){let e=await ye.find(this.context.cwd,this.context.plugins),t=this.name.replace(/[.[].*$/,""),i=this.name.replace(/^[^.[]*/,"");if(typeof e.settings.get(t)=="undefined")throw new Pe(`Couldn't find a configuration settings named "${t}"`);let s=e.getSpecial(t,{hideSecrets:!this.unsafe,getNativePaths:!0}),o=Se.convertMapsToIndexableObjects(s),a=i?(0,One.default)(o,i):o,l=await Je.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();fN.inspect.styles.name="cyan",this.context.stdout.write(`${(0,fN.inspect)(a,{depth:Infinity,colors:e.get("enableColors"),compact:!1})} -`)}return l.exitCode()}};$C.paths=[["config","get"]],$C.usage=Re.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 Mne=$C;var Vse=ge(EN()),Xse=ge(C0()),Zse=ge(_se()),IN=ge(require("util")),tm=class extends Le{constructor(){super(...arguments);this.json=J.Boolean("--json",!1,{description:"Set complex configuration settings to JSON values"});this.home=J.Boolean("-H,--home",!1,{description:"Update the home configuration instead of the project configuration"});this.name=J.String();this.value=J.String()}async execute(){let e=await ye.find(this.context.cwd,this.context.plugins),t=()=>{if(!e.projectCwd)throw new Pe("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 Pe(`Couldn't find a configuration settings named "${i}"`);if(i==="enableStrictSettings")throw new Pe("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=>ye.updateHomeConfiguration(h):h=>ye.updateConfiguration(t(),h))(h=>{if(n){let p=(0,Vse.default)(h);return(0,Zse.default)(p,this.name,o),p}else return te(N({},h),{[i]:o})});let c=(await ye.find(this.context.cwd,this.context.plugins)).getSpecial(i,{hideSecrets:!0,getNativePaths:!0}),u=Se.convertMapsToIndexableObjects(c),g=n?(0,Xse.default)(u,n):u;return(await Je.start({configuration:e,includeFooter:!1,stdout:this.context.stdout},async h=>{IN.inspect.styles.name="cyan",h.reportInfo(X.UNNAMED,`Successfully set ${this.name} to ${(0,IN.inspect)(g,{depth:Infinity,colors:e.get("enableColors"),compact:!1})}`)})).exitCode()}};tm.paths=[["config","set"]],tm.usage=Re.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 $se=tm;var Aoe=ge(EN()),loe=ge(yC()),coe=ge(aoe()),rm=class extends Le{constructor(){super(...arguments);this.home=J.Boolean("-H,--home",!1,{description:"Update the home configuration instead of the project configuration"});this.name=J.String()}async execute(){let e=await ye.find(this.context.cwd,this.context.plugins),t=()=>{if(!e.projectCwd)throw new Pe("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 Pe(`Couldn't find a configuration settings named "${i}"`);let o=this.home?l=>ye.updateHomeConfiguration(l):l=>ye.updateConfiguration(t(),l);return(await Je.start({configuration:e,includeFooter:!1,stdout:this.context.stdout},async l=>{let c=!1;await o(u=>{if(!(0,loe.default)(u,this.name))return l.reportWarning(X.UNNAMED,`Configuration doesn't contain setting ${this.name}; there is nothing to unset`),c=!0,u;let g=n?(0,Aoe.default)(u):N({},u);return(0,coe.default)(g,this.name),g}),c||l.reportInfo(X.UNNAMED,`Successfully unset ${this.name}`)})).exitCode()}};rm.paths=[["config","unset"]],rm.usage=Re.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 uoe=rm;var yN=ge(require("util")),im=class extends Le{constructor(){super(...arguments);this.verbose=J.Boolean("-v,--verbose",!1,{description:"Print the setting description on top of the regular key/value information"});this.why=J.Boolean("--why",!1,{description:"Print the reason why a setting is set a particular way"});this.json=J.Boolean("--json",!1,{description:"Format the output as an NDJSON stream"})}async execute(){let e=await ye.find(this.context.cwd,this.context.plugins,{strict:!1});return(await Je.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(X.INVALID_CONFIGURATION_KEY,`Invalid configuration key "${n}" in ${s}`);i.reportSeparator()}if(this.json){let n=Se.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(N({key:s,effective:a,source:l},o))}}else{let n=Se.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,yN.inspect)(e.getSpecial(c,{hideSecrets:!0,getNativePaths:!0}),o)}`)}else for(let a of n)i.reportInfo(null,`${a.padEnd(s," ")} ${(0,yN.inspect)(e.getSpecial(a,{hideSecrets:!0,getNativePaths:!0}),o)}`)}})).exitCode()}};im.paths=[["config"]],im.usage=Re.Usage({description:"display the current configuration",details:` - This command prints the current active configuration settings. - `,examples:[["Print the active configuration settings","$0 config"]]});var goe=im;ys();var wN={};ft(wN,{Strategy:()=>Bu,acceptedStrategies:()=>P3e,dedupe:()=>BN});var foe=ge(is()),Bu;(function(e){e.HIGHEST="highest"})(Bu||(Bu={}));var P3e=new Set(Object.values(Bu)),D3e={highest:async(r,e,{resolver:t,fetcher:i,resolveOptions:n,fetchOptions:s})=>{let o=new Map;for(let[a,l]of r.storedResolutions){let c=r.storedDescriptors.get(a);if(typeof c=="undefined")throw new Error(`Assertion failed: The descriptor (${a}) should have been registered`);Se.getSetWithDefault(o,c.identHash).add(l)}return Array.from(r.storedDescriptors.values(),async a=>{if(e.length&&!foe.default.isMatch(P.stringifyIdent(a),e))return null;let l=r.storedResolutions.get(a.descriptorHash);if(typeof l=="undefined")throw new Error(`Assertion failed: The resolution (${a.descriptorHash}) should have been registered`);let c=r.originalPackages.get(l);if(typeof c=="undefined"||!t.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(y=>{let b=r.originalPackages.get(y);if(typeof b=="undefined")throw new Error(`Assertion failed: The package (${y}) should have been registered`);return b.reference}),f=await t.getSatisfying(a,g,n),h=f==null?void 0:f[0];if(typeof h=="undefined")return null;let p=h.locatorHash,m=r.originalPackages.get(p);if(typeof m=="undefined")throw new Error(`Assertion failed: The package (${p}) should have been registered`);return p===l?null:{descriptor:a,currentPackage:c,updatedPackage:m}})}};async function BN(r,{strategy:e,patterns:t,cache:i,report:n}){let{configuration:s}=r,o=new di,a=s.makeResolver(),l=s.makeFetcher(),c={cache:i,checksums:r.storedChecksums,fetcher:l,project:r,report:o,skipIntegrityCheck:!0,cacheOptions:{skipIntegrityCheck:!0}},u={project:r,resolver:a,report:o,fetchOptions:c};return await n.startTimerPromise("Deduplication step",async()=>{let f=await D3e[e](r,t,{resolver:a,resolveOptions:u,fetcher:l,fetchOptions:c}),h=Ji.progressViaCounter(f.length);n.reportProgress(h);let p=0;await Promise.all(f.map(b=>b.then(v=>{if(v===null)return;p++;let{descriptor:x,currentPackage:T,updatedPackage:q}=v;n.reportInfo(X.UNNAMED,`${P.prettyDescriptor(s,x)} can be deduped from ${P.prettyLocator(s,T)} to ${P.prettyLocator(s,q)}`),n.reportJson({descriptor:P.stringifyDescriptor(x),currentResolution:P.stringifyLocator(T),updatedResolution:P.stringifyLocator(q)}),r.storedResolutions.set(x.descriptorHash,q.locatorHash)}).finally(()=>h.tick())));let m;switch(p){case 0:m="No packages";break;case 1:m="One package";break;default:m=`${p} packages`}let y=ae.pretty(s,e,ae.Type.CODE);return n.reportInfo(X.UNNAMED,`${m} can be deduped using the ${y} strategy`),p})}var nm=class extends Le{constructor(){super(...arguments);this.strategy=J.String("-s,--strategy",Bu.HIGHEST,{description:"The strategy to use when deduping dependencies",validator:nn(Bu)});this.check=J.Boolean("-c,--check",!1,{description:"Exit with exit code 1 when duplicates are found, without persisting the dependency tree"});this.json=J.Boolean("--json",!1,{description:"Format the output as an NDJSON stream"});this.mode=J.String("--mode",{description:"Change what artifacts installs generate",validator:nn(Ci)});this.patterns=J.Rest()}async execute(){let e=await ye.find(this.context.cwd,this.context.plugins),{project:t}=await ze.find(e,this.context.cwd),i=await Nt.find(e);await t.restoreInstallState({restoreResolutions:!1});let n=0,s=await Je.start({configuration:e,includeFooter:!1,stdout:this.context.stdout,json:this.json},async o=>{n=await BN(t,{strategy:this.strategy,patterns:this.patterns,cache:i,report:o})});return s.hasErrors()?s.exitCode():this.check?n?1:0:(await Je.start({configuration:e,stdout:this.context.stdout,json:this.json},async a=>{await t.install({cache:i,report:a,mode:this.mode})})).exitCode()}};nm.paths=[["dedupe"]],nm.usage=Re.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 hoe=nm;var J0=class extends Le{async execute(){let{plugins:e}=await ye.find(this.context.cwd,this.context.plugins),t=[];for(let o of e){let{commands:a}=o[1];if(a){let c=ws.from(a).definitions();t.push([o[0],c])}}let i=this.cli.definitions(),n=(o,a)=>o.split(" ").slice(1).join()===a.split(" ").slice(1).join(),s=doe()["@yarnpkg/builder"].bundles.standard;for(let o of t){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)} -`)}};J0.paths=[["--clipanion=definitions"]];var Coe=J0;var W0=class extends Le{async execute(){this.context.stdout.write(this.cli.usage(null))}};W0.paths=[["help"],["--help"],["-h"]];var moe=W0;var bN=class extends Le{constructor(){super(...arguments);this.leadingArgument=J.String();this.args=J.Proxy()}async execute(){if(this.leadingArgument.match(/[\\/]/)&&!P.tryParseIdent(this.leadingArgument)){let e=k.resolve(this.context.cwd,H.toPortablePath(this.leadingArgument));return await this.cli.run(this.args,{cwd:e})}else return await this.cli.run(["run",this.leadingArgument,...this.args])}},Eoe=bN;var z0=class extends Le{async execute(){this.context.stdout.write(`${Ur||""} -`)}};z0.paths=[["-v"],["--version"]];var Ioe=z0;var sm=class extends Le{constructor(){super(...arguments);this.commandName=J.String();this.args=J.Proxy()}async execute(){let e=await ye.find(this.context.cwd,this.context.plugins),{project:t,locator:i}=await ze.find(e,this.context.cwd);return await t.restoreInstallState(),await Zt.executePackageShellcode(i,this.commandName,this.args,{cwd:this.context.cwd,stdin:this.context.stdin,stdout:this.context.stdout,stderr:this.context.stderr,project:t})}};sm.paths=[["exec"]],sm.usage=Re.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 yoe=sm;ys();var om=class extends Le{constructor(){super(...arguments);this.hash=J.String({required:!1,validator:fp(gp(),[hp(/^p[0-9a-f]{5}$/)])})}async execute(){let e=await ye.find(this.context.cwd,this.context.plugins),{project:t}=await ze.find(e,this.context.cwd);return await t.restoreInstallState({restoreResolutions:!1}),await t.applyLightResolution(),typeof this.hash!="undefined"?await R3e(this.hash,t,{stdout:this.context.stdout}):(await Je.start({configuration:e,stdout:this.context.stdout,includeFooter:!1},async n=>{var o;let s=[([,a])=>P.stringifyLocator(t.storedPackages.get(a.subject)),([,a])=>P.stringifyIdent(a.requested)];for(let[a,l]of Se.sortMap(t.peerRequirements,s)){let c=t.storedPackages.get(l.subject);if(typeof c=="undefined")throw new Error("Assertion failed: Expected the subject package to have been registered");let u=t.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=ae.pretty(e,a,ae.Type.CODE),h=P.prettyLocator(e,c),p=P.prettyIdent(e,l.requested),m=P.prettyIdent(e,u),y=l.allRequesters.length-1,b=`descendant${y===1?"":"s"}`,v=y>0?` and ${y} ${b}`:"",x=g!==null?"provides":"doesn't provide";n.reportInfo(null,`${f} \u2192 ${h} ${x} ${p} to ${m}${v}`)}})).exitCode()}};om.paths=[["explain","peer-requirements"]],om.usage=Re.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 woe=om;async function R3e(r,e,t){let{configuration:i}=e,n=e.peerRequirements.get(r);if(typeof n=="undefined")throw new Error(`No peerDependency requirements found for hash: "${r}"`);return(await Je.start({configuration:i,stdout:t.stdout,includeFooter:!1},async o=>{var b,v;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=(b=a.dependencies.get(n.requested.identHash))!=null?b: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(x=>{let T=e.storedPackages.get(x);if(typeof T=="undefined")throw new Error("Assertion failed: Expected the package to be registered");let q=P.devirtualizeLocator(T),Y=e.storedPackages.get(q.locatorHash);if(typeof Y=="undefined")throw new Error("Assertion failed: Expected the package to be registered");let $=Y.peerDependencies.get(n.requested.identHash);if(typeof $=="undefined")throw new Error("Assertion failed: Expected the peer dependency to be registered");return{pkg:T,peerDependency:$}});if(g!==null){let x=f.every(({peerDependency:T})=>Wt.satisfiesWithPrereleases(g.version,T.range));o.reportInfo(X.UNNAMED,`${P.prettyLocator(i,a)} provides ${P.prettyLocator(i,g)} with version ${P.prettyReference(i,(v=g.version)!=null?v:"")}, which ${x?"satisfies":"doesn't satisfy"} the following requirements:`)}else o.reportInfo(X.UNNAMED,`${P.prettyLocator(i,a)} doesn't provide ${P.prettyIdent(i,n.requested)}, breaking the following requirements:`);o.reportSeparator();let h=ae.mark(i),p=[];for(let{pkg:x,peerDependency:T}of Se.sortMap(f,q=>P.stringifyLocator(q.pkg))){let Y=(g!==null?Wt.satisfiesWithPrereleases(g.version,T.range):!1)?h.Check:h.Cross;p.push({stringifiedLocator:P.stringifyLocator(x),prettyLocator:P.prettyLocator(i,x),prettyRange:P.prettyRange(i,T.range),mark:Y})}let m=Math.max(...p.map(({stringifiedLocator:x})=>x.length)),y=Math.max(...p.map(({prettyRange:x})=>x.length));for(let{stringifiedLocator:x,prettyLocator:T,prettyRange:q,mark:Y}of Se.sortMap(p,({stringifiedLocator:$})=>$))o.reportInfo(null,`${T.padEnd(m+(T.length-x.length)," ")} \u2192 ${q.padEnd(y," ")} ${Y}`);p.length>1&&(o.reportSeparator(),o.reportInfo(X.UNNAMED,`Note: these requirements start with ${P.prettyLocator(e.configuration,l)}`))})).exitCode()}ys();var Boe=ge(ri()),am=class extends Le{constructor(){super(...arguments);this.onlyIfNeeded=J.Boolean("--only-if-needed",!1,{description:"Only lock the Yarn version if it isn't already locked"});this.version=J.String()}async execute(){let e=await ye.find(this.context.cwd,this.context.plugins);if(e.get("yarnPath")&&this.onlyIfNeeded)return 0;let t=()=>{if(typeof Ur=="undefined")throw new Pe("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=t();else if(this.version==="latest"||this.version==="berry"||this.version==="stable")i=`https://repo.yarnpkg.com/${await Am(e,"stable")}/packages/yarnpkg-cli/bin/yarn.js`;else if(this.version==="canary")i=`https://repo.yarnpkg.com/${await Am(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(/^https?:/))i=this.version;else if(this.version.match(/^\.{0,2}[\\/]/)||H.isAbsolute(this.version))i=`file://${H.resolve(this.version)}`;else if(Wt.satisfiesWithPrereleases(this.version,">=2.0.0"))i=`https://repo.yarnpkg.com/${this.version}/packages/yarnpkg-cli/bin/yarn.js`;else if(Wt.satisfiesWithPrereleases(this.version,"^0.x || ^1.x"))i=`https://github.com/yarnpkg/yarn/releases/download/v${this.version}/yarn-${this.version}.js`;else if(Wt.validRange(this.version))i=`https://repo.yarnpkg.com/${await F3e(e,this.version)}/packages/yarnpkg-cli/bin/yarn.js`;else throw new Pe(`Invalid version descriptor "${this.version}"`);return(await Je.start({configuration:e,stdout:this.context.stdout,includeLogs:!this.context.quiet},async s=>{let o="file://",a;i.startsWith(o)?(s.reportInfo(X.UNNAMED,`Downloading ${ae.pretty(e,i,Ri.URL)}`),a=await K.readFilePromise(H.toPortablePath(i.slice(o.length)))):(s.reportInfo(X.UNNAMED,`Retrieving ${ae.pretty(e,i,Ri.PATH)}`),a=await ir.get(i,{configuration:e})),await QN(e,null,a,{report:s})})).exitCode()}};am.paths=[["set","version"]],am.usage=Re.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"],["Use a release from a URL","$0 set version https://repo.yarnpkg.com/3.1.0/packages/yarnpkg-cli/bin/yarn.js"],["Download the version used to invoke the command","$0 set version self"]]});var boe=am;async function F3e(r,e){let i=(await ir.get("https://repo.yarnpkg.com/tags",{configuration:r,jsonResponse:!0})).tags.filter(n=>Wt.satisfiesWithPrereleases(n,e));if(i.length===0)throw new Pe(`No matching release found for range ${ae.pretty(r,e,ae.Type.RANGE)}.`);return i[0]}async function Am(r,e){let t=await ir.get("https://repo.yarnpkg.com/tags",{configuration:r,jsonResponse:!0});if(!t.latest[e])throw new Pe(`Tag ${ae.pretty(r,e,ae.Type.RANGE)} not found`);return t.latest[e]}async function QN(r,e,t,{report:i}){var g;e===null&&await K.mktempPromise(async f=>{let h=k.join(f,"yarn.cjs");await K.writeFilePromise(h,t);let{stdout:p}=await Nr.execvp(process.execPath,[H.fromPortablePath(h),"--version"],{cwd:f,env:te(N({},process.env),{YARN_IGNORE_PATH:"1"})});if(e=p.trim(),!Boe.default.valid(e))throw new Error(`Invalid semver version. ${ae.pretty(r,"yarn --version",ae.Type.CODE)} returned: -${e}`)});let n=(g=r.projectCwd)!=null?g:r.startingCwd,s=k.resolve(n,".yarn/releases"),o=k.resolve(s,`yarn-${e}.cjs`),a=k.relative(r.startingCwd,o),l=k.relative(n,o),c=r.get("yarnPath"),u=c===null||c.startsWith(`${s}/`);if(i.reportInfo(X.UNNAMED,`Saving the new release in ${ae.pretty(r,a,"magenta")}`),await K.removePromise(k.dirname(o)),await K.mkdirPromise(k.dirname(o),{recursive:!0}),await K.writeFilePromise(o,t,{mode:493}),u){await ye.updateConfiguration(n,{yarnPath:l});let f=await At.tryFind(n)||new At;f.packageManager=`yarn@${e&&Se.isTaggedYarnVersion(e)?e:await Am(r,"stable")}`;let h={};f.exportTo(h);let p=k.join(n,At.fileName),m=`${JSON.stringify(h,null,f.indent)} -`;await K.changeFilePromise(p,m,{automaticNewlines:!0})}}function Qoe(r){return X[II(r)]}var N3e=/## (?YN[0-9]{4}) - `(?[A-Z_]+)`\n\n(?
(?:.(?!##))+)/gs;async function L3e(r){let t=`https://repo.yarnpkg.com/${Se.isTaggedYarnVersion(Ur)?Ur:await Am(r,"canary")}/packages/gatsby/content/advanced/error-codes.md`,i=await ir.get(t,{configuration:r});return new Map(Array.from(i.toString().matchAll(N3e),({groups:n})=>{if(!n)throw new Error("Assertion failed: Expected the match to have been successful");let s=Qoe(n.code);if(n.name!==s)throw new Error(`Assertion failed: Invalid error code data: Expected "${n.name}" to be named "${s}"`);return[n.code,n.details]}))}var lm=class extends Le{constructor(){super(...arguments);this.code=J.String({required:!1,validator:fp(gp(),[hp(/^YN[0-9]{4}$/)])});this.json=J.Boolean("--json",!1,{description:"Format the output as an NDJSON stream"})}async execute(){let e=await ye.find(this.context.cwd,this.context.plugins);if(typeof this.code!="undefined"){let t=Qoe(this.code),i=ae.pretty(e,t,ae.Type.CODE),n=this.cli.format().header(`${this.code} - ${i}`),o=(await L3e(e)).get(this.code),a=typeof o!="undefined"?ae.jsonOrPretty(this.json,e,ae.tuple(ae.Type.MARKDOWN,{text:o,format:this.cli.format(),paragraphs:!0})):`This error code does not have a description. - -You can help us by editing this page on GitHub \u{1F642}: -${ae.jsonOrPretty(this.json,e,ae.tuple(ae.Type.URL,"https://github.com/yarnpkg/berry/blob/master/packages/gatsby/content/advanced/error-codes.md"))} -`;this.json?this.context.stdout.write(`${JSON.stringify({code:this.code,name:t,details:a})} -`):this.context.stdout.write(`${n} - -${a} -`)}else{let t={children:Se.mapAndFilter(Object.entries(X),([i,n])=>Number.isNaN(Number(i))?Se.mapAndFilter.skip:{label:_A(Number(i)),value:ae.tuple(ae.Type.CODE,n)})};ls.emitTree(t,{configuration:e,stdout:this.context.stdout,json:this.json})}}};lm.paths=[["explain"]],lm.usage=Re.Usage({description:"explain an error code",details:` - When the code argument is specified, this command prints its name and its details. - - When used without arguments, this command lists all error codes and their names. - `,examples:[["Explain an error code","$0 explain YN0006"],["List all error codes","$0 explain"]]});var Soe=lm;var voe=ge(is()),cm=class extends Le{constructor(){super(...arguments);this.all=J.Boolean("-A,--all",!1,{description:"Print versions of a package from the whole project"});this.recursive=J.Boolean("-R,--recursive",!1,{description:"Print information for all packages, including transitive dependencies"});this.extra=J.Array("-X,--extra",[],{description:"An array of requests of extra data provided by plugins"});this.cache=J.Boolean("--cache",!1,{description:"Print information about the cache entry of a package (path, size, checksum)"});this.dependents=J.Boolean("--dependents",!1,{description:"Print all dependents for each matching package"});this.manifest=J.Boolean("--manifest",!1,{description:"Print data obtained by looking at the package archive (license, homepage, ...)"});this.nameOnly=J.Boolean("--name-only",!1,{description:"Only print the name for the matching packages"});this.virtuals=J.Boolean("--virtuals",!1,{description:"Print each instance of the virtual packages"});this.json=J.Boolean("--json",!1,{description:"Format the output as an NDJSON stream"});this.patterns=J.Rest()}async execute(){let e=await ye.find(this.context.cwd,this.context.plugins),{project:t,workspace:i}=await ze.find(e,this.context.cwd),n=await Nt.find(e);if(!i&&!this.all)throw new ht(t.cwd,this.context.cwd);await t.restoreInstallState();let s=new Set(this.extra);this.cache&&s.add("cache"),this.dependents&&s.add("dependents"),this.manifest&&s.add("manifest");let o=(x,{recursive:T})=>{let q=x.anchoredLocator.locatorHash,Y=new Map,$=[q];for(;$.length>0;){let _=$.shift();if(Y.has(_))continue;let ne=t.storedPackages.get(_);if(typeof ne=="undefined")throw new Error("Assertion failed: Expected the package to be registered");if(Y.set(_,ne),P.isVirtualLocator(ne)&&$.push(P.devirtualizeLocator(ne).locatorHash),!(!T&&_!==q))for(let ee of ne.dependencies.values()){let A=t.storedResolutions.get(ee.descriptorHash);if(typeof A=="undefined")throw new Error("Assertion failed: Expected the resolution to be registered");$.push(A)}}return Y.values()},a=({recursive:x})=>{let T=new Map;for(let q of t.workspaces)for(let Y of o(q,{recursive:x}))T.set(Y.locatorHash,Y);return T.values()},l=({all:x,recursive:T})=>x&&T?t.storedPackages.values():x?a({recursive:T}):o(i,{recursive:T}),c=({all:x,recursive:T})=>{let q=l({all:x,recursive:T}),Y=this.patterns.map(ne=>{let ee=P.parseLocator(ne),A=voe.default.makeRe(P.stringifyIdent(ee)),oe=P.isVirtualLocator(ee),ce=oe?P.devirtualizeLocator(ee):ee;return Z=>{let O=P.stringifyIdent(Z);if(!A.test(O))return!1;if(ee.reference==="unknown")return!0;let L=P.isVirtualLocator(Z),de=L?P.devirtualizeLocator(Z):Z;return!(oe&&L&&ee.reference!==Z.reference||ce.reference!==de.reference)}}),$=Se.sortMap([...q],ne=>P.stringifyLocator(ne));return{selection:$.filter(ne=>Y.length===0||Y.some(ee=>ee(ne))),sortedLookup:$}},{selection:u,sortedLookup:g}=c({all:this.all,recursive:this.recursive});if(u.length===0)throw new Pe("No package matched your request");let f=new Map;if(this.dependents)for(let x of g)for(let T of x.dependencies.values()){let q=t.storedResolutions.get(T.descriptorHash);if(typeof q=="undefined")throw new Error("Assertion failed: Expected the resolution to be registered");Se.getArrayWithDefault(f,q).push(x)}let h=new Map;for(let x of g){if(!P.isVirtualLocator(x))continue;let T=P.devirtualizeLocator(x);Se.getArrayWithDefault(h,T.locatorHash).push(x)}let p={},m={children:p},y=e.makeFetcher(),b={project:t,fetcher:y,cache:n,checksums:t.storedChecksums,report:new di,cacheOptions:{skipIntegrityCheck:!0},skipIntegrityCheck:!0},v=[async(x,T,q)=>{var _,ne;if(!T.has("manifest"))return;let Y=await y.fetch(x,b),$;try{$=await At.find(Y.prefixPath,{baseFs:Y.packageFs})}finally{(_=Y.releaseFs)==null||_.call(Y)}q("Manifest",{License:ae.tuple(ae.Type.NO_HINT,$.license),Homepage:ae.tuple(ae.Type.URL,(ne=$.raw.homepage)!=null?ne:null)})},async(x,T,q)=>{var A;if(!T.has("cache"))return;let Y={mockedPackages:t.disabledLocators,unstablePackages:t.conditionalLocators},$=(A=t.storedChecksums.get(x.locatorHash))!=null?A:null,_=n.getLocatorPath(x,$,Y),ne;if(_!==null)try{ne=K.statSync(_)}catch{}let ee=typeof ne!="undefined"?[ne.size,ae.Type.SIZE]:void 0;q("Cache",{Checksum:ae.tuple(ae.Type.NO_HINT,$),Path:ae.tuple(ae.Type.PATH,_),Size:ee})}];for(let x of u){let T=P.isVirtualLocator(x);if(!this.virtuals&&T)continue;let q={},Y={value:[x,ae.Type.LOCATOR],children:q};if(p[P.stringifyLocator(x)]=Y,this.nameOnly){delete Y.children;continue}let $=h.get(x.locatorHash);typeof $!="undefined"&&(q.Instances={label:"Instances",value:ae.tuple(ae.Type.NUMBER,$.length)}),q.Version={label:"Version",value:ae.tuple(ae.Type.NO_HINT,x.version)};let _=(ee,A)=>{let oe={};if(q[ee]=oe,Array.isArray(A))oe.children=A.map(ce=>({value:ce}));else{let ce={};oe.children=ce;for(let[Z,O]of Object.entries(A))typeof O!="undefined"&&(ce[Z]={label:Z,value:O})}};if(!T){for(let ee of v)await ee(x,s,_);await e.triggerHook(ee=>ee.fetchPackageInfo,x,s,_)}x.bin.size>0&&!T&&_("Exported Binaries",[...x.bin.keys()].map(ee=>ae.tuple(ae.Type.PATH,ee)));let ne=f.get(x.locatorHash);typeof ne!="undefined"&&ne.length>0&&_("Dependents",ne.map(ee=>ae.tuple(ae.Type.LOCATOR,ee))),x.dependencies.size>0&&!T&&_("Dependencies",[...x.dependencies.values()].map(ee=>{var ce;let A=t.storedResolutions.get(ee.descriptorHash),oe=typeof A!="undefined"&&(ce=t.storedPackages.get(A))!=null?ce:null;return ae.tuple(ae.Type.RESOLUTION,{descriptor:ee,locator:oe})})),x.peerDependencies.size>0&&T&&_("Peer dependencies",[...x.peerDependencies.values()].map(ee=>{var Z,O;let A=x.dependencies.get(ee.identHash),oe=typeof A!="undefined"&&(Z=t.storedResolutions.get(A.descriptorHash))!=null?Z:null,ce=oe!==null&&(O=t.storedPackages.get(oe))!=null?O:null;return ae.tuple(ae.Type.RESOLUTION,{descriptor:ee,locator:ce})}))}ls.emitTree(m,{configuration:e,json:this.json,stdout:this.context.stdout,separators:this.nameOnly?0:2})}};cm.paths=[["info"]],cm.usage=Re.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 xoe=cm;var _0=ge(Ic());ys();var um=class extends Le{constructor(){super(...arguments);this.json=J.Boolean("--json",!1,{description:"Format the output as an NDJSON stream"});this.immutable=J.Boolean("--immutable",{description:"Abort with an error exit code if the lockfile was to be modified"});this.immutableCache=J.Boolean("--immutable-cache",{description:"Abort with an error exit code if the cache folder was to be modified"});this.checkCache=J.Boolean("--check-cache",!1,{description:"Always refetch the packages and ensure that their checksums are consistent"});this.inlineBuilds=J.Boolean("--inline-builds",{description:"Verbosely print the output of the build steps of dependencies"});this.mode=J.String("--mode",{description:"Change what artifacts installs generate",validator:nn(Ci)});this.cacheFolder=J.String("--cache-folder",{hidden:!0});this.frozenLockfile=J.Boolean("--frozen-lockfile",{hidden:!0});this.ignoreEngines=J.Boolean("--ignore-engines",{hidden:!0});this.nonInteractive=J.Boolean("--non-interactive",{hidden:!0});this.preferOffline=J.Boolean("--prefer-offline",{hidden:!0});this.production=J.Boolean("--production",{hidden:!0});this.registry=J.String("--registry",{hidden:!0});this.silent=J.Boolean("--silent",{hidden:!0});this.networkTimeout=J.String("--network-timeout",{hidden:!0})}async execute(){var g;let e=await ye.find(this.context.cwd,this.context.plugins);typeof this.inlineBuilds!="undefined"&&e.useWithSource("",{enableInlineBuilds:this.inlineBuilds},e.startingCwd,{overwrite:!0});let t=!!process.env.FUNCTION_TARGET||!!process.env.GOOGLE_RUNTIME,i=async(f,{error:h})=>{let p=await Je.start({configuration:e,stdout:this.context.stdout,includeFooter:!1},async m=>{h?m.reportError(X.DEPRECATED_CLI_SETTINGS,f):m.reportWarning(X.DEPRECATED_CLI_SETTINGS,f)});return p.hasErrors()?p.exitCode():null};if(typeof this.ignoreEngines!="undefined"){let f=await i("The --ignore-engines option is deprecated; engine checking isn't a core feature anymore",{error:!_0.default.VERCEL});if(f!==null)return f}if(typeof this.registry!="undefined"){let f=await i("The --registry option is deprecated; prefer setting npmRegistryServer in your .yarnrc.yml file",{error:!1});if(f!==null)return f}if(typeof this.preferOffline!="undefined"){let f=await i("The --prefer-offline flag is deprecated; use the --cached flag with 'yarn add' instead",{error:!_0.default.VERCEL});if(f!==null)return f}if(typeof this.production!="undefined"){let f=await i("The --production option is deprecated on 'install'; use 'yarn workspaces focus' instead",{error:!0});if(f!==null)return f}if(typeof this.nonInteractive!="undefined"){let f=await i("The --non-interactive option is deprecated",{error:!t});if(f!==null)return f}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 f=await i("The cache-folder option has been deprecated; use rc settings instead",{error:!_0.default.NETLIFY});if(f!==null)return f}let n=this.mode===Ci.UpdateLockfile;if(n&&(this.immutable||this.immutableCache))throw new Pe(`${ae.pretty(e,"--immutable",ae.Type.CODE)} and ${ae.pretty(e,"--immutable-cache",ae.Type.CODE)} cannot be used with ${ae.pretty(e,"--mode=update-lockfile",ae.Type.CODE)}`);let s=((g=this.immutable)!=null?g:e.get("enableImmutableInstalls"))&&!n,o=this.immutableCache&&!n;if(e.projectCwd!==null){let f=await Je.start({configuration:e,json:this.json,stdout:this.context.stdout,includeFooter:!1},async h=>{await T3e(e,s)&&(h.reportInfo(X.AUTOMERGE_SUCCESS,"Automatically fixed merge conflicts \u{1F44D}"),h.reportSeparator())});if(f.hasErrors())return f.exitCode()}if(e.projectCwd!==null&&typeof e.sources.get("nodeLinker")=="undefined"){let f=e.projectCwd,h;try{h=await K.readFilePromise(k.join(f,kt.lockfile),"utf8")}catch{}if(h==null?void 0:h.includes("yarn lockfile v1")){let p=await Je.start({configuration:e,json:this.json,stdout:this.context.stdout,includeFooter:!1},async m=>{m.reportInfo(X.AUTO_NM_SUCCESS,"Migrating from Yarn 1; automatically enabling the compatibility node-modules linker \u{1F44D}"),m.reportSeparator(),e.use("",{nodeLinker:"node-modules"},f,{overwrite:!0}),await ye.updateConfiguration(f,{nodeLinker:"node-modules"})});if(p.hasErrors())return p.exitCode()}}if(e.projectCwd!==null){let f=await Je.start({configuration:e,json:this.json,stdout:this.context.stdout,includeFooter:!1},async h=>{var p;((p=ye.telemetry)==null?void 0:p.isNew)&&(h.reportInfo(X.TELEMETRY_NOTICE,"Yarn will periodically gather anonymous telemetry: https://yarnpkg.com/advanced/telemetry"),h.reportInfo(X.TELEMETRY_NOTICE,`Run ${ae.pretty(e,"yarn config set --home enableTelemetry 0",ae.Type.CODE)} to disable`),h.reportSeparator())});if(f.hasErrors())return f.exitCode()}let{project:a,workspace:l}=await ze.find(e,this.context.cwd),c=await Nt.find(e,{immutable:o,check:this.checkCache});if(!l)throw new ht(a.cwd,this.context.cwd);return await a.restoreInstallState({restoreResolutions:!1}),(await Je.start({configuration:e,json:this.json,stdout:this.context.stdout,includeLogs:!0},async f=>{await a.install({cache:c,report:f,immutable:s,mode:this.mode})})).exitCode()}};um.paths=[["install"],Re.Default],um.usage=Re.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 koe=um,O3e="|||||||",M3e=">>>>>>>",K3e="=======",Poe="<<<<<<<";async function T3e(r,e){if(!r.projectCwd)return!1;let t=k.join(r.projectCwd,r.get("lockfileFilename"));if(!await K.existsPromise(t))return!1;let i=await K.readFilePromise(t,"utf8");if(!i.includes(Poe))return!1;if(e)throw new ct(X.AUTOMERGE_IMMUTABLE,"Cannot autofix a lockfile when running an immutable install");let[n,s]=U3e(i),o,a;try{o=Si(n),a=Si(s)}catch(c){throw new ct(X.AUTOMERGE_FAILED_TO_PARSE,"The individual variants of the lockfile failed to parse")}let l=N(N({},o),a);for(let[c,u]of Object.entries(l))typeof u=="string"&&delete l[c];return await K.changeFilePromise(t,Ma(l),{automaticNewlines:!0}),!0}function U3e(r){let e=[[],[]],t=r.split(/\r?\n/g),i=!1;for(;t.length>0;){let n=t.shift();if(typeof n=="undefined")throw new Error("Assertion failed: Some lines should remain");if(n.startsWith(Poe)){for(;t.length>0;){let s=t.shift();if(typeof s=="undefined")throw new Error("Assertion failed: Some lines should remain");if(s===K3e){i=!1;break}else if(i||s.startsWith(O3e)){i=!0;continue}else e[0].push(s)}for(;t.length>0;){let s=t.shift();if(typeof s=="undefined")throw new Error("Assertion failed: Some lines should remain");if(s.startsWith(M3e))break;e[1].push(s)}}else e[0].push(n),e[1].push(n)}return[e[0].join(` -`),e[1].join(` -`)]}var gm=class extends Le{constructor(){super(...arguments);this.all=J.Boolean("-A,--all",!1,{description:"Link all workspaces belonging to the target project to the current one"});this.private=J.Boolean("-p,--private",!1,{description:"Also link private workspaces belonging to the target project to the current one"});this.relative=J.Boolean("-r,--relative",!1,{description:"Link workspaces using relative paths instead of absolute paths"});this.destination=J.String()}async execute(){let e=await ye.find(this.context.cwd,this.context.plugins),{project:t,workspace:i}=await ze.find(e,this.context.cwd),n=await Nt.find(e);if(!i)throw new ht(t.cwd,this.context.cwd);await t.restoreInstallState({restoreResolutions:!1});let s=k.resolve(this.context.cwd,H.toPortablePath(this.destination)),o=await ye.find(s,this.context.plugins,{useRc:!1,strict:!1}),{project:a,workspace:l}=await ze.find(o,s);if(t.cwd===a.cwd)throw new Pe("Invalid destination; Can't link the project to itself");if(!l)throw new ht(a.cwd,s);let c=t.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 Pe("No workspace found to be linked in the target project")}else{if(!l.manifest.name)throw new Pe("The target workspace doesn't have a name and thus cannot be linked");if(l.manifest.private&&!this.private)throw new Pe("The target workspace is marked private - use the --private flag to link it anyway");u.push(l)}for(let f of u){let h=P.stringifyIdent(f.locator),p=this.relative?k.relative(t.cwd,f.cwd):f.cwd;c.manifest.resolutions.push({pattern:{descriptor:{fullName:h}},reference:`portal:${p}`})}return(await Je.start({configuration:e,stdout:this.context.stdout},async f=>{await t.install({cache:n,report:f})})).exitCode()}};gm.paths=[["link"]],gm.usage=Re.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 Doe=gm;var fm=class extends Le{constructor(){super(...arguments);this.args=J.Proxy()}async execute(){return this.cli.run(["exec","node",...this.args])}};fm.paths=[["node"]],fm.usage=Re.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 Roe=fm;var Hoe=ge(require("os"));var Noe=ge(require("os"));var H3e="https://raw.githubusercontent.com/yarnpkg/berry/master/plugins.yml";async function bu(r){let e=await ir.get(H3e,{configuration:r});return Si(e.toString())}var hm=class extends Le{constructor(){super(...arguments);this.json=J.Boolean("--json",!1,{description:"Format the output as an NDJSON stream"})}async execute(){let e=await ye.find(this.context.cwd,this.context.plugins);return(await Je.start({configuration:e,json:this.json,stdout:this.context.stdout},async i=>{let n=await bu(e);for(let s of Object.entries(n)){let[l,o]=s,a=o,{experimental:c}=a,u=Or(a,["experimental"]);let g=l;c&&(g+=" [experimental]"),i.reportJson(N({name:l,experimental:c},u)),i.reportInfo(null,g)}})).exitCode()}};hm.paths=[["plugin","list"]],hm.usage=Re.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 Foe=hm;var j3e=/^[0-9]+$/;function Loe(r){return j3e.test(r)?`pull/${r}/head`:r}var G3e=({repository:r,branch:e},t)=>[["git","init",H.fromPortablePath(t)],["git","remote","add","origin",r],["git","fetch","origin","--depth=1",Loe(e)],["git","reset","--hard","FETCH_HEAD"]],Y3e=({branch:r})=>[["git","fetch","origin","--depth=1",Loe(r),"--force"],["git","reset","--hard","FETCH_HEAD"],["git","clean","-dfx"]],q3e=({plugins:r,noMinify:e},t)=>[["yarn","build:cli",...new Array().concat(...r.map(i=>["--plugin",k.resolve(t,i)])),...e?["--no-minify"]:[],"|"]],pm=class extends Le{constructor(){super(...arguments);this.installPath=J.String("--path",{description:"The path where the repository should be cloned to"});this.repository=J.String("--repository","https://github.com/yarnpkg/berry.git",{description:"The repository that should be cloned"});this.branch=J.String("--branch","master",{description:"The branch of the repository that should be cloned"});this.plugins=J.Array("--plugin",[],{description:"An array of additional plugins that should be included in the bundle"});this.noMinify=J.Boolean("--no-minify",!1,{description:"Build a bundle for development (debugging) - non-minified and non-mangled"});this.force=J.Boolean("-f,--force",!1,{description:"Always clone the repository instead of trying to fetch the latest commits"});this.skipPlugins=J.Boolean("--skip-plugins",!1,{description:"Skip updating the contrib plugins"})}async execute(){let e=await ye.find(this.context.cwd,this.context.plugins),{project:t}=await ze.find(e,this.context.cwd),i=typeof this.installPath!="undefined"?k.resolve(this.context.cwd,H.toPortablePath(this.installPath)):k.resolve(H.toPortablePath((0,Noe.tmpdir)()),"yarnpkg-sources",Dn.makeHash(this.repository).slice(0,6));return(await Je.start({configuration:e,stdout:this.context.stdout},async s=>{await vN(this,{configuration:e,report:s,target:i}),s.reportSeparator(),s.reportInfo(X.UNNAMED,"Building a fresh bundle"),s.reportSeparator(),await dm(q3e(this,i),{configuration:e,context:this.context,target:i}),s.reportSeparator();let o=k.resolve(i,"packages/yarnpkg-cli/bundles/yarn.js"),a=await K.readFilePromise(o);await QN(e,"sources",a,{report:s}),this.skipPlugins||await J3e(this,{project:t,report:s,target:i})})).exitCode()}};pm.paths=[["set","version","from","sources"]],pm.usage=Re.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 Toe=pm;async function dm(r,{configuration:e,context:t,target:i}){for(let[n,...s]of r){let o=s[s.length-1]==="|";if(o&&s.pop(),o)await Nr.pipevp(n,s,{cwd:i,stdin:t.stdin,stdout:t.stdout,stderr:t.stderr,strict:!0});else{t.stdout.write(`${ae.pretty(e,` $ ${[n,...s].join(" ")}`,"grey")} -`);try{await Nr.execvp(n,s,{cwd:i,strict:!0})}catch(a){throw t.stdout.write(a.stdout||a.stack),a}}}}async function vN(r,{configuration:e,report:t,target:i}){let n=!1;if(!r.force&&K.existsSync(k.join(i,".git"))){t.reportInfo(X.UNNAMED,"Fetching the latest commits"),t.reportSeparator();try{await dm(Y3e(r),{configuration:e,context:r.context,target:i}),n=!0}catch(s){t.reportSeparator(),t.reportWarning(X.UNNAMED,"Repository update failed; we'll try to regenerate it")}}n||(t.reportInfo(X.UNNAMED,"Cloning the remote repository"),t.reportSeparator(),await K.removePromise(i),await K.mkdirPromise(i,{recursive:!0}),await dm(G3e(r,i),{configuration:e,context:r.context,target:i}))}async function J3e(r,{project:e,report:t,target:i}){let n=await bu(e.configuration),s=new Set(Object.keys(n));for(let o of e.configuration.plugins.keys())!s.has(o)||await SN(o,r,{project:e,report:t,target:i})}var Ooe=ge(ri()),Moe=ge(require("url")),Koe=ge(require("vm"));var Cm=class extends Le{constructor(){super(...arguments);this.name=J.String()}async execute(){let e=await ye.find(this.context.cwd,this.context.plugins);return(await Je.start({configuration:e,stdout:this.context.stdout},async i=>{let{project:n}=await ze.find(e,this.context.cwd),s,o;if(this.name.match(/^\.{0,2}[\\/]/)||H.isAbsolute(this.name)){let a=k.resolve(this.context.cwd,H.toPortablePath(this.name));i.reportInfo(X.UNNAMED,`Reading ${ae.pretty(e,a,ae.Type.PATH)}`),s=k.relative(n.cwd,a),o=await K.readFilePromise(a)}else{let a;if(this.name.match(/^https?:/)){try{new Moe.URL(this.name)}catch{throw new ct(X.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=P.parseLocator(this.name.replace(/^((@yarnpkg\/)?plugin-)?/,"@yarnpkg/plugin-"));if(l.reference!=="unknown"&&!Ooe.default.valid(l.reference))throw new ct(X.UNNAMED,"Official plugins only accept strict version references. Use an explicit URL if you wish to download them from another location.");let c=P.stringifyIdent(l),u=await bu(e);if(!Object.prototype.hasOwnProperty.call(u,c))throw new ct(X.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}/`):Ur!==null&&(a=a.replace(/\/master\//,`/@yarnpkg/cli/${Ur}/`))}i.reportInfo(X.UNNAMED,`Downloading ${ae.pretty(e,a,"green")}`),o=await ir.get(a,{configuration:e})}await xN(s,o,{project:n,report:i})})).exitCode()}};Cm.paths=[["plugin","import"]],Cm.usage=Re.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 Uoe=Cm;async function xN(r,e,{project:t,report:i}){let{configuration:n}=t,s={},o={exports:s};(0,Koe.runInNewContext)(e.toString(),{module:o,exports:s});let a=o.exports.name,l=`.yarn/plugins/${a}.cjs`,c=k.resolve(t.cwd,l);i.reportInfo(X.UNNAMED,`Saving the new plugin in ${ae.pretty(n,l,"magenta")}`),await K.mkdirPromise(k.dirname(c),{recursive:!0}),await K.writeFilePromise(c,e);let u={path:l,spec:r};await ye.updateConfiguration(t.cwd,g=>{let f=[],h=!1;for(let p of g.plugins||[]){let m=typeof p!="string"?p.path:p,y=k.resolve(t.cwd,H.toPortablePath(m)),{name:b}=Se.dynamicRequire(y);b!==a?f.push(p):(f.push(u),h=!0)}return h||f.push(u),te(N({},g),{plugins:f})})}var W3e=({pluginName:r,noMinify:e},t)=>[["yarn",`build:${r}`,...e?["--no-minify"]:[],"|"]],mm=class extends Le{constructor(){super(...arguments);this.installPath=J.String("--path",{description:"The path where the repository should be cloned to"});this.repository=J.String("--repository","https://github.com/yarnpkg/berry.git",{description:"The repository that should be cloned"});this.branch=J.String("--branch","master",{description:"The branch of the repository that should be cloned"});this.noMinify=J.Boolean("--no-minify",!1,{description:"Build a plugin for development (debugging) - non-minified and non-mangled"});this.force=J.Boolean("-f,--force",!1,{description:"Always clone the repository instead of trying to fetch the latest commits"});this.name=J.String()}async execute(){let e=await ye.find(this.context.cwd,this.context.plugins),t=typeof this.installPath!="undefined"?k.resolve(this.context.cwd,H.toPortablePath(this.installPath)):k.resolve(H.toPortablePath((0,Hoe.tmpdir)()),"yarnpkg-sources",Dn.makeHash(this.repository).slice(0,6));return(await Je.start({configuration:e,stdout:this.context.stdout},async n=>{let{project:s}=await ze.find(e,this.context.cwd),o=P.parseIdent(this.name.replace(/^((@yarnpkg\/)?plugin-)?/,"@yarnpkg/plugin-")),a=P.stringifyIdent(o),l=await bu(e);if(!Object.prototype.hasOwnProperty.call(l,a))throw new ct(X.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 vN(this,{configuration:e,report:n,target:t}),await SN(c,this,{project:s,report:n,target:t})})).exitCode()}};mm.paths=[["plugin","import","from","sources"]],mm.usage=Re.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 joe=mm;async function SN(r,{context:e,noMinify:t},{project:i,report:n,target:s}){let o=r.replace(/@yarnpkg\//,""),{configuration:a}=i;n.reportSeparator(),n.reportInfo(X.UNNAMED,`Building a fresh ${o}`),n.reportSeparator(),await dm(W3e({pluginName:o,noMinify:t},s),{configuration:a,context:e,target:s}),n.reportSeparator();let l=k.resolve(s,`packages/${o}/bundles/${r}.js`),c=await K.readFilePromise(l);await xN(r,c,{project:i,report:n})}var Em=class extends Le{constructor(){super(...arguments);this.name=J.String()}async execute(){let e=await ye.find(this.context.cwd,this.context.plugins),{project:t}=await ze.find(e,this.context.cwd);return(await Je.start({configuration:e,stdout:this.context.stdout},async n=>{let s=this.name,o=P.parseIdent(s);if(!e.plugins.has(s))throw new Pe(`${P.prettyIdent(e,o)} isn't referenced by the current configuration`);let a=`.yarn/plugins/${s}.cjs`,l=k.resolve(t.cwd,a);K.existsSync(l)&&(n.reportInfo(X.UNNAMED,`Removing ${ae.pretty(e,a,ae.Type.PATH)}...`),await K.removePromise(l)),n.reportInfo(X.UNNAMED,"Updating the configuration..."),await ye.updateConfiguration(t.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:te(N({},c),{plugins:u})})})).exitCode()}};Em.paths=[["plugin","remove"]],Em.usage=Re.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 Goe=Em;var Im=class extends Le{constructor(){super(...arguments);this.json=J.Boolean("--json",!1,{description:"Format the output as an NDJSON stream"})}async execute(){let e=await ye.find(this.context.cwd,this.context.plugins);return(await Je.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()}};Im.paths=[["plugin","runtime"]],Im.usage=Re.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 Yoe=Im;var ym=class extends Le{constructor(){super(...arguments);this.idents=J.Rest()}async execute(){let e=await ye.find(this.context.cwd,this.context.plugins),{project:t,workspace:i}=await ze.find(e,this.context.cwd),n=await Nt.find(e);if(!i)throw new ht(t.cwd,this.context.cwd);let s=new Set;for(let a of this.idents)s.add(P.parseIdent(a).identHash);if(await t.restoreInstallState({restoreResolutions:!1}),await t.resolveEverything({cache:n,report:new di}),s.size>0)for(let a of t.storedPackages.values())s.has(a.identHash)&&t.storedBuildState.delete(a.locatorHash);else t.storedBuildState.clear();return(await Je.start({configuration:e,stdout:this.context.stdout,includeLogs:!this.context.quiet},async a=>{await t.install({cache:n,report:a})})).exitCode()}};ym.paths=[["rebuild"]],ym.usage=Re.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 qoe=ym;var kN=ge(is());ys();var wm=class extends Le{constructor(){super(...arguments);this.all=J.Boolean("-A,--all",!1,{description:"Apply the operation to all workspaces from the current project"});this.mode=J.String("--mode",{description:"Change what artifacts installs generate",validator:nn(Ci)});this.patterns=J.Rest()}async execute(){let e=await ye.find(this.context.cwd,this.context.plugins),{project:t,workspace:i}=await ze.find(e,this.context.cwd),n=await Nt.find(e);if(!i)throw new ht(t.cwd,this.context.cwd);await t.restoreInstallState({restoreResolutions:!1});let s=this.all?t.workspaces:[i],o=[Hr.REGULAR,Hr.DEVELOPMENT,Hr.PEER],a=[],l=!1,c=[];for(let h of this.patterns){let p=!1,m=P.parseIdent(h);for(let y of s){let b=[...y.manifest.peerDependenciesMeta.keys()];for(let v of(0,kN.default)(b,h))y.manifest.peerDependenciesMeta.delete(v),l=!0,p=!0;for(let v of o){let x=y.manifest.getForScope(v),T=[...x.values()].map(q=>P.stringifyIdent(q));for(let q of(0,kN.default)(T,P.stringifyIdent(m))){let{identHash:Y}=P.parseIdent(q),$=x.get(Y);if(typeof $=="undefined")throw new Error("Assertion failed: Expected the descriptor to be registered");y.manifest[v].delete(Y),c.push([y,v,$]),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 Pe(`${u} ${ae.prettyList(e,a,Ri.CODE)} ${g} match any packages referenced by ${f} workspace`);return l?(await e.triggerMultipleHooks(p=>p.afterWorkspaceDependencyRemoval,c),(await Je.start({configuration:e,stdout:this.context.stdout},async p=>{await t.install({cache:n,report:p,mode:this.mode})})).exitCode()):0}};wm.paths=[["remove"]],wm.usage=Re.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 Joe=wm;var Woe=ge(require("util")),V0=class extends Le{async execute(){let e=await ye.find(this.context.cwd,this.context.plugins),{project:t,workspace:i}=await ze.find(e,this.context.cwd);if(!i)throw new ht(t.cwd,this.context.cwd);return(await Je.start({configuration:e,stdout:this.context.stdout},async s=>{let o=i.manifest.scripts,a=Se.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,Woe.inspect)(g,l)}`)})).exitCode()}};V0.paths=[["run"]];var zoe=V0;var Bm=class extends Le{constructor(){super(...arguments);this.inspect=J.String("--inspect",!1,{tolerateBoolean:!0,description:"Forwarded to the underlying Node process when executing a binary"});this.inspectBrk=J.String("--inspect-brk",!1,{tolerateBoolean:!0,description:"Forwarded to the underlying Node process when executing a binary"});this.topLevel=J.Boolean("-T,--top-level",!1,{description:"Check the root workspace for scripts and/or binaries instead of the current one"});this.binariesOnly=J.Boolean("-B,--binaries-only",!1,{description:"Ignore any user defined scripts and only check for binaries"});this.silent=J.Boolean("--silent",{hidden:!0});this.scriptName=J.String();this.args=J.Proxy()}async execute(){let e=await ye.find(this.context.cwd,this.context.plugins),{project:t,workspace:i,locator:n}=await ze.find(e,this.context.cwd);await t.restoreInstallState();let s=this.topLevel?t.topLevelWorkspace.anchoredLocator:n;if(!this.binariesOnly&&await Zt.hasPackageScript(s,this.scriptName,{project:t}))return await Zt.executePackageScript(s,this.scriptName,this.args,{project:t,stdin:this.context.stdin,stdout:this.context.stdout,stderr:this.context.stderr});let o=await Zt.getPackageAccessibleBinaries(s,{project:t});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 Zt.executePackageAccessibleBinary(s,this.scriptName,this.args,{cwd:this.context.cwd,project:t,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(t.workspaces.map(async u=>u.manifest.scripts.has(this.scriptName)?u:null))).filter(u=>u!==null);if(c.length===1)return await Zt.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 Pe(`Couldn't find a script name "${this.scriptName}" in the top-level (used by ${P.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 Pe(`Couldn't find a script name "${this.scriptName}" in the top-level (used by ${P.prettyLocator(e,n)}).`);{if(this.scriptName==="global")throw new Pe("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 Lf)for(let g of u)if(l.length>=g.length&&JSON.stringify(l.slice(0,g.length))===JSON.stringify(g))throw new Pe(`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 Pe(`Couldn't find a script named "${this.scriptName}".`)}}};Bm.paths=[["run"]],Bm.usage=Re.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 _oe=Bm;var bm=class extends Le{constructor(){super(...arguments);this.save=J.Boolean("-s,--save",!1,{description:"Persist the resolution inside the top-level manifest"});this.descriptor=J.String();this.resolution=J.String()}async execute(){let e=await ye.find(this.context.cwd,this.context.plugins),{project:t,workspace:i}=await ze.find(e,this.context.cwd),n=await Nt.find(e);if(await t.restoreInstallState({restoreResolutions:!1}),!i)throw new ht(t.cwd,this.context.cwd);let s=P.parseDescriptor(this.descriptor,!0),o=P.makeDescriptor(s,this.resolution);return t.storedDescriptors.set(s.descriptorHash,s),t.storedDescriptors.set(o.descriptorHash,o),t.resolutionAliases.set(s.descriptorHash,o.descriptorHash),(await Je.start({configuration:e,stdout:this.context.stdout},async l=>{await t.install({cache:n,report:l})})).exitCode()}};bm.paths=[["set","resolution"]],bm.usage=Re.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 Voe=bm;var Xoe=ge(is()),Qm=class extends Le{constructor(){super(...arguments);this.all=J.Boolean("-A,--all",!1,{description:"Unlink all workspaces belonging to the target project from the current one"});this.leadingArguments=J.Rest()}async execute(){let e=await ye.find(this.context.cwd,this.context.plugins),{project:t,workspace:i}=await ze.find(e,this.context.cwd),n=await Nt.find(e);if(!i)throw new ht(t.cwd,this.context.cwd);let s=t.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=k.resolve(this.context.cwd,H.toPortablePath(l));if(Se.isPathLike(l)){let u=await ye.find(c,this.context.plugins,{useRc:!1,strict:!1}),{project:g,workspace:f}=await ze.find(u,c);if(!f)throw new ht(g.cwd,c);if(this.all){for(let h of g.workspaces)h.manifest.name&&o.add(P.stringifyIdent(h.locator));if(o.size===0)throw new Pe("No workspace found to be unlinked in the target project")}else{if(!f.manifest.name)throw new Pe("The target workspace doesn't have a name and thus cannot be unlinked");o.add(P.stringifyIdent(f.locator))}}else{let u=[...s.manifest.resolutions.map(({pattern:g})=>g.descriptor.fullName)];for(let g of(0,Xoe.default)(u,l))o.add(g)}}return s.manifest.resolutions=s.manifest.resolutions.filter(({pattern:l})=>!o.has(l.descriptor.fullName)),(await Je.start({configuration:e,stdout:this.context.stdout},async l=>{await t.install({cache:n,report:l})})).exitCode()}};Qm.paths=[["unlink"]],Qm.usage=Re.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 Zoe=Qm;var $oe=ge(WC()),PN=ge(is());ys();var th=class extends Le{constructor(){super(...arguments);this.interactive=J.Boolean("-i,--interactive",{description:"Offer various choices, depending on the detected upgrade paths"});this.exact=J.Boolean("-E,--exact",!1,{description:"Don't use any semver modifier on the resolved range"});this.tilde=J.Boolean("-T,--tilde",!1,{description:"Use the `~` semver modifier on the resolved range"});this.caret=J.Boolean("-C,--caret",!1,{description:"Use the `^` semver modifier on the resolved range"});this.recursive=J.Boolean("-R,--recursive",!1,{description:"Resolve again ALL resolutions for those packages"});this.mode=J.String("--mode",{description:"Change what artifacts installs generate",validator:nn(Ci)});this.patterns=J.Rest()}async execute(){return this.recursive?await this.executeUpRecursive():await this.executeUpClassic()}async executeUpRecursive(){let e=await ye.find(this.context.cwd,this.context.plugins),{project:t,workspace:i}=await ze.find(e,this.context.cwd),n=await Nt.find(e);if(!i)throw new ht(t.cwd,this.context.cwd);await t.restoreInstallState({restoreResolutions:!1});let s=[...t.storedDescriptors.values()],o=s.map(u=>P.stringifyIdent(u)),a=new Set;for(let u of this.patterns){if(P.parseDescriptor(u).range!=="unknown")throw new Pe("Ranges aren't allowed when using --recursive");for(let g of(0,PN.default)(o,u)){let f=P.parseIdent(g);a.add(f.identHash)}}let l=s.filter(u=>a.has(u.identHash));for(let u of l)t.storedDescriptors.delete(u.descriptorHash),t.storedResolutions.delete(u.descriptorHash);return(await Je.start({configuration:e,stdout:this.context.stdout},async u=>{await t.install({cache:n,report:u})})).exitCode()}async executeUpClassic(){var m;let e=await ye.find(this.context.cwd,this.context.plugins),{project:t,workspace:i}=await ze.find(e,this.context.cwd),n=await Nt.find(e);if(!i)throw new ht(t.cwd,this.context.cwd);await t.restoreInstallState({restoreResolutions:!1});let s=(m=this.interactive)!=null?m:e.get("preferInteractive"),o=zC(this,t),a=s?[Vr.KEEP,Vr.REUSE,Vr.PROJECT,Vr.LATEST]:[Vr.PROJECT,Vr.LATEST],l=[],c=[];for(let y of this.patterns){let b=!1,v=P.parseDescriptor(y);for(let x of t.workspaces)for(let T of[Hr.REGULAR,Hr.DEVELOPMENT]){let Y=[...x.manifest.getForScope(T).values()].map($=>P.stringifyIdent($));for(let $ of(0,PN.default)(Y,P.stringifyIdent(v))){let _=P.parseIdent($),ne=x.manifest[T].get(_.identHash);if(typeof ne=="undefined")throw new Error("Assertion failed: Expected the descriptor to be registered");let ee=P.makeDescriptor(_,v.range);l.push(Promise.resolve().then(async()=>[x,T,ne,await _C(ee,{project:t,workspace:x,cache:n,target:T,modifier:o,strategies:a})])),b=!0}}b||c.push(y)}if(c.length>1)throw new Pe(`Patterns ${ae.prettyList(e,c,Ri.CODE)} don't match any packages referenced by any workspace`);if(c.length>0)throw new Pe(`Pattern ${ae.prettyList(e,c,Ri.CODE)} doesn't match any packages referenced by any workspace`);let u=await Promise.all(l),g=await pA.start({configuration:e,stdout:this.context.stdout,suggestInstall:!1},async y=>{for(let[,,b,{suggestions:v,rejections:x}]of u){let T=v.filter(q=>q.descriptor!==null);if(T.length===0){let[q]=x;if(typeof q=="undefined")throw new Error("Assertion failed: Expected an error to have been set");let Y=this.cli.error(q);t.configuration.get("enableNetwork")?y.reportError(X.CANT_SUGGEST_RESOLUTIONS,`${P.prettyDescriptor(e,b)} can't be resolved to a satisfying range - -${Y}`):y.reportError(X.CANT_SUGGEST_RESOLUTIONS,`${P.prettyDescriptor(e,b)} can't be resolved to a satisfying range (note: network resolution has been disabled) - -${Y}`)}else T.length>1&&!s&&y.reportError(X.CANT_SUGGEST_RESOLUTIONS,`${P.prettyDescriptor(e,b)} has multiple possible upgrade strategies; use -i to disambiguate manually`)}});if(g.hasErrors())return g.exitCode();let f=!1,h=[];for(let[y,b,,{suggestions:v}]of u){let x,T=v.filter(_=>_.descriptor!==null),q=T[0].descriptor,Y=T.every(_=>P.areDescriptorsEqual(_.descriptor,q));T.length===1||Y?x=q:(f=!0,{answer:x}=await(0,$oe.prompt)({type:"select",name:"answer",message:`Which range to you want to use in ${P.prettyWorkspace(e,y)} \u276F ${b}?`,choices:v.map(({descriptor:_,name:ne,reason:ee})=>_?{name:ne,hint:ee,descriptor:_}:{name:ne,hint:ee,disabled:!0}),onCancel:()=>process.exit(130),result(_){return this.find(_,"descriptor")},stdin:this.context.stdin,stdout:this.context.stdout}));let $=y.manifest[b].get(x.identHash);if(typeof $=="undefined")throw new Error("Assertion failed: This descriptor should have a matching entry");if($.descriptorHash!==x.descriptorHash)y.manifest[b].set(x.identHash,x),h.push([y,b,$,x]);else{let _=e.makeResolver(),ne={project:t,resolver:_},ee=_.bindDescriptor($,y.anchoredLocator,ne);t.forgetResolution(ee)}}return await e.triggerMultipleHooks(y=>y.afterWorkspaceDependencyReplacement,h),f&&this.context.stdout.write(` -`),(await Je.start({configuration:e,stdout:this.context.stdout},async y=>{await t.install({cache:n,report:y,mode:this.mode})})).exitCode()}};th.paths=[["up"]],th.usage=Re.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'"]]}),th.schema=[eS("recursive",Bc.Forbids,["interactive","exact","tilde","caret"],{ignore:[void 0,!1]})];var eae=th;var Sm=class extends Le{constructor(){super(...arguments);this.recursive=J.Boolean("-R,--recursive",!1,{description:"List, for each workspace, what are all the paths that lead to the dependency"});this.json=J.Boolean("--json",!1,{description:"Format the output as an NDJSON stream"});this.peers=J.Boolean("--peers",!1,{description:"Also print the peer dependencies that match the specified name"});this.package=J.String()}async execute(){let e=await ye.find(this.context.cwd,this.context.plugins),{project:t,workspace:i}=await ze.find(e,this.context.cwd);if(!i)throw new ht(t.cwd,this.context.cwd);await t.restoreInstallState();let n=P.parseIdent(this.package).identHash,s=this.recursive?_3e(t,n,{configuration:e,peers:this.peers}):z3e(t,n,{configuration:e,peers:this.peers});ls.emitTree(s,{configuration:e,stdout:this.context.stdout,json:this.json,separators:1})}};Sm.paths=[["why"]],Sm.usage=Re.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 tae=Sm;function z3e(r,e,{configuration:t,peers:i}){let n=Se.sortMap(r.storedPackages.values(),a=>P.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=r.storedResolutions.get(u.descriptorHash);if(!g)throw new Error("Assertion failed: The resolution should have been registered");let f=r.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=P.stringifyLocator(a);s[p]={value:[a,ae.Type.LOCATOR],children:l}}let h=P.stringifyLocator(f);l[h]={value:[{descriptor:u,locator:f},ae.Type.DEPENDENT]}}}return o}function _3e(r,e,{configuration:t,peers:i}){let n=Se.sortMap(r.workspaces,f=>P.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 m=r.storedResolutions.get(p.descriptorHash);if(!m)throw new Error("Assertion failed: The resolution should have been registered");let y=r.storedPackages.get(m);if(!y)throw new Error("Assertion failed: The package should have been registered");a(y)&&(h=!0)}return h&&o.add(f.locatorHash),h};for(let f of n){let h=r.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 m=p!==null?ae.tuple(ae.Type.DEPENDENT,{locator:f,descriptor:p}):ae.tuple(ae.Type.LOCATOR,f),y={},b={value:m,children:y},v=P.stringifyLocator(f);if(h[v]=b,!l.has(f.locatorHash)&&(l.add(f.locatorHash),!(p!==null&&r.tryWorkspaceByLocator(f))))for(let x of f.dependencies.values()){if(!i&&f.peerDependencies.has(x.identHash))continue;let T=r.storedResolutions.get(x.descriptorHash);if(!T)throw new Error("Assertion failed: The resolution should have been registered");let q=r.storedPackages.get(T);if(!q)throw new Error("Assertion failed: The package should have been registered");g(q,y,x)}};for(let f of n){let h=r.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 jN={};ft(jN,{default:()=>dWe,gitUtils:()=>Qu});var Qu={};ft(Qu,{TreeishProtocols:()=>On,clone:()=>KN,fetchBase:()=>wae,fetchChangedFiles:()=>Bae,fetchChangedWorkspaces:()=>hWe,fetchRoot:()=>yae,isGitUrl:()=>ih,lsRemote:()=>Iae,normalizeLocator:()=>TN,normalizeRepoUrl:()=>vm,resolveUrl:()=>MN,splitRepoUrl:()=>xm});var NN=ge(dae()),Cae=ge(Zw()),rh=ge(require("querystring")),LN=ge(ri()),mae=ge(require("url"));function Eae(){return te(N({},process.env),{GIT_SSH_COMMAND:process.env.GIT_SSH_COMMAND||`${process.env.GIT_SSH||"ssh"} -o BatchMode=yes`})}var fWe=[/^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\/(.+)?$/],On;(function(n){n.Commit="commit",n.Head="head",n.Tag="tag",n.Semver="semver"})(On||(On={}));function ih(r){return r?fWe.some(e=>!!r.match(e)):!1}function xm(r){r=vm(r);let e=r.indexOf("#");if(e===-1)return{repo:r,treeish:{protocol:On.Head,request:"HEAD"},extra:{}};let t=r.slice(0,e),i=r.slice(e+1);if(i.match(/^[a-z]+=/)){let n=rh.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(On).find(l=>Object.prototype.hasOwnProperty.call(n,l)),o,a;typeof s!="undefined"?(o=s,a=n[s]):(o=On.Head,a="HEAD");for(let l of Object.values(On))delete n[l];return{repo:t,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:t,treeish:{protocol:s,request:o},extra:{}}}}function vm(r,{git:e=!1}={}){var t;if(r=r.replace(/^git\+https:/,"https:"),r=r.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"),r=r.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){r=r.replace(/^git\+([^:]+):/,"$1:");let i;try{i=mae.default.parse(r)}catch{i=null}i&&i.protocol==="ssh:"&&((t=i.path)==null?void 0:t.startsWith("/:"))&&(r=r.replace(/^ssh:\/\//,""))}return r}function TN(r){return P.makeLocator(r,vm(r.reference))}async function Iae(r,e){let t=vm(r,{git:!0});if(!ir.getNetworkSettings(`https://${(0,NN.default)(t).resource}`,{configuration:e}).enableNetwork)throw new Error(`Request to '${t}' has been blocked because of your configuration settings`);let n=await ON("listing refs",["ls-remote",t],{cwd:e.startingCwd,env:Eae()},{configuration:e,normalizedRepoUrl:t}),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 MN(r,e){let{repo:t,treeish:{protocol:i,request:n},extra:s}=xm(r),o=await Iae(t,e),a=(c,u)=>{switch(c){case On.Commit:{if(!u.match(/^[a-f0-9]{40}$/))throw new Error("Invalid commit hash");return rh.default.stringify(te(N({},s),{commit:u}))}case On.Head:{let g=o.get(u==="HEAD"?u:`refs/heads/${u}`);if(typeof g=="undefined")throw new Error(`Unknown head ("${u}")`);return rh.default.stringify(te(N({},s),{commit:g}))}case On.Tag:{let g=o.get(`refs/tags/${u}`);if(typeof g=="undefined")throw new Error(`Unknown tag ("${u}")`);return rh.default.stringify(te(N({},s),{commit:g}))}case On.Semver:{let g=Wt.validRange(u);if(!g)throw new Error(`Invalid range ("${u}")`);let f=new Map([...o.entries()].filter(([p])=>p.startsWith("refs/tags/")).map(([p,m])=>[LN.default.parse(p.slice(10)),m]).filter(p=>p[0]!==null)),h=LN.default.maxSatisfying([...f.keys()],g);if(h===null)throw new Error(`No matching range ("${u}")`);return rh.default.stringify(te(N({},s),{commit:f.get(h)}))}case null:{let g;if((g=l(On.Commit,u))!==null||(g=l(On.Tag,u))!==null||(g=l(On.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`${t}#${a(i,n)}`}async function KN(r,e){return await e.getLimit("cloneConcurrency")(async()=>{let{repo:t,treeish:{protocol:i,request:n}}=xm(r);if(i!=="commit")throw new Error("Invalid treeish protocol when cloning");let s=vm(t,{git:!0});if(ir.getNetworkSettings(`https://${(0,NN.default)(s).resource}`,{configuration:e}).enableNetwork===!1)throw new Error(`Request to '${s}' has been blocked because of your configuration settings`);let o=await K.mktempPromise(),a={cwd:o,env:Eae()};return await ON("cloning the repository",["clone","-c core.autocrlf=false",s,H.fromPortablePath(o)],a,{configuration:e,normalizedRepoUrl:s}),await ON("switching branch",["checkout",`${n}`],a,{configuration:e,normalizedRepoUrl:s}),o})}async function yae(r){let e=null,t,i=r;do t=i,await K.existsPromise(k.join(t,".git"))&&(e=t),i=k.dirname(t);while(e===null&&i!==t);return e}async function wae(r,{baseRefs:e}){if(e.length===0)throw new Pe("Can't run this command with zero base refs specified.");let t=[];for(let a of e){let{code:l}=await Nr.execvp("git",["merge-base",a,"HEAD"],{cwd:r});l===0&&t.push(a)}if(t.length===0)throw new Pe(`No ancestor could be found between any of HEAD and ${e.join(", ")}`);let{stdout:i}=await Nr.execvp("git",["merge-base","HEAD",...t],{cwd:r,strict:!0}),n=i.trim(),{stdout:s}=await Nr.execvp("git",["show","--quiet","--pretty=format:%s",n],{cwd:r,strict:!0}),o=s.trim();return{hash:n,title:o}}async function Bae(r,{base:e,project:t}){let i=Se.buildIgnorePattern(t.configuration.get("changesetIgnorePatterns")),{stdout:n}=await Nr.execvp("git",["diff","--name-only",`${e}`],{cwd:r,strict:!0}),s=n.split(/\r\n|\r|\n/).filter(c=>c.length>0).map(c=>k.resolve(r,H.toPortablePath(c))),{stdout:o}=await Nr.execvp("git",["ls-files","--others","--exclude-standard"],{cwd:r,strict:!0}),a=o.split(/\r\n|\r|\n/).filter(c=>c.length>0).map(c=>k.resolve(r,H.toPortablePath(c))),l=[...new Set([...s,...a].sort())];return i?l.filter(c=>!k.relative(t.cwd,c).match(i)):l}async function hWe({ref:r,project:e}){if(e.configuration.projectCwd===null)throw new Pe("This command can only be run from within a Yarn project");let t=[k.resolve(e.cwd,e.configuration.get("cacheFolder")),k.resolve(e.cwd,e.configuration.get("installStatePath")),k.resolve(e.cwd,e.configuration.get("lockfileFilename")),k.resolve(e.cwd,e.configuration.get("virtualFolder"))];await e.configuration.triggerHook(o=>o.populateYarnPaths,e,o=>{o!=null&&t.push(o)});let i=await yae(e.configuration.projectCwd);if(i==null)throw new Pe("This command can only be run on Git repositories");let n=await wae(i,{baseRefs:typeof r=="string"?[r]:e.configuration.get("changesetBaseRefs")}),s=await Bae(i,{base:n.hash,project:e});return new Set(Se.mapAndFilter(s,o=>{let a=e.tryWorkspaceByFilePath(o);return a===null?Se.mapAndFilter.skip:t.some(l=>o.startsWith(l))?Se.mapAndFilter.skip:a}))}async function ON(r,e,t,{configuration:i,normalizedRepoUrl:n}){try{return await Nr.execvp("git",e,te(N({},t),{strict:!0}))}catch(s){if(!(s instanceof Nr.ExecError))throw s;let o=s.reportExtra,a=s.stderr.toString();throw new ct(X.EXCEPTION,`Failed ${r}`,l=>{l.reportError(X.EXCEPTION,` ${ae.prettyField(i,{label:"Repository URL",value:ae.tuple(ae.Type.URL,n)})}`);for(let c of a.matchAll(/^(.+?): (.*)$/gm)){let[,u,g]=c;u=u.toLowerCase();let f=u==="error"?"Error":`${(0,Cae.default)(u)} Error`;l.reportError(X.EXCEPTION,` ${ae.prettyField(i,{label:f,value:ae.tuple(ae.Type.NO_HINT,g)})}`)}o==null||o(l)})}}var UN=class{supports(e,t){return ih(e.reference)}getLocalPath(e,t){return null}async fetch(e,t){let i=t.checksums.get(e.locatorHash)||null,n=TN(e),s=new Map(t.checksums);s.set(n.locatorHash,i);let o=te(N({},t),{checksums:s}),a=await this.downloadHosted(n,o);if(a!==null)return a;let[l,c,u]=await t.cache.fetchPackageFromCache(e,i,N({onHit:()=>t.report.reportCacheHit(e),onMiss:()=>t.report.reportCacheMiss(e,`${P.prettyLocator(t.project.configuration,e)} can't be found in the cache and will be fetched from the remote repository`),loader:()=>this.cloneFromRemote(n,o),skipIntegrityCheck:t.skipIntegrityCheck},t.cacheOptions));return{packageFs:l,releaseFs:c,prefixPath:P.getIdentVendorPath(e),checksum:u}}async downloadHosted(e,t){return t.project.configuration.reduceHook(i=>i.fetchHostedRepository,null,e,t)}async cloneFromRemote(e,t){let i=await KN(e.reference,t.project.configuration),n=xm(e.reference),s=k.join(i,"package.tgz");await Zt.prepareExternalProject(i,s,{configuration:t.project.configuration,report:t.report,workspace:n.extra.workspace,locator:e});let o=await K.readFilePromise(s);return await Se.releaseAfterUseAsync(async()=>await Bi.convertToZip(o,{compressionLevel:t.project.configuration.get("compressionLevel"),prefixPath:P.getIdentVendorPath(e),stripComponents:1}))}};var HN=class{supportsDescriptor(e,t){return ih(e.range)}supportsLocator(e,t){return ih(e.reference)}shouldPersistResolution(e,t){return!0}bindDescriptor(e,t,i){return e}getResolutionDependencies(e,t){return[]}async getCandidates(e,t,i){let n=await MN(e.range,i.project.configuration);return[P.makeLocator(e,n)]}async getSatisfying(e,t,i){return null}async resolve(e,t){if(!t.fetchOptions)throw new Error("Assertion failed: This resolver cannot be used unless a fetcher is configured");let i=await t.fetchOptions.fetcher.fetch(e,t.fetchOptions),n=await Se.releaseAfterUseAsync(async()=>await At.find(i.prefixPath,{baseFs:i.packageFs}),i.releaseFs);return te(N({},e),{version:n.version||"0.0.0",languageName:n.languageName||t.project.configuration.get("defaultLanguageName"),linkType:Qt.HARD,conditions:n.getConditions(),dependencies:n.dependencies,peerDependencies:n.peerDependencies,dependenciesMeta:n.dependenciesMeta,peerDependenciesMeta:n.peerDependenciesMeta,bin:n.bin})}};var pWe={configuration:{changesetBaseRefs:{description:"The base git refs that the current HEAD is compared against when detecting changes. Supports git branches, tags, and commits.",type:Ie.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:Ie.STRING,default:[],isArray:!0},cloneConcurrency:{description:"Maximal number of concurrent clones",type:Ie.NUMBER,default:2}},fetchers:[UN],resolvers:[HN]};var dWe=pWe;var km=class extends Le{constructor(){super(...arguments);this.since=J.String("--since",{description:"Only include workspaces that have been changed since the specified ref.",tolerateBoolean:!0});this.recursive=J.Boolean("-R,--recursive",!1,{description:"Find packages via dependencies/devDependencies instead of using the workspaces field"});this.verbose=J.Boolean("-v,--verbose",!1,{description:"Also return the cross-dependencies between workspaces"});this.json=J.Boolean("--json",!1,{description:"Format the output as an NDJSON stream"})}async execute(){let e=await ye.find(this.context.cwd,this.context.plugins),{project:t}=await ze.find(e,this.context.cwd);return(await Je.start({configuration:e,json:this.json,stdout:this.context.stdout},async n=>{let s=this.since?await Qu.fetchChangedWorkspaces({ref:this.since,project:t}):t.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 At.hardDependencies)for(let[h,p]of l.getForScope(f)){let m=t.tryWorkspaceByDescriptor(p);m===null?t.workspacesByIdent.has(h)&&g.add(p):u.add(m)}c={workspaceDependencies:Array.from(u).map(f=>f.relativeCwd),mismatchedWorkspaceDependencies:Array.from(g).map(f=>P.stringifyDescriptor(f))}}n.reportInfo(null,`${a.relativeCwd}`),n.reportJson(N({location:a.relativeCwd,name:l.name?P.stringifyIdent(l.name):null},c))}})).exitCode()}};km.paths=[["workspaces","list"]],km.usage=Re.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 bae=km;var Pm=class extends Le{constructor(){super(...arguments);this.workspaceName=J.String();this.commandName=J.String();this.args=J.Proxy()}async execute(){let e=await ye.find(this.context.cwd,this.context.plugins),{project:t,workspace:i}=await ze.find(e,this.context.cwd);if(!i)throw new ht(t.cwd,this.context.cwd);let n=t.workspaces,s=new Map(n.map(a=>{let l=P.convertToIdent(a.locator);return[P.stringifyIdent(l),a]})),o=s.get(this.workspaceName);if(o===void 0){let a=Array.from(s.keys()).sort();throw new Pe(`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})}};Pm.paths=[["workspace"]],Pm.usage=Re.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 Qae=Pm;var CWe={configuration:{enableImmutableInstalls:{description:"If true (the default on CI), prevents the install command from modifying the lockfile",type:Ie.BOOLEAN,default:Sae.isCI},defaultSemverRangePrefix:{description:"The default save prefix: '^', '~' or ''",type:Ie.STRING,values:["^","~",""],default:pa.CARET}},commands:[Tne,Mne,$se,uoe,Voe,Toe,boe,bae,Coe,moe,Eoe,Ioe,Nne,Lne,goe,hoe,yoe,woe,Soe,xoe,koe,Doe,Zoe,Roe,joe,Uoe,Goe,Foe,Yoe,qoe,Joe,zoe,_oe,eae,tae,Qae]},mWe=CWe;var zN={};ft(zN,{default:()=>IWe});var Ge={optional:!0},YN=[["@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:Ge,zenObservable:Ge}}],["any-observable@<0.5.1",{peerDependenciesMeta:{rxjs:Ge,zenObservable:Ge}}],["@pm2/agent@<1.0.4",{dependencies:{debug:"*"}}],["debug@<4.2.0",{peerDependenciesMeta:{["supports-color"]:Ge}}],["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"]:Ge,["postcss-jsx"]:Ge,["postcss-less"]:Ge,["postcss-markdown"]:Ge,["postcss-scss"]:Ge}}],["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:Ge}}],["snowpack@>=3.3.0",{dependencies:{["node-gyp"]:"^7.1.0"}}],["promise-inflight@*",{peerDependenciesMeta:{bluebird:Ge}}],["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@<=0.5.2",{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:Ge,"vue-template-compiler":Ge}}],["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:Ge,"utf-8-validate":Ge}}],["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@<=4.6.0-next.3",{dependencies:{debug:"^4.3.1"}}],["gatsby-react-router-scroll@<=5.6.0-next.0",{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":Ge,"vuetify-loader":Ge}}],["vue-cli-plugin-vuetify@<=2.0.4",{dependencies:{"null-loader":"^3.0.0"}}],["vue-cli-plugin-vuetify@>=2.4.3",{peerDependencies:{vue:"*"}}],["@vuetify/cli-plugin-utils@<=0.0.4",{dependencies:{semver:"^6.3.0"},peerDependenciesMeta:{"sass-loader":Ge}}],["@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":Ge}}],["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":Ge}}],["consolidate@<0.16.0",{peerDependencies:{mustache:"^3.0.0"},peerDependenciesMeta:{mustache:Ge}}],["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:Ge,tinyliquid:Ge,"liquid-node":Ge,jade:Ge,"then-jade":Ge,dust:Ge,"dustjs-helpers":Ge,"dustjs-linkedin":Ge,swig:Ge,"swig-templates":Ge,"razor-tmpl":Ge,atpl:Ge,liquor:Ge,twig:Ge,ejs:Ge,eco:Ge,jazz:Ge,jqtpl:Ge,hamljs:Ge,hamlet:Ge,whiskers:Ge,"haml-coffee":Ge,"hogan.js":Ge,templayed:Ge,handlebars:Ge,underscore:Ge,lodash:Ge,pug:Ge,"then-pug":Ge,qejs:Ge,walrus:Ge,mustache:Ge,just:Ge,ect:Ge,mote:Ge,toffee:Ge,dot:Ge,"bracket-template":Ge,ractive:Ge,nunjucks:Ge,htmling:Ge,"babel-core":Ge,plates:Ge,"react-dom":Ge,react:Ge,"arc-templates":Ge,vash:Ge,slm:Ge,marko:Ge,teacup:Ge,"coffee-script":Ge,squirrelly:Ge,twing:Ge}}],["vue-loader@<=16.3.3",{peerDependencies:{"@vue/compiler-sfc":"^3.0.8",webpack:"^4.1.0 || ^5.0.0-0"},peerDependenciesMeta:{"@vue/compiler-sfc":Ge}}],["vue-loader@^16.7.0",{peerDependencies:{"@vue/compiler-sfc":"^3.0.8",vue:"^3.2.13"},peerDependenciesMeta:{"@vue/compiler-sfc":Ge,vue:Ge}}],["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@<2.0.0",{dependencies:{"json-parse-even-better-errors":"^2.3.1"}}],["bin-links@<2.3.0",{dependencies:{"mkdirp-infer-owner":"^1.0.2"}}],["rollup-plugin-polyfill-node@<=0.8.0",{peerDependencies:{rollup:"^1.20.0 || ^2.0.0"}}],["snowpack@<3.8.6",{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:Ge}}],["redux-persist@*",{peerDependencies:{react:">=16"},peerDependenciesMeta:{react:Ge}}],["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(r=>[r,{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":Ge,"webpack-command":Ge}}],["webpack@<5.0.0-beta.23",{peerDependenciesMeta:{"webpack-cli":Ge}}],["webpack-dev-server@<3.10.2",{peerDependenciesMeta:{"webpack-cli":Ge}}],["@docusaurus/responsive-loader@<1.5.0",{peerDependenciesMeta:{sharp:Ge,jimp:Ge}}],["eslint-module-utils@*",{peerDependenciesMeta:{"eslint-import-resolver-node":Ge,"eslint-import-resolver-typescript":Ge,"eslint-import-resolver-webpack":Ge,"@typescript-eslint/parser":Ge}}],["eslint-plugin-import@*",{peerDependenciesMeta:{"@typescript-eslint/parser":Ge}}],["critters-webpack-plugin@<3.0.2",{peerDependenciesMeta:{"html-webpack-plugin":Ge}}],["terser@<=5.10.0",{dependencies:{acorn:"^8.5.0"}}],["babel-preset-react-app@10.0.x",{dependencies:{"@babel/plugin-proposal-private-property-in-object":"^7.16.0"}}],["eslint-config-react-app@*",{peerDependenciesMeta:{typescript:Ge}}],["@vue/eslint-config-typescript@<11.0.0",{peerDependenciesMeta:{typescript:Ge}}],["unplugin-vue2-script-setup@<0.9.1",{peerDependencies:{"@vue/composition-api":"^1.4.3","@vue/runtime-dom":"^3.2.26"}}],["@cypress/snapshot@*",{dependencies:{debug:"^3.2.7"}}],["auto-relay@*",{peerDependencies:{"reflect-metadata":"^0.1.13"}}],["vue-template-babel-compiler@<1.2.0",{peerDependencies:{["vue-template-compiler"]:"^2.6.0"}}],["@parcel/transformer-image@<2.5.0",{peerDependencies:{["@parcel/core"]:"*"}}],["@parcel/transformer-js@<2.5.0",{peerDependencies:{["@parcel/core"]:"*"}}],["parcel@*",{peerDependenciesMeta:{["@parcel/core"]:Ge}}],["react-scripts@*",{peerDependencies:{eslint:"*"}}],["focus-trap-react@^8.0.0",{dependencies:{tabbable:"^5.3.2"}}],["react-rnd@<10.3.7",{peerDependencies:{react:">=16.3.0","react-dom":">=16.3.0"}}],["connect-mongo@*",{peerDependencies:{"express-session":"^1.17.1"}}],["vue-i18n@<9",{peerDependencies:{vue:"^2"}}],["vue-router@<4",{peerDependencies:{vue:"^2"}}],["unified@<10",{dependencies:{"@types/unist":"^2.0.0"}}],["react-github-btn@<=1.3.0",{peerDependencies:{react:">=16.3.0"}}],["react-dev-utils@*",{peerDependencies:{typescript:">=2.7",webpack:">=4"},peerDependenciesMeta:{typescript:{optional:!0}}}],["@asyncapi/react-component@<=1.0.0-next.39",{peerDependencies:{react:">=16.8.0","react-dom":">=16.8.0"}}]];var qN;function vae(){return typeof qN=="undefined"&&(qN=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()),qN}var JN;function xae(){return typeof JN=="undefined"&&(JN=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()),JN}var WN;function kae(){return typeof WN=="undefined"&&(WN=require("zlib").brotliDecompressSync(Buffer.from("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","base64")).toString()),WN}var Pae=new Map([[P.makeIdent(null,"fsevents").identHash,vae],[P.makeIdent(null,"resolve").identHash,xae],[P.makeIdent(null,"typescript").identHash,kae]]),EWe={hooks:{registerPackageExtensions:async(r,e)=>{for(let[t,i]of YN)e(P.parseDescriptor(t,!0),i)},getBuiltinPatch:async(r,e)=>{var s;let t="compat/";if(!e.startsWith(t))return;let i=P.parseIdent(e.slice(t.length)),n=(s=Pae.get(i.identHash))==null?void 0:s();return typeof n!="undefined"?n:null},reduceDependency:async(r,e,t,i)=>typeof Pae.get(r.identHash)=="undefined"?r:P.makeDescriptor(r,P.makeRange({protocol:"patch:",source:P.stringifyDescriptor(r),selector:`~builtin`,params:null}))}},IWe=EWe;var _N={};ft(_N,{default:()=>wWe});var X0=class extends Le{constructor(){super(...arguments);this.pkg=J.String("-p,--package",{description:"The package to run the provided command from"});this.quiet=J.Boolean("-q,--quiet",!1,{description:"Only report critical errors instead of printing the full install logs"});this.command=J.String();this.args=J.Proxy()}async execute(){let e=[];this.pkg&&e.push("--package",this.pkg),this.quiet&&e.push("--quiet");let t=P.parseDescriptor(this.command),i;t.scope?i=P.makeIdent(t.scope,`create-${t.name}`):t.name.startsWith("@")?i=P.makeIdent(t.name.substring(1),"create"):i=P.makeIdent(null,`create-${t.name}`);let n=P.stringifyIdent(i);return t.range!=="unknown"&&(n+=`@${t.range}`),this.cli.run(["dlx",...e,n,...this.args])}};X0.paths=[["create"]];var Dae=X0;var Dm=class extends Le{constructor(){super(...arguments);this.packages=J.Array("-p,--package",{description:"The package(s) to install before running the command"});this.quiet=J.Boolean("-q,--quiet",!1,{description:"Only report critical errors instead of printing the full install logs"});this.command=J.String();this.args=J.Proxy()}async execute(){return ye.telemetry=null,await K.mktempPromise(async e=>{var p;let t=k.join(e,`dlx-${process.pid}`);await K.mkdirPromise(t),await K.writeFilePromise(k.join(t,"package.json"),`{} -`),await K.writeFilePromise(k.join(t,"yarn.lock"),"");let i=k.join(t,".yarnrc.yml"),n=await ye.findProjectCwd(this.context.cwd,kt.lockfile),s=!(await ye.find(this.context.cwd,null,{strict:!1})).get("enableGlobalCache"),o=n!==null?k.join(n,".yarnrc.yml"):null;o!==null&&K.existsSync(o)?(await K.copyFilePromise(o,i),await ye.updateConfiguration(t,m=>{let y=te(N({},m),{enableGlobalCache:s,enableTelemetry:!1});return Array.isArray(m.plugins)&&(y.plugins=m.plugins.map(b=>{let v=typeof b=="string"?b:b.path,x=H.isAbsolute(v)?v:H.resolve(H.fromPortablePath(n),v);return typeof b=="string"?x:{path:x,spec:b.spec}})),y})):await K.writeFilePromise(i,`enableGlobalCache: ${s} -enableTelemetry: false -`);let a=(p=this.packages)!=null?p:[this.command],l=P.parseDescriptor(this.command).name,c=await this.cli.run(["add","--",...a],{cwd:t,quiet:this.quiet});if(c!==0)return c;this.quiet||this.context.stdout.write(` -`);let u=await ye.find(t,this.context.plugins),{project:g,workspace:f}=await ze.find(u,t);if(f===null)throw new ht(g.cwd,t);await g.restoreInstallState();let h=await Zt.getWorkspaceAccessibleBinaries(f);return h.has(l)===!1&&h.size===1&&typeof this.packages=="undefined"&&(l=Array.from(h)[0][0]),await Zt.executeWorkspaceAccessibleBinary(f,l,this.args,{packageAccessibleBinaries:h,cwd:this.context.cwd,stdin:this.context.stdin,stdout:this.context.stdout,stderr:this.context.stderr})})}};Dm.paths=[["dlx"]],Dm.usage=Re.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 Rae=Dm;var yWe={commands:[Dae,Rae]},wWe=yWe;var nL={};ft(nL,{default:()=>QWe,fileUtils:()=>VN});var nh=/^(?:[a-zA-Z]:[\\/]|\.{0,2}\/)/,Rm=/^[^?]*\.(?:tar\.gz|tgz)(?:::.*)?$/,Xr="file:";var VN={};ft(VN,{makeArchiveFromLocator:()=>Z0,makeBufferFromLocator:()=>$N,makeLocator:()=>ZN,makeSpec:()=>Fae,parseSpec:()=>XN});function XN(r){let{params:e,selector:t}=P.parseRange(r),i=H.toPortablePath(t);return{parentLocator:e&&typeof e.locator=="string"?P.parseLocator(e.locator):null,path:i}}function Fae({parentLocator:r,path:e,folderHash:t,protocol:i}){let n=r!==null?{locator:P.stringifyLocator(r)}:{},s=typeof t!="undefined"?{hash:t}:{};return P.makeRange({protocol:i,source:e,selector:e,params:N(N({},s),n)})}function ZN(r,{parentLocator:e,path:t,folderHash:i,protocol:n}){return P.makeLocator(r,Fae({parentLocator:e,path:t,folderHash:i,protocol:n}))}async function Z0(r,{protocol:e,fetchOptions:t,inMemory:i=!1}){let{parentLocator:n,path:s}=P.parseFileStyleRange(r.reference,{protocol:e}),o=k.isAbsolute(s)?{packageFs:new _t(Me.root),prefixPath:Me.dot,localPath:Me.root}:await t.fetcher.fetch(n,t),a=o.localPath?{packageFs:new _t(Me.root),prefixPath:k.relative(Me.root,o.localPath)}:o;o!==a&&o.releaseFs&&o.releaseFs();let l=a.packageFs,c=k.join(a.prefixPath,s);return await Se.releaseAfterUseAsync(async()=>await Bi.makeArchiveFromDirectory(c,{baseFs:l,prefixPath:P.getIdentVendorPath(r),compressionLevel:t.project.configuration.get("compressionLevel"),inMemory:i}),a.releaseFs)}async function $N(r,{protocol:e,fetchOptions:t}){return(await Z0(r,{protocol:e,fetchOptions:t,inMemory:!0})).getBufferAndClose()}var eL=class{supports(e,t){return!!e.reference.startsWith(Xr)}getLocalPath(e,t){let{parentLocator:i,path:n}=P.parseFileStyleRange(e.reference,{protocol:Xr});if(k.isAbsolute(n))return n;let s=t.fetcher.getLocalPath(i,t);return s===null?null:k.resolve(s,n)}async fetch(e,t){let i=t.checksums.get(e.locatorHash)||null,[n,s,o]=await t.cache.fetchPackageFromCache(e,i,N({onHit:()=>t.report.reportCacheHit(e),onMiss:()=>t.report.reportCacheMiss(e,`${P.prettyLocator(t.project.configuration,e)} can't be found in the cache and will be fetched from the disk`),loader:()=>this.fetchFromDisk(e,t),skipIntegrityCheck:t.skipIntegrityCheck},t.cacheOptions));return{packageFs:n,releaseFs:s,prefixPath:P.getIdentVendorPath(e),localPath:this.getLocalPath(e,t),checksum:o}}async fetchFromDisk(e,t){return Z0(e,{protocol:Xr,fetchOptions:t})}};var BWe=2,tL=class{supportsDescriptor(e,t){return e.range.match(nh)?!0:!!e.range.startsWith(Xr)}supportsLocator(e,t){return!!e.reference.startsWith(Xr)}shouldPersistResolution(e,t){return!1}bindDescriptor(e,t,i){return nh.test(e.range)&&(e=P.makeDescriptor(e,`${Xr}${e.range}`)),P.bindDescriptor(e,{locator:P.stringifyLocator(t)})}getResolutionDependencies(e,t){return[]}async getCandidates(e,t,i){if(!i.fetchOptions)throw new Error("Assertion failed: This resolver cannot be used unless a fetcher is configured");let{path:n,parentLocator:s}=XN(e.range);if(s===null)throw new Error("Assertion failed: The descriptor should have been bound");let o=await $N(P.makeLocator(e,P.makeRange({protocol:Xr,source:n,selector:n,params:{locator:P.stringifyLocator(s)}})),{protocol:Xr,fetchOptions:i.fetchOptions}),a=Dn.makeHash(`${BWe}`,o).slice(0,6);return[ZN(e,{parentLocator:s,path:n,folderHash:a,protocol:Xr})]}async getSatisfying(e,t,i){return null}async resolve(e,t){if(!t.fetchOptions)throw new Error("Assertion failed: This resolver cannot be used unless a fetcher is configured");let i=await t.fetchOptions.fetcher.fetch(e,t.fetchOptions),n=await Se.releaseAfterUseAsync(async()=>await At.find(i.prefixPath,{baseFs:i.packageFs}),i.releaseFs);return te(N({},e),{version:n.version||"0.0.0",languageName:n.languageName||t.project.configuration.get("defaultLanguageName"),linkType:Qt.HARD,conditions:n.getConditions(),dependencies:n.dependencies,peerDependencies:n.peerDependencies,dependenciesMeta:n.dependenciesMeta,peerDependenciesMeta:n.peerDependenciesMeta,bin:n.bin})}};var rL=class{supports(e,t){return Rm.test(e.reference)?!!e.reference.startsWith(Xr):!1}getLocalPath(e,t){return null}async fetch(e,t){let i=t.checksums.get(e.locatorHash)||null,[n,s,o]=await t.cache.fetchPackageFromCache(e,i,N({onHit:()=>t.report.reportCacheHit(e),onMiss:()=>t.report.reportCacheMiss(e,`${P.prettyLocator(t.project.configuration,e)} can't be found in the cache and will be fetched from the disk`),loader:()=>this.fetchFromDisk(e,t),skipIntegrityCheck:t.skipIntegrityCheck},t.cacheOptions));return{packageFs:n,releaseFs:s,prefixPath:P.getIdentVendorPath(e),checksum:o}}async fetchFromDisk(e,t){let{parentLocator:i,path:n}=P.parseFileStyleRange(e.reference,{protocol:Xr}),s=k.isAbsolute(n)?{packageFs:new _t(Me.root),prefixPath:Me.dot,localPath:Me.root}:await t.fetcher.fetch(i,t),o=s.localPath?{packageFs:new _t(Me.root),prefixPath:k.relative(Me.root,s.localPath)}:s;s!==o&&s.releaseFs&&s.releaseFs();let a=o.packageFs,l=k.join(o.prefixPath,n),c=await a.readFilePromise(l);return await Se.releaseAfterUseAsync(async()=>await Bi.convertToZip(c,{compressionLevel:t.project.configuration.get("compressionLevel"),prefixPath:P.getIdentVendorPath(e),stripComponents:1}),o.releaseFs)}};var iL=class{supportsDescriptor(e,t){return Rm.test(e.range)?!!(e.range.startsWith(Xr)||nh.test(e.range)):!1}supportsLocator(e,t){return Rm.test(e.reference)?!!e.reference.startsWith(Xr):!1}shouldPersistResolution(e,t){return!0}bindDescriptor(e,t,i){return nh.test(e.range)&&(e=P.makeDescriptor(e,`${Xr}${e.range}`)),P.bindDescriptor(e,{locator:P.stringifyLocator(t)})}getResolutionDependencies(e,t){return[]}async getCandidates(e,t,i){let n=e.range;return n.startsWith(Xr)&&(n=n.slice(Xr.length)),[P.makeLocator(e,`${Xr}${H.toPortablePath(n)}`)]}async getSatisfying(e,t,i){return null}async resolve(e,t){if(!t.fetchOptions)throw new Error("Assertion failed: This resolver cannot be used unless a fetcher is configured");let i=await t.fetchOptions.fetcher.fetch(e,t.fetchOptions),n=await Se.releaseAfterUseAsync(async()=>await At.find(i.prefixPath,{baseFs:i.packageFs}),i.releaseFs);return te(N({},e),{version:n.version||"0.0.0",languageName:n.languageName||t.project.configuration.get("defaultLanguageName"),linkType:Qt.HARD,conditions:n.getConditions(),dependencies:n.dependencies,peerDependencies:n.peerDependencies,dependenciesMeta:n.dependenciesMeta,peerDependenciesMeta:n.peerDependenciesMeta,bin:n.bin})}};var bWe={fetchers:[rL,eL],resolvers:[iL,tL]},QWe=bWe;var oL={};ft(oL,{default:()=>xWe});var Nae=ge(require("querystring")),Lae=[/^https?:\/\/(?:([^/]+?)@)?github.com\/([^/#]+)\/([^/#]+)\/tarball\/([^/#]+)(?:#(.*))?$/,/^https?:\/\/(?:([^/]+?)@)?github.com\/([^/#]+)\/([^/#]+?)(?:\.git)?(?:#(.*))?$/];function Tae(r){return r?Lae.some(e=>!!r.match(e)):!1}function Oae(r){let e;for(let a of Lae)if(e=r.match(a),e)break;if(!e)throw new Error(SWe(r));let[,t,i,n,s="master"]=e,{commit:o}=Nae.default.parse(s);return s=o||s.replace(/[^:]*:/,""),{auth:t,username:i,reponame:n,treeish:s}}function SWe(r){return`Input cannot be parsed as a valid GitHub URL ('${r}').`}var sL=class{supports(e,t){return!!Tae(e.reference)}getLocalPath(e,t){return null}async fetch(e,t){let i=t.checksums.get(e.locatorHash)||null,[n,s,o]=await t.cache.fetchPackageFromCache(e,i,N({onHit:()=>t.report.reportCacheHit(e),onMiss:()=>t.report.reportCacheMiss(e,`${P.prettyLocator(t.project.configuration,e)} can't be found in the cache and will be fetched from GitHub`),loader:()=>this.fetchFromNetwork(e,t),skipIntegrityCheck:t.skipIntegrityCheck},t.cacheOptions));return{packageFs:n,releaseFs:s,prefixPath:P.getIdentVendorPath(e),checksum:o}}async fetchFromNetwork(e,t){let i=await ir.get(this.getLocatorUrl(e,t),{configuration:t.project.configuration});return await K.mktempPromise(async n=>{let s=new _t(n);await Bi.extractArchiveTo(i,s,{stripComponents:1});let o=Qu.splitRepoUrl(e.reference),a=k.join(n,"package.tgz");await Zt.prepareExternalProject(n,a,{configuration:t.project.configuration,report:t.report,workspace:o.extra.workspace,locator:e});let l=await K.readFilePromise(a);return await Bi.convertToZip(l,{compressionLevel:t.project.configuration.get("compressionLevel"),prefixPath:P.getIdentVendorPath(e),stripComponents:1})})}getLocatorUrl(e,t){let{auth:i,username:n,reponame:s,treeish:o}=Oae(e.reference);return`https://${i?`${i}@`:""}github.com/${n}/${s}/archive/${o}.tar.gz`}};var vWe={hooks:{async fetchHostedRepository(r,e,t){if(r!==null)return r;let i=new sL;if(!i.supports(e,t))return null;try{return await i.fetch(e,t)}catch(n){return null}}}},xWe=vWe;var lL={};ft(lL,{default:()=>PWe});var Fm=/^[^?]*\.(?:tar\.gz|tgz)(?:\?.*)?$/,Nm=/^https?:/;var aL=class{supports(e,t){return Fm.test(e.reference)?!!Nm.test(e.reference):!1}getLocalPath(e,t){return null}async fetch(e,t){let i=t.checksums.get(e.locatorHash)||null,[n,s,o]=await t.cache.fetchPackageFromCache(e,i,N({onHit:()=>t.report.reportCacheHit(e),onMiss:()=>t.report.reportCacheMiss(e,`${P.prettyLocator(t.project.configuration,e)} can't be found in the cache and will be fetched from the remote server`),loader:()=>this.fetchFromNetwork(e,t),skipIntegrityCheck:t.skipIntegrityCheck},t.cacheOptions));return{packageFs:n,releaseFs:s,prefixPath:P.getIdentVendorPath(e),checksum:o}}async fetchFromNetwork(e,t){let i=await ir.get(e.reference,{configuration:t.project.configuration});return await Bi.convertToZip(i,{compressionLevel:t.project.configuration.get("compressionLevel"),prefixPath:P.getIdentVendorPath(e),stripComponents:1})}};var AL=class{supportsDescriptor(e,t){return Fm.test(e.range)?!!Nm.test(e.range):!1}supportsLocator(e,t){return Fm.test(e.reference)?!!Nm.test(e.reference):!1}shouldPersistResolution(e,t){return!0}bindDescriptor(e,t,i){return e}getResolutionDependencies(e,t){return[]}async getCandidates(e,t,i){return[P.convertDescriptorToLocator(e)]}async getSatisfying(e,t,i){return null}async resolve(e,t){if(!t.fetchOptions)throw new Error("Assertion failed: This resolver cannot be used unless a fetcher is configured");let i=await t.fetchOptions.fetcher.fetch(e,t.fetchOptions),n=await Se.releaseAfterUseAsync(async()=>await At.find(i.prefixPath,{baseFs:i.packageFs}),i.releaseFs);return te(N({},e),{version:n.version||"0.0.0",languageName:n.languageName||t.project.configuration.get("defaultLanguageName"),linkType:Qt.HARD,conditions:n.getConditions(),dependencies:n.dependencies,peerDependencies:n.peerDependencies,dependenciesMeta:n.dependenciesMeta,peerDependenciesMeta:n.peerDependenciesMeta,bin:n.bin})}};var kWe={fetchers:[aL],resolvers:[AL]},PWe=kWe;var fL={};ft(fL,{default:()=>D4e});var cAe=ge(lAe()),gL=ge(require("util")),Lm=class extends Le{constructor(){super(...arguments);this.private=J.Boolean("-p,--private",!1,{description:"Initialize a private package"});this.workspace=J.Boolean("-w,--workspace",!1,{description:"Initialize a workspace root with a `packages/` directory"});this.install=J.String("-i,--install",!1,{tolerateBoolean:!0,description:"Initialize a package with a specific bundle that will be locked in the project"});this.usev2=J.Boolean("-2",!1,{hidden:!0});this.yes=J.Boolean("-y,--yes",{hidden:!0});this.assumeFreshProject=J.Boolean("--assume-fresh-project",!1,{hidden:!0})}async execute(){let e=await ye.find(this.context.cwd,this.context.plugins),t=typeof this.install=="string"?this.install:this.usev2||this.install===!0?"latest":null;return t!==null?await this.executeProxy(e,t):await this.executeRegular(e)}async executeProxy(e,t){if(e.projectCwd!==null&&e.projectCwd!==this.context.cwd)throw new Pe("Cannot use the --install flag from within a project subdirectory");K.existsSync(this.context.cwd)||await K.mkdirPromise(this.context.cwd,{recursive:!0});let i=k.join(this.context.cwd,e.get("lockfileFilename"));K.existsSync(i)||await K.writeFilePromise(i,"");let n=await this.cli.run(["set","version",t],{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 K.mktempPromise(async o=>{let{code:a}=await Nr.pipevp("yarn",["init",...s],{cwd:this.context.cwd,stdin:this.context.stdin,stdout:this.context.stdout,stderr:this.context.stderr,env:await Zt.makeScriptEnv({binFolder:o})});return a})}async executeRegular(e){var l;let t=null;try{t=(await ze.find(e,this.context.cwd)).project}catch{t=null}K.existsSync(this.context.cwd)||await K.mkdirPromise(this.context.cwd,{recursive:!0});let i=await At.tryFind(this.context.cwd)||new At,n=Object.fromEntries(e.get("initFields").entries());i.load(n),i.name=(l=i.name)!=null?l:P.makeIdent(e.get("initScope"),k.basename(this.context.cwd)),i.packageManager=Ur&&Se.isTaggedYarnVersion(Ur)?`yarn@${Ur}`:null,typeof i.raw.private=="undefined"&&(this.private||this.workspace&&i.workspaceDefinitions.length===0)&&(i.private=!0),this.workspace&&i.workspaceDefinitions.length===0&&(await K.mkdirPromise(k.join(this.context.cwd,"packages"),{recursive:!0}),i.workspaceDefinitions=[{pattern:"packages/*"}]);let s={};i.exportTo(s),gL.inspect.styles.name="cyan",this.context.stdout.write(`${(0,gL.inspect)(s,{depth:Infinity,colors:!0,compact:!1})} -`);let o=k.join(this.context.cwd,At.fileName);await K.changeFilePromise(o,`${JSON.stringify(s,null,2)} -`,{automaticNewlines:!0});let a=k.join(this.context.cwd,"README.md");if(K.existsSync(a)||await K.writeFilePromise(a,`# ${P.stringifyIdent(i.name)} -`),!t||t.cwd===this.context.cwd){let c=k.join(this.context.cwd,kt.lockfile);K.existsSync(c)||await K.writeFilePromise(c,"");let g=[".yarn/*","!.yarn/patches","!.yarn/plugins","!.yarn/releases","!.yarn/sdks","!.yarn/versions","","# 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(y=>`${y} -`).join(""),f=k.join(this.context.cwd,".gitignore");K.existsSync(f)||await K.writeFilePromise(f,g);let h={["*"]:{endOfLine:"lf",insertFinalNewline:!0},["*.{js,json,yml}"]:{charset:"utf-8",indentStyle:"space",indentSize:2}};(0,cAe.default)(h,e.get("initEditorConfig"));let p=`root = true -`;for(let[y,b]of Object.entries(h)){p+=` -[${y}] -`;for(let[v,x]of Object.entries(b))p+=`${v.replace(/[A-Z]/g,q=>`_${q.toLowerCase()}`)} = ${x} -`}let m=k.join(this.context.cwd,".editorconfig");K.existsSync(m)||await K.writeFilePromise(m,p),K.existsSync(k.join(this.context.cwd,".git"))||await Nr.execvp("git",["init"],{cwd:this.context.cwd})}}};Lm.paths=[["init"]],Lm.usage=Re.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 uAe=Lm;var P4e={configuration:{initScope:{description:"Scope used when creating packages via the init command",type:Ie.STRING,default:null},initFields:{description:"Additional fields to set when creating packages via the init command",type:Ie.MAP,valueDefinition:{description:"",type:Ie.ANY}},initEditorConfig:{description:"Extra rules to define in the generator editorconfig",type:Ie.MAP,valueDefinition:{description:"",type:Ie.ANY}}},commands:[uAe]},D4e=P4e;var mL={};ft(mL,{default:()=>F4e});var wA="portal:",BA="link:";var hL=class{supports(e,t){return!!e.reference.startsWith(wA)}getLocalPath(e,t){let{parentLocator:i,path:n}=P.parseFileStyleRange(e.reference,{protocol:wA});if(k.isAbsolute(n))return n;let s=t.fetcher.getLocalPath(i,t);return s===null?null:k.resolve(s,n)}async fetch(e,t){var c;let{parentLocator:i,path:n}=P.parseFileStyleRange(e.reference,{protocol:wA}),s=k.isAbsolute(n)?{packageFs:new _t(Me.root),prefixPath:Me.dot,localPath:Me.root}:await t.fetcher.fetch(i,t),o=s.localPath?{packageFs:new _t(Me.root),prefixPath:k.relative(Me.root,s.localPath),localPath:Me.root}:s;s!==o&&s.releaseFs&&s.releaseFs();let a=o.packageFs,l=k.resolve((c=o.localPath)!=null?c:o.packageFs.getRealPath(),o.prefixPath,n);return s.localPath?{packageFs:new _t(l,{baseFs:a}),releaseFs:o.releaseFs,prefixPath:Me.dot,localPath:l}:{packageFs:new La(l,{baseFs:a}),releaseFs:o.releaseFs,prefixPath:Me.dot}}};var pL=class{supportsDescriptor(e,t){return!!e.range.startsWith(wA)}supportsLocator(e,t){return!!e.reference.startsWith(wA)}shouldPersistResolution(e,t){return!1}bindDescriptor(e,t,i){return P.bindDescriptor(e,{locator:P.stringifyLocator(t)})}getResolutionDependencies(e,t){return[]}async getCandidates(e,t,i){let n=e.range.slice(wA.length);return[P.makeLocator(e,`${wA}${H.toPortablePath(n)}`)]}async getSatisfying(e,t,i){return null}async resolve(e,t){if(!t.fetchOptions)throw new Error("Assertion failed: This resolver cannot be used unless a fetcher is configured");let i=await t.fetchOptions.fetcher.fetch(e,t.fetchOptions),n=await Se.releaseAfterUseAsync(async()=>await At.find(i.prefixPath,{baseFs:i.packageFs}),i.releaseFs);return te(N({},e),{version:n.version||"0.0.0",languageName:n.languageName||t.project.configuration.get("defaultLanguageName"),linkType:Qt.SOFT,conditions:n.getConditions(),dependencies:new Map([...n.dependencies]),peerDependencies:n.peerDependencies,dependenciesMeta:n.dependenciesMeta,peerDependenciesMeta:n.peerDependenciesMeta,bin:n.bin})}};var dL=class{supports(e,t){return!!e.reference.startsWith(BA)}getLocalPath(e,t){let{parentLocator:i,path:n}=P.parseFileStyleRange(e.reference,{protocol:BA});if(k.isAbsolute(n))return n;let s=t.fetcher.getLocalPath(i,t);return s===null?null:k.resolve(s,n)}async fetch(e,t){var c;let{parentLocator:i,path:n}=P.parseFileStyleRange(e.reference,{protocol:BA}),s=k.isAbsolute(n)?{packageFs:new _t(Me.root),prefixPath:Me.dot,localPath:Me.root}:await t.fetcher.fetch(i,t),o=s.localPath?{packageFs:new _t(Me.root),prefixPath:k.relative(Me.root,s.localPath),localPath:Me.root}:s;s!==o&&s.releaseFs&&s.releaseFs();let a=o.packageFs,l=k.resolve((c=o.localPath)!=null?c:o.packageFs.getRealPath(),o.prefixPath,n);return s.localPath?{packageFs:new _t(l,{baseFs:a}),releaseFs:o.releaseFs,prefixPath:Me.dot,discardFromLookup:!0,localPath:l}:{packageFs:new La(l,{baseFs:a}),releaseFs:o.releaseFs,prefixPath:Me.dot,discardFromLookup:!0}}};var CL=class{supportsDescriptor(e,t){return!!e.range.startsWith(BA)}supportsLocator(e,t){return!!e.reference.startsWith(BA)}shouldPersistResolution(e,t){return!1}bindDescriptor(e,t,i){return P.bindDescriptor(e,{locator:P.stringifyLocator(t)})}getResolutionDependencies(e,t){return[]}async getCandidates(e,t,i){let n=e.range.slice(BA.length);return[P.makeLocator(e,`${BA}${H.toPortablePath(n)}`)]}async getSatisfying(e,t,i){return null}async resolve(e,t){return te(N({},e),{version:"0.0.0",languageName:t.project.configuration.get("defaultLanguageName"),linkType:Qt.SOFT,conditions:null,dependencies:new Map,peerDependencies:new Map,dependenciesMeta:new Map,peerDependenciesMeta:new Map,bin:new Map})}};var R4e={fetchers:[dL,hL],resolvers:[CL,pL]},F4e=R4e;var JL={};ft(JL,{default:()=>j8e});var Mn;(function(i){i[i.REGULAR=0]="REGULAR",i[i.WORKSPACE=1]="WORKSPACE",i[i.EXTERNAL_SOFT_LINK=2]="EXTERNAL_SOFT_LINK"})(Mn||(Mn={}));var bA;(function(i){i[i.YES=0]="YES",i[i.NO=1]="NO",i[i.DEPENDS=2]="DEPENDS"})(bA||(bA={}));var EL=(r,e)=>`${r}@${e}`,gAe=(r,e)=>{let t=e.indexOf("#"),i=t>=0?e.substring(t+1):e;return EL(r,i)},yo;(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"})(yo||(yo={}));var hAe=(r,e={})=>{let t=e.debugLevel||Number(process.env.NM_DEBUG_LEVEL||-1),i=e.check||t>=9,n=e.hoistingLimits||new Map,s={check:i,debugLevel:t,hoistingLimits:n,fastLookupPossible:!0},o;s.debugLevel>=0&&(o=Date.now());let a=N4e(r,s),l=!1,c=0;do l=IL(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=Tm(a);if(IL(a,[a],new Set([a.locator]),new Map,s).isGraphChanged)throw new Error(`The hoisting result is not terminal, prev tree: -${u}, next tree: -${Tm(a)}`);let f=fAe(a);if(f)throw new Error(`${f}, after hoisting finished: -${Tm(a)}`)}return s.debugLevel>=2&&console.log(Tm(a)),L4e(a)},T4e=r=>{let e=r[r.length-1],t=new Map,i=new Set,n=s=>{if(!i.has(s)){i.add(s);for(let o of s.hoistedDependencies.values())t.set(o.name,o);for(let o of s.dependencies.values())s.peerNames.has(o.name)||n(o)}};return n(e),t},O4e=r=>{let e=r[r.length-1],t=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 r)u=g.dependencies.get(c.name),u&&t.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),t},pAe=(r,e)=>{if(e.decoupled)return e;let{name:t,references:i,ident:n,locator:s,dependencies:o,originalDependencies:a,hoistedDependencies:l,peerNames:c,reasons:u,isHoistBorder:g,hoistPriority:f,dependencyKind:h,hoistedFrom:p,hoistedTo:m}=e,y={name:t,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,dependencyKind:h,hoistedFrom:new Map(p),hoistedTo:new Map(m)},b=y.dependencies.get(t);return b&&b.ident==y.ident&&y.dependencies.set(t,y),r.dependencies.set(y.name,y),y},M4e=(r,e)=>{let t=new Map([[r.name,[r.ident]]]);for(let n of r.dependencies.values())r.peerNames.has(n.name)||t.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(!r.peerNames.has(s)){let a=t.get(s);a||(a=[],t.set(s,a)),a.indexOf(o)<0&&a.push(o)}}return t},yL=r=>{let e=new Set,t=(i,n=new Set)=>{if(!n.has(i)){n.add(i);for(let s of i.peerNames)if(!r.peerNames.has(s)){let o=r.dependencies.get(s);o&&!e.has(o)&&t(o,n)}e.add(i)}};for(let i of r.dependencies.values())r.peerNames.has(i.name)||t(i);return e},IL=(r,e,t,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=U4e(o),l=M4e(o,a),c=r==o?new Map:n.fastLookupPossible?T4e(e):O4e(e),u,g=!1,f=!1,h=new Map(Array.from(l.entries()).map(([m,y])=>[m,y[0]])),p=new Map;do{let m=K4e(r,e,t,c,h,l,i,p,n);m.isGraphChanged&&(f=!0),m.anotherRoundNeeded&&(g=!0),u=!1;for(let[y,b]of l)b.length>1&&!o.dependencies.has(y)&&(h.delete(y),b.shift(),h.set(y,b[0]),u=!0)}while(u);for(let m of o.dependencies.values())if(!o.peerNames.has(m.name)&&!t.has(m.locator)){t.add(m.locator);let y=IL(r,[...e,m],t,p,n);y.isGraphChanged&&(f=!0),y.anotherRoundNeeded&&(g=!0),t.delete(m.locator)}return{anotherRoundNeeded:g,isGraphChanged:f}},H4e=r=>{for(let[e,t]of r.dependencies)if(!r.peerNames.has(e)&&t.ident!==r.ident)return!0;return!1},j4e=(r,e,t,i,n,s,o,a,{outputReason:l,fastLookupPossible:c})=>{let u,g=null,f=new Set;l&&(u=`${Array.from(e).map(y=>Li(y)).join("\u2192")}`);let h=t[t.length-1],m=!(i.ident===h.ident);if(l&&!m&&(g="- self-reference"),m&&(m=i.dependencyKind!==1,l&&!m&&(g="- workspace")),m&&i.dependencyKind===2&&(m=!H4e(i),l&&!m&&(g="- external soft link with unhoisted dependencies")),m&&(m=h.dependencyKind!==1||h.hoistedFrom.has(i.name)||e.size===1,l&&!m&&(g=h.reasons.get(i.name))),m&&(m=!r.peerNames.has(i.name),l&&!m&&(g=`- cannot shadow peer: ${Li(r.originalDependencies.get(i.name).locator)} at ${u}`)),m){let y=!1,b=n.get(i.name);if(y=!b||b.ident===i.ident,l&&!y&&(g=`- filled by: ${Li(b.locator)} at ${u}`),y)for(let v=t.length-1;v>=1;v--){let T=t[v].dependencies.get(i.name);if(T&&T.ident!==i.ident){y=!1;let q=a.get(h);q||(q=new Set,a.set(h,q)),q.add(i.name),l&&(g=`- filled by ${Li(T.locator)} at ${t.slice(0,v).map(Y=>Li(Y.locator)).join("\u2192")}`);break}}m=y}if(m&&(m=s.get(i.name)===i.ident,l&&!m&&(g=`- filled by: ${Li(o.get(i.name)[0])} at ${u}`)),m){let y=!0,b=new Set(i.peerNames);for(let v=t.length-1;v>=1;v--){let x=t[v];for(let T of b){if(x.peerNames.has(T)&&x.originalDependencies.has(T))continue;let q=x.dependencies.get(T);q&&r.dependencies.get(T)!==q&&(v===t.length-1?f.add(q):(f=null,y=!1,l&&(g=`- peer dependency ${Li(q.locator)} from parent ${Li(x.locator)} was not hoisted to ${u}`))),b.delete(T)}if(!y)break}m=y}if(m&&!c)for(let y of i.hoistedDependencies.values()){let b=n.get(y.name)||r.dependencies.get(y.name);if(!b||y.ident!==b.ident){m=!1,l&&(g=`- previously hoisted dependency mismatch, needed: ${Li(y.locator)}, available: ${Li(b==null?void 0:b.locator)}`);break}}return f!==null&&f.size>0?{isHoistable:2,dependsOn:f,reason:g}:{isHoistable:m?0:1,reason:g}},$0=r=>`${r.name}@${r.locator}`,K4e=(r,e,t,i,n,s,o,a,l)=>{let c=e[e.length-1],u=new Set,g=!1,f=!1,h=(b,v,x,T,q)=>{if(u.has(T))return;let Y=[...v,$0(T)],$=[...x,$0(T)],_=new Map,ne=new Map;for(let Z of yL(T)){let O=j4e(c,t,[c,...b,T],Z,i,n,s,a,{outputReason:l.debugLevel>=2,fastLookupPossible:l.fastLookupPossible});if(ne.set(Z,O),O.isHoistable===2)for(let L of O.dependsOn){let de=_.get(L.name)||new Set;de.add(Z.name),_.set(L.name,de)}}let ee=new Set,A=(Z,O,L)=>{if(!ee.has(Z)){ee.add(Z),ne.set(Z,{isHoistable:1,reason:L});for(let de of _.get(Z.name)||[])A(T.dependencies.get(de),O,l.debugLevel>=2?`- peer dependency ${Li(Z.locator)} from parent ${Li(T.locator)} was not hoisted`:"")}};for(let[Z,O]of ne)O.isHoistable===1&&A(Z,O,O.reason);let oe=!1;for(let Z of ne.keys())if(!ee.has(Z)){f=!0;let O=o.get(T);O&&O.has(Z.name)&&(g=!0),oe=!0,T.dependencies.delete(Z.name),T.hoistedDependencies.set(Z.name,Z),T.reasons.delete(Z.name);let L=c.dependencies.get(Z.name);if(l.debugLevel>=2){let de=Array.from(v).concat([T.locator]).map(je=>Li(je)).join("\u2192"),Be=c.hoistedFrom.get(Z.name);Be||(Be=[],c.hoistedFrom.set(Z.name,Be)),Be.push(de),T.hoistedTo.set(Z.name,Array.from(e).map(je=>Li(je.locator)).join("\u2192"))}if(!L)c.ident!==Z.ident&&(c.dependencies.set(Z.name,Z),q.add(Z));else for(let de of Z.references)L.references.add(de)}if(T.dependencyKind===2&&oe&&(g=!0),l.check){let Z=fAe(r);if(Z)throw new Error(`${Z}, after hoisting dependencies of ${[c,...b,T].map(O=>Li(O.locator)).join("\u2192")}: -${Tm(r)}`)}let ce=yL(T);for(let Z of ce)if(ee.has(Z)){let O=ne.get(Z);if((n.get(Z.name)===Z.ident||!T.reasons.has(Z.name))&&O.isHoistable!==0&&T.reasons.set(Z.name,O.reason),!Z.isHoistBorder&&$.indexOf($0(Z))<0){u.add(T);let de=pAe(T,Z);h([...b,T],Y,$,de,m),u.delete(T)}}},p,m=new Set(yL(c)),y=Array.from(e).map(b=>$0(b));do{p=m,m=new Set;for(let b of p){if(b.locator===c.locator||b.isHoistBorder)continue;let v=pAe(c,b);h([],Array.from(t),y,v,m)}}while(m.size>0);return{anotherRoundNeeded:g,isGraphChanged:f}},fAe=r=>{let e=[],t=new Set,i=new Set,n=(s,o,a)=>{if(t.has(s)||(t.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=>Li(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(", ")}`:""}`,m=`${h?` hoisted to ${h}`:""}`,y=`${g()}${p}`;u?u.ident!==c.ident&&e.push(`${y} - broken require promise for ${c.name}${m}: expected ${c.ident}, but found: ${u.ident}`):e.push(`${y} - broken require promise: no required dependency ${c.name}${m} 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(r,r.dependencies,r),e.join(` -`)},N4e=(r,e)=>{let{identName:t,name:i,reference:n,peerNames:s}=r,o={name:i,references:new Set([n]),locator:EL(t,n),ident:gAe(t,n),dependencies:new Map,originalDependencies:new Map,hoistedDependencies:new Map,peerNames:new Set(s),reasons:new Map,decoupled:!0,isHoistBorder:!0,hoistPriority:0,dependencyKind:1,hoistedFrom:new Map,hoistedTo:new Map},a=new Map([[r,o]]),l=(c,u)=>{let g=a.get(c),f=!!g;if(!g){let{name:h,identName:p,reference:m,peerNames:y,hoistPriority:b,dependencyKind:v}=c,x=e.hoistingLimits.get(u.locator);g={name:h,references:new Set([m]),locator:EL(p,m),ident:gAe(p,m),dependencies:new Map,originalDependencies:new Map,hoistedDependencies:new Map,peerNames:new Set(y),reasons:new Map,decoupled:!0,isHoistBorder:x?x.has(h):!1,hoistPriority:b||0,dependencyKind:v||0,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=m=>{if(!h.has(m)){h.add(m),m.decoupled=!1;for(let y of m.dependencies.values())m.peerNames.has(y.name)||p(y)}};p(g)}else for(let h of c.dependencies)l(h,g)};for(let c of r.dependencies)l(c,o);return o},wL=r=>r.substring(0,r.indexOf("@",1)),L4e=r=>{let e={name:r.name,identName:wL(r.locator),references:new Set(r.references),dependencies:new Set},t=new Set([r]),i=(n,s,o)=>{let a=t.has(n),l;if(s===n)l=o;else{let{name:c,references:u,locator:g}=n;l={name:c,identName:wL(g),references:u,dependencies:new Set}}if(o.dependencies.add(l),!a){t.add(n);for(let c of n.dependencies.values())n.peerNames.has(c.name)||i(c,n,l);t.delete(n)}};for(let n of r.dependencies.values())i(n,r,e);return e},U4e=r=>{let e=new Map,t=new Set([r]),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=!!t.has(a);if(n(a).dependents.add(o.ident),!l){t.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 r.dependencies.values())r.peerNames.has(o.name)||s(r,o);return e},Li=r=>{if(!r)return"none";let e=r.indexOf("@",1),t=r.substring(0,e);t.endsWith("$wsroot$")&&(t=`wh:${t.replace("$wsroot$","")}`);let i=r.substring(e+1);if(i==="workspace:.")return".";if(i){let n=(i.indexOf("#")>0?i.split("#")[1]:i).replace("npm:","");return i.startsWith("virtual")&&(t=`v:${t}`),n.startsWith("workspace")&&(t=`w:${t}`,n=""),`${t}${n?`@${n}`:""}`}else return`${t}`},dAe=5e4,Tm=r=>{let e=0,t=(n,s,o="")=>{if(e>dAe||s.has(n))return"";e++;let a=Array.from(n.dependencies.values()).sort((c,u)=>c.name===u.name?0:c.name>u.name?1:-1),l="";s.add(n);for(let c=0;c":"")+(f!==u.name?`a:${u.name}:`:"")+Li(u.locator)+(g?` ${g}`:"")} -`,l+=t(u,s,`${o}${cdAe?` -Tree is too large, part of the tree has been dunped -`:"")};var wo;(function(t){t.HARD="HARD",t.SOFT="SOFT"})(wo||(wo={}));var Kn;(function(i){i.WORKSPACES="workspaces",i.DEPENDENCIES="dependencies",i.NONE="none"})(Kn||(Kn={}));var CAe="node_modules",Su="$wsroot$";var Om=(r,e)=>{let{packageTree:t,hoistingLimits:i,errors:n,preserveSymlinksRequired:s}=G4e(r,e),o=null;if(n.length===0){let a=hAe(t,{hoistingLimits:i});o=Y4e(r,a,e)}return{tree:o,errors:n,preserveSymlinksRequired:s}},da=r=>`${r.name}@${r.reference}`,BL=r=>{let e=new Map;for(let[t,i]of r.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(t)}for(let t of e.values())t.locations=t.locations.sort((i,n)=>{let s=i.split(k.delimiter).length,o=n.split(k.delimiter).length;return n===i?0:s!==o?o-s:n>i?1:-1});return e},mAe=(r,e)=>{let t=P.isVirtualLocator(r)?P.devirtualizeLocator(r):r,i=P.isVirtualLocator(e)?P.devirtualizeLocator(e):e;return P.areLocatorsEqual(t,i)},bL=(r,e,t,i)=>{if(r.linkType!==wo.SOFT)return!1;let n=H.toPortablePath(t.resolveVirtual&&e.reference&&e.reference.startsWith("virtual:")?t.resolveVirtual(r.packageLocation):r.packageLocation);return k.contains(i,n)===null},q4e=r=>{let e=r.getPackageInformation(r.topLevel);if(e===null)throw new Error("Assertion failed: Expected the top-level package to have been registered");if(r.findPackageLocator(e.packageLocation)===null)throw new Error("Assertion failed: Expected the top-level package to have a physical locator");let i=H.toPortablePath(e.packageLocation.slice(0,-1)),n=new Map,s={children:new Map},o=r.getDependencyTreeRoots(),a=new Map,l=new Set,c=(f,h)=>{let p=da(f);if(l.has(p))return;l.add(p);let m=r.getPackageInformation(f);if(m){let y=h?da(h):"";if(da(f)!==y&&m.linkType===wo.SOFT&&!bL(m,f,r,i)){let b=EAe(m,f,r);(!a.get(b)||f.reference.startsWith("workspace:"))&&a.set(b,f)}for(let[b,v]of m.packageDependencies)v!==null&&(m.packagePeers.has(b)||c(r.getLocator(b,v),f))}};for(let f of o)c(f,null);let u=i.split(k.sep);for(let f of a.values()){let h=r.getPackageInformation(f),m=H.toPortablePath(h.packageLocation.slice(0,-1)).split(k.sep).slice(u.length),y=s;for(let b of m){let v=y.children.get(b);v||(v={children:new Map},y.children.set(b,v)),y=v}y.workspaceLocator=f}let g=(f,h)=>{if(f.workspaceLocator){let p=da(h),m=n.get(p);m||(m=new Set,n.set(p,m)),m.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},G4e=(r,e)=>{let t=[],i=!1,n=new Map,s=q4e(r),o=r.getPackageInformation(r.topLevel);if(o===null)throw new Error("Assertion failed: Expected the top-level package to have been registered");let a=r.findPackageLocator(o.packageLocation);if(a===null)throw new Error("Assertion failed: Expected the top-level package to have a physical locator");let l=H.toPortablePath(o.packageLocation.slice(0,-1)),c={name:a.name,identName:a.name,reference:a.reference,peerNames:o.packagePeers,dependencies:new Set,dependencyKind:Mn.WORKSPACE},u=new Map,g=(h,p)=>`${da(p)}:${h}`,f=(h,p,m,y,b,v,x,T)=>{var Z,O;let q=g(h,m),Y=u.get(q),$=!!Y;!$&&m.name===a.name&&m.reference===a.reference&&(Y=c,u.set(q,c));let _=bL(p,m,r,l);if(!Y){let L=Mn.REGULAR;_?L=Mn.EXTERNAL_SOFT_LINK:p.linkType===wo.SOFT&&m.name.endsWith(Su)&&(L=Mn.WORKSPACE),Y={name:h,identName:m.name,reference:m.reference,dependencies:new Set,peerNames:L===Mn.WORKSPACE?new Set:p.packagePeers,dependencyKind:L},u.set(q,Y)}let ne;if(_?ne=2:b.linkType===wo.SOFT?ne=1:ne=0,Y.hoistPriority=Math.max(Y.hoistPriority||0,ne),T&&!_){let L=da({name:y.identName,reference:y.reference}),de=n.get(L)||new Set;n.set(L,de),de.add(Y.name)}let ee=new Map(p.packageDependencies);if(e.project){let L=e.project.workspacesByCwd.get(H.toPortablePath(p.packageLocation.slice(0,-1)));if(L){let de=new Set([...Array.from(L.manifest.peerDependencies.values(),Be=>P.stringifyIdent(Be)),...Array.from(L.manifest.peerDependenciesMeta.keys())]);for(let Be of de)ee.has(Be)||(ee.set(Be,v.get(Be)||null),Y.peerNames.add(Be))}}let A=da({name:m.name.replace(Su,""),reference:m.reference}),oe=s.get(A);if(oe)for(let L of oe)ee.set(`${L.name}${Su}`,L.reference);(p!==b||p.linkType!==wo.SOFT||!_&&(!e.selfReferencesByCwd||e.selfReferencesByCwd.get(x)))&&y.dependencies.add(Y);let ce=m!==a&&p.linkType===wo.SOFT&&!m.name.endsWith(Su)&&!_;if(!$&&!ce){let L=new Map;for(let[de,Be]of ee)if(Be!==null){let je=r.getLocator(de,Be),re=r.getLocator(de.replace(Su,""),Be),se=r.getPackageInformation(re);if(se===null)throw new Error("Assertion failed: Expected the package to have been registered");let be=bL(se,je,r,l);if(e.validateExternalSoftLinks&&e.project&&be){se.packageDependencies.size>0&&(i=!0);for(let[ve,pe]of se.packageDependencies)if(pe!==null){let V=P.parseLocator(Array.isArray(pe)?`${pe[0]}@${pe[1]}`:`${ve}@${pe}`);if(da(V)!==da(je)){let Qe=ee.get(ve);if(Qe){let le=P.parseLocator(Array.isArray(Qe)?`${Qe[0]}@${Qe[1]}`:`${ve}@${Qe}`);mAe(le,V)||t.push({messageName:X.NM_CANT_INSTALL_EXTERNAL_SOFT_LINK,text:`Cannot link ${P.prettyIdent(e.project.configuration,P.parseIdent(je.name))} into ${P.prettyLocator(e.project.configuration,P.parseLocator(`${m.name}@${m.reference}`))} dependency ${P.prettyLocator(e.project.configuration,V)} conflicts with parent dependency ${P.prettyLocator(e.project.configuration,le)}`})}else{let le=L.get(ve);if(le){let fe=le.target,gt=P.parseLocator(Array.isArray(fe)?`${fe[0]}@${fe[1]}`:`${ve}@${fe}`);mAe(gt,V)||t.push({messageName:X.NM_CANT_INSTALL_EXTERNAL_SOFT_LINK,text:`Cannot link ${P.prettyIdent(e.project.configuration,P.parseIdent(je.name))} into ${P.prettyLocator(e.project.configuration,P.parseLocator(`${m.name}@${m.reference}`))} dependency ${P.prettyLocator(e.project.configuration,V)} conflicts with dependency ${P.prettyLocator(e.project.configuration,gt)} from sibling portal ${P.prettyIdent(e.project.configuration,P.parseIdent(le.portal.name))}`})}else L.set(ve,{target:V.reference,portal:je})}}}}let he=(Z=e.hoistingLimitsByCwd)==null?void 0:Z.get(x),Fe=be?x:k.relative(l,H.toPortablePath(se.packageLocation))||Me.dot,Ke=(O=e.hoistingLimitsByCwd)==null?void 0:O.get(Fe),ke=he===Kn.DEPENDENCIES||Ke===Kn.DEPENDENCIES||Ke===Kn.WORKSPACES;f(de,se,je,Y,p,ee,Fe,ke)}}};return f(a.name,o,a,c,o,o.packageDependencies,Me.dot,!1),{packageTree:c,hoistingLimits:n,errors:t,preserveSymlinksRequired:i}};function EAe(r,e,t){let i=t.resolveVirtual&&e.reference&&e.reference.startsWith("virtual:")?t.resolveVirtual(r.packageLocation):r.packageLocation;return H.toPortablePath(i||r.packageLocation)}function J4e(r,e,t){let i=e.getLocator(r.name.replace(Su,""),r.reference),n=e.getPackageInformation(i);if(n===null)throw new Error("Assertion failed: Expected the package to be registered");let s,o;return t.pnpifyFs?(o=H.toPortablePath(n.packageLocation),s=wo.SOFT):(o=EAe(n,r,e),s=n.linkType),{linkType:s,target:o}}var Y4e=(r,e,t)=>{let i=new Map,n=(u,g,f)=>{let{linkType:h,target:p}=J4e(u,r,t);return{locator:da(u),nodePath:g,target:p,linkType:h,aliases:f}},s=u=>{let[g,f]=u.split("/");return f?{scope:Jr(g),name:Jr(f)}:{scope:null,name:Jr(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(),m={name:h.identName,reference:p[0]},{name:y,scope:b}=s(h.name),v=b?[b,y]:[y],x=k.join(g,CAe),T=k.join(x,...v),q=`${f}/${m.name}`,Y=n(m,f,p.slice(1)),$=!1;if(Y.linkType===wo.SOFT&&t.project){let _=t.project.workspacesByCwd.get(Y.target.slice(0,-1));$=!!(_&&!_.manifest.name)}if(!h.name.endsWith(Su)&&!$){let _=i.get(T);if(_){if(_.dirList)throw new Error(`Assertion failed: ${T} cannot merge dir node with leaf node`);{let oe=P.parseLocator(_.locator),ce=P.parseLocator(Y.locator);if(_.linkType!==Y.linkType)throw new Error(`Assertion failed: ${T} cannot merge nodes with different link types ${_.nodePath}/${P.stringifyLocator(oe)} and ${f}/${P.stringifyLocator(ce)}`);if(oe.identHash!==ce.identHash)throw new Error(`Assertion failed: ${T} cannot merge nodes with different idents ${_.nodePath}/${P.stringifyLocator(oe)} and ${f}/s${P.stringifyLocator(ce)}`);Y.aliases=[...Y.aliases,..._.aliases,P.parseLocator(_.locator).reference]}}i.set(T,Y);let ne=T.split("/"),ee=ne.indexOf(CAe),A=ne.length-1;for(;ee>=0&&A>ee;){let oe=H.toPortablePath(ne.slice(0,A).join(k.sep)),ce=Jr(ne[A]),Z=i.get(oe);if(!Z)i.set(oe,{dirList:new Set([ce])});else if(Z.dirList){if(Z.dirList.has(ce))break;Z.dirList.add(ce)}A--}}a(h,Y.linkType===wo.SOFT?Y.target:T,q)}}},l=n({name:e.name,reference:Array.from(e.references)[0]},"",[]),c=l.target;return i.set(c,l),a(e,c,""),i};var LL={};ft(LL,{PnpInstaller:()=>oh,PnpLinker:()=>xu,default:()=>d8e,getPnpPath:()=>Tl,jsInstallUtils:()=>Ca,pnpUtils:()=>FL,quotePathIfNeeded:()=>GAe});var HAe=ge(ri()),jAe=ge(require("url"));var IAe;(function(t){t.HARD="HARD",t.SOFT="SOFT"})(IAe||(IAe={}));var er;(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"})(er||(er={}));var yAe={[er.DEFAULT]:{collapsed:!1,next:{["*"]:er.DEFAULT}},[er.TOP_LEVEL]:{collapsed:!1,next:{fallbackExclusionList:er.FALLBACK_EXCLUSION_LIST,packageRegistryData:er.PACKAGE_REGISTRY_DATA,["*"]:er.DEFAULT}},[er.FALLBACK_EXCLUSION_LIST]:{collapsed:!1,next:{["*"]:er.FALLBACK_EXCLUSION_ENTRIES}},[er.FALLBACK_EXCLUSION_ENTRIES]:{collapsed:!0,next:{["*"]:er.FALLBACK_EXCLUSION_DATA}},[er.FALLBACK_EXCLUSION_DATA]:{collapsed:!0,next:{["*"]:er.DEFAULT}},[er.PACKAGE_REGISTRY_DATA]:{collapsed:!1,next:{["*"]:er.PACKAGE_REGISTRY_ENTRIES}},[er.PACKAGE_REGISTRY_ENTRIES]:{collapsed:!0,next:{["*"]:er.PACKAGE_STORE_DATA}},[er.PACKAGE_STORE_DATA]:{collapsed:!1,next:{["*"]:er.PACKAGE_STORE_ENTRIES}},[er.PACKAGE_STORE_ENTRIES]:{collapsed:!0,next:{["*"]:er.PACKAGE_INFORMATION_DATA}},[er.PACKAGE_INFORMATION_DATA]:{collapsed:!1,next:{packageDependencies:er.PACKAGE_DEPENDENCIES,["*"]:er.DEFAULT}},[er.PACKAGE_DEPENDENCIES]:{collapsed:!1,next:{["*"]:er.PACKAGE_DEPENDENCY}},[er.PACKAGE_DEPENDENCY]:{collapsed:!0,next:{["*"]:er.DEFAULT}}};function W4e(r,e,t){let i="";i+="[";for(let n=0,s=r.length;ns(o)));let n=t.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=>t[s])}function X4e(r){let e=new Map,t=Mm(r.fallbackExclusionList||[],[({name:i,reference:n})=>i,({name:i,reference:n})=>n]);for(let{name:i,reference:n}of t){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 Z4e(r){return Mm(r.fallbackPool||[],([e])=>e)}function $4e(r){let e=[];for(let[t,i]of Mm(r.packageRegistry,([n])=>n===null?"0":`1${n}`)){let n=[];e.push([t,n]);for(let[s,{packageLocation:o,packageDependencies:a,packagePeers:l,linkType:c,discardFromLookup:u}]of Mm(i,([g])=>g===null?"0":`1${g}`)){let g=[];t!==null&&s!==null&&!a.has(t)&&g.push([t,s]);for(let[p,m]of Mm(a.entries(),([y])=>y))g.push([p,m]);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 Km(r){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:r.dependencyTreeRoots,enableTopLevelFallback:r.enableTopLevelFallback||!1,ignorePatternData:r.ignorePattern||null,fallbackExclusionList:X4e(r),fallbackPool:Z4e(r),packageRegistryData:$4e(r)}}var SAe=ge(QAe());function vAe(r,e){return[r?`${r} -`:"",`/* 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",`} -`,` -`,`function $$SETUP_STATE(hydrateRuntimeState, basePath) { -`,e.replace(/^/gm," "),`} -`,` -`,(0,SAe.default)()].join("")}function e8e(r){return JSON.stringify(r,null,2)}function t8e(r){return`'${r.replace(/\\/g,"\\\\").replace(/'/g,"\\'").replace(/\n/g,`\\ -`)}'`}function r8e(r){return[`return hydrateRuntimeState(JSON.parse(${t8e(BAe(r))}), {basePath: basePath || __dirname}); -`].join("")}function i8e(r){return[`var path = require('path'); -`,`var dataLocation = path.resolve(__dirname, ${JSON.stringify(r)}); -`,`return hydrateRuntimeState(require(dataLocation), {basePath: basePath || path.dirname(dataLocation)}); -`].join("")}function xAe(r){let e=Km(r),t=r8e(e);return vAe(r.shebang,t)}function kAe(r){let e=Km(r),t=i8e(r.dataLocation),i=vAe(r.shebang,t);return{dataFile:e8e(e),loaderFile:i}}var RAe=ge(require("fs")),l8e=ge(require("path")),FAe=ge(require("util"));function SL(r,{basePath:e}){let t=H.toPortablePath(e),i=k.resolve(t),n=r.ignorePatternData!==null?new RegExp(r.ignorePatternData):null,s=new Map,o=new Map(r.packageRegistryData.map(([g,f])=>[g,new Map(f.map(([h,p])=>{var x;if(g===null!=(h===null))throw new Error("Assertion failed: The name and reference should be null, or neither should");let m=(x=p.discardFromLookup)!=null?x:!1,y={name:g,reference:h},b=s.get(p.packageLocation);b?(b.discardFromLookup=b.discardFromLookup&&m,m||(b.locator=y)):s.set(p.packageLocation,{locator:y,discardFromLookup:m});let v=null;return[h,{packageDependencies:new Map(p.packageDependencies),packagePeers:new Set(p.packagePeers),linkType:p.linkType,discardFromLookup:m,get packageLocation(){return v||(v=k.join(i,p.packageLocation))}}]}))])),a=new Map(r.fallbackExclusionList.map(([g,f])=>[g,new Set(f)])),l=new Map(r.fallbackPool),c=r.dependencyTreeRoots,u=r.enableTopLevelFallback;return{basePath:t,dependencyTreeRoots:c,enableTopLevelFallback:u,fallbackExclusionList:a,fallbackPool:l,ignorePattern:n,packageLocatorsByLocations:s,packageRegistry:o}}var Um=ge(require("module"));function sh(r,e){if(typeof r=="string")return r;if(r){let t,i;if(Array.isArray(r)){for(t=0;t0)return(f=sh(n[g],u))?f.replace("*",c.substring(g.length-1)):vu(i,c,1)}return vu(i,c)}}var vL=ge(require("util"));var ur;(function(c){c.API_ERROR="API_ERROR",c.BUILTIN_NODE_RESOLUTION_FAILED="BUILTIN_NODE_RESOLUTION_FAILED",c.EXPORTS_RESOLUTION_FAILED="EXPORTS_RESOLUTION_FAILED",c.MISSING_DEPENDENCY="MISSING_DEPENDENCY",c.MISSING_PEER_DEPENDENCY="MISSING_PEER_DEPENDENCY",c.QUALIFIED_PATH_RESOLUTION_FAILED="QUALIFIED_PATH_RESOLUTION_FAILED",c.INTERNAL="INTERNAL",c.UNDECLARED_DEPENDENCY="UNDECLARED_DEPENDENCY",c.UNSUPPORTED="UNSUPPORTED"})(ur||(ur={}));var s8e=new Set([ur.BUILTIN_NODE_RESOLUTION_FAILED,ur.MISSING_DEPENDENCY,ur.MISSING_PEER_DEPENDENCY,ur.QUALIFIED_PATH_RESOLUTION_FAILED,ur.UNDECLARED_DEPENDENCY]);function ai(r,e,t={},i){i!=null||(i=s8e.has(r)?"MODULE_NOT_FOUND":r);let n={configurable:!0,writable:!0,enumerable:!1};return Object.defineProperties(new Error(e),{code:te(N({},n),{value:i}),pnpCode:te(N({},n),{value:r}),data:te(N({},n),{value:t})})}function Bo(r){return H.normalize(H.fromPortablePath(r))}var o8e=ge(require("fs")),DAe=ge(require("module")),a8e=ge(require("path")),A8e=new Set(DAe.Module.builtinModules||Object.keys(process.binding("natives"))),tb=r=>r.startsWith("node:")||A8e.has(r);function xL(r,e){let t=Number(process.env.PNP_ALWAYS_WARN_ON_FALLBACK)>0,i=Number(process.env.PNP_DEBUG_LEVEL),n=/^(?![a-zA-Z]:[\\/]|\\\\|\.{0,2}(?:\/|$))((?:node:)?(?:@[^/]+\/)?[^/]+)\/*(.*|)$/,s=/^(\/|\.{1,2}(\/|$))/,o=/\/$/,a=/^\.{0,2}\//,l={name:null,reference:null},c=[],u=new Set;if(r.enableTopLevelFallback===!0&&c.push(l),e.compatibilityMode!==!1)for(let re of["react-scripts","gatsby"]){let se=r.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");c.push({name:re,reference:be})}}let{ignorePattern:g,packageRegistry:f,packageLocatorsByLocations:h}=r;function p(re,se){return{fn:re,args:se,error:null,result:null}}function m(re){var Ke,ke,ve,pe,V,Qe;let se=(ve=(ke=(Ke=process.stderr)==null?void 0:Ke.hasColors)==null?void 0:ke.call(Ke))!=null?ve:process.stdout.isTTY,be=(le,fe)=>`[${le}m${fe}`,he=re.error;console.error(he?be("31;1",`\u2716 ${(pe=re.error)==null?void 0:pe.message.replace(/\n.*/s,"")}`):be("33;1","\u203C Resolution")),re.args.length>0&&console.error();for(let le of re.args)console.error(` ${be("37;1","In \u2190")} ${(0,vL.inspect)(le,{colors:se,compact:!0})}`);re.result&&(console.error(),console.error(` ${be("37;1","Out \u2192")} ${(0,vL.inspect)(re.result,{colors:se,compact:!0})}`));let Fe=(Qe=(V=new Error().stack.match(/(?<=^ +)at.*/gm))==null?void 0:V.slice(2))!=null?Qe:[];if(Fe.length>0){console.error();for(let le of Fe)console.error(` ${be("38;5;244",le)}`)}console.error()}function y(re,se){if(e.allowDebug===!1)return se;if(Number.isFinite(i)){if(i>=2)return(...be)=>{let he=p(re,be);try{return he.result=se(...be)}catch(Fe){throw he.error=Fe}finally{m(he)}};if(i>=1)return(...be)=>{try{return se(...be)}catch(he){let Fe=p(re,be);throw Fe.error=he,m(Fe),he}}}return se}function b(re){let se=A(re);if(!se)throw ai(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 v(re){if(re.name===null)return!0;for(let se of r.dependencyTreeRoots)if(se.name===re.name&&se.reference===re.reference)return!0;return!1}let x=new Set(["default","node","require"]);function T(re,se=x){let be=Z(k.join(re,"internal.js"),{resolveIgnored:!0,includeDiscardFromLookup:!0});if(be===null)throw ai(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:he}=b(be),Fe=k.join(he,kt.manifest);if(!e.fakeFs.existsSync(Fe))return null;let Ke=JSON.parse(e.fakeFs.readFileSync(Fe,"utf8")),ke=k.contains(he,re);if(ke===null)throw ai(ur.INTERNAL,"unqualifiedPath doesn't contain the packageLocation (this is probably an internal error)");a.test(ke)||(ke=`./${ke}`);let ve;try{ve=PAe(Ke,k.normalize(ke),{conditions:se,unsafe:!0})}catch(pe){throw ai(ur.EXPORTS_RESOLUTION_FAILED,pe.message,{unqualifiedPath:Bo(re),locator:be,pkgJson:Ke,subpath:Bo(ke),conditions:se},"ERR_PACKAGE_PATH_NOT_EXPORTED")}return typeof ve=="string"?k.join(he,ve):null}function q(re,se,{extensions:be}){let he;try{se.push(re),he=e.fakeFs.statSync(re)}catch(Fe){}if(he&&!he.isDirectory())return e.fakeFs.realpathSync(re);if(he&&he.isDirectory()){let Fe;try{Fe=JSON.parse(e.fakeFs.readFileSync(k.join(re,kt.manifest),"utf8"))}catch(ke){}let Ke;if(Fe&&Fe.main&&(Ke=k.resolve(re,Fe.main)),Ke&&Ke!==re){let ke=q(Ke,se,{extensions:be});if(ke!==null)return ke}}for(let Fe=0,Ke=be.length;Fe{let ve=JSON.stringify(ke.name);if(he.has(ve))return;he.add(ve);let pe=oe(ke);for(let V of pe)if(b(V).packagePeers.has(re))Fe(V);else{let le=be.get(V.name);typeof le=="undefined"&&be.set(V.name,le=new Set),le.add(V.reference)}};Fe(se);let Ke=[];for(let ke of[...be.keys()].sort())for(let ve of[...be.get(ke)].sort())Ke.push({name:ke,reference:ve});return Ke}function Z(re,{resolveIgnored:se=!1,includeDiscardFromLookup:be=!1}={}){if(_(re)&&!se)return null;let he=k.relative(r.basePath,re);he.match(s)||(he=`./${he}`),he.endsWith("/")||(he=`${he}/`);do{let Fe=h.get(he);if(typeof Fe=="undefined"||Fe.discardFromLookup&&!be){he=he.substring(0,he.lastIndexOf("/",he.length-2)+1);continue}return Fe.locator}while(he!=="");return null}function O(re,se,{considerBuiltins:be=!0}={}){if(re==="pnpapi")return H.toPortablePath(e.pnpapiResolution);if(be&&tb(re))return null;let he=Bo(re),Fe=se&&Bo(se);if(se&&_(se)&&(!k.isAbsolute(re)||Z(re)===null)){let ve=$(re,se);if(ve===!1)throw ai(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: "${he}" -Required by: ${Fe} -`,{request:he,issuer:Fe});return H.toPortablePath(ve)}let Ke,ke=re.match(n);if(ke){if(!se)throw ai(ur.API_ERROR,"The resolveToUnqualified function must be called with a valid issuer when the path isn't a builtin nor absolute",{request:he,issuer:Fe});let[,ve,pe]=ke,V=Z(se);if(!V){let jt=$(re,se);if(jt===!1)throw ai(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: "${he}" -Required by: ${Fe} -`,{request:he,issuer:Fe});return H.toPortablePath(jt)}let le=b(V).packageDependencies.get(ve),fe=null;if(le==null&&V.name!==null){let jt=r.fallbackExclusionList.get(V.name);if(!jt||!jt.has(V.reference)){for(let Oi=0,Xs=c.length;Oiv(Qr))?gt=ai(ur.MISSING_PEER_DEPENDENCY,`${V.name} tried to access ${ve} (a peer dependency) but it isn't provided by your application; this makes the require call ambiguous and unsound. - -Required package: ${ve}${ve!==he?` (via "${he}")`:""} -Required by: ${V.name}@${V.reference} (via ${Fe}) -${jt.map(Qr=>`Ancestor breaking the chain: ${Qr.name}@${Qr.reference} -`).join("")} -`,{request:he,issuer:Fe,issuerLocator:Object.assign({},V),dependencyName:ve,brokenAncestors:jt}):gt=ai(ur.MISSING_PEER_DEPENDENCY,`${V.name} tried to access ${ve} (a peer dependency) but it isn't provided by its ancestors; this makes the require call ambiguous and unsound. - -Required package: ${ve}${ve!==he?` (via "${he}")`:""} -Required by: ${V.name}@${V.reference} (via ${Fe}) - -${jt.map(Qr=>`Ancestor breaking the chain: ${Qr.name}@${Qr.reference} -`).join("")} -`,{request:he,issuer:Fe,issuerLocator:Object.assign({},V),dependencyName:ve,brokenAncestors:jt})}else le===void 0&&(!be&&tb(re)?v(V)?gt=ai(ur.UNDECLARED_DEPENDENCY,`Your application tried to access ${ve}. 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 ${ve} isn't otherwise declared in your dependencies, this makes the require call ambiguous and unsound. - -Required package: ${ve}${ve!==he?` (via "${he}")`:""} -Required by: ${Fe} -`,{request:he,issuer:Fe,dependencyName:ve}):gt=ai(ur.UNDECLARED_DEPENDENCY,`${V.name} tried to access ${ve}. 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 ${ve} isn't otherwise declared in ${V.name}'s dependencies, this makes the require call ambiguous and unsound. - -Required package: ${ve}${ve!==he?` (via "${he}")`:""} -Required by: ${Fe} -`,{request:he,issuer:Fe,issuerLocator:Object.assign({},V),dependencyName:ve}):v(V)?gt=ai(ur.UNDECLARED_DEPENDENCY,`Your application tried to access ${ve}, but it isn't declared in your dependencies; this makes the require call ambiguous and unsound. - -Required package: ${ve}${ve!==he?` (via "${he}")`:""} -Required by: ${Fe} -`,{request:he,issuer:Fe,dependencyName:ve}):gt=ai(ur.UNDECLARED_DEPENDENCY,`${V.name} tried to access ${ve}, but it isn't declared in its dependencies; this makes the require call ambiguous and unsound. - -Required package: ${ve}${ve!==he?` (via "${he}")`:""} -Required by: ${V.name}@${V.reference} (via ${Fe}) -`,{request:he,issuer:Fe,issuerLocator:Object.assign({},V),dependencyName:ve}));if(le==null){if(fe===null||gt===null)throw gt||new Error("Assertion failed: Expected an error to have been set");le=fe;let jt=gt.message.replace(/\n.*/g,"");gt.message=jt,!u.has(jt)&&i!==0&&(u.add(jt),process.emitWarning(gt))}let Ht=Array.isArray(le)?{name:le[0],reference:le[1]}:{name:ve,reference:le},Mt=b(Ht);if(!Mt.packageLocation)throw ai(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: ${Ht.name}@${Ht.reference}${Ht.name!==he?` (via "${he}")`:""} -Required by: ${V.name}@${V.reference} (via ${Fe}) -`,{request:he,issuer:Fe,dependencyLocator:Object.assign({},Ht)});let Ei=Mt.packageLocation;pe?Ke=k.join(Ei,pe):Ke=Ei}else if(k.isAbsolute(re))Ke=k.normalize(re);else{if(!se)throw ai(ur.API_ERROR,"The resolveToUnqualified function must be called with a valid issuer when the path isn't a builtin nor absolute",{request:he,issuer:Fe});let ve=k.resolve(se);se.match(o)?Ke=k.normalize(k.join(ve,re)):Ke=k.normalize(k.join(k.dirname(ve),re))}return k.normalize(Ke)}function L(re,se,be=x){if(s.test(re))return se;let he=T(se,be);return he?k.normalize(he):se}function de(re,{extensions:se=Object.keys(Um.Module._extensions)}={}){var Fe,Ke;let be=[],he=q(re,be,{extensions:se});if(he)return k.normalize(he);{let ke=Bo(re),ve=Z(re);if(ve){let{packageLocation:pe}=b(ve),V=!0;try{e.fakeFs.accessSync(pe)}catch(Qe){if((Qe==null?void 0:Qe.code)==="ENOENT")V=!1;else{let le=((Ke=(Fe=Qe==null?void 0:Qe.message)!=null?Fe:Qe)!=null?Ke:"empty exception thrown").replace(/^[A-Z]/,fe=>fe.toLowerCase());throw ai(ur.QUALIFIED_PATH_RESOLUTION_FAILED,`Required package exists but could not be accessed (${le}). - -Missing package: ${ve.name}@${ve.reference} -Expected package location: ${Bo(pe)} -`,{unqualifiedPath:ke,extensions:se})}}if(!V){let Qe=pe.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 ai(ur.QUALIFIED_PATH_RESOLUTION_FAILED,`${Qe} - -Missing package: ${ve.name}@${ve.reference} -Expected package location: ${Bo(pe)} -`,{unqualifiedPath:ke,extensions:se})}}throw ai(ur.QUALIFIED_PATH_RESOLUTION_FAILED,`Qualified path resolution failed: we looked for the following paths, but none could be accessed. - -Source path: ${ke} -${be.map(pe=>`Not found: ${Bo(pe)} -`).join("")}`,{unqualifiedPath:ke,extensions:se})}}function Be(re,se,{considerBuiltins:be,extensions:he,conditions:Fe}={}){try{let Ke=O(re,se,{considerBuiltins:be});if(re==="pnpapi")return Ke;if(Ke===null)return null;let ke=()=>se!==null?_(se):!1,ve=(!be||!tb(re))&&!ke()?L(re,Ke,Fe):Ke;return de(ve,{extensions:he})}catch(Ke){throw Object.prototype.hasOwnProperty.call(Ke,"pnpCode")&&Object.assign(Ke.data,{request:Bo(re),issuer:se&&Bo(se)}),Ke}}function je(re){let se=k.normalize(re),be=Wr.resolveVirtual(se);return be!==se?be:null}return{VERSIONS:ne,topLevel:ee,getLocator:(re,se)=>Array.isArray(se)?{name:se[0],reference:se[1]}:{name:re,reference:se},getDependencyTreeRoots:()=>[...r.dependencyTreeRoots],getAllLocators(){let re=[];for(let[se,be]of f)for(let he of be.keys())se!==null&&he!==null&&re.push({name:se,reference:he});return re},getPackageInformation:re=>{let se=A(re);if(se===null)return null;let be=H.fromPortablePath(se.packageLocation);return te(N({},se),{packageLocation:be})},findPackageLocator:re=>Z(H.toPortablePath(re)),resolveToUnqualified:y("resolveToUnqualified",(re,se,be)=>{let he=se!==null?H.toPortablePath(se):null,Fe=O(H.toPortablePath(re),he,be);return Fe===null?null:H.fromPortablePath(Fe)}),resolveUnqualified:y("resolveUnqualified",(re,se)=>H.fromPortablePath(de(H.toPortablePath(re),se))),resolveRequest:y("resolveRequest",(re,se,be)=>{let he=se!==null?H.toPortablePath(se):null,Fe=Be(H.toPortablePath(re),he,be);return Fe===null?null:H.fromPortablePath(Fe)}),resolveVirtual:y("resolveVirtual",re=>{let se=je(H.toPortablePath(re));return se!==null?H.fromPortablePath(se):null})}}var O0t=(0,FAe.promisify)(RAe.readFile);var NAe=(r,e,t)=>{let i=Km(r),n=SL(i,{basePath:e}),s=H.join(e,kt.pnpCjs);return xL(n,{fakeFs:t,pnpapiResolution:s})};var PL=ge(TAe());var Ca={};ft(Ca,{checkAndReportManifestCompatibility:()=>MAe,checkManifestCompatibility:()=>OAe,extractBuildScripts:()=>rb,getExtractHint:()=>DL,hasBindingGyp:()=>RL});function OAe(r){return P.isPackageCompatible(r,Vg.getArchitectureSet())}function MAe(r,e,{configuration:t,report:i}){return OAe(r)?!0:(i==null||i.reportWarningOnce(X.INCOMPATIBLE_ARCHITECTURE,`${P.prettyLocator(t,r)} The ${Vg.getArchitectureName()} architecture is incompatible with this package, ${e} skipped.`),!1)}function rb(r,e,t,{configuration:i,report:n}){let s=[];for(let a of["preinstall","install","postinstall"])e.manifest.scripts.has(a)&&s.push([cs.SCRIPT,a]);return!e.manifest.scripts.has("install")&&e.misc.hasBindingGyp&&s.push([cs.SHELLCODE,"node-gyp rebuild"]),s.length===0?[]:r.linkType!==Qt.HARD?(n==null||n.reportWarningOnce(X.SOFT_LINK_BUILD,`${P.prettyLocator(i,r)} lists build scripts, but is referenced through a soft link. Soft links don't support build scripts, so they'll be ignored.`),[]):t&&t.built===!1?(n==null||n.reportInfoOnce(X.BUILD_DISABLED,`${P.prettyLocator(i,r)} lists build scripts, but its build has been explicitly disabled through configuration.`),[]):!i.get("enableScripts")&&!t.built?(n==null||n.reportWarningOnce(X.DISABLED_BUILD_SCRIPTS,`${P.prettyLocator(i,r)} lists build scripts, but all build scripts have been disabled.`),[]):MAe(r,"build",{configuration:i,report:n})?s:[]}var c8e=new Set([".exe",".h",".hh",".hpp",".c",".cc",".cpp",".java",".jar",".node"]);function DL(r){return r.packageFs.getExtractHint({relevantExtensions:c8e})}function RL(r){let e=k.join(r.prefixPath,"binding.gyp");return r.packageFs.existsSync(e)}var FL={};ft(FL,{getUnpluggedPath:()=>Hm});function Hm(r,{configuration:e}){return k.resolve(e.get("pnpUnpluggedFolder"),P.slugifyLocator(r))}var u8e=new Set([P.makeIdent(null,"nan").identHash,P.makeIdent(null,"node-gyp").identHash,P.makeIdent(null,"node-pre-gyp").identHash,P.makeIdent(null,"node-addon-api").identHash,P.makeIdent(null,"fsevents").identHash,P.makeIdent(null,"open").identHash,P.makeIdent(null,"opn").identHash]),xu=class{constructor(){this.mode="strict";this.pnpCache=new Map}supportsPackage(e,t){return this.isEnabled(t)}async findPackageLocation(e,t){if(!this.isEnabled(t))throw new Error("Assertion failed: Expected the PnP linker to be enabled");let i=Tl(t.project).cjs;if(!K.existsSync(i))throw new Pe(`The project in ${ae.pretty(t.project.configuration,`${t.project.cwd}/package.json`,ae.Type.PATH)} doesn't seem to have been installed - running an install there might help`);let n=Se.getFactoryWithDefault(this.pnpCache,i,()=>Se.dynamicRequire(i,{cachingStrategy:Se.CachingStrategy.FsTime})),s={name:P.stringifyIdent(e),reference:e.reference},o=n.getPackageInformation(s);if(!o)throw new Pe(`Couldn't find ${P.prettyLocator(t.project.configuration,e)} in the currently installed PnP map - running an install might help`);return H.toPortablePath(o.packageLocation)}async findPackageLocator(e,t){if(!this.isEnabled(t))return null;let i=Tl(t.project).cjs;if(!K.existsSync(i))return null;let s=Se.getFactoryWithDefault(this.pnpCache,i,()=>Se.dynamicRequire(i,{cachingStrategy:Se.CachingStrategy.FsTime})).findPackageLocator(H.fromPortablePath(e));return s?P.makeLocator(P.parseIdent(s.name),s.reference):null}makeInstaller(e){return new oh(e)}isEnabled(e){return!(e.project.configuration.get("nodeLinker")!=="pnp"||e.project.configuration.get("pnpMode")!==this.mode)}},oh=class{constructor(e){this.opts=e;this.mode="strict";this.asyncActions=new Se.AsyncActions(10);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,t,i){let n=P.stringifyIdent(e),s=e.reference,o=!!this.opts.project.tryWorkspaceByLocator(e),a=P.isVirtualLocator(e),l=e.peerDependencies.size>0&&!a,c=!l&&!o,u=!l&&e.linkType!==Qt.SOFT,g,f;if(c||u){let x=a?P.devirtualizeLocator(e):e;g=this.customData.store.get(x.locatorHash),typeof g=="undefined"&&(g=await g8e(t),e.linkType===Qt.HARD&&this.customData.store.set(x.locatorHash,g)),g.manifest.type==="module"&&(this.isESMLoaderRequired=!0),f=this.opts.project.getDependencyMeta(x,e.version)}let h=c?rb(e,g,f,{configuration:this.opts.project.configuration,report:this.opts.report}):[],p=u?await this.unplugPackageIfNeeded(e,g,t,f,i):t.packageFs;if(k.isAbsolute(t.prefixPath))throw new Error(`Assertion failed: Expected the prefix path (${t.prefixPath}) to be relative to the parent`);let m=k.resolve(p.getRealPath(),t.prefixPath),y=NL(this.opts.project.cwd,m),b=new Map,v=new Set;if(a){for(let x of e.peerDependencies.values())b.set(P.stringifyIdent(x),null),v.add(P.stringifyIdent(x));if(!o){let x=P.devirtualizeLocator(e);this.virtualTemplates.set(x.locatorHash,{location:NL(this.opts.project.cwd,Wr.resolveVirtual(m)),locator:x})}}return Se.getMapWithDefault(this.packageRegistry,n).set(s,{packageLocation:y,packageDependencies:b,packagePeers:v,linkType:e.linkType,discardFromLookup:t.discardFromLookup||!1}),{packageLocation:m,buildDirective:h.length>0?h:null}}async attachInternalDependencies(e,t){let i=this.getPackageInformation(e);for(let[n,s]of t){let o=P.areIdentsEqual(n,s)?s.reference:[P.stringifyIdent(s),s.reference];i.packageDependencies.set(P.stringifyIdent(n),o)}}async attachExternalDependents(e,t){for(let i of t)this.getDiskInformation(i).packageDependencies.set(P.stringifyIdent(e),e.reference)}async finalizeInstall(){if(this.opts.project.configuration.get("pnpMode")!==this.mode)return;let e=Tl(this.opts.project);if(K.existsSync(e.cjsLegacy)&&(this.opts.report.reportWarning(X.UNNAMED,`Removing the old ${ae.pretty(this.opts.project.configuration,kt.pnpJs,ae.Type.PATH)} file. You might need to manually update existing references to reference the new ${ae.pretty(this.opts.project.configuration,kt.pnpCjs,ae.Type.PATH)} file. If you use Editor SDKs, you'll have to rerun ${ae.pretty(this.opts.project.configuration,"yarn sdks",ae.Type.CODE)}.`),await K.removePromise(e.cjsLegacy)),this.isEsmEnabled()||await K.removePromise(e.esmLoader),this.opts.project.configuration.get("nodeLinker")!=="pnp"){await K.removePromise(e.cjs),await K.removePromise(this.opts.project.configuration.get("pnpDataPath")),await K.removePromise(e.esmLoader);return}for(let{locator:u,location:g}of this.virtualTemplates.values())Se.getMapWithDefault(this.packageRegistry,P.stringifyIdent(u)).set(u.reference,{packageLocation:g,packageDependencies:new Map,packagePeers:new Set,linkType:Qt.SOFT,discardFromLookup:!1});this.packageRegistry.set(null,new Map([[null,this.getPackageInformation(this.opts.project.topLevelWorkspace.anchoredLocator)]]));let t=this.opts.project.configuration.get("pnpFallbackMode"),i=this.opts.project.workspaces.map(({anchoredLocator:u})=>({name:P.stringifyIdent(u),reference:u.reference})),n=t!=="none",s=[],o=new Map,a=Se.buildIgnorePattern([".yarn/sdks/**",...this.opts.project.configuration.get("pnpIgnorePatterns")]),l=this.packageRegistry,c=this.opts.project.configuration.get("pnpShebang");if(t==="dependencies-only")for(let u of this.opts.project.storedPackages.values())this.opts.project.tryWorkspaceByLocator(u)&&s.push({name:P.stringifyIdent(u),reference:u.reference});return await this.asyncActions.wait(),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 t=Tl(this.opts.project),i=this.opts.project.configuration.get("pnpDataPath"),n=await this.locateNodeModules(e.ignorePattern);if(n.length>0){this.opts.report.reportWarning(X.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 K.removePromise(o)}if(await this.transformPnpSettings(e),this.opts.project.configuration.get("pnpEnableInlining")){let o=xAe(e);await K.changeFilePromise(t.cjs,o,{automaticNewlines:!0,mode:493}),await K.removePromise(i)}else{let o=k.relative(k.dirname(t.cjs),i),{dataFile:a,loaderFile:l}=kAe(te(N({},e),{dataLocation:o}));await K.changeFilePromise(t.cjs,l,{automaticNewlines:!0,mode:493}),await K.changeFilePromise(i,a,{automaticNewlines:!0,mode:420})}this.isEsmEnabled()&&(this.opts.report.reportWarning(X.UNNAMED,"ESM support for PnP uses the experimental loader API and is therefore experimental"),await K.changeFilePromise(t.esmLoader,(0,PL.default)(),{automaticNewlines:!0,mode:420}));let s=this.opts.project.configuration.get("pnpUnpluggedFolder");if(this.unpluggedPaths.size===0)await K.removePromise(s);else for(let o of await K.readdirPromise(s)){let a=k.resolve(s,o);this.unpluggedPaths.has(a)||await K.removePromise(a)}}async locateNodeModules(e){let t=[],i=e?new RegExp(e):null;for(let n of this.opts.project.workspaces){let s=k.join(n.cwd,"node_modules");if(i&&i.test(k.relative(this.opts.project.cwd,n.cwd))||!K.existsSync(s))continue;let o=await K.readdirPromise(s,{withFileTypes:!0}),a=o.filter(l=>!l.isDirectory()||l.name===".bin"||!l.name.startsWith("."));if(a.length===o.length)t.push(s);else for(let l of a)t.push(k.join(s,l.name))}return t}async unplugPackageIfNeeded(e,t,i,n,s){return this.shouldBeUnplugged(e,t,n)?this.unplugPackage(e,i,s):i.packageFs}shouldBeUnplugged(e,t,i){return typeof i.unplugged!="undefined"?i.unplugged:u8e.has(e.identHash)||e.conditions!=null?!0:t.manifest.preferUnplugged!==null?t.manifest.preferUnplugged:!!(rb(e,t,i,{configuration:this.opts.project.configuration}).length>0||t.misc.extractHint)}async unplugPackage(e,t,i){let n=Hm(e,{configuration:this.opts.project.configuration});return this.opts.project.disabledLocators.has(e.locatorHash)?new Na(n,{baseFs:t.packageFs,pathUtils:k}):(this.unpluggedPaths.add(n),i.holdFetchResult(this.asyncActions.set(e.locatorHash,async()=>{let s=k.join(n,t.prefixPath,".ready");await K.existsPromise(s)||(this.opts.project.storedBuildState.delete(e.locatorHash),await K.mkdirPromise(n,{recursive:!0}),await K.copyPromise(n,Me.dot,{baseFs:t.packageFs,overwrite:!1}),await K.writeFilePromise(s,""))})),new _t(n))}getPackageInformation(e){let t=P.stringifyIdent(e),i=e.reference,n=this.packageRegistry.get(t);if(!n)throw new Error(`Assertion failed: The package information store should have been available (for ${P.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 ${P.prettyLocator(this.opts.project.configuration,e)})`);return s}getDiskInformation(e){let t=Se.getMapWithDefault(this.packageRegistry,"@@disk"),i=NL(this.opts.project.cwd,e);return Se.getFactoryWithDefault(t,i,()=>({packageLocation:i,packageDependencies:new Map,packagePeers:new Set,linkType:Qt.SOFT,discardFromLookup:!1}))}};function NL(r,e){let t=k.relative(r,e);return t.match(/^\.{0,2}\//)||(t=`./${t}`),t.replace(/\/?$/,"/")}async function g8e(r){var i;let e=(i=await At.tryFind(r.prefixPath,{baseFs:r.packageFs}))!=null?i:new At,t=new Set(["preinstall","install","postinstall"]);for(let n of e.scripts.keys())t.has(n)||e.scripts.delete(n);return{manifest:{scripts:e.scripts,preferUnplugged:e.preferUnplugged,type:e.type},misc:{extractHint:DL(r),hasBindingGyp:RL(r)}}}var KAe=ge(is());var jm=class extends Le{constructor(){super(...arguments);this.all=J.Boolean("-A,--all",!1,{description:"Unplug direct dependencies from the entire project"});this.recursive=J.Boolean("-R,--recursive",!1,{description:"Unplug both direct and transitive dependencies"});this.json=J.Boolean("--json",!1,{description:"Format the output as an NDJSON stream"});this.patterns=J.Rest()}async execute(){let e=await ye.find(this.context.cwd,this.context.plugins),{project:t,workspace:i}=await ze.find(e,this.context.cwd),n=await Nt.find(e);if(!i)throw new ht(t.cwd,this.context.cwd);if(e.get("nodeLinker")!=="pnp")throw new Pe("This command can only be used if the `nodeLinker` option is set to `pnp`");await t.restoreInstallState();let s=new Set(this.patterns),o=this.patterns.map(f=>{let h=P.parseDescriptor(f),p=h.range!=="unknown"?h:P.makeDescriptor(h,"*");if(!Wt.validRange(p.range))throw new Pe(`The range of the descriptor patterns must be a valid semver range (${P.prettyDescriptor(e,p)})`);return m=>{let y=P.stringifyIdent(m);return!KAe.default.isMatch(y,P.stringifyIdent(p))||m.version&&!Wt.satisfiesWithPrereleases(m.version,p.range)?!1:(s.delete(f),!0)}}),a=()=>{let f=[];for(let h of t.storedPackages.values())!t.tryWorkspaceByLocator(h)&&!P.isVirtualLocator(h)&&o.some(p=>p(h))&&f.push(h);return f},l=f=>{let h=new Set,p=[],m=(y,b)=>{if(!h.has(y.locatorHash)&&(h.add(y.locatorHash),!t.tryWorkspaceByLocator(y)&&o.some(v=>v(y))&&p.push(y),!(b>0&&!this.recursive)))for(let v of y.dependencies.values()){let x=t.storedResolutions.get(v.descriptorHash);if(!x)throw new Error("Assertion failed: The resolution should have been registered");let T=t.storedPackages.get(x);if(!T)throw new Error("Assertion failed: The package should have been registered");m(T,b+1)}};for(let y of f){let b=t.storedPackages.get(y.anchoredLocator.locatorHash);if(!b)throw new Error("Assertion failed: The package should have been registered");m(b,0)}return p},c,u;if(this.all&&this.recursive?(c=a(),u="the project"):this.all?(c=l(t.workspaces),u="any workspace"):(c=l([i]),u="this workspace"),s.size>1)throw new Pe(`Patterns ${ae.prettyList(e,s,ae.Type.CODE)} don't match any packages referenced by ${u}`);if(s.size>0)throw new Pe(`Pattern ${ae.prettyList(e,s,ae.Type.CODE)} doesn't match any packages referenced by ${u}`);return c=Se.sortMap(c,f=>P.stringifyLocator(f)),(await Je.start({configuration:e,stdout:this.context.stdout,json:this.json},async f=>{var h;for(let p of c){let m=(h=p.version)!=null?h:"unknown",y=t.topLevelWorkspace.manifest.ensureDependencyMeta(P.makeDescriptor(p,m));y.unplugged=!0,f.reportInfo(X.UNNAMED,`Will unpack ${P.prettyLocator(e,p)} to ${ae.pretty(e,Hm(p,{configuration:e}),ae.Type.PATH)}`),f.reportJson({locator:P.stringifyLocator(p),version:m})}await t.topLevelWorkspace.persistManifest(),f.reportSeparator(),await t.install({cache:n,report:f})})).exitCode()}};jm.paths=[["unplug"]],jm.usage=Re.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 UAe=jm;var Tl=r=>({cjs:k.join(r.cwd,kt.pnpCjs),cjsLegacy:k.join(r.cwd,kt.pnpJs),esmLoader:k.join(r.cwd,".pnp.loader.mjs")}),GAe=r=>/\s/.test(r)?JSON.stringify(r):r;async function f8e(r,e,t){let i=Tl(r),n=`--require ${GAe(H.fromPortablePath(i.cjs))}`;if(K.existsSync(i.esmLoader)&&(n=`${n} --experimental-loader ${(0,jAe.pathToFileURL)(H.fromPortablePath(i.esmLoader)).href}`),i.cjs.includes(" ")&&HAe.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(K.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 h8e(r,e){let t=Tl(r);e(t.cjs),e(t.esmLoader),e(r.configuration.get("pnpDataPath")),e(r.configuration.get("pnpUnpluggedFolder"))}var p8e={hooks:{populateYarnPaths:h8e,setupScriptEnvironment:f8e},configuration:{nodeLinker:{description:'The linker used for installing Node packages, one of: "pnp", "node-modules"',type:Ie.STRING,default:"pnp"},pnpMode:{description:"If 'strict', generates standard PnP maps. If 'loose', merges them with the n_m resolution.",type:Ie.STRING,default:"strict"},pnpShebang:{description:"String to prepend to the generated PnP script",type:Ie.STRING,default:"#!/usr/bin/env node"},pnpIgnorePatterns:{description:"Array of glob patterns; files matching them will use the classic resolution",type:Ie.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:Ie.BOOLEAN,default:!1},pnpEnableInlining:{description:"If true, the PnP data will be inlined along with the generated loader",type:Ie.BOOLEAN,default:!0},pnpFallbackMode:{description:"If true, the generated PnP loader will follow the top-level fallback rule",type:Ie.STRING,default:"dependencies-only"},pnpUnpluggedFolder:{description:"Folder where the unplugged packages must be stored",type:Ie.ABSOLUTE_PATH,default:"./.yarn/unplugged"},pnpDataPath:{description:"Path of the file where the PnP data (used by the loader) must be written",type:Ie.ABSOLUTE_PATH,default:"./.pnp.data.json"}},linkers:[xu],commands:[UAe]},d8e=p8e;var _Ae=ge(zAe());var UL=ge(require("crypto")),VAe=ge(require("fs")),XAe=1,jr="node_modules",ib=".bin",ZAe=".yarn-state.yml",Ti;(function(i){i.CLASSIC="classic",i.HARDLINKS_LOCAL="hardlinks-local",i.HARDLINKS_GLOBAL="hardlinks-global"})(Ti||(Ti={}));var HL=class{constructor(){this.installStateCache=new Map}supportsPackage(e,t){return this.isEnabled(t)}async findPackageLocation(e,t){if(!this.isEnabled(t))throw new Error("Assertion failed: Expected the node-modules linker to be enabled");let i=t.project.tryWorkspaceByLocator(e);if(i)return i.cwd;let n=await Se.getFactoryWithDefault(this.installStateCache,t.project.cwd,async()=>await jL(t.project,{unrollAliases:!0}));if(n===null)throw new Pe("Couldn't find the node_modules state file - running an install might help (findPackageLocation)");let s=n.locatorMap.get(P.stringifyLocator(e));if(!s){let a=new Pe(`Couldn't find ${P.prettyLocator(t.project.configuration,e)} in the currently installed node_modules map - running an install might help`);throw a.code="LOCATOR_NOT_INSTALLED",a}let o=t.project.configuration.startingCwd;return s.locations.find(a=>k.contains(o,a))||s.locations[0]}async findPackageLocator(e,t){if(!this.isEnabled(t))return null;let i=await Se.getFactoryWithDefault(this.installStateCache,t.project.cwd,async()=>await jL(t.project,{unrollAliases:!0}));if(i===null)return null;let{locationRoot:n,segments:s}=nb(k.resolve(e),{skipPrefix:t.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 P.parseLocator(a)}makeInstaller(e){return new $Ae(e)}isEnabled(e){return e.project.configuration.get("nodeLinker")==="node-modules"}},$Ae=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:2})}attachCustomData(e){this.customData=e}async installPackage(e,t){var u;let i=k.resolve(t.packageFs.getRealPath(),t.prefixPath),n=this.customData.store.get(e.locatorHash);if(typeof n=="undefined"&&(n=await F8e(e,t),e.linkType===Qt.HARD&&this.customData.store.set(e.locatorHash,n)),!P.isPackageCompatible(e,this.opts.project.configuration.getSupportedArchitectures()))return{packageLocation:null,buildDirective:null};let s=new Map,o=new Set;s.has(P.stringifyIdent(e))||s.set(P.stringifyIdent(e),e.reference);let a=e;if(P.isVirtualLocator(e)){a=P.devirtualizeLocator(e);for(let g of e.peerDependencies.values())s.set(P.stringifyIdent(g),null),o.add(P.stringifyIdent(g))}let l={packageLocation:`${H.fromPortablePath(i)}/`,packageDependencies:s,packagePeers:o,linkType:e.linkType,discardFromLookup:(u=t.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=t.checksum?t.checksum.substring(t.checksum.indexOf("/")+1):null;return this.realLocatorChecksums.set(a.locatorHash,c),{packageLocation:i,buildDirective:null}}async attachInternalDependencies(e,t){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 t){let o=P.areIdentsEqual(n,s)?s.reference:[P.stringifyIdent(s),s.reference];i.pnpNode.packageDependencies.set(P.stringifyIdent(n),o)}}async attachExternalDependents(e,t){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 Wr({baseFs:new Is({libzip:await fn(),maxOpenFiles:80,readOnlyArchives:!0})}),t=await jL(this.opts.project),i=this.opts.project.configuration.get("nmMode");(t===null||i!==t.nmMode)&&(this.opts.project.storedBuildState.clear(),t={locatorMap:new Map,binSymlinks:new Map,locationTree:new Map,nmMode:i,mtimeMs:0});let n=new Map(this.opts.project.workspaces.map(f=>{var p,m;let h=this.opts.project.configuration.get("nmHoistingLimits");try{h=Se.validateEnum(Kn,(m=(p=f.manifest.installConfig)==null?void 0:p.hoistingLimits)!=null?m:h)}catch(y){let b=P.prettyWorkspace(this.opts.project.configuration,f);this.opts.report.reportWarning(X.INVALID_MANIFEST,`${b}: Invalid 'installConfig.hoistingLimits' value. Expected one of ${Object.values(Kn).join(", ")}, using default: "${h}"`)}return[f.relativeCwd,h]})),s=new Map(this.opts.project.workspaces.map(f=>{var p,m;let h=this.opts.project.configuration.get("nmSelfReferences");return h=(m=(p=f.manifest.installConfig)==null?void 0:p.selfReferences)!=null?m: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:P.stringifyIdent(f.locator),reference:h.reference}}),getPackageInformation:f=>{let h=f.reference===null?this.opts.project.topLevelWorkspace.anchoredLocator:P.makeLocator(P.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(H.toPortablePath(f));if(h!==null){let p=h.anchoredLocator;return{name:P.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=>H.fromPortablePath(Wr.resolveVirtual(H.toPortablePath(f)))},{tree:a,errors:l,preserveSymlinksRequired:c}=Om(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=BL(a);await N8e(t,u,{baseFs:e,project:this.opts.project,report:this.opts.report,realLocatorChecksums:this.realLocatorChecksums,loadManifest:async f=>{let h=P.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(ele(f))continue;let p=P.parseLocator(f),m=this.localStore.get(p.locatorHash);if(typeof m=="undefined")throw new Error("Assertion failed: Expected the slot to exist");if(this.opts.project.tryWorkspaceByLocator(m.pkg))continue;let y=Ca.extractBuildScripts(m.pkg,m.customPackageData,m.dependencyMeta,{configuration:this.opts.project.configuration,report:this.opts.report});y.length!==0&&g.push({buildLocations:h.locations,locatorHash:p.locatorHash,buildDirective:y})}return c&&this.opts.report.reportWarning(X.NM_PRESERVE_SYMLINKS_REQUIRED,`The application uses portals and that's why ${ae.pretty(this.opts.project.configuration,"--preserve-symlinks",ae.Type.CODE)} Node option is required for launching it`),{customData:this.customData,records:g}}};async function F8e(r,e){var n;let t=(n=await At.tryFind(e.prefixPath,{baseFs:e.packageFs}))!=null?n:new At,i=new Set(["preinstall","install","postinstall"]);for(let s of t.scripts.keys())i.has(s)||t.scripts.delete(s);return{manifest:{bin:t.bin,scripts:t.scripts},misc:{extractHint:Ca.getExtractHint(e),hasBindingGyp:Ca.hasBindingGyp(e)}}}async function L8e(r,e,t,i,{installChangedByUser:n}){let s="";s+=`# Warning: This file is automatically generated. Removing it is fine, but will -`,s+=`# cause your node_modules installation to become invalidated. -`,s+=` -`,s+=`__metadata: -`,s+=` version: ${XAe} -`,s+=` nmMode: ${i.value} -`;let o=Array.from(e.keys()).sort(),a=P.stringifyLocator(r.topLevelWorkspace.anchoredLocator);for(let u of o){let g=e.get(u);s+=` -`,s+=`${JSON.stringify(u)}: -`,s+=` locations: -`;for(let f of g.locations){let h=k.contains(r.cwd,f);if(h===null)throw new Error(`Assertion failed: Expected the path to be within the project (${f})`);s+=` - ${JSON.stringify(h)} -`}if(g.aliases.length>0){s+=` aliases: -`;for(let f of g.aliases)s+=` - ${JSON.stringify(f)} -`}if(u===a&&t.size>0){s+=` bin: -`;for(let[f,h]of t){let p=k.contains(r.cwd,f);if(p===null)throw new Error(`Assertion failed: Expected the path to be within the project (${f})`);s+=` ${JSON.stringify(p)}: -`;for(let[m,y]of h){let b=k.relative(k.join(f,jr),y);s+=` ${JSON.stringify(m)}: ${JSON.stringify(b)} -`}}}}let l=r.cwd,c=k.join(l,jr,ZAe);n&&await K.removePromise(c),await K.changeFilePromise(c,s,{automaticNewlines:!0})}async function jL(r,{unrollAliases:e=!1}={}){let t=r.cwd,i=k.join(t,jr,ZAe),n;try{n=await K.statPromise(i)}catch(c){}if(!n)return null;let s=Si(await K.readFilePromise(i,"utf8"));if(s.__metadata.version>XAe)return null;let o=s.__metadata.nmMode||Ti.CLASSIC,a=new Map,l=new Map;delete s.__metadata;for(let[c,u]of Object.entries(s)){let g=u.locations.map(h=>k.join(t,h)),f=u.bin;if(f)for(let[h,p]of Object.entries(f)){let m=k.join(t,H.toPortablePath(h)),y=Se.getMapWithDefault(l,m);for(let[b,v]of Object.entries(p))y.set(Jr(b),H.toPortablePath([m,jr,v].join(k.sep)))}if(a.set(c,{target:Me.dot,linkType:Qt.HARD,locations:g,aliases:u.aliases||[]}),e&&u.aliases)for(let h of u.aliases){let{scope:p,name:m}=P.parseLocator(c),y=P.makeLocator(P.makeIdent(p,m),h),b=P.stringifyLocator(y);a.set(b,{target:Me.dot,linkType:Qt.HARD,locations:g,aliases:[]})}}return{locatorMap:a,binSymlinks:l,locationTree:tle(a,{skipPrefix:r.cwd}),nmMode:o,mtimeMs:n.mtimeMs}}var Ah=async(r,e)=>{if(r.split(k.sep).indexOf(jr)<0)throw new Error(`Assertion failed: trying to remove dir that doesn't contain node_modules: ${r}`);try{if(!e.innerLoop){let i=e.allowSymlink?await K.statPromise(r):await K.lstatPromise(r);if(e.allowSymlink&&!i.isDirectory()||!e.allowSymlink&&i.isSymbolicLink()){await K.unlinkPromise(r);return}}let t=await K.readdirPromise(r,{withFileTypes:!0});for(let i of t){let n=k.join(r,Jr(i.name));i.isDirectory()?(i.name!==jr||e&&e.innerLoop)&&await Ah(n,{innerLoop:!0,contentsOnly:!1}):await K.unlinkPromise(n)}e.contentsOnly||await K.rmdirPromise(r)}catch(t){if(t.code!=="ENOENT"&&t.code!=="ENOTEMPTY")throw t}},rle=4,nb=(r,{skipPrefix:e})=>{let t=k.contains(e,r);if(t===null)throw new Error(`Assertion failed: Writing attempt prevented to ${r} which is outside project root: ${e}`);let i=t.split(k.sep).filter(l=>l!==""),n=i.indexOf(jr),s=i.slice(0,n).join(k.sep),o=k.join(e,s),a=i.slice(n);return{locationRoot:o,segments:a}},tle=(r,{skipPrefix:e})=>{let t=new Map;if(r===null)return t;let i=()=>({children:new Map,linkType:Qt.HARD});for(let[n,s]of r.entries()){if(s.linkType===Qt.SOFT&&k.contains(e,s.target)!==null){let a=Se.getFactoryWithDefault(t,s.target,i);a.locator=n,a.linkType=s.linkType}for(let o of s.locations){let{locationRoot:a,segments:l}=nb(o,{skipPrefix:e}),c=Se.getFactoryWithDefault(t,a,i);for(let u=0;u{let t;try{process.platform==="win32"&&(t=await K.lstatPromise(r))}catch(i){}process.platform=="win32"&&(!t||t.isDirectory())?await K.symlinkPromise(r,e,"junction"):await K.symlinkPromise(k.relative(k.dirname(e),r),e)};async function ile(r,e,t){let i=k.join(r,Jr(`${UL.default.randomBytes(16).toString("hex")}.tmp`));try{await K.writeFilePromise(i,t);try{await K.linkPromise(i,e)}catch(n){}}finally{await K.unlinkPromise(i)}}async function T8e({srcPath:r,dstPath:e,srcMode:t,globalHardlinksStore:i,baseFs:n,nmMode:s,digest:o}){if(s.value===Ti.HARDLINKS_GLOBAL&&i&&o){let l=k.join(i,o.substring(0,2),`${o.substring(2)}.dat`),c;try{if(await Dn.checksumFile(l,{baseFs:K,algorithm:"sha1"})!==o){let g=k.join(i,Jr(`${UL.default.randomBytes(16).toString("hex")}.tmp`));await K.renamePromise(l,g);let f=await n.readFilePromise(r);await K.writeFilePromise(g,f);try{await K.linkPromise(g,l),await K.unlinkPromise(g)}catch(h){}}await K.linkPromise(l,e),c=!0}catch(u){c=!1}if(!c){let u=await n.readFilePromise(r);await ile(i,l,u);try{await K.linkPromise(l,e)}catch(g){g&&g.code&&g.code=="EXDEV"&&(s.value=Ti.HARDLINKS_LOCAL,await n.copyFilePromise(r,e))}}}else await n.copyFilePromise(r,e);let a=t&511;a!==420&&await K.chmodPromise(e,a)}var Ol;(function(i){i.FILE="file",i.DIRECTORY="directory",i.SYMLINK="symlink"})(Ol||(Ol={}));var O8e=async(r,e,{baseFs:t,globalHardlinksStore:i,nmMode:n,packageChecksum:s})=>{await K.mkdirPromise(r,{recursive:!0});let o=async(l=Me.dot)=>{let c=k.join(e,l),u=await t.readdirPromise(c,{withFileTypes:!0}),g=new Map;for(let f of u){let h=k.join(l,f.name),p,m=k.join(c,f.name);if(f.isFile()){if(p={kind:Ol.FILE,mode:(await t.lstatPromise(m)).mode},n.value===Ti.HARDLINKS_GLOBAL){let y=await Dn.checksumFile(m,{baseFs:t,algorithm:"sha1"});p.digest=y}}else if(f.isDirectory())p={kind:Ol.DIRECTORY};else if(f.isSymbolicLink())p={kind:Ol.SYMLINK,symlinkTo:await t.readlinkPromise(m)};else throw new Error(`Unsupported file type (file: ${m}, mode: 0o${await t.statSync(m).mode.toString(8).padStart(6,"0")})`);if(g.set(h,p),f.isDirectory()&&h!==jr){let y=await o(h);for(let[b,v]of y)g.set(b,v)}}return g},a;if(n.value===Ti.HARDLINKS_GLOBAL&&i&&s){let l=k.join(i,s.substring(0,2),`${s.substring(2)}.json`);try{a=new Map(Object.entries(JSON.parse(await K.readFilePromise(l,"utf8"))))}catch(c){a=await o(),await ile(i,l,Buffer.from(JSON.stringify(Object.fromEntries(a))))}}else a=await o();for(let[l,c]of a){let u=k.join(e,l),g=k.join(r,l);c.kind===Ol.DIRECTORY?await K.mkdirPromise(g,{recursive:!0}):c.kind===Ol.FILE?await T8e({srcPath:u,dstPath:g,srcMode:c.mode,digest:c.digest,nmMode:n,baseFs:t,globalHardlinksStore:i}):c.kind===Ol.SYMLINK&&await GL(k.resolve(k.dirname(g),c.symlinkTo),g)}};function M8e(r,e,t,i){let n=new Map,s=new Map,o=new Map,a=!1,l=(c,u,g,f,h)=>{let p=!0,m=k.join(c,u),y=new Set;if(u===jr||u.startsWith("@")){let v;try{v=K.statSync(m)}catch(T){}p=!!v,v?v.mtimeMs>t?(a=!0,y=new Set(K.readdirSync(m))):y=new Set(g.children.get(u).children.keys()):a=!0;let x=e.get(c);if(x){let T=k.join(c,jr,ib),q;try{q=K.statSync(T)}catch(Y){}if(!q)a=!0;else if(q.mtimeMs>t){a=!0;let Y=new Set(K.readdirSync(T)),$=new Map;s.set(c,$);for(let[_,ne]of x)Y.has(_)&&$.set(_,ne)}else s.set(c,x)}}else p=h.has(u);let b=g.children.get(u);if(p){let{linkType:v,locator:x}=b,T={children:new Map,linkType:v,locator:x};if(f.children.set(u,T),x){let q=Se.getSetWithDefault(o,x);q.add(m),o.set(x,q)}for(let q of b.children.keys())l(m,q,b,T,y)}else b.locator&&i.storedBuildState.delete(P.parseLocator(b.locator).locatorHash)};for(let[c,u]of r){let{linkType:g,locator:f}=u,h={children:new Map,linkType:g,locator:f};if(n.set(c,h),f){let p=Se.getSetWithDefault(o,u.locator);p.add(c),o.set(u.locator,p)}u.children.has(jr)&&l(c,jr,u,h,new Set)}return{locationTree:n,binSymlinks:s,locatorLocations:o,installChangedByUser:a}}function ele(r){let e=P.parseDescriptor(r);return P.isVirtualDescriptor(e)&&(e=P.devirtualizeDescriptor(e)),e.range.startsWith("link:")}async function K8e(r,e,t,{loadManifest:i}){let n=new Map;for(let[a,{locations:l}]of r){let c=ele(a)?null:await i(a,l[0]),u=new Map;if(c)for(let[g,f]of c.bin){let h=k.join(l[0],f);f!==""&&K.existsSync(h)&&u.set(g,f)}n.set(a,u)}let s=new Map,o=(a,l,c)=>{let u=new Map,g=k.contains(t,a);if(c.locator&&g!==null){let f=n.get(c.locator);for(let[h,p]of f){let m=k.join(a,H.toPortablePath(p));u.set(Jr(h),m)}for(let[h,p]of c.children){let m=k.join(a,h),y=o(m,m,p);y.size>0&&s.set(a,new Map([...s.get(a)||new Map,...y]))}}else for(let[f,h]of c.children){let p=o(k.join(a,f),l,h);for(let[m,y]of p)u.set(m,y)}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 nle=(r,e)=>{if(!r||!e)return r===e;let t=P.parseLocator(r);P.isVirtualLocator(t)&&(t=P.devirtualizeLocator(t));let i=P.parseLocator(e);return P.isVirtualLocator(i)&&(i=P.devirtualizeLocator(i)),P.areLocatorsEqual(t,i)};function YL(r){return k.join(r.get("globalFolder"),"store")}async function N8e(r,e,{baseFs:t,project:i,report:n,loadManifest:s,realLocatorChecksums:o}){let a=k.join(i.cwd,jr),{locationTree:l,binSymlinks:c,locatorLocations:u,installChangedByUser:g}=M8e(r.locationTree,r.binSymlinks,r.mtimeMs,i),f=tle(e,{skipPrefix:i.cwd}),h=[],p=async({srcDir:_,dstDir:ne,linkType:ee,globalHardlinksStore:A,nmMode:oe,packageChecksum:ce})=>{let Z=(async()=>{try{ee===Qt.SOFT?(await K.mkdirPromise(k.dirname(ne),{recursive:!0}),await GL(k.resolve(_),ne)):await O8e(ne,_,{baseFs:t,globalHardlinksStore:A,nmMode:oe,packageChecksum:ce})}catch(O){throw O.message=`While persisting ${_} -> ${ne} ${O.message}`,O}finally{T.tick()}})().then(()=>h.splice(h.indexOf(Z),1));h.push(Z),h.length>rle&&await Promise.race(h)},m=async(_,ne,ee)=>{let A=(async()=>{let oe=async(ce,Z,O)=>{try{O.innerLoop||await K.mkdirPromise(Z,{recursive:!0});let L=await K.readdirPromise(ce,{withFileTypes:!0});for(let de of L){if(!O.innerLoop&&de.name===ib)continue;let Be=k.join(ce,de.name),je=k.join(Z,de.name);de.isDirectory()?(de.name!==jr||O&&O.innerLoop)&&(await K.mkdirPromise(je,{recursive:!0}),await oe(Be,je,te(N({},O),{innerLoop:!0}))):$.value===Ti.HARDLINKS_LOCAL||$.value===Ti.HARDLINKS_GLOBAL?await K.linkPromise(Be,je):await K.copyFilePromise(Be,je,VAe.default.constants.COPYFILE_FICLONE)}}catch(L){throw O.innerLoop||(L.message=`While cloning ${ce} -> ${Z} ${L.message}`),L}finally{O.innerLoop||T.tick()}};await oe(_,ne,ee)})().then(()=>h.splice(h.indexOf(A),1));h.push(A),h.length>rle&&await Promise.race(h)},y=async(_,ne,ee)=>{if(ee)for(let[A,oe]of ne.children){let ce=ee.children.get(A);await y(k.join(_,A),oe,ce)}else{ne.children.has(jr)&&await Ah(k.join(_,jr),{contentsOnly:!1});let A=k.basename(_)===jr&&f.has(k.join(k.dirname(_),k.sep));await Ah(_,{contentsOnly:_===a,allowSymlink:A})}};for(let[_,ne]of l){let ee=f.get(_);for(let[A,oe]of ne.children){if(A===".")continue;let ce=ee&&ee.children.get(A),Z=k.join(_,A);await y(Z,oe,ce)}}let b=async(_,ne,ee)=>{if(ee){nle(ne.locator,ee.locator)||await Ah(_,{contentsOnly:ne.linkType===Qt.HARD});for(let[A,oe]of ne.children){let ce=ee.children.get(A);await b(k.join(_,A),oe,ce)}}else{ne.children.has(jr)&&await Ah(k.join(_,jr),{contentsOnly:!0});let A=k.basename(_)===jr&&f.has(k.join(k.dirname(_),k.sep));await Ah(_,{contentsOnly:ne.linkType===Qt.HARD,allowSymlink:A})}};for(let[_,ne]of f){let ee=l.get(_);for(let[A,oe]of ne.children){if(A===".")continue;let ce=ee&&ee.children.get(A);await b(k.join(_,A),oe,ce)}}let v=new Map,x=[];for(let[_,ne]of u)for(let ee of ne){let{locationRoot:A,segments:oe}=nb(ee,{skipPrefix:i.cwd}),ce=f.get(A),Z=A;if(ce){for(let O of oe)if(Z=k.join(Z,O),ce=ce.children.get(O),!ce)break;if(ce){let O=nle(ce.locator,_),L=e.get(ce.locator),de=L.target,Be=Z,je=L.linkType;if(O)v.has(de)||v.set(de,Be);else if(de!==Be){let re=P.parseLocator(ce.locator);P.isVirtualLocator(re)&&(re=P.devirtualizeLocator(re)),x.push({srcDir:de,dstDir:Be,linkType:je,realLocatorHash:re.locatorHash})}}}}for(let[_,{locations:ne}]of e.entries())for(let ee of ne){let{locationRoot:A,segments:oe}=nb(ee,{skipPrefix:i.cwd}),ce=l.get(A),Z=f.get(A),O=A,L=e.get(_),de=P.parseLocator(_);P.isVirtualLocator(de)&&(de=P.devirtualizeLocator(de));let Be=de.locatorHash,je=L.target,re=ee;if(je===re)continue;let se=L.linkType;for(let be of oe)Z=Z.children.get(be);if(!ce)x.push({srcDir:je,dstDir:re,linkType:se,realLocatorHash:Be});else for(let be of oe)if(O=k.join(O,be),ce=ce.children.get(be),!ce){x.push({srcDir:je,dstDir:re,linkType:se,realLocatorHash:Be});break}}let T=Ji.progressViaCounter(x.length),q=n.reportProgress(T),Y=i.configuration.get("nmMode"),$={value:Y};try{let _=$.value===Ti.HARDLINKS_GLOBAL?`${YL(i.configuration)}/v1`:null;if(_&&!await K.existsPromise(_)){await K.mkdirpPromise(_);for(let ee=0;ee<256;ee++)await K.mkdirPromise(k.join(_,ee.toString(16).padStart(2,"0")))}for(let ee of x)(ee.linkType===Qt.SOFT||!v.has(ee.srcDir))&&(v.set(ee.srcDir,ee.dstDir),await p(te(N({},ee),{globalHardlinksStore:_,nmMode:$,packageChecksum:o.get(ee.realLocatorHash)||null})));await Promise.all(h),h.length=0;for(let ee of x){let A=v.get(ee.srcDir);ee.linkType!==Qt.SOFT&&ee.dstDir!==A&&await m(A,ee.dstDir,{nmMode:$})}await Promise.all(h),await K.mkdirPromise(a,{recursive:!0});let ne=await K8e(e,f,i.cwd,{loadManifest:s});await U8e(c,ne,i.cwd),await L8e(i,e,ne,$,{installChangedByUser:g}),Y==Ti.HARDLINKS_GLOBAL&&$.value==Ti.HARDLINKS_LOCAL&&n.reportWarningOnce(X.NM_HARDLINKS_MODE_DOWNGRADED,"'nmMode' has been downgraded to 'hardlinks-local' due to global cache and install folder being on different devices")}finally{q.stop()}}async function U8e(r,e,t){for(let i of r.keys()){if(k.contains(t,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=k.join(i,jr,ib);await K.removePromise(n)}}for(let[i,n]of e){if(k.contains(t,i)===null)throw new Error(`Assertion failed. Excepted bin symlink location to be inside project dir, instead it was at ${i}`);let s=k.join(i,jr,ib),o=r.get(i)||new Map;await K.mkdirPromise(s,{recursive:!0});for(let a of o.keys())n.has(a)||(await K.removePromise(k.join(s,a)),process.platform==="win32"&&await K.removePromise(k.join(s,Jr(`${a}.cmd`))));for(let[a,l]of n){let c=o.get(a),u=k.join(s,a);c!==l&&(process.platform==="win32"?await(0,_Ae.default)(H.fromPortablePath(l),H.fromPortablePath(u),{createPwshFile:!1}):(await K.removePromise(u),await GL(l,u),k.contains(t,await K.realpathPromise(l))!==null&&await K.chmodPromise(l,493)))}}}var qL=class extends xu{constructor(){super(...arguments);this.mode="loose"}makeInstaller(e){return new sle(e)}},sle=class extends oh{constructor(){super(...arguments);this.mode="loose"}async transformPnpSettings(e){let t=new Wr({baseFs:new Is({libzip:await fn(),maxOpenFiles:80,readOnlyArchives:!0})}),i=NAe(e,this.opts.project.cwd,t),{tree:n,errors:s}=Om(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=P.parseLocator(g.locator),h=P.stringifyIdent(f);h===u?o.set(u,f.reference):o.set(u,[h,f.reference])},l=k.join(this.opts.project.cwd,kt.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=k.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=k.join(g,h),m=n.get(p);if(typeof m=="undefined")throw new Error("Assertion failed: Expected the subchild to have been registered");if("target"in m)a(`${u}/${h}`,m);else throw new Error("Assertion failed: Expected the leaf junction to be a package")}}}}};var H8e={hooks:{cleanGlobalArtifacts:async r=>{let e=YL(r);await K.removePromise(e)}},configuration:{nmHoistingLimits:{description:"Prevent packages to be hoisted past specific levels",type:Ie.STRING,values:[Kn.WORKSPACES,Kn.DEPENDENCIES,Kn.NONE],default:Kn.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:Ie.STRING,values:[Ti.CLASSIC,Ti.HARDLINKS_LOCAL,Ti.HARDLINKS_GLOBAL],default:Ti.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:Ie.BOOLEAN,default:!0}},linkers:[HL,qL]},j8e=H8e;var qT={};ft(qT,{default:()=>V9e,npmConfigUtils:()=>br,npmHttpUtils:()=>zt,npmPublishUtils:()=>wh});var cle=ge(ri());var Cr="npm:";var zt={};ft(zt,{AuthType:()=>us,customPackageError:()=>q8e,del:()=>z8e,get:()=>bo,getIdentUrl:()=>Kl,handleInvalidAuthenticationError:()=>Ml,post:()=>J8e,put:()=>W8e});var Ale=ge(WC()),lle=ge(require("url"));var br={};ft(br,{RegistryType:()=>QA,getAuditRegistry:()=>G8e,getAuthConfiguration:()=>zL,getDefaultRegistry:()=>sb,getPublishRegistry:()=>ole,getRegistryConfiguration:()=>ale,getScopeConfiguration:()=>WL,getScopeRegistry:()=>SA,normalizeRegistry:()=>ma});var QA;(function(i){i.AUDIT_REGISTRY="npmAuditRegistry",i.FETCH_REGISTRY="npmRegistryServer",i.PUBLISH_REGISTRY="npmPublishRegistry"})(QA||(QA={}));function ma(r){return r.replace(/\/$/,"")}function G8e(r,{configuration:e}){let t=e.get(QA.AUDIT_REGISTRY);return t!==null?ma(t):ole(r,{configuration:e})}function ole(r,{configuration:e}){var t;return((t=r.publishConfig)==null?void 0:t.registry)?ma(r.publishConfig.registry):r.name?SA(r.name.scope,{configuration:e,type:QA.PUBLISH_REGISTRY}):sb({configuration:e,type:QA.PUBLISH_REGISTRY})}function SA(r,{configuration:e,type:t=QA.FETCH_REGISTRY}){let i=WL(r,{configuration:e});if(i===null)return sb({configuration:e,type:t});let n=i.get(t);return n===null?sb({configuration:e,type:t}):ma(n)}function sb({configuration:r,type:e=QA.FETCH_REGISTRY}){let t=r.get(e);return ma(t!==null?t:r.get(QA.FETCH_REGISTRY))}function ale(r,{configuration:e}){let t=e.get("npmRegistries"),i=ma(r),n=t.get(i);if(typeof n!="undefined")return n;let s=t.get(i.replace(/^[a-z]+:/,""));return typeof s!="undefined"?s:null}function WL(r,{configuration:e}){if(r===null)return null;let i=e.get("npmScopes").get(r);return i||null}function zL(r,{configuration:e,ident:t}){let i=t&&WL(t.scope,{configuration:e});return(i==null?void 0:i.get("npmAuthIdent"))||(i==null?void 0:i.get("npmAuthToken"))?i:ale(r,{configuration:e})||e}var us;(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"})(us||(us={}));async function Ml(r,{attemptedAs:e,registry:t,headers:i,configuration:n}){var s,o;if(ob(r))throw new ct(X.AUTHENTICATION_INVALID,"Invalid OTP token");if(((s=r.originalError)==null?void 0:s.name)==="HTTPError"&&((o=r.originalError)==null?void 0:o.response.statusCode)===401)throw new ct(X.AUTHENTICATION_INVALID,`Invalid authentication (${typeof e!="string"?`as ${await Y8e(t,i,{configuration:n})}`:`attempted as ${e}`})`)}function q8e(r){var e;return((e=r.response)==null?void 0:e.statusCode)===404?"Package not found":null}function Kl(r){return r.scope?`/@${r.scope}%2f${r.name}`:`/${r.name}`}async function bo(r,a){var l=a,{configuration:e,headers:t,ident:i,authType:n,registry:s}=l,o=Or(l,["configuration","headers","ident","authType","registry"]);if(i&&typeof s=="undefined"&&(s=SA(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 ab(s,{authType:n,configuration:e,ident:i});c&&(t=te(N({},t),{authorization:c}));try{return await ir.get(r.charAt(0)==="/"?`${s}${r}`:r,N({configuration:e,headers:t},o))}catch(u){throw await Ml(u,{registry:s,configuration:e,headers:t}),u}}async function J8e(r,e,u){var g=u,{attemptedAs:t,configuration:i,headers:n,ident:s,authType:o=3,registry:a,otp:l}=g,c=Or(g,["attemptedAs","configuration","headers","ident","authType","registry","otp"]);if(s&&typeof a=="undefined"&&(a=SA(s.scope,{configuration:i})),typeof a!="string")throw new Error("Assertion failed: The registry should be a string");let f=await ab(a,{authType:o,configuration:i,ident:s});f&&(n=te(N({},n),{authorization:f})),l&&(n=N(N({},n),lh(l)));try{return await ir.post(a+r,e,N({configuration:i,headers:n},c))}catch(h){if(!ob(h)||l)throw await Ml(h,{attemptedAs:t,registry:a,configuration:i,headers:n}),h;l=await _L();let p=N(N({},n),lh(l));try{return await ir.post(`${a}${r}`,e,N({configuration:i,headers:p},c))}catch(m){throw await Ml(m,{attemptedAs:t,registry:a,configuration:i,headers:n}),m}}}async function W8e(r,e,u){var g=u,{attemptedAs:t,configuration:i,headers:n,ident:s,authType:o=3,registry:a,otp:l}=g,c=Or(g,["attemptedAs","configuration","headers","ident","authType","registry","otp"]);if(s&&typeof a=="undefined"&&(a=SA(s.scope,{configuration:i})),typeof a!="string")throw new Error("Assertion failed: The registry should be a string");let f=await ab(a,{authType:o,configuration:i,ident:s});f&&(n=te(N({},n),{authorization:f})),l&&(n=N(N({},n),lh(l)));try{return await ir.put(a+r,e,N({configuration:i,headers:n},c))}catch(h){if(!ob(h))throw await Ml(h,{attemptedAs:t,registry:a,configuration:i,headers:n}),h;l=await _L();let p=N(N({},n),lh(l));try{return await ir.put(`${a}${r}`,e,N({configuration:i,headers:p},c))}catch(m){throw await Ml(m,{attemptedAs:t,registry:a,configuration:i,headers:n}),m}}}async function z8e(r,c){var u=c,{attemptedAs:e,configuration:t,headers:i,ident:n,authType:s=3,registry:o,otp:a}=u,l=Or(u,["attemptedAs","configuration","headers","ident","authType","registry","otp"]);if(n&&typeof o=="undefined"&&(o=SA(n.scope,{configuration:t})),typeof o!="string")throw new Error("Assertion failed: The registry should be a string");let g=await ab(o,{authType:s,configuration:t,ident:n});g&&(i=te(N({},i),{authorization:g})),a&&(i=N(N({},i),lh(a)));try{return await ir.del(o+r,N({configuration:t,headers:i},l))}catch(f){if(!ob(f)||a)throw await Ml(f,{attemptedAs:e,registry:o,configuration:t,headers:i}),f;a=await _L();let h=N(N({},i),lh(a));try{return await ir.del(`${o}${r}`,N({configuration:t,headers:h},l))}catch(p){throw await Ml(p,{attemptedAs:e,registry:o,configuration:t,headers:i}),p}}}async function ab(r,{authType:e=2,configuration:t,ident:i}){let n=zL(r,{configuration:t,ident:i}),s=_8e(n,e);if(!s)return null;let o=await t.reduceHook(a=>a.getNpmAuthenticationHeader,void 0,r,{configuration:t,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 ct(X.AUTHENTICATION_NOT_FOUND,"No authentication configured for request");return null}function _8e(r,e){switch(e){case 2:return r.get("npmAlwaysAuth");case 1:case 3:return!0;case 0:return!1;default:throw new Error("Unreachable")}}async function Y8e(r,e,{configuration:t}){var i;if(typeof e=="undefined"||typeof e.authorization=="undefined")return"an anonymous user";try{return(i=(await ir.get(new lle.URL(`${r}/-/whoami`).href,{configuration:t,headers:e,jsonResponse:!0})).username)!=null?i:"an unknown user"}catch{return"an unknown user"}}async function _L(){if(process.env.TEST_ENV)return process.env.TEST_NPM_2FA_TOKEN||"";let{otp:r}=await(0,Ale.prompt)({type:"password",name:"otp",message:"One-time password:",required:!0,onCancel:()=>process.exit(130)});return r}function ob(r){var e,t;if(((e=r.originalError)==null?void 0:e.name)!=="HTTPError")return!1;try{return((t=r.originalError)==null?void 0:t.response.headers["www-authenticate"].split(/,\s*/).map(n=>n.toLowerCase())).includes("otp")}catch(i){return!1}}function lh(r){return{["npm-otp"]:r}}var VL=class{supports(e,t){if(!e.reference.startsWith(Cr))return!1;let{selector:i,params:n}=P.parseRange(e.reference);return!(!cle.default.valid(i)||n===null||typeof n.__archiveUrl!="string")}getLocalPath(e,t){return null}async fetch(e,t){let i=t.checksums.get(e.locatorHash)||null,[n,s,o]=await t.cache.fetchPackageFromCache(e,i,N({onHit:()=>t.report.reportCacheHit(e),onMiss:()=>t.report.reportCacheMiss(e,`${P.prettyLocator(t.project.configuration,e)} can't be found in the cache and will be fetched from the remote server`),loader:()=>this.fetchFromNetwork(e,t),skipIntegrityCheck:t.skipIntegrityCheck},t.cacheOptions));return{packageFs:n,releaseFs:s,prefixPath:P.getIdentVendorPath(e),checksum:o}}async fetchFromNetwork(e,t){let{params:i}=P.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 bo(i.__archiveUrl,{configuration:t.project.configuration,ident:e});return await Bi.convertToZip(n,{compressionLevel:t.project.configuration.get("compressionLevel"),prefixPath:P.getIdentVendorPath(e),stripComponents:1})}};var XL=class{supportsDescriptor(e,t){return!(!e.range.startsWith(Cr)||!P.tryParseDescriptor(e.range.slice(Cr.length),!0))}supportsLocator(e,t){return!1}shouldPersistResolution(e,t){throw new Error("Unreachable")}bindDescriptor(e,t,i){return e}getResolutionDependencies(e,t){let i=P.parseDescriptor(e.range.slice(Cr.length),!0);return t.resolver.getResolutionDependencies(i,t)}async getCandidates(e,t,i){let n=P.parseDescriptor(e.range.slice(Cr.length),!0);return await i.resolver.getCandidates(n,t,i)}async getSatisfying(e,t,i){let n=P.parseDescriptor(e.range.slice(Cr.length),!0);return i.resolver.getSatisfying(n,t,i)}resolve(e,t){throw new Error("Unreachable")}};var ule=ge(ri()),gle=ge(require("url"));var Qo=class{supports(e,t){if(!e.reference.startsWith(Cr))return!1;let i=new gle.URL(e.reference);return!(!ule.default.valid(i.pathname)||i.searchParams.has("__archiveUrl"))}getLocalPath(e,t){return null}async fetch(e,t){let i=t.checksums.get(e.locatorHash)||null,[n,s,o]=await t.cache.fetchPackageFromCache(e,i,N({onHit:()=>t.report.reportCacheHit(e),onMiss:()=>t.report.reportCacheMiss(e,`${P.prettyLocator(t.project.configuration,e)} can't be found in the cache and will be fetched from the remote registry`),loader:()=>this.fetchFromNetwork(e,t),skipIntegrityCheck:t.skipIntegrityCheck},t.cacheOptions));return{packageFs:n,releaseFs:s,prefixPath:P.getIdentVendorPath(e),checksum:o}}async fetchFromNetwork(e,t){let i;try{i=await bo(Qo.getLocatorUrl(e),{configuration:t.project.configuration,ident:e})}catch(n){i=await bo(Qo.getLocatorUrl(e).replace(/%2f/g,"/"),{configuration:t.project.configuration,ident:e})}return await Bi.convertToZip(i,{compressionLevel:t.project.configuration.get("compressionLevel"),prefixPath:P.getIdentVendorPath(e),stripComponents:1})}static isConventionalTarballUrl(e,t,{configuration:i}){let n=SA(e.scope,{configuration:i}),s=Qo.getLocatorUrl(e);return t=t.replace(/^https?:(\/\/(?:[^/]+\.)?npmjs.org(?:$|\/))/,"https:$1"),n=n.replace(/^https:\/\/registry\.npmjs\.org($|\/)/,"https://registry.yarnpkg.com$1"),t=t.replace(/^https:\/\/registry\.npmjs\.org($|\/)/,"https://registry.yarnpkg.com$1"),t===n+s||t===n+s.replace(/%2f/g,"/")}static getLocatorUrl(e){let t=Wt.clean(e.reference.slice(Cr.length));if(t===null)throw new ct(X.RESOLVER_NOT_FOUND,"The npm semver resolver got selected, but the version isn't semver");return`${Kl(e)}/-/${e.name}-${t}.tgz`}};var fle=ge(ri());var Ab=P.makeIdent(null,"node-gyp"),V8e=/\b(node-gyp|prebuild-install)\b/,ZL=class{supportsDescriptor(e,t){return e.range.startsWith(Cr)?!!Wt.validRange(e.range.slice(Cr.length)):!1}supportsLocator(e,t){if(!e.reference.startsWith(Cr))return!1;let{selector:i}=P.parseRange(e.reference);return!!fle.default.valid(i)}shouldPersistResolution(e,t){return!0}bindDescriptor(e,t,i){return e}getResolutionDependencies(e,t){return[]}async getCandidates(e,t,i){let n=Wt.validRange(e.range.slice(Cr.length));if(n===null)throw new Error(`Expected a valid range, got ${e.range.slice(Cr.length)}`);let s=await bo(Kl(e),{configuration:i.project.configuration,ident:e,jsonResponse:!0}),o=Se.mapAndFilter(Object.keys(s.versions),c=>{try{let u=new Wt.SemVer(c);if(n.test(u))return u}catch{}return Se.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=P.makeLocator(e,`${Cr}${c.raw}`),g=s.versions[c.raw].dist.tarball;return Qo.isConventionalTarballUrl(u,g,{configuration:i.project.configuration})?u:P.bindLocator(u,{__archiveUrl:g})})}async getSatisfying(e,t,i){let n=Wt.validRange(e.range.slice(Cr.length));if(n===null)throw new Error(`Expected a valid range, got ${e.range.slice(Cr.length)}`);return Se.mapAndFilter(t,s=>{try{let{selector:o}=P.parseRange(s,{requireProtocol:Cr}),a=new Wt.SemVer(o);if(n.test(a))return{reference:s,version:a}}catch{}return Se.mapAndFilter.skip}).sort((s,o)=>-s.version.compare(o.version)).map(({reference:s})=>P.makeLocator(e,s))}async resolve(e,t){let{selector:i}=P.parseRange(e.reference),n=Wt.clean(i);if(n===null)throw new ct(X.RESOLVER_NOT_FOUND,"The npm semver resolver got selected, but the version isn't semver");let s=await bo(Kl(e),{configuration:t.project.configuration,ident:e,jsonResponse:!0});if(!Object.prototype.hasOwnProperty.call(s,"versions"))throw new ct(X.REMOTE_INVALID,'Registry returned invalid data for - missing "versions" field');if(!Object.prototype.hasOwnProperty.call(s.versions,n))throw new ct(X.REMOTE_NOT_FOUND,`Registry failed to return reference "${n}"`);let o=new At;if(o.load(s.versions[n]),!o.dependencies.has(Ab.identHash)&&!o.peerDependencies.has(Ab.identHash)){for(let a of o.scripts.values())if(a.match(V8e)){o.dependencies.set(Ab.identHash,P.makeDescriptor(Ab,"latest")),t.report.reportWarningOnce(X.NODE_GYP_INJECTED,`${P.prettyLocator(t.project.configuration,e)}: Implicit dependencies on node-gyp are discouraged`);break}}if(typeof o.raw.deprecated=="string"&&o.raw.deprecated!==""){let a=P.prettyLocator(t.project.configuration,e),l=o.raw.deprecated.match(/\S/)?`${a} is deprecated: ${o.raw.deprecated}`:`${a} is deprecated`;t.report.reportWarningOnce(X.DEPRECATED_PACKAGE,l)}return te(N({},e),{version:n,languageName:"node",linkType:Qt.HARD,conditions:o.getConditions(),dependencies:o.dependencies,peerDependencies:o.peerDependencies,dependenciesMeta:o.dependenciesMeta,peerDependenciesMeta:o.peerDependenciesMeta,bin:o.bin})}};var $L=class{supportsDescriptor(e,t){return!(!e.range.startsWith(Cr)||!zg.test(e.range.slice(Cr.length)))}supportsLocator(e,t){return!1}shouldPersistResolution(e,t){throw new Error("Unreachable")}bindDescriptor(e,t,i){return e}getResolutionDependencies(e,t){return[]}async getCandidates(e,t,i){let n=e.range.slice(Cr.length),s=await bo(Kl(e),{configuration:i.project.configuration,ident:e,jsonResponse:!0});if(!Object.prototype.hasOwnProperty.call(s,"dist-tags"))throw new ct(X.REMOTE_INVALID,'Registry returned invalid data - missing "dist-tags" field');let o=s["dist-tags"];if(!Object.prototype.hasOwnProperty.call(o,n))throw new ct(X.REMOTE_NOT_FOUND,`Registry failed to return tag "${n}"`);let a=o[n],l=P.makeLocator(e,`${Cr}${a}`),c=s.versions[a].dist.tarball;return Qo.isConventionalTarballUrl(l,c,{configuration:i.project.configuration})?[l]:[P.bindLocator(l,{__archiveUrl:c})]}async getSatisfying(e,t,i){return null}async resolve(e,t){throw new Error("Unreachable")}};var wh={};ft(wh,{getGitHead:()=>z9e,makePublishBody:()=>W9e});var HT={};ft(HT,{default:()=>k9e,packUtils:()=>PA});var PA={};ft(PA,{genPackList:()=>Pb,genPackStream:()=>UT,genPackageManifest:()=>Hce,hasPackScripts:()=>MT,prepareForPack:()=>KT});var OT=ge(is()),Kce=ge(Mce()),Uce=ge(require("zlib")),m9e=["/package.json","/readme","/readme.*","/license","/license.*","/licence","/licence.*","/changelog","/changelog.*"],E9e=["/package.tgz",".github",".git",".hg","node_modules",".npmignore",".gitignore",".#*",".DS_Store"];async function MT(r){return!!(Zt.hasWorkspaceScript(r,"prepack")||Zt.hasWorkspaceScript(r,"postpack"))}async function KT(r,{report:e},t){await Zt.maybeExecuteWorkspaceLifecycleScript(r,"prepack",{report:e});try{let i=k.join(r.cwd,At.fileName);await K.existsPromise(i)&&await r.manifest.loadFile(i,{baseFs:K}),await t()}finally{await Zt.maybeExecuteWorkspaceLifecycleScript(r,"postpack",{report:e})}}async function UT(r,e){var s,o;typeof e=="undefined"&&(e=await Pb(r));let t=new Set;for(let a of(o=(s=r.manifest.publishConfig)==null?void 0:s.executableFiles)!=null?o:new Set)t.add(k.normalize(a));for(let a of r.manifest.bin.values())t.add(k.normalize(a));let i=Kce.default.pack();process.nextTick(async()=>{for(let a of e){let l=k.normalize(a),c=k.resolve(r.cwd,l),u=k.join("package",l),g=await K.lstatPromise(c),f={name:u,mtime:new Date(Rr.SAFE_TIME*1e3)},h=t.has(l)?493:420,p,m,y=new Promise((v,x)=>{p=v,m=x}),b=v=>{v?m(v):p()};if(g.isFile()){let v;l==="package.json"?v=Buffer.from(JSON.stringify(await Hce(r),null,2)):v=await K.readFilePromise(c),i.entry(te(N({},f),{mode:h,type:"file"}),v,b)}else g.isSymbolicLink()?i.entry(te(N({},f),{mode:h,type:"symlink",linkname:await K.readlinkPromise(c)}),b):b(new Error(`Unsupported file type ${g.mode} for ${H.fromPortablePath(l)}`));await y}i.finalize()});let n=(0,Uce.createGzip)();return i.pipe(n),n}async function Hce(r){let e=JSON.parse(JSON.stringify(r.manifest.raw));return await r.project.configuration.triggerHook(t=>t.beforeWorkspacePacking,r,e),e}async function Pb(r){var g,f,h,p,m,y,b,v;let e=r.project,t=e.configuration,i={accept:[],reject:[]};for(let x of E9e)i.reject.push(x);for(let x of m9e)i.accept.push(x);i.reject.push(t.get("rcFilename"));let n=x=>{if(x===null||!x.startsWith(`${r.cwd}/`))return;let T=k.relative(r.cwd,x),q=k.resolve(Me.root,T);i.reject.push(q)};n(k.resolve(e.cwd,t.get("lockfileFilename"))),n(t.get("cacheFolder")),n(t.get("globalFolder")),n(t.get("installStatePath")),n(t.get("virtualFolder")),n(t.get("yarnPath")),await t.triggerHook(x=>x.populateYarnPaths,e,x=>{n(x)});for(let x of e.workspaces){let T=k.relative(r.cwd,x.cwd);T!==""&&!T.match(/^(\.\.)?\//)&&i.reject.push(`/${T}`)}let s={accept:[],reject:[]},o=(f=(g=r.manifest.publishConfig)==null?void 0:g.main)!=null?f:r.manifest.main,a=(p=(h=r.manifest.publishConfig)==null?void 0:h.module)!=null?p:r.manifest.module,l=(y=(m=r.manifest.publishConfig)==null?void 0:m.browser)!=null?y:r.manifest.browser,c=(v=(b=r.manifest.publishConfig)==null?void 0:b.bin)!=null?v:r.manifest.bin;o!=null&&s.accept.push(k.resolve(Me.root,o)),a!=null&&s.accept.push(k.resolve(Me.root,a)),typeof l=="string"&&s.accept.push(k.resolve(Me.root,l));for(let x of c.values())s.accept.push(k.resolve(Me.root,x));if(l instanceof Map)for(let[x,T]of l.entries())s.accept.push(k.resolve(Me.root,x)),typeof T=="string"&&s.accept.push(k.resolve(Me.root,T));let u=r.manifest.files!==null;if(u){s.reject.push("/*");for(let x of r.manifest.files)jce(s.accept,x,{cwd:Me.root})}return await I9e(r.cwd,{hasExplicitFileList:u,globalList:i,ignoreList:s})}async function I9e(r,{hasExplicitFileList:e,globalList:t,ignoreList:i}){let n=[],s=new La(r),o=[[Me.root,[i]]];for(;o.length>0;){let[a,l]=o.pop(),c=await s.lstatPromise(a);if(!Yce(a,{globalList:t,ignoreLists:c.isDirectory()?null:l}))if(c.isDirectory()){let u=await s.readdirPromise(a),g=!1,f=!1;if(!e||a!==Me.root)for(let m of u)g=g||m===".gitignore",f=f||m===".npmignore";let h=f?await Gce(s,a,".npmignore"):g?await Gce(s,a,".gitignore"):null,p=h!==null?[h].concat(l):l;Yce(a,{globalList:t,ignoreLists:l})&&(p=[...l,{accept:[],reject:["**/*"]}]);for(let m of u)o.push([k.resolve(a,m),p])}else(c.isFile()||c.isSymbolicLink())&&n.push(k.relative(Me.root,a))}return n.sort()}async function Gce(r,e,t){let i={accept:[],reject:[]},n=await r.readFilePromise(k.join(e,t),"utf8");for(let s of n.split(/\n/g))jce(i.reject,s,{cwd:e});return i}function y9e(r,{cwd:e}){let t=r[0]==="!";return t&&(r=r.slice(1)),r.match(/\.{0,1}\//)&&(r=k.resolve(e,r)),t&&(r=`!${r}`),r}function jce(r,e,{cwd:t}){let i=e.trim();i===""||i[0]==="#"||r.push(y9e(i,{cwd:t}))}var gs;(function(i){i[i.None=0]="None",i[i.Match=1]="Match",i[i.NegatedMatch=2]="NegatedMatch"})(gs||(gs={}));function Yce(r,{globalList:e,ignoreLists:t}){let i=Db(r,e.accept);if(i!==0)return i===2;let n=Db(r,e.reject);if(n!==0)return n===1;if(t!==null)for(let s of t){let o=Db(r,s.accept);if(o!==0)return o===2;let a=Db(r,s.reject);if(a!==0)return a===1}return!1}function Db(r,e){let t=e,i=[];for(let n=0;n{await KT(i,{report:l},async()=>{l.reportJson({base:H.fromPortablePath(i.cwd)});let c=await Pb(i);for(let u of c)l.reportInfo(null,H.fromPortablePath(u)),l.reportJson({location:H.fromPortablePath(u)});if(!this.dryRun){let u=await UT(i,c),g=K.createWriteStream(s);u.pipe(g),await new Promise(f=>{g.on("finish",f)})}}),this.dryRun||(l.reportInfo(X.UNNAMED,`Package archive generated in ${ae.pretty(e,s,ae.Type.PATH)}`),l.reportJson({output:H.fromPortablePath(s)}))})).exitCode()}};rE.paths=[["pack"]],rE.usage=Re.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 Jce=rE;function w9e(r,{workspace:e}){let t=r.replace("%s",B9e(e)).replace("%v",b9e(e));return H.toPortablePath(t)}function B9e(r){return r.manifest.name!==null?P.slugifyIdent(r.manifest.name):"package"}function b9e(r){return r.manifest.version!==null?r.manifest.version:"unknown"}var Q9e=["dependencies","devDependencies","peerDependencies"],S9e="workspace:",v9e=(r,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 t=r.project;for(let s of Q9e)for(let o of r.manifest.getForScope(s).values()){let a=t.tryWorkspaceByDescriptor(o),l=P.parseRange(o.range);if(l.protocol===S9e)if(a===null){if(t.tryWorkspaceByIdent(o)===null)throw new ct(X.WORKSPACE_NOT_FOUND,`${P.prettyDescriptor(t.configuration,o)}: No local workspace found for this range`)}else{let c;P.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;let u=s==="dependencies"?P.makeDescriptor(o,"unknown"):null,g=u!==null&&r.manifest.ensureDependencyMeta(u).optional?"optionalDependencies":s;e[g][P.stringifyIdent(o)]=c}}},x9e={hooks:{beforeWorkspacePacking:v9e},commands:[Jce]},k9e=x9e;var tue=ge(require("crypto")),rue=ge(eue()),iue=ge(require("url"));async function W9e(r,e,{access:t,tag:i,registry:n,gitHead:s}){let o=r.project.configuration,a=r.manifest.name,l=r.manifest.version,c=P.stringifyIdent(a),u=(0,tue.createHash)("sha1").update(e).digest("hex"),g=rue.default.fromData(e).toString();typeof t=="undefined"&&(r.manifest.publishConfig&&typeof r.manifest.publishConfig.access=="string"?t=r.manifest.publishConfig.access:o.get("npmPublishAccess")!==null?t=o.get("npmPublishAccess"):a.scope?t="restricted":t="public");let f=await PA.genPackageManifest(r),h=`${c}-${l}.tgz`,p=new iue.URL(`${ma(n)}/${c}/-/${h}`);return{_id:c,_attachments:{[h]:{content_type:"application/octet-stream",data:e.toString("base64"),length:e.length}},name:c,access:t,["dist-tags"]:{[i]:l},versions:{[l]:te(N({},f),{_id:`${c}@${l}`,name:c,version:l,gitHead:s,dist:{shasum:u,integrity:g,tarball:p.toString()}})}}}async function z9e(r){try{let{stdout:e}=await Nr.execvp("git",["rev-parse","--revs-only","HEAD"],{cwd:r});return e.trim()===""?void 0:e.trim()}catch{return}}var JT={npmAlwaysAuth:{description:"URL of the selected npm registry (note: npm enterprise isn't supported)",type:Ie.BOOLEAN,default:!1},npmAuthIdent:{description:"Authentication identity for the npm registry (_auth in npm and yarn v1)",type:Ie.SECRET,default:null},npmAuthToken:{description:"Authentication token for the npm registry (_authToken in npm and yarn v1)",type:Ie.SECRET,default:null}},nue={npmAuditRegistry:{description:"Registry to query for audit reports",type:Ie.STRING,default:null},npmPublishRegistry:{description:"Registry to push packages to",type:Ie.STRING,default:null},npmRegistryServer:{description:"URL of the selected npm registry (note: npm enterprise isn't supported)",type:Ie.STRING,default:"https://registry.yarnpkg.com"}},_9e={configuration:te(N(N({},JT),nue),{npmScopes:{description:"Settings per package scope",type:Ie.MAP,valueDefinition:{description:"",type:Ie.SHAPE,properties:N(N({},JT),nue)}},npmRegistries:{description:"Settings per registry",type:Ie.MAP,normalizeKeys:ma,valueDefinition:{description:"",type:Ie.SHAPE,properties:N({},JT)}}}),fetchers:[VL,Qo],resolvers:[XL,ZL,$L]},V9e=_9e;var VT={};ft(VT,{default:()=>s_e});ys();var Ba;(function(i){i.All="all",i.Production="production",i.Development="development"})(Ba||(Ba={}));var vo;(function(s){s.Info="info",s.Low="low",s.Moderate="moderate",s.High="high",s.Critical="critical"})(vo||(vo={}));var Rb=[vo.Info,vo.Low,vo.Moderate,vo.High,vo.Critical];function sue(r,e){let t=[],i=new Set,n=o=>{i.has(o)||(i.add(o),t.push(o))};for(let o of e)n(o);let s=new Set;for(;t.length>0;){let o=t.shift(),a=r.storedResolutions.get(o);if(typeof a=="undefined")throw new Error("Assertion failed: Expected the resolution to have been registered");let l=r.storedPackages.get(a);if(!!l){s.add(o);for(let c of l.dependencies.values())n(c.descriptorHash)}}return s}function X9e(r,e){return new Set([...r].filter(t=>!e.has(t)))}function Z9e(r,e,{all:t}){let i=t?r.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=sue(r,l),g=sue(r,c);return X9e(g,u)}function oue(r){let e={};for(let t of r)e[P.stringifyIdent(t)]=P.parseRange(t.range).selector;return e}function aue(r){if(typeof r=="undefined")return new Set;let e=Rb.indexOf(r),t=Rb.slice(e);return new Set(t)}function $9e(r,e){let t=aue(e),i={};for(let n of t)i[n]=r[n];return i}function Aue(r,e){var i;let t=$9e(r,e);for(let n of Object.keys(t))if((i=t[n])!=null?i:0>0)return!0;return!1}function lue(r,e){var s;let t={},i={children:t},n=Object.values(r.advisories);if(e!=null){let o=aue(e);n=n.filter(a=>o.has(a.severity))}for(let o of Se.sortMap(n,a=>a.module_name))t[o.module_name]={label:o.module_name,value:ae.tuple(ae.Type.RANGE,o.findings.map(a=>a.version).join(", ")),children:{Issue:{label:"Issue",value:ae.tuple(ae.Type.NO_HINT,o.title)},URL:{label:"URL",value:ae.tuple(ae.Type.URL,o.url)},Severity:{label:"Severity",value:ae.tuple(ae.Type.NO_HINT,o.severity)},["Vulnerable Versions"]:{label:"Vulnerable Versions",value:ae.tuple(ae.Type.RANGE,o.vulnerable_versions)},["Patched Versions"]:{label:"Patched Versions",value:ae.tuple(ae.Type.RANGE,o.patched_versions)},Via:{label:"Via",value:ae.tuple(ae.Type.NO_HINT,Array.from(new Set(o.findings.map(a=>a.paths).flat().map(a=>a.split(">")[0]))).join(", "))},Recommendation:{label:"Recommendation",value:ae.tuple(ae.Type.NO_HINT,(s=o.recommendation)==null?void 0:s.replace(/\n/g," "))}}};return i}function cue(r,e,{all:t,environment:i}){let n=t?r.workspaces:[e],s=[Ba.All,Ba.Production].includes(i),o=[];if(s)for(let c of n)for(let u of c.manifest.dependencies.values())o.push(u);let a=[Ba.All,Ba.Development].includes(i),l=[];if(a)for(let c of n)for(let u of c.manifest.devDependencies.values())l.push(u);return oue([...o,...l].filter(c=>P.parseRange(c.range).protocol===null))}function uue(r,e,{all:t}){var s;let i=Z9e(r,e,{all:t}),n={};for(let o of r.storedPackages.values())n[P.stringifyIdent(o)]={version:(s=o.version)!=null?s:"0.0.0",integrity:o.identHash,requires:oue(o.dependencies.values()),dev:i.has(P.convertLocatorToDescriptor(o).descriptorHash)};return n}var sE=class extends Le{constructor(){super(...arguments);this.all=J.Boolean("-A,--all",!1,{description:"Audit dependencies from all workspaces"});this.recursive=J.Boolean("-R,--recursive",!1,{description:"Audit transitive dependencies as well"});this.environment=J.String("--environment",Ba.All,{description:"Which environments to cover",validator:nn(Ba)});this.json=J.Boolean("--json",!1,{description:"Format the output as an NDJSON stream"});this.severity=J.String("--severity",vo.Info,{description:"Minimal severity requested for packages to be displayed",validator:nn(vo)})}async execute(){let e=await ye.find(this.context.cwd,this.context.plugins),{project:t,workspace:i}=await ze.find(e,this.context.cwd);if(!i)throw new ht(t.cwd,this.context.cwd);await t.restoreInstallState();let n=cue(t,i,{all:this.all,environment:this.environment}),s=uue(t,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=br.getAuditRegistry(i.manifest,{configuration:e}),l,c=await pA.start({configuration:e,stdout:this.context.stdout},async()=>{l=await zt.post("/-/npm/v1/security/audits/quick",o,{authType:zt.AuthType.BEST_EFFORT,configuration:e,jsonResponse:!0,registry:a})});if(c.hasErrors())return c.exitCode();let u=Aue(l.metadata.vulnerabilities,this.severity);return!this.json&&u?(ls.emitTree(lue(l,this.severity),{configuration:e,json:this.json,stdout:this.context.stdout,separators:2}),1):(await Je.start({configuration:e,includeFooter:!1,json:this.json,stdout:this.context.stdout},async f=>{f.reportJson(l),u||f.reportInfo(X.EXCEPTION,"No audit suggestions")})).exitCode()}};sE.paths=[["npm","audit"]],sE.usage=Re.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 ${Rb.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 gue=sE;var WT=ge(ri()),zT=ge(require("util")),oE=class extends Le{constructor(){super(...arguments);this.fields=J.String("-f,--fields",{description:"A comma-separated list of manifest fields that should be displayed"});this.json=J.Boolean("--json",!1,{description:"Format the output as an NDJSON stream"});this.packages=J.Rest()}async execute(){let e=await ye.find(this.context.cwd,this.context.plugins),{project:t}=await ze.find(e,this.context.cwd),i=typeof this.fields!="undefined"?new Set(["name",...this.fields.split(/\s*,\s*/)]):null,n=[],s=!1,o=await Je.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 x=t.topLevelWorkspace;if(!x.manifest.name)throw new Pe(`Missing ${ae.pretty(e,"name",ae.Type.CODE)} field in ${H.fromPortablePath(k.join(x.cwd,kt.manifest))}`);c=P.makeDescriptor(x.manifest.name,"unknown")}else c=P.parseDescriptor(l);let u=zt.getIdentUrl(c),g=_T(await zt.get(u,{configuration:e,ident:c,jsonResponse:!0,customErrorMessage:zt.customPackageError})),f=Object.keys(g.versions).sort(WT.default.compareLoose),p=g["dist-tags"].latest||f[f.length-1],m=Wt.validRange(c.range);if(m){let x=WT.default.maxSatisfying(f,m);x!==null?p=x:(a.reportWarning(X.UNNAMED,`Unmet range ${P.prettyRange(e,c.range)}; falling back to the latest version`),s=!0)}else Object.prototype.hasOwnProperty.call(g["dist-tags"],c.range)?p=g["dist-tags"][c.range]:c.range!=="unknown"&&(a.reportWarning(X.UNNAMED,`Unknown tag ${P.prettyRange(e,c.range)}; falling back to the latest version`),s=!0);let y=g.versions[p],b=te(N(N({},g),y),{version:p,versions:f}),v;if(i!==null){v={};for(let x of i){let T=b[x];if(typeof T!="undefined")v[x]=T;else{a.reportWarning(X.EXCEPTION,`The ${ae.pretty(e,x,ae.Type.CODE)} field doesn't exist inside ${P.prettyIdent(e,c)}'s information`),s=!0;continue}}}else this.json||(delete b.dist,delete b.readme,delete b.users),v=b;a.reportJson(v),this.json||n.push(v)}});zT.inspect.styles.name="cyan";for(let a of n)(a!==n[0]||s)&&this.context.stdout.write(` -`),this.context.stdout.write(`${(0,zT.inspect)(a,{depth:Infinity,colors:!0,compact:!1})} -`);return o.exitCode()}};oE.paths=[["npm","info"]],oE.usage=Re.Usage({category:"Npm-related commands",description:"show information about a package",details:"\n This command fetches 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 or to the corresponding tagged version. 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 information.\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 all available information about react@next","yarn npm info react@next"],["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 fue=oE;function _T(r){if(Array.isArray(r)){let e=[];for(let t of r)t=_T(t),t&&e.push(t);return e}else if(typeof r=="object"&&r!==null){let e={};for(let t of Object.keys(r)){if(t.startsWith("_"))continue;let i=_T(r[t]);i&&(e[t]=i)}return e}else return r||null}var hue=ge(WC()),aE=class extends Le{constructor(){super(...arguments);this.scope=J.String("-s,--scope",{description:"Login to the registry configured for a given scope"});this.publish=J.Boolean("--publish",!1,{description:"Login to the publish registry"})}async execute(){let e=await ye.find(this.context.cwd,this.context.plugins),t=await Fb({configuration:e,cwd:this.context.cwd,publish:this.publish,scope:this.scope});return(await Je.start({configuration:e,stdout:this.context.stdout},async n=>{let s=await t_e({registry:t,report:n,stdin:this.context.stdin,stdout:this.context.stdout}),o=`/-/user/org.couchdb.user:${encodeURIComponent(s.name)}`,a=await zt.put(o,s,{attemptedAs:s.name,configuration:e,registry:t,jsonResponse:!0,authType:zt.AuthType.NO_AUTH});return await e_e(t,a.token,{configuration:e,scope:this.scope}),n.reportInfo(X.UNNAMED,"Successfully logged in")})).exitCode()}};aE.paths=[["npm","login"]],aE.usage=Re.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 pue=aE;async function Fb({scope:r,publish:e,configuration:t,cwd:i}){return r&&e?br.getScopeRegistry(r,{configuration:t,type:br.RegistryType.PUBLISH_REGISTRY}):r?br.getScopeRegistry(r,{configuration:t}):e?br.getPublishRegistry((await Wf(t,i)).manifest,{configuration:t}):br.getDefaultRegistry({configuration:t})}async function e_e(r,e,{configuration:t,scope:i}){let n=o=>a=>{let l=Se.isIndexableObject(a)?a:{},c=l[o],u=Se.isIndexableObject(c)?c:{};return te(N({},l),{[o]:te(N({},u),{npmAuthToken:e})})},s=i?{npmScopes:n(i)}:{npmRegistries:n(r)};return await ye.updateHomeConfiguration(s)}async function t_e({registry:r,report:e,stdin:t,stdout:i}){if(process.env.TEST_ENV)return{name:process.env.TEST_NPM_USER||"",password:process.env.TEST_NPM_PASSWORD||""};e.reportInfo(X.UNNAMED,`Logging in to ${r}`);let n=!1;r.match(/^https:\/\/npm\.pkg\.github\.com(\/|$)/)&&(e.reportInfo(X.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,hue.prompt)([{type:"input",name:"username",message:"Username:",required:!0,onCancel:()=>process.exit(130),stdin:t,stdout:i},{type:"password",name:"password",message:n?"Token:":"Password:",required:!0,onCancel:()=>process.exit(130),stdin:t,stdout:i}]);return e.reportSeparator(),{name:s,password:o}}var Bh=new Set(["npmAuthIdent","npmAuthToken"]),AE=class extends Le{constructor(){super(...arguments);this.scope=J.String("-s,--scope",{description:"Logout of the registry configured for a given scope"});this.publish=J.Boolean("--publish",!1,{description:"Logout of the publish registry"});this.all=J.Boolean("-A,--all",!1,{description:"Logout of all registries"})}async execute(){let e=await ye.find(this.context.cwd,this.context.plugins),t=async()=>{var l;let n=await Fb({configuration:e,cwd:this.context.cwd,publish:this.publish,scope:this.scope}),s=await ye.find(this.context.cwd,this.context.plugins),o=P.makeIdent((l=this.scope)!=null?l:null,"pkg");return!br.getAuthConfiguration(n,{configuration:s,ident:o}).get("npmAuthToken")};return(await Je.start({configuration:e,stdout:this.context.stdout},async n=>{if(this.all&&(await r_e(),n.reportInfo(X.UNNAMED,"Successfully logged out from everything")),this.scope){await due("npmScopes",this.scope),await t()?n.reportInfo(X.UNNAMED,`Successfully logged out from ${this.scope}`):n.reportWarning(X.UNNAMED,"Scope authentication settings removed, but some other ones settings still apply to it");return}let s=await Fb({configuration:e,cwd:this.context.cwd,publish:this.publish});await due("npmRegistries",s),await t()?n.reportInfo(X.UNNAMED,`Successfully logged out from ${s}`):n.reportWarning(X.UNNAMED,"Registry authentication settings removed, but some other ones settings still apply to it")})).exitCode()}};AE.paths=[["npm","logout"]],AE.usage=Re.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 Cue=AE;function i_e(r,e){let t=r[e];if(!Se.isIndexableObject(t))return!1;let i=new Set(Object.keys(t));if([...Bh].every(s=>!i.has(s)))return!1;for(let s of Bh)i.delete(s);if(i.size===0)return r[e]=void 0,!0;let n=N({},t);for(let s of Bh)delete n[s];return r[e]=n,!0}async function r_e(){let r=e=>{let t=!1,i=Se.isIndexableObject(e)?N({},e):{};i.npmAuthToken&&(delete i.npmAuthToken,t=!0);for(let n of Object.keys(i))i_e(i,n)&&(t=!0);if(Object.keys(i).length!==0)return t?i:e};return await ye.updateHomeConfiguration({npmRegistries:r,npmScopes:r})}async function due(r,e){return await ye.updateHomeConfiguration({[r]:t=>{let i=Se.isIndexableObject(t)?t:{};if(!Object.prototype.hasOwnProperty.call(i,e))return t;let n=i[e],s=Se.isIndexableObject(n)?n:{},o=new Set(Object.keys(s));if([...Bh].every(l=>!o.has(l)))return t;for(let l of Bh)o.delete(l);if(o.size===0)return Object.keys(i).length===1?void 0:te(N({},i),{[e]:void 0});let a={};for(let l of Bh)a[l]=void 0;return te(N({},i),{[e]:N(N({},s),a)})}})}var lE=class extends Le{constructor(){super(...arguments);this.access=J.String("--access",{description:"The access for the published package (public or restricted)"});this.tag=J.String("--tag","latest",{description:"The tag on the registry that the package should be attached to"});this.tolerateRepublish=J.Boolean("--tolerate-republish",!1,{description:"Warn and exit when republishing an already existing version of a package"});this.otp=J.String("--otp",{description:"The OTP token to use with the command"})}async execute(){let e=await ye.find(this.context.cwd,this.context.plugins),{project:t,workspace:i}=await ze.find(e,this.context.cwd);if(!i)throw new ht(t.cwd,this.context.cwd);if(i.manifest.private)throw new Pe("Private workspaces cannot be published");if(i.manifest.name===null||i.manifest.version===null)throw new Pe("Workspaces must have valid names and versions to be published on an external registry");await t.restoreInstallState();let n=i.manifest.name,s=i.manifest.version,o=br.getPublishRegistry(i.manifest,{configuration:e});return(await Je.start({configuration:e,stdout:this.context.stdout},async l=>{var c,u;if(this.tolerateRepublish)try{let g=await zt.get(zt.getIdentUrl(n),{configuration:e,registry:o,ident:n,jsonResponse:!0});if(!Object.prototype.hasOwnProperty.call(g,"versions"))throw new ct(X.REMOTE_INVALID,'Registry returned invalid data for - missing "versions" field');if(Object.prototype.hasOwnProperty.call(g.versions,s)){l.reportWarning(X.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 Zt.maybeExecuteWorkspaceLifecycleScript(i,"prepublish",{report:l}),await PA.prepareForPack(i,{report:l},async()=>{let g=await PA.genPackList(i);for(let y of g)l.reportInfo(null,y);let f=await PA.genPackStream(i,g),h=await Se.bufferStream(f),p=await wh.getGitHead(i.cwd),m=await wh.makePublishBody(i,h,{access:this.access,tag:this.tag,registry:o,gitHead:p});await zt.put(zt.getIdentUrl(n),m,{configuration:e,registry:o,ident:n,otp:this.otp,jsonResponse:!0})}),l.reportInfo(X.UNNAMED,"Package archive published")})).exitCode()}};lE.paths=[["npm","publish"]],lE.usage=Re.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 mue=lE;var Iue=ge(ri());var cE=class extends Le{constructor(){super(...arguments);this.json=J.Boolean("--json",!1,{description:"Format the output as an NDJSON stream"});this.package=J.String({required:!1})}async execute(){let e=await ye.find(this.context.cwd,this.context.plugins),{project:t,workspace:i}=await ze.find(e,this.context.cwd),n;if(typeof this.package!="undefined")n=P.parseIdent(this.package);else{if(!i)throw new ht(t.cwd,this.context.cwd);if(!i.manifest.name)throw new Pe(`Missing 'name' field in ${H.fromPortablePath(k.join(i.cwd,kt.manifest))}`);n=i.manifest.name}let s=await uE(n,e),a={children:Se.sortMap(Object.entries(s),([l])=>l).map(([l,c])=>({value:ae.tuple(ae.Type.RESOLUTION,{descriptor:P.makeDescriptor(n,l),locator:P.makeLocator(n,c)})}))};return ls.emitTree(a,{configuration:e,json:this.json,stdout:this.context.stdout})}};cE.paths=[["npm","tag","list"]],cE.usage=Re.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 Eue=cE;async function uE(r,e){let t=`/-/package${zt.getIdentUrl(r)}/dist-tags`;return zt.get(t,{configuration:e,ident:r,jsonResponse:!0,customErrorMessage:zt.customPackageError})}var gE=class extends Le{constructor(){super(...arguments);this.package=J.String();this.tag=J.String()}async execute(){let e=await ye.find(this.context.cwd,this.context.plugins),{project:t,workspace:i}=await ze.find(e,this.context.cwd);if(!i)throw new ht(t.cwd,this.context.cwd);let n=P.parseDescriptor(this.package,!0),s=n.range;if(!Iue.default.valid(s))throw new Pe(`The range ${ae.pretty(e,n.range,ae.Type.RANGE)} must be a valid semver version`);let o=br.getPublishRegistry(i.manifest,{configuration:e}),a=ae.pretty(e,n,ae.Type.IDENT),l=ae.pretty(e,s,ae.Type.RANGE),c=ae.pretty(e,this.tag,ae.Type.CODE);return(await Je.start({configuration:e,stdout:this.context.stdout},async g=>{let f=await uE(n,e);Object.prototype.hasOwnProperty.call(f,this.tag)&&f[this.tag]===s&&g.reportWarning(X.UNNAMED,`Tag ${c} is already set to version ${l}`);let h=`/-/package${zt.getIdentUrl(n)}/dist-tags/${encodeURIComponent(this.tag)}`;await zt.put(h,s,{configuration:e,registry:o,ident:n,jsonRequest:!0,jsonResponse:!0}),g.reportInfo(X.UNNAMED,`Tag ${c} added to version ${l} of package ${a}`)})).exitCode()}};gE.paths=[["npm","tag","add"]],gE.usage=Re.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 yue=gE;var fE=class extends Le{constructor(){super(...arguments);this.package=J.String();this.tag=J.String()}async execute(){if(this.tag==="latest")throw new Pe("The 'latest' tag cannot be removed.");let e=await ye.find(this.context.cwd,this.context.plugins),{project:t,workspace:i}=await ze.find(e,this.context.cwd);if(!i)throw new ht(t.cwd,this.context.cwd);let n=P.parseIdent(this.package),s=br.getPublishRegistry(i.manifest,{configuration:e}),o=ae.pretty(e,this.tag,ae.Type.CODE),a=ae.pretty(e,n,ae.Type.IDENT),l=await uE(n,e);if(!Object.prototype.hasOwnProperty.call(l,this.tag))throw new Pe(`${o} is not a tag of package ${a}`);return(await Je.start({configuration:e,stdout:this.context.stdout},async u=>{let g=`/-/package${zt.getIdentUrl(n)}/dist-tags/${encodeURIComponent(this.tag)}`;await zt.del(g,{configuration:e,registry:s,ident:n,jsonResponse:!0}),u.reportInfo(X.UNNAMED,`Tag ${o} removed from package ${a}`)})).exitCode()}};fE.paths=[["npm","tag","remove"]],fE.usage=Re.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 wue=fE;var hE=class extends Le{constructor(){super(...arguments);this.scope=J.String("-s,--scope",{description:"Print username for the registry configured for a given scope"});this.publish=J.Boolean("--publish",!1,{description:"Print username for the publish registry"})}async execute(){let e=await ye.find(this.context.cwd,this.context.plugins),t;return this.scope&&this.publish?t=br.getScopeRegistry(this.scope,{configuration:e,type:br.RegistryType.PUBLISH_REGISTRY}):this.scope?t=br.getScopeRegistry(this.scope,{configuration:e}):this.publish?t=br.getPublishRegistry((await Wf(e,this.context.cwd)).manifest,{configuration:e}):t=br.getDefaultRegistry({configuration:e}),(await Je.start({configuration:e,stdout:this.context.stdout},async n=>{var o,a;let s;try{s=await zt.get("/-/whoami",{configuration:e,registry:t,authType:zt.AuthType.ALWAYS_AUTH,jsonResponse:!0,ident:this.scope?P.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(X.AUTHENTICATION_INVALID,"Authentication failed - your credentials may have expired");return}else throw l}n.reportInfo(X.UNNAMED,s.username)})).exitCode()}};hE.paths=[["npm","whoami"]],hE.usage=Re.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 Bue=hE;var n_e={configuration:{npmPublishAccess:{description:"Default access of the published packages",type:Ie.STRING,default:null}},commands:[gue,fue,pue,Cue,mue,yue,Eue,wue,Bue]},s_e=n_e;var nO={};ft(nO,{default:()=>y_e,patchUtils:()=>XT});var XT={};ft(XT,{applyPatchFile:()=>Tb,diffFolders:()=>tO,extractPackageToDisk:()=>eO,extractPatchFlags:()=>Due,isParentRequired:()=>$T,loadPatchFiles:()=>mE,makeDescriptor:()=>m_e,makeLocator:()=>ZT,parseDescriptor:()=>dE,parseLocator:()=>CE,parsePatchFile:()=>Lb});var pE=class extends Error{constructor(e,t){super(`Cannot apply hunk #${e+1}`);this.hunk=t}};var o_e=/^@@ -(\d+)(,(\d+))? \+(\d+)(,(\d+))? @@.*/;function bh(r){return k.relative(Me.root,k.resolve(Me.root,H.toPortablePath(r)))}function a_e(r){let e=r.trim().match(o_e);if(!e)throw new Error(`Bad header line: '${r}'`);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 A_e=420,l_e=493,Zr;(function(i){i.Context="context",i.Insertion="insertion",i.Deletion="deletion"})(Zr||(Zr={}));var bue=()=>({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}),c_e=r=>({header:a_e(r),parts:[]}),u_e={["@"]:"header",["-"]:Zr.Deletion,["+"]:Zr.Insertion,[" "]:Zr.Context,["\\"]:"pragma",undefined:Zr.Context};function f_e(r){let e=[],t=bue(),i="parsing header",n=null,s=null;function o(){n&&(s&&(n.parts.push(s),s=null),t.hunks.push(n),n=null)}function a(){o(),e.push(t),t=bue()}for(let l=0;l0?"patch":"mode change",v=null;switch(b){case"rename":{if(!u||!g)throw new Error("Bad parser state: rename from & to not given");e.push({type:"rename",semverExclusivity:i,fromPath:bh(u),toPath:bh(g)}),v=g}break;case"file deletion":{let x=n||p;if(!x)throw new Error("Bad parse state: no path given for file deletion");e.push({type:"file deletion",semverExclusivity:i,hunk:y&&y[0]||null,path:bh(x),mode:Nb(l),hash:f})}break;case"file creation":{let x=s||m;if(!x)throw new Error("Bad parse state: no path given for file creation");e.push({type:"file creation",semverExclusivity:i,hunk:y&&y[0]||null,path:bh(x),mode:Nb(c),hash:h})}break;case"patch":case"mode change":v=m||s;break;default:Se.assertNever(b);break}v&&o&&a&&o!==a&&e.push({type:"mode change",semverExclusivity:i,path:bh(v),oldMode:Nb(o),newMode:Nb(a)}),v&&y&&y.length&&e.push({type:"patch",semverExclusivity:i,path:bh(v),hunks:y,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 Nb(r){let e=parseInt(r,8)&511;if(e!==A_e&&e!==l_e)throw new Error(`Unexpected file mode string: ${r}`);return e}function Lb(r){let e=r.split(/\n/g);return e[e.length-1]===""&&e.pop(),h_e(f_e(e))}function g_e(r){let e=0,t=0;for(let{type:i,lines:n}of r.parts)switch(i){case Zr.Context:t+=n.length,e+=n.length;break;case Zr.Deletion:e+=n.length;break;case Zr.Insertion:t+=n.length;break;default:Se.assertNever(i);break}if(e!==r.header.original.length||t!==r.header.patched.length){let i=n=>n<0?n:`+${n}`;throw new Error(`hunk header integrity check failed (expected @@ ${i(r.header.original.length)} ${i(r.header.patched.length)} @@, got @@ ${i(e)} ${i(t)} @@)`)}}async function Qh(r,e,t){let i=await r.lstatPromise(e),n=await t();if(typeof n!="undefined"&&(e=n),r.lutimesPromise)await r.lutimesPromise(e,i.atime,i.mtime);else if(!i.isSymbolicLink())await r.utimesPromise(e,i.atime,i.mtime);else throw new Error("Cannot preserve the time values of a symlink")}async function Tb(r,{baseFs:e=new ar,dryRun:t=!1,version:i=null}={}){for(let n of r)if(!(n.semverExclusivity!==null&&i!==null&&!Wt.satisfiesWithPrereleases(i,n.semverExclusivity)))switch(n.type){case"file deletion":if(t){if(!e.existsSync(n.path))throw new Error(`Trying to delete a file that doesn't exist: ${n.path}`)}else await Qh(e,k.dirname(n.path),async()=>{await e.unlinkPromise(n.path)});break;case"rename":if(t){if(!e.existsSync(n.fromPath))throw new Error(`Trying to move a file that doesn't exist: ${n.fromPath}`)}else await Qh(e,k.dirname(n.fromPath),async()=>{await Qh(e,k.dirname(n.toPath),async()=>{await Qh(e,n.fromPath,async()=>(await e.movePromise(n.fromPath,n.toPath),n.toPath))})});break;case"file creation":if(t){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(k.dirname(n.path),{chmod:493,utimes:[Rr.SAFE_TIME,Rr.SAFE_TIME]}),await e.writeFilePromise(n.path,s,{mode:n.mode}),await e.utimesPromise(n.path,Rr.SAFE_TIME,Rr.SAFE_TIME)}break;case"patch":await Qh(e,n.path,async()=>{await p_e(n,{baseFs:e,dryRun:t})});break;case"mode change":{let o=(await e.statPromise(n.path)).mode;if(Que(n.newMode)!==Que(o))continue;await Qh(e,n.path,async()=>{await e.chmodPromise(n.path,n.newMode)})}break;default:Se.assertNever(n);break}}function Que(r){return(r&64)>0}function Sue(r){return r.replace(/\s+$/,"")}function d_e(r,e){return Sue(r)===Sue(e)}async function p_e({hunks:r,path:e},{baseFs:t,dryRun:i=!1}){let n=await t.statSync(e).mode,o=(await t.readFileSync(e,"utf8")).split(/\n/),a=[],l=0,c=0;for(let g of r){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),m=Math.max(h,p),y=0,b=0,v=null;for(;y<=m;){if(y<=h&&(b=f-y,v=vue(g,o,b),v!==null)){y=-y;break}if(y<=p&&(b=f+y,v=vue(g,o,b),v!==null))break;y+=1}if(v===null)throw new pE(r.indexOf(g),g);a.push(v),l+=y,c=b+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:Se.assertNever(f);break}await t.writeFilePromise(e,o.join(` -`),{mode:n})}function vue(r,e,t){let i=[];for(let n of r.parts)switch(n.type){case Zr.Context:case Zr.Deletion:{for(let s of n.lines){let o=e[t];if(o==null||!d_e(o,s))return null;t+=1}n.type===Zr.Deletion&&(i.push({type:"splice",index:t-n.lines.length,numToDelete:n.lines.length,linesToInsert:[]}),n.noNewlineAtEndOfFile&&i.push({type:"push",line:""}))}break;case Zr.Insertion:i.push({type:"splice",index:t,numToDelete:0,linesToInsert:n.lines}),n.noNewlineAtEndOfFile&&i.push({type:"pop"});break;default:Se.assertNever(n.type);break}return i}var C_e=/^builtin<([^>]+)>$/;function xue(r,e){let{source:t,selector:i,params:n}=P.parseRange(r);if(t===null)throw new Error("Patch locators must explicitly define their source");let s=i?i.split(/&/).map(c=>H.toPortablePath(c)):[],o=n&&typeof n.locator=="string"?P.parseLocator(n.locator):null,a=n&&typeof n.version=="string"?n.version:null,l=e(t);return{parentLocator:o,sourceItem:l,patchPaths:s,sourceVersion:a}}function dE(r){let i=xue(r.range,P.parseDescriptor),{sourceItem:e}=i,t=Or(i,["sourceItem"]);return te(N({},t),{sourceDescriptor:e})}function CE(r){let i=xue(r.reference,P.parseLocator),{sourceItem:e}=i,t=Or(i,["sourceItem"]);return te(N({},t),{sourceLocator:e})}function kue({parentLocator:r,sourceItem:e,patchPaths:t,sourceVersion:i,patchHash:n},s){let o=r!==null?{locator:P.stringifyLocator(r)}:{},a=typeof i!="undefined"?{version:i}:{},l=typeof n!="undefined"?{hash:n}:{};return P.makeRange({protocol:"patch:",source:s(e),selector:t.join("&"),params:N(N(N({},a),l),o)})}function m_e(r,{parentLocator:e,sourceDescriptor:t,patchPaths:i}){return P.makeLocator(r,kue({parentLocator:e,sourceItem:t,patchPaths:i},P.stringifyDescriptor))}function ZT(r,{parentLocator:e,sourcePackage:t,patchPaths:i,patchHash:n}){return P.makeLocator(r,kue({parentLocator:e,sourceItem:t,sourceVersion:t.version,patchPaths:i,patchHash:n},P.stringifyLocator))}function Pue({onAbsolute:r,onRelative:e,onBuiltin:t},i){i.startsWith("~")&&(i=i.slice(1));let s=i.match(C_e);return s!==null?t(s[1]):k.isAbsolute(i)?r(i):e(i)}function Due(r){let e=r.startsWith("~");return e&&(r=r.slice(1)),{optional:e}}function $T(r){return Pue({onAbsolute:()=>!1,onRelative:()=>!0,onBuiltin:()=>!1},r)}async function mE(r,e,t){let i=r!==null?await t.fetcher.fetch(r,t):null,n=i&&i.localPath?{packageFs:new _t(Me.root),prefixPath:k.relative(Me.root,i.localPath)}:i;i&&i!==n&&i.releaseFs&&i.releaseFs();let s=await Se.releaseAfterUseAsync(async()=>await Promise.all(e.map(async o=>{let a=Due(o),l=await Pue({onAbsolute:async()=>await K.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(k.join(n.prefixPath,o),"utf8")},onBuiltin:async c=>await t.project.configuration.firstHook(u=>u.getBuiltinPatch,t.project,c)},o);return te(N({},a),{source:l})})));for(let o of s)typeof o.source=="string"&&(o.source=o.source.replace(/\r\n?/g,` -`));return s}async function eO(r,{cache:e,project:t}){let i=t.storedPackages.get(r.locatorHash);if(typeof i=="undefined")throw new Error("Assertion failed: Expected the package to be registered");let n=t.storedChecksums,s=new di,o=t.configuration.makeFetcher(),a=await o.fetch(r,{cache:e,project:t,fetcher:o,checksums:n,report:s}),l=await K.mktempPromise(),c=k.join(l,"source"),u=k.join(l,"user"),g=k.join(l,".yarn-patch.json");return await Promise.all([K.copyPromise(c,a.prefixPath,{baseFs:a.packageFs}),K.copyPromise(u,a.prefixPath,{baseFs:a.packageFs}),K.writeJsonPromise(g,{locator:P.stringifyLocator(r),version:i.version})]),K.detachTemp(l),u}async function tO(r,e){let t=H.fromPortablePath(r).replace(/\\/g,"/"),i=H.fromPortablePath(e).replace(/\\/g,"/"),{stdout:n,stderr:s}=await Nr.execvp("git",["-c","core.safecrlf=false","diff","--src-prefix=a/","--dst-prefix=b/","--ignore-cr-at-eol","--full-index","--no-index","--no-renames","--text",t,i],{cwd:H.toPortablePath(process.cwd()),env:te(N({},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=t.startsWith("/")?a=>a.slice(1):a=>a;return n.replace(new RegExp(`(a|b)(${Se.escapeRegExp(`/${o(t)}/`)})`,"g"),"$1/").replace(new RegExp(`(a|b)${Se.escapeRegExp(`/${o(i)}/`)}`,"g"),"$1/").replace(new RegExp(Se.escapeRegExp(`${t}/`),"g"),"").replace(new RegExp(Se.escapeRegExp(`${i}/`),"g"),"")}function Rue(r,{configuration:e,report:t}){for(let i of r.parts)for(let n of i.lines)switch(i.type){case Zr.Context:t.reportInfo(null,` ${ae.pretty(e,n,"grey")}`);break;case Zr.Deletion:t.reportError(X.FROZEN_LOCKFILE_EXCEPTION,`- ${ae.pretty(e,n,ae.Type.REMOVED)}`);break;case Zr.Insertion:t.reportError(X.FROZEN_LOCKFILE_EXCEPTION,`+ ${ae.pretty(e,n,ae.Type.ADDED)}`);break;default:Se.assertNever(i.type)}}var rO=class{supports(e,t){return!!e.reference.startsWith("patch:")}getLocalPath(e,t){return null}async fetch(e,t){let i=t.checksums.get(e.locatorHash)||null,[n,s,o]=await t.cache.fetchPackageFromCache(e,i,N({onHit:()=>t.report.reportCacheHit(e),onMiss:()=>t.report.reportCacheMiss(e,`${P.prettyLocator(t.project.configuration,e)} can't be found in the cache and will be fetched from the disk`),loader:()=>this.patchPackage(e,t),skipIntegrityCheck:t.skipIntegrityCheck},t.cacheOptions));return{packageFs:n,releaseFs:s,prefixPath:P.getIdentVendorPath(e),localPath:this.getLocalPath(e,t),checksum:o}}async patchPackage(e,t){let{parentLocator:i,sourceLocator:n,sourceVersion:s,patchPaths:o}=CE(e),a=await mE(i,o,t),l=await K.mktempPromise(),c=k.join(l,"current.zip"),u=await t.fetcher.fetch(n,t),g=P.getIdentVendorPath(e),f=await fn(),h=new li(c,{libzip:f,create:!0,level:t.project.configuration.get("compressionLevel")});await Se.releaseAfterUseAsync(async()=>{await h.copyPromise(g,u.prefixPath,{baseFs:u.packageFs,stableSort:!0})},u.releaseFs),h.saveAndClose();for(let{source:p,optional:m}of a){if(p===null)continue;let y=new li(c,{libzip:f,level:t.project.configuration.get("compressionLevel")}),b=new _t(k.resolve(Me.root,g),{baseFs:y});try{await Tb(Lb(p),{baseFs:b,version:s})}catch(v){if(!(v instanceof pE))throw v;let x=t.project.configuration.get("enableInlineHunks"),T=!x&&!m?" (set enableInlineHunks for details)":"",q=`${P.prettyLocator(t.project.configuration,e)}: ${v.message}${T}`,Y=$=>{!x||Rue(v.hunk,{configuration:t.project.configuration,report:$})};if(y.discardAndClose(),m){t.report.reportWarningOnce(X.PATCH_HUNK_FAILED,q,{reportExtra:Y});continue}else throw new ct(X.PATCH_HUNK_FAILED,q,Y)}y.saveAndClose()}return new li(c,{libzip:f,level:t.project.configuration.get("compressionLevel")})}};var E_e=3,iO=class{supportsDescriptor(e,t){return!!e.range.startsWith("patch:")}supportsLocator(e,t){return!!e.reference.startsWith("patch:")}shouldPersistResolution(e,t){return!1}bindDescriptor(e,t,i){let{patchPaths:n}=dE(e);return n.every(s=>!$T(s))?e:P.bindDescriptor(e,{locator:P.stringifyLocator(t)})}getResolutionDependencies(e,t){let{sourceDescriptor:i}=dE(e);return[i]}async getCandidates(e,t,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}=dE(e),a=await mE(n,o,i.fetchOptions),l=t.get(s.descriptorHash);if(typeof l=="undefined")throw new Error("Assertion failed: The dependency should have been resolved");let c=Dn.makeHash(`${E_e}`,...a.map(u=>JSON.stringify(u))).slice(0,6);return[ZT(e,{parentLocator:n,sourcePackage:l,patchPaths:o,patchHash:c})]}async getSatisfying(e,t,i){return null}async resolve(e,t){let{sourceLocator:i}=CE(e),n=await t.resolver.resolve(i,t);return N(N({},n),e)}};var EE=class extends Le{constructor(){super(...arguments);this.save=J.Boolean("-s,--save",!1,{description:"Add the patch to your resolution entries"});this.patchFolder=J.String()}async execute(){let e=await ye.find(this.context.cwd,this.context.plugins),{project:t,workspace:i}=await ze.find(e,this.context.cwd);if(!i)throw new ht(t.cwd,this.context.cwd);await t.restoreInstallState();let n=k.resolve(this.context.cwd,H.toPortablePath(this.patchFolder)),s=k.join(n,"../source"),o=k.join(n,"../.yarn-patch.json");if(!K.existsSync(s))throw new Pe("The argument folder didn't get created by 'yarn patch'");let a=await tO(s,n),l=await K.readJsonPromise(o),c=P.parseLocator(l.locator,!0);if(!t.storedPackages.has(c.locatorHash))throw new Pe("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=k.join(u,`${P.slugifyLocator(c)}.patch`);await K.mkdirPromise(u,{recursive:!0}),await K.writeFilePromise(g,a);let f=k.relative(t.cwd,g);t.topLevelWorkspace.manifest.resolutions.push({pattern:{descriptor:{fullName:P.stringifyIdent(c),description:l.version}},reference:`patch:${P.stringifyLocator(c)}#${f}`}),await t.persist()}};EE.paths=[["patch-commit"]],EE.usage=Re.Usage({description:"generate a patch out of a directory",details:"\n By default, 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 With the `-s,--save` option set, the patchfile won't be printed on stdout anymore and will instead be stored within a local file (by default kept within `.yarn/patches`, but configurable via the `patchFolder` setting). A `resolutions` entry will also be added to your top-level manifest, referencing the patched package via the `patch:` protocol.\n\n Note that only folders generated by `yarn patch` are accepted as valid input for `yarn patch-commit`.\n "});var Fue=EE;var IE=class extends Le{constructor(){super(...arguments);this.json=J.Boolean("--json",!1,{description:"Format the output as an NDJSON stream"});this.package=J.String()}async execute(){let e=await ye.find(this.context.cwd,this.context.plugins),{project:t,workspace:i}=await ze.find(e,this.context.cwd),n=await Nt.find(e);if(!i)throw new ht(t.cwd,this.context.cwd);await t.restoreInstallState();let s=P.parseLocator(this.package);if(s.reference==="unknown"){let o=Se.mapAndFilter([...t.storedPackages.values()],a=>a.identHash!==s.identHash?Se.mapAndFilter.skip:P.isVirtualLocator(a)?Se.mapAndFilter.skip:a);if(o.length===0)throw new Pe("No package found in the project for the given locator");if(o.length>1)throw new Pe(`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=>` -- ${P.prettyLocator(e,a)}`).join("")}`);s=o[0]}if(!t.storedPackages.has(s.locatorHash))throw new Pe("No package found in the project for the given locator");await Je.start({configuration:e,json:this.json,stdout:this.context.stdout},async o=>{let a=await eO(s,{cache:n,project:t});o.reportJson({locator:P.stringifyLocator(s),path:H.fromPortablePath(a)}),o.reportInfo(X.UNNAMED,`Package ${P.prettyLocator(e,s)} got extracted with success!`),o.reportInfo(X.UNNAMED,`You can now edit the following folder: ${ae.pretty(e,H.fromPortablePath(a),"magenta")}`),o.reportInfo(X.UNNAMED,`Once you are done run ${ae.pretty(e,`yarn patch-commit -s ${process.platform==="win32"?'"':""}${H.fromPortablePath(a)}${process.platform==="win32"?'"':""}`,"cyan")} and Yarn will store a patchfile based on your changes.`)})}};IE.paths=[["patch"]],IE.usage=Re.Usage({description:"prepare a package for patching",details:"\n This command will cause a package to be extracted in a temporary directory intended to be editable at will.\n \n Once you're done with your changes, run `yarn patch-commit -s ` (with `` being the temporary directory you received) to generate a patchfile and register it into your top-level manifest via the `patch:` protocol. Run `yarn patch-commit -h` for more details.\n "});var Nue=IE;var I_e={configuration:{enableInlineHunks:{description:"If true, the installs will print unmatched patch hunks",type:Ie.BOOLEAN,default:!1},patchFolder:{description:"Folder where the patch files must be written",type:Ie.ABSOLUTE_PATH,default:"./.yarn/patches"}},commands:[Fue,Nue],fetchers:[rO],resolvers:[iO]},y_e=I_e;var AO={};ft(AO,{default:()=>b_e});var sO=class{supportsPackage(e,t){return this.isEnabled(t)}async findPackageLocation(e,t){if(!this.isEnabled(t))throw new Error("Assertion failed: Expected the pnpm linker to be enabled");let i=oO(),n=t.project.installersCustomData.get(i);if(!n)throw new Pe(`The project in ${ae.pretty(t.project.configuration,`${t.project.cwd}/package.json`,ae.Type.PATH)} doesn't seem to have been installed - running an install there might help`);let s=n.pathByLocator.get(e.locatorHash);if(typeof s=="undefined")throw new Pe(`Couldn't find ${P.prettyLocator(t.project.configuration,e)} in the currently installed pnpm map - running an install might help`);return s}async findPackageLocator(e,t){if(!this.isEnabled(t))return null;let i=oO(),n=t.project.installersCustomData.get(i);if(!n)throw new Pe(`The project in ${ae.pretty(t.project.configuration,`${t.project.cwd}/package.json`,ae.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=k.dirname(a);let l=n.locatorByPath.get(a);if(l)return l}while(o!==a);return null}makeInstaller(e){return new Lue(e)}isEnabled(e){return e.project.configuration.get("nodeLinker")==="pnpm"}},Lue=class{constructor(e){this.opts=e;this.asyncActions=new Se.AsyncActions(10);this.customData={pathByLocator:new Map,locatorByPath:new Map}}getCustomDataKey(){return oO()}attachCustomData(e){}async installPackage(e,t,i){switch(e.linkType){case Qt.SOFT:return this.installPackageSoft(e,t,i);case Qt.HARD:return this.installPackageHard(e,t,i)}throw new Error("Assertion failed: Unsupported package link type")}async installPackageSoft(e,t,i){let n=k.resolve(t.packageFs.getRealPath(),t.prefixPath);return this.customData.pathByLocator.set(e.locatorHash,n),{packageLocation:n,buildDirective:null}}async installPackageHard(e,t,i){var u;let n=w_e(e,{project:this.opts.project});this.customData.locatorByPath.set(n,P.stringifyLocator(e)),this.customData.pathByLocator.set(e.locatorHash,n),i.holdFetchResult(this.asyncActions.set(e.locatorHash,async()=>{await K.mkdirPromise(n,{recursive:!0}),await K.copyPromise(n,t.prefixPath,{baseFs:t.packageFs,overwrite:!1})}));let o=P.isVirtualLocator(e)?P.devirtualizeLocator(e):e,a={manifest:(u=await At.tryFind(t.prefixPath,{baseFs:t.packageFs}))!=null?u:new At,misc:{hasBindingGyp:Ca.hasBindingGyp(t)}},l=this.opts.project.getDependencyMeta(o,e.version),c=Ca.extractBuildScripts(e,a,l,{configuration:this.opts.project.configuration,report:this.opts.report});return{packageLocation:n,buildDirective:c}}async attachInternalDependencies(e,t){this.opts.project.configuration.get("nodeLinker")==="pnpm"&&(!Mue(e,{project:this.opts.project})||this.asyncActions.reduce(e.locatorHash,async i=>{await i;let n=this.customData.pathByLocator.get(e.locatorHash);if(typeof n=="undefined")throw new Error(`Assertion failed: Expected the package to have been registered (${P.stringifyLocator(e)})`);let s=k.join(n,kt.nodeModules),o=[],a=await Kue(s);for(let[l,c]of t){let u=c;Mue(c,{project:this.opts.project})||(this.opts.report.reportWarning(X.UNNAMED,"The pnpm linker doesn't support providing different versions to workspaces' peer dependencies"),u=P.devirtualizeLocator(c));let g=this.customData.pathByLocator.get(u.locatorHash);if(typeof g=="undefined")throw new Error(`Assertion failed: Expected the package to have been registered (${P.stringifyLocator(c)})`);let f=P.stringifyIdent(l),h=k.join(s,f),p=k.relative(k.dirname(h),g),m=a.get(f);a.delete(f),o.push(Promise.resolve().then(async()=>{if(m){if(m.isSymbolicLink()&&await K.readlinkPromise(h)===p)return;await K.removePromise(h)}await K.mkdirpPromise(k.dirname(h)),process.platform=="win32"?await K.symlinkPromise(g,h,"junction"):await K.symlinkPromise(p,h)}))}o.push(Uue(s,a)),await Promise.all(o)}))}async attachExternalDependents(e,t){throw new Error("External dependencies haven't been implemented for the pnpm linker")}async finalizeInstall(){let e=Oue(this.opts.project);if(this.opts.project.configuration.get("nodeLinker")!=="pnpm")await K.removePromise(e);else{let t=[],i=new Set;for(let s of this.customData.pathByLocator.values()){let o=k.contains(e,s);if(o!==null){let[a,,...l]=o.split(k.sep);i.add(a);let c=k.join(e,a);t.push(K.readdirPromise(c).then(u=>Promise.all(u.map(async g=>{let f=k.join(c,g);if(g===kt.nodeModules){let h=await Kue(f);return h.delete(l.join(k.sep)),Uue(f,h)}else return K.removePromise(f)}))).catch(u=>{if(u.code!=="ENOENT")throw u}))}}let n;try{n=await K.readdirPromise(e)}catch{n=[]}for(let s of n)i.has(s)||t.push(K.removePromise(k.join(e,s)));await Promise.all(t)}return await this.asyncActions.wait(),await aO(e),this.opts.project.configuration.get("nodeLinker")!=="node-modules"&&await aO(Tue(this.opts.project)),{customData:this.customData}}};function oO(){return JSON.stringify({name:"PnpmInstaller",version:2})}function Tue(r){return k.join(r.cwd,kt.nodeModules)}function Oue(r){return k.join(Tue(r),".store")}function w_e(r,{project:e}){let t=P.slugifyLocator(r),i=P.getIdentVendorPath(r);return k.join(Oue(e),t,i)}function Mue(r,{project:e}){return!P.isVirtualLocator(r)||!e.tryWorkspaceByLocator(r)}async function Kue(r){let e=new Map,t=[];try{t=await K.readdirPromise(r,{withFileTypes:!0})}catch(i){if(i.code!=="ENOENT")throw i}try{for(let i of t)if(!i.name.startsWith("."))if(i.name.startsWith("@")){let n=await K.readdirPromise(k.join(r,i.name),{withFileTypes:!0});if(n.length===0)e.set(i.name,i);else for(let s of n)e.set(`${i.name}/${s.name}`,s)}else e.set(i.name,i)}catch(i){if(i.code!=="ENOENT")throw i}return e}async function Uue(r,e){var n;let t=[],i=new Set;for(let s of e.keys()){t.push(K.removePromise(k.join(r,s)));let o=(n=P.tryParseIdent(s))==null?void 0:n.scope;o&&i.add(`@${o}`)}return Promise.all(t).then(()=>Promise.all([...i].map(s=>aO(k.join(r,s)))))}async function aO(r){try{await K.rmdirPromise(r)}catch(e){if(e.code!=="ENOENT"&&e.code!=="ENOTEMPTY")throw e}}var B_e={linkers:[sO]},b_e=B_e;var L0=()=>({modules:new Map([["@yarnpkg/cli",GC],["@yarnpkg/core",EC],["@yarnpkg/fslib",Zh],["@yarnpkg/libzip",Md],["@yarnpkg/parsers",op],["@yarnpkg/shell",Ud],["clipanion",cZ(Cp)],["semver",Q_e],["typanion",cg],["yup",S_e],["@yarnpkg/plugin-essentials",GN],["@yarnpkg/plugin-compat",zN],["@yarnpkg/plugin-dlx",_N],["@yarnpkg/plugin-file",nL],["@yarnpkg/plugin-git",jN],["@yarnpkg/plugin-github",oL],["@yarnpkg/plugin-http",lL],["@yarnpkg/plugin-init",fL],["@yarnpkg/plugin-link",mL],["@yarnpkg/plugin-nm",JL],["@yarnpkg/plugin-npm",qT],["@yarnpkg/plugin-npm-cli",VT],["@yarnpkg/plugin-pack",HT],["@yarnpkg/plugin-patch",nO],["@yarnpkg/plugin-pnp",LL],["@yarnpkg/plugin-pnpm",AO]]),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"])});s0({binaryVersion:Ur||"",pluginConfiguration:L0()});})(); -/*! - * 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 deleted file mode 100644 index 4d327a49a06..00000000000 --- a/.yarn/sdks/eslint/bin/eslint.js +++ /dev/null @@ -1,20 +0,0 @@ -#!/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 deleted file mode 100644 index fc728d952bb..00000000000 --- a/.yarn/sdks/eslint/lib/api.js +++ /dev/null @@ -1,20 +0,0 @@ -#!/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 deleted file mode 100644 index d0ae2df0dc7..00000000000 --- a/.yarn/sdks/eslint/package.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "name": "eslint", - "version": "8.13.0-sdk", - "main": "./lib/api.js", - "type": "commonjs" -} diff --git a/.yarn/sdks/integrations.yml b/.yarn/sdks/integrations.yml deleted file mode 100644 index aa9d0d0ad81..00000000000 --- a/.yarn/sdks/integrations.yml +++ /dev/null @@ -1,5 +0,0 @@ -# This file is automatically generated by @yarnpkg/sdks. -# Manual changes might be lost! - -integrations: - - vscode diff --git a/.yarnrc.yml b/.yarnrc.yml deleted file mode 100644 index fc5c8616695..00000000000 --- a/.yarnrc.yml +++ /dev/null @@ -1,43 +0,0 @@ -defaultSemverRangePrefix: "" - -enableTelemetry: false - -nodeLinker: pnp - -packageExtensions: - "@parcel/cache@*": - dependencies: - "@parcel/core": 2.6.2 - "@parcel/fs@*": - dependencies: - "@parcel/core": 2.6.2 - "@parcel/optimizer-image@*": - dependencies: - "@parcel/core": 2.6.2 - "@parcel/package-manager@*": - dependencies: - "@parcel/core": 2.6.2 - "@parcel/workers@*": - dependencies: - "@parcel/core": 2.6.2 - eslint-config-standard@*: - dependencies: - eslint-plugin-n: "*" - select2-bootstrap-5-theme@*: - dependencies: - "@popperjs/core": "*" - -plugins: - - path: .yarn/plugins/@yarnpkg/plugin-interactive-tools.cjs - spec: "@yarnpkg/plugin-interactive-tools" - -supportedArchitectures: - cpu: - - x64 - - arm64 - os: - - darwin - - linux - - win32 - -yarnPath: .yarn/releases/yarn-3.2.2.cjs diff --git a/LICENSE b/LICENSE index aaed0ef57dc..dc6e0c56635 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ BSD 3-Clause License -Copyright (c) 2008-2022, The IETF Trust +Copyright (c) 2008-2024, The IETF Trust All rights reserved. Redistribution and use in source and binary forms, with or without @@ -26,4 +26,4 @@ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/README.md b/README.md index d11fe4e1861..48dfdae27e4 100644 --- a/README.md +++ b/README.md @@ -1,15 +1,16 @@
-IETF Datatracker +Datatracker + +# Datatracker [![Release](https://img.shields.io/github/release/ietf-tools/datatracker.svg?style=flat&maxAge=300)](https://github.com/ietf-tools/datatracker/releases) [![License](https://img.shields.io/github/license/ietf-tools/datatracker)](https://github.com/ietf-tools/datatracker/blob/main/LICENSE) -[![Code Coverage](https://codecov.io/gh/ietf-tools/datatracker/branch/feat/bs5/graph/badge.svg?token=V4DXB0Q28C)](https://codecov.io/gh/ietf-tools/datatracker) -[![Nightly Dev DB Image](https://github.com/ietf-tools/datatracker/actions/workflows/dev-db-nightly.yml/badge.svg)](https://github.com/ietf-tools/datatracker/pkgs/container/datatracker-db) -[![Python Version](https://img.shields.io/badge/python-3.9-blue?logo=python&logoColor=white)](#prerequisites) -[![Django Version](https://img.shields.io/badge/django-2.x-51be95?logo=django&logoColor=white)](#prerequisites) -[![Node Version](https://img.shields.io/badge/node.js-16.x-green?logo=node.js&logoColor=white)](#prerequisites) -[![MariaDB Version](https://img.shields.io/badge/mariadb-10-blue?logo=mariadb&logoColor=white)](#prerequisites) +[![Code Coverage](https://codecov.io/gh/ietf-tools/datatracker/branch/feat/bs5/graph/badge.svg?token=V4DXB0Q28C)](https://codecov.io/gh/ietf-tools/datatracker) +[![Python Version](https://img.shields.io/badge/python-3.12-blue?logo=python&logoColor=white)](#prerequisites) +[![Django Version](https://img.shields.io/badge/django-4.x-51be95?logo=django&logoColor=white)](#prerequisites) +[![Node Version](https://img.shields.io/badge/node.js-26.x-green?logo=node.js&logoColor=white)](#prerequisites) +[![MariaDB Version](https://img.shields.io/badge/postgres-17-blue?logo=postgresql&logoColor=white)](#prerequisites) ##### The day-to-day front-end to the IETF database for people who work on IETF standards. @@ -18,7 +19,8 @@ - [**Production Website**](https://datatracker.ietf.org) - [Changelog](https://github.com/ietf-tools/datatracker/releases) - [Contributing](https://github.com/ietf-tools/.github/blob/main/CONTRIBUTING.md) -- [Getting Started](#getting-started) +- [Getting Started](#getting-started) - *[ tl;dr ](#the-tldr-to-get-going)* + - [Creating a Fork](#creating-a-fork) - [Git Cloning Tips](#git-cloning-tips) - [Docker Dev Environment](docker/README.md) - [Database & Assets](#database--assets) @@ -33,6 +35,10 @@ - [Handling of Internal Static Files](#handling-of-internal-static-files) - [Changes to Template Files](#changes-to-template-files) - [Deployment](#deployment) +- [Running Tests](#running-tests) + - [Python](#python-tests) + - [Frontend](#frontend-tests) + - [Diff Tool](#diff-tool) --- @@ -40,14 +46,24 @@ This project is following the standard **Git Feature Workflow** development model. Learn about all the various steps of the development workflow, from creating a fork to submitting a pull request, in the [Contributing](https://github.com/ietf-tools/.github/blob/main/CONTRIBUTING.md) guide. +> [!TIP] > Make sure to read the [Styleguides](https://github.com/ietf-tools/.github/blob/main/CONTRIBUTING.md#styleguides) section to ensure a cohesive code format across the project. You can submit bug reports, enhancement and new feature requests in the [discussions](https://github.com/ietf-tools/datatracker/discussions) area. Accepted tickets will be converted to issues. +#### Creating a Fork + +Click the Fork button in the top-right corner of the repository to create a personal copy that you can work on. + +> [!NOTE] +> Some GitHub Actions might be enabled by default in your fork. You should disable them by going to **Settings** > **Actions** > **General** and selecting **Disable actions** (then Save). + #### Git Cloning Tips As outlined in the [Contributing](https://github.com/ietf-tools/.github/blob/main/CONTRIBUTING.md) guide, you will first want to create a fork of the datatracker project in your personal GitHub account before cloning it. +Windows developers: [Start with WSL2 from the beginning](https://github.com/ietf-tools/.github/blob/main/docs/windows-dev.md). + Because of the extensive history of this project, cloning the datatracker project locally can take a long time / disk space. You can speed up the cloning process by limiting the history depth, for example *(replace `USERNAME` with your GitHub username)*: - To fetch only up to the 10 latest commits: @@ -59,6 +75,25 @@ Because of the extensive history of this project, cloning the datatracker projec git clone --shallow-since=DATE https://github.com/USERNAME/datatracker.git ``` +#### The tl;dr to get going + +Note that you will have to have cloned the datatracker code locally - please read the above sections. + +Datatracker development is performed using Docker containers. You will need to be able to run docker (and docker-compose) on your machine to effectively develop. It is possible to get a purely native install working, but it is _very complicated_ and typically takes a first time datatracker developer a full day of setup, where the docker setup completes in a small number of minutes. + +Many developers are using [VS Code](https://code.visualstudio.com/) and taking advantage of VS Code's ability to start a project in a set of containers. If you are using VS Code, simply start VS Code in your clone and inside VS Code choose `Restart in container`. + +If VS Code is not available to you, in your clone, type `cd docker; ./run` + +Once the containers are started, run the tests to make sure your checkout is a good place to start from (all tests should pass - if any fail, ask for help at tools-help@). Inside the app container's shell type: +```sh +ietf/manage.py test --settings=settings_test +``` + +Note that we recently moved the datatracker onto PostgreSQL - you may still find older documentation that suggests testing with settings_sqlitetest. That will no longer work. + +For a more detailed description of getting going, see [docker/README.md](docker/README.md). + #### Overview of the datatracker models A beginning of a [walkthrough of the datatracker models](https://notes.ietf.org/iab-aid-datatracker-database-overview) was prepared for the IAB AID workshop. @@ -71,16 +106,33 @@ Read the [Docker Dev Environment](docker/README.md) guide to get started. ### Database & Assets -Nightly database dumps of the datatracker are available at -https://www.ietf.org/lib/dt/sprint/ietf_utf8.sql.gz +Nightly database dumps of the datatracker are available as Docker images: `ghcr.io/ietf-tools/datatracker-db:latest` + +> [!TIP] +> In order to update the database in your dev environment to the latest version, you should run the `docker/cleandb` script. + +### Blob storage for dev/test + +The dev and test environments use [minio](https://github.com/minio/minio) to provide local blob storage. See the settings files for how the app container communicates with the blobstore container. If you need to work with minio directly from outside the containers (to interact with its api or console), use `docker compose` from the top level directory of your clone to expose it at an ephemeral port. + +``` +$ docker compose port blobstore 9001 +0.0.0.0: + +$ curl -I http://localhost: +HTTP/1.1 200 OK +... +``` + + +The minio container exposes the minio api at port 9000 and the minio console at port 9001 -> Note that this link is provided as reference only. To update the database in your dev environment to the latest version, you should instead run the `docker/cleandb` script! ### Frontend Development #### Intro -We now use `yarn` to manage assets for the Datatracker, and `vite`/`parcel` to package them. `yarn` maintains its `node` packages under the `.yarn` directory. +Assets are built + bundled using `vite` / `parcel`. The datatracker uses 2 different build systems, depending on the use case: - [**Vite**](https://vitejs.dev/) for Vue 3 pages / components @@ -92,12 +144,12 @@ Pages will gradually be updated to Vue 3 components. These components are locate Each Vue 3 app has its own sub-directory. For example, the agenda app is located under `/client/agenda`. -The datatracker makes use of the Django-Vite plugin to point to either the Vite.js server or the precompiled production files. The `DJANGO_VITE_DEV_MODE` flag, found in the `ietf/settings_local.py` file determines whether the Vite.js server is used or not. +The datatracker makes use of the Django-Vite plugin to point to either the Vite.js server or the precompiled production files. The `DJANGO_VITE["default"]["dev_mode"]` flag, found in the `ietf/settings_local.py` file determines whether the Vite.js server is used or not. In development mode, you must start the Vite.js development server, in addition to the usual Datatracker server: ```sh -yarn dev +npm run dev ``` Any changes made to the files under `/client` will automatically trigger a hot-reload of the modified components. @@ -105,20 +157,20 @@ Any changes made to the files under `/client` will automatically trigger a hot-r To generate production assets, run the build command: ```sh -yarn build +npm run build ``` This will create packages under `ietf/static/dist-neue`, which are then served by the Django development server, and which must be uploaded to the CDN. #### Parcel *(Legacy/jQuery)* -The Datatracker includes these packages from the various Javascript and CSS files in `ietf/static/js` and `ietf/static/css`, respectively. +The Datatracker includes these packages from the various Javascript and CSS files in `ietf/static/js` and `ietf/static/css` respectively, bundled using Parcel. Static images are likewise in `ietf/static/images`. -Whenever changes are made to the files under `ietf/static`, you must re-run `parcel` to package them: +Whenever changes are made to the files under `ietf/static`, you must re-run the build command to package them: ``` shell -yarn legacy:build +npm run legacy:build ``` This will create packages under `ietf/static/dist/ietf`, which are then served by the Django development server, and which must be uploaded to the CDN. @@ -168,11 +220,9 @@ In order to work backwards from a file served in development mode to the locatio #### Handling of External Javascript and CSS Components -In order to make it easy to keep track of and upgrade external components, these are now handled by a tool called `yarn` via the configuration in `package.json`. - To add a new package, simply run (replace `` with the NPM module name): ```sh -yarn add +npm install ``` #### Handling of Internal Static Files @@ -191,3 +241,80 @@ During deployment, it is now necessary to run the management command: ietf/manage.py collectstatic ```` before activating a new release. + +## Running Tests + +### Python Tests + +From a datatracker container, run the command: +```sh +./ietf/manage.py test --settings=settings_test +``` + +> [!TIP] +> You can limit the run to specific tests using the `--pattern` argument. + +### Frontend Tests + +Frontend tests are done via Playwright. There're 2 different type of tests: + +- Tests that test Vue pages / components and run natively without any external dependency. +- Tests that require a running datatracker instance to test against (usually legacy views). + +> [!IMPORTANT] +> Make sure you have Node.js 16.x or later installed on your machine. + +#### Run Vue Tests + +> [!WARNING] +> All commands below **MUST** be run from the `./playwright` directory, unless noted otherwise. + +1. Run **once** to install dependencies on your system: + ```sh + npm install + npm run install-deps + ``` + +2. Run in a **separate process**, from the **project root directory**: + ```sh + npm run preview + ``` + +3. Run the tests, in of these 3 modes, from the `./playwright` directory: + + 3.1 To run the tests headlessly (command line mode): + ```sh + npm test + ``` + 3.2 To run the tests visually **(CANNOT run in docker)**: + ```sh + npm run test:visual + ``` + + 3.3 To run the tests in debug mode **(CANNOT run in docker)**: + ```sh + npm run test:debug + ``` + +#### Run Legacy Views Tests + +First, you need to start a datatracker instance (dev or prod), ideally from a docker container, exposing the 8000 port. + +> [!WARNING] +> All commands below **MUST** be run from the `./playwright` directory. + +1. Run **once** to install dependencies on your system: +```sh +npm install +npm run install-deps +``` + +2. Run the tests headlessly (command line mode): +```sh +npm run test:legacy +``` + + +### Diff Tool + +To compare 2 different datatracker instances and look for diff, read the [diff tool instructions](dev/diff). diff --git a/bin/add-old-drafts-from-archive.py b/bin/add-old-drafts-from-archive.py deleted file mode 100755 index e169ecdcfc8..00000000000 --- a/bin/add-old-drafts-from-archive.py +++ /dev/null @@ -1,150 +0,0 @@ -#!/usr/bin/env python -# Copyright The IETF Trust 2017-2019, All Rights Reserved - -import datetime -import os -import sys -from pathlib import Path -from contextlib import closing - -os.environ["DJANGO_SETTINGS_MODULE"] = "ietf.settings" - -import django -django.setup() - -from django.conf import settings -from django.core.validators import validate_email, ValidationError -from ietf.utils.draft import PlaintextDraft -from ietf.submit.utils import update_authors - -import debug # pyflakes:ignore - -from ietf.doc.models import Document, NewRevisionDocEvent, DocEvent, State -from ietf.person.models import Person - -system = Person.objects.get(name="(System)") -expired = State.objects.get(type='draft',slug='expired') - -names = set() -print 'collecting draft names ...' -versions = 0 -for p in Path(settings.INTERNET_DRAFT_PATH).glob('draft*.txt'): - n = str(p).split('/')[-1].split('-') - if n[-1][:2].isdigit(): - name = '-'.join(n[:-1]) - if '--' in name or '.txt' in name or '[' in name or '=' in name or '&' in name: - continue - if name.startswith('draft-draft-'): - continue - if name == 'draft-ietf-trade-iotp-v1_0-dsig': - continue - if len(n[-1]) != 6: - continue - if name.startswith('draft-mlee-'): - continue - names.add('-'.join(n[:-1])) - -count=0 -print 'iterating through names ...' -for name in sorted(names): - if not Document.objects.filter(name=name).exists(): - paths = list(Path(settings.INTERNET_DRAFT_PATH).glob('%s-??.txt'%name)) - paths.sort() - doc = None - for p in paths: - n = str(p).split('/')[-1].split('-') - rev = n[-1][:2] - with open(str(p)) as txt_file: - raw = txt_file.read() - try: - text = raw.decode('utf8') - except UnicodeDecodeError: - text = raw.decode('latin1') - try: - draft = PlaintextDraft(text, txt_file.name, name_from_source=True) - except Exception as e: - print name, rev, "Can't parse", p,":",e - continue - if draft.errors and draft.errors.keys()!=['draftname',]: - print "Errors - could not process", name, rev, datetime.datetime.fromtimestamp(p.stat().st_mtime), draft.errors, draft.get_title().encode('utf8') - else: - time = datetime.datetime.fromtimestamp(p.stat().st_mtime) - if not doc: - doc = Document.objects.create(name=name, - time=time, - type_id='draft', - title=draft.get_title(), - abstract=draft.get_abstract(), - rev = rev, - pages=draft.get_pagecount(), - words=draft.get_wordcount(), - expires=time+datetime.timedelta(settings.INTERNET_DRAFT_DAYS_TO_EXPIRE), - ) - DocAlias.objects.create(name=doc.name).docs.add(doc) - doc.states.add(expired) - # update authors - authors = [] - for author in draft.get_author_list(): - full_name, first_name, middle_initial, last_name, name_suffix, email, country, company = author - - author_name = full_name.replace("\n", "").replace("\r", "").replace("<", "").replace(">", "").strip() - - if email: - try: - validate_email(email) - except ValidationError: - email = "" - - def turn_into_unicode(s): - if s is None: - return u"" - - if isinstance(s, unicode): - return s - else: - try: - return s.decode("utf-8") - except UnicodeDecodeError: - try: - return s.decode("latin-1") - except UnicodeDecodeError: - return "" - - author_name = turn_into_unicode(author_name) - email = turn_into_unicode(email) - company = turn_into_unicode(company) - - authors.append({ - "name": author_name, - "email": email, - "affiliation": company, - "country": country - }) - dummysubmission=type('', (), {})() #https://stackoverflow.com/questions/19476816/creating-an-empty-object-in-python - dummysubmission.authors = authors - update_authors(doc,dummysubmission) - - # add a docevent with words explaining where this came from - events = [] - e = NewRevisionDocEvent.objects.create( - type="new_revision", - doc=doc, - rev=rev, - by=system, - desc="New version available: %s-%s.txt" % (doc.name, doc.rev), - time=time, - ) - events.append(e) - e = DocEvent.objects.create( - type="comment", - doc = doc, - rev = rev, - by = system, - desc = "Revision added from id-archive on %s by %s"%(datetime.date.today(),sys.argv[0]), - time=time, - ) - events.append(e) - doc.time = time - doc.rev = rev - doc.save_with_history(events) - print "Added",name, rev diff --git a/bin/check-copyright b/bin/check-copyright deleted file mode 100755 index 6698e3fda36..00000000000 --- a/bin/check-copyright +++ /dev/null @@ -1,261 +0,0 @@ -#!/usr/bin/env python3.7 -# -*- mode: python; coding: utf-8 -*- -# Copyright The IETF Trust 2019, All Rights Reserved -""" -NAME - $program - Check for current copyright notice in given files - -SYNOPSIS - $program [OPTIONS] ARGS - -DESCRIPTION - Given a list of files or filename wildcard patterns, check all for - an IETF Trust copyright notice with the current year. Optionally - generate a diff on standard out which can be used by 'patch'. - - An invocation similar to the following can be particularly useful with - a set of changed version-controlled files, as it will fix up the - Copyright statements of any python files with pending changes: - - $ check-copyright -p $(svn st | cut -c 9- | grep '\.py$' ) | patch -p0 - - -%(options)s - -AUTHOR - Written by Henrik Levkowetz, - -COPYRIGHT - Copyright 2019 the IETF Trust - - This program is free software; you can redistribute it and/or modify - it under the terms of the Simplified BSD license as published by the - Open Source Initiative at http://opensource.org/licenses/BSD-2-Clause. - -""" - - -import datetime -import os -import sys -import time - -path = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) -if not path in sys.path: - sys.path.insert(0, path) - -import getopt -import re -import pytz -import tzparse -import debug - -version = "1.0.0" -program = os.path.basename(sys.argv[0]) -progdir = os.path.dirname(sys.argv[0]) - -debug.debug = True - -# ---------------------------------------------------------------------- -# Parse options - -options = "" -for line in re.findall("\n +(if|elif) +opt in \[(.+)\]:\s+#(.+)\n", open(sys.argv[0]).read()): - if not options: - options += "OPTIONS\n" - options += " %-16s %s\n" % (line[1].replace('"', ''), line[2]) -options = options.strip() - -# with ' < 1:' on the next line, this is a no-op: -if len(sys.argv) < 1: - print(__doc__ % locals()) - sys.exit(1) - -try: - opts, files = getopt.gnu_getopt(sys.argv[1:], "hC:pvV", ["help", "copyright=", "patch", "version", "verbose",]) -except Exception as e: - print( "%s: %s" % (program, e)) - sys.exit(1) - -# ---------------------------------------------------------------------- -# Handle options - -# set default values, if any -opt_verbose = 0 -opt_patch = False -opt_copyright = "Copyright The IETF Trust {years}, All Rights Reserved" - -# handle individual options -for opt, value in opts: - if opt in ["-h", "--help"]: # Output this help, then exit - print( __doc__ % locals() ) - sys.exit(1) - elif opt in ["-p", "--patch"]: # Generate patch output rather than error messages - opt_patch = True - elif opt in ["-C", "--copyright"]: # Copyright line pattern using {years} for years - opt_copyright = value - elif opt in ["-V", "--version"]: # Output version information, then exit - print( program, version ) - sys.exit(0) - elif opt in ["-v", "--verbose"]: # Be more verbose - opt_verbose += 1 - -# ---------------------------------------------------------------------- -def say(s): - sys.stderr.write("%s\n" % (s)) - -# ---------------------------------------------------------------------- -def note(s): - if opt_verbose: - sys.stderr.write("%s\n" % (s)) - -# ---------------------------------------------------------------------- -def die(s, error=1): - sys.stderr.write("\n%s: Error: %s\n\n" % (program, s)) - sys.exit(error) - -# ---------------------------------------------------------------------- - -def pipe(cmd, inp=None): - import shlex - from subprocess import Popen, PIPE - args = shlex.split(cmd) - bufsize = 4096 - stdin = PIPE if inp else None - pipe = Popen(args, stdin=stdin, stdout=PIPE, stderr=PIPE, bufsize=bufsize, encoding='utf-8', universal_newlines=True) - out, err = pipe.communicate(inp) - code = pipe.returncode - if code != 0: - raise OSError(err) - return out - -# ---------------------------------------------------------------------- -def split_loginfo(line): - try: - parts = line.split() - rev = parts[0][1:] - who = parts[2] - date = parts[4] - time = parts[5] - tz = parts[6] - when = tzparse.tzparse(" ".join(parts[4:7]), "%Y-%m-%d %H:%M:%S %Z") - when = when.astimezone(pytz.utc) - except ValueError as e: - sys.stderr.write("Bad log line format: %s\n %s\n" % (line, e)) - - return rev, who, when - -# ---------------------------------------------------------------------- -def get_first_commit(path): - note("Getting first commit for '%s'" % path) - cmd = 'svn log %s' % path - if opt_verbose > 1: - note("Running '%s' ..." % cmd) - try: - commit_log = pipe(cmd) - commit_log = commit_log.splitlines() - commit_log.reverse() - for line in commit_log: - if re.search(loginfo_format, line): - rev, who, when = split_loginfo(line) - break - else: - pass - except OSError: - rev, who, when = None, None, datetime.datetime.now() - return { path: { 'rev': rev, 'who': who, 'date': when.strftime('%Y-%m-%d %H:%M:%S'), }, } - - -# ---------------------------------------------------------------------- -# The program itself - -import os -import json - -cwd = os.getcwd() - -# Get current initinfo from cache and svn -cachefn = os.path.join(os.environ.get('HOME', '.'), '.initinfo') - -if os.path.exists(cachefn): - note("Reading initinfo cache file %s" % cachefn) - with open(cachefn, "r") as file: - cache = json.load(file) -else: - sys.stderr.write("No initinfo cache file found -- will have to extract all information from SVN.\n"+ - "This may take some time.\n\n") - cache = {} -initinfo = cache - -merged_revs = {} -write_cache = False -loginfo_format = r'^r[0-9]+ \| [^@]+@[^@]+ \| \d\d\d\d-\d\d-\d\d ' - -year = time.strftime('%Y') -copyright_re = "(?i)"+opt_copyright.format(years=r"(\d+-)?\d+") -for path in files: - try: - if not os.path.exists(path): - note("File does not exist: %s" % path) - continue - note("Checking path %s" % path) - if not path in initinfo: - initinfo.update(get_first_commit(path)) - write_cache = True - date = initinfo[path]['date'] - init = date[:4] - - copyright_year_re = "(?i)"+opt_copyright.format(years=r"({init}-)?{year}".format(init=init, year=year)) - with open(path) as file: - try: - chunk = file.read(4000) - except UnicodeDecodeError as e: - sys.stderr.write(f'Error when reading {file.name}: {e}\n') - raise - if os.path.basename(path) == '__init__.py' and len(chunk)==0: - continue - if not re.search(copyright_year_re, chunk): - if year == init: - copyright = opt_copyright.format(years=year) - else: - copyright = opt_copyright.format(years=f"{init}-{year}") - if opt_patch: - print(f"--- {file.name}\t(original)") - print(f"+++ {file.name}\t(modified)") - if not re.search(copyright_re, chunk): - # Simple case, just insert copyright at the top - print( "@@ -1,3 +1,4 @@") - print(f"+# {copyright}") - for i, line in list(enumerate(chunk.splitlines()))[:3]: - print(f" {line}") - else: - # Find old copyright, then emit preceding lines, - # change, and following lines. - pos = None - for i, line in enumerate(chunk.splitlines(), start=1): - if re.search(copyright_re, line): - pos = i - break - if not pos: - raise RuntimeError("Unexpected state: Expected a copyright line, but found none") - print(f"@@ -1,{pos+3} +1,{pos+3} @@") - for i, line in list(enumerate(chunk.splitlines(), start=1))[:pos+3]: - if i == pos: - print(f"-{line}") - print(f"+# {copyright}") - else: - print(f" {line}") - else: - sys.stderr.write(f"{path}(1): Error: Missing or bad copyright. Expected: {copyright}") - except Exception: - if write_cache: - cache = initinfo - with open(cachefn, "w") as file: - json.dump(cache, file, indent=2, sort_keys=True) - raise - -if write_cache: - cache = initinfo - with open(cachefn, "w") as file: - json.dump(cache, file, indent=2, sort_keys=True) - diff --git a/bin/count.c b/bin/count.c deleted file mode 100644 index 786f15eb978..00000000000 --- a/bin/count.c +++ /dev/null @@ -1,26 +0,0 @@ -#include - -int main( void ) -{ - int c; - int count = 0; - - //turn off buffering - setvbuf(stdin, NULL, _IONBF, 0); - setvbuf(stdout, NULL, _IONBF, 0); - setvbuf(stderr, NULL, _IONBF, 0); - - c = fgetc(stdin); - while(c != EOF) - { - if (c=='.' || c=='E' || c=='F' || c=='s') count++; else count=0; - fputc(c, stdout); - fflush(stdout); - if (count && count % 76 == 0) { - fprintf(stderr, "%4d\n", count); - fflush(stderr); - } - c = fgetc(stdin); - } - return 0; -} diff --git a/bin/daily b/bin/daily deleted file mode 100755 index 40cf3fd2bec..00000000000 --- a/bin/daily +++ /dev/null @@ -1,68 +0,0 @@ -#!/bin/bash - -# Nightly datatracker jobs. -# -# This script is expected to be triggered by cron from -# /etc/cron.d/datatracker -export LANG=en_US.UTF-8 -export PYTHONIOENCODING=utf-8 - -# Make sure we stop if something goes wrong: -program=${0##*/} -trap 'echo "$program($LINENO): Command failed with error code $? ([$$] $0 $*)"; exit 1' ERR - -# Datatracker directory -DTDIR=/a/www/ietf-datatracker/web -cd $DTDIR/ - -logger -p user.info -t cron "Running $DTDIR/bin/daily" - -# Run the hourly jobs first -$DTDIR/bin/hourly - -# Set up the virtual environment -source $DTDIR/env/bin/activate - - -# Update our information about the current version of some commands we use -$DTDIR/ietf/manage.py update_external_command_info - -# Get IANA-registered yang models -#YANG_IANA_DIR=$(python -c 'import ietf.settings; print ietf.settings.SUBMIT_YANG_IANA_MODEL_DIR') -# Hardcode the rsync target to avoid any unwanted deletes: -# rsync -avzq --delete rsync.ietf.org::iana/yang-parameters/ /a/www/ietf-ftp/yang/ianamod/ -rsync -avzq --delete /a/www/ietf-ftp/iana/yang-parameters/ /a/www/ietf-ftp/yang/ianamod/ - -# Get Yang models from Yangcatalog. -rsync -avzq rsync://yangcatalog.org:10873/yangdeps /a/www/ietf-ftp/yang/catalogmod/ - -# Populate the yang repositories -$DTDIR/ietf/manage.py populate_yang_model_dirs -v0 - -# Re-run yang checks on active documents -$DTDIR/ietf/manage.py run_yang_model_checks -v0 - -# Expire internet drafts -# Enable when removed from /a/www/ietf-datatracker/scripts/Cron-runner: -$DTDIR/ietf/bin/expire-ids - -# Send nomcom reminders about nomination acceptance and questionnaires -$DTDIR/ietf/manage.py send_reminders - -# Expire last calls -# Enable when removed from /a/www/ietf-datatracker/scripts/Cron-runner: -$DTDIR/ietf/bin/expire-last-calls - -# Run an extended version of the rfc editor update, to catch changes -# with backdated timestamps -# Enable when removed from /a/www/ietf-datatracker/scripts/Cron-runner: -$DTDIR/ietf/bin/rfc-editor-index-updates -d 1969-01-01 - -# Fetch meeting attendance data from ietf.org/registration/attendees -$DTDIR/ietf/manage.py fetch_meeting_attendance --latest 2 - -# Send reminders originating from the review app -$DTDIR/ietf/bin/send-review-reminders - -# Purge older PersonApiKeyEvents -$DTDIR/ietf/manage.py purge_old_personal_api_key_events 14 diff --git a/bin/drop-new-tables b/bin/drop-new-tables deleted file mode 100755 index ec1594ae261..00000000000 --- a/bin/drop-new-tables +++ /dev/null @@ -1,13 +0,0 @@ -#!/bin/bash - -# Drop tables which don't exist in the database dump. - -[ -n "$1" ] || { echo -e "\nUsage: $0 DUMPFILE\n\nError: No database dump file given"; exit 1; } - -zcat $1 | head | grep "Database: ietf_utf8" || { echo "Is this a database dump? Expected to see 'Database: ietf_utf8' "; exit 1; } - -echo -e "\nSQL commands:\n" - -diff <(zcat $1 | grep '^DROP TABLE IF EXISTS' | tr -d '`;' | field 5) <(ietf/manage.py dbshell <<< 'show tables;' | tail -n +2) | grep '^>' | awk '{print "drop table if exists", $2, ";";}' | tee /dev/stderr | ietf/manage.py dbshell - -echo -e "\nDone" diff --git a/bin/dump-to-names-json b/bin/dump-to-names-json deleted file mode 100644 index 9c7dfac07dd..00000000000 --- a/bin/dump-to-names-json +++ /dev/null @@ -1,16 +0,0 @@ -#!/bin/bash - -# This script provides a limited selected dump of database content with the -# purpose of generating a test fixture that provides the test data needed -# by the test suite. -# -# The generated data fixture is sorted and normalized in order to produce -# minimal commit diffs which reflect only actual changes in the fixture data, -# without apparent changes resulting only from ordering changes. - -set -x -ietf/manage.py dumpdata --indent 1 doc.State doc.BallotType doc.StateType \ - mailtrigger.MailTrigger mailtrigger.Recipient name utils.VersionInfo \ - group.GroupFeatures stats.CountryAlias dbtemplate.DBTemplate \ - | jq --sort-keys "sort_by(.model, .pk)" \ - | jq '[.[] | select(.model!="dbtemplate.dbtemplate" or .pk==354)]' > ietf/name/fixtures/names.json diff --git a/bin/every15m b/bin/every15m deleted file mode 100755 index c0b0752f6a2..00000000000 --- a/bin/every15m +++ /dev/null @@ -1,28 +0,0 @@ -#!/bin/bash - -# datatracker jobs to run every 15 minutes -# -# This script is expected to be triggered by cron from -# /etc/cron.d/datatracker - -export LANG=en_US.UTF-8 -export PYTHONIOENCODING=utf-8 - -DTDIR=/a/www/ietf-datatracker/web -cd $DTDIR/ - -# Set up the virtual environment -source $DTDIR/env/bin/activate - -logger -p user.info -t cron "Running $DTDIR/bin/every15m" - -# Send mail scheduled to go out at certain times -$DTDIR/ietf/bin/send-scheduled-mail all - -# Reparse the last _year_ of RFC index entries -# (which is the default if -d is not provided) -# until https://github.com/ietf-tools/datatracker/issues/3734 -# is addressed. -# This takes about 20s on production as of 2022-08-11 -$DTDIR/ietf/bin/rfc-editor-index-updates - diff --git a/bin/hourly b/bin/hourly deleted file mode 100755 index 77310302ce8..00000000000 --- a/bin/hourly +++ /dev/null @@ -1,101 +0,0 @@ -#!/bin/bash - -# Hourly datatracker jobs -# -# This script is expected to be triggered by cron from -# /etc/cron.d/datatracker -export LANG=en_US.UTF-8 -export PYTHONIOENCODING=utf-8 - -# Make sure we stop if something goes wrong: -program=${0##*/} -trap 'echo "$program($LINENO): Command failed with error code $? ([$$] $0 $*)"; exit 1' ERR - -DTDIR=/a/www/ietf-datatracker/web -cd $DTDIR/ - -# Set up the virtual environment -source $DTDIR/env/bin/activate - -logger -p user.info -t cron "Running $DTDIR/bin/hourly" - -# *** Enable when removed from /a/www/ietf-datatracker/scripts/Cron-runner: *** - -# # Update community lists. Remove once the community rewrite (will be around 6.20.0 ) -# $DTDIR/ietf/manage.py update_community_lists -# -# # Polling backup for iana and rfc-editory post APIs -$DTDIR/ietf/bin/iana-changes-updates -$DTDIR/ietf/bin/iana-protocols-updates -# $DTDIR/ietf/bin/rfc-editor-index-updates -# $DTDIR/ietf/bin/rfc-editor-queue-updates -# -# # Generate alias and virtual files for draft email aliases -# $DTDIR/ietf/bin/generate-draft-aliases && \ -# ( cd /a/postfix; /usr/sbin/postalias -o draft-aliases; ) && \ -# ( cd /a/postfix; /usr/sbin/postmap -o draft-virtual; ) -# -# # Generate alias and virtual files for group email aliases -# $DTDIR/ietf/bin/generate-wg-aliases && \ -# ( cd /a/postfix; /usr/sbin/postalias -o group-aliases; ) && \ -# ( cd /a/postfix; /usr/sbin/postmap -o group-virtual; ) -# -# Generate some static files -ID=/a/ietfdata/doc/draft/repository -DERIVED=/a/ietfdata/derived -DOWNLOAD=/a/www/www6s/download - -export TMPDIR=/a/tmp - -TMPFILE1=`mktemp` || exit 1 -TMPFILE2=`mktemp` || exit 1 -TMPFILE3=`mktemp` || exit 1 -TMPFILE4=`mktemp` || exit 1 -TMPFILE5=`mktemp` || exit 1 -TMPFILE6=`mktemp` || exit 1 -TMPFILE7=`mktemp` || exit 1 -TMPFILE8=`mktemp` || exit 1 -TMPFILE9=`mktemp` || exit 1 -TMPFILEA=`mktemp` || exit 1 -TMPFILEB=`mktemp` || exit 1 - -chmod a+r $TMPFILE1 $TMPFILE2 $TMPFILE3 $TMPFILE4 $TMPFILE5 $TMPFILE6 $TMPFILE7 $TMPFILE8 $TMPFILE9 $TMPFILEA $TMPFILEB - -python -m ietf.idindex.generate_all_id_txt >> $TMPFILE1 -python -m ietf.idindex.generate_id_index_txt >> $TMPFILE2 -python -m ietf.idindex.generate_id_abstracts_txt >> $TMPFILE3 -cp $TMPFILE1 $TMPFILE4 -cp $TMPFILE2 $TMPFILE5 -cp $TMPFILE3 $TMPFILE6 -cp $TMPFILE1 $TMPFILE8 -cp $TMPFILE2 $TMPFILE9 -cp $TMPFILE3 $TMPFILEA -python -m ietf.idindex.generate_all_id2_txt >> $TMPFILE7 -cp $TMPFILE7 $TMPFILEB - -mv $TMPFILE1 $ID/all_id.txt -mv $TMPFILE2 $ID/1id-index.txt -mv $TMPFILE3 $ID/1id-abstracts.txt -mv $TMPFILE4 $DOWNLOAD/id-all.txt -mv $TMPFILE5 $DOWNLOAD/id-index.txt -mv $TMPFILE6 $DOWNLOAD/id-abstract.txt -mv $TMPFILE7 $ID/all_id2.txt -mv $TMPFILE8 $DERIVED/all_id.txt -mv $TMPFILE9 $DERIVED/1id-index.txt -mv $TMPFILEA $DERIVED/1id-abstracts.txt -mv $TMPFILEB $DERIVED/all_id2.txt - -$DTDIR/ietf/manage.py generate_idnits2_rfc_status -$DTDIR/ietf/manage.py generate_idnits2_rfcs_obsoleted - -CHARTER=/a/www/ietf-ftp/charter -wget -q https://datatracker.ietf.org/wg/1wg-charters-by-acronym.txt -O $CHARTER/1wg-charters-by-acronym.txt -wget -q https://datatracker.ietf.org/wg/1wg-charters.txt -O $CHARTER/1wg-charters.txt - -# Regenerate the last week of bibxml-ids -$DTDIR/ietf/manage.py generate_draft_bibxml_files - -# Create and update group wikis -#$DTDIR/ietf/manage.py create_group_wikis - -# exit 0 diff --git a/bin/mkdiagram b/bin/mkdiagram deleted file mode 100755 index 4f015c0abea..00000000000 --- a/bin/mkdiagram +++ /dev/null @@ -1,50 +0,0 @@ -#!/bin/bash - -# assume we're in bin/, sibling to ietf/ - -cd ${0%/*}/../ietf || { echo "CD to ietf directory failed, bailing out"; exit; } - -trap 'echo "$program($LINENO): Command failed with error code $? ($0 $*)"; exit 1' ERR - -if [ "$*" ]; then apps="$@"; graph="${1%.*}"; else apps=$(ls */models.py | sed 's!/models.py!!'); graph="models"; fi - -newapps="doc group meeting message person name" -legacyapps="announcements idindex idrfc idtracker iesg ietfauth ipr liaisons mailinglists proceedings redirects submit wgcharter wginfo" - -proxy="$(grep ^class */proxy.py | tr '()' ' ' | awk '{printf $2 ","}')" -names="$(grep ^class name/models.py | tr '()' ' ' | awk '{printf $2 ","}')" -legacy="$(for app in $legacyapps; do grep ^class $app/models.py | tr '()' ' '; done | grep -v ' Meeting\\(' | awk '{printf $2 ","}')" -events="$(egrep '^class .+DocEvent' doc/models.py | tr '()' ' ' | awk '{printf $2 ","}')" - -echo -e "proxy: $proxy\n" -echo -e "names: $names\n" -echo -e "legacy:$legacy\n" -echo -e "events:$events\n" - -exclude="--exclude=$proxy,$names,$legacy" - -export PYTHONPATH="$PWD/.." - -echo "Validating..." -./manage.py validate - -export PYTHONPATH=`dirname $PWD` -module=${PWD##*/} -export DJANGO_SETTINGS_MODULE=$module.settings -export graph -export title - -echo "Generate model graph" -graph="models-with-names-and-events" -title="New IETF Database schema" -${0%/*}/../ietf/manage.py graph_models --exclude="$proxy,$legacy" --title "$title" $apps > $graph.dot && dot -Tpng $graph.dot > $graph.png - -echo "Generate new model without names" -graph="models-with-names" -title="New IETF Database schema, without name tables" -modelviz.py --exclude="$proxy,$legacy,$names" --title "$title" $apps > $graph.dot && dot -Tpng $graph.dot > $graph.png - -echo "Generate new model without names and subevents" -graph="models" -title="New IETF Database schema, without name tables and subevents" -modelviz.py --exclude="$proxy,$legacy,$names,$events" --title "$title" $apps > $graph.dot && dot -Tpng $graph.dot > $graph.png diff --git a/bin/mm_hourly b/bin/mm_hourly deleted file mode 100755 index 0d1da2e572c..00000000000 --- a/bin/mm_hourly +++ /dev/null @@ -1,24 +0,0 @@ -#!/bin/bash - -# Hourly datatracker jobs, ***run as mailman*** -# -# This script is expected to be triggered by cron from -# $DTDIR/etc/cron.d/datatracker which should be symlinked from -# /etc/cron.d/ - -export LANG=en_US.UTF-8 -export PYTHONIOENCODING=utf-8 - -# Make sure we stop if something goes wrong: -program=${0##*/} -trap 'echo "$program($LINENO): Command failed with error code $? ([$$] $0 $*)"; exit 1' ERR - -DTDIR=/a/www/ietf-datatracker/web -cd $DTDIR/ - -# Set up the virtual environment -source $DTDIR/env/bin/activate - -logger -p user.info -t cron "Running $DTDIR/bin/mm_hourly" - -$DTDIR/ietf/manage.py import_mailman_listinfo diff --git a/bin/monthly b/bin/monthly deleted file mode 100755 index 1d36abc2102..00000000000 --- a/bin/monthly +++ /dev/null @@ -1,17 +0,0 @@ -#!/bin/bash - -# Weekly datatracker jobs. -# -# This script is expected to be triggered by cron from -# /etc/cron.d/datatracker -export LANG=en_US.UTF-8 -export PYTHONIOENCODING=utf-8 - -DTDIR=/a/www/ietf-datatracker/web -cd $DTDIR/ - -# Set up the virtual environment -source $DTDIR/env/bin/activate - -logger -p user.info -t cron "Running $DTDIR/bin/monthly" - diff --git a/bin/release-coverage b/bin/release-coverage deleted file mode 100755 index 22177c17a6c..00000000000 --- a/bin/release-coverage +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/bash -zcat release-coverage.json.gz | jq 'to_entries[] | [.value.time, .key, .value.code.coverage, .value.template.coverage, .value.url.coverage] ' 2>/dev/null | tr "\n][" " \n" | tr -d ' "Z' | tr ",T" " " | sort -n | cut -c 2- | sed -n '/2015-03-10/,$p' diff --git a/bin/setupenv b/bin/setupenv deleted file mode 100755 index b9f0f72da09..00000000000 --- a/bin/setupenv +++ /dev/null @@ -1,45 +0,0 @@ -#!/usr/bin/env python - - -import os -import subprocess -import requests -import sys -import stat -import shutil - -basedir = os.path.dirname(os.path.dirname(__file__)) - -sys.path.append(basedir) - -shutil.copyfile(os.path.join(basedir, 'docker/settings_local.py'), os.path.join(basedir, 'settings_local.py')) - -from ietf.settings_sqlitetest import * # we don't import from django.conf here, on purpose - -for dir in [ AGENDA_PATH, IDSUBMIT_REPOSITORY_PATH, IDSUBMIT_STAGING_PATH, - INTERNET_DRAFT_ARCHIVE_DIR, os.path.dirname(DRAFT_ALIASES_PATH), PHOTOS_DIR, - os.path.dirname(os.path.abspath(TEST_GHOSTDRIVER_LOG_PATH)), ]: - if not os.path.exists(dir): - print("Creating %s" % dir) - os.makedirs(dir) - -for path in [ DRAFT_ALIASES_PATH, DRAFT_VIRTUAL_PATH, GROUP_ALIASES_PATH, GROUP_VIRTUAL_PATH, ]: - if not os.path.exists(path): - print("Setting up %s" % path) - dir, fn = os.path.split(path) - url = "https://zinfandel.tools.ietf.org/src/db/tmp/%s" % fn - r = requests.get(url) - if r.status_code == 200: - with open(path, "w") as of: - of.write(r.text) - else: - print("Error %s fetching '%s'" % (r.status_code, url)) - -path = IDSUBMIT_IDNITS_BINARY -if not os.path.exists(path): - print("Setting up %s" % path) - r = requests.get('https://tools.ietf.org/tools/idnits/idnits') - with open(path, 'w') as idnits: - idnits.write(r.text) - os.chmod(path, 0755) - \ No newline at end of file diff --git a/bin/update b/bin/update deleted file mode 100755 index bcb6e8b1297..00000000000 --- a/bin/update +++ /dev/null @@ -1,229 +0,0 @@ -#!/bin/bash - -version="0.34" -program=$(basename $0) - -NEW="" # If there are more than $NEW % new lines, skip update -OLD="" # If there are more than $OLD % deleted lines, skip update -FILE="" -verbose="" -silent="" - -# ---------------------------------------------------------------------- -function usage() { -cat < -EOF -exit -} - - -# ---------------------------------------------------------------------- -function note() { - if [ -n "$verbose" ]; then - echo -e "$program: $*" - fi -} - -# ---------------------------------------------------------------------- -function warn() { - [ "$QUIET" ] || echo -e "$program: $*" -} - -# ---------------------------------------------------------------------- -function err() { - echo -e "$program: $*" > /dev/stderr -} - -# ----------------------------------------------------------------------------- -function leave() { - errcode=$1; shift - if [ "$errcode" -ge "2" ]; then warn "$*"; else note "$*"; fi - if [ -f "$tempfile" ]; then rm $tempfile; fi - if [ -f "$difffile" ]; then rm $difffile; fi - if [ "$errcode" = "1" -a "$RESULT" = "0" ]; then exit 0; else exit $errcode; fi -} - -# ---------------------------------------------------------------------- -# Set up error trap -trap 'leave 127 "$program($LINENO): Command failed with error code $? while processing '$origfile'."' ERR - -# exit with a message if a command fails -set -e - -# ---------------------------------------------------------------------- -# Get any options -# - -# Default values -PAT="\$path\$base.%Y-%m-%d_%H%M" -RESULT="0" -QUIET="" - -# Based on the sample code in /usr/share/doc/util-linux/examples/parse.bash.gz -if [ "$(uname)" = "Linux" ]; then - GETOPT_RESULT=$(getopt -o bc:ef:hn:o:p:qrvV --long backup,maxchg:,empty,file:,help,maxnew:,maxold:,prefix:,report,quiet,verbose,version -n "$program" -- "$@") -else - GETOPT_RESULT=$(getopt bc:ef:hn:o:p:qrvV "$@") -fi - -if [ $? != 0 ] ; then echo "Terminating..." >&2 ; exit 1 ; fi - -note "GETOPT_RESULT: $GETOPT_RESULT" -eval set -- "$GETOPT_RESULT" - -while true ; do - case "$1" in - -b|--backup) backup=1; shift ;; # Back up earlier versions by creating a backup file - -c|--maxchg) CHG="$2"; shift 2 ;; # Limit on percentage of changed lines - -e|--empty) empty=1; shift ;; # Permit the update to be empty (default: discard) - -f|--file) FILE="$2"; shift 2 ;; # Read input from FILE instead of standard input - -h|--help) usage; shift ;; # Show this text and exit - -n|--maxnew) NEW="$2"; shift 2 ;; # Limit on percentage of new (added) lines - -o|--maxold) OLD="$2"; shift 2 ;; # Limit on percentage of old (deleted) lines - -p|--pat*) PAT="$2"; shift 2 ;; # Backup name base ('$path$base.%Y%m%d_%H%M') - -q|--quiet) QUIET=1; shift;; # Be less verbose - -r|--result) RESULT=1; shift ;; # Return 1 if update not done - -v|--verbose) verbose=1; shift ;; # Be more verbose about what's happening - -V|--version) echo -e "$program\t$version"; exit;; # Show version and exit - --) shift ; break ;; - *) echo "$program: Internal error, inconsistent option specification." ; exit 1 ;; - esac -done - -if [ $CHG ]; then OLD=$CHG; NEW=$CHG; fi - -if [ $# -lt 1 ]; then echo -e "$program: Missing output filename\n"; usage; fi - -origfile=$1 -tempfile=$(mktemp) -difffile=$(mktemp) - -if [ -e "$origfile" ]; then - cp -p $origfile $tempfile # For ownership and permissions - cat $FILE > $tempfile - [ "$FILE" ] && touch -r $FILE $tempfile - # This won't work if we don't have sufficient privileges: - #chown --reference=$origfile $tempfile - #chmod --reference=$origfile $tempfile -else - cat $FILE > $origfile - [ "$FILE" ] && touch -r $FILE $tempfile - leave 0 "Created file '$origfile'" -fi - -origlen=$(wc -c < $origfile) -newlen=$(wc -c < $tempfile) - -if [ $origlen = 0 -a $newlen = 0 ]; then - rm $tempfile - leave 1 "New content is identical (and void) - not updating '$origfile'." -fi -if [ $newlen = 0 -a -z "$empty" ]; then - leave 1 "New content is void - not updating '$origfile'." -fi - -diff $origfile $tempfile > $difffile || [ $? -le 1 ] && true # suppress the '1' error code on differences -difflen=$(wc -l < $difffile) -if [ $difflen = 0 ]; then - leave 1 "New content is identical - not updating '$origfile'." -fi - -if [ "$OLD" -o "$NEW" ]; then - - if [ "$NEW" ]; then maxnew=$(( $origlen * $NEW / 100 )); fi - if [ "$OLD" ]; then maxdel=$(( $origlen * $OLD / 100 )); fi - - newcount=$(grep "^> " $difffile | wc -c) - outcount=$(grep "^< " $difffile | wc -c) - delcount=$(grep "^! " $difffile | wc -c) - delcount=$(( $outcount + $delcount )) - rm $difffile - - if [ "$OLD" ]; then - if [ "$delcount" -ge "$maxdel" ]; then - cp $tempfile $origfile.update - leave 2 "New content has too many removed lines ($delcount/$origlen)\n - not updating '$origfile'.\nNew content placed in '$origfile.update' instead" - fi - fi - if [ "$NEW" ]; then - if [ "$newcount" -ge "$maxnew" ]; then - cp $tempfile $origfile.update - leave 2 "New content has too many added lines ($newcount/$origlen)\n - not updating '$origfile'.\nNew content placed in '$origfile.update' instead" - fi - fi -fi - -if [ "$backup" ]; then - - path=${origfile%/*} - name=${origfile##*/} - base=${name%.*} - ext=${origfile##*.} - - if [ "$ext" = "$origfile" ]; then - ext="" - elif [ ! "${ext%/*}" = "$ext" ]; then - ext="" - else - ext=".$ext" - fi - - if [ "$path" = "$origfile" ]; then - path="" - else - path="$path/" - fi - - ver=1 - backfile=$(eval date +"$PAT") - backpath="${backfile%/*}" - if [ "$backpath" = "$backfile" ]; then - backpath="." - fi - if [ ! -d $backpath ]; then - if [ -e $backpath ]; then - leave 3 "The backup path '$backpath' exists but isn't a directory" - else - mkdir -p $backpath - fi - fi - while [ -e "$backfile,$ver$ext" ]; do - ver=$(( $ver+1 )) - done - note "Saving backup: $backfile,$ver$ext" - cp -p "$origfile" "$backfile,$ver$ext" - chmod -w "$backfile,$ver$ext" || true -fi - -if ! mv $tempfile $origfile; then cp -p $tempfile $origfile; fi -leave 0 "Updated file '$origfile'" diff --git a/bin/vnu.jar b/bin/vnu.jar index 776d5836bac..1766224071c 100644 Binary files a/bin/vnu.jar and b/bin/vnu.jar differ diff --git a/bin/weekly b/bin/weekly deleted file mode 100755 index cca8403fd4a..00000000000 --- a/bin/weekly +++ /dev/null @@ -1,25 +0,0 @@ -#!/bin/bash - -# Weekly datatracker jobs. -# -# This script is expected to be triggered by cron from -# /etc/cron.d/datatracker -export LANG=en_US.UTF-8 -export PYTHONIOENCODING=utf-8 - -DTDIR=/a/www/ietf-datatracker/web -cd $DTDIR/ - -# Set up the virtual environment -source $DTDIR/env/bin/activate - -logger -p user.info -t cron "Running $DTDIR/bin/weekly" - - -# Send out weekly summaries of apikey usage - -$DTDIR/ietf/manage.py send_apikey_usage_emails - -# Send notifications about coming expirations -$DTDIR/ietf/bin/notify-expirations - diff --git a/client/App.vue b/client/App.vue new file mode 100644 index 00000000000..7750674296d --- /dev/null +++ b/client/App.vue @@ -0,0 +1,102 @@ + + + + + diff --git a/client/Embedded.vue b/client/Embedded.vue new file mode 100644 index 00000000000..80b105dc152 --- /dev/null +++ b/client/Embedded.vue @@ -0,0 +1,44 @@ + + + diff --git a/client/agenda/Agenda.vue b/client/agenda/Agenda.vue index d02eb6d32a8..99a46f4fe98 100644 --- a/client/agenda/Agenda.vue +++ b/client/agenda/Agenda.vue @@ -7,20 +7,34 @@ span #[strong IETF {{agendaStore.meeting.number}}] Meeting Agenda {{titleExtra}} .meeting-h1-badges.d-none.d-sm-flex span.meeting-warning(v-if='agendaStore.meeting.warningNote') {{agendaStore.meeting.warningNote}} - span.meeting-beta BETA h4 span {{agendaStore.meeting.city}}, {{ meetingDate }} - h6.float-end.d-none.d-lg-inline(v-if='meetingUpdated') #[span.text-muted Updated:] {{ meetingUpdated }} + h6.float-end.d-none.d-lg-inline(v-if='meetingUpdated') #[span.text-body-secondary Updated:] {{ meetingUpdated }} .agenda-topnav.my-3 meeting-navigation - n-button.d-none.d-sm-flex( - quaternary - @click='toggleSettings' - ) - template(#icon) - i.bi.bi-gear - span Settings + .agenda-topnav-right.d-none.d-md-flex + n-button( + quaternary + @click='startTour' + ) + template(#icon) + i.bi.bi-question-square + span Help + n-button( + quaternary + @click='toggleShare' + ) + template(#icon) + i.bi.bi-share + span Share + n-button( + quaternary + @click='toggleSettings' + ) + template(#icon) + i.bi.bi-gear + span Settings .row .col @@ -35,7 +49,7 @@ n-popover(v-if='!agendaStore.infoNoteShown') template(#trigger) n-button.ms-2(text, @click='toggleInfoNote') - i.bi.bi-info-circle.text-muted + i.bi.bi-info-circle.text-body-secondary span Show Info Note .col-12.col-sm-auto.d-flex.align-items-center i.bi.bi-globe.me-2 @@ -44,17 +58,20 @@ n-button( :type='agendaStore.isTimezoneMeeting ? `primary` : `default`' @click='setTimezone(`meeting`)' + :text-color='agendaStore.isTimezoneMeeting ? `#FFF` : null' ) Meeting n-button( :type='agendaStore.isTimezoneLocal ? `primary` : `default`' @click='setTimezone(`local`)' + :text-color='agendaStore.isTimezoneLocal ? `#FFF` : null' ) Local n-button( :type='agendaStore.timezone === `UTC` ? `primary` : `default`' @click='setTimezone(`UTC`)' + :text-color='agendaStore.timezone === `UTC` ? `#FFF` : null' ) UTC n-select.agenda-timezone-ddn( - v-if='agendaStore.viewport > 1250' + v-if='siteStore.viewport > 1250' v-model:value='agendaStore.timezone' :options='timezones' placeholder='Select Time Zone' @@ -62,7 +79,7 @@ @update:value='() => { agendaStore.persistMeetingPreferences() }' ) - .alert.alert-warning.mt-3(v-if='agendaStore.isCurrentMeeting') #[strong Note:] IETF agendas are subject to change, up to and during a meeting. + .agenda-currentwarn.alert.alert-warning.mt-3(v-if='agendaStore.isCurrentMeeting') #[strong Note:] IETF agendas are subject to change, up to and during a meeting. .agenda-infonote.mt-3(v-if='agendaStore.meeting.infoNote && agendaStore.infoNoteShown') n-popover template(#trigger) @@ -134,10 +151,11 @@ // ----------------------------------- // -> Anchored Day Quick Access Menu // ----------------------------------- - .col-auto.d-print-none(v-if='agendaStore.viewport >= 990') + .col-auto.d-print-none(v-if='siteStore.viewport >= 990') agenda-quick-access agenda-mobile-bar + agenda-share-modal(v-model:shown='state.shareModalShown') diff --git a/client/agenda/AgendaFilter.vue b/client/agenda/AgendaFilter.vue index 5209b174ac1..b1f10657086 100644 --- a/client/agenda/AgendaFilter.vue +++ b/client/agenda/AgendaFilter.vue @@ -60,11 +60,11 @@ n-drawer(v-model:show='state.isShown', placement='bottom', :height='state.drawer ) template(#trigger) span.badge BoF - span #[a(href='https://www.ietf.org/how/bofs/', target='_blank') Birds of a Feather] sessions (BoFs) are initial discussions about a particular topic of interest to the IETF community. + span #[a(:href='getUrl(`bofDefinition`)', target='_blank') Birds of a Feather] sessions (BoFs) are initial discussions about a particular topic of interest to the IETF community. diff --git a/client/agenda/AgendaScheduleCalendar.vue b/client/agenda/AgendaScheduleCalendar.vue index 7467fafb50a..98632963419 100644 --- a/client/agenda/AgendaScheduleCalendar.vue +++ b/client/agenda/AgendaScheduleCalendar.vue @@ -4,21 +4,24 @@ n-drawer(v-model:show='isShown', placement='bottom', :height='state.drawerHeight template(#header) span Calendar View .agenda-calendar-actions - template(v-if='agendaStore.viewport > 990') + template(v-if='siteStore.viewport > 990') i.bi.bi-globe.me-2 small.me-2: strong Timezone: n-button-group n-button( :type='agendaStore.isTimezoneMeeting ? `primary` : `default`' @click='setTimezone(`meeting`)' + :text-color='agendaStore.isTimezoneMeeting ? `#FFF` : null' ) Meeting n-button( :type='agendaStore.isTimezoneLocal ? `primary` : `default`' @click='setTimezone(`local`)' + :text-color='agendaStore.isTimezoneLocal ? `#FFF` : null' ) Local n-button( :type='agendaStore.timezone === `UTC` ? `primary` : `default`' @click='setTimezone(`UTC`)' + :text-color='agendaStore.timezone === `UTC` ? `#FFF` : null' ) UTC n-divider(vertical) n-button.me-2( @@ -32,7 +35,7 @@ n-drawer(v-model:show='isShown', placement='bottom', :height='state.drawerHeight n-badge.ms-2(:value='agendaStore.selectedCatSubs.length', processing) n-button( ghost - color='gray' + :color='siteStore.theme === `dark` ? `#e35d6a` : `gray`' strong @click='close' ) @@ -81,20 +84,21 @@ import { NPopover } from 'naive-ui' -import '@fullcalendar/core/vdom' // solves problem with Vite import FullCalendar from '@fullcalendar/vue3' import timeGridPlugin from '@fullcalendar/timegrid' import interactionPlugin from '@fullcalendar/interaction' -import luxonPlugin from '@fullcalendar/luxon2' +import luxonPlugin from '@fullcalendar/luxon3' import bootstrap5Plugin from '@fullcalendar/bootstrap5' import AgendaDetailsModal from './AgendaDetailsModal.vue' import { useAgendaStore } from './store' +import { useSiteStore } from '../shared/store' // STORES const agendaStore = useAgendaStore() +const siteStore = useSiteStore() // STATE @@ -183,6 +187,7 @@ function refreshData () { let earliestDate = DateTime.fromISO('2200-01-01') let latestDate = DateTime.fromISO('1990-01-01') let nowDate = DateTime.now() + let hasCrossDayEvents = false calendarOptions.events = agendaStore.scheduleAdjusted.map(ev => { // -> Determine boundaries @@ -198,6 +203,9 @@ function refreshData () { if (ev.adjustedEnd < latestDate) { latestDate = ev.adjustedEnd } + if (ev.adjustedStart.day !== ev.adjustedEnd.day) { + hasCrossDayEvents = true + } // -> Build event object return { id: ev.id, @@ -210,8 +218,8 @@ function refreshData () { }) // -> Display settings - calendarOptions.slotMinTime = `${earliestHour.toString().padStart(2, '0')}:00:00` - calendarOptions.slotMaxTime = `${latestHour.toString().padStart(2, '0')}:00:00` + calendarOptions.slotMinTime = hasCrossDayEvents ? '00:00:00' : `${earliestHour.toString().padStart(2, '0')}:00:00` + calendarOptions.slotMaxTime = hasCrossDayEvents ? '23:59:59' : `${latestHour.toString().padStart(2, '0')}:00:00` calendarOptions.validRange.start = earliestDate.minus({ days: 1 }).toISODate() calendarOptions.validRange.end = latestDate.plus({ days: 1 }).toISODate() // calendarOptions.scrollTime = `${earliestHour.toString().padStart(2, '0')}:00:00` @@ -322,7 +330,6 @@ function close () { } .badge { - width: 30px; font-size: .7em; border: 1px solid #CCC; text-transform: uppercase; diff --git a/client/agenda/AgendaScheduleList.vue b/client/agenda/AgendaScheduleList.vue index eeec271a56a..bbe5dfee8b7 100644 --- a/client/agenda/AgendaScheduleList.vue +++ b/client/agenda/AgendaScheduleList.vue @@ -7,7 +7,7 @@ th.agenda-table-head-check(v-if='pickerModeActive')   th.agenda-table-head-time Time th.agenda-table-head-location(colspan='2') Location - th.agenda-table-head-event(colspan='2') {{ agendaStore.viewport < 990 ? '' : 'Event' }} + th.agenda-table-head-event(colspan='2') {{ siteStore.viewport < 990 ? '' : 'Event' }} tbody tr.agenda-table-display-noresult( v-if='!meetingEvents || meetingEvents.length < 1' @@ -15,6 +15,7 @@ td(:colspan='pickerModeActive ? 6 : 5') i.bi.bi-exclamation-triangle.me-2 span(v-if='agendaStore.searchVisible && agendaStore.searchText') No event matching your search query. + span(v-else-if='agendaStore.meeting.prelimAgendaDate') A preliminary agenda is expected to be released on {{ agendaStore.meeting.prelimAgendaDate }} span(v-else) Nothing to display tr( v-for='item of meetingEvents' @@ -24,7 +25,7 @@ ) //- ROW - DAY HEADING ----------------------- template(v-if='item.displayType === `day`') - td(:id='`agenda-day-` + item.id', :colspan='pickerModeActive ? 6 : 5') {{item.date}} + td(:id='item.slug', :colspan='pickerModeActive ? 6 : 5') {{item.date}} //- ROW - SESSION HEADING ------------------- template(v-else-if='item.displayType === `session-head`') td.agenda-table-cell-check(v-if='pickerModeActive')   @@ -58,17 +59,17 @@ span.badge {{item.location.short}} span {{item.location.name}} router-link.discreet( - :to='`/meeting/` + agendaStore.meeting.number + `/floor-plan-neue?room=` + xslugify(item.room)' + :to='`/meeting/` + agendaStore.meeting.number + `/floor-plan?room=` + xslugify(item.room)' :aria-label='item.room' ) {{item.room}} span(v-else) {{item.room}} //- CELL - GROUP -------------------------- td.agenda-table-cell-group(v-if='item.type === `regular`') - span.badge(v-if='agendaStore.areaIndicatorsShown && agendaStore.viewport > 1200') {{item.groupAcronym}} + span.badge(v-if='agendaStore.areaIndicatorsShown && siteStore.viewport > 1200') {{item.groupAcronym}} a.discreet(:href='`/group/` + item.acronym + `/about/`') {{item.acronym}} //- CELL - NAME --------------------------- td.agenda-table-cell-name - i.bi.me-2(v-if='item.icon && agendaStore.eventIconsShown', :class='item.icon') + i.bi.me-2.agenda-event-icon(v-if='item.icon && agendaStore.eventIconsShown', :class='item.icon') a.discreet( v-if='item.flags.agenda' :href='item.agenda.url' @@ -83,6 +84,14 @@ template(#trigger) span.badge.is-bof BoF span #[a(href='https://www.ietf.org/how/bofs/', target='_blank') Birds of a Feather] sessions (BoFs) are initial discussions about a particular topic of interest to the IETF community. + n-popover( + v-if='item.isProposed' + trigger='hover' + :width='250' + ) + template(#trigger) + span.badge.is-proposed Proposed + span #[a(href='https://www.ietf.org/process/wgs/', target='_blank') Proposed WGs] are groups in the process of being chartered. If the charter is not approved by the IESG before the IETF meeting, the session may be canceled. .agenda-table-note(v-if='item.note') i.bi.bi-arrow-return-right.me-1 span {{item.note}} @@ -105,24 +114,19 @@ template(v-else) span.badge.is-cancelled(v-if='!isMobile && item.status === `canceled`') Cancelled span.badge.is-rescheduled(v-else-if='!isMobile && item.status === `resched`') Rescheduled - .agenda-table-cell-links-buttons(v-else-if='agendaStore.viewport < 1200 && item.links && item.links.length > 0') + .agenda-table-cell-links-buttons(v-else-if='siteStore.viewport < 1200 && item.links && item.links.length > 0') n-dropdown( v-if='!agendaStore.colorPickerVisible' trigger='click' :options='item.links' key-field='id' :render-icon='renderLinkIcon' - @select='goToSessionLink' + :render-label='renderLink' ) n-button(size='tiny') i.bi.bi-three-dots .agenda-table-cell-links-buttons(v-else-if='item.links && item.links.length > 0') - template(v-if='item.flags.agenda') - n-popover - template(#trigger) - i.bi.bi-collection(@click='showMaterials(item.key)') - span Show meeting materials - template(v-else-if='item.type === `regular`') + template(v-if='!item.flags.agenda && item.type === `regular`') n-popover template(#trigger) i.no-meeting-materials @@ -131,7 +135,17 @@ span No meeting materials yet. n-popover(v-for='lnk of item.links', :key='lnk.id') template(#trigger) + button( + v-if="lnk.click" + type="button" + :id='`btn-` + lnk.id' + @click='lnk.click' + :aria-label='lnk.label' + :class='`border-0 bg-transparent text-` + lnk.color' + ): i.bi(:class='`bi-` + lnk.icon') a( + v-else + :id='`btn-` + lnk.id' :href='lnk.href' :aria-label='lnk.label' :class='`text-` + lnk.color' @@ -196,7 +210,9 @@ import { import AgendaDetailsModal from './AgendaDetailsModal.vue' -import { useAgendaStore } from './store' +import { useAgendaStore, daySlugPrefix, daySlug } from './store' +import { useSiteStore } from '../shared/store' +import { getUrl } from '../shared/urls' // MESSAGE PROVIDER @@ -205,6 +221,7 @@ const message = useMessage() // STORES const agendaStore = useAgendaStore() +const siteStore = useSiteStore() // DATA @@ -232,60 +249,102 @@ const meetingEvents = computed(() => { return reduce(sortBy(agendaStore.scheduleAdjusted, 'adjustedStartDate'), (acc, item) => { const isLive = current >= item.adjustedStart && current < item.adjustedEnd - const itemTimeSlot = agendaStore.viewport > 576 ? + const itemTimeSlot = siteStore.viewport > 576 ? `${item.adjustedStart.toFormat('HH:mm')} - ${item.adjustedEnd.toFormat('HH:mm')}` : `${item.adjustedStart.toFormat('HH:mm')} ${item.adjustedEnd.toFormat('HH:mm')}` // -> Add date row const itemDate = DateTime.fromISO(item.adjustedStartDate) + let willRenderDateRow = false if (itemDate.toISODate() !== acc.lastDate) { acc.result.push({ id: item.id, + slug: daySlug(item), key: `day-${itemDate.toISODate()}`, displayType: 'day', date: itemDate.toLocaleString(DateTime.DATE_HUGE), cssClasses: 'agenda-table-display-day' }) + willRenderDateRow = true } acc.lastDate = itemDate.toISODate() // -> Add session header row - if (item.type === 'regular' && acc.lastTypeName !== `${item.type}-${item.name}`) { + const typeName = `${item.type}-${item.slotName}` + if (item.type === 'regular' && (acc.lastTypeName !== typeName || willRenderDateRow)) { acc.result.push({ key: `sesshd-${item.id}`, displayType: 'session-head', timeslot: itemTimeSlot, - name: `${item.adjustedStart.toFormat('cccc')} ${item.name}`, + name: `${item.adjustedStart.setZone(agendaStore.meeting.timezone).toFormat('cccc')} ${item.slotName}`, cssClasses: 'agenda-table-display-session-head' + (isLive ? ' agenda-table-live' : '') }) } - acc.lastTypeName = `${item.type}-${item.name}` - - // -> Populate event links + acc.lastTypeName = typeName + + // + /** + * -> Populate event menu items + * + * links is an array of either, + * 1. { href: "...", click: undefined, ...sharedProps } + * 2. { click: () => {...}, href: undefined, ...sharedProps } + */ const links = [] - if (item.flags.showAgenda || ['regular', 'plenary'].includes(item.type)) { + const typesWithLinks = ['regular', 'plenary', 'other'] + const purposesWithoutLinks = ['admin', 'closed_meeting', 'officehours', 'social'] + if (item.flags.showAgenda || (typesWithLinks.includes(item.type) && !purposesWithoutLinks.includes(item.purpose))) { if (item.flags.agenda) { + // -> Meeting Materials + links.push({ + id: `btn-${item.id}-mat`, + label: 'Show meeting materials', + icon: 'collection', + href: undefined, + click: () => showMaterials(item.id), + color: 'darkgray' + }) links.push({ id: `lnk-${item.id}-tar`, label: 'Download meeting materials as .tar archive', icon: 'file-zip', - href: `/meeting/${agendaStore.meeting.number}/agenda/${item.acronym}-drafts.tgz`, + href: getUrl('meetingMaterialsTar', { + meetingNumber: agendaStore.meeting.number, + eventAcronym: item.acronym + }), color: 'brown' }) links.push({ id: `lnk-${item.id}-pdf`, label: 'Download meeting materials as PDF file', icon: 'file-pdf', - href: `/meeting/${agendaStore.meeting.number}/agenda/${item.acronym}-drafts.pdf`, + href: getUrl('meetingMaterialsPdf', { + meetingNumber: agendaStore.meeting.number, + eventAcronym: item.acronym + }), color: 'red' }) } - if (agendaStore.useHedgeDoc) { + // -> Point to Wiki for Hackathon sessions, HedgeDocs otherwise + if (item.groupAcronym === 'hackathon') { + links.push({ + id: `lnk-${item.id}-wiki`, + label: 'Wiki', + icon: 'book', + href: getUrl('hackathonWiki', { + meetingNumber: agendaStore.meeting.number + }), + color: 'blue' + }) + } else if (agendaStore.usesNotes) { links.push({ id: `lnk-${item.id}-note`, label: 'Notepad for note-takers', icon: 'journal-text', - href: `https://notes.ietf.org/notes-ietf-${agendaStore.meeting.number}-${item.type === 'plenary' ? 'plenary' : item.acronym}`, + href: getUrl('meetingNotes', { + meetingNumber: agendaStore.meeting.number, + eventAcronym: item.type === 'plenary' ? 'plenary' : item.acronym + }), color: 'blue' }) } @@ -339,16 +398,6 @@ const meetingEvents = computed(() => { color: 'teal' }) } - // -> Calendar item - if (item.links.calendar) { - links.push({ - id: `lnk-${item.id}-calendar`, - label: isMobile.value ? `Calendar (.ics) entry for this session` : `Calendar (.ics) entry for ${item.acronym} session on ${item.adjustedStart.toFormat('fff')}`, - icon: 'calendar-check', - href: item.links.calendar, - color: 'pink' - }) - } } else { // -> Post event if (meetingNumberInt >= 60) { @@ -398,13 +447,43 @@ const meetingEvents = computed(() => { id: `lnk-${item.id}-rec`, label: 'Session recording', icon: 'film', - href: `https://www.meetecho.com/ietf${agendaStore.meeting.number}/recordings#${item.acronym.toUpperCase()}`, + href: getUrl('meetingMeetechoRecordings', { + meetingNumber: agendaStore.meeting.number, + eventAcronym: item.acronym.toUpperCase() + }), color: 'purple' }) } + // -> Keep showing video client / on-site tool for Plenary until end of day, in case it goes over the planned time range + if (item.type === 'plenary' && item.adjustedEnd.day === current.day) { + links.push({ + id: `lnk-${item.id}-video`, + label: 'Full Client with Video', + icon: 'camera-video', + href: item.links.videoStream, + color: 'purple' + }) + links.push({ + id: `lnk-${item.id}-onsitetool`, + label: 'Onsite tool', + icon: 'telephone-outbound', + href: item.links.onsiteTool, + color: 'teal' + }) + } } } } + // Add Calendar item for all events that has a calendar link + if (item.adjustedEnd > current && item.links.calendar) { + links.push({ + id: `lnk-${item.id}-calendar`, + label: 'Calendar (.ics) entry for this session', + icon: 'calendar-check', + href: item.links.calendar, + color: 'pink' + }) + } // Event icon let icon = null @@ -418,7 +497,7 @@ const meetingEvents = computed(() => { case 'other': if (item.name.toLowerCase().indexOf('office hours') >= 0) { icon = 'bi-building' - } else if (item.name.toLowerCase().indexOf('hackathon') >= 0) { + } else if (item.groupAcronym === 'hackathon') { icon = 'bi-command bi-pink' } break @@ -445,6 +524,7 @@ const meetingEvents = computed(() => { // groupParentName: item.groupParent?.name, icon, isBoF: item.isBoF, + isProposed: item.isProposed, isSessionEvent: item.type === 'regular', links, location: item.location, @@ -478,7 +558,7 @@ const pickedEvents = computed({ }) const isMobile = computed(() => { - return agendaStore.viewport < 576 + return siteStore.viewport < 576 }) // METHODS @@ -538,17 +618,53 @@ function renderLinkIcon (opt) { return h('i', { class: `bi bi-${opt.icon} text-${opt.color}` }) } +function renderLink (opt) { + if (opt.click) { + return h('button', { type: 'button', class: 'overflow-button', onClick: opt.click }, opt.label) + } + + return h('a', { href: opt.href, target: '_blank' }, opt.label) +} + function recalculateRedLine () { state.currentMinute = DateTime.local().minute - const lastEventId = agendaStore.findCurrentEventId() + const currentEventId = agendaStore.findCurrentEventId() - if (lastEventId) { - state.redhandOffset = document.getElementById(`agenda-rowid-${lastEventId}`)?.offsetTop || 0 + if (currentEventId) { + state.redhandOffset = document.getElementById(`agenda-rowid-${currentEventId}`)?.offsetTop || 0 } else { state.redhandOffset = 0 } } +/** + * On page load when browser location hash contains '#now' or '#agenda-day-*' then scroll accordingly + */ +;(function scrollToHashInit() { + if (!window.location.hash) { + return + } + if (!(window.location.hash === "#now" || window.location.hash.startsWith(`#${daySlugPrefix}`))) { + return + } + const unsubscribe = agendaStore.$subscribe((_mutation, agendaStoreState) => { + if (agendaStoreState.schedule.length === 0) { + return + } + unsubscribe() // we only need to scroll once, so unsubscribe from future updates + if (window.location.hash === "#now") { + const nowEventId = agendaStore.findNowEvent() + if (nowEventId) { + document.getElementById(`agenda-rowid-${nowEventId}`)?.scrollIntoView(true) + } else { + message.warning('There is no event happening right now or in the future.') + } + } else if(window.location.hash.startsWith(`#${daySlugPrefix}`)) { + document.getElementById(window.location.hash.substring(1))?.scrollIntoView(true) + } + }) +})() + // MOUNTED onMounted(() => { @@ -658,6 +774,10 @@ onBeforeUnmount(() => { border-radius: 5px; border-collapse: separate; border-spacing: 0; + + @at-root .theme-dark & { + border-color: #000; + } } // -> Table HEADER @@ -677,6 +797,11 @@ onBeforeUnmount(() => { font-weight: 600; border-right: 1px solid #FFF; + @at-root .theme-dark & { + border-bottom-color: #000; + border-right-color: #000; + } + @media screen and (max-width: $bs5-break-md) { font-size: .8em; padding: 0 6px; @@ -731,6 +856,10 @@ onBeforeUnmount(() => { tr:nth-child(odd) td { background-color: #F9F9F9; + + @at-root .theme-dark & { + background-color: darken($gray-900, 5%); + } } &-display-noresult > td { @@ -740,6 +869,12 @@ onBeforeUnmount(() => { color: $gray-800; text-shadow: 1px 1px 0 #FFF; font-weight: 600; + + @at-root .theme-dark & { + background: linear-gradient(to bottom, $gray-900, $gray-800); + color: #FFF; + text-shadow: 1px 1px 0 $gray-900; + } } &-display-day > td { @@ -751,6 +886,10 @@ onBeforeUnmount(() => { font-weight: 600; scroll-margin-top: 25px; + @at-root .theme-dark & { + border-bottom-color: #000; + } + @media screen and (max-width: $bs5-break-md) { font-size: .9em; } @@ -763,6 +902,11 @@ onBeforeUnmount(() => { padding: 0 12px; color: #333; + @at-root .theme-dark & { + background: linear-gradient(to top, lighten($blue-900, 8%), lighten($blue-900, 4%)) !important; + color: $blue-100; + } + @media screen and (max-width: $bs5-break-md) { padding: 0 6px; } @@ -770,12 +914,21 @@ onBeforeUnmount(() => { &.agenda-table-cell-ts { border-right: 1px solid $blue-200 !important; color: $blue-700; + + @at-root .theme-dark & { + border-right-color: $blue-700 !important; + color: $blue-200; + } } &.agenda-table-cell-name { color: $blue-700; font-weight: 600; + @at-root .theme-dark & { + color: $blue-200; + } + @media screen and (max-width: $bs5-break-md) { font-size: .9em; } @@ -787,6 +940,10 @@ onBeforeUnmount(() => { padding: 0 12px; color: #333; + @at-root .theme-dark & { + color: #FFF; + } + @media screen and (max-width: $bs5-break-md) { padding: 2px 6px; } @@ -795,6 +952,11 @@ onBeforeUnmount(() => { background-color: desaturate($blue-700, 50%) !important; border-bottom: 1px solid #FFF; padding-bottom: 2px; + + @at-root .theme-dark & { + background-color: $gray-800 !important; + border-bottom-color: #000; + } } &.agenda-table-cell-ts { @@ -803,6 +965,13 @@ onBeforeUnmount(() => { border-right: 1px solid $blue-200 !important; color: $blue-200; border-bottom: 1px solid #FFF; + + @at-root .theme-dark & { + background: linear-gradient(to right, rgba(lighten($blue-900, 8%), .1), lighten($blue-900, 5%)); + border-right-color: $blue-700 !important; + border-bottom-color: $blue-700; + color: $blue-700; + } } } @@ -811,6 +980,11 @@ onBeforeUnmount(() => { border-right: 1px solid $gray-300 !important; white-space: nowrap; + @at-root .theme-dark & { + color: $yellow-100; + border-right-color: $gray-700 !important; + } + @media screen and (max-width: 1300px) { font-size: .85rem; } @@ -854,6 +1028,11 @@ onBeforeUnmount(() => { border-right: 1px solid $gray-300 !important; white-space: nowrap; + @at-root .theme-dark & { + color: $gray-400; + border-right-color: $gray-700 !important; + } + @media screen and (max-width: $bs5-break-md) { font-size: .7rem; word-break: break-all; @@ -880,6 +1059,14 @@ onBeforeUnmount(() => { border-top-left-radius: 0; border-bottom-left-radius: 0; margin-right: 6px; + + @at-root .theme-dark & { + background-color: $gray-700; + border-bottom-color: $gray-600; + border-right-color: $gray-600; + color: $gray-200; + text-shadow: 1px 1px $gray-800; + } } } @@ -890,13 +1077,26 @@ onBeforeUnmount(() => { word-wrap: break-word; } - .badge.is-bof { - background-color: $teal-500; + .badge { margin: 0 8px; + &.is-bof { + background-color: $teal-500; + + @at-root .theme-dark & { + background-color: $teal-700; + } + } + + &.is-proposed { + background-color: $gray-500; + + @at-root .theme-dark & { + background-color: $gray-700; + } + } + @media screen and (max-width: $bs5-break-md) { - width: 30px; - display: block; margin: 2px 0 0 0; } } @@ -911,6 +1111,10 @@ onBeforeUnmount(() => { } &.bi-green { color: $green-500; + + @at-root .theme-dark & { + color: $green-300; + } } &.bi-pink { color: $pink-500; @@ -951,7 +1155,7 @@ onBeforeUnmount(() => { .agenda-table-cell-links-buttons { white-space: nowrap; - > a, > i { + > a, > i, > button { margin-left: 3px; color: #666; cursor: pointer; @@ -960,6 +1164,11 @@ onBeforeUnmount(() => { padding: 2px 3px; transition: background-color .6s ease; + @at-root .theme-dark & { + background-color: rgba(0, 0, 0, .2); + color: $gray-200; + } + &:hover, &:focus { color: $blue; } @@ -968,6 +1177,10 @@ onBeforeUnmount(() => { color: $red-500; background-color: rgba($red-500, .1); + @at-root .theme-dark & { + color: $red-400; + } + &:hover, &:focus { background-color: rgba($red-500, .3); } @@ -976,14 +1189,34 @@ onBeforeUnmount(() => { color: $orange-700; background-color: rgba($orange-500, .1); + @at-root .theme-dark & { + color: $orange-400; + } + &:hover, &:focus { background-color: rgba($orange-500, .3); } } + &.text-darkgray { + color: $gray-900; + background-color: rgba($gray-700, .1); + + @at-root .theme-dark & { + color: $gray-100; + } + + &:hover, &:focus { + background-color: rgba($gray-700, .3); + } + } &.text-blue { color: $blue-600; background-color: rgba($blue-300, .1); + @at-root .theme-dark & { + color: $blue-300; + } + &:hover, &:focus { background-color: rgba($blue-300, .3); } @@ -992,6 +1225,10 @@ onBeforeUnmount(() => { color: $green-500; background-color: rgba($green-300, .1); + @at-root .theme-dark & { + color: $green-300; + } + &:hover, &:focus { background-color: rgba($green-300, .3); } @@ -1000,6 +1237,10 @@ onBeforeUnmount(() => { color: $purple-500; background-color: rgba($purple-400, .1); + @at-root .theme-dark & { + color: $purple-300; + } + &:hover, &:focus { background-color: rgba($purple-400, .3); } @@ -1008,6 +1249,10 @@ onBeforeUnmount(() => { color: $pink-500; background-color: rgba($pink-400, .1); + @at-root .theme-dark & { + color: $pink-400; + } + &:hover, &:focus { background-color: rgba($pink-400, .3); } @@ -1016,6 +1261,10 @@ onBeforeUnmount(() => { color: $teal-600; background-color: rgba($teal-400, .1); + @at-root .theme-dark & { + color: $teal-300; + } + &:hover, &:focus { background-color: rgba($teal-400, .3); } @@ -1035,13 +1284,17 @@ onBeforeUnmount(() => { &-cell-ts { border-right: 1px solid $gray-300 !important; - // -> Use system font instead of Montserrat so that all digits align vertically + // -> Use system font instead of Inter so that all digits align vertically font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif; font-size: 1rem; font-weight: 700; text-align: right; white-space: nowrap; + @at-root .theme-dark & { + border-right-color: $gray-700 !important; + } + @media screen and (max-width: 1300px) { font-size: .9rem; } @@ -1067,8 +1320,22 @@ onBeforeUnmount(() => { border-bottom: none; } + &.agenda-table-cell-ts.is-session-event { + @at-root .theme-dark & { + background: transparent; + color: $red-300; + border-top: 1px solid darken($red-100, 5%); + border-bottom-color: darken($red-100, 5%); + } + } + &.agenda-table-cell-room { border-right: 1px solid darken($red-100, 5%) !important; + text-decoration: line-through; + } + + &.agenda-table-cell-name > a, &.agenda-table-cell-name > span { + text-decoration: line-through; } &:last-child { @@ -1085,8 +1352,22 @@ onBeforeUnmount(() => { border-bottom: none; } + &.agenda-table-cell-ts.is-session-event { + @at-root .theme-dark & { + background: transparent; + color: $orange-300; + border-top: 1px solid darken($orange-100, 5%); + border-bottom-color: darken($orange-100, 5%); + } + } + &.agenda-table-cell-room { border-right: 1px solid darken($orange-100, 5%) !important; + text-decoration: line-through; + } + + &.agenda-table-cell-name > a, &.agenda-table-cell-name > span { + text-decoration: line-through; } &:last-child { @@ -1098,10 +1379,21 @@ onBeforeUnmount(() => { border-top: 1px solid darken($indigo-100, 5%); border-bottom: 1px solid darken($indigo-100, 5%); + @at-root .theme-dark & { + color: $indigo-100; + // border-bottom-color: #000; + } + &.agenda-table-cell-ts { background: linear-gradient(to right, lighten($indigo-100, 8%), lighten($indigo-100, 5%)); color: $indigo-700; border-right: 1px solid $indigo-100 !important; + + @at-root .theme-dark & { + background: rgba($indigo, .1) !important; + color: $indigo-100; + border-right-color: $indigo-500 !important; + } } &.agenda-table-cell-room { @@ -1111,10 +1403,18 @@ onBeforeUnmount(() => { &.agenda-table-cell-name { color: $indigo-700; font-style: italic; + + @at-root .theme-dark & { + color: $indigo-200; + } } &.agenda-table-cell-links { background: linear-gradient(to right, lighten($indigo-100, 5%), lighten($indigo-100, 8%)); + + @at-root .theme-dark & { + background: rgba($indigo, .1) !important; + } } } &-type-plenary td { @@ -1123,9 +1423,19 @@ onBeforeUnmount(() => { border-top: 1px solid darken($teal-100, 5%); border-bottom: 1px solid darken($teal-100, 5%); + @at-root .theme-dark & { + background: rgba($teal, .15) !important; + color: $teal-100; + border-bottom: 1px solid darken($teal-600, 5%); + } + &.agenda-table-cell-ts { background: linear-gradient(to right, lighten($teal-100, 8%), lighten($teal-100, 2%)); border-right: 1px solid $teal-200 !important; + + @at-root .theme-dark & { + border-right-color: $teal-700 !important; + } } &.agenda-table-cell-room { @@ -1135,10 +1445,18 @@ onBeforeUnmount(() => { &.agenda-table-cell-name { font-weight: 600; color: $teal-700; + + @at-root .theme-dark & { + color: $teal-200; + } } &.agenda-table-cell-links { background: linear-gradient(to right, rgba(lighten($teal, 54%), 0), lighten($teal, 54%)); + + @at-root .theme-dark & { + background: rgba($teal, .15) !important; + } } } @@ -1303,6 +1621,22 @@ onBeforeUnmount(() => { } } +.overflow-button { + font-size: inherit; + padding: 0; + border: 0; + background: transparent; + + &:before { + content: ""; + position: absolute; + left: 0; + right: 0; + top: 0; + bottom: 0; + } +} + @keyframes fadeInAnim { 0% { opacity: 0; diff --git a/client/agenda/AgendaSettings.vue b/client/agenda/AgendaSettings.vue index 748b6bf4b81..b074bc32477 100644 --- a/client/agenda/AgendaSettings.vue +++ b/client/agenda/AgendaSettings.vue @@ -3,7 +3,7 @@ n-drawer(v-model:show='isShown', placement='right', :width='panelWidth') n-drawer-content.agenda-settings template(#header) span Agenda Settings - .d-flex.justify-content-end + .agenda-settings-actions.d-flex.justify-content-end n-dropdown( :options='actionOptions' size='large' @@ -31,7 +31,7 @@ n-drawer(v-model:show='isShown', placement='right', :width='panelWidth') n-divider(title-placement='left') i.bi.bi-globe.me-2 small Timezone - n-button-group.mt-2(style='justify-content: stretch; width: 100%;') + n-button-group.mt-2#agenda-settings-tz-btn(style='justify-content: stretch; width: 100%;') n-button( style='flex-grow: 1;' :type='agendaStore.isTimezoneMeeting ? `primary` : `default`' @@ -47,7 +47,7 @@ n-drawer(v-model:show='isShown', placement='right', :width='panelWidth') :type='agendaStore.timezone === `UTC` ? `primary` : `default`' @click='setTimezone(`UTC`)' ) UTC - n-select.mt-2( + n-select.mt-2#agenda-settings-tz-ddn( v-model:value='agendaStore.timezone' :options='timezones' placeholder='Select Time Zone' @@ -61,7 +61,7 @@ n-drawer(v-model:show='isShown', placement='right', :width='panelWidth') //- .d-flex.align-items-center.mt-3 //- n-switch.me-3(v-model:value='agendaStore.listDayCollapse', disabled) //- span.small Collapse Days by Default - .d-flex.align-items-center.mt-3 + #agenda-settings-tgl-colorlgd.d-flex.align-items-center.mt-3 n-switch.me-3( v-model:value='agendaStore.colorLegendShown' aria-label='Display Color Legend' @@ -71,7 +71,7 @@ n-drawer(v-model:show='isShown', placement='right', :width='panelWidth') template(#trigger) i.bi.bi-info-circle span Only displayed when a color is assigned to at least 1 event. - .d-flex.align-items-center.mt-3 + #agenda-settings-tgl-infonote.d-flex.align-items-center.mt-3 n-switch.me-3( v-model:value='agendaStore.infoNoteShown' aria-label='Display Current Meeting Info Note' @@ -81,19 +81,19 @@ n-drawer(v-model:show='isShown', placement='right', :width='panelWidth') template(#trigger) i.bi.bi-info-circle span Any update to the note will result in this setting being turned back on. - .d-flex.align-items-center.mt-3 + #agenda-settings-tgl-eventicons.d-flex.align-items-center.mt-3 n-switch.me-3( v-model:value='agendaStore.eventIconsShown' aria-label='Display Event Icons' ) span.small Display Event Icons - .d-flex.align-items-center.mt-3 + #agenda-settings-tgl-floorind.d-flex.align-items-center.mt-3 n-switch.me-3( v-model:value='agendaStore.floorIndicatorsShown' aria-label='Display Floor Indicators' ) span.small Display Floor Indicators - .d-flex.align-items-center.mt-3 + #agenda-settings-tgl-groupind.d-flex.align-items-center.mt-3 n-switch.me-3( v-model:value='agendaStore.areaIndicatorsShown' aria-label='Display Group Area Indicators' @@ -103,7 +103,7 @@ n-drawer(v-model:show='isShown', placement='right', :width='panelWidth') template(#trigger) i.bi.bi-info-circle span Will not be shown on smaller screens, regardless of this setting. - .d-flex.align-items-center.mt-3 + #agenda-settings-tgl-redline.d-flex.align-items-center.mt-3 n-switch.me-3( v-model:value='agendaStore.redhandShown' aria-label='Display Realtime Red Line' @@ -113,7 +113,7 @@ n-drawer(v-model:show='isShown', placement='right', :width='panelWidth') template(#trigger) i.bi.bi-info-circle span Only shown during live events. Updated every 5 seconds. - .d-flex.align-items-center.mt-3 + #agenda-settings-tgl-boldertxt.d-flex.align-items-center.mt-3 n-switch.me-3( v-model:value='agendaStore.bolderText' aria-label='Use Bolder Text' @@ -137,10 +137,10 @@ n-drawer(v-model:show='isShown', placement='right', :width='panelWidth') @click='agendaStore.defaultCalendarView = `day`' ) Day - n-divider(title-placement='left') + n-divider#agenda-settings-colors-header(title-placement='left') i.bi.bi-palette.me-2 small Custom Colors / Tags - .d-flex.align-items-center.mt-3(v-for='(cl, idx) of state.colors') + .agenda-settings-colors-row.d-flex.align-items-center.mt-3(v-for='(cl, idx) of state.colors') n-color-picker.me-3( :modes='[`hex`]' :render-label='() => {}' @@ -198,6 +198,8 @@ import { } from 'naive-ui' import { useAgendaStore } from './store' +import { useSiteStore } from '../shared/store' + import timezones from '../shared/timezones' // MESSAGE PROVIDER @@ -207,6 +209,7 @@ const message = useMessage() // STORES const agendaStore = useAgendaStore() +const siteStore = useSiteStore() // STATE @@ -266,7 +269,7 @@ const calcOffset = computed(() => { return agendaStore.nowDebugDiff ? JSON.stringify(agendaStore.nowDebugDiff.toObject()) : 'None' }) const panelWidth = computed(() => { - return agendaStore.viewport > 500 ? 500 : agendaStore.viewport + return siteStore.viewport > 500 ? 500 : siteStore.viewport }) // WATCHERS @@ -364,6 +367,7 @@ async function actionClick (key) { redhandShown: configJson.redhandShown === true }) state.colors = cloneDeep(agendaStore.colors) + message.success('Config imported successfully.') } catch (err) { console.warn(err) message.error('Failed to import JSON config.') @@ -453,6 +457,14 @@ onMounted(() => { font-size: .8rem; color: $gray-700; text-shadow: 1px 1px 0 #FFF; + + @at-root .theme-dark & { + background-color: $gray-900; + text-shadow: none; + border-bottom-color: $gray-700; + border-right-color: $gray-700; + color: #FFF; + } } &-calcoffset { diff --git a/client/agenda/AgendaShareModal.vue b/client/agenda/AgendaShareModal.vue new file mode 100644 index 00000000000..a71938673bf --- /dev/null +++ b/client/agenda/AgendaShareModal.vue @@ -0,0 +1,173 @@ + + + + + diff --git a/client/agenda/App.vue b/client/agenda/App.vue deleted file mode 100644 index 8ef43a48597..00000000000 --- a/client/agenda/App.vue +++ /dev/null @@ -1,129 +0,0 @@ - - - - - diff --git a/client/agenda/FloorPlan.vue b/client/agenda/FloorPlan.vue index a345befa516..eccd59aeaa2 100644 --- a/client/agenda/FloorPlan.vue +++ b/client/agenda/FloorPlan.vue @@ -5,7 +5,6 @@ span #[strong IETF {{agendaStore.meeting.number}}] Floor Plan .meeting-h1-badges.d-none.d-sm-flex span.meeting-warning(v-if='agendaStore.meeting.warningNote') {{agendaStore.meeting.warningNote}} - span.meeting-beta BETA h4 span {{agendaStore.meeting.city}}, {{ meetingDate }} @@ -59,13 +58,18 @@ import find from 'lodash/find' import xslugify from '../shared/xslugify' import { DateTime } from 'luxon' import { useRoute, useRouter } from 'vue-router' + import { useAgendaStore } from './store' +import { useSiteStore } from '../shared/store' import MeetingNavigation from './MeetingNavigation.vue' +import './agenda.scss' + // STORES const agendaStore = useAgendaStore() +const siteStore = useSiteStore() // ROUTER @@ -144,7 +148,7 @@ watch(() => state.currentRoom, () => { }, 100) }) }) -watch(() => agendaStore.viewport, () => { +watch(() => siteStore.viewport, () => { nextTick(() => { computePlanSizeRatio() }) @@ -183,10 +187,10 @@ function handleDesiredRoom () { if (rm) { state.currentFloor = fl.id state.currentRoom = rm.id + state.desiredRoom = null break } } - state.desiredRoom = null } } @@ -216,10 +220,9 @@ onBeforeUnmount(() => { // MOUNTED onMounted(() => { - // -> Go to current meeting if not provided - if (!route.params.meetingNumber && agendaStore.meeting.number) { - router.replace({ params: { meetingNumber: agendaStore.meeting.number } }) - } + agendaStore.fetch(route.params.meetingNumber) + + handleCurrentMeetingRedirect() // -> Hide Loading Screen if (agendaStore.isLoaded) { @@ -255,6 +258,11 @@ onMounted(() => { border-radius: 5px; font-weight: 500; + @at-root .theme-dark & { + background-color: darken($gray-900, 5%); + border-color: $gray-700; + } + a { cursor: pointer; diff --git a/client/agenda/MeetingNavigation.vue b/client/agenda/MeetingNavigation.vue index 67d8a7eca79..d03fd4c49bb 100644 --- a/client/agenda/MeetingNavigation.vue +++ b/client/agenda/MeetingNavigation.vue @@ -10,7 +10,7 @@ ul.nav.nav-tabs.meeting-nav(v-if='agendaStore.isLoaded') router-link.nav-link( v-else active-class='active' - :to='`/meeting/` + agendaStore.meeting.number + `/` + tab.key + `-neue`' + :to='`/meeting/` + agendaStore.meeting.number + `/` + tab.key' ) i.bi.me-2.d-none.d-sm-inline(:class='tab.icon') span {{tab.title}} diff --git a/client/agenda/agenda.scss b/client/agenda/agenda.scss new file mode 100644 index 00000000000..e3e46d14f0c --- /dev/null +++ b/client/agenda/agenda.scss @@ -0,0 +1,76 @@ +@import "bootstrap/scss/functions"; +@import "bootstrap/scss/variables"; +@import "../shared/breakpoints"; + +.meeting { + > h1 { + font-weight: 500; + color: $gray-700; + display: flex; + justify-content: space-between; + align-items: center; + + @at-root .theme-dark & { + color: $gray-300; + } + + @media screen and (max-width: $bs5-break-sm) { + justify-content: center; + + > span { + font-size: .95em; + } + } + + strong { + font-weight: 700; + background: linear-gradient(220deg, $blue-500 20%, $purple-500 70%); + background-clip: text; + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + box-decoration-break: clone; + + @at-root .theme-dark & { + background-image: linear-gradient(220deg, $yellow-200 20%, $orange-400 70%); + } + } + } + + &-h1-badges { + display: flex; + justify-content: end; + align-items: center; + + > span { + font-size: 13px; + font-weight: 700; + background-color: $pink-500; + box-shadow: 0 0 5px 0 rgba($pink-500, .5); + color: #FFF; + padding: 5px 8px; + border-radius: 6px; + + & + span { + margin-left: 10px; + } + } + } + + &-warning { + background-color: $red-500 !important; + box-shadow: 0 0 5px 0 rgba($red-500, .5) !important; + color: #FFF; + animation: warningBorderFlash 1s ease infinite; + } + + > h4 { + @media screen and (max-width: $bs5-break-sm) { + text-align: center; + + > span { + font-size: .8em; + text-align: center; + } + } + } +} diff --git a/client/agenda/router.js b/client/agenda/router.js deleted file mode 100644 index eeafb207152..00000000000 --- a/client/agenda/router.js +++ /dev/null @@ -1,23 +0,0 @@ -import { createRouter, createWebHistory } from 'vue-router' - -export default createRouter({ - history: createWebHistory(), - routes: [ - { - name: 'agenda', - path: '/meeting/:meetingNumber(\\d+)?/agenda-neue', - component: () => import('./Agenda.vue'), - meta: { - hideLeftMenu: true - } - }, - { - name: 'floor-plan', - path: '/meeting/:meetingNumber(\\d+)?/floor-plan-neue', - component: () => import('./FloorPlan.vue'), - meta: { - hideLeftMenu: true - } - } - ] -}) diff --git a/client/agenda/store.js b/client/agenda/store.js index 5671e41ae60..b5498303a68 100644 --- a/client/agenda/store.js +++ b/client/agenda/store.js @@ -3,6 +3,9 @@ import { DateTime } from 'luxon' import uniqBy from 'lodash/uniqBy' import murmur from 'murmurhash-js/murmurhash3_gc' +import { useSiteStore } from '../shared/store' +import { storageAvailable } from '../shared/feature-detect' + const urlRe = /http[s]?:\/\/(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*\(\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+/ const conferenceDomains = ['webex.com', 'zoom.us', 'jitsi.org', 'meetecho.com', 'gather.town'] @@ -23,7 +26,6 @@ export const useAgendaStore = defineStore('agenda', { { hex: '#20c997', tag: 'Attended' } ], colorAssignments: {}, - criticalError: null, currentTab: 'agenda', dayIntersectId: '', defaultCalendarView: 'week', @@ -35,7 +37,6 @@ export const useAgendaStore = defineStore('agenda', { infoNoteShown: true, isCurrentMeeting: false, isLoaded: false, - isMobile: /Mobi/i.test(navigator.userAgent), listDayCollapse: false, meeting: {}, nowDebugDiff: null, @@ -49,8 +50,7 @@ export const useAgendaStore = defineStore('agenda', { selectedCatSubs: [], settingsShown: false, timezone: DateTime.local().zoneName, - useHedgeDoc: false, - viewport: Math.round(window.innerWidth), + usesNotes: false, visibleDays: [] }), getters: { @@ -119,10 +119,11 @@ export const useAgendaStore = defineStore('agenda', { }) }, meetingDays () { + const siteStore = useSiteStore() return uniqBy(this.scheduleAdjusted, 'adjustedStartDate').sort().map(s => ({ - slug: s.id.toString(), + slug: daySlug(s), ts: s.adjustedStartDate, - label: this.viewport < 1350 ? DateTime.fromISO(s.adjustedStartDate).toFormat('ccc LLL d') : DateTime.fromISO(s.adjustedStartDate).toLocaleString(DateTime.DATE_HUGE) + label: siteStore.viewport < 1350 ? DateTime.fromISO(s.adjustedStartDate).toFormat('ccc LLL d') : DateTime.fromISO(s.adjustedStartDate).toLocaleString(DateTime.DATE_HUGE) })) }, isMeetingLive (state) { @@ -133,18 +134,25 @@ export const useAgendaStore = defineStore('agenda', { } }, actions: { - async fetch () { + async fetch (meetingNumber) { try { - const meetingData = JSON.parse(document.getElementById('meeting-data').textContent) + if (!meetingNumber) { + const meetingData = JSON.parse(document.getElementById('meeting-data').textContent) + meetingNumber = meetingData.meetingNumber + } - const resp = await fetch(`/api/meeting/${meetingData.meetingNumber}/agenda-data`, { credentials: 'omit' }) + const resp = await fetch(`/api/meeting/${meetingNumber}/agenda-data`) if (!resp.ok) { throw new Error(resp.statusText) } const agendaData = await resp.json() // -> Switch to meeting timezone - this.timezone = window.localStorage.getItem(`agenda.${agendaData.meeting.number}.timezone`) || agendaData.meeting.timezone + if (storageAvailable('localStorage')) { + this.timezone = window.localStorage.getItem(`agenda.${agendaData.meeting.number}.timezone`) || agendaData.meeting.timezone + } else { + this.timezone = agendaData.meeting.timezone + } // -> Load meeting data this.categories = agendaData.categories @@ -152,31 +160,47 @@ export const useAgendaStore = defineStore('agenda', { this.isCurrentMeeting = agendaData.isCurrentMeeting this.meeting = agendaData.meeting this.schedule = agendaData.schedule - this.useHedgeDoc = agendaData.useHedgeDoc + this.usesNotes = agendaData.usesNotes // -> Compute current info note hash this.infoNoteHash = murmur(agendaData.meeting.infoNote, 0).toString() // -> Load meeting-specific preferences - this.infoNoteShown = !(window.localStorage.getItem(`agenda.${agendaData.meeting.number}.hideInfo`) === this.infoNoteHash) - this.colorAssignments = JSON.parse(window.localStorage.getItem(`agenda.${agendaData.meeting.number}.colorAssignments`) || '{}') - this.pickedEvents = JSON.parse(window.localStorage.getItem(`agenda.${agendaData.meeting.number}.pickedEvents`) || '[]') + if (storageAvailable('localStorage')) { + this.infoNoteShown = !(window.localStorage.getItem(`agenda.${agendaData.meeting.number}.hideInfo`) === this.infoNoteHash) + this.colorAssignments = JSON.parse(window.localStorage.getItem(`agenda.${agendaData.meeting.number}.colorAssignments`) || '{}') + this.selectedCatSubs = JSON.parse(window.localStorage.getItem(`agenda.${agendaData.meeting.number}.filters`) || '[]') + this.pickedEvents = JSON.parse(window.localStorage.getItem(`agenda.${agendaData.meeting.number}.pickedEvents`) || '[]') + } else { + this.infoNoteShown = true + this.colorAssignments = {} + this.selectedCatSubs = [] + this.pickedEvents = [] + } this.isLoaded = true } catch (err) { console.error(err) - this.criticalError = `Failed to load this meeting: ${err.message}` + const siteStore = useSiteStore() + siteStore.$patch({ + criticalError: `Failed to load this meeting: ${err.message}`, + criticalErrorLink: meetingNumber ? `/meeting/${meetingNumber}/agenda.txt` : `/meeting/agenda.txt`, + criticalErrorLinkText: 'Switch to text-only agenda version' + }) } this.hideLoadingScreen() }, persistMeetingPreferences () { + if (!storageAvailable('localStorage')) { return } + if (this.infoNoteShown) { window.localStorage.removeItem(`agenda.${this.meeting.number}.hideInfo`) } else { window.localStorage.setItem(`agenda.${this.meeting.number}.hideInfo`, this.infoNoteHash) } window.localStorage.setItem(`agenda.${this.meeting.number}.colorAssignments`, JSON.stringify(this.colorAssignments)) + window.localStorage.setItem(`agenda.${this.meeting.number}.filters`, JSON.stringify(this.selectedCatSubs)) window.localStorage.setItem(`agenda.${this.meeting.number}.pickedEvents`, JSON.stringify(this.pickedEvents)) window.localStorage.setItem(`agenda.${this.meeting.number}.timezone`, this.timezone) }, @@ -206,19 +230,41 @@ export const useAgendaStore = defineStore('agenda', { return lastEvent.id || null }, + findNowEventId () { + const currentEventId = this.findCurrentEventId() + + if (currentEventId) { + return currentEventId + } + + // if there isn't a current event then instead find the next event + + const current = (this.nowDebugDiff ? DateTime.local().minus(this.nowDebugDiff) : DateTime.local()).setZone(this.timezone) + + // -> Find next event after current time + let nextEventId = undefined + for(const sh of this.scheduleAdjusted) { + if (sh.adjustedStart > current) { + nextEventId = sh.id + break + } + } + + return nextEventId || null + }, hideLoadingScreen () { // -> Hide loading screen - const loadingRef = document.querySelector('#app-meeting-loading') + const loadingRef = document.querySelector('#app-loading') if (loadingRef) { loadingRef.remove() } } }, persist: { - enabled: true, + enabled: storageAvailable('localStorage'), strategies: [ { - storage: localStorage, + storage: storageAvailable('localStorage') ? localStorage : null, paths: [ 'areaIndicatorsShown', 'bolderText', @@ -268,3 +314,8 @@ function findFirstConferenceUrl (txt) { } catch (err) { } return null } + +export const daySlugPrefix = 'agenda-day-' +export function daySlug(s) { + return `${daySlugPrefix}${s.adjustedStartDate}` // eg 'agenda-day-2024-08-13' +} diff --git a/client/agenda/tour.js b/client/agenda/tour.js new file mode 100644 index 00000000000..27b2a8b0dd0 --- /dev/null +++ b/client/agenda/tour.js @@ -0,0 +1,113 @@ +import Shepherd from 'shepherd.js' +import 'shepherd.js/dist/css/shepherd.css' + +export function initTour ({ mobileMode, pickerMode }) { + const tour = new Shepherd.Tour({ + useModalOverlay: true, + defaultStepOptions: { + classes: 'shepherd-theme-custom', + scrollTo: false, + modalOverlayOpeningPadding: 8, + modalOverlayOpeningRadius: 4, + popperOptions: { + modifiers: [ + { + name: 'offset', + options: { + offset: [0,20] + } + } + ] + } + } + }) + const defaultButtons = [ + { + text: 'Exit', + action: tour.cancel, + secondary: true + }, + { + text: 'Next', + action: tour.next + } + ] + + // STEPS + + tour.addSteps([ + { + title: 'Filter Areas + Groups', + text: 'You can filter the list of sessions by areas or working groups you\'re interested in. The filters you select here also apply to the Calendar View and persist even if you come back to this page later.', + attachTo: { + element: mobileMode ? '.agenda-mobile-bar > button:first-child' : '#agenda-quickaccess-filterbyareagroups-btn', + on: mobileMode ? 'top' : 'left' + }, + buttons: defaultButtons + }, + { + title: 'Pick Sessions', + text: 'Alternatively select individual sessions from the list to build your own schedule.', + attachTo: { + element: pickerMode ? '.agenda-quickaccess-btnrow' : '#agenda-quickaccess-picksessions-btn', + on: 'left' + }, + buttons: defaultButtons, + showOn: () => !mobileMode + }, + { + title: 'Calendar View', + text: 'View the current list of sessions in a calendar view, by week or by day. The filters you selected above also apply in this view.', + attachTo: { + element: mobileMode ? '.agenda-mobile-bar > button:nth-child(2)' : '#agenda-quickaccess-calview-btn', + on: mobileMode ? 'top' : 'left' + }, + buttons: defaultButtons + }, + { + title: 'Add to your calendar', + text: 'Add the current list of sessions to your personal calendar application, in either webcal or ics format.', + attachTo: { + element: mobileMode ? '.agenda-mobile-bar > button:nth-child(3)' : '#agenda-quickaccess-addtocal-btn', + on: mobileMode ? 'top' : 'left' + }, + buttons: defaultButtons + }, + { + title: 'Search Events', + text: 'Filter the list of sessions by searching for specific keywords in the title, location, acronym, notes or group name. Click the button again to close the search and discard its filtering.', + attachTo: { + element: '.agenda-table-search', + on: 'top' + }, + buttons: defaultButtons + }, + { + title: 'Assign Colors to Events', + text: 'Assign colors to individual events to keep track of those you find interesting, wish to attend or define your own colors / descriptions from the Settings panel.', + attachTo: { + element: '.agenda-table-colorpicker', + on: 'top' + }, + buttons: defaultButtons + }, + { + title: 'Sessions', + text: 'View the session materials by either clicking on its title or using the Show meeting materials button on the right. You can locate the room holding this event on the floor plan by clicking on the location name.', + attachTo: { + element: () => document.querySelector('.agenda-table-display-event'), + on: 'top' + }, + buttons: [ + { + text: 'Finish', + action: tour.next + } + ], + modalOverlayOpeningPadding: 0, + modalOverlayOpeningRadius: 2 + } + ]) + + return tour +} diff --git a/client/components/ChatLog.vue b/client/components/ChatLog.vue new file mode 100644 index 00000000000..b3a4f7b40f4 --- /dev/null +++ b/client/components/ChatLog.vue @@ -0,0 +1,176 @@ + + + + + diff --git a/client/components/Polls.vue b/client/components/Polls.vue new file mode 100644 index 00000000000..0846d4ed160 --- /dev/null +++ b/client/components/Polls.vue @@ -0,0 +1,110 @@ + + + + + diff --git a/client/components/Status.vue b/client/components/Status.vue new file mode 100644 index 00000000000..4fded5bbe40 --- /dev/null +++ b/client/components/Status.vue @@ -0,0 +1,80 @@ + diff --git a/client/components/n-theme.vue b/client/components/n-theme.vue index 9fff81671e9..b55c9772b97 100644 --- a/client/components/n-theme.vue +++ b/client/components/n-theme.vue @@ -1,24 +1,45 @@ - diff --git a/client/embedded.js b/client/embedded.js new file mode 100644 index 00000000000..0509c0aecf8 --- /dev/null +++ b/client/embedded.js @@ -0,0 +1,21 @@ +import { createApp } from 'vue' +import piniaPersist from 'pinia-plugin-persist' +import Embedded from './Embedded.vue' +import { createPiniaSingleton } from './shared/create-pinia-singleton' + +// Initialize store (Pinia) + +const pinia = createPiniaSingleton() +pinia.use(piniaPersist) + +// Mount App + +const mountEls = document.querySelectorAll('div.vue-embed') +for (const mnt of mountEls) { + const app = createApp(Embedded, { + componentName: mnt.dataset.component, + componentId: mnt.dataset.componentId + }) + app.use(pinia) + app.mount(mnt) +} diff --git a/client/index.html b/client/index.html new file mode 100644 index 00000000000..75d6f777276 --- /dev/null +++ b/client/index.html @@ -0,0 +1,26 @@ + + + + + + Vite Test + + + + + + + + +
+
+
+
+
+
+
+
+ + + + diff --git a/client/agenda/main.js b/client/main.js similarity index 80% rename from client/agenda/main.js rename to client/main.js index b74f855a522..3fbad907b1d 100644 --- a/client/agenda/main.js +++ b/client/main.js @@ -1,14 +1,14 @@ import { createApp } from 'vue' -import { createPinia } from 'pinia' import piniaPersist from 'pinia-plugin-persist' import App from './App.vue' import router from './router' +import { createPiniaSingleton } from './shared/create-pinia-singleton' const app = createApp(App, {}) // Initialize store (Pinia) -const pinia = createPinia() +const pinia = createPiniaSingleton() pinia.use(piniaPersist) app.use(pinia) @@ -28,4 +28,4 @@ app.use(router) // Mount App -app.mount('#app-meeting') +app.mount('#app') diff --git a/client/router.js b/client/router.js new file mode 100644 index 00000000000..d5c07101c8d --- /dev/null +++ b/client/router.js @@ -0,0 +1,45 @@ +import { createRouter, createWebHistory } from 'vue-router' + +export default createRouter({ + history: createWebHistory(), + routes: [ + // --------------------------------------------------------- + // MEETING + // --------------------------------------------------------- + { + name: 'agenda', + path: '/meeting/:meetingNumber(\\d+)?/agenda', + component: () => import('./agenda/Agenda.vue'), + meta: { + hideLeftMenu: true + } + }, + { + name: 'floor-plan', + path: '/meeting/:meetingNumber(\\d+)?/floor-plan', + component: () => import('./agenda/FloorPlan.vue'), + meta: { + hideLeftMenu: true + } + }, + // -> Redirects + { + path: '/meeting/:meetingNumber(\\d+)?/agenda.html', + redirect: to => { + return { name: 'agenda' } + } + }, + { + path: '/meeting/:meetingNumber(\\d+)?/agenda-utc', + redirect: to => { + return { name: 'agenda', query: { ...to.query, tz: 'UTC' } } + } + }, + { + path: '/meeting/:meetingNumber(\\d+)?/agenda/personalize', + redirect: to => { + return { name: 'agenda', query: { ...to.query, pick: true } } + } + } + ] +}) diff --git a/client/shared/colors.scss b/client/shared/colors.scss new file mode 100644 index 00000000000..e34c459e911 --- /dev/null +++ b/client/shared/colors.scss @@ -0,0 +1,139 @@ +// Bootstrap 5 Color Variables +// Extracted from https://github.com/twbs/bootstrap/blob/main/scss/_variables.scss +// Copyright (c) 2011-2022 Twitter, Inc. +// Copyright (c) 2011-2022 The Bootstrap Authors + +// Tint a color: mix a color with white +@function tint-color($color, $weight) { + @return mix(white, $color, $weight); +} + +// Shade a color: mix a color with black +@function shade-color($color, $weight) { + @return mix(black, $color, $weight); +} + +// Color system + +$white: #fff !default; +$gray-100: #f8f9fa !default; +$gray-200: #e9ecef !default; +$gray-300: #dee2e6 !default; +$gray-400: #ced4da !default; +$gray-500: #adb5bd !default; +$gray-600: #6c757d !default; +$gray-700: #495057 !default; +$gray-800: #343a40 !default; +$gray-900: #212529 !default; +$black: #000 !default; + +$blue: #0d6efd !default; +$indigo: #6610f2 !default; +$purple: #6f42c1 !default; +$pink: #d63384 !default; +$red: #dc3545 !default; +$orange: #fd7e14 !default; +$yellow: #ffc107 !default; +$green: #198754 !default; +$teal: #20c997 !default; +$cyan: #0dcaf0 !default; + +$blue-100: tint-color($blue, 80%) !default; +$blue-200: tint-color($blue, 60%) !default; +$blue-300: tint-color($blue, 40%) !default; +$blue-400: tint-color($blue, 20%) !default; +$blue-500: $blue !default; +$blue-600: shade-color($blue, 20%) !default; +$blue-700: shade-color($blue, 40%) !default; +$blue-800: shade-color($blue, 60%) !default; +$blue-900: shade-color($blue, 80%) !default; + +$indigo-100: tint-color($indigo, 80%) !default; +$indigo-200: tint-color($indigo, 60%) !default; +$indigo-300: tint-color($indigo, 40%) !default; +$indigo-400: tint-color($indigo, 20%) !default; +$indigo-500: $indigo !default; +$indigo-600: shade-color($indigo, 20%) !default; +$indigo-700: shade-color($indigo, 40%) !default; +$indigo-800: shade-color($indigo, 60%) !default; +$indigo-900: shade-color($indigo, 80%) !default; + +$purple-100: tint-color($purple, 80%) !default; +$purple-200: tint-color($purple, 60%) !default; +$purple-300: tint-color($purple, 40%) !default; +$purple-400: tint-color($purple, 20%) !default; +$purple-500: $purple !default; +$purple-600: shade-color($purple, 20%) !default; +$purple-700: shade-color($purple, 40%) !default; +$purple-800: shade-color($purple, 60%) !default; +$purple-900: shade-color($purple, 80%) !default; + +$pink-100: tint-color($pink, 80%) !default; +$pink-200: tint-color($pink, 60%) !default; +$pink-300: tint-color($pink, 40%) !default; +$pink-400: tint-color($pink, 20%) !default; +$pink-500: $pink !default; +$pink-600: shade-color($pink, 20%) !default; +$pink-700: shade-color($pink, 40%) !default; +$pink-800: shade-color($pink, 60%) !default; +$pink-900: shade-color($pink, 80%) !default; + +$red-100: tint-color($red, 80%) !default; +$red-200: tint-color($red, 60%) !default; +$red-300: tint-color($red, 40%) !default; +$red-400: tint-color($red, 20%) !default; +$red-500: $red !default; +$red-600: shade-color($red, 20%) !default; +$red-700: shade-color($red, 40%) !default; +$red-800: shade-color($red, 60%) !default; +$red-900: shade-color($red, 80%) !default; + +$orange-100: tint-color($orange, 80%) !default; +$orange-200: tint-color($orange, 60%) !default; +$orange-300: tint-color($orange, 40%) !default; +$orange-400: tint-color($orange, 20%) !default; +$orange-500: $orange !default; +$orange-600: shade-color($orange, 20%) !default; +$orange-700: shade-color($orange, 40%) !default; +$orange-800: shade-color($orange, 60%) !default; +$orange-900: shade-color($orange, 80%) !default; + +$yellow-100: tint-color($yellow, 80%) !default; +$yellow-200: tint-color($yellow, 60%) !default; +$yellow-300: tint-color($yellow, 40%) !default; +$yellow-400: tint-color($yellow, 20%) !default; +$yellow-500: $yellow !default; +$yellow-600: shade-color($yellow, 20%) !default; +$yellow-700: shade-color($yellow, 40%) !default; +$yellow-800: shade-color($yellow, 60%) !default; +$yellow-900: shade-color($yellow, 80%) !default; + +$green-100: tint-color($green, 80%) !default; +$green-200: tint-color($green, 60%) !default; +$green-300: tint-color($green, 40%) !default; +$green-400: tint-color($green, 20%) !default; +$green-500: $green !default; +$green-600: shade-color($green, 20%) !default; +$green-700: shade-color($green, 40%) !default; +$green-800: shade-color($green, 60%) !default; +$green-900: shade-color($green, 80%) !default; + +$teal-100: tint-color($teal, 80%) !default; +$teal-200: tint-color($teal, 60%) !default; +$teal-300: tint-color($teal, 40%) !default; +$teal-400: tint-color($teal, 20%) !default; +$teal-500: $teal !default; +$teal-600: shade-color($teal, 20%) !default; +$teal-700: shade-color($teal, 40%) !default; +$teal-800: shade-color($teal, 60%) !default; +$teal-900: shade-color($teal, 80%) !default; + +$cyan-100: tint-color($cyan, 80%) !default; +$cyan-200: tint-color($cyan, 60%) !default; +$cyan-300: tint-color($cyan, 40%) !default; +$cyan-400: tint-color($cyan, 20%) !default; +$cyan-500: $cyan !default; +$cyan-600: shade-color($cyan, 20%) !default; +$cyan-700: shade-color($cyan, 40%) !default; +$cyan-800: shade-color($cyan, 60%) !default; +$cyan-900: shade-color($cyan, 80%) !default; diff --git a/client/shared/create-pinia-singleton.js b/client/shared/create-pinia-singleton.js new file mode 100644 index 00000000000..f0013245a1e --- /dev/null +++ b/client/shared/create-pinia-singleton.js @@ -0,0 +1,6 @@ +import { createPinia } from 'pinia' + +export function createPiniaSingleton(){ + window.pinia = window.pinia ?? createPinia() + return window.pinia +} diff --git a/client/shared/feature-detect.js b/client/shared/feature-detect.js new file mode 100644 index 00000000000..4b8232643ea --- /dev/null +++ b/client/shared/feature-detect.js @@ -0,0 +1,19 @@ +const cache = {} + +export function storageAvailable(type) { + if (Object.prototype.hasOwnProperty.call(cache, type)) { + return cache[type] + } + try { + let storage = window[type] + const x = '__storage_test__' + storage.setItem(x, x) + storage.removeItem(x) + cache[type] = true + return true + } + catch (e) { + cache[type] = false + return false + } +} diff --git a/client/shared/json-wrapper.js b/client/shared/json-wrapper.js new file mode 100644 index 00000000000..e080b5a4791 --- /dev/null +++ b/client/shared/json-wrapper.js @@ -0,0 +1,20 @@ +export const JSONWrapper = { + parse(jsonString, defaultValue) { + if(typeof jsonString !== "string") { + return defaultValue + } + try { + return JSON.parse(jsonString); + } catch (e) { + console.error(e); + } + return defaultValue + }, + stringify(data) { + try { + return JSON.stringify(data); + } catch (e) { + console.error(e) + } + }, +} diff --git a/client/shared/local-storage-wrapper.js b/client/shared/local-storage-wrapper.js new file mode 100644 index 00000000000..88cd3dc589e --- /dev/null +++ b/client/shared/local-storage-wrapper.js @@ -0,0 +1,42 @@ + +/* + * DEVELOPER NOTE + * + * Some browsers can block storage (localStorage, sessionStorage) + * access for privacy reasons, and all browsers can have storage + * that's full, and then they throw exceptions. + * + * See https://michalzalecki.com/why-using-localStorage-directly-is-a-bad-idea/ + * + * Exceptions can even be thrown when testing if localStorage + * even exists. This can throw: + * + * if (window.localStorage) + * + * Also localStorage/sessionStorage can be enabled after DOMContentLoaded + * so we handle it gracefully. + * + * 1) we need to wrap all usage in try/catch + * 2) we need to defer actual usage of these until + * necessary, + * + */ + +export const localStorageWrapper = { + getItem: (key) => { + try { + return localStorage.getItem(key) + } catch (e) { + console.error(e); + } + return null; + }, + setItem: (key, value) => { + try { + return localStorage.setItem(key, value) + } catch (e) { + console.error(e); + } + return; + }, +} diff --git a/client/shared/status-common.js b/client/shared/status-common.js new file mode 100644 index 00000000000..6503bfbf634 --- /dev/null +++ b/client/shared/status-common.js @@ -0,0 +1,5 @@ +// Used in Playwright Status and components + +export const STATUS_STORAGE_KEY = "status-dismissed" + +export const generateStatusTestId = (id) => `status-${id}` diff --git a/client/shared/store.js b/client/shared/store.js new file mode 100644 index 00000000000..5dd57f2c814 --- /dev/null +++ b/client/shared/store.js @@ -0,0 +1,12 @@ +import { defineStore } from 'pinia' + +export const useSiteStore = defineStore('site', { + state: () => ({ + criticalError: null, + criticalErrorLink: null, + criticalErrorLinkText: null, + isMobile: /Mobi/i.test(navigator.userAgent), + viewport: Math.round(window.innerWidth), + theme: null + }) +}) diff --git a/client/shared/timezones.js b/client/shared/timezones.js index c3bc4730005..8239c1f98ee 100644 --- a/client/shared/timezones.js +++ b/client/shared/timezones.js @@ -1,252 +1,252 @@ export default [ - { label: '(GMT-11:00) Niue', value: 'Pacific/Niue' }, - { label: '(GMT-11:00) Pago Pago', value: 'Pacific/Pago_Pago' }, - { label: '(GMT-10:00) Hawaii Time', value: 'Pacific/Honolulu' }, - { label: '(GMT-10:00) Rarotonga', value: 'Pacific/Rarotonga' }, - { label: '(GMT-10:00) Tahiti', value: 'Pacific/Tahiti' }, - { label: '(GMT-09:30) Marquesas', value: 'Pacific/Marquesas' }, - { label: '(GMT-09:00) Alaska Time', value: 'America/Anchorage' }, - { label: '(GMT-09:00) Gambier', value: 'Pacific/Gambier' }, - { label: '(GMT-08:00) Pacific Time - Los Angeles', value: 'America/Los_Angeles' }, - { label: '(GMT-08:00) Pacific Time - Tijuana', value: 'America/Tijuana' }, - { label: '(GMT-08:00) Pacific Time - Vancouver', value: 'America/Vancouver' }, - { label: '(GMT-08:00) Pacific Time - Whitehorse', value: 'America/Whitehorse' }, - { label: '(GMT-08:00) Pitcairn', value: 'Pacific/Pitcairn' }, - { label: '(GMT-07:00) Mountain Time - Arizona', value: 'America/Phoenix' }, - { label: '(GMT-07:00) Mountain Time - Chihuahua, Mazatlan', value: 'America/Mazatlan' }, - { label: '(GMT-07:00) Mountain Time - Dawson Creek', value: 'America/Dawson_Creek' }, - { label: '(GMT-07:00) Mountain Time - Denver', value: 'America/Denver' }, - { label: '(GMT-07:00) Mountain Time - Edmonton', value: 'America/Edmonton' }, - { label: '(GMT-07:00) Mountain Time - Hermosillo', value: 'America/Hermosillo' }, - { label: '(GMT-07:00) Mountain Time - Yellowknife', value: 'America/Yellowknife' }, - { label: '(GMT-06:00) Belize', value: 'America/Belize' }, - { label: '(GMT-06:00) Central Time - Chicago', value: 'America/Chicago' }, - { label: '(GMT-06:00) Central Time - Mexico City', value: 'America/Mexico_City' }, - { label: '(GMT-06:00) Central Time - Regina', value: 'America/Regina' }, - { label: '(GMT-06:00) Central Time - Tegucigalpa', value: 'America/Tegucigalpa' }, - { label: '(GMT-06:00) Central Time - Winnipeg', value: 'America/Winnipeg' }, - { label: '(GMT-06:00) Costa Rica', value: 'America/Costa_Rica' }, - { label: '(GMT-06:00) El Salvador', value: 'America/El_Salvador' }, - { label: '(GMT-06:00) Galapagos', value: 'Pacific/Galapagos' }, - { label: '(GMT-06:00) Guatemala', value: 'America/Guatemala' }, - { label: '(GMT-06:00) Managua', value: 'America/Managua' }, - { label: '(GMT-05:00) America Cancun', value: 'America/Cancun' }, - { label: '(GMT-05:00) Bogota', value: 'America/Bogota' }, - { label: '(GMT-05:00) Easter Island', value: 'Pacific/Easter' }, - { label: '(GMT-05:00) Eastern Time - New York', value: 'America/New_York' }, - { label: '(GMT-05:00) Eastern Time - Iqaluit', value: 'America/Iqaluit' }, - { label: '(GMT-05:00) Eastern Time - Toronto', value: 'America/Toronto' }, - { label: '(GMT-05:00) Guayaquil', value: 'America/Guayaquil' }, - { label: '(GMT-05:00) Havana', value: 'America/Havana' }, - { label: '(GMT-05:00) Jamaica', value: 'America/Jamaica' }, - { label: '(GMT-05:00) Lima', value: 'America/Lima' }, - { label: '(GMT-05:00) Nassau', value: 'America/Nassau' }, - { label: '(GMT-05:00) Panama', value: 'America/Panama' }, - { label: '(GMT-05:00) Port-au-Prince', value: 'America/Port-au-Prince' }, - { label: '(GMT-05:00) Rio Branco', value: 'America/Rio_Branco' }, - { label: '(GMT-04:00) Atlantic Time - Halifax', value: 'America/Halifax' }, - { label: '(GMT-04:00) Barbados', value: 'America/Barbados' }, - { label: '(GMT-04:00) Bermuda', value: 'Atlantic/Bermuda' }, - { label: '(GMT-04:00) Boa Vista', value: 'America/Boa_Vista' }, - { label: '(GMT-04:00) Caracas', value: 'America/Caracas' }, - { label: '(GMT-04:00) Curacao', value: 'America/Curacao' }, - { label: '(GMT-04:00) Grand Turk', value: 'America/Grand_Turk' }, - { label: '(GMT-04:00) Guyana', value: 'America/Guyana' }, - { label: '(GMT-04:00) La Paz', value: 'America/La_Paz' }, - { label: '(GMT-04:00) Manaus', value: 'America/Manaus' }, - { label: '(GMT-04:00) Martinique', value: 'America/Martinique' }, - { label: '(GMT-04:00) Port of Spain', value: 'America/Port_of_Spain' }, - { label: '(GMT-04:00) Porto Velho', value: 'America/Porto_Velho' }, - { label: '(GMT-04:00) Puerto Rico', value: 'America/Puerto_Rico' }, - { label: '(GMT-04:00) Santo Domingo', value: 'America/Santo_Domingo' }, - { label: '(GMT-04:00) Thule', value: 'America/Thule' }, - { label: '(GMT-03:30) Newfoundland Time - St. Johns', value: 'America/St_Johns' }, - { label: '(GMT-03:00) Araguaina', value: 'America/Araguaina' }, - { label: '(GMT-03:00) Asuncion', value: 'America/Asuncion' }, - { label: '(GMT-03:00) Belem', value: 'America/Belem' }, - { label: '(GMT-03:00) Buenos Aires', value: 'America/Argentina/Buenos_Aires' }, - { label: '(GMT-03:00) Campo Grande', value: 'America/Campo_Grande' }, - { label: '(GMT-03:00) Cayenne', value: 'America/Cayenne' }, - { label: '(GMT-03:00) Cuiaba', value: 'America/Cuiaba' }, - { label: '(GMT-03:00) Fortaleza', value: 'America/Fortaleza' }, - { label: '(GMT-03:00) Godthab', value: 'America/Godthab' }, - { label: '(GMT-03:00) Maceio', value: 'America/Maceio' }, - { label: '(GMT-03:00) Miquelon', value: 'America/Miquelon' }, - { label: '(GMT-03:00) Montevideo', value: 'America/Montevideo' }, - { label: '(GMT-03:00) Palmer', value: 'Antarctica/Palmer' }, - { label: '(GMT-03:00) Paramaribo', value: 'America/Paramaribo' }, - { label: '(GMT-03:00) Punta Arenas', value: 'America/Punta_Arenas' }, - { label: '(GMT-03:00) Recife', value: 'America/Recife' }, - { label: '(GMT-03:00) Rothera', value: 'Antarctica/Rothera' }, - { label: '(GMT-03:00) Salvador', value: 'America/Bahia' }, - { label: '(GMT-03:00) Santiago', value: 'America/Santiago' }, - { label: '(GMT-03:00) Stanley', value: 'Atlantic/Stanley' }, - { label: '(GMT-02:00) Noronha', value: 'America/Noronha' }, - { label: '(GMT-02:00) Sao Paulo', value: 'America/Sao_Paulo' }, - { label: '(GMT-02:00) South Georgia', value: 'Atlantic/South_Georgia' }, - { label: '(GMT-01:00) Azores', value: 'Atlantic/Azores' }, - { label: '(GMT-01:00) Cape Verde', value: 'Atlantic/Cape_Verde' }, - { label: '(GMT-01:00) Scoresbysund', value: 'America/Scoresbysund' }, - { label: '(GMT+00:00) Abidjan', value: 'Africa/Abidjan' }, - { label: '(GMT+00:00) Accra', value: 'Africa/Accra' }, - { label: '(GMT+00:00) Bissau', value: 'Africa/Bissau' }, - { label: '(GMT+00:00) Canary Islands', value: 'Atlantic/Canary' }, - { label: '(GMT+00:00) Casablanca', value: 'Africa/Casablanca' }, - { label: '(GMT+00:00) Danmarkshavn', value: 'America/Danmarkshavn' }, - { label: '(GMT+00:00) Dublin', value: 'Europe/Dublin' }, - { label: '(GMT+00:00) El Aaiun', value: 'Africa/El_Aaiun' }, - { label: '(GMT+00:00) Faeroe', value: 'Atlantic/Faroe' }, - { label: '(GMT+00:00) UTC / GMT', value: 'UTC' }, - { label: '(GMT+00:00) Lisbon', value: 'Europe/Lisbon' }, - { label: '(GMT+00:00) London', value: 'Europe/London' }, - { label: '(GMT+00:00) Monrovia', value: 'Africa/Monrovia' }, - { label: '(GMT+00:00) Reykjavik', value: 'Atlantic/Reykjavik' }, - { label: '(GMT+01:00) Algiers', value: 'Africa/Algiers' }, - { label: '(GMT+01:00) Amsterdam', value: 'Europe/Amsterdam' }, - { label: '(GMT+01:00) Andorra', value: 'Europe/Andorra' }, - { label: '(GMT+01:00) Berlin', value: 'Europe/Berlin' }, - { label: '(GMT+01:00) Brussels', value: 'Europe/Brussels' }, - { label: '(GMT+01:00) Budapest', value: 'Europe/Budapest' }, - { label: '(GMT+01:00) Central European Time - Belgrade', value: 'Europe/Belgrade' }, - { label: '(GMT+01:00) Central European Time - Prague', value: 'Europe/Prague' }, - { label: '(GMT+01:00) Ceuta', value: 'Africa/Ceuta' }, - { label: '(GMT+01:00) Copenhagen', value: 'Europe/Copenhagen' }, - { label: '(GMT+01:00) Gibraltar', value: 'Europe/Gibraltar' }, - { label: '(GMT+01:00) Lagos', value: 'Africa/Lagos' }, - { label: '(GMT+01:00) Luxembourg', value: 'Europe/Luxembourg' }, - { label: '(GMT+01:00) Madrid', value: 'Europe/Madrid' }, - { label: '(GMT+01:00) Malta', value: 'Europe/Malta' }, - { label: '(GMT+01:00) Monaco', value: 'Europe/Monaco' }, - { label: '(GMT+01:00) Ndjamena', value: 'Africa/Ndjamena' }, - { label: '(GMT+01:00) Oslo', value: 'Europe/Oslo' }, - { label: '(GMT+01:00) Paris', value: 'Europe/Paris' }, - { label: '(GMT+01:00) Rome', value: 'Europe/Rome' }, - { label: '(GMT+01:00) Stockholm', value: 'Europe/Stockholm' }, - { label: '(GMT+01:00) Tirane', value: 'Europe/Tirane' }, - { label: '(GMT+01:00) Tunis', value: 'Africa/Tunis' }, - { label: '(GMT+01:00) Vienna', value: 'Europe/Vienna' }, - { label: '(GMT+01:00) Warsaw', value: 'Europe/Warsaw' }, - { label: '(GMT+01:00) Zurich', value: 'Europe/Zurich' }, - { label: '(GMT+02:00) Amman', value: 'Asia/Amman' }, - { label: '(GMT+02:00) Athens', value: 'Europe/Athens' }, - { label: '(GMT+02:00) Beirut', value: 'Asia/Beirut' }, - { label: '(GMT+02:00) Bucharest', value: 'Europe/Bucharest' }, - { label: '(GMT+02:00) Cairo', value: 'Africa/Cairo' }, - { label: '(GMT+02:00) Chisinau', value: 'Europe/Chisinau' }, - { label: '(GMT+02:00) Damascus', value: 'Asia/Damascus' }, - { label: '(GMT+02:00) Gaza', value: 'Asia/Gaza' }, - { label: '(GMT+02:00) Helsinki', value: 'Europe/Helsinki' }, - { label: '(GMT+02:00) Jerusalem', value: 'Asia/Jerusalem' }, - { label: '(GMT+02:00) Johannesburg', value: 'Africa/Johannesburg' }, - { label: '(GMT+02:00) Khartoum', value: 'Africa/Khartoum' }, - { label: '(GMT+02:00) Kiev', value: 'Europe/Kiev' }, - { label: '(GMT+02:00) Maputo', value: 'Africa/Maputo' }, - { label: '(GMT+02:00) Moscow-01 - Kaliningrad', value: 'Europe/Kaliningrad' }, - { label: '(GMT+02:00) Nicosia', value: 'Asia/Nicosia' }, - { label: '(GMT+02:00) Riga', value: 'Europe/Riga' }, - { label: '(GMT+02:00) Sofia', value: 'Europe/Sofia' }, - { label: '(GMT+02:00) Tallinn', value: 'Europe/Tallinn' }, - { label: '(GMT+02:00) Tripoli', value: 'Africa/Tripoli' }, - { label: '(GMT+02:00) Vilnius', value: 'Europe/Vilnius' }, - { label: '(GMT+02:00) Windhoek', value: 'Africa/Windhoek' }, - { label: '(GMT+03:00) Baghdad', value: 'Asia/Baghdad' }, - { label: '(GMT+03:00) Istanbul', value: 'Europe/Istanbul' }, - { label: '(GMT+03:00) Minsk', value: 'Europe/Minsk' }, - { label: '(GMT+03:00) Moscow+00 - Moscow', value: 'Europe/Moscow' }, - { label: '(GMT+03:00) Nairobi', value: 'Africa/Nairobi' }, - { label: '(GMT+03:00) Qatar', value: 'Asia/Qatar' }, - { label: '(GMT+03:00) Riyadh', value: 'Asia/Riyadh' }, - { label: '(GMT+03:00) Syowa', value: 'Antarctica/Syowa' }, - { label: '(GMT+03:30) Tehran', value: 'Asia/Tehran' }, - { label: '(GMT+04:00) Baku', value: 'Asia/Baku' }, - { label: '(GMT+04:00) Dubai', value: 'Asia/Dubai' }, - { label: '(GMT+04:00) Mahe', value: 'Indian/Mahe' }, - { label: '(GMT+04:00) Mauritius', value: 'Indian/Mauritius' }, - { label: '(GMT+04:00) Moscow+01 - Samara', value: 'Europe/Samara' }, - { label: '(GMT+04:00) Reunion', value: 'Indian/Reunion' }, - { label: '(GMT+04:00) Tbilisi', value: 'Asia/Tbilisi' }, - { label: '(GMT+04:00) Yerevan', value: 'Asia/Yerevan' }, - { label: '(GMT+04:30) Kabul', value: 'Asia/Kabul' }, - { label: '(GMT+05:00) Aqtau', value: 'Asia/Aqtau' }, - { label: '(GMT+05:00) Aqtobe', value: 'Asia/Aqtobe' }, - { label: '(GMT+05:00) Ashgabat', value: 'Asia/Ashgabat' }, - { label: '(GMT+05:00) Dushanbe', value: 'Asia/Dushanbe' }, - { label: '(GMT+05:00) Karachi', value: 'Asia/Karachi' }, - { label: '(GMT+05:00) Kerguelen', value: 'Indian/Kerguelen' }, - { label: '(GMT+05:00) Maldives', value: 'Indian/Maldives' }, - { label: '(GMT+05:00) Mawson', value: 'Antarctica/Mawson' }, - { label: '(GMT+05:00) Moscow+02 - Yekaterinburg', value: 'Asia/Yekaterinburg' }, - { label: '(GMT+05:00) Tashkent', value: 'Asia/Tashkent' }, - { label: '(GMT+05:30) Colombo', value: 'Asia/Colombo' }, - { label: '(GMT+05:30) India Standard Time', value: 'Asia/Kolkata' }, - { label: '(GMT+05:45) Kathmandu', value: 'Asia/Kathmandu' }, - { label: '(GMT+06:00) Almaty', value: 'Asia/Almaty' }, - { label: '(GMT+06:00) Bishkek', value: 'Asia/Bishkek' }, - { label: '(GMT+06:00) Chagos', value: 'Indian/Chagos' }, - { label: '(GMT+06:00) Dhaka', value: 'Asia/Dhaka' }, - { label: '(GMT+06:00) Moscow+03 - Omsk', value: 'Asia/Omsk' }, - { label: '(GMT+06:00) Thimphu', value: 'Asia/Thimphu' }, - { label: '(GMT+06:00) Vostok', value: 'Antarctica/Vostok' }, - { label: '(GMT+06:30) Cocos', value: 'Indian/Cocos' }, - { label: '(GMT+06:30) Rangoon', value: 'Asia/Yangon' }, - { label: '(GMT+07:00) Bangkok', value: 'Asia/Bangkok' }, - { label: '(GMT+07:00) Christmas', value: 'Indian/Christmas' }, - { label: '(GMT+07:00) Davis', value: 'Antarctica/Davis' }, - { label: '(GMT+07:00) Hanoi', value: 'Asia/Saigon' }, - { label: '(GMT+07:00) Hovd', value: 'Asia/Hovd' }, - { label: '(GMT+07:00) Jakarta', value: 'Asia/Jakarta' }, - { label: '(GMT+07:00) Moscow+04 - Krasnoyarsk', value: 'Asia/Krasnoyarsk' }, - { label: '(GMT+08:00) Brunei', value: 'Asia/Brunei' }, - { label: '(GMT+08:00) China Time - Beijing', value: 'Asia/Shanghai' }, - { label: '(GMT+08:00) Choibalsan', value: 'Asia/Choibalsan' }, - { label: '(GMT+08:00) Hong Kong', value: 'Asia/Hong_Kong' }, - { label: '(GMT+08:00) Kuala Lumpur', value: 'Asia/Kuala_Lumpur' }, - { label: '(GMT+08:00) Macau', value: 'Asia/Macau' }, - { label: '(GMT+08:00) Makassar', value: 'Asia/Makassar' }, - { label: '(GMT+08:00) Manila', value: 'Asia/Manila' }, - { label: '(GMT+08:00) Moscow+05 - Irkutsk', value: 'Asia/Irkutsk' }, - { label: '(GMT+08:00) Singapore', value: 'Asia/Singapore' }, - { label: '(GMT+08:00) Taipei', value: 'Asia/Taipei' }, - { label: '(GMT+08:00) Ulaanbaatar', value: 'Asia/Ulaanbaatar' }, - { label: '(GMT+08:00) Western Time - Perth', value: 'Australia/Perth' }, - { label: '(GMT+08:30) Pyongyang', value: 'Asia/Pyongyang' }, - { label: '(GMT+09:00) Dili', value: 'Asia/Dili' }, - { label: '(GMT+09:00) Jayapura', value: 'Asia/Jayapura' }, - { label: '(GMT+09:00) Moscow+06 - Yakutsk', value: 'Asia/Yakutsk' }, - { label: '(GMT+09:00) Palau', value: 'Pacific/Palau' }, - { label: '(GMT+09:00) Seoul', value: 'Asia/Seoul' }, - { label: '(GMT+09:00) Tokyo', value: 'Asia/Tokyo' }, - { label: '(GMT+09:30) Central Time - Darwin', value: 'Australia/Darwin' }, - { label: '(GMT+10:00) Dumont D\'Urville', value: 'Antarctica/DumontDUrville' }, - { label: '(GMT+10:00) Eastern Time - Brisbane', value: 'Australia/Brisbane' }, - { label: '(GMT+10:00) Guam', value: 'Pacific/Guam' }, - { label: '(GMT+10:00) Moscow+07 - Vladivostok', value: 'Asia/Vladivostok' }, - { label: '(GMT+10:00) Port Moresby', value: 'Pacific/Port_Moresby' }, - { label: '(GMT+10:00) Truk', value: 'Pacific/Chuuk' }, - { label: '(GMT+10:30) Central Time - Adelaide', value: 'Australia/Adelaide' }, - { label: '(GMT+11:00) Casey', value: 'Antarctica/Casey' }, - { label: '(GMT+11:00) Eastern Time - Hobart', value: 'Australia/Hobart' }, - { label: '(GMT+11:00) Eastern Time - Melbourne, Sydney', value: 'Australia/Sydney' }, - { label: '(GMT+11:00) Efate', value: 'Pacific/Efate' }, - { label: '(GMT+11:00) Guadalcanal', value: 'Pacific/Guadalcanal' }, - { label: '(GMT+11:00) Kosrae', value: 'Pacific/Kosrae' }, - { label: '(GMT+11:00) Moscow+08 - Magadan', value: 'Asia/Magadan' }, - { label: '(GMT+11:00) Norfolk', value: 'Pacific/Norfolk' }, - { label: '(GMT+11:00) Noumea', value: 'Pacific/Noumea' }, - { label: '(GMT+11:00) Ponape', value: 'Pacific/Pohnpei' }, - { label: '(GMT+12:00) Funafuti', value: 'Pacific/Funafuti' }, - { label: '(GMT+12:00) Kwajalein', value: 'Pacific/Kwajalein' }, - { label: '(GMT+12:00) Majuro', value: 'Pacific/Majuro' }, - { label: '(GMT+12:00) Moscow+09 - Petropavlovsk-Kamchatskiy', value: 'Asia/Kamchatka' }, - { label: '(GMT+12:00) Nauru', value: 'Pacific/Nauru' }, - { label: '(GMT+12:00) Tarawa', value: 'Pacific/Tarawa' }, - { label: '(GMT+12:00) Wake', value: 'Pacific/Wake' }, - { label: '(GMT+12:00) Wallis', value: 'Pacific/Wallis' }, - { label: '(GMT+13:00) Auckland', value: 'Pacific/Auckland' }, - { label: '(GMT+13:00) Enderbury', value: 'Pacific/Enderbury' }, - { label: '(GMT+13:00) Fakaofo', value: 'Pacific/Fakaofo' }, - { label: '(GMT+13:00) Fiji', value: 'Pacific/Fiji' }, - { label: '(GMT+13:00) Tongatapu', value: 'Pacific/Tongatapu' }, - { label: '(GMT+14:00) Apia', value: 'Pacific/Apia' }, - { label: '(GMT+14:00) Kiritimati', value: 'Pacific/Kiritimati' } + { label: 'Pacific - Niue', value: 'Pacific/Niue' }, + { label: 'Pacific - Pago Pago', value: 'Pacific/Pago_Pago' }, + { label: 'Pacific - Hawaii Time', value: 'Pacific/Honolulu' }, + { label: 'Pacific - Rarotonga', value: 'Pacific/Rarotonga' }, + { label: 'Pacific - Tahiti', value: 'Pacific/Tahiti' }, + { label: 'Pacific - Marquesas', value: 'Pacific/Marquesas' }, + { label: 'America - Alaska Time', value: 'America/Anchorage' }, + { label: 'Pacific - Gambier', value: 'Pacific/Gambier' }, + { label: 'America - Pacific Time - Los Angeles', value: 'America/Los_Angeles' }, + { label: 'America - Pacific Time - Tijuana', value: 'America/Tijuana' }, + { label: 'America - Pacific Time - Vancouver', value: 'America/Vancouver' }, + { label: 'America - Pacific Time - Whitehorse', value: 'America/Whitehorse' }, + { label: 'Pacific - Pitcairn', value: 'Pacific/Pitcairn' }, + { label: 'America - Mountain Time - Arizona', value: 'America/Phoenix' }, + { label: 'America - Mountain Time - Chihuahua, Mazatlan', value: 'America/Mazatlan' }, + { label: 'America - Mountain Time - Dawson Creek', value: 'America/Dawson_Creek' }, + { label: 'America - Mountain Time - Denver', value: 'America/Denver' }, + { label: 'America - Mountain Time - Edmonton', value: 'America/Edmonton' }, + { label: 'America - Mountain Time - Hermosillo', value: 'America/Hermosillo' }, + { label: 'America - Mountain Time - Yellowknife', value: 'America/Yellowknife' }, + { label: 'America - Belize', value: 'America/Belize' }, + { label: 'America - Central Time - Chicago', value: 'America/Chicago' }, + { label: 'America - Central Time - Mexico City', value: 'America/Mexico_City' }, + { label: 'America - Central Time - Regina', value: 'America/Regina' }, + { label: 'America - Central Time - Tegucigalpa', value: 'America/Tegucigalpa' }, + { label: 'America - Central Time - Winnipeg', value: 'America/Winnipeg' }, + { label: 'America - Costa Rica', value: 'America/Costa_Rica' }, + { label: 'America - El Salvador', value: 'America/El_Salvador' }, + { label: 'Pacific - Galapagos', value: 'Pacific/Galapagos' }, + { label: 'America - Guatemala', value: 'America/Guatemala' }, + { label: 'America - Managua', value: 'America/Managua' }, + { label: 'America - America Cancun', value: 'America/Cancun' }, + { label: 'America - Bogota', value: 'America/Bogota' }, + { label: 'Pacific - Easter Island', value: 'Pacific/Easter' }, + { label: 'America - Eastern Time - New York', value: 'America/New_York' }, + { label: 'America - Eastern Time - Iqaluit', value: 'America/Iqaluit' }, + { label: 'America - Eastern Time - Toronto', value: 'America/Toronto' }, + { label: 'America - Guayaquil', value: 'America/Guayaquil' }, + { label: 'America - Havana', value: 'America/Havana' }, + { label: 'America - Jamaica', value: 'America/Jamaica' }, + { label: 'America - Lima', value: 'America/Lima' }, + { label: 'America - Nassau', value: 'America/Nassau' }, + { label: 'America - Panama', value: 'America/Panama' }, + { label: 'America - Port-au-Prince', value: 'America/Port-au-Prince' }, + { label: 'America - Rio Branco', value: 'America/Rio_Branco' }, + { label: 'America - Atlantic Time - Halifax', value: 'America/Halifax' }, + { label: 'America - Barbados', value: 'America/Barbados' }, + { label: 'Atlantic - Bermuda', value: 'Atlantic/Bermuda' }, + { label: 'America - Boa Vista', value: 'America/Boa_Vista' }, + { label: 'America - Caracas', value: 'America/Caracas' }, + { label: 'America - Curacao', value: 'America/Curacao' }, + { label: 'America - Grand Turk', value: 'America/Grand_Turk' }, + { label: 'America - Guyana', value: 'America/Guyana' }, + { label: 'America - La Paz', value: 'America/La_Paz' }, + { label: 'America - Manaus', value: 'America/Manaus' }, + { label: 'America - Martinique', value: 'America/Martinique' }, + { label: 'America - Port of Spain', value: 'America/Port_of_Spain' }, + { label: 'America - Porto Velho', value: 'America/Porto_Velho' }, + { label: 'America - Puerto Rico', value: 'America/Puerto_Rico' }, + { label: 'America - Santo Domingo', value: 'America/Santo_Domingo' }, + { label: 'America - Thule', value: 'America/Thule' }, + { label: 'America - Newfoundland Time - St. Johns', value: 'America/St_Johns' }, + { label: 'America - Araguaina', value: 'America/Araguaina' }, + { label: 'America - Asuncion', value: 'America/Asuncion' }, + { label: 'America - Belem', value: 'America/Belem' }, + { label: 'America - Buenos Aires', value: 'America/Argentina/Buenos_Aires' }, + { label: 'America - Campo Grande', value: 'America/Campo_Grande' }, + { label: 'America - Cayenne', value: 'America/Cayenne' }, + { label: 'America - Cuiaba', value: 'America/Cuiaba' }, + { label: 'America - Fortaleza', value: 'America/Fortaleza' }, + { label: 'America - Godthab', value: 'America/Godthab' }, + { label: 'America - Maceio', value: 'America/Maceio' }, + { label: 'America - Miquelon', value: 'America/Miquelon' }, + { label: 'America - Montevideo', value: 'America/Montevideo' }, + { label: 'Antarctica - Palmer', value: 'Antarctica/Palmer' }, + { label: 'America - Paramaribo', value: 'America/Paramaribo' }, + { label: 'America - Punta Arenas', value: 'America/Punta_Arenas' }, + { label: 'America - Recife', value: 'America/Recife' }, + { label: 'Antarctica - Rothera', value: 'Antarctica/Rothera' }, + { label: 'America - Salvador', value: 'America/Bahia' }, + { label: 'America - Santiago', value: 'America/Santiago' }, + { label: 'Atlantic - Stanley', value: 'Atlantic/Stanley' }, + { label: 'America - Noronha', value: 'America/Noronha' }, + { label: 'America - Sao Paulo', value: 'America/Sao_Paulo' }, + { label: 'Atlantic - South Georgia', value: 'Atlantic/South_Georgia' }, + { label: 'Atlantic - Azores', value: 'Atlantic/Azores' }, + { label: 'Atlantic - Cape Verde', value: 'Atlantic/Cape_Verde' }, + { label: 'America - Scoresbysund', value: 'America/Scoresbysund' }, + { label: 'Africa - Abidjan', value: 'Africa/Abidjan' }, + { label: 'Africa - Accra', value: 'Africa/Accra' }, + { label: 'Africa - Bissau', value: 'Africa/Bissau' }, + { label: 'Atlantic - Canary Islands', value: 'Atlantic/Canary' }, + { label: 'Africa - Casablanca', value: 'Africa/Casablanca' }, + { label: 'America - Danmarkshavn', value: 'America/Danmarkshavn' }, + { label: 'Europe - Dublin', value: 'Europe/Dublin' }, + { label: 'Africa - El Aaiun', value: 'Africa/El_Aaiun' }, + { label: 'Atlantic - Faeroe', value: 'Atlantic/Faroe' }, + { label: 'UTC / GMT', value: 'UTC' }, + { label: 'Europe - Lisbon', value: 'Europe/Lisbon' }, + { label: 'Europe - London', value: 'Europe/London' }, + { label: 'Africa - Monrovia', value: 'Africa/Monrovia' }, + { label: 'Atlantic - Reykjavik', value: 'Atlantic/Reykjavik' }, + { label: 'Africa - Algiers', value: 'Africa/Algiers' }, + { label: 'Europe - Amsterdam', value: 'Europe/Amsterdam' }, + { label: 'Europe - Andorra', value: 'Europe/Andorra' }, + { label: 'Europe - Berlin', value: 'Europe/Berlin' }, + { label: 'Europe - Brussels', value: 'Europe/Brussels' }, + { label: 'Europe - Budapest', value: 'Europe/Budapest' }, + { label: 'Europe - Central European Time - Belgrade', value: 'Europe/Belgrade' }, + { label: 'Europe - Central European Time - Prague', value: 'Europe/Prague' }, + { label: 'Africa - Ceuta', value: 'Africa/Ceuta' }, + { label: 'Europe - Copenhagen', value: 'Europe/Copenhagen' }, + { label: 'Europe - Gibraltar', value: 'Europe/Gibraltar' }, + { label: 'Africa - Lagos', value: 'Africa/Lagos' }, + { label: 'Europe - Luxembourg', value: 'Europe/Luxembourg' }, + { label: 'Europe - Madrid', value: 'Europe/Madrid' }, + { label: 'Europe - Malta', value: 'Europe/Malta' }, + { label: 'Europe - Monaco', value: 'Europe/Monaco' }, + { label: 'Africa - Ndjamena', value: 'Africa/Ndjamena' }, + { label: 'Europe - Oslo', value: 'Europe/Oslo' }, + { label: 'Europe - Paris', value: 'Europe/Paris' }, + { label: 'Europe - Rome', value: 'Europe/Rome' }, + { label: 'Europe - Stockholm', value: 'Europe/Stockholm' }, + { label: 'Europe - Tirane', value: 'Europe/Tirane' }, + { label: 'Africa - Tunis', value: 'Africa/Tunis' }, + { label: 'Europe - Vienna', value: 'Europe/Vienna' }, + { label: 'Europe - Warsaw', value: 'Europe/Warsaw' }, + { label: 'Europe - Zurich', value: 'Europe/Zurich' }, + { label: 'Asia - Amman', value: 'Asia/Amman' }, + { label: 'Europe - Athens', value: 'Europe/Athens' }, + { label: 'Asia - Beirut', value: 'Asia/Beirut' }, + { label: 'Europe - Bucharest', value: 'Europe/Bucharest' }, + { label: 'Africa - Cairo', value: 'Africa/Cairo' }, + { label: 'Europe - Chisinau', value: 'Europe/Chisinau' }, + { label: 'Asia - Damascus', value: 'Asia/Damascus' }, + { label: 'Asia - Gaza', value: 'Asia/Gaza' }, + { label: 'Europe - Helsinki', value: 'Europe/Helsinki' }, + { label: 'Asia - Jerusalem', value: 'Asia/Jerusalem' }, + { label: 'Africa - Johannesburg', value: 'Africa/Johannesburg' }, + { label: 'Africa - Khartoum', value: 'Africa/Khartoum' }, + { label: 'Europe - Kiev', value: 'Europe/Kiev' }, + { label: 'Africa - Maputo', value: 'Africa/Maputo' }, + { label: 'Europe - Moscow-01 - Kaliningrad', value: 'Europe/Kaliningrad' }, + { label: 'Asia - Nicosia', value: 'Asia/Nicosia' }, + { label: 'Europe - Riga', value: 'Europe/Riga' }, + { label: 'Europe - Sofia', value: 'Europe/Sofia' }, + { label: 'Europe - Tallinn', value: 'Europe/Tallinn' }, + { label: 'Africa - Tripoli', value: 'Africa/Tripoli' }, + { label: 'Europe - Vilnius', value: 'Europe/Vilnius' }, + { label: 'Africa - Windhoek', value: 'Africa/Windhoek' }, + { label: 'Asia - Baghdad', value: 'Asia/Baghdad' }, + { label: 'Europe - Istanbul', value: 'Europe/Istanbul' }, + { label: 'Europe - Minsk', value: 'Europe/Minsk' }, + { label: 'Europe - Moscow+00 - Moscow', value: 'Europe/Moscow' }, + { label: 'Africa - Nairobi', value: 'Africa/Nairobi' }, + { label: 'Asia - Qatar', value: 'Asia/Qatar' }, + { label: 'Asia - Riyadh', value: 'Asia/Riyadh' }, + { label: 'Antarctica - Syowa', value: 'Antarctica/Syowa' }, + { label: 'Asia - Tehran', value: 'Asia/Tehran' }, + { label: 'Asia - Baku', value: 'Asia/Baku' }, + { label: 'Asia - Dubai', value: 'Asia/Dubai' }, + { label: 'Indian - Mahe', value: 'Indian/Mahe' }, + { label: 'Indian - Mauritius', value: 'Indian/Mauritius' }, + { label: 'Europe - Moscow+01 - Samara', value: 'Europe/Samara' }, + { label: 'Indian - Reunion', value: 'Indian/Reunion' }, + { label: 'Asia - Tbilisi', value: 'Asia/Tbilisi' }, + { label: 'Asia - Yerevan', value: 'Asia/Yerevan' }, + { label: 'Asia - Kabul', value: 'Asia/Kabul' }, + { label: 'Asia - Aqtau', value: 'Asia/Aqtau' }, + { label: 'Asia - Aqtobe', value: 'Asia/Aqtobe' }, + { label: 'Asia - Ashgabat', value: 'Asia/Ashgabat' }, + { label: 'Asia - Dushanbe', value: 'Asia/Dushanbe' }, + { label: 'Asia - Karachi', value: 'Asia/Karachi' }, + { label: 'Indian - Kerguelen', value: 'Indian/Kerguelen' }, + { label: 'Indian - Maldives', value: 'Indian/Maldives' }, + { label: 'Antarctica - Mawson', value: 'Antarctica/Mawson' }, + { label: 'Asia - Moscow+02 - Yekaterinburg', value: 'Asia/Yekaterinburg' }, + { label: 'Asia - Tashkent', value: 'Asia/Tashkent' }, + { label: 'Asia - Colombo', value: 'Asia/Colombo' }, + { label: 'Asia - India Standard Time', value: 'Asia/Kolkata' }, + { label: 'Asia - Kathmandu', value: 'Asia/Kathmandu' }, + { label: 'Asia - Almaty', value: 'Asia/Almaty' }, + { label: 'Asia - Bishkek', value: 'Asia/Bishkek' }, + { label: 'Indian - Chagos', value: 'Indian/Chagos' }, + { label: 'Asia - Dhaka', value: 'Asia/Dhaka' }, + { label: 'Asia - Moscow+03 - Omsk', value: 'Asia/Omsk' }, + { label: 'Asia - Thimphu', value: 'Asia/Thimphu' }, + { label: 'Antarctica - Vostok', value: 'Antarctica/Vostok' }, + { label: 'Indian - Cocos', value: 'Indian/Cocos' }, + { label: 'Asia - Rangoon', value: 'Asia/Yangon' }, + { label: 'Asia - Bangkok', value: 'Asia/Bangkok' }, + { label: 'Indian - Christmas', value: 'Indian/Christmas' }, + { label: 'Antarctica - Davis', value: 'Antarctica/Davis' }, + { label: 'Asia - Hanoi', value: 'Asia/Saigon' }, + { label: 'Asia - Hovd', value: 'Asia/Hovd' }, + { label: 'Asia - Jakarta', value: 'Asia/Jakarta' }, + { label: 'Asia - Moscow+04 - Krasnoyarsk', value: 'Asia/Krasnoyarsk' }, + { label: 'Asia - Brunei', value: 'Asia/Brunei' }, + { label: 'Asia - China Time - Beijing', value: 'Asia/Shanghai' }, + { label: 'Asia - Choibalsan', value: 'Asia/Choibalsan' }, + { label: 'Asia - Hong Kong', value: 'Asia/Hong_Kong' }, + { label: 'Asia - Kuala Lumpur', value: 'Asia/Kuala_Lumpur' }, + { label: 'Asia - Macau', value: 'Asia/Macau' }, + { label: 'Asia - Makassar', value: 'Asia/Makassar' }, + { label: 'Asia - Manila', value: 'Asia/Manila' }, + { label: 'Asia - Moscow+05 - Irkutsk', value: 'Asia/Irkutsk' }, + { label: 'Asia - Singapore', value: 'Asia/Singapore' }, + { label: 'Asia - Taipei', value: 'Asia/Taipei' }, + { label: 'Asia - Ulaanbaatar', value: 'Asia/Ulaanbaatar' }, + { label: 'Australia - Western Time - Perth', value: 'Australia/Perth' }, + { label: 'Asia - Pyongyang', value: 'Asia/Pyongyang' }, + { label: 'Asia - Dili', value: 'Asia/Dili' }, + { label: 'Asia - Jayapura', value: 'Asia/Jayapura' }, + { label: 'Asia - Moscow+06 - Yakutsk', value: 'Asia/Yakutsk' }, + { label: 'Pacific - Palau', value: 'Pacific/Palau' }, + { label: 'Asia - Seoul', value: 'Asia/Seoul' }, + { label: 'Asia - Tokyo', value: 'Asia/Tokyo' }, + { label: 'Australia - Central Time - Darwin', value: 'Australia/Darwin' }, + { label: 'Antarctica - Dumont D\'Urville', value: 'Antarctica/DumontDUrville' }, + { label: 'Australia - Eastern Time - Brisbane', value: 'Australia/Brisbane' }, + { label: 'Pacific - Guam', value: 'Pacific/Guam' }, + { label: 'Asia - Moscow+07 - Vladivostok', value: 'Asia/Vladivostok' }, + { label: 'Pacific - Port Moresby', value: 'Pacific/Port_Moresby' }, + { label: 'Pacific - Truk', value: 'Pacific/Chuuk' }, + { label: 'Australia - Central Time - Adelaide', value: 'Australia/Adelaide' }, + { label: 'Antarctica - Casey', value: 'Antarctica/Casey' }, + { label: 'Australia - Eastern Time - Hobart', value: 'Australia/Hobart' }, + { label: 'Australia - Eastern Time - Melbourne, Sydney', value: 'Australia/Sydney' }, + { label: 'Pacific - Efate', value: 'Pacific/Efate' }, + { label: 'Pacific - Guadalcanal', value: 'Pacific/Guadalcanal' }, + { label: 'Pacific - Kosrae', value: 'Pacific/Kosrae' }, + { label: 'Asia - Moscow+08 - Magadan', value: 'Asia/Magadan' }, + { label: 'Pacific - Norfolk', value: 'Pacific/Norfolk' }, + { label: 'Pacific - Noumea', value: 'Pacific/Noumea' }, + { label: 'Pacific - Ponape', value: 'Pacific/Pohnpei' }, + { label: 'Pacific - Funafuti', value: 'Pacific/Funafuti' }, + { label: 'Pacific - Kwajalein', value: 'Pacific/Kwajalein' }, + { label: 'Pacific - Majuro', value: 'Pacific/Majuro' }, + { label: 'Asia - Moscow+09 - Petropavlovsk-Kamchatskiy', value: 'Asia/Kamchatka' }, + { label: 'Pacific - Nauru', value: 'Pacific/Nauru' }, + { label: 'Pacific - Tarawa', value: 'Pacific/Tarawa' }, + { label: 'Pacific - Wake', value: 'Pacific/Wake' }, + { label: 'Pacific - Wallis', value: 'Pacific/Wallis' }, + { label: 'Pacific - Auckland', value: 'Pacific/Auckland' }, + { label: 'Pacific - Enderbury', value: 'Pacific/Enderbury' }, + { label: 'Pacific - Fakaofo', value: 'Pacific/Fakaofo' }, + { label: 'Pacific - Fiji', value: 'Pacific/Fiji' }, + { label: 'Pacific - Tongatapu', value: 'Pacific/Tongatapu' }, + { label: 'Pacific - Apia', value: 'Pacific/Apia' }, + { label: 'Pacific - Kiritimati', value: 'Pacific/Kiritimati' } ] diff --git a/client/shared/urls.js b/client/shared/urls.js new file mode 100644 index 00000000000..ba84dc2ffce --- /dev/null +++ b/client/shared/urls.js @@ -0,0 +1,18 @@ +/** + * DO NOT add the urls here directly. Edit the urls.json file instead. + * The urls are automatically precompiled into the variable below at build time. + */ +const urls = { /* __COMPILED_URLS__ */ } + +/** + * Get an URL and replace tokens with provided values. + * + * @param {string} key The key of the URL template to use. + * @param {Object} [tokens] An object of tokens to replace in the URL template. + * @returns {string} URL with tokens replaced with the provided values. + */ +export const getUrl = (key, tokens = {}) => { + if (!key) { throw new Error('Must provide a key for getUrl()') } + if (!urls[key]) { throw new Error('Invalid getUrl() key') } + return urls[key](tokens) +} diff --git a/client/shared/urls.json b/client/shared/urls.json new file mode 100644 index 00000000000..15410d68df1 --- /dev/null +++ b/client/shared/urls.json @@ -0,0 +1,10 @@ +{ + "bofDefinition": "https://www.ietf.org/how/bofs/", + "hackathonWiki": "https://wiki.ietf.org/meeting/{meetingNumber}/hackathon", + "meetingCalIcs": "/meeting/{meetingNumber}/agenda.ics", + "meetingDetails": "/meeting/{meetingNumber}/session/{eventAcronym}/", + "meetingMaterialsPdf": "/meeting/{meetingNumber}/agenda/{eventAcronym}-drafts.pdf", + "meetingMaterialsTar": "/meeting/{meetingNumber}/agenda/{eventAcronym}-drafts.tgz", + "meetingMeetechoRecordings": "https://www.meetecho.com/ietf{meetingNumber}/recordings#{eventAcronym}", + "meetingNotes": "https://notes.ietf.org/notes-ietf-{meetingNumber}-{eventAcronym}" +} diff --git a/client/shared/xslugify.js b/client/shared/xslugify.js index daf0bdf2ba4..e1ac556ddf0 100644 --- a/client/shared/xslugify.js +++ b/client/shared/xslugify.js @@ -1,5 +1,5 @@ import slugify from 'slugify' export default (str) => { - return slugify(str.replace('/', '-'), { lower: true }) + return slugify(str.replaceAll('/', '-').replaceAll(/['&]/g, ''), { lower: true }) } diff --git a/cypress.config.js b/cypress.config.js deleted file mode 100644 index 8ed6c2a4da5..00000000000 --- a/cypress.config.js +++ /dev/null @@ -1,19 +0,0 @@ -const { defineConfig } = require('cypress') - -module.exports = defineConfig({ - chromeWebSecurity: false, - component: { - devServer: { - framework: 'vue', - bundler: 'vite', - } - }, - e2e: { - baseUrl: 'http://localhost:8000', - setupNodeEvents(on, config) { - // implement node event listeners here - } - }, - viewportWidth: 1280, - viewportHeight: 800 -}) diff --git a/cypress/.gitignore b/cypress/.gitignore deleted file mode 100644 index c93c160370e..00000000000 --- a/cypress/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -screenshots -videos diff --git a/cypress/e2e/meeting/agenda.cy.js b/cypress/e2e/meeting/agenda.cy.js deleted file mode 100644 index b156490027d..00000000000 --- a/cypress/e2e/meeting/agenda.cy.js +++ /dev/null @@ -1,94 +0,0 @@ -describe('meeting agenda', () => { - before(() => { - cy.visit('/meeting/113/agenda/') - }) - - it('toggle customize panel when clicking on customize header bar', () => { - cy.get('#agenda-filter-customize').click() - cy.get('#customize').should('be.visible').and('have.class', 'show') - - cy.get('#agenda-filter-customize').click() - cy.get('#customize').should('not.be.visible').and('not.have.class', 'show') - }) - - it('customize panel should have at least 3 areas', () => { - cy.get('#agenda-filter-customize').click() - cy.get('.agenda-filter-areaselectbtn').should('have.length.at.least', 3) - }) - - it('customize panel should have at least 10 groups', () => { - cy.get('.agenda-filter-groupselectbtn').should('have.length.at.least', 10) - }) - - it('filtering the agenda should modify the URL', () => { - cy.get('.agenda-filter-groupselectbtn').take(5).as('selectedGroups').each(randomElement => { - cy.wrap(randomElement).click() - cy.wrap(randomElement).invoke('attr', 'data-filter-item').then(keyword => { - cy.url().should('contain', keyword) - }) - }) - - // Deselect everything - cy.get('@selectedGroups').click({ multiple: true }) - }) - - it('selecting an area should select all corresponding groups', () => { - cy.get('.agenda-filter-areaselectbtn').first().click().invoke('attr', 'data-filter-item').then(area => { - cy.url().should('contain', area) - - cy.get(`.agenda-filter-groupselectbtn[data-filter-keywords*="${area}"]`).each(group => { - cy.wrap(group).invoke('attr', 'data-filter-keywords').then(groupKeywords => { - // In case value is a comma-separated list of keywords... - if (groupKeywords.indexOf(',') < 0 || groupKeywords.split(',').includes(area)) { - cy.wrap(group).should('have.class', 'active') - } - }) - }) - }) - }) - - it('weekview iframe should load', () => { - cy.get('#weekview > iframe').its('0.contentDocument').should('exist') - cy.get('#weekview > iframe').its('0.contentDocument.readyState').should('equal', 'complete') - cy.get('#weekview > iframe').its('0.contentDocument.body', { - timeout: 30000 - }).should('not.be.empty') - }) -}) - -describe('meeting agenda weekview', () => { - before(() => { - cy.visit('/meeting/agenda/week-view.html') - }) - it('should have day headers', () => { - cy.get('.agenda-weekview-day').should('have.length.greaterThan', 0).and('be.visible') - }) - it('should have day columns', () => { - cy.get('.agenda-weekview-column').should('have.length.greaterThan', 0).and('be.visible') - }) - - it('should have the same number of day headers and columns', () => { - cy.get('.agenda-weekview-day').its('length').then(lgth => { - cy.get('.agenda-weekview-column').should('have.length', lgth) - }) - }) - - it('should have meetings', () => { - cy.get('.agenda-weekview-meeting').should('have.length.greaterThan', 0).and('be.visible') - }) - - it('meeting hover should cause expansion to column width', () => { - cy.get('.agenda-weekview-column:first').invoke('outerWidth').then(colWidth => { - /* eslint-disable cypress/no-unnecessary-waiting */ - cy.get('.agenda-weekview-meeting-mini').any(5).each(meeting => { - cy.wrap(meeting) - .wait(250) - .realHover({ position: 'center' }) - .invoke('outerWidth') - .should('be.closeTo', colWidth, 1) - // Move over to top left corner of the page to end the mouseover of the current meeting block - cy.get('.agenda-weekview-day:first').realHover().wait(250) - }) - }) - }) -}) diff --git a/cypress/e2e/nomcom/expertise.cy.js b/cypress/e2e/nomcom/expertise.cy.js deleted file mode 100644 index f6a075291fa..00000000000 --- a/cypress/e2e/nomcom/expertise.cy.js +++ /dev/null @@ -1,25 +0,0 @@ -describe('expertise', () => { - before(() => { - cy.visit('/nomcom/2021/expertise/') - }) - - it('expertises with expandable panels should expand', () => { - cy.get('.nomcom-req-positions-tabs > li > button').each($tab => { - cy.wrap($tab).click() - cy.wrap($tab).should('have.class', 'active') - - cy.wrap($tab).invoke('attr', 'data-bs-target').then($tabId => { - cy.get($tabId).should('have.class', 'tab-pane').and('have.class', 'active').and('be.visible') - - cy.get($tabId).then($tabContent => { - if ($tabContent.find('.generic_iesg_reqs_header').length) { - cy.wrap($tabContent).find('.generic_iesg_reqs_header').click() - cy.wrap($tabContent).find('.generic_iesg_reqs_header').invoke('attr', 'href').then($expandId => { - cy.get($expandId).should('be.visible') - }) - } - }) - }) - }) - }) -}) diff --git a/cypress/e2e/nomcom/questionnaires.cy.js b/cypress/e2e/nomcom/questionnaires.cy.js deleted file mode 100644 index 839b5d7d37c..00000000000 --- a/cypress/e2e/nomcom/questionnaires.cy.js +++ /dev/null @@ -1,16 +0,0 @@ -describe('questionnaires', () => { - before(() => { - cy.visit('/nomcom/2021/questionnaires/') - }) - - it('position tabs should display the appropriate panel on click', () => { - cy.get('.nomcom-questnr-positions-tabs > li > button').each($tab => { - cy.wrap($tab).click() - cy.wrap($tab).should('have.class', 'active') - - cy.wrap($tab).invoke('attr', 'data-bs-target').then($tabId => { - cy.get($tabId).should('have.class', 'tab-pane').and('have.class', 'active').and('be.visible') - }) - }) - }) -}) diff --git a/cypress/fixtures/users.json b/cypress/fixtures/users.json deleted file mode 100644 index 79b699aa772..00000000000 --- a/cypress/fixtures/users.json +++ /dev/null @@ -1,232 +0,0 @@ -[ - { - "id": 1, - "name": "Leanne Graham", - "username": "Bret", - "email": "Sincere@april.biz", - "address": { - "street": "Kulas Light", - "suite": "Apt. 556", - "city": "Gwenborough", - "zipcode": "92998-3874", - "geo": { - "lat": "-37.3159", - "lng": "81.1496" - } - }, - "phone": "1-770-736-8031 x56442", - "website": "hildegard.org", - "company": { - "name": "Romaguera-Crona", - "catchPhrase": "Multi-layered client-server neural-net", - "bs": "harness real-time e-markets" - } - }, - { - "id": 2, - "name": "Ervin Howell", - "username": "Antonette", - "email": "Shanna@melissa.tv", - "address": { - "street": "Victor Plains", - "suite": "Suite 879", - "city": "Wisokyburgh", - "zipcode": "90566-7771", - "geo": { - "lat": "-43.9509", - "lng": "-34.4618" - } - }, - "phone": "010-692-6593 x09125", - "website": "anastasia.net", - "company": { - "name": "Deckow-Crist", - "catchPhrase": "Proactive didactic contingency", - "bs": "synergize scalable supply-chains" - } - }, - { - "id": 3, - "name": "Clementine Bauch", - "username": "Samantha", - "email": "Nathan@yesenia.net", - "address": { - "street": "Douglas Extension", - "suite": "Suite 847", - "city": "McKenziehaven", - "zipcode": "59590-4157", - "geo": { - "lat": "-68.6102", - "lng": "-47.0653" - } - }, - "phone": "1-463-123-4447", - "website": "ramiro.info", - "company": { - "name": "Romaguera-Jacobson", - "catchPhrase": "Face to face bifurcated interface", - "bs": "e-enable strategic applications" - } - }, - { - "id": 4, - "name": "Patricia Lebsack", - "username": "Karianne", - "email": "Julianne.OConner@kory.org", - "address": { - "street": "Hoeger Mall", - "suite": "Apt. 692", - "city": "South Elvis", - "zipcode": "53919-4257", - "geo": { - "lat": "29.4572", - "lng": "-164.2990" - } - }, - "phone": "493-170-9623 x156", - "website": "kale.biz", - "company": { - "name": "Robel-Corkery", - "catchPhrase": "Multi-tiered zero tolerance productivity", - "bs": "transition cutting-edge web services" - } - }, - { - "id": 5, - "name": "Chelsey Dietrich", - "username": "Kamren", - "email": "Lucio_Hettinger@annie.ca", - "address": { - "street": "Skiles Walks", - "suite": "Suite 351", - "city": "Roscoeview", - "zipcode": "33263", - "geo": { - "lat": "-31.8129", - "lng": "62.5342" - } - }, - "phone": "(254)954-1289", - "website": "demarco.info", - "company": { - "name": "Keebler LLC", - "catchPhrase": "User-centric fault-tolerant solution", - "bs": "revolutionize end-to-end systems" - } - }, - { - "id": 6, - "name": "Mrs. Dennis Schulist", - "username": "Leopoldo_Corkery", - "email": "Karley_Dach@jasper.info", - "address": { - "street": "Norberto Crossing", - "suite": "Apt. 950", - "city": "South Christy", - "zipcode": "23505-1337", - "geo": { - "lat": "-71.4197", - "lng": "71.7478" - } - }, - "phone": "1-477-935-8478 x6430", - "website": "ola.org", - "company": { - "name": "Considine-Lockman", - "catchPhrase": "Synchronised bottom-line interface", - "bs": "e-enable innovative applications" - } - }, - { - "id": 7, - "name": "Kurtis Weissnat", - "username": "Elwyn.Skiles", - "email": "Telly.Hoeger@billy.biz", - "address": { - "street": "Rex Trail", - "suite": "Suite 280", - "city": "Howemouth", - "zipcode": "58804-1099", - "geo": { - "lat": "24.8918", - "lng": "21.8984" - } - }, - "phone": "210.067.6132", - "website": "elvis.io", - "company": { - "name": "Johns Group", - "catchPhrase": "Configurable multimedia task-force", - "bs": "generate enterprise e-tailers" - } - }, - { - "id": 8, - "name": "Nicholas Runolfsdottir V", - "username": "Maxime_Nienow", - "email": "Sherwood@rosamond.me", - "address": { - "street": "Ellsworth Summit", - "suite": "Suite 729", - "city": "Aliyaview", - "zipcode": "45169", - "geo": { - "lat": "-14.3990", - "lng": "-120.7677" - } - }, - "phone": "586.493.6943 x140", - "website": "jacynthe.com", - "company": { - "name": "Abernathy Group", - "catchPhrase": "Implemented secondary concept", - "bs": "e-enable extensible e-tailers" - } - }, - { - "id": 9, - "name": "Glenna Reichert", - "username": "Delphine", - "email": "Chaim_McDermott@dana.io", - "address": { - "street": "Dayna Park", - "suite": "Suite 449", - "city": "Bartholomebury", - "zipcode": "76495-3109", - "geo": { - "lat": "24.6463", - "lng": "-168.8889" - } - }, - "phone": "(775)976-6794 x41206", - "website": "conrad.com", - "company": { - "name": "Yost and Sons", - "catchPhrase": "Switchable contextually-based project", - "bs": "aggregate real-time technologies" - } - }, - { - "id": 10, - "name": "Clementina DuBuque", - "username": "Moriah.Stanton", - "email": "Rey.Padberg@karina.biz", - "address": { - "street": "Kattie Turnpike", - "suite": "Suite 198", - "city": "Lebsackbury", - "zipcode": "31428-2261", - "geo": { - "lat": "-38.2386", - "lng": "57.2232" - } - }, - "phone": "024-648-3804", - "website": "ambrose.net", - "company": { - "name": "Hoeger LLC", - "catchPhrase": "Centralized empowering task-force", - "bs": "target end-to-end models" - } - } -] \ No newline at end of file diff --git a/cypress/plugins/index.js b/cypress/plugins/index.js deleted file mode 100644 index 6b495580a01..00000000000 --- a/cypress/plugins/index.js +++ /dev/null @@ -1,21 +0,0 @@ -// *********************************************************** -// This example plugins/index.js can be used to load plugins -// -// You can change the location of this file or turn off loading -// the plugins file with the 'pluginsFile' configuration option. -// -// You can read more here: -// https://on.cypress.io/plugins-guide -// *********************************************************** - -// This function is called when a project is opened or re-opened (e.g. due to -// the project's config changing) - -/** - * @type {Cypress.PluginConfig} - */ -// eslint-disable-next-line no-unused-vars -module.exports = (on, config) => { - // `on` is used to hook into various events Cypress emits - // `config` is the resolved Cypress config -} diff --git a/cypress/support/commands.js b/cypress/support/commands.js deleted file mode 100644 index 8a17b4e0099..00000000000 --- a/cypress/support/commands.js +++ /dev/null @@ -1,43 +0,0 @@ -// *********************************************** -// This example commands.js shows you how to -// create various custom commands and overwrite -// existing commands. -// -// For more comprehensive examples of custom -// commands please read more here: -// https://on.cypress.io/custom-commands -// *********************************************** -// -// -// -- This is a parent command -- -// Cypress.Commands.add('login', (email, password) => { ... }) -// -// -// -- This is a child command -- -// Cypress.Commands.add('drag', { prevSubject: 'element'}, (subject, options) => { ... }) -// -// -// -- This is a dual command -- -// Cypress.Commands.add('dismiss', { prevSubject: 'optional'}, (subject, options) => { ... }) -// -// -// -- This will overwrite an existing command -- -// Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... }) - -Cypress.Commands.add('any', { prevSubject: 'element' }, (subject, size = 1) => { - cy.wrap(subject).then(elementList => { - elementList = (elementList.jquery) ? elementList.get() : elementList - elementList = Cypress._.sampleSize(elementList, size) - elementList = (elementList.length > 1) ? elementList : elementList[0] - cy.wrap(elementList) - }) -}) - -Cypress.Commands.add('take', { prevSubject: 'element' }, (subject, size = 1) => { - cy.wrap(subject).then(elementList => { - elementList = (elementList.jquery) ? elementList.get() : elementList - elementList = Cypress._.take(elementList, size) - elementList = (elementList.length > 1) ? elementList : elementList[0] - cy.wrap(elementList) - }) -}) diff --git a/cypress/support/component-index.html b/cypress/support/component-index.html deleted file mode 100644 index ac6e79fd83d..00000000000 --- a/cypress/support/component-index.html +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - Components App - - -
- - \ No newline at end of file diff --git a/cypress/support/component.js b/cypress/support/component.js deleted file mode 100644 index b091808fa5d..00000000000 --- a/cypress/support/component.js +++ /dev/null @@ -1,27 +0,0 @@ -// *********************************************************** -// This example support/component.js is processed and -// loaded automatically before your test files. -// -// This is a great place to put global configuration and -// behavior that modifies Cypress. -// -// You can change the location of this file or turn off -// automatically serving support files with the -// 'supportFile' configuration option. -// -// You can read more here: -// https://on.cypress.io/configuration -// *********************************************************** - -// Import commands.js using ES2015 syntax: -import './commands' - -// Alternatively you can use CommonJS syntax: -// require('./commands') - -import { mount } from 'cypress/vue' - -Cypress.Commands.add('mount', mount) - -// Example use: -// cy.mount(MyComponent) \ No newline at end of file diff --git a/cypress/support/e2e.js b/cypress/support/e2e.js deleted file mode 100644 index f28c4dad088..00000000000 --- a/cypress/support/e2e.js +++ /dev/null @@ -1,22 +0,0 @@ -// *********************************************************** -// This example support/e2e.js is processed and -// loaded automatically before your test files. -// -// This is a great place to put global configuration and -// behavior that modifies Cypress. -// -// You can change the location of this file or turn off -// automatically serving support files with the -// 'supportFile' configuration option. -// -// You can read more here: -// https://on.cypress.io/configuration -// *********************************************************** - -// Import commands.js using ES2015 syntax: -import './commands' - -// Alternatively you can use CommonJS syntax: -// require('./commands') - -import 'cypress-real-events/support' diff --git a/cypress/support/index.js b/cypress/support/index.js deleted file mode 100644 index 33bd59c13ad..00000000000 --- a/cypress/support/index.js +++ /dev/null @@ -1,22 +0,0 @@ -// *********************************************************** -// This example support/index.js is processed and -// loaded automatically before your test files. -// -// This is a great place to put global configuration and -// behavior that modifies Cypress. -// -// You can change the location of this file or turn off -// automatically serving support files with the -// 'supportFile' configuration option. -// -// You can read more here: -// https://on.cypress.io/configuration -// *********************************************************** - -// Import commands.js using ES2015 syntax: -import './commands' - -// Alternatively you can use CommonJS syntax: -// require('./commands') - -import 'cypress-real-events/support' diff --git a/debug.py b/debug.py index bf34367cceb..4f0d64bae2b 100644 --- a/debug.py +++ b/debug.py @@ -3,15 +3,7 @@ import sys import time as timeutils import inspect -from typing import Callable -try: - import syslog - logger = syslog.syslog # type: Callable -except ImportError: # import syslog will fail on Windows boxes - import logging - logging.basicConfig(filename='tracker.log',level=logging.INFO) - logger = logging.info try: from pprint import pformat @@ -55,7 +47,7 @@ def fix(s,n=64): if len(s) > n+3: s = s[:n]+"..." return s - def wrap(fn, *params,**kwargs): + def wrap(*params,**kwargs): call = wrap.callcount = wrap.callcount + 1 indent = ' ' * _report_indent[0] @@ -81,8 +73,8 @@ def wrap(fn, *params,**kwargs): return ret wrap.callcount = 0 if debug: - from decorator import decorator - return decorator(wrap, fn) + from functools import update_wrapper + return update_wrapper(wrap, fn) else: return fn @@ -119,7 +111,7 @@ def clock(s): def time(fn): """Decorator to print timing information about a function call. """ - def wrap(fn, *params,**kwargs): + def wrap(*params,**kwargs): indent = ' ' * _report_indent[0] fc = "%s.%s()" % (fn.__module__, fn.__name__,) @@ -132,8 +124,8 @@ def wrap(fn, *params,**kwargs): return ret wrap.callcount = 0 if debug: - from decorator import decorator - return decorator(wrap, fn) + from functools import update_wrapper + return update_wrapper(wrap, fn) else: return fn @@ -155,13 +147,6 @@ def showpos(name): indent = ' ' * (_report_indent[0]) sys.stderr.write("%s%s:%s: %s: '%s'\n" % (indent, fn, line, name, value)) -def log(name): - if debug: - frame = inspect.stack()[1][0] - value = eval(name, frame.f_globals, frame.f_locals) - indent = ' ' * (_report_indent[0]) - logger("%s%s: %s" % (indent, name, value)) - def pprint(name): if debug: frame = inspect.stack()[1][0] @@ -190,7 +175,7 @@ def type(name): value = eval(name, frame.f_globals, frame.f_locals) indent = ' ' * (_report_indent[0]) sys.stderr.write("%s%s: %s\n" % (indent, name, value)) - + def say(s): if debug: indent = ' ' * (_report_indent[0]) @@ -205,11 +190,11 @@ def wrapper(*args, **kwargs): prof.dump_stats(datafn) return retval if debug: - from decorator import decorator - return decorator(wrapper, fn) + from functools import update_wrapper + return update_wrapper(wrapper, fn) else: return fn - + def traceback(levels=None): if debug: indent = ' ' * (_report_indent[0]) diff --git a/dev/INSTALL b/dev/INSTALL deleted file mode 100644 index 132e607f528..00000000000 --- a/dev/INSTALL +++ /dev/null @@ -1,102 +0,0 @@ -============================================================================== - IETF Datatracker -============================================================================== - ------------------------------------------------------------------------------- - Installation Instructions ------------------------------------------------------------------------------- - -General Instructions for Deployment of a New Release -==================================================== - - 1. Make a directory to hold the new release:: - sudo su - -s /bin/bash wwwrun - mkdir /a/www/ietf-datatracker/${releasenumber} - cd /a/www/ietf-datatracker/${releasenumber} - - 2. Fetch the release tarball from github - (see https://github.com/ietf-tools/datatracker/releases):: - - wget https://github.com/ietf-tools/datatracker/releases/download/${releasenumber}/release.tar.gz - tar xzvf release.tar.gz - - 3. Copy ietf/settings_local.py from previous release:: - - cp ../web/ietf/settings_local.py ietf/ - - 4. Setup a new virtual environment and install requirements:: - - python3.9 -mvenv env - source env/bin/activate - pip install -r requirements.txt - - 5. Move static files into place for CDN (/a/www/www6s/lib/dt): - - ietf/manage.py collectstatic - - 6. Run system checks (which patches the just installed modules):: - - ietf/manage.py check - - 7. Run migrations: - - ietf/manage.py migrate - - Take note if any migrations were executed. - - 8. Back out one directory level, then re-point the 'web' symlink:: - - cd .. - rm ./web; ln -s ${releasenumber} web - - 9. Reload the datatracker service (it is no longer necessary to restart apache) :: - - exit # or CTRL-D, back to root level shell - systemctl restart datatracker - - 10. Verify operation: - - http://datatracker.ietf.org/ - - 11. If install failed and there were no migrations at step 7, revert web symlink and repeat the restart in step 9. - If there were migrations at step 7, they will need to be reversed before the restart at step 9. If it's not obvious - what to do to reverse the migrations, contact the dev team. - - -Patching a Production Release -============================= - -Sometimes it can prove necessary to patch an existing release. -The following process should be used: - - 1. Code and test the patch on an copy of the release with any - previously applied patches put in place. - - 2. Produce a patch file, named with date and subject:: - - $ git diff > 2013-03-25-ballot-calculation.patch - - 3. Move the patch file to the production server, and place it in - '/a/www/ietf-datatracker/patches/' - - 4. Make a recursive copy of the production code to a new directory, named with a patch number. - - /a/www/ietf-datatracker $ rsync -a web/ ${releasenumber}.p1/ - - 5. Apply the patch:: - - /a/www/ietf-datatracker $ cd ${releasenumber}.p1/ - /a/www/ietf-datatracker/${releasnumber}.p1 $ patch -p1 \ - < ../patches/2013-03-25-ballot-calculation.patch - - This must not produce any messages about failing to apply any chunks; - if it does, go back to 1. and figure out why. - - 6. Edit ``.../ietf/__init__.py`` in the new patched release to indicate the patch - version in the ``__patch__`` string. - - 7. Change the 'web' symlink, reload etc. as described in - `General Instructions for Deployment of a New Release`_. - - - diff --git a/dev/build/Dockerfile b/dev/build/Dockerfile new file mode 100644 index 00000000000..d80aceaffb5 --- /dev/null +++ b/dev/build/Dockerfile @@ -0,0 +1,41 @@ +FROM ghcr.io/ietf-tools/datatracker-app-base:20260804T1752 +LABEL maintainer="IETF Tools Team " + +ENV DEBIAN_FRONTEND=noninteractive + +# uid 498 = wwwrun and gid 496 = www on ietfa +RUN groupadd -g 1000 datatracker && \ + useradd -c "Datatracker User" -u 1000 -g datatracker -m -s /bin/false datatracker + +RUN apt-get purge -y imagemagick imagemagick-6-common + +# Install libreoffice (needed via PPT2PDF_COMMAND) +RUN apt-get update && \ + apt-get -qy install libreoffice-nogui + +COPY . . +COPY ./dev/build/start.sh ./start.sh +COPY ./dev/build/datatracker-start.sh ./datatracker-start.sh +COPY ./dev/build/migration-start.sh ./migration-start.sh +COPY ./dev/build/celery-start.sh ./celery-start.sh +COPY ./dev/build/gunicorn.conf.py ./gunicorn.conf.py + +RUN pip3 --disable-pip-version-check --no-cache-dir install -r requirements.txt && \ + echo '# empty' > ietf/settings_local.py && \ + ietf/manage.py patch_libraries && \ + rm -f ietf/settings_local.py + +RUN chmod +x start.sh && \ + chmod +x datatracker-start.sh && \ + chmod +x migration-start.sh && \ + chmod +x celery-start.sh && \ + chmod +x docker/scripts/app-create-dirs.sh && \ + sh ./docker/scripts/app-create-dirs.sh + +RUN mkdir -p /a + +VOLUME [ "/a" ] + +EXPOSE 8000 + +CMD ["./start.sh"] diff --git a/dev/build/TARGET_BASE b/dev/build/TARGET_BASE new file mode 100644 index 00000000000..d40bd9e9299 --- /dev/null +++ b/dev/build/TARGET_BASE @@ -0,0 +1 @@ +20260804T1752 diff --git a/dev/build/celery-start.sh b/dev/build/celery-start.sh new file mode 100644 index 00000000000..69dcd7bbda8 --- /dev/null +++ b/dev/build/celery-start.sh @@ -0,0 +1,52 @@ +#!/bin/bash -e +# +# Run a celery worker +# +echo "Running Datatracker checks..." +./ietf/manage.py check + +# Check whether the blobdb database exists - inspectdb will return a false +# status if not. +if ietf/manage.py inspectdb --database blobdb > /dev/null 2>&1; then + HAVE_BLOBDB="yes" +fi + +migrations_applied_for () { + local DATABASE=${1:-default} + ietf/manage.py migrate --check --database "$DATABASE" +} + +migrations_all_applied () { + if [[ "$HAVE_BLOBDB" == "yes" ]]; then + migrations_applied_for default && migrations_applied_for blobdb + else + migrations_applied_for default + fi +} + +if ! migrations_all_applied; then + echo "Unapplied migrations found, waiting to start..." + sleep 5 + while ! migrations_all_applied ; do + echo "... still waiting for migrations..." + sleep 5 + done +fi + +echo "Starting Celery..." + +cleanup () { + # Cleanly terminate the celery app by sending it a TERM, then waiting for it to exit. + if [[ -n "${celery_pid}" ]]; then + echo "Gracefully terminating celery worker. This may take a few minutes if tasks are in progress..." + kill -TERM "${celery_pid}" + wait "${celery_pid}" + fi +} + +trap 'trap "" TERM; cleanup' TERM + +# start celery in the background so we can trap the TERM signal +celery "$@" & +celery_pid=$! +wait "${celery_pid}" diff --git a/dev/build/collectstatics.sh b/dev/build/collectstatics.sh new file mode 100644 index 00000000000..44f1c608a93 --- /dev/null +++ b/dev/build/collectstatics.sh @@ -0,0 +1,13 @@ +#!/bin/bash + +# Copy temp local settings +cp dev/build/settings_local_collectstatics.py ietf/settings_local.py + +# Install Python dependencies +pip --disable-pip-version-check --no-cache-dir install -r requirements.txt + +# Collect statics +ietf/manage.py collectstatic + +# Delete temp local settings +rm ietf/settings_local.py \ No newline at end of file diff --git a/dev/build/datatracker-start.sh b/dev/build/datatracker-start.sh new file mode 100644 index 00000000000..012a563412e --- /dev/null +++ b/dev/build/datatracker-start.sh @@ -0,0 +1,50 @@ +#!/bin/bash -e + +echo "Running Datatracker checks..." +./ietf/manage.py check + +# Check whether the blobdb database exists - inspectdb will return a false +# status if not. +if ietf/manage.py inspectdb --database blobdb > /dev/null 2>&1; then + HAVE_BLOBDB="yes" +fi + +migrations_applied_for () { + local DATABASE=${1:-default} + ietf/manage.py migrate --check --database "$DATABASE" +} + +migrations_all_applied () { + if [[ "$HAVE_BLOBDB" == "yes" ]]; then + migrations_applied_for default && migrations_applied_for blobdb + else + migrations_applied_for default + fi +} + +if ! migrations_all_applied; then + echo "Unapplied migrations found, waiting to start..." + sleep 5 + while ! migrations_all_applied ; do + echo "... still waiting for migrations..." + sleep 5 + done +fi + +echo "Starting Datatracker..." + +# trap TERM and shut down gunicorn +cleanup () { + if [[ -n "${gunicorn_pid}" ]]; then + echo "Terminating gunicorn..." + kill -TERM "${gunicorn_pid}" + wait "${gunicorn_pid}" + fi +} + +trap 'trap "" TERM; cleanup' TERM + +# start gunicorn in the background so we can trap the TERM signal +gunicorn -c /workspace/gunicorn.conf.py ${DATATRACKER_GUNICORN_EXTRA_ARGS} ietf.wsgi:application & +gunicorn_pid=$! +wait "${gunicorn_pid}" diff --git a/dev/deploy/exclude-patterns.txt b/dev/build/exclude-patterns.txt similarity index 100% rename from dev/deploy/exclude-patterns.txt rename to dev/build/exclude-patterns.txt diff --git a/dev/build/gunicorn.conf.py b/dev/build/gunicorn.conf.py new file mode 100644 index 00000000000..03e81eac5e2 --- /dev/null +++ b/dev/build/gunicorn.conf.py @@ -0,0 +1,181 @@ +# Copyright The IETF Trust 2024-2026, All Rights Reserved + +import os +import ietf +from opentelemetry import trace +from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter +from opentelemetry.sdk.resources import Resource +from opentelemetry.sdk.trace import TracerProvider +from opentelemetry.sdk.trace.export import BatchSpanProcessor +from opentelemetry.instrumentation.django import DjangoInstrumentor +from opentelemetry.instrumentation.psycopg2 import Psycopg2Instrumentor +from opentelemetry.instrumentation.pymemcache import PymemcacheInstrumentor +from opentelemetry.instrumentation.requests import RequestsInstrumentor + +# Bind all ipv4 interfaces (nginx uses loopback, but k8s health checks don't) +_BIND_PORT = os.environ.get("DATATRACKER_GUNICORN_BIND_PORT", "8000") +bind = [f"0.0.0.0:{_BIND_PORT}"] + +# Disable control socket +control_socket_disable = True + +# Settings configurable via environment +workers = int(os.environ.get("DATATRACKER_GUNICORN_WORKERS", "9")) +max_requests = int(os.environ.get("DATATRACKER_GUNICORN_MAX_REQUESTS", "32768")) +timeout = int(os.environ.get("DATATRACKER_GUNICORN_TIMEOUT", "180")) +loglevel = os.environ.get("DATATRACKER_GUNICORN_LOG_LEVEL", "info") + +# Logging / stdout capture +capture_output = True +accesslog = "-" + +# Configure security scheme headers for forwarded requests. Cloudflare sets X-Forwarded-Proto +# for us. Don't trust any of the other similar headers. Only trust the header if it's coming +# from localhost, as all legitimate traffic will reach gunicorn via co-located nginx. +secure_scheme_headers = {"X-FORWARDED-PROTO": "https"} +forwarded_allow_ips = "127.0.0.1, ::1" # this is the default + +# Log as JSON on stdout (to distinguish from Django's logs on stderr) +# +# This is applied as an update to gunicorn's glogging.CONFIG_DEFAULTS. +logconfig_dict = { + "version": 1, + "disable_existing_loggers": False, + "root": {"level": "INFO", "handlers": ["console"]}, + "loggers": { + "gunicorn.error": { + "level": "INFO", + "handlers": ["console"], + "propagate": False, + "qualname": "gunicorn.error", + }, + "gunicorn.access": { + "level": "INFO", + "handlers": ["access_console"], + "propagate": False, + "qualname": "gunicorn.access", + }, + }, + "handlers": { + "console": { + "class": "logging.StreamHandler", + "formatter": "json", + "stream": "ext://sys.stdout", + }, + "access_console": { + "class": "logging.StreamHandler", + "formatter": "access_json", + "stream": "ext://sys.stdout", + }, + }, + "formatters": { + "json": { + "class": "ietf.utils.jsonlogger.DatatrackerJsonFormatter", + "style": "{", + "format": "{asctime}{levelname}{message}{name}{process}", + }, + "access_json": { + "class": "ietf.utils.jsonlogger.GunicornRequestJsonFormatter", + "style": "{", + "format": "{asctime}{levelname}{message}{name}{process}", + }, + }, +} + +# Track in-flight requests and emit a list of what was happeningwhen a worker is terminated. +# For the default sync worker, there will only be one request per PID, but allow for the +# possibility of multiple requests in case we switch to a different worker class. +# +# This dict is only visible within a single worker, but key by pid to guarantee no conflicts. +# +# Use a list rather than a set to allow for the possibility of overlapping identical requests. +in_flight_by_pid: dict[str, list[str]] = {} # pid -> list of in-flight requests + + +def _describe_request(req): + """Generate a consistent description of a request + + The return value is used identify in-flight requests, so it must not vary between the + start and end of handling a request. E.g., do not include a timestamp. + """ + client_ip = "-" + asn = "-" + cf_ray = "-" + for header, value in req.headers: + header = header.lower() + if header == "cf-connecting-ip": + client_ip = value + elif header == "x-ip-src-asnum": + asn = value + elif header == "cf-ray": + cf_ray = value + if req.query: + path = f"{req.path}?{req.query}" + else: + path = req.path + return f"{req.method} {path} (client_ip={client_ip}, asn={asn}, cf_ray={cf_ray})" + + +def pre_request(worker, req): + """Log the start of a request and add it to the in-flight list""" + request_description = _describe_request(req) + worker.log.info(f"gunicorn starting to process {request_description}") + in_flight = in_flight_by_pid.setdefault(worker.pid, []) + in_flight.append(request_description) + + +def worker_abort(worker): + """Emit an error log if any requests were in-flight""" + in_flight = in_flight_by_pid.get(worker.pid, []) + if len(in_flight) > 0: + worker.log.error( + f"Aborted worker {worker.pid} with in-flight requests: {', '.join(in_flight)}" + ) + + +def worker_int(worker): + """Emit an error log if any requests were in-flight""" + in_flight = in_flight_by_pid.get(worker.pid, []) + if len(in_flight) > 0: + worker.log.error( + f"Interrupted worker {worker.pid} with in-flight requests: {', '.join(in_flight)}" + ) + + +def post_request(worker, req, environ, resp): + """Remove request from in-flight list when we finish handling it""" + request_description = _describe_request(req) + in_flight = in_flight_by_pid.get(worker.pid, []) + if request_description in in_flight: + in_flight.remove(request_description) + +def post_fork(server, worker): + server.log.info("Worker spawned (pid: %s)", worker.pid) + + # Setting DATATRACKER_OPENTELEMETRY_ENABLE=all in the environment will enable all + # opentelemetry instrumentations. Individual instrumentations can be selected by + # using a space-separated list. See the code below for available instrumentations. + telemetry_env = os.environ.get("DATATRACKER_OPENTELEMETRY_ENABLE", "").strip() + if telemetry_env != "": + enabled_telemetry = [tok.strip().lower() for tok in telemetry_env.split()] + resource = Resource.create(attributes={ + "service.name": "datatracker", + "service.version": ietf.__version__, + "service.instance.id": worker.pid, + "service.namespace": "datatracker", + "deployment.environment.name": os.environ.get("DATATRACKER_SERVICE_ENV", "dev") + }) + trace.set_tracer_provider(TracerProvider(resource=resource)) + otlp_exporter = OTLPSpanExporter(endpoint="https://heimdall-otlp.ietf.org/v1/traces") + + trace.get_tracer_provider().add_span_processor(BatchSpanProcessor(otlp_exporter)) + + # Instrumentations + if "all" in enabled_telemetry or "django" in enabled_telemetry: + DjangoInstrumentor().instrument() + if "all" in enabled_telemetry or "psycopg2" in enabled_telemetry: + Psycopg2Instrumentor().instrument() + if "all" in enabled_telemetry or "pymemcache" in enabled_telemetry: + PymemcacheInstrumentor().instrument() + if "all" in enabled_telemetry or "requests" in enabled_telemetry: + RequestsInstrumentor().instrument() diff --git a/dev/build/migration-start.sh b/dev/build/migration-start.sh new file mode 100644 index 00000000000..578daf5ceff --- /dev/null +++ b/dev/build/migration-start.sh @@ -0,0 +1,13 @@ +#!/bin/bash -e + +echo "Running Datatracker migrations..." +./ietf/manage.py migrate --settings=settings_local + +# Check whether the blobdb database exists - inspectdb will return a false +# status if not. +if ./ietf/manage.py inspectdb --database blobdb > /dev/null 2>&1; then + echo "Running Blobdb migrations ..." + ./ietf/manage.py migrate --settings=settings_local --database=blobdb +fi + +echo "Done!" diff --git a/dev/build/settings_local_collectstatics.py b/dev/build/settings_local_collectstatics.py new file mode 100644 index 00000000000..ccb4b33979e --- /dev/null +++ b/dev/build/settings_local_collectstatics.py @@ -0,0 +1,8 @@ +# Copyright The IETF Trust 2007-2019, All Rights Reserved +# -*- coding: utf-8 -*- + +from ietf import __version__ +from ietf.settings import * # pyflakes:ignore + +STATIC_URL = "https://static.ietf.org/dt/%s/"%__version__ +STATIC_ROOT = os.path.abspath(BASE_DIR + "/../static/") diff --git a/dev/build/start.sh b/dev/build/start.sh new file mode 100644 index 00000000000..3b036370685 --- /dev/null +++ b/dev/build/start.sh @@ -0,0 +1,29 @@ +#!/bin/bash +# +# Environment config: +# +# CONTAINER_ROLE - datatracker, celery, beat, migrations, or replicator (defaults to datatracker) +# +case "${CONTAINER_ROLE:-datatracker}" in + auth) + exec ./datatracker-start.sh + ;; + beat) + exec ./celery-start.sh --app=ietf beat + ;; + celery) + exec ./celery-start.sh --app=ietf worker + ;; + datatracker) + exec ./datatracker-start.sh + ;; + migrations) + exec ./migration-start.sh + ;; + replicator) + exec ./celery-start.sh --app=ietf worker --queues=blobdb --concurrency=1 + ;; + *) + echo "Unknown role '${CONTAINER_ROLE}'" + exit 255 +esac diff --git a/ietf/ietfauth/management/__init__.py b/dev/celery/Dockerfile similarity index 100% rename from ietf/ietfauth/management/__init__.py rename to dev/celery/Dockerfile diff --git a/dev/codecov.yml b/dev/codecov.yml index 7e6c6e20094..7ec1def6c5f 100644 --- a/dev/codecov.yml +++ b/dev/codecov.yml @@ -4,3 +4,8 @@ coverage: default: target: auto threshold: 1% + patch: + default: + informational: true +github_checks: + annotations: false diff --git a/dev/coverage-action/.eslintrc b/dev/coverage-action/.eslintrc deleted file mode 100644 index 7c7b9ae4c12..00000000000 --- a/dev/coverage-action/.eslintrc +++ /dev/null @@ -1,4 +0,0 @@ -{ - "root": true, - "extends": "standard" -} diff --git a/dev/coverage-action/.npmrc b/dev/coverage-action/.npmrc index 6d1bedf02a5..fcbbb678280 100644 --- a/dev/coverage-action/.npmrc +++ b/dev/coverage-action/.npmrc @@ -1,2 +1,5 @@ +audit = false +fund = false save-exact = true save-prefix = "" +update-notifier = false diff --git a/dev/coverage-action/action.yml b/dev/coverage-action/action.yml index b8d732a5344..60c8de2d92d 100644 --- a/dev/coverage-action/action.yml +++ b/dev/coverage-action/action.yml @@ -35,7 +35,7 @@ outputs: changelog: description: Changelog with headers prepended and coverage stats + chart appended runs: - using: 'node16' + using: 'node20' main: 'index.js' branding: icon: layers diff --git a/dev/coverage-action/index.js b/dev/coverage-action/index.js index 57249bfdb17..f1821e24a47 100644 --- a/dev/coverage-action/index.js +++ b/dev/coverage-action/index.js @@ -1,24 +1,19 @@ -const github = require('@actions/github') -const core = require('@actions/core') -const orderBy = require('lodash/orderBy') -const find = require('lodash/find') -const round = require('lodash/round') -const fs = require('fs/promises') -const { DateTime } = require('luxon') -const isPlainObject = require('lodash/isPlainObject') +import github from '@actions/github' +import core from '@actions/core' +import { orderBy } from 'es-toolkit/array' +import { round } from 'es-toolkit/compat' +import fs from 'fs/promises' const dec = new TextDecoder() -async function main () { +async function main() { const token = core.getInput('token') - const tokenCommon = core.getInput('tokenCommon') const inputCovPath = core.getInput('coverageResultsPath') // 'data/coverage-raw.json' const outputCovPath = core.getInput('coverageResultsPath') // 'data/coverage.json' const outputHistPath = core.getInput('histCoveragePath') // 'data/historical-coverage.json' const relVersionRaw = core.getInput('version') // 'v7.47.0' const relVersion = relVersionRaw.indexOf('v') === 0 ? relVersionRaw.substring(1) : relVersionRaw const gh = github.getOctokit(token) - const ghCommon = github.getOctokit(tokenCommon) const owner = github.context.repo.owner // 'ietf-tools' const repo = github.context.repo.repo // 'datatracker' const sender = github.context.payload.sender.login // 'rjsparks' @@ -37,10 +32,18 @@ async function main () { // -> Fix coverage results versioning console.info(`Writing ${relVersion} normalized coverage.json file...`) - fs.writeFile(outputCovPath, JSON.stringify({ - [relVersion]: covLatest.latest, - version: relVersion - }, null, 2), 'utf8') + fs.writeFile( + outputCovPath, + JSON.stringify( + { + [relVersion]: covLatest.latest, + version: relVersion + }, + null, + 2 + ), + 'utf8' + ) // -> Fetch existing releases const releases = [] @@ -66,9 +69,11 @@ async function main () { // -> Fetch latest historical coverage let covData = null for (const rel of orderBy(releases, ['created_at'], ['desc'])) { - if (rel.draft) { continue } + if (rel.draft) { + continue + } - const covAsset = find(rel.assets, ['name', 'historical-coverage.json']) + const covAsset = rel.assets.find((a) => a.name === 'historical-coverage.json') if (covAsset) { console.info(`Fetching latest historical-coverage.json from release ${rel.name}...`) const covRaw = await gh.request('GET /repos/{owner}/{repo}/releases/assets/{asset_id}', { @@ -97,9 +102,11 @@ async function main () { } // -> Find matching release version - const newRelease = find(releases, ['name', relVersionRaw]) + const newRelease = releases.find((r) => r.name === relVersionRaw) if (!newRelease) { - console.warn(`Could not find a release matching ${relVersionRaw}... Skipping coverage chart generation...`) + console.warn( + `Could not find a release matching ${relVersionRaw}... Skipping coverage chart generation...` + ) return } @@ -115,139 +122,6 @@ async function main () { chartsDirListing.push(...respDir.data) } - // -> Coverage Chart - if (chartsDirListing.some(c => c.name === `${newRelease.id}.svg`)) { - console.info(`Chart SVG already exists for ${newRelease.name}, skipping...`) - } else { - console.info(`Generating chart SVG for ${newRelease.name}...`) - - const { ChartJSNodeCanvas } = require('chartjs-node-canvas') - const chartJSNodeCanvas = new ChartJSNodeCanvas({ type: 'svg', width: 850, height: 300, backgroundColour: '#FFFFFF' }) - - // -> Reorder versions - const versions = [] - for (const [key, value] of Object.entries(covData)) { - if (isPlainObject(value)) { - const vRel = find(releases, r => r.tag_name === key || r.tag_name === `v${key}`) - if (!vRel) { - continue - } - versions.push({ - tag: key, - time: vRel.created_at, - stats: { - code: round(value.code * 100, 2), - template: round(value.template * 100, 2), - url: round(value.url * 100, 2) - } - }) - } - } - const roVersions = orderBy(versions, ['time', 'tag'], ['asc', 'asc']) - - // -> Fill axis + data points - const labels = [] - const datasetCode = [] - const datasetTemplate = [] - const datasetUrl = [] - - for (const ver of roVersions) { - labels.push(ver.tag) - datasetCode.push(ver.stats.code) - datasetTemplate.push(ver.stats.template) - datasetUrl.push(ver.stats.url) - } - - // -> Generate chart SVG - const outputStream = chartJSNodeCanvas.renderToBufferSync({ - type: 'line', - options: { - borderColor: '#CCC', - layout: { - padding: 20 - }, - plugins: { - legend: { - position: 'bottom', - labels: { - font: { - size: 11 - } - } - } - }, - scales: { - x: { - ticks: { - font: { - size: 10 - } - } - }, - y: { - ticks: { - callback: (value) => { - return `${value}%` - }, - font: { - size: 10 - } - } - } - } - }, - data: { - labels, - datasets: [ - { - label: 'Code', - data: datasetCode, - borderWidth: 2, - borderColor: '#E53935', - backgroundColor: '#C6282833', - fill: false, - cubicInterpolationMode: 'monotone', - tension: 0.4, - pointRadius: 0 - }, - { - label: 'Templates', - data: datasetTemplate, - borderWidth: 2, - borderColor: '#039BE5', - backgroundColor: '#0277BD33', - fill: false, - cubicInterpolationMode: 'monotone', - tension: 0.4, - pointRadius: 0 - }, - { - label: 'URLs', - data: datasetUrl, - borderWidth: 2, - borderColor: '#7CB342', - backgroundColor: '#558B2F33', - fill: false, - cubicInterpolationMode: 'monotone', - tension: 0.4, - pointRadius: 0 - } - ] - } - }, 'image/svg+xml') - const svg = Buffer.from(outputStream).toString('base64') - - // -> Upload to common repo - console.info(`Uploading chart SVG for ${newRelease.name}...`) - await ghCommon.rest.repos.createOrUpdateFileContents({ - owner, - repo: repoCommon, - path: `assets/graphs/datatracker/${newRelease.id}.svg`, - message: `chore: update datatracker release chart for release ${newRelease.name}`, - content: svg - }) - } - // -> Add to changelog body let formattedBody = '' const covInfo = { @@ -257,7 +131,19 @@ async function main () { } formattedBody = summary ? `**Summary:** ${summary}\n` : '' - formattedBody += `**Release Date**: ${DateTime.now().setZone('utc').toFormat('ccc, LLLL d, y \'at\' h:mm a ZZZZ')}\n` + formattedBody += `**Release Date**: ${Temporal.Now.zonedDateTimeISO('UTC').toLocaleString( + 'en-US', + { + weekday: 'short', + month: 'long', + day: 'numeric', + year: 'numeric', + hour: 'numeric', + minute: '2-digit', + hour12: true, + timeZoneName: 'short' + } + )}\n` formattedBody += `**Release Author**: @${sender}\n` formattedBody += '\n---\n\n' formattedBody += changelog @@ -265,14 +151,13 @@ async function main () { formattedBody += `![](https://img.shields.io/badge/Code-${covInfo.code}%25-${getCoverageColor(covInfo.code)}?style=flat-square)` formattedBody += `![](https://img.shields.io/badge/Templates-${covInfo.template}%25-${getCoverageColor(covInfo.template)}?style=flat-square)` formattedBody += `![](https://img.shields.io/badge/URLs-${covInfo.url}%25-${getCoverageColor(covInfo.url)}?style=flat-square)\n\n` - formattedBody += `![chart](https://raw.githubusercontent.com/${owner}/${repoCommon}/main/assets/graphs/datatracker/${newRelease.id}.svg)` core.setOutput('changelog', formattedBody) } main() -function getCoverageColor (val) { +function getCoverageColor(val) { if (val >= 95) { return 'brightgreen' } else if (val >= 90) { diff --git a/dev/coverage-action/package-lock.json b/dev/coverage-action/package-lock.json index d90dd210af8..a63148186fe 100644 --- a/dev/coverage-action/package-lock.json +++ b/dev/coverage-action/package-lock.json @@ -9,4646 +9,433 @@ "version": "1.0.0", "license": "BSD-3-Clause", "dependencies": { - "@actions/core": "1.6.0", - "@actions/github": "5.0.0", - "chart.js": "3.7.1", - "chartjs-node-canvas": "4.1.6", - "lodash": "4.17.21", - "luxon": "2.3.1" - }, - "devDependencies": { - "eslint": "7.32.0", - "eslint-config-standard": "16.0.3", - "eslint-plugin-import": "2.25.4", - "eslint-plugin-node": "11.1.0", - "eslint-plugin-promise": "5.2.0" + "@actions/core": "3.0.1", + "@actions/github": "9.1.1", + "es-toolkit": "1.50.0" } }, "node_modules/@actions/core": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/@actions/core/-/core-1.6.0.tgz", - "integrity": "sha512-NB1UAZomZlCV/LmJqkLhNTqtKfFXJZAUPcfl/zqG7EfsQdeUJtaWO98SGbuQ3pydJ3fHl2CvI/51OKYlCYYcaw==", - "dependencies": { - "@actions/http-client": "^1.0.11" - } - }, - "node_modules/@actions/github": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@actions/github/-/github-5.0.0.tgz", - "integrity": "sha512-QvE9eAAfEsS+yOOk0cylLBIO/d6WyWIOvsxxzdrPFaud39G6BOkUwScXZn1iBzQzHyu9SBkkLSWlohDWdsasAQ==", - "dependencies": { - "@actions/http-client": "^1.0.11", - "@octokit/core": "^3.4.0", - "@octokit/plugin-paginate-rest": "^2.13.3", - "@octokit/plugin-rest-endpoint-methods": "^5.1.1" - } - }, - "node_modules/@actions/http-client": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-1.0.11.tgz", - "integrity": "sha512-VRYHGQV1rqnROJqdMvGUbY/Kn8vriQe/F9HR2AlYHzmKuM/p3kjNuXhmdBfcVgsvRWTz5C5XW5xvndZrVBuAYg==", - "dependencies": { - "tunnel": "0.0.6" - } - }, - "node_modules/@babel/code-frame": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", - "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", - "dev": true, + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@actions/core/-/core-3.0.1.tgz", + "integrity": "sha512-a6d/Nwahm9fliVGRhdhofo40HjHQasUPusmc7vBfyky+7Z+P2A1J68zyFVaNcEclc/Se+eO595oAr5nwEIoIUA==", + "license": "MIT", "dependencies": { - "@babel/highlight": "^7.10.4" - } - }, - "node_modules/@babel/helper-validator-identifier": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz", - "integrity": "sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw==", - "dev": true, - "engines": { - "node": ">=6.9.0" + "@actions/exec": "^3.0.0", + "@actions/http-client": "^4.0.0" } }, - "node_modules/@babel/highlight": { - "version": "7.16.10", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.16.10.tgz", - "integrity": "sha512-5FnTQLSLswEj6IkgVw5KusNUUFY9ZGqe/TRFnP/BKYHYgfh7tc+C7mwiy95/yNP7Dh9x580Vv8r7u7ZfTBFxdw==", - "dev": true, + "node_modules/@actions/exec": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@actions/exec/-/exec-3.0.0.tgz", + "integrity": "sha512-6xH/puSoNBXb72VPlZVm7vQ+svQpFyA96qdDBvhB8eNZOE8LtPf9L4oAsfzK/crCL8YZ+19fKYVnM63Sl+Xzlw==", + "license": "MIT", "dependencies": { - "@babel/helper-validator-identifier": "^7.16.7", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" - }, - "engines": { - "node": ">=6.9.0" + "@actions/io": "^3.0.2" } }, - "node_modules/@babel/highlight/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, + "node_modules/@actions/github": { + "version": "9.1.1", + "resolved": "https://registry.npmjs.org/@actions/github/-/github-9.1.1.tgz", + "integrity": "sha512-tL5JbYOBZHc0ngEnCsaDcryUizIUIlQyIMwy1Wkx93H5HzbBJ7TbiPx2PnFjBwZW0Vh05JmfFZhecE6gglYegA==", + "license": "MIT", "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" + "@actions/http-client": "^3.0.2", + "@octokit/core": "^7.0.6", + "@octokit/plugin-paginate-rest": "^14.0.0", + "@octokit/plugin-rest-endpoint-methods": "^17.0.0", + "@octokit/request": "^10.0.7", + "@octokit/request-error": "^7.1.0", + "undici": "^6.23.0" } }, - "node_modules/@babel/highlight/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, + "node_modules/@actions/github/node_modules/@actions/http-client": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-3.0.2.tgz", + "integrity": "sha512-JP38FYYpyqvUsz+Igqlc/JG6YO9PaKuvqjM3iGvaLqFnJ7TFmcLyy2IDrY0bI0qCQug8E9K+elv5ZNfw62ZJzA==", + "license": "MIT", "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" + "tunnel": "^0.0.6", + "undici": "^6.23.0" } }, - "node_modules/@babel/highlight/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, + "node_modules/@actions/http-client": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-4.0.1.tgz", + "integrity": "sha512-+Nvd1ImaOZBSoPbsUtEhv+1z99H12xzncCkz0a3RuehINE81FZSe2QTj3uvAPTcJX/SCzUQHQ0D1GrPMbrPitg==", + "license": "MIT", "dependencies": { - "color-name": "1.1.3" + "tunnel": "^0.0.6", + "undici": "^6.23.0" } }, - "node_modules/@babel/highlight/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - }, - "node_modules/@babel/highlight/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true, - "engines": { - "node": ">=0.8.0" - } + "node_modules/@actions/io": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@actions/io/-/io-3.0.2.tgz", + "integrity": "sha512-nRBchcMM+QK1pdjO7/idu86rbJI5YHUKCvKs0KxnSYbVe3F51UfGxuZX4Qy/fWlp6l7gWFwIkrOzN+oUK03kfw==", + "license": "MIT" }, - "node_modules/@babel/highlight/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true, + "node_modules/@octokit/auth-token": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-6.0.0.tgz", + "integrity": "sha512-P4YJBPdPSpWTQ1NU4XYdvHvXJJDxM6YwpS0FZHRgP7YFkdVxsWcpWGy/NVqlAA7PcPCnMacXlRm1y2PFZRWL/w==", + "license": "MIT", "engines": { - "node": ">=4" + "node": ">= 20" } }, - "node_modules/@babel/highlight/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, + "node_modules/@octokit/core": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/@octokit/core/-/core-7.0.6.tgz", + "integrity": "sha512-DhGl4xMVFGVIyMwswXeyzdL4uXD5OGILGX5N8Y+f6W7LhC1Ze2poSNrkF/fedpVDHEEZ+PHFW0vL14I+mm8K3Q==", + "license": "MIT", "dependencies": { - "has-flag": "^3.0.0" + "@octokit/auth-token": "^6.0.0", + "@octokit/graphql": "^9.0.3", + "@octokit/request": "^10.0.6", + "@octokit/request-error": "^7.0.2", + "@octokit/types": "^16.0.0", + "before-after-hook": "^4.0.0", + "universal-user-agent": "^7.0.0" }, "engines": { - "node": ">=4" + "node": ">= 20" } }, - "node_modules/@eslint/eslintrc": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.3.tgz", - "integrity": "sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw==", - "dev": true, + "node_modules/@octokit/endpoint": { + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-11.0.3.tgz", + "integrity": "sha512-FWFlNxghg4HrXkD3ifYbS/IdL/mDHjh9QcsNyhQjN8dplUoZbejsdpmuqdA76nxj2xoWPs7p8uX2SNr9rYu0Ag==", + "license": "MIT", "dependencies": { - "ajv": "^6.12.4", - "debug": "^4.1.1", - "espree": "^7.3.0", - "globals": "^13.9.0", - "ignore": "^4.0.6", - "import-fresh": "^3.2.1", - "js-yaml": "^3.13.1", - "minimatch": "^3.0.4", - "strip-json-comments": "^3.1.1" + "@octokit/types": "^16.0.0", + "universal-user-agent": "^7.0.2" }, "engines": { - "node": "^10.12.0 || >=12.0.0" + "node": ">= 20" } }, - "node_modules/@humanwhocodes/config-array": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.5.0.tgz", - "integrity": "sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg==", - "dev": true, + "node_modules/@octokit/graphql": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-9.0.3.tgz", + "integrity": "sha512-grAEuupr/C1rALFnXTv6ZQhFuL1D8G5y8CN04RgrO4FIPMrtm+mcZzFG7dcBm+nq+1ppNixu+Jd78aeJOYxlGA==", + "license": "MIT", "dependencies": { - "@humanwhocodes/object-schema": "^1.2.0", - "debug": "^4.1.1", - "minimatch": "^3.0.4" + "@octokit/request": "^10.0.6", + "@octokit/types": "^16.0.0", + "universal-user-agent": "^7.0.0" }, "engines": { - "node": ">=10.10.0" - } - }, - "node_modules/@humanwhocodes/object-schema": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", - "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", - "dev": true - }, - "node_modules/@mapbox/node-pre-gyp": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.8.tgz", - "integrity": "sha512-CMGKi28CF+qlbXh26hDe6NxCd7amqeAzEqnS6IHeO6LoaKyM/n+Xw3HT1COdq8cuioOdlKdqn/hCmqPUOMOywg==", - "dependencies": { - "detect-libc": "^1.0.3", - "https-proxy-agent": "^5.0.0", - "make-dir": "^3.1.0", - "node-fetch": "^2.6.5", - "nopt": "^5.0.0", - "npmlog": "^5.0.1", - "rimraf": "^3.0.2", - "semver": "^7.3.5", - "tar": "^6.1.11" - }, - "bin": { - "node-pre-gyp": "bin/node-pre-gyp" - } - }, - "node_modules/@octokit/auth-token": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-2.5.0.tgz", - "integrity": "sha512-r5FVUJCOLl19AxiuZD2VRZ/ORjp/4IN98Of6YJoJOkY75CIBuYfmiNHGrDwXr+aLGG55igl9QrxX3hbiXlLb+g==", - "dependencies": { - "@octokit/types": "^6.0.3" - } - }, - "node_modules/@octokit/core": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/@octokit/core/-/core-3.6.0.tgz", - "integrity": "sha512-7RKRKuA4xTjMhY+eG3jthb3hlZCsOwg3rztWh75Xc+ShDWOfDDATWbeZpAHBNRpm4Tv9WgBMOy1zEJYXG6NJ7Q==", - "dependencies": { - "@octokit/auth-token": "^2.4.4", - "@octokit/graphql": "^4.5.8", - "@octokit/request": "^5.6.3", - "@octokit/request-error": "^2.0.5", - "@octokit/types": "^6.0.3", - "before-after-hook": "^2.2.0", - "universal-user-agent": "^6.0.0" - } - }, - "node_modules/@octokit/endpoint": { - "version": "6.0.12", - "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-6.0.12.tgz", - "integrity": "sha512-lF3puPwkQWGfkMClXb4k/eUT/nZKQfxinRWJrdZaJO85Dqwo/G0yOC434Jr2ojwafWJMYqFGFa5ms4jJUgujdA==", - "dependencies": { - "@octokit/types": "^6.0.3", - "is-plain-object": "^5.0.0", - "universal-user-agent": "^6.0.0" - } - }, - "node_modules/@octokit/graphql": { - "version": "4.8.0", - "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-4.8.0.tgz", - "integrity": "sha512-0gv+qLSBLKF0z8TKaSKTsS39scVKF9dbMxJpj3U0vC7wjNWFuIpL/z76Qe2fiuCbDRcJSavkXsVtMS6/dtQQsg==", - "dependencies": { - "@octokit/request": "^5.6.0", - "@octokit/types": "^6.0.3", - "universal-user-agent": "^6.0.0" + "node": ">= 20" } }, "node_modules/@octokit/openapi-types": { - "version": "11.2.0", - "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-11.2.0.tgz", - "integrity": "sha512-PBsVO+15KSlGmiI8QAzaqvsNlZlrDlyAJYcrXBCvVUxCp7VnXjkwPoFHgjEJXx3WF9BAwkA6nfCUA7i9sODzKA==" + "version": "27.0.0", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-27.0.0.tgz", + "integrity": "sha512-whrdktVs1h6gtR+09+QsNk2+FO+49j6ga1c55YZudfEG+oKJVvJLQi3zkOm5JjiUXAagWK2tI2kTGKJ2Ys7MGA==", + "license": "MIT" }, "node_modules/@octokit/plugin-paginate-rest": { - "version": "2.17.0", - "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-2.17.0.tgz", - "integrity": "sha512-tzMbrbnam2Mt4AhuyCHvpRkS0oZ5MvwwcQPYGtMv4tUa5kkzG58SVB0fcsLulOZQeRnOgdkZWkRUiyBlh0Bkyw==", + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-14.0.0.tgz", + "integrity": "sha512-fNVRE7ufJiAA3XUrha2omTA39M6IXIc6GIZLvlbsm8QOQCYvpq/LkMNGyFlB1d8hTDzsAXa3OKtybdMAYsV/fw==", + "license": "MIT", "dependencies": { - "@octokit/types": "^6.34.0" + "@octokit/types": "^16.0.0" }, - "peerDependencies": { - "@octokit/core": ">=2" - } - }, - "node_modules/@octokit/plugin-rest-endpoint-methods": { - "version": "5.13.0", - "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-5.13.0.tgz", - "integrity": "sha512-uJjMTkN1KaOIgNtUPMtIXDOjx6dGYysdIFhgA52x4xSadQCz3b/zJexvITDVpANnfKPW/+E0xkOvLntqMYpviA==", - "dependencies": { - "@octokit/types": "^6.34.0", - "deprecation": "^2.3.1" + "engines": { + "node": ">= 20" }, "peerDependencies": { - "@octokit/core": ">=3" + "@octokit/core": ">=6" } }, - "node_modules/@octokit/request": { - "version": "5.6.3", - "resolved": "https://registry.npmjs.org/@octokit/request/-/request-5.6.3.tgz", - "integrity": "sha512-bFJl0I1KVc9jYTe9tdGGpAMPy32dLBXXo1dS/YwSCTL/2nd9XeHsY616RE3HPXDVk+a+dBuzyz5YdlXwcDTr2A==", - "dependencies": { - "@octokit/endpoint": "^6.0.1", - "@octokit/request-error": "^2.1.0", - "@octokit/types": "^6.16.1", - "is-plain-object": "^5.0.0", - "node-fetch": "^2.6.7", - "universal-user-agent": "^6.0.0" - } - }, - "node_modules/@octokit/request-error": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-2.1.0.tgz", - "integrity": "sha512-1VIvgXxs9WHSjicsRwq8PlR2LR2x6DwsJAaFgzdi0JfJoGSO8mYI/cHJQ+9FbN21aa+DrgNLnwObmyeSC8Rmpg==", - "dependencies": { - "@octokit/types": "^6.0.3", - "deprecation": "^2.0.0", - "once": "^1.4.0" - } - }, - "node_modules/@octokit/types": { - "version": "6.34.0", - "resolved": "https://registry.npmjs.org/@octokit/types/-/types-6.34.0.tgz", - "integrity": "sha512-s1zLBjWhdEI2zwaoSgyOFoKSl109CUcVBCc7biPJ3aAf6LGLU6szDvi31JPU7bxfla2lqfhjbbg/5DdFNxOwHw==", + "node_modules/@octokit/plugin-rest-endpoint-methods": { + "version": "17.0.0", + "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-17.0.0.tgz", + "integrity": "sha512-B5yCyIlOJFPqUUeiD0cnBJwWJO8lkJs5d8+ze9QDP6SvfiXSz1BF+91+0MeI1d2yxgOhU/O+CvtiZ9jSkHhFAw==", + "license": "MIT", "dependencies": { - "@octokit/openapi-types": "^11.2.0" - } - }, - "node_modules/@types/json5": { - "version": "0.0.29", - "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", - "integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=", - "dev": true - }, - "node_modules/abbrev": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" - }, - "node_modules/acorn": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", - "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", - "dev": true, - "bin": { - "acorn": "bin/acorn" + "@octokit/types": "^16.0.0" }, "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-jsx": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true, + "node": ">= 20" + }, "peerDependencies": { - "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + "@octokit/core": ">=6" } }, - "node_modules/agent-base": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", - "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "node_modules/@octokit/request": { + "version": "10.0.11", + "resolved": "https://registry.npmjs.org/@octokit/request/-/request-10.0.11.tgz", + "integrity": "sha512-+s7HUxjfFqOMS9VlIwDffq0MikjSAK0gSpG73W+meAvVAvX4MBrHYTK5Bj3Uot55qFT4gzUtfzE4mGWY4Br8/Q==", + "license": "MIT", "dependencies": { - "debug": "4" + "@octokit/endpoint": "^11.0.3", + "@octokit/request-error": "^7.0.2", + "@octokit/types": "^16.0.0", + "content-type": "^2.0.0", + "json-with-bigint": "^3.5.3", + "universal-user-agent": "^7.0.2" }, "engines": { - "node": ">= 6.0.0" + "node": ">= 20" } }, - "node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, + "node_modules/@octokit/request-error": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-7.1.0.tgz", + "integrity": "sha512-KMQIfq5sOPpkQYajXHwnhjCC0slzCNScLHs9JafXc4RAJI+9f+jNDlBNaIMTvazOPLgb4BnlhGJOTbnN0wIjPw==", + "license": "MIT", "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" + "@octokit/types": "^16.0.0" }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/ansi-colors": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", - "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "engines": { - "node": ">=8" + "node": ">= 20" } }, - "node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, + "node_modules/@octokit/types": { + "version": "16.0.0", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-16.0.0.tgz", + "integrity": "sha512-sKq+9r1Mm4efXW1FCk7hFSeJo4QKreL/tTbR0rz/qx/r1Oa2VV83LTA/H/MuCOX7uCIJmQVRKBcbmWoySjAnSg==", + "license": "MIT", "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "@octokit/openapi-types": "^27.0.0" } }, - "node_modules/aproba": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz", - "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==" + "node_modules/before-after-hook": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-4.0.0.tgz", + "integrity": "sha512-q6tR3RPqIB1pMiTRMFcZwuG5T8vwp+vUvEG0vuI6B+Rikh5BfPp2fQ82c925FOs+b0lcFQ8CFrL+KbilfZFhOQ==", + "license": "Apache-2.0" }, - "node_modules/are-we-there-yet": { + "node_modules/content-type": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-2.0.0.tgz", - "integrity": "sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==", - "dependencies": { - "delegates": "^1.0.0", - "readable-stream": "^3.6.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "dependencies": { - "sprintf-js": "~1.0.2" - } - }, - "node_modules/array-includes": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.4.tgz", - "integrity": "sha512-ZTNSQkmWumEbiHO2GF4GmWxYVTiQyJy2XOTa15sdQSrvKn7l+180egQMqlrMOUMCyLMD7pmyQe4mMDUT6Behrw==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.1", - "get-intrinsic": "^1.1.1", - "is-string": "^1.0.7" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/array.prototype.flat": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.2.5.tgz", - "integrity": "sha512-KaYU+S+ndVqyUnignHftkwc58o3uVU1jzczILJ1tN2YaIZpFIKBiP/x/j97E5MVPsaCloPbqWLB/8qCTVvT2qg==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.0" - }, + "resolved": "https://registry.npmjs.org/content-type/-/content-type-2.0.0.tgz", + "integrity": "sha512-j/O/d7GcZCyNl7/hwZAb606rzqkyvaDctLmckbxLzHvFBzTJHuGEdodATcP3yIRoDrLHkIATJuvzbFlp/ki2cQ==", + "license": "MIT", "engines": { - "node": ">= 0.4" + "node": ">=18" }, "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/astral-regex": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", - "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" - }, - "node_modules/before-after-hook": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.2.tgz", - "integrity": "sha512-3pZEU3NT5BFUo/AD5ERPWOgQOCZITni6iavr5AUw5AUwQjMlI0kzu5btnyD39AF0gUEsDPwJT+oY1ORBJijPjQ==" - }, - "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "type": "opencollective", + "url": "https://opencollective.com/express" } }, - "node_modules/call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", - "dev": true, - "dependencies": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } + "node_modules/es-toolkit": { + "version": "1.50.0", + "resolved": "https://registry.npmjs.org/es-toolkit/-/es-toolkit-1.50.0.tgz", + "integrity": "sha512-OyZKhUVvEep9ITEiwHn8GKnMRQIVqoSIX7WnRbkWgJkllCujilqP2rD0u979tkl8wqyc8ICwlc1UBVv/Sl1G6w==" }, - "node_modules/callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true, - "engines": { - "node": ">=6" - } + "node_modules/json-with-bigint": { + "version": "3.5.8", + "resolved": "https://registry.npmjs.org/json-with-bigint/-/json-with-bigint-3.5.8.tgz", + "integrity": "sha512-eq/4KP6K34kwa7TcFdtvnftvHCD9KvHOGGICWwMFc4dOOKF5t4iYqnfLK8otCRCRv06FXOzGGyqE8h8ElMvvdw==", + "license": "MIT" }, - "node_modules/canvas": { - "version": "2.9.1", - "resolved": "https://registry.npmjs.org/canvas/-/canvas-2.9.1.tgz", - "integrity": "sha512-vSQti1uG/2gjv3x6QLOZw7TctfufaerTWbVe+NSduHxxLGB+qf3kFgQ6n66DSnuoINtVUjrLLIK2R+lxrBG07A==", - "hasInstallScript": true, - "dependencies": { - "@mapbox/node-pre-gyp": "^1.0.0", - "nan": "^2.15.0", - "simple-get": "^3.0.3" - }, + "node_modules/tunnel": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz", + "integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==", + "license": "MIT", "engines": { - "node": ">=6" + "node": ">=0.6.11 <=0.7.0 || >=0.7.3" } }, - "node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, + "node_modules/undici": { + "version": "6.27.0", + "resolved": "https://registry.npmjs.org/undici/-/undici-6.27.0.tgz", + "integrity": "sha512-YmfV3YnEDzXRC5lZ2jWtWWHKGUm1zIt8AhesR1tens+HTNv+YZlN/dp6G727LOvMJ8xjP9Be7Y2Sdr96LDm+pg==", + "license": "MIT", "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "node": ">=18.17" } }, - "node_modules/chart.js": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/chart.js/-/chart.js-3.7.1.tgz", - "integrity": "sha512-8knRegQLFnPQAheZV8MjxIXc5gQEfDFD897BJgv/klO/vtIyFFmgMXrNfgrXpbTr/XbTturxRgxIXx/Y+ASJBA==" - }, - "node_modules/chartjs-node-canvas": { - "version": "4.1.6", - "resolved": "https://registry.npmjs.org/chartjs-node-canvas/-/chartjs-node-canvas-4.1.6.tgz", - "integrity": "sha512-UQJbPWrvqB/FoLclGA9BaLQmZbzSYlujF4w8NZd6Xzb+sqgACBb2owDX6m7ifCXLjUW5Nz0Qx0qqrTtQkkSoYw==", - "dependencies": { - "canvas": "^2.8.0", - "tslib": "^2.3.1" - }, - "peerDependencies": { - "chart.js": "^3.5.1" + "node_modules/universal-user-agent": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-7.0.3.tgz", + "integrity": "sha512-TmnEAEAsBJVZM/AADELsK76llnwcf9vMKuPz8JflO1frO8Lchitr0fNaN9d+Ap0BjKtqWqd/J17qeDnXh8CL2A==", + "license": "ISC" + } + }, + "dependencies": { + "@actions/core": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@actions/core/-/core-3.0.1.tgz", + "integrity": "sha512-a6d/Nwahm9fliVGRhdhofo40HjHQasUPusmc7vBfyky+7Z+P2A1J68zyFVaNcEclc/Se+eO595oAr5nwEIoIUA==", + "requires": { + "@actions/exec": "^3.0.0", + "@actions/http-client": "^4.0.0" } }, - "node_modules/chownr": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", - "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", - "engines": { - "node": ">=10" + "@actions/exec": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@actions/exec/-/exec-3.0.0.tgz", + "integrity": "sha512-6xH/puSoNBXb72VPlZVm7vQ+svQpFyA96qdDBvhB8eNZOE8LtPf9L4oAsfzK/crCL8YZ+19fKYVnM63Sl+Xzlw==", + "requires": { + "@actions/io": "^3.0.2" } }, - "node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" + "@actions/github": { + "version": "9.1.1", + "resolved": "https://registry.npmjs.org/@actions/github/-/github-9.1.1.tgz", + "integrity": "sha512-tL5JbYOBZHc0ngEnCsaDcryUizIUIlQyIMwy1Wkx93H5HzbBJ7TbiPx2PnFjBwZW0Vh05JmfFZhecE6gglYegA==", + "requires": { + "@actions/http-client": "^3.0.2", + "@octokit/core": "^7.0.6", + "@octokit/plugin-paginate-rest": "^14.0.0", + "@octokit/plugin-rest-endpoint-methods": "^17.0.0", + "@octokit/request": "^10.0.7", + "@octokit/request-error": "^7.1.0", + "undici": "^6.23.0" + }, + "dependencies": { + "@actions/http-client": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-3.0.2.tgz", + "integrity": "sha512-JP38FYYpyqvUsz+Igqlc/JG6YO9PaKuvqjM3iGvaLqFnJ7TFmcLyy2IDrY0bI0qCQug8E9K+elv5ZNfw62ZJzA==", + "requires": { + "tunnel": "^0.0.6", + "undici": "^6.23.0" + } + } } }, - "node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/color-support": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", - "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", - "bin": { - "color-support": "bin.js" + "@actions/http-client": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-4.0.1.tgz", + "integrity": "sha512-+Nvd1ImaOZBSoPbsUtEhv+1z99H12xzncCkz0a3RuehINE81FZSe2QTj3uvAPTcJX/SCzUQHQ0D1GrPMbrPitg==", + "requires": { + "tunnel": "^0.0.6", + "undici": "^6.23.0" } }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" - }, - "node_modules/console-control-strings": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", - "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=" + "@actions/io": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@actions/io/-/io-3.0.2.tgz", + "integrity": "sha512-nRBchcMM+QK1pdjO7/idu86rbJI5YHUKCvKs0KxnSYbVe3F51UfGxuZX4Qy/fWlp6l7gWFwIkrOzN+oUK03kfw==" }, - "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } + "@octokit/auth-token": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-6.0.0.tgz", + "integrity": "sha512-P4YJBPdPSpWTQ1NU4XYdvHvXJJDxM6YwpS0FZHRgP7YFkdVxsWcpWGy/NVqlAA7PcPCnMacXlRm1y2PFZRWL/w==" }, - "node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } + "@octokit/core": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/@octokit/core/-/core-7.0.6.tgz", + "integrity": "sha512-DhGl4xMVFGVIyMwswXeyzdL4uXD5OGILGX5N8Y+f6W7LhC1Ze2poSNrkF/fedpVDHEEZ+PHFW0vL14I+mm8K3Q==", + "requires": { + "@octokit/auth-token": "^6.0.0", + "@octokit/graphql": "^9.0.3", + "@octokit/request": "^10.0.6", + "@octokit/request-error": "^7.0.2", + "@octokit/types": "^16.0.0", + "before-after-hook": "^4.0.0", + "universal-user-agent": "^7.0.0" } }, - "node_modules/decompress-response": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-4.2.1.tgz", - "integrity": "sha512-jOSne2qbyE+/r8G1VU+G/82LBs2Fs4LAsTiLSHOCOMZQl2OKZ6i8i4IyHemTe+/yIXOtTcRQMzPcgyhoFlqPkw==", - "dependencies": { - "mimic-response": "^2.0.0" - }, - "engines": { - "node": ">=8" + "@octokit/endpoint": { + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-11.0.3.tgz", + "integrity": "sha512-FWFlNxghg4HrXkD3ifYbS/IdL/mDHjh9QcsNyhQjN8dplUoZbejsdpmuqdA76nxj2xoWPs7p8uX2SNr9rYu0Ag==", + "requires": { + "@octokit/types": "^16.0.0", + "universal-user-agent": "^7.0.2" } }, - "node_modules/deep-is": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true - }, - "node_modules/define-properties": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", - "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", - "dev": true, - "dependencies": { - "object-keys": "^1.0.12" - }, - "engines": { - "node": ">= 0.4" + "@octokit/graphql": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-9.0.3.tgz", + "integrity": "sha512-grAEuupr/C1rALFnXTv6ZQhFuL1D8G5y8CN04RgrO4FIPMrtm+mcZzFG7dcBm+nq+1ppNixu+Jd78aeJOYxlGA==", + "requires": { + "@octokit/request": "^10.0.6", + "@octokit/types": "^16.0.0", + "universal-user-agent": "^7.0.0" } }, - "node_modules/delegates": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", - "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=" - }, - "node_modules/deprecation": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz", - "integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==" + "@octokit/openapi-types": { + "version": "27.0.0", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-27.0.0.tgz", + "integrity": "sha512-whrdktVs1h6gtR+09+QsNk2+FO+49j6ga1c55YZudfEG+oKJVvJLQi3zkOm5JjiUXAagWK2tI2kTGKJ2Ys7MGA==" }, - "node_modules/detect-libc": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", - "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=", - "bin": { - "detect-libc": "bin/detect-libc.js" - }, - "engines": { - "node": ">=0.10" + "@octokit/plugin-paginate-rest": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-14.0.0.tgz", + "integrity": "sha512-fNVRE7ufJiAA3XUrha2omTA39M6IXIc6GIZLvlbsm8QOQCYvpq/LkMNGyFlB1d8hTDzsAXa3OKtybdMAYsV/fw==", + "requires": { + "@octokit/types": "^16.0.0" } }, - "node_modules/doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "dev": true, - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=6.0.0" + "@octokit/plugin-rest-endpoint-methods": { + "version": "17.0.0", + "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-17.0.0.tgz", + "integrity": "sha512-B5yCyIlOJFPqUUeiD0cnBJwWJO8lkJs5d8+ze9QDP6SvfiXSz1BF+91+0MeI1d2yxgOhU/O+CvtiZ9jSkHhFAw==", + "requires": { + "@octokit/types": "^16.0.0" } }, - "node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" - }, - "node_modules/enquirer": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", - "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", - "dev": true, - "dependencies": { - "ansi-colors": "^4.1.1" - }, - "engines": { - "node": ">=8.6" + "@octokit/request": { + "version": "10.0.11", + "resolved": "https://registry.npmjs.org/@octokit/request/-/request-10.0.11.tgz", + "integrity": "sha512-+s7HUxjfFqOMS9VlIwDffq0MikjSAK0gSpG73W+meAvVAvX4MBrHYTK5Bj3Uot55qFT4gzUtfzE4mGWY4Br8/Q==", + "requires": { + "@octokit/endpoint": "^11.0.3", + "@octokit/request-error": "^7.0.2", + "@octokit/types": "^16.0.0", + "content-type": "^2.0.0", + "json-with-bigint": "^3.5.3", + "universal-user-agent": "^7.0.2" } }, - "node_modules/es-abstract": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.19.1.tgz", - "integrity": "sha512-2vJ6tjA/UfqLm2MPs7jxVybLoB8i1t1Jd9R3kISld20sIxPcTbLuggQOUxeWeAvIUkduv/CfMjuh4WmiXr2v9w==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "get-intrinsic": "^1.1.1", - "get-symbol-description": "^1.0.0", - "has": "^1.0.3", - "has-symbols": "^1.0.2", - "internal-slot": "^1.0.3", - "is-callable": "^1.2.4", - "is-negative-zero": "^2.0.1", - "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.1", - "is-string": "^1.0.7", - "is-weakref": "^1.0.1", - "object-inspect": "^1.11.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.2", - "string.prototype.trimend": "^1.0.4", - "string.prototype.trimstart": "^1.0.4", - "unbox-primitive": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "@octokit/request-error": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-7.1.0.tgz", + "integrity": "sha512-KMQIfq5sOPpkQYajXHwnhjCC0slzCNScLHs9JafXc4RAJI+9f+jNDlBNaIMTvazOPLgb4BnlhGJOTbnN0wIjPw==", + "requires": { + "@octokit/types": "^16.0.0" } }, - "node_modules/es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "dev": true, - "dependencies": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "@octokit/types": { + "version": "16.0.0", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-16.0.0.tgz", + "integrity": "sha512-sKq+9r1Mm4efXW1FCk7hFSeJo4QKreL/tTbR0rz/qx/r1Oa2VV83LTA/H/MuCOX7uCIJmQVRKBcbmWoySjAnSg==", + "requires": { + "@octokit/openapi-types": "^27.0.0" } }, - "node_modules/escape-string-regexp": { + "before-after-hook": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } + "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-4.0.0.tgz", + "integrity": "sha512-q6tR3RPqIB1pMiTRMFcZwuG5T8vwp+vUvEG0vuI6B+Rikh5BfPp2fQ82c925FOs+b0lcFQ8CFrL+KbilfZFhOQ==" }, - "node_modules/eslint": { - "version": "7.32.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.32.0.tgz", - "integrity": "sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA==", - "dev": true, - "dependencies": { - "@babel/code-frame": "7.12.11", - "@eslint/eslintrc": "^0.4.3", - "@humanwhocodes/config-array": "^0.5.0", - "ajv": "^6.10.0", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.0.1", - "doctrine": "^3.0.0", - "enquirer": "^2.3.5", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^5.1.1", - "eslint-utils": "^2.1.0", - "eslint-visitor-keys": "^2.0.0", - "espree": "^7.3.1", - "esquery": "^1.4.0", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", - "functional-red-black-tree": "^1.0.1", - "glob-parent": "^5.1.2", - "globals": "^13.6.0", - "ignore": "^4.0.6", - "import-fresh": "^3.0.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "js-yaml": "^3.13.1", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.0.4", - "natural-compare": "^1.4.0", - "optionator": "^0.9.1", - "progress": "^2.0.0", - "regexpp": "^3.1.0", - "semver": "^7.2.1", - "strip-ansi": "^6.0.0", - "strip-json-comments": "^3.1.0", - "table": "^6.0.9", - "text-table": "^0.2.0", - "v8-compile-cache": "^2.0.3" - }, - "bin": { - "eslint": "bin/eslint.js" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } + "content-type": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-2.0.0.tgz", + "integrity": "sha512-j/O/d7GcZCyNl7/hwZAb606rzqkyvaDctLmckbxLzHvFBzTJHuGEdodATcP3yIRoDrLHkIATJuvzbFlp/ki2cQ==" }, - "node_modules/eslint-config-standard": { - "version": "16.0.3", - "resolved": "https://registry.npmjs.org/eslint-config-standard/-/eslint-config-standard-16.0.3.tgz", - "integrity": "sha512-x4fmJL5hGqNJKGHSjnLdgA6U6h1YW/G2dW9fA+cyVur4SK6lyue8+UgNKWlZtUDTXvgKDD/Oa3GQjmB5kjtVvg==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "peerDependencies": { - "eslint": "^7.12.1", - "eslint-plugin-import": "^2.22.1", - "eslint-plugin-node": "^11.1.0", - "eslint-plugin-promise": "^4.2.1 || ^5.0.0" - } + "es-toolkit": { + "version": "1.50.0", + "resolved": "https://registry.npmjs.org/es-toolkit/-/es-toolkit-1.50.0.tgz", + "integrity": "sha512-OyZKhUVvEep9ITEiwHn8GKnMRQIVqoSIX7WnRbkWgJkllCujilqP2rD0u979tkl8wqyc8ICwlc1UBVv/Sl1G6w==" }, - "node_modules/eslint-import-resolver-node": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.6.tgz", - "integrity": "sha512-0En0w03NRVMn9Uiyn8YRPDKvWjxCWkslUEhGNTdGx15RvPJYQ+lbOlqrlNI2vEAs4pDYK4f/HN2TbDmk5TP0iw==", - "dev": true, - "dependencies": { - "debug": "^3.2.7", - "resolve": "^1.20.0" - } + "json-with-bigint": { + "version": "3.5.8", + "resolved": "https://registry.npmjs.org/json-with-bigint/-/json-with-bigint-3.5.8.tgz", + "integrity": "sha512-eq/4KP6K34kwa7TcFdtvnftvHCD9KvHOGGICWwMFc4dOOKF5t4iYqnfLK8otCRCRv06FXOzGGyqE8h8ElMvvdw==" }, - "node_modules/eslint-import-resolver-node/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "dependencies": { - "ms": "^2.1.1" - } + "tunnel": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz", + "integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==" }, - "node_modules/eslint-module-utils": { - "version": "2.7.3", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.7.3.tgz", - "integrity": "sha512-088JEC7O3lDZM9xGe0RerkOMd0EjFl+Yvd1jPWIkMT5u3H9+HC34mWWPnqPrN13gieT9pBOO+Qt07Nb/6TresQ==", - "dev": true, - "dependencies": { - "debug": "^3.2.7", - "find-up": "^2.1.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/eslint-module-utils/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/eslint-plugin-es": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-es/-/eslint-plugin-es-3.0.1.tgz", - "integrity": "sha512-GUmAsJaN4Fc7Gbtl8uOBlayo2DqhwWvEzykMHSCZHU3XdJ+NSzzZcVhXh3VxX5icqQ+oQdIEawXX8xkR3mIFmQ==", - "dev": true, - "dependencies": { - "eslint-utils": "^2.0.0", - "regexpp": "^3.0.0" - }, - "engines": { - "node": ">=8.10.0" - }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" - }, - "peerDependencies": { - "eslint": ">=4.19.1" - } - }, - "node_modules/eslint-plugin-import": { - "version": "2.25.4", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.25.4.tgz", - "integrity": "sha512-/KJBASVFxpu0xg1kIBn9AUa8hQVnszpwgE7Ld0lKAlx7Ie87yzEzCgSkekt+le/YVhiaosO4Y14GDAOc41nfxA==", - "dev": true, - "dependencies": { - "array-includes": "^3.1.4", - "array.prototype.flat": "^1.2.5", - "debug": "^2.6.9", - "doctrine": "^2.1.0", - "eslint-import-resolver-node": "^0.3.6", - "eslint-module-utils": "^2.7.2", - "has": "^1.0.3", - "is-core-module": "^2.8.0", - "is-glob": "^4.0.3", - "minimatch": "^3.0.4", - "object.values": "^1.1.5", - "resolve": "^1.20.0", - "tsconfig-paths": "^3.12.0" - }, - "engines": { - "node": ">=4" - }, - "peerDependencies": { - "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8" - } - }, - "node_modules/eslint-plugin-import/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/eslint-plugin-import/node_modules/doctrine": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", - "dev": true, - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/eslint-plugin-import/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - }, - "node_modules/eslint-plugin-node": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-11.1.0.tgz", - "integrity": "sha512-oUwtPJ1W0SKD0Tr+wqu92c5xuCeQqB3hSCHasn/ZgjFdA9iDGNkNf2Zi9ztY7X+hNuMib23LNGRm6+uN+KLE3g==", - "dev": true, - "dependencies": { - "eslint-plugin-es": "^3.0.0", - "eslint-utils": "^2.0.0", - "ignore": "^5.1.1", - "minimatch": "^3.0.4", - "resolve": "^1.10.1", - "semver": "^6.1.0" - }, - "engines": { - "node": ">=8.10.0" - }, - "peerDependencies": { - "eslint": ">=5.16.0" - } - }, - "node_modules/eslint-plugin-node/node_modules/ignore": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", - "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", - "dev": true, - "engines": { - "node": ">= 4" - } - }, - "node_modules/eslint-plugin-node/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/eslint-plugin-promise": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-5.2.0.tgz", - "integrity": "sha512-SftLb1pUG01QYq2A/hGAWfDRXqYD82zE7j7TopDOyNdU+7SvvoXREls/+PRTY17vUXzXnZA/zfnyKgRH6x4JJw==", - "dev": true, - "engines": { - "node": "^10.12.0 || >=12.0.0" - }, - "peerDependencies": { - "eslint": "^7.0.0" - } - }, - "node_modules/eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", - "dev": true, - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/eslint-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", - "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", - "dev": true, - "dependencies": { - "eslint-visitor-keys": "^1.1.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" - } - }, - "node_modules/eslint-utils/node_modules/eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/eslint-visitor-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", - "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/espree": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", - "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==", - "dev": true, - "dependencies": { - "acorn": "^7.4.0", - "acorn-jsx": "^5.3.1", - "eslint-visitor-keys": "^1.3.0" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/espree/node_modules/eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true, - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/esquery": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", - "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", - "dev": true, - "dependencies": { - "estraverse": "^5.1.0" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/esquery/node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "dev": true, - "dependencies": { - "estraverse": "^5.2.0" - }, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/esrecurse/node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true - }, - "node_modules/fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true - }, - "node_modules/fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", - "dev": true - }, - "node_modules/file-entry-cache": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", - "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", - "dev": true, - "dependencies": { - "flat-cache": "^3.0.4" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", - "dev": true, - "dependencies": { - "locate-path": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/flat-cache": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", - "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", - "dev": true, - "dependencies": { - "flatted": "^3.1.0", - "rimraf": "^3.0.2" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/flatted": { - "version": "3.2.5", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.5.tgz", - "integrity": "sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg==", - "dev": true - }, - "node_modules/fs-minipass": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", - "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" - }, - "node_modules/function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true - }, - "node_modules/functional-red-black-tree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", - "dev": true - }, - "node_modules/gauge": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/gauge/-/gauge-3.0.2.tgz", - "integrity": "sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q==", - "dependencies": { - "aproba": "^1.0.3 || ^2.0.0", - "color-support": "^1.1.2", - "console-control-strings": "^1.0.0", - "has-unicode": "^2.0.1", - "object-assign": "^4.1.1", - "signal-exit": "^3.0.0", - "string-width": "^4.2.3", - "strip-ansi": "^6.0.1", - "wide-align": "^1.1.2" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/get-intrinsic": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", - "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", - "dev": true, - "dependencies": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/get-symbol-description": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", - "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/glob": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", - "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/globals": { - "version": "13.13.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.13.0.tgz", - "integrity": "sha512-EQ7Q18AJlPwp3vUDL4mKA0KXrXyNIQyWon6T6XQiBQF0XHvRsiCSrWmmeATpUzdJN2HhWZU6Pdl0a9zdep5p6A==", - "dev": true, - "dependencies": { - "type-fest": "^0.20.2" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, - "dependencies": { - "function-bind": "^1.1.1" - }, - "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/has-bigints": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz", - "integrity": "sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==", - "dev": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", - "dev": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-tostringtag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", - "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", - "dev": true, - "dependencies": { - "has-symbols": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-unicode": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", - "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=" - }, - "node_modules/https-proxy-agent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz", - "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==", - "dependencies": { - "agent-base": "6", - "debug": "4" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", - "dev": true, - "engines": { - "node": ">= 4" - } - }, - "node_modules/import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "dev": true, - "dependencies": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", - "dev": true, - "engines": { - "node": ">=0.8.19" - } - }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "node_modules/internal-slot": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz", - "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==", - "dev": true, - "dependencies": { - "get-intrinsic": "^1.1.0", - "has": "^1.0.3", - "side-channel": "^1.0.4" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/is-bigint": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", - "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", - "dev": true, - "dependencies": { - "has-bigints": "^1.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-boolean-object": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", - "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-callable": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.4.tgz", - "integrity": "sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==", - "dev": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-core-module": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.1.tgz", - "integrity": "sha512-SdNCUs284hr40hFTFP6l0IfZ/RSrMXF3qgoRHd3/79unUTvrFO/JoXwkGm+5J/Oe3E/b5GsnG330uUNgRpu1PA==", - "dev": true, - "dependencies": { - "has": "^1.0.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-date-object": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", - "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", - "dev": true, - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "engines": { - "node": ">=8" - } - }, - "node_modules/is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, - "dependencies": { - "is-extglob": "^2.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-negative-zero": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", - "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==", - "dev": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-number-object": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.6.tgz", - "integrity": "sha512-bEVOqiRcvo3zO1+G2lVMy+gkkEm9Yh7cDMRusKKu5ZJKPUYSJwICTKZrNKHA2EbSP0Tu0+6B/emsYNHZyn6K8g==", - "dev": true, - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-plain-object": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", - "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-regex": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", - "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-shared-array-buffer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.1.tgz", - "integrity": "sha512-IU0NmyknYZN0rChcKhRO1X8LYz5Isj/Fsqh8NJOSf+N/hCOTwy29F32Ik7a+QszE63IdvmwdTPDd6cZ5pg4cwA==", - "dev": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-string": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", - "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", - "dev": true, - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-symbol": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", - "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", - "dev": true, - "dependencies": { - "has-symbols": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-weakref": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", - "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true - }, - "node_modules/js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true - }, - "node_modules/js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", - "dev": true, - "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true - }, - "node_modules/json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", - "dev": true - }, - "node_modules/json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", - "dev": true, - "dependencies": { - "minimist": "^1.2.0" - }, - "bin": { - "json5": "lib/cli.js" - } - }, - "node_modules/levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", - "dev": true, - "dependencies": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", - "dev": true, - "dependencies": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" - }, - "node_modules/lodash.merge": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true - }, - "node_modules/lodash.truncate": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", - "integrity": "sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=", - "dev": true - }, - "node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/luxon": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/luxon/-/luxon-2.3.1.tgz", - "integrity": "sha512-I8vnjOmhXsMSlNMZlMkSOvgrxKJl0uOsEzdGgGNZuZPaS9KlefpE9KV95QFftlJSC+1UyCC9/I69R02cz/zcCA==", - "engines": { - "node": ">=12" - } - }, - "node_modules/make-dir": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", - "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", - "dependencies": { - "semver": "^6.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/make-dir/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/mimic-response": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-2.1.0.tgz", - "integrity": "sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA==", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/minimist": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", - "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==", - "dev": true - }, - "node_modules/minipass": { - "version": "3.1.6", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.6.tgz", - "integrity": "sha512-rty5kpw9/z8SX9dmxblFA6edItUmwJgMeYDZRrwlIVN27i8gysGbznJwUggw2V/FVqFSDdWy040ZPS811DYAqQ==", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/minizlib": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", - "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", - "dependencies": { - "minipass": "^3.0.0", - "yallist": "^4.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "bin": { - "mkdirp": "bin/cmd.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "node_modules/nan": { - "version": "2.15.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.15.0.tgz", - "integrity": "sha512-8ZtvEnA2c5aYCZYd1cvgdnU6cqwixRoYg70xPLWUws5ORTa/lnw+u4amixRS/Ac5U5mQVgp9pnlSUnbNWFaWZQ==" - }, - "node_modules/natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", - "dev": true - }, - "node_modules/node-fetch": { - "version": "2.6.7", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", - "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", - "dependencies": { - "whatwg-url": "^5.0.0" - }, - "engines": { - "node": "4.x || >=6.0.0" - }, - "peerDependencies": { - "encoding": "^0.1.0" - }, - "peerDependenciesMeta": { - "encoding": { - "optional": true - } - } - }, - "node_modules/nopt": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz", - "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==", - "dependencies": { - "abbrev": "1" - }, - "bin": { - "nopt": "bin/nopt.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/npmlog": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-5.0.1.tgz", - "integrity": "sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==", - "dependencies": { - "are-we-there-yet": "^2.0.0", - "console-control-strings": "^1.1.0", - "gauge": "^3.0.0", - "set-blocking": "^2.0.0" - } - }, - "node_modules/object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-inspect": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.0.tgz", - "integrity": "sha512-Ho2z80bVIvJloH+YzRmpZVQe87+qASmBUKZDWgx9cu+KDrX2ZDH/3tMy+gXbZETVGs2M8YdxObOh7XAtim9Y0g==", - "dev": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/object.assign": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", - "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3", - "has-symbols": "^1.0.1", - "object-keys": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/object.values": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.5.tgz", - "integrity": "sha512-QUZRW0ilQ3PnPpbNtgdNV1PDbEqLIiSFB3l+EnGtBQ/8SUTLj1PZwtQHABZtLgwpJZTSZhuGLOGk57Drx2IvYg==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dependencies": { - "wrappy": "1" - } - }, - "node_modules/optionator": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", - "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", - "dev": true, - "dependencies": { - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.3" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/p-limit": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", - "dev": true, - "dependencies": { - "p-try": "^1.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", - "dev": true, - "dependencies": { - "p-limit": "^1.1.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/p-try": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, - "dependencies": { - "callsites": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true - }, - "node_modules/prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", - "dev": true, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/progress": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", - "dev": true, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/regexpp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", - "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" - } - }, - "node_modules/require-from-string": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", - "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/resolve": { - "version": "1.22.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.0.tgz", - "integrity": "sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw==", - "dev": true, - "dependencies": { - "is-core-module": "^2.8.1", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - }, - "bin": { - "resolve": "bin/resolve" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" - }, - "node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/side-channel": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", - "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.0", - "get-intrinsic": "^1.0.2", - "object-inspect": "^1.9.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" - }, - "node_modules/simple-concat": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", - "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/simple-get": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-3.1.1.tgz", - "integrity": "sha512-CQ5LTKGfCpvE1K0n2us+kuMPbk/q0EKl82s4aheV9oXjFEz6W/Y7oQFVJuU6QG77hRT4Ghb5RURteF5vnWjupA==", - "dependencies": { - "decompress-response": "^4.2.0", - "once": "^1.3.1", - "simple-concat": "^1.0.0" - } - }, - "node_modules/slice-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", - "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.0.0", - "astral-regex": "^2.0.0", - "is-fullwidth-code-point": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/slice-ansi?sponsor=1" - } - }, - "node_modules/sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", - "dev": true - }, - "node_modules/string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dependencies": { - "safe-buffer": "~5.2.0" - } - }, - "node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/string.prototype.trimend": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz", - "integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/string.prototype.trimstart": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz", - "integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/supports-preserve-symlinks-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", - "dev": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/table": { - "version": "6.8.0", - "resolved": "https://registry.npmjs.org/table/-/table-6.8.0.tgz", - "integrity": "sha512-s/fitrbVeEyHKFa7mFdkuQMWlH1Wgw/yEXMt5xACT4ZpzWFluehAxRtUUQKPuWhaLAWhFcVx6w3oC8VKaUfPGA==", - "dev": true, - "dependencies": { - "ajv": "^8.0.1", - "lodash.truncate": "^4.4.2", - "slice-ansi": "^4.0.0", - "string-width": "^4.2.3", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/table/node_modules/ajv": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", - "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", - "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/table/node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true - }, - "node_modules/tar": { - "version": "6.1.11", - "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.11.tgz", - "integrity": "sha512-an/KZQzQUkZCkuoAA64hM92X0Urb6VpRhAFllDzz44U2mcD5scmT3zBc4VgVpkugF580+DQn8eAFSyoQt0tznA==", - "dependencies": { - "chownr": "^2.0.0", - "fs-minipass": "^2.0.0", - "minipass": "^3.0.0", - "minizlib": "^2.1.1", - "mkdirp": "^1.0.3", - "yallist": "^4.0.0" - }, - "engines": { - "node": ">= 10" - } - }, - "node_modules/text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", - "dev": true - }, - "node_modules/tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=" - }, - "node_modules/tsconfig-paths": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.1.tgz", - "integrity": "sha512-fxDhWnFSLt3VuTwtvJt5fpwxBHg5AdKWMsgcPOOIilyjymcYVZoCQF8fvFRezCNfblEXmi+PcM1eYHeOAgXCOQ==", - "dev": true, - "dependencies": { - "@types/json5": "^0.0.29", - "json5": "^1.0.1", - "minimist": "^1.2.6", - "strip-bom": "^3.0.0" - } - }, - "node_modules/tslib": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", - "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" - }, - "node_modules/tunnel": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz", - "integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==", - "engines": { - "node": ">=0.6.11 <=0.7.0 || >=0.7.3" - } - }, - "node_modules/type-check": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", - "dev": true, - "dependencies": { - "prelude-ls": "^1.2.1" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/unbox-primitive": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz", - "integrity": "sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw==", - "dev": true, - "dependencies": { - "function-bind": "^1.1.1", - "has-bigints": "^1.0.1", - "has-symbols": "^1.0.2", - "which-boxed-primitive": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/universal-user-agent": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.0.tgz", - "integrity": "sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w==" - }, - "node_modules/uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dev": true, - "dependencies": { - "punycode": "^2.1.0" - } - }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" - }, - "node_modules/v8-compile-cache": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", - "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", - "dev": true - }, - "node_modules/webidl-conversions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=" - }, - "node_modules/whatwg-url": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=", - "dependencies": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" - } - }, - "node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/which-boxed-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", - "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", - "dev": true, - "dependencies": { - "is-bigint": "^1.0.1", - "is-boolean-object": "^1.1.0", - "is-number-object": "^1.0.4", - "is-string": "^1.0.5", - "is-symbol": "^1.0.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/wide-align": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz", - "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==", - "dependencies": { - "string-width": "^1.0.2 || 2 || 3 || 4" - } - }, - "node_modules/word-wrap": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", - "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" - }, - "node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" - } - }, - "dependencies": { - "@actions/core": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/@actions/core/-/core-1.6.0.tgz", - "integrity": "sha512-NB1UAZomZlCV/LmJqkLhNTqtKfFXJZAUPcfl/zqG7EfsQdeUJtaWO98SGbuQ3pydJ3fHl2CvI/51OKYlCYYcaw==", - "requires": { - "@actions/http-client": "^1.0.11" - } - }, - "@actions/github": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@actions/github/-/github-5.0.0.tgz", - "integrity": "sha512-QvE9eAAfEsS+yOOk0cylLBIO/d6WyWIOvsxxzdrPFaud39G6BOkUwScXZn1iBzQzHyu9SBkkLSWlohDWdsasAQ==", - "requires": { - "@actions/http-client": "^1.0.11", - "@octokit/core": "^3.4.0", - "@octokit/plugin-paginate-rest": "^2.13.3", - "@octokit/plugin-rest-endpoint-methods": "^5.1.1" - } - }, - "@actions/http-client": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-1.0.11.tgz", - "integrity": "sha512-VRYHGQV1rqnROJqdMvGUbY/Kn8vriQe/F9HR2AlYHzmKuM/p3kjNuXhmdBfcVgsvRWTz5C5XW5xvndZrVBuAYg==", - "requires": { - "tunnel": "0.0.6" - } - }, - "@babel/code-frame": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", - "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", - "dev": true, - "requires": { - "@babel/highlight": "^7.10.4" - } - }, - "@babel/helper-validator-identifier": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz", - "integrity": "sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw==", - "dev": true - }, - "@babel/highlight": { - "version": "7.16.10", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.16.10.tgz", - "integrity": "sha512-5FnTQLSLswEj6IkgVw5KusNUUFY9ZGqe/TRFnP/BKYHYgfh7tc+C7mwiy95/yNP7Dh9x580Vv8r7u7ZfTBFxdw==", - "dev": true, - "requires": { - "@babel/helper-validator-identifier": "^7.16.7", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "@eslint/eslintrc": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.3.tgz", - "integrity": "sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw==", - "dev": true, - "requires": { - "ajv": "^6.12.4", - "debug": "^4.1.1", - "espree": "^7.3.0", - "globals": "^13.9.0", - "ignore": "^4.0.6", - "import-fresh": "^3.2.1", - "js-yaml": "^3.13.1", - "minimatch": "^3.0.4", - "strip-json-comments": "^3.1.1" - } - }, - "@humanwhocodes/config-array": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.5.0.tgz", - "integrity": "sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg==", - "dev": true, - "requires": { - "@humanwhocodes/object-schema": "^1.2.0", - "debug": "^4.1.1", - "minimatch": "^3.0.4" - } - }, - "@humanwhocodes/object-schema": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", - "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", - "dev": true - }, - "@mapbox/node-pre-gyp": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.8.tgz", - "integrity": "sha512-CMGKi28CF+qlbXh26hDe6NxCd7amqeAzEqnS6IHeO6LoaKyM/n+Xw3HT1COdq8cuioOdlKdqn/hCmqPUOMOywg==", - "requires": { - "detect-libc": "^1.0.3", - "https-proxy-agent": "^5.0.0", - "make-dir": "^3.1.0", - "node-fetch": "^2.6.5", - "nopt": "^5.0.0", - "npmlog": "^5.0.1", - "rimraf": "^3.0.2", - "semver": "^7.3.5", - "tar": "^6.1.11" - } - }, - "@octokit/auth-token": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-2.5.0.tgz", - "integrity": "sha512-r5FVUJCOLl19AxiuZD2VRZ/ORjp/4IN98Of6YJoJOkY75CIBuYfmiNHGrDwXr+aLGG55igl9QrxX3hbiXlLb+g==", - "requires": { - "@octokit/types": "^6.0.3" - } - }, - "@octokit/core": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/@octokit/core/-/core-3.6.0.tgz", - "integrity": "sha512-7RKRKuA4xTjMhY+eG3jthb3hlZCsOwg3rztWh75Xc+ShDWOfDDATWbeZpAHBNRpm4Tv9WgBMOy1zEJYXG6NJ7Q==", - "requires": { - "@octokit/auth-token": "^2.4.4", - "@octokit/graphql": "^4.5.8", - "@octokit/request": "^5.6.3", - "@octokit/request-error": "^2.0.5", - "@octokit/types": "^6.0.3", - "before-after-hook": "^2.2.0", - "universal-user-agent": "^6.0.0" - } - }, - "@octokit/endpoint": { - "version": "6.0.12", - "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-6.0.12.tgz", - "integrity": "sha512-lF3puPwkQWGfkMClXb4k/eUT/nZKQfxinRWJrdZaJO85Dqwo/G0yOC434Jr2ojwafWJMYqFGFa5ms4jJUgujdA==", - "requires": { - "@octokit/types": "^6.0.3", - "is-plain-object": "^5.0.0", - "universal-user-agent": "^6.0.0" - } - }, - "@octokit/graphql": { - "version": "4.8.0", - "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-4.8.0.tgz", - "integrity": "sha512-0gv+qLSBLKF0z8TKaSKTsS39scVKF9dbMxJpj3U0vC7wjNWFuIpL/z76Qe2fiuCbDRcJSavkXsVtMS6/dtQQsg==", - "requires": { - "@octokit/request": "^5.6.0", - "@octokit/types": "^6.0.3", - "universal-user-agent": "^6.0.0" - } - }, - "@octokit/openapi-types": { - "version": "11.2.0", - "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-11.2.0.tgz", - "integrity": "sha512-PBsVO+15KSlGmiI8QAzaqvsNlZlrDlyAJYcrXBCvVUxCp7VnXjkwPoFHgjEJXx3WF9BAwkA6nfCUA7i9sODzKA==" - }, - "@octokit/plugin-paginate-rest": { - "version": "2.17.0", - "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-2.17.0.tgz", - "integrity": "sha512-tzMbrbnam2Mt4AhuyCHvpRkS0oZ5MvwwcQPYGtMv4tUa5kkzG58SVB0fcsLulOZQeRnOgdkZWkRUiyBlh0Bkyw==", - "requires": { - "@octokit/types": "^6.34.0" - } - }, - "@octokit/plugin-rest-endpoint-methods": { - "version": "5.13.0", - "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-5.13.0.tgz", - "integrity": "sha512-uJjMTkN1KaOIgNtUPMtIXDOjx6dGYysdIFhgA52x4xSadQCz3b/zJexvITDVpANnfKPW/+E0xkOvLntqMYpviA==", - "requires": { - "@octokit/types": "^6.34.0", - "deprecation": "^2.3.1" - } - }, - "@octokit/request": { - "version": "5.6.3", - "resolved": "https://registry.npmjs.org/@octokit/request/-/request-5.6.3.tgz", - "integrity": "sha512-bFJl0I1KVc9jYTe9tdGGpAMPy32dLBXXo1dS/YwSCTL/2nd9XeHsY616RE3HPXDVk+a+dBuzyz5YdlXwcDTr2A==", - "requires": { - "@octokit/endpoint": "^6.0.1", - "@octokit/request-error": "^2.1.0", - "@octokit/types": "^6.16.1", - "is-plain-object": "^5.0.0", - "node-fetch": "^2.6.7", - "universal-user-agent": "^6.0.0" - } - }, - "@octokit/request-error": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-2.1.0.tgz", - "integrity": "sha512-1VIvgXxs9WHSjicsRwq8PlR2LR2x6DwsJAaFgzdi0JfJoGSO8mYI/cHJQ+9FbN21aa+DrgNLnwObmyeSC8Rmpg==", - "requires": { - "@octokit/types": "^6.0.3", - "deprecation": "^2.0.0", - "once": "^1.4.0" - } - }, - "@octokit/types": { - "version": "6.34.0", - "resolved": "https://registry.npmjs.org/@octokit/types/-/types-6.34.0.tgz", - "integrity": "sha512-s1zLBjWhdEI2zwaoSgyOFoKSl109CUcVBCc7biPJ3aAf6LGLU6szDvi31JPU7bxfla2lqfhjbbg/5DdFNxOwHw==", - "requires": { - "@octokit/openapi-types": "^11.2.0" - } - }, - "@types/json5": { - "version": "0.0.29", - "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", - "integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=", - "dev": true - }, - "abbrev": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" - }, - "acorn": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", - "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", - "dev": true - }, - "acorn-jsx": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true, - "requires": {} - }, - "agent-base": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", - "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", - "requires": { - "debug": "4" - } - }, - "ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "ansi-colors": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", - "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", - "dev": true - }, - "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==" - }, - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "aproba": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz", - "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==" - }, - "are-we-there-yet": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-2.0.0.tgz", - "integrity": "sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==", - "requires": { - "delegates": "^1.0.0", - "readable-stream": "^3.6.0" - } - }, - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "requires": { - "sprintf-js": "~1.0.2" - } - }, - "array-includes": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.4.tgz", - "integrity": "sha512-ZTNSQkmWumEbiHO2GF4GmWxYVTiQyJy2XOTa15sdQSrvKn7l+180egQMqlrMOUMCyLMD7pmyQe4mMDUT6Behrw==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.1", - "get-intrinsic": "^1.1.1", - "is-string": "^1.0.7" - } - }, - "array.prototype.flat": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.2.5.tgz", - "integrity": "sha512-KaYU+S+ndVqyUnignHftkwc58o3uVU1jzczILJ1tN2YaIZpFIKBiP/x/j97E5MVPsaCloPbqWLB/8qCTVvT2qg==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.0" - } - }, - "astral-regex": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", - "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", - "dev": true - }, - "balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" - }, - "before-after-hook": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.2.tgz", - "integrity": "sha512-3pZEU3NT5BFUo/AD5ERPWOgQOCZITni6iavr5AUw5AUwQjMlI0kzu5btnyD39AF0gUEsDPwJT+oY1ORBJijPjQ==" - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", - "dev": true, - "requires": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" - } - }, - "callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true - }, - "canvas": { - "version": "2.9.1", - "resolved": "https://registry.npmjs.org/canvas/-/canvas-2.9.1.tgz", - "integrity": "sha512-vSQti1uG/2gjv3x6QLOZw7TctfufaerTWbVe+NSduHxxLGB+qf3kFgQ6n66DSnuoINtVUjrLLIK2R+lxrBG07A==", - "requires": { - "@mapbox/node-pre-gyp": "^1.0.0", - "nan": "^2.15.0", - "simple-get": "^3.0.3" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "chart.js": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/chart.js/-/chart.js-3.7.1.tgz", - "integrity": "sha512-8knRegQLFnPQAheZV8MjxIXc5gQEfDFD897BJgv/klO/vtIyFFmgMXrNfgrXpbTr/XbTturxRgxIXx/Y+ASJBA==" - }, - "chartjs-node-canvas": { - "version": "4.1.6", - "resolved": "https://registry.npmjs.org/chartjs-node-canvas/-/chartjs-node-canvas-4.1.6.tgz", - "integrity": "sha512-UQJbPWrvqB/FoLclGA9BaLQmZbzSYlujF4w8NZd6Xzb+sqgACBb2owDX6m7ifCXLjUW5Nz0Qx0qqrTtQkkSoYw==", - "requires": { - "canvas": "^2.8.0", - "tslib": "^2.3.1" - } - }, - "chownr": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", - "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==" - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "color-support": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", - "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==" - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" - }, - "console-control-strings": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", - "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=" - }, - "cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "requires": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - } - }, - "debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "requires": { - "ms": "2.1.2" - } - }, - "decompress-response": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-4.2.1.tgz", - "integrity": "sha512-jOSne2qbyE+/r8G1VU+G/82LBs2Fs4LAsTiLSHOCOMZQl2OKZ6i8i4IyHemTe+/yIXOtTcRQMzPcgyhoFlqPkw==", - "requires": { - "mimic-response": "^2.0.0" - } - }, - "deep-is": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true - }, - "define-properties": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", - "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", - "dev": true, - "requires": { - "object-keys": "^1.0.12" - } - }, - "delegates": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", - "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=" - }, - "deprecation": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz", - "integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==" - }, - "detect-libc": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", - "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=" - }, - "doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "dev": true, - "requires": { - "esutils": "^2.0.2" - } - }, - "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" - }, - "enquirer": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", - "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", - "dev": true, - "requires": { - "ansi-colors": "^4.1.1" - } - }, - "es-abstract": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.19.1.tgz", - "integrity": "sha512-2vJ6tjA/UfqLm2MPs7jxVybLoB8i1t1Jd9R3kISld20sIxPcTbLuggQOUxeWeAvIUkduv/CfMjuh4WmiXr2v9w==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "get-intrinsic": "^1.1.1", - "get-symbol-description": "^1.0.0", - "has": "^1.0.3", - "has-symbols": "^1.0.2", - "internal-slot": "^1.0.3", - "is-callable": "^1.2.4", - "is-negative-zero": "^2.0.1", - "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.1", - "is-string": "^1.0.7", - "is-weakref": "^1.0.1", - "object-inspect": "^1.11.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.2", - "string.prototype.trimend": "^1.0.4", - "string.prototype.trimstart": "^1.0.4", - "unbox-primitive": "^1.0.1" - } - }, - "es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "dev": true, - "requires": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - } - }, - "escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true - }, - "eslint": { - "version": "7.32.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.32.0.tgz", - "integrity": "sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA==", - "dev": true, - "requires": { - "@babel/code-frame": "7.12.11", - "@eslint/eslintrc": "^0.4.3", - "@humanwhocodes/config-array": "^0.5.0", - "ajv": "^6.10.0", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.0.1", - "doctrine": "^3.0.0", - "enquirer": "^2.3.5", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^5.1.1", - "eslint-utils": "^2.1.0", - "eslint-visitor-keys": "^2.0.0", - "espree": "^7.3.1", - "esquery": "^1.4.0", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", - "functional-red-black-tree": "^1.0.1", - "glob-parent": "^5.1.2", - "globals": "^13.6.0", - "ignore": "^4.0.6", - "import-fresh": "^3.0.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "js-yaml": "^3.13.1", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.0.4", - "natural-compare": "^1.4.0", - "optionator": "^0.9.1", - "progress": "^2.0.0", - "regexpp": "^3.1.0", - "semver": "^7.2.1", - "strip-ansi": "^6.0.0", - "strip-json-comments": "^3.1.0", - "table": "^6.0.9", - "text-table": "^0.2.0", - "v8-compile-cache": "^2.0.3" - } - }, - "eslint-config-standard": { - "version": "16.0.3", - "resolved": "https://registry.npmjs.org/eslint-config-standard/-/eslint-config-standard-16.0.3.tgz", - "integrity": "sha512-x4fmJL5hGqNJKGHSjnLdgA6U6h1YW/G2dW9fA+cyVur4SK6lyue8+UgNKWlZtUDTXvgKDD/Oa3GQjmB5kjtVvg==", - "dev": true, - "requires": {} - }, - "eslint-import-resolver-node": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.6.tgz", - "integrity": "sha512-0En0w03NRVMn9Uiyn8YRPDKvWjxCWkslUEhGNTdGx15RvPJYQ+lbOlqrlNI2vEAs4pDYK4f/HN2TbDmk5TP0iw==", - "dev": true, - "requires": { - "debug": "^3.2.7", - "resolve": "^1.20.0" - }, - "dependencies": { - "debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - } - } - }, - "eslint-module-utils": { - "version": "2.7.3", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.7.3.tgz", - "integrity": "sha512-088JEC7O3lDZM9xGe0RerkOMd0EjFl+Yvd1jPWIkMT5u3H9+HC34mWWPnqPrN13gieT9pBOO+Qt07Nb/6TresQ==", - "dev": true, - "requires": { - "debug": "^3.2.7", - "find-up": "^2.1.0" - }, - "dependencies": { - "debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - } - } - }, - "eslint-plugin-es": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-es/-/eslint-plugin-es-3.0.1.tgz", - "integrity": "sha512-GUmAsJaN4Fc7Gbtl8uOBlayo2DqhwWvEzykMHSCZHU3XdJ+NSzzZcVhXh3VxX5icqQ+oQdIEawXX8xkR3mIFmQ==", - "dev": true, - "requires": { - "eslint-utils": "^2.0.0", - "regexpp": "^3.0.0" - } - }, - "eslint-plugin-import": { - "version": "2.25.4", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.25.4.tgz", - "integrity": "sha512-/KJBASVFxpu0xg1kIBn9AUa8hQVnszpwgE7Ld0lKAlx7Ie87yzEzCgSkekt+le/YVhiaosO4Y14GDAOc41nfxA==", - "dev": true, - "requires": { - "array-includes": "^3.1.4", - "array.prototype.flat": "^1.2.5", - "debug": "^2.6.9", - "doctrine": "^2.1.0", - "eslint-import-resolver-node": "^0.3.6", - "eslint-module-utils": "^2.7.2", - "has": "^1.0.3", - "is-core-module": "^2.8.0", - "is-glob": "^4.0.3", - "minimatch": "^3.0.4", - "object.values": "^1.1.5", - "resolve": "^1.20.0", - "tsconfig-paths": "^3.12.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "doctrine": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", - "dev": true, - "requires": { - "esutils": "^2.0.2" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - } - } - }, - "eslint-plugin-node": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-11.1.0.tgz", - "integrity": "sha512-oUwtPJ1W0SKD0Tr+wqu92c5xuCeQqB3hSCHasn/ZgjFdA9iDGNkNf2Zi9ztY7X+hNuMib23LNGRm6+uN+KLE3g==", - "dev": true, - "requires": { - "eslint-plugin-es": "^3.0.0", - "eslint-utils": "^2.0.0", - "ignore": "^5.1.1", - "minimatch": "^3.0.4", - "resolve": "^1.10.1", - "semver": "^6.1.0" - }, - "dependencies": { - "ignore": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", - "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", - "dev": true - }, - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - } - } - }, - "eslint-plugin-promise": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-5.2.0.tgz", - "integrity": "sha512-SftLb1pUG01QYq2A/hGAWfDRXqYD82zE7j7TopDOyNdU+7SvvoXREls/+PRTY17vUXzXnZA/zfnyKgRH6x4JJw==", - "dev": true, - "requires": {} - }, - "eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", - "dev": true, - "requires": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - } - }, - "eslint-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", - "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", - "dev": true, - "requires": { - "eslint-visitor-keys": "^1.1.0" - }, - "dependencies": { - "eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", - "dev": true - } - } - }, - "eslint-visitor-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", - "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", - "dev": true - }, - "espree": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", - "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==", - "dev": true, - "requires": { - "acorn": "^7.4.0", - "acorn-jsx": "^5.3.1", - "eslint-visitor-keys": "^1.3.0" - }, - "dependencies": { - "eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", - "dev": true - } - } - }, - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true - }, - "esquery": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", - "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", - "dev": true, - "requires": { - "estraverse": "^5.1.0" - }, - "dependencies": { - "estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true - } - } - }, - "esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "dev": true, - "requires": { - "estraverse": "^5.2.0" - }, - "dependencies": { - "estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true - } - } - }, - "estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true - }, - "esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true - }, - "fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true - }, - "fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true - }, - "fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", - "dev": true - }, - "file-entry-cache": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", - "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", - "dev": true, - "requires": { - "flat-cache": "^3.0.4" - } - }, - "find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", - "dev": true, - "requires": { - "locate-path": "^2.0.0" - } - }, - "flat-cache": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", - "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", - "dev": true, - "requires": { - "flatted": "^3.1.0", - "rimraf": "^3.0.2" - } - }, - "flatted": { - "version": "3.2.5", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.5.tgz", - "integrity": "sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg==", - "dev": true - }, - "fs-minipass": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", - "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", - "requires": { - "minipass": "^3.0.0" - } - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" - }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true - }, - "functional-red-black-tree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", - "dev": true - }, - "gauge": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/gauge/-/gauge-3.0.2.tgz", - "integrity": "sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q==", - "requires": { - "aproba": "^1.0.3 || ^2.0.0", - "color-support": "^1.1.2", - "console-control-strings": "^1.0.0", - "has-unicode": "^2.0.1", - "object-assign": "^4.1.1", - "signal-exit": "^3.0.0", - "string-width": "^4.2.3", - "strip-ansi": "^6.0.1", - "wide-align": "^1.1.2" - } - }, - "get-intrinsic": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", - "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", - "dev": true, - "requires": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1" - } - }, - "get-symbol-description": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", - "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.1" - } - }, - "glob": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", - "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "requires": { - "is-glob": "^4.0.1" - } - }, - "globals": { - "version": "13.13.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.13.0.tgz", - "integrity": "sha512-EQ7Q18AJlPwp3vUDL4mKA0KXrXyNIQyWon6T6XQiBQF0XHvRsiCSrWmmeATpUzdJN2HhWZU6Pdl0a9zdep5p6A==", - "dev": true, - "requires": { - "type-fest": "^0.20.2" - } - }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, - "requires": { - "function-bind": "^1.1.1" - } - }, - "has-bigints": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz", - "integrity": "sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==", - "dev": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", - "dev": true - }, - "has-tostringtag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", - "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", - "dev": true, - "requires": { - "has-symbols": "^1.0.2" - } - }, - "has-unicode": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", - "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=" - }, - "https-proxy-agent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz", - "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==", - "requires": { - "agent-base": "6", - "debug": "4" - } - }, - "ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", - "dev": true - }, - "import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "dev": true, - "requires": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - } - }, - "imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", - "dev": true - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "internal-slot": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz", - "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==", - "dev": true, - "requires": { - "get-intrinsic": "^1.1.0", - "has": "^1.0.3", - "side-channel": "^1.0.4" - } - }, - "is-bigint": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", - "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", - "dev": true, - "requires": { - "has-bigints": "^1.0.1" - } - }, - "is-boolean-object": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", - "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - } - }, - "is-callable": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.4.tgz", - "integrity": "sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==", - "dev": true - }, - "is-core-module": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.1.tgz", - "integrity": "sha512-SdNCUs284hr40hFTFP6l0IfZ/RSrMXF3qgoRHd3/79unUTvrFO/JoXwkGm+5J/Oe3E/b5GsnG330uUNgRpu1PA==", - "dev": true, - "requires": { - "has": "^1.0.3" - } - }, - "is-date-object": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", - "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", - "dev": true, - "requires": { - "has-tostringtag": "^1.0.0" - } - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" - }, - "is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-negative-zero": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", - "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==", - "dev": true - }, - "is-number-object": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.6.tgz", - "integrity": "sha512-bEVOqiRcvo3zO1+G2lVMy+gkkEm9Yh7cDMRusKKu5ZJKPUYSJwICTKZrNKHA2EbSP0Tu0+6B/emsYNHZyn6K8g==", - "dev": true, - "requires": { - "has-tostringtag": "^1.0.0" - } - }, - "is-plain-object": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", - "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==" - }, - "is-regex": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", - "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - } - }, - "is-shared-array-buffer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.1.tgz", - "integrity": "sha512-IU0NmyknYZN0rChcKhRO1X8LYz5Isj/Fsqh8NJOSf+N/hCOTwy29F32Ik7a+QszE63IdvmwdTPDd6cZ5pg4cwA==", - "dev": true - }, - "is-string": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", - "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", - "dev": true, - "requires": { - "has-tostringtag": "^1.0.0" - } - }, - "is-symbol": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", - "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", - "dev": true, - "requires": { - "has-symbols": "^1.0.2" - } - }, - "is-weakref": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", - "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", - "dev": true, - "requires": { - "call-bind": "^1.0.2" - } - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true - }, - "js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true - }, - "js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", - "dev": true, - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true - }, - "json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", - "dev": true - }, - "json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", - "dev": true, - "requires": { - "minimist": "^1.2.0" - } - }, - "levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", - "dev": true, - "requires": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - } - }, - "locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", - "dev": true, - "requires": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" - } - }, - "lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" - }, - "lodash.merge": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true - }, - "lodash.truncate": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", - "integrity": "sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=", - "dev": true - }, - "lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "requires": { - "yallist": "^4.0.0" - } - }, - "luxon": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/luxon/-/luxon-2.3.1.tgz", - "integrity": "sha512-I8vnjOmhXsMSlNMZlMkSOvgrxKJl0uOsEzdGgGNZuZPaS9KlefpE9KV95QFftlJSC+1UyCC9/I69R02cz/zcCA==" - }, - "make-dir": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", - "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", - "requires": { - "semver": "^6.0.0" - }, - "dependencies": { - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" - } - } - }, - "mimic-response": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-2.1.0.tgz", - "integrity": "sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA==" - }, - "minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", - "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==", - "dev": true - }, - "minipass": { - "version": "3.1.6", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.6.tgz", - "integrity": "sha512-rty5kpw9/z8SX9dmxblFA6edItUmwJgMeYDZRrwlIVN27i8gysGbznJwUggw2V/FVqFSDdWy040ZPS811DYAqQ==", - "requires": { - "yallist": "^4.0.0" - } - }, - "minizlib": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", - "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", - "requires": { - "minipass": "^3.0.0", - "yallist": "^4.0.0" - } - }, - "mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==" - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "nan": { - "version": "2.15.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.15.0.tgz", - "integrity": "sha512-8ZtvEnA2c5aYCZYd1cvgdnU6cqwixRoYg70xPLWUws5ORTa/lnw+u4amixRS/Ac5U5mQVgp9pnlSUnbNWFaWZQ==" - }, - "natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", - "dev": true - }, - "node-fetch": { - "version": "2.6.7", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", - "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", - "requires": { - "whatwg-url": "^5.0.0" - } - }, - "nopt": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz", - "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==", - "requires": { - "abbrev": "1" - } - }, - "npmlog": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-5.0.1.tgz", - "integrity": "sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==", - "requires": { - "are-we-there-yet": "^2.0.0", - "console-control-strings": "^1.1.0", - "gauge": "^3.0.0", - "set-blocking": "^2.0.0" - } - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" - }, - "object-inspect": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.0.tgz", - "integrity": "sha512-Ho2z80bVIvJloH+YzRmpZVQe87+qASmBUKZDWgx9cu+KDrX2ZDH/3tMy+gXbZETVGs2M8YdxObOh7XAtim9Y0g==", - "dev": true - }, - "object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true - }, - "object.assign": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", - "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", - "dev": true, - "requires": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3", - "has-symbols": "^1.0.1", - "object-keys": "^1.1.1" - } - }, - "object.values": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.5.tgz", - "integrity": "sha512-QUZRW0ilQ3PnPpbNtgdNV1PDbEqLIiSFB3l+EnGtBQ/8SUTLj1PZwtQHABZtLgwpJZTSZhuGLOGk57Drx2IvYg==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.1" - } - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "requires": { - "wrappy": "1" - } - }, - "optionator": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", - "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", - "dev": true, - "requires": { - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.3" - } - }, - "p-limit": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", - "dev": true, - "requires": { - "p-try": "^1.0.0" - } - }, - "p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", - "dev": true, - "requires": { - "p-limit": "^1.1.0" - } - }, - "p-try": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", - "dev": true - }, - "parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, - "requires": { - "callsites": "^3.0.0" - } - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "dev": true - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" - }, - "path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true - }, - "path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true - }, - "prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", - "dev": true - }, - "progress": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", - "dev": true - }, - "punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", - "dev": true - }, - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - }, - "regexpp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", - "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", - "dev": true - }, - "require-from-string": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", - "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", - "dev": true - }, - "resolve": { - "version": "1.22.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.0.tgz", - "integrity": "sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw==", - "dev": true, - "requires": { - "is-core-module": "^2.8.1", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - } - }, - "resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true - }, - "rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "requires": { - "glob": "^7.1.3" - } - }, - "safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" - }, - "semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", - "requires": { - "lru-cache": "^6.0.0" - } - }, - "set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" - }, - "shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "requires": { - "shebang-regex": "^3.0.0" - } - }, - "shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true - }, - "side-channel": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", - "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", - "dev": true, - "requires": { - "call-bind": "^1.0.0", - "get-intrinsic": "^1.0.2", - "object-inspect": "^1.9.0" - } - }, - "signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" - }, - "simple-concat": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", - "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==" - }, - "simple-get": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-3.1.1.tgz", - "integrity": "sha512-CQ5LTKGfCpvE1K0n2us+kuMPbk/q0EKl82s4aheV9oXjFEz6W/Y7oQFVJuU6QG77hRT4Ghb5RURteF5vnWjupA==", - "requires": { - "decompress-response": "^4.2.0", - "once": "^1.3.1", - "simple-concat": "^1.0.0" - } - }, - "slice-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", - "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", - "dev": true, - "requires": { - "ansi-styles": "^4.0.0", - "astral-regex": "^2.0.0", - "is-fullwidth-code-point": "^3.0.0" - } - }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", - "dev": true - }, - "string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "requires": { - "safe-buffer": "~5.2.0" - } - }, - "string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - } - }, - "string.prototype.trimend": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz", - "integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3" - } - }, - "string.prototype.trimstart": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz", - "integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3" - } - }, - "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "requires": { - "ansi-regex": "^5.0.1" - } - }, - "strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", - "dev": true - }, - "strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - }, - "supports-preserve-symlinks-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", - "dev": true - }, - "table": { - "version": "6.8.0", - "resolved": "https://registry.npmjs.org/table/-/table-6.8.0.tgz", - "integrity": "sha512-s/fitrbVeEyHKFa7mFdkuQMWlH1Wgw/yEXMt5xACT4ZpzWFluehAxRtUUQKPuWhaLAWhFcVx6w3oC8VKaUfPGA==", - "dev": true, - "requires": { - "ajv": "^8.0.1", - "lodash.truncate": "^4.4.2", - "slice-ansi": "^4.0.0", - "string-width": "^4.2.3", - "strip-ansi": "^6.0.1" - }, - "dependencies": { - "ajv": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", - "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - } - }, - "json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true - } - } - }, - "tar": { - "version": "6.1.11", - "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.11.tgz", - "integrity": "sha512-an/KZQzQUkZCkuoAA64hM92X0Urb6VpRhAFllDzz44U2mcD5scmT3zBc4VgVpkugF580+DQn8eAFSyoQt0tznA==", - "requires": { - "chownr": "^2.0.0", - "fs-minipass": "^2.0.0", - "minipass": "^3.0.0", - "minizlib": "^2.1.1", - "mkdirp": "^1.0.3", - "yallist": "^4.0.0" - } - }, - "text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", - "dev": true - }, - "tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=" - }, - "tsconfig-paths": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.1.tgz", - "integrity": "sha512-fxDhWnFSLt3VuTwtvJt5fpwxBHg5AdKWMsgcPOOIilyjymcYVZoCQF8fvFRezCNfblEXmi+PcM1eYHeOAgXCOQ==", - "dev": true, - "requires": { - "@types/json5": "^0.0.29", - "json5": "^1.0.1", - "minimist": "^1.2.6", - "strip-bom": "^3.0.0" - } - }, - "tslib": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", - "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" - }, - "tunnel": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz", - "integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==" - }, - "type-check": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", - "dev": true, - "requires": { - "prelude-ls": "^1.2.1" - } - }, - "type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true - }, - "unbox-primitive": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz", - "integrity": "sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw==", - "dev": true, - "requires": { - "function-bind": "^1.1.1", - "has-bigints": "^1.0.1", - "has-symbols": "^1.0.2", - "which-boxed-primitive": "^1.0.2" - } + "undici": { + "version": "6.27.0", + "resolved": "https://registry.npmjs.org/undici/-/undici-6.27.0.tgz", + "integrity": "sha512-YmfV3YnEDzXRC5lZ2jWtWWHKGUm1zIt8AhesR1tens+HTNv+YZlN/dp6G727LOvMJ8xjP9Be7Y2Sdr96LDm+pg==" }, "universal-user-agent": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.0.tgz", - "integrity": "sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w==" - }, - "uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dev": true, - "requires": { - "punycode": "^2.1.0" - } - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" - }, - "v8-compile-cache": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", - "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", - "dev": true - }, - "webidl-conversions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=" - }, - "whatwg-url": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=", - "requires": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" - } - }, - "which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - }, - "which-boxed-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", - "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", - "dev": true, - "requires": { - "is-bigint": "^1.0.1", - "is-boolean-object": "^1.1.0", - "is-number-object": "^1.0.4", - "is-string": "^1.0.5", - "is-symbol": "^1.0.3" - } - }, - "wide-align": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz", - "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==", - "requires": { - "string-width": "^1.0.2 || 2 || 3 || 4" - } - }, - "word-wrap": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", - "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", - "dev": true - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" - }, - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-7.0.3.tgz", + "integrity": "sha512-TmnEAEAsBJVZM/AADELsK76llnwcf9vMKuPz8JflO1frO8Lchitr0fNaN9d+Ap0BjKtqWqd/J17qeDnXh8CL2A==" } } } diff --git a/dev/coverage-action/package.json b/dev/coverage-action/package.json index 8a46cdf62e1..4607922d81a 100644 --- a/dev/coverage-action/package.json +++ b/dev/coverage-action/package.json @@ -2,22 +2,13 @@ "name": "coverage-action", "version": "1.0.0", "description": "Parse and generate coverage and changelog files for Datatracker releases", - "main": "index.js", - "author": "IETF Trust", "license": "BSD-3-Clause", + "author": "IETF Trust", + "type": "module", + "main": "index.js", "dependencies": { - "@actions/core": "1.6.0", - "@actions/github": "5.0.0", - "chart.js": "3.7.1", - "chartjs-node-canvas": "4.1.6", - "lodash": "4.17.21", - "luxon": "2.3.1" - }, - "devDependencies": { - "eslint": "7.32.0", - "eslint-config-standard": "16.0.3", - "eslint-plugin-import": "2.25.4", - "eslint-plugin-node": "11.1.0", - "eslint-plugin-promise": "5.2.0" + "@actions/core": "3.0.1", + "@actions/github": "9.1.1", + "es-toolkit": "1.50.0" } } diff --git a/dev/del-old-packages/.gitignore b/dev/del-old-packages/.gitignore new file mode 100644 index 00000000000..07e6e472cc7 --- /dev/null +++ b/dev/del-old-packages/.gitignore @@ -0,0 +1 @@ +/node_modules diff --git a/dev/del-old-packages/.npmrc b/dev/del-old-packages/.npmrc new file mode 100644 index 00000000000..fcbbb678280 --- /dev/null +++ b/dev/del-old-packages/.npmrc @@ -0,0 +1,5 @@ +audit = false +fund = false +save-exact = true +save-prefix = "" +update-notifier = false diff --git a/dev/del-old-packages/README.md b/dev/del-old-packages/README.md new file mode 100644 index 00000000000..5f8f88e09e3 --- /dev/null +++ b/dev/del-old-packages/README.md @@ -0,0 +1,15 @@ +## Tool to delete old versions in GitHub Packages container registry + +This tool will fetch all versions for packages `datatracker-db` and `datatracker-db-pg` and delete all versions that are not latest and older than 7 days. + +### Requirements + +- Node 18.x or later +- Must provide a valid token in ENV variable `GITHUB_TOKEN` with read and delete packages permissions. + +### Usage + +```sh +npm install +node index +``` \ No newline at end of file diff --git a/dev/del-old-packages/index.js b/dev/del-old-packages/index.js new file mode 100644 index 00000000000..d41b971e3e9 --- /dev/null +++ b/dev/del-old-packages/index.js @@ -0,0 +1,64 @@ +import { Octokit } from '@octokit/core' +import { setTimeout } from 'node:timers/promises' +import { DateTime } from 'luxon' + +const octokit = new Octokit({ + auth: process.env.GITHUB_TOKEN +}) + +const oldestDate = DateTime.utc().minus({ days: 7 }) + +for (const pkgName of ['datatracker-db']) { + let hasMore = true + let currentPage = 1 + + while (hasMore) { + try { + console.info(`Fetching page ${currentPage}...`) + const versions = await octokit.request( + 'GET /orgs/{org}/packages/{package_type}/{package_name}/versions{?page,per_page,state}', + { + package_type: 'container', + package_name: pkgName, + org: 'ietf-tools', + page: currentPage, + per_page: 100 + } + ) + if (versions?.data?.length > 0) { + for (const ver of versions?.data) { + const verDate = DateTime.fromISO(ver.created_at) + if ( + ver?.metadata?.container?.tags?.includes('latest') || + ver?.metadata?.container?.tags?.includes('latest-arm64') || + ver?.metadata?.container?.tags?.includes('latest-x64') + ) { + console.info(`Latest package (${ver.id})... Skipping...`) + } else if (verDate > oldestDate) { + console.info(`Recent package (${ver.id}, ${verDate.toRelative()})... Skipping...`) + } else { + console.info(`Deleting package version ${ver.id}...`) + await octokit.request( + 'DELETE /orgs/{org}/packages/{package_type}/{package_name}/versions/{package_version_id}', + { + package_type: 'container', + package_name: pkgName, + org: 'ietf-tools', + package_version_id: ver.id + } + ) + await setTimeout(250) + } + } + currentPage++ + hasMore = true + } else { + hasMore = false + console.info('No more versions for this package.') + } + } catch (err) { + console.error(err) + hasMore = false + } + } +} diff --git a/dev/del-old-packages/package-lock.json b/dev/del-old-packages/package-lock.json new file mode 100644 index 00000000000..e866242de07 --- /dev/null +++ b/dev/del-old-packages/package-lock.json @@ -0,0 +1,254 @@ +{ + "name": "del-packages", + "version": "1.0.0", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "name": "del-packages", + "version": "1.0.0", + "license": "ISC", + "dependencies": { + "@octokit/core": "7.0.6", + "luxon": "3.7.2" + } + }, + "node_modules/@octokit/auth-token": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-6.0.0.tgz", + "integrity": "sha512-P4YJBPdPSpWTQ1NU4XYdvHvXJJDxM6YwpS0FZHRgP7YFkdVxsWcpWGy/NVqlAA7PcPCnMacXlRm1y2PFZRWL/w==", + "license": "MIT", + "engines": { + "node": ">= 20" + } + }, + "node_modules/@octokit/core": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/@octokit/core/-/core-7.0.6.tgz", + "integrity": "sha512-DhGl4xMVFGVIyMwswXeyzdL4uXD5OGILGX5N8Y+f6W7LhC1Ze2poSNrkF/fedpVDHEEZ+PHFW0vL14I+mm8K3Q==", + "license": "MIT", + "dependencies": { + "@octokit/auth-token": "^6.0.0", + "@octokit/graphql": "^9.0.3", + "@octokit/request": "^10.0.6", + "@octokit/request-error": "^7.0.2", + "@octokit/types": "^16.0.0", + "before-after-hook": "^4.0.0", + "universal-user-agent": "^7.0.0" + }, + "engines": { + "node": ">= 20" + } + }, + "node_modules/@octokit/endpoint": { + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-11.0.3.tgz", + "integrity": "sha512-FWFlNxghg4HrXkD3ifYbS/IdL/mDHjh9QcsNyhQjN8dplUoZbejsdpmuqdA76nxj2xoWPs7p8uX2SNr9rYu0Ag==", + "license": "MIT", + "dependencies": { + "@octokit/types": "^16.0.0", + "universal-user-agent": "^7.0.2" + }, + "engines": { + "node": ">= 20" + } + }, + "node_modules/@octokit/graphql": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-9.0.3.tgz", + "integrity": "sha512-grAEuupr/C1rALFnXTv6ZQhFuL1D8G5y8CN04RgrO4FIPMrtm+mcZzFG7dcBm+nq+1ppNixu+Jd78aeJOYxlGA==", + "license": "MIT", + "dependencies": { + "@octokit/request": "^10.0.6", + "@octokit/types": "^16.0.0", + "universal-user-agent": "^7.0.0" + }, + "engines": { + "node": ">= 20" + } + }, + "node_modules/@octokit/openapi-types": { + "version": "27.0.0", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-27.0.0.tgz", + "integrity": "sha512-whrdktVs1h6gtR+09+QsNk2+FO+49j6ga1c55YZudfEG+oKJVvJLQi3zkOm5JjiUXAagWK2tI2kTGKJ2Ys7MGA==", + "license": "MIT" + }, + "node_modules/@octokit/request": { + "version": "10.0.11", + "resolved": "https://registry.npmjs.org/@octokit/request/-/request-10.0.11.tgz", + "integrity": "sha512-+s7HUxjfFqOMS9VlIwDffq0MikjSAK0gSpG73W+meAvVAvX4MBrHYTK5Bj3Uot55qFT4gzUtfzE4mGWY4Br8/Q==", + "license": "MIT", + "dependencies": { + "@octokit/endpoint": "^11.0.3", + "@octokit/request-error": "^7.0.2", + "@octokit/types": "^16.0.0", + "content-type": "^2.0.0", + "json-with-bigint": "^3.5.3", + "universal-user-agent": "^7.0.2" + }, + "engines": { + "node": ">= 20" + } + }, + "node_modules/@octokit/request-error": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-7.1.0.tgz", + "integrity": "sha512-KMQIfq5sOPpkQYajXHwnhjCC0slzCNScLHs9JafXc4RAJI+9f+jNDlBNaIMTvazOPLgb4BnlhGJOTbnN0wIjPw==", + "license": "MIT", + "dependencies": { + "@octokit/types": "^16.0.0" + }, + "engines": { + "node": ">= 20" + } + }, + "node_modules/@octokit/types": { + "version": "16.0.0", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-16.0.0.tgz", + "integrity": "sha512-sKq+9r1Mm4efXW1FCk7hFSeJo4QKreL/tTbR0rz/qx/r1Oa2VV83LTA/H/MuCOX7uCIJmQVRKBcbmWoySjAnSg==", + "license": "MIT", + "dependencies": { + "@octokit/openapi-types": "^27.0.0" + } + }, + "node_modules/before-after-hook": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-4.0.0.tgz", + "integrity": "sha512-q6tR3RPqIB1pMiTRMFcZwuG5T8vwp+vUvEG0vuI6B+Rikh5BfPp2fQ82c925FOs+b0lcFQ8CFrL+KbilfZFhOQ==", + "license": "Apache-2.0" + }, + "node_modules/content-type": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-2.0.0.tgz", + "integrity": "sha512-j/O/d7GcZCyNl7/hwZAb606rzqkyvaDctLmckbxLzHvFBzTJHuGEdodATcP3yIRoDrLHkIATJuvzbFlp/ki2cQ==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/json-with-bigint": { + "version": "3.5.8", + "resolved": "https://registry.npmjs.org/json-with-bigint/-/json-with-bigint-3.5.8.tgz", + "integrity": "sha512-eq/4KP6K34kwa7TcFdtvnftvHCD9KvHOGGICWwMFc4dOOKF5t4iYqnfLK8otCRCRv06FXOzGGyqE8h8ElMvvdw==", + "license": "MIT" + }, + "node_modules/luxon": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/luxon/-/luxon-3.7.2.tgz", + "integrity": "sha512-vtEhXh/gNjI9Yg1u4jX/0YVPMvxzHuGgCm6tC5kZyb08yjGWGnqAjGJvcXbqQR2P3MyMEFnRbpcdFS6PBcLqew==", + "license": "MIT", + "engines": { + "node": ">=12" + } + }, + "node_modules/universal-user-agent": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-7.0.3.tgz", + "integrity": "sha512-TmnEAEAsBJVZM/AADELsK76llnwcf9vMKuPz8JflO1frO8Lchitr0fNaN9d+Ap0BjKtqWqd/J17qeDnXh8CL2A==", + "license": "ISC" + } + }, + "dependencies": { + "@octokit/auth-token": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-6.0.0.tgz", + "integrity": "sha512-P4YJBPdPSpWTQ1NU4XYdvHvXJJDxM6YwpS0FZHRgP7YFkdVxsWcpWGy/NVqlAA7PcPCnMacXlRm1y2PFZRWL/w==" + }, + "@octokit/core": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/@octokit/core/-/core-7.0.6.tgz", + "integrity": "sha512-DhGl4xMVFGVIyMwswXeyzdL4uXD5OGILGX5N8Y+f6W7LhC1Ze2poSNrkF/fedpVDHEEZ+PHFW0vL14I+mm8K3Q==", + "requires": { + "@octokit/auth-token": "^6.0.0", + "@octokit/graphql": "^9.0.3", + "@octokit/request": "^10.0.6", + "@octokit/request-error": "^7.0.2", + "@octokit/types": "^16.0.0", + "before-after-hook": "^4.0.0", + "universal-user-agent": "^7.0.0" + } + }, + "@octokit/endpoint": { + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-11.0.3.tgz", + "integrity": "sha512-FWFlNxghg4HrXkD3ifYbS/IdL/mDHjh9QcsNyhQjN8dplUoZbejsdpmuqdA76nxj2xoWPs7p8uX2SNr9rYu0Ag==", + "requires": { + "@octokit/types": "^16.0.0", + "universal-user-agent": "^7.0.2" + } + }, + "@octokit/graphql": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-9.0.3.tgz", + "integrity": "sha512-grAEuupr/C1rALFnXTv6ZQhFuL1D8G5y8CN04RgrO4FIPMrtm+mcZzFG7dcBm+nq+1ppNixu+Jd78aeJOYxlGA==", + "requires": { + "@octokit/request": "^10.0.6", + "@octokit/types": "^16.0.0", + "universal-user-agent": "^7.0.0" + } + }, + "@octokit/openapi-types": { + "version": "27.0.0", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-27.0.0.tgz", + "integrity": "sha512-whrdktVs1h6gtR+09+QsNk2+FO+49j6ga1c55YZudfEG+oKJVvJLQi3zkOm5JjiUXAagWK2tI2kTGKJ2Ys7MGA==" + }, + "@octokit/request": { + "version": "10.0.11", + "resolved": "https://registry.npmjs.org/@octokit/request/-/request-10.0.11.tgz", + "integrity": "sha512-+s7HUxjfFqOMS9VlIwDffq0MikjSAK0gSpG73W+meAvVAvX4MBrHYTK5Bj3Uot55qFT4gzUtfzE4mGWY4Br8/Q==", + "requires": { + "@octokit/endpoint": "^11.0.3", + "@octokit/request-error": "^7.0.2", + "@octokit/types": "^16.0.0", + "content-type": "^2.0.0", + "json-with-bigint": "^3.5.3", + "universal-user-agent": "^7.0.2" + } + }, + "@octokit/request-error": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-7.1.0.tgz", + "integrity": "sha512-KMQIfq5sOPpkQYajXHwnhjCC0slzCNScLHs9JafXc4RAJI+9f+jNDlBNaIMTvazOPLgb4BnlhGJOTbnN0wIjPw==", + "requires": { + "@octokit/types": "^16.0.0" + } + }, + "@octokit/types": { + "version": "16.0.0", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-16.0.0.tgz", + "integrity": "sha512-sKq+9r1Mm4efXW1FCk7hFSeJo4QKreL/tTbR0rz/qx/r1Oa2VV83LTA/H/MuCOX7uCIJmQVRKBcbmWoySjAnSg==", + "requires": { + "@octokit/openapi-types": "^27.0.0" + } + }, + "before-after-hook": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-4.0.0.tgz", + "integrity": "sha512-q6tR3RPqIB1pMiTRMFcZwuG5T8vwp+vUvEG0vuI6B+Rikh5BfPp2fQ82c925FOs+b0lcFQ8CFrL+KbilfZFhOQ==" + }, + "content-type": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-2.0.0.tgz", + "integrity": "sha512-j/O/d7GcZCyNl7/hwZAb606rzqkyvaDctLmckbxLzHvFBzTJHuGEdodATcP3yIRoDrLHkIATJuvzbFlp/ki2cQ==" + }, + "json-with-bigint": { + "version": "3.5.8", + "resolved": "https://registry.npmjs.org/json-with-bigint/-/json-with-bigint-3.5.8.tgz", + "integrity": "sha512-eq/4KP6K34kwa7TcFdtvnftvHCD9KvHOGGICWwMFc4dOOKF5t4iYqnfLK8otCRCRv06FXOzGGyqE8h8ElMvvdw==" + }, + "luxon": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/luxon/-/luxon-3.7.2.tgz", + "integrity": "sha512-vtEhXh/gNjI9Yg1u4jX/0YVPMvxzHuGgCm6tC5kZyb08yjGWGnqAjGJvcXbqQR2P3MyMEFnRbpcdFS6PBcLqew==" + }, + "universal-user-agent": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-7.0.3.tgz", + "integrity": "sha512-TmnEAEAsBJVZM/AADELsK76llnwcf9vMKuPz8JflO1frO8Lchitr0fNaN9d+Ap0BjKtqWqd/J17qeDnXh8CL2A==" + } + } +} diff --git a/dev/del-old-packages/package.json b/dev/del-old-packages/package.json new file mode 100644 index 00000000000..fb491db98c6 --- /dev/null +++ b/dev/del-old-packages/package.json @@ -0,0 +1,16 @@ +{ + "name": "del-packages", + "version": "1.0.0", + "description": "", + "license": "ISC", + "author": "", + "type": "module", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "dependencies": { + "@octokit/core": "7.0.6", + "luxon": "3.7.2" + } +} diff --git a/dev/deploy/build.sh b/dev/deploy/build.sh deleted file mode 100644 index a802acb46ba..00000000000 --- a/dev/deploy/build.sh +++ /dev/null @@ -1,11 +0,0 @@ -#!/bin/bash - -echo "Compiling native node packages..." -yarn rebuild -echo "Packaging static assets..." -if [ "${SHOULD_DEPLOY}" = "true" ]; then - yarn build --base=https://www.ietf.org/lib/dt/$PKG_VERSION/ -else - yarn build -fi -yarn legacy:build diff --git a/dev/diff/.editorconfig b/dev/diff/.editorconfig deleted file mode 100644 index fec5c665197..00000000000 --- a/dev/diff/.editorconfig +++ /dev/null @@ -1,7 +0,0 @@ -[*] -indent_size = 2 -indent_style = space -charset = utf-8 -trim_trailing_whitespace = false -end_of_line = lf -insert_final_newline = true diff --git a/dev/diff/.npmrc b/dev/diff/.npmrc new file mode 100644 index 00000000000..fcbbb678280 --- /dev/null +++ b/dev/diff/.npmrc @@ -0,0 +1,5 @@ +audit = false +fund = false +save-exact = true +save-prefix = "" +update-notifier = false diff --git a/dev/diff/README.md b/dev/diff/README.md index 7b9838a904c..5e635d0e55d 100644 --- a/dev/diff/README.md +++ b/dev/diff/README.md @@ -1 +1,22 @@ -# diff +# Datatracker Diff Tool + +This tool facilitates testing 2 different datatracker instances (with their own database) and look for changes using the diff tool. Everything runs in docker containers. + +The source instance will use the code from where it is run. The target instance can be a remote tag / branch / commmit or another local folder. + +## Requirements + +- Node `26.x` or later +- Docker + +## Usage + +1. From the `dev/diff` directory, run the command: +```sh +npm install +``` +2. Then run the command: +```sh +node cli +``` +3. Follow the on-screen instructions. diff --git a/dev/diff/cli.js b/dev/diff/cli.js index 2170b77b720..c6479f26f4d 100644 --- a/dev/diff/cli.js +++ b/dev/diff/cli.js @@ -10,7 +10,7 @@ import { pipeline } from 'stream/promises' import { PassThrough } from 'stream' import prettyBytes from 'pretty-bytes' import extract from 'extract-zip' -import tar from 'tar' +import * as tar from 'tar' import { kebabCase } from 'lodash-es' import { Listr } from 'listr2' import { performance } from 'perf_hooks' @@ -18,9 +18,8 @@ import { Duration } from 'luxon' import keypress from 'keypress' let dock = null -let diffOutput = [] const diffStack = [] -const config = { +const config = { options: [], source: process.cwd(), target: null, @@ -39,20 +38,20 @@ const sha1reg = /^[0-9a-f]{5,40}$/ /** * Prompt the user for a path - * + * * @param {Task} task Listr task instance * @param {String} msg Prompt message * @param {Boolean} mustExist Whether the path must already exist * @returns path */ -async function promptForPath (task, msg, mustExist = true, initial) { +async function promptForPath(task, msg, mustExist = true, initial) { return task.prompt([ { type: 'input', name: 'path', message: msg, initial, - async validate (input) { + async validate(input) { if (!input) { return 'You must provide a valid path!' } @@ -60,7 +59,7 @@ async function promptForPath (task, msg, mustExist = true, initial) { if (proposedPath.includes(config.source)) { return 'Path must be different than the current datatracker project path!' } else if (mustExist && !(await fs.pathExists(proposedPath))) { - return 'Path is invalid or doesn\'t exist!' + return "Path is invalid or doesn't exist!" } else { return true } @@ -71,24 +70,21 @@ async function promptForPath (task, msg, mustExist = true, initial) { /** * Download and Extract a zip archive - * + * * @param {Task} task Listr task instance * @param {Object} param1 Options */ -async function downloadExtractZip (task, { msg, url, ext = 'zip', branch }) { +async function downloadExtractZip(task, { msg, url, ext = 'zip', branch }) { const archivePath = path.join(config.target, `archive.${ext}`) await fs.emptyDir(config.target) // Download zip try { task.title = msg const downloadBranchStream = got.stream(url) - downloadBranchStream.on('downloadProgress', progress => { + downloadBranchStream.on('downloadProgress', (progress) => { task.output = `${prettyBytes(progress.transferred)} downloaded.` }) - await pipeline( - downloadBranchStream, - fs.createWriteStream(archivePath) - ) + await pipeline(downloadBranchStream, fs.createWriteStream(archivePath)) task.title = `Downloaded ${ext} archive successfully.` } catch (err) { throw new Error(`Failed to download ${ext} archive from GitHub. ${err.message}`) @@ -102,20 +98,22 @@ async function downloadExtractZip (task, { msg, url, ext = 'zip', branch }) { await fs.ensureDir(tmpDir) await extract(archivePath, { dir: tmpDir, - onEntry (entry) { + onEntry(entry) { task.output = entry.fileName } }) task.title = 'Moving extracted files to final location...' task.output = config.target - await fs.move(path.join(tmpDir, kebabCase(`datatracker-${branch}`)), config.target, { overwrite: true }) + await fs.move(path.join(tmpDir, kebabCase(`datatracker-${branch}`)), config.target, { + overwrite: true + }) await fs.remove(tmpDir) } else if (ext === 'tgz') { await tar.x({ strip: 1, file: archivePath, cwd: config.target, - filter (path) { + filter(path) { task.output = path return true } @@ -130,29 +128,29 @@ async function downloadExtractZip (task, { msg, url, ext = 'zip', branch }) { /** * Run a command on a running container - * + * * @param {Task} task Listr task instance * @param {Docker.Container} container Docker container instance * @param {Array} cmd Command to execute * @param {Boolean} collectOutput Whether to collect and return the command output */ -async function executeCommand (task, container, cmd, collectOutput = false, silent = false) { +async function executeCommand(task, container, cmd, collectOutput = false, silent = false) { const logStack = [] const errStack = [] let logFStream = null return new Promise(async (resolve, reject) => { // Handle stream output const logStream = new PassThrough() - logStream.on('data', chunk => { + logStream.on('data', (chunk) => { const logLine = chunk.toString('utf8').trim() if (logLine && !silent) { task.output = logLine if (collectOutput) { - logStack.push(...logLine.split('\n').filter(l => l)) + logStack.push(...logLine.split('\n').filter((l) => l)) } } }) - logStream.on('error', chunk => { + logStream.on('error', (chunk) => { task.output = chunk.toString('utf8') errStack.push(chunk.toString('utf8')) }) @@ -176,7 +174,6 @@ async function executeCommand (task, container, cmd, collectOutput = false, sile reject(new Error(errStack)) } else { if (!silent) { - } task.output = '' resolve(logStack) @@ -189,80 +186,82 @@ async function executeCommand (task, container, cmd, collectOutput = false, sile /** * Run cleanup tasks (e.g. stop/remove docker resources) - * + * * @param {Boolean} exitAfter Whether to exit the process at the end */ -async function cleanup (exitAfter = false) { +async function cleanup(exitAfter = false) { try { - const cleanupTasks = new Listr([ - // ------------------------ - // Stop + Remove Containers - // ------------------------ - { - title: 'Stop + remove docker containers', - task: async (ctx, task) => { - task.output = 'Stopping containers...' - try { - await Promise.allSettled([ - containers.dbSource && containers.dbSource.stop(), - containers.dbTarget && containers.dbTarget.stop(), - containers.appSource && containers.appSource.stop(), - containers.appTarget && containers.appTarget.stop() - ]) - } catch (err) { } - task.output = 'Removing containers...' - try { - await Promise.allSettled([ - containers.dbSource && containers.dbSource.remove({ v: true }), - containers.dbTarget && containers.dbTarget.remove({ v: true }), - containers.appSource && containers.appSource.remove({ v: true }), - containers.appTarget && containers.appTarget.remove({ v: true }) - ]) - } catch (err) { } - task.output = 'Removing network...' - try { - await containers.net.remove() - } catch (err) {} - } - }, - // -------------------- - // Restore config files - // -------------------- - { - title: 'Restore original source settings file', - task: async (ctx, task) => { - const sourceSettingsPath = path.join(config.source, 'ietf/settings_local.py') - if (await fs.pathExists(`${sourceSettingsPath}.bak`)) { - await fs.move(`${sourceSettingsPath}.bak`, sourceSettingsPath, { overwrite: true }) - task.title = 'Restored original source settings file.' - } else { - task.skip('Nothing to restore.') + const cleanupTasks = new Listr( + [ + // ------------------------ + // Stop + Remove Containers + // ------------------------ + { + title: 'Stop + remove docker containers', + task: async (ctx, task) => { + task.output = 'Stopping containers...' + try { + await Promise.allSettled([ + containers.dbSource && containers.dbSource.stop(), + containers.dbTarget && containers.dbTarget.stop(), + containers.appSource && containers.appSource.stop(), + containers.appTarget && containers.appTarget.stop() + ]) + } catch {} + task.output = 'Removing containers...' + try { + await Promise.allSettled([ + containers.dbSource && containers.dbSource.remove({ v: true }), + containers.dbTarget && containers.dbTarget.remove({ v: true }), + containers.appSource && containers.appSource.remove({ v: true }), + containers.appTarget && containers.appTarget.remove({ v: true }) + ]) + } catch {} + task.output = 'Removing network...' + try { + await containers.net.remove() + } catch {} } - } - }, - { - title: 'Restore original target settings file', - task: async (ctx, task) => { - const targetSettingsPath = path.join(config.target, 'ietf/settings_local.py') - if (await fs.pathExists(`${targetSettingsPath}.bak`)) { - await fs.move(`${targetSettingsPath}.bak`, targetSettingsPath, { overwrite: true }) - task.title = 'Restored original target settings file.' - } else { - task.skip('Nothing to restore.') + }, + // -------------------- + // Restore config files + // -------------------- + { + title: 'Restore original source settings file', + task: async (ctx, task) => { + const sourceSettingsPath = path.join(config.source, 'ietf/settings_local.py') + if (await fs.pathExists(`${sourceSettingsPath}.bak`)) { + await fs.move(`${sourceSettingsPath}.bak`, sourceSettingsPath, { overwrite: true }) + task.title = 'Restored original source settings file.' + } else { + task.skip('Nothing to restore.') + } + } + }, + { + title: 'Restore original target settings file', + task: async (ctx, task) => { + const targetSettingsPath = path.join(config.target, 'ietf/settings_local.py') + if (await fs.pathExists(`${targetSettingsPath}.bak`)) { + await fs.move(`${targetSettingsPath}.bak`, targetSettingsPath, { overwrite: true }) + task.title = 'Restored original target settings file.' + } else { + task.skip('Nothing to restore.') + } } } + ], + { + registerSignalListeners: false } - ], { - registerSignalListeners: false - }) - + ) + await cleanupTasks.run() // Cleanup if (config.tmpDir) { await fs.remove(config.tmpDir) } - } catch (err) { console.error(chalk.redBright(err.message)) process.exit(1) @@ -273,7 +272,7 @@ async function cleanup (exitAfter = false) { } } -async function main () { +async function main() { console.clear() console.info('╔════════════════════════════╗') console.info('║ IETF DATATRACKER DIFF TOOL ║') @@ -299,7 +298,7 @@ async function main () { title: 'Find base datatracker instance base path', task: async (ctx, task) => { let parentIdx = 0 - while(!(await fs.pathExists(path.join(config.source, 'requirements.txt')))) { + while (!(await fs.pathExists(path.join(config.source, 'requirements.txt')))) { config.source = path.resolve(config.source, '..') parentIdx++ if (parentIdx > 2) { @@ -340,7 +339,10 @@ async function main () { // ------------------------------------------------ case 'local': { task.title = 'Waiting for diff target path input' - config.target = await promptForPath(task, 'Enter the local path to the datatracker project to compare against:') + config.target = await promptForPath( + task, + 'Enter the local path to the datatracker project to compare against:' + ) task.title = `Using path ${config.target} for target datatracker instance.` break } @@ -352,16 +354,18 @@ async function main () { let branch = 'main' try { task.title = 'Fetching available remote branches...' - const branchesResp = await got('https://api.github.com/repos/ietf-tools/datatracker/branches?per_page=100').json() + const branchesResp = await got( + 'https://api.github.com/repos/ietf-tools/datatracker/branches?per_page=100' + ).json() if (branchesResp?.length < 1) { throw new Error('No remote branches available.') } - branches.push(...branchesResp.map(b => b.name)) + branches.push(...branchesResp.map((b) => b.name)) task.output = `Fetched ${branches.length} remote branches.` } catch (err) { throw new Error(`Failed to fetch branches! ${err.message}`) } - + branch = await task.prompt([ { type: 'select', @@ -369,11 +373,15 @@ async function main () { choices: branches } ]) - + // Prompt for local path where to download branch contents - config.target = await promptForPath(task, 'Enter a local path where the branch contents will be downloaded to:', false) + config.target = await promptForPath( + task, + 'Enter a local path where the branch contents will be downloaded to:', + false + ) await fs.ensureDir(config.target) - + // Download / Extract branch zip await downloadExtractZip(task, { msg: `Downloading ${branch} branch contents...`, @@ -387,18 +395,22 @@ async function main () { // MODE: REMOTE TAG // ------------------------------------------------ case 'tag': { - // Prompt for tag + // Prompt for tag const tag = await task.prompt([ { type: 'input', message: 'Enter the remote repository tag to compare against:' } ]) - + // Prompt for local path where to download tag contents - config.target = await promptForPath(task, 'Enter a local path where the tag contents will be downloaded to:', false) + config.target = await promptForPath( + task, + 'Enter a local path where the tag contents will be downloaded to:', + false + ) await fs.ensureDir(config.target) - + // Download / Extract tag tarball await downloadExtractZip(task, { msg: `Downloading tag ${tag} contents...`, @@ -412,12 +424,12 @@ async function main () { // MODE: REMOTE COMMIT // ------------------------------------------------ case 'commit': { - // Prompt for commit hash + // Prompt for commit hash const commit = await task.prompt([ { type: 'input', message: 'Enter the FULL commit hash to compare against:', - async validate (input) { + async validate(input) { if (!input) { return 'You must provide a hash!' } else if (!sha1reg.test(input)) { @@ -427,11 +439,15 @@ async function main () { } } ]) - + // Prompt for local path where to download commit contents - config.target = await promptForPath(task, 'Enter a local path where the commit contents will be downloaded to:', false) + config.target = await promptForPath( + task, + 'Enter a local path where the commit contents will be downloaded to:', + false + ) await fs.ensureDir(config.target) - + // Download / Extract commit tarball await downloadExtractZip(task, { msg: `Downloading commit ${commit} contents...`, @@ -447,9 +463,13 @@ async function main () { case 'release': { task.title = 'Waiting for diff target download location' // Prompt for local path where to download release - config.target = await promptForPath(task, 'Enter a local path where the latest release will be downloaded to:', false) + config.target = await promptForPath( + task, + 'Enter a local path where the latest release will be downloaded to:', + false + ) await fs.ensureDir(config.target) - + // Download / extract latest release await downloadExtractZip(task, { msg: 'Downloading latest release...', @@ -469,8 +489,14 @@ async function main () { if (!(await fs.pathExists(path.join(config.target, 'dev/diff')))) { task.output = `Add missing diff tool files...` await fs.ensureDir(path.join(config.target, 'dev/diff')) - await fs.copy(path.join(config.source, 'dev/diff/prepare.sh'), path.join(config.target, 'dev/diff/prepare.sh')) - await fs.copy(path.join(config.source, 'dev/diff/settings_local.py'), path.join(config.target, 'dev/diff/settings_local.py')) + await fs.copy( + path.join(config.source, 'dev/diff/prepare.sh'), + path.join(config.target, 'dev/diff/prepare.sh') + ) + await fs.copy( + path.join(config.source, 'dev/diff/settings_local.py'), + path.join(config.target, 'dev/diff/settings_local.py') + ) } } }, @@ -489,14 +515,54 @@ async function main () { message: 'Select additional options to enable:', hint: '(use to toggle, to confirm)', choices: [ - { message: 'Skip HTML Validation', name: '--skip-html-validation', hint: 'Skip HTML Validation', indicator: toggleIndicatorFn }, - { message: 'Fail-fast', name: '--failfast', hint: 'Stop the crawl on the first page failure', indicator: toggleIndicatorFn }, - { message: 'No-Follow', name: '--no-follow', hint: 'Do not follow URLs found in fetched pages, just check the given URLs', indicator: toggleIndicatorFn }, - { message: 'No-Revisit', name: '--no-revisit', hint: 'Don\'t revisit already visited URLs', indicator: toggleIndicatorFn }, - { message: 'Pedantic', name: '--pedantic', hint: 'Stop the crawl on the first error or warning', indicator: toggleIndicatorFn }, - { message: 'Random', name: '--random', hint: 'Crawl URLs randomly', indicator: toggleIndicatorFn }, - { message: 'Validate All', name: '--validate-all', hint: 'Run html 5 validation on all pages, without skipping similar urls', indicator: toggleIndicatorFn }, - { message: 'Verbose', name: '--verbose', hint: 'Be more verbose', indicator: toggleIndicatorFn } + { + message: 'Skip HTML Validation', + name: '--skip-html-validation', + hint: 'Skip HTML Validation', + indicator: toggleIndicatorFn + }, + { + message: 'Fail-fast', + name: '--failfast', + hint: 'Stop the crawl on the first page failure', + indicator: toggleIndicatorFn + }, + { + message: 'No-Follow', + name: '--no-follow', + hint: 'Do not follow URLs found in fetched pages, just check the given URLs', + indicator: toggleIndicatorFn + }, + { + message: 'No-Revisit', + name: '--no-revisit', + hint: "Don't revisit already visited URLs", + indicator: toggleIndicatorFn + }, + { + message: 'Pedantic', + name: '--pedantic', + hint: 'Stop the crawl on the first error or warning', + indicator: toggleIndicatorFn + }, + { + message: 'Random', + name: '--random', + hint: 'Crawl URLs randomly', + indicator: toggleIndicatorFn + }, + { + message: 'Validate All', + name: '--validate-all', + hint: 'Run html 5 validation on all pages, without skipping similar urls', + indicator: toggleIndicatorFn + }, + { + message: 'Verbose', + name: '--verbose', + hint: 'Be more verbose', + indicator: toggleIndicatorFn + } ] } ]) @@ -517,7 +583,12 @@ async function main () { }) if (saveToDisk) { - config.savePath = await promptForPath(task, 'Enter the path where the crawl output will be saved:', false, path.join(os.homedir(), 'Desktop/crawl-out.txt')) + config.savePath = await promptForPath( + task, + 'Enter the path where the crawl output will be saved:', + false, + path.join(os.homedir(), 'Desktop/crawl-out.txt') + ) task.title = `Crawl output will be saved to ${config.savePath}` } else { config.tmpDir = await fs.mkdtemp(path.join(os.tmpdir(), 'dt-')) @@ -531,21 +602,33 @@ async function main () { // ---------------------------- { title: 'Set datatracker config files', - task: async (ctx, task) => { + task: async (_ctx, _task) => { // Source const sourceSettingsPath = path.join(config.source, 'ietf/settings_local.py') if (await fs.pathExists(sourceSettingsPath)) { await fs.move(sourceSettingsPath, `${sourceSettingsPath}.bak`, { overwrite: true }) } - const cfgSourceRaw = await fs.readFile(path.join(config.source, 'dev/diff/settings_local.py'), 'utf8') - await fs.outputFile(sourceSettingsPath, cfgSourceRaw.replace('__DBHOST__', 'dt-diff-db-source')) + const cfgSourceRaw = await fs.readFile( + path.join(config.source, 'dev/diff/settings_local.py'), + 'utf8' + ) + await fs.outputFile( + sourceSettingsPath, + cfgSourceRaw.replace('__DBHOST__', 'dt-diff-db-source') + ) // Target const targetSettingsPath = path.join(config.target, 'ietf/settings_local.py') if (await fs.pathExists(targetSettingsPath)) { await fs.move(targetSettingsPath, `${targetSettingsPath}.bak`, { overwrite: true }) } - const cfgTargetRaw = await fs.readFile(path.join(config.target, 'dev/diff/settings_local.py'), 'utf8') - await fs.outputFile(targetSettingsPath, cfgTargetRaw.replace('__DBHOST__', 'dt-diff-db-target')) + const cfgTargetRaw = await fs.readFile( + path.join(config.target, 'dev/diff/settings_local.py'), + 'utf8' + ) + await fs.outputFile( + targetSettingsPath, + cfgTargetRaw.replace('__DBHOST__', 'dt-diff-db-target') + ) } }, // ------------------ @@ -553,33 +636,45 @@ async function main () { // ------------------ { title: 'Pull latest docker images', - task: (ctx, task) => task.newListr([ - { - title: 'Pulling latest DB docker image...', - task: async (subctx, subtask) => { - const dbImagePullStream = await dock.pull('ghcr.io/ietf-tools/datatracker-db:latest') - await new Promise((resolve, reject) => { - dock.modem.followProgress(dbImagePullStream, (err, res) => err ? reject(err) : resolve(res)) - }) - subtask.title = `Pulled latest DB docker image successfully.` - } - }, - { - title: 'Pulling latest Datatracker base docker image...', - task: async (subctx, subtask) => { - const appImagePullStream = await dock.pull('ghcr.io/ietf-tools/datatracker-app-base:latest') - await new Promise((resolve, reject) => { - dock.modem.followProgress(appImagePullStream, (err, res) => err ? reject(err) : resolve(res)) - }) - subtask.title = `Pulled latest Datatracker base docker image successfully.` + task: (ctx, task) => + task.newListr( + [ + { + title: 'Pulling latest DB docker image...', + task: async (subctx, subtask) => { + const dbImagePullStream = await dock.pull( + 'ghcr.io/ietf-tools/datatracker-db:latest' + ) + await new Promise((resolve, reject) => { + dock.modem.followProgress(dbImagePullStream, (err, res) => + err ? reject(err) : resolve(res) + ) + }) + subtask.title = `Pulled latest DB docker image successfully.` + } + }, + { + title: 'Pulling latest Datatracker base docker image...', + task: async (subctx, subtask) => { + const appImagePullStream = await dock.pull( + 'ghcr.io/ietf-tools/datatracker-app-base:latest' + ) + await new Promise((resolve, reject) => { + dock.modem.followProgress(appImagePullStream, (err, res) => + err ? reject(err) : resolve(res) + ) + }) + subtask.title = `Pulled latest Datatracker base docker image successfully.` + } + } + ], + { + concurrent: true, + rendererOptions: { + collapse: false + } } - } - ], { - concurrent: true, - rendererOptions: { - collapse: false - } - }) + ) }, // -------------- // Create network @@ -600,135 +695,226 @@ async function main () { // ---------------------------- { title: 'Create DB docker containers', - task: (ctx, task) => task.newListr([ - { - title: 'Creating source DB docker container...', - task: async (subctx, subtask) => { - containers.dbSource = await dock.createContainer({ - Image: 'ghcr.io/ietf-tools/datatracker-db:latest', - name: 'dt-diff-db-source', - Hostname: 'dbsource', - HostConfig: { - NetworkMode: 'dt-diff-net' + task: (ctx, task) => + task.newListr( + [ + { + title: 'Creating source DB docker container...', + task: async (subctx, subtask) => { + containers.dbSource = await dock.createContainer({ + Image: 'ghcr.io/ietf-tools/datatracker-db:latest', + name: 'dt-diff-db-source', + Hostname: 'dbsource', + HostConfig: { + NetworkMode: 'dt-diff-net' + } + }) + await containers.dbSource.start() + subtask.title = `Created source DB docker container (dt-diff-db-source) successfully.` } - }) - await containers.dbSource.start() - subtask.title = `Created source DB docker container (dt-diff-db-source) successfully.` - } - }, - { - title: 'Creating target DB docker container...', - task: async (subctx, subtask) => { - containers.dbTarget = await dock.createContainer({ - Image: 'ghcr.io/ietf-tools/datatracker-db:latest', - name: 'dt-diff-db-target', - Hostname: 'dbtarget', - HostConfig: { - NetworkMode: 'dt-diff-net' + }, + { + title: 'Creating target DB docker container...', + task: async (subctx, subtask) => { + containers.dbTarget = await dock.createContainer({ + Image: 'ghcr.io/ietf-tools/datatracker-db:latest', + name: 'dt-diff-db-target', + Hostname: 'dbtarget', + HostConfig: { + NetworkMode: 'dt-diff-net' + } + }) + await containers.dbTarget.start() + subtask.title = `Created target DB docker container (dt-diff-db-target) successfully.` } - }) - await containers.dbTarget.start() - subtask.title = `Created target DB docker container (dt-diff-db-target) successfully.` + } + ], + { + concurrent: true, + rendererOptions: { + collapse: false + } } - } - ], { - concurrent: true, - rendererOptions: { - collapse: false - } - }) + ) }, // ------------------------------------- // Create + Start Datatracker containers // ------------------------------------- { title: 'Create Datatracker docker containers', - task: (ctx, task) => task.newListr([ - { - title: 'Creating source Datatracker docker container...', - task: async (subctx, subtask) => { - containers.appSource = await dock.createContainer({ - Image: 'ghcr.io/ietf-tools/datatracker-app-base:latest', - name: 'dt-diff-app-source', - Tty: true, - Hostname: 'appsource', - HostConfig: { - Binds: [ - `${config.source}:/workspace` - ], - NetworkMode: 'dt-diff-net' + task: (ctx, task) => + task.newListr( + [ + { + title: 'Creating source Datatracker docker container...', + task: async (subctx, subtask) => { + containers.appSource = await dock.createContainer({ + Image: 'ghcr.io/ietf-tools/datatracker-app-base:latest', + name: 'dt-diff-app-source', + Tty: true, + Hostname: 'appsource', + HostConfig: { + NetworkMode: 'dt-diff-net' + } + }) + await containers.appSource.start() + subtask.title = `Created source Datatracker docker container (dt-diff-app-source) successfully.` } - }) - await containers.appSource.start() - subtask.title = `Created source Datatracker docker container (dt-diff-app-source) successfully.` + }, + { + title: 'Creating target Datatracker docker container...', + task: async (subctx, subtask) => { + containers.appTarget = await dock.createContainer({ + Image: 'ghcr.io/ietf-tools/datatracker-app-base:latest', + name: 'dt-diff-app-target', + Tty: true, + Hostname: 'apptarget', + HostConfig: { + NetworkMode: 'dt-diff-net' + } + }) + await containers.appTarget.start() + subtask.title = `Created target Datatracker docker container (dt-diff-app-target) successfully.` + } + } + ], + { + concurrent: true, + rendererOptions: { + collapse: false + } } - }, - { - title: 'Creating target Datatracker docker container...', - task: async (subctx, subtask) => { - containers.appTarget = await dock.createContainer({ - Image: 'ghcr.io/ietf-tools/datatracker-app-base:latest', - name: 'dt-diff-app-target', - Tty: true, - Hostname: 'apptarget', - HostConfig: { - Binds: [ - `${config.target}:/workspace` - ], - NetworkMode: 'dt-diff-net' + ) + }, + // -------------------------------------------- + // Copy working files to Datatracker containers + // -------------------------------------------- + { + title: 'Copy working files to Datatracker docker containers', + task: (ctx, task) => + task.newListr( + [ + { + title: 'Copying workfing files into source Datatracker docker container...', + task: async (subctx, subtask) => { + const tgzPath = path.join(config.source, 'diff-import.tgz') + await tar.c( + { + gzip: true, + file: tgzPath, + cwd: config.source, + filter(path) { + if (path.includes('.git') || path.includes('node_modules')) { + return false + } + subtask.output = path + return true + } + }, + ['.'] + ) + subtask.output = 'Injecting into container...' + await containers.appSource.putArchive(tgzPath, { + path: '/workspace' + }) + await fs.remove(tgzPath) + subtask.title = `Imported working files into source Datatracker docker container (dt-diff-app-source) successfully.` } - }) - await containers.appTarget.start() - subtask.title = `Created target Datatracker docker container (dt-diff-app-target) successfully.` + }, + { + title: 'Copying working files into target Datatracker docker container...', + task: async (subctx, subtask) => { + const tgzPath = path.join(config.target, 'diff-import.tgz') + await tar.c( + { + gzip: true, + file: tgzPath, + cwd: config.target, + filter(path) { + if (path.includes('.git') || path.includes('node_modules')) { + return false + } + subtask.output = path + return true + } + }, + ['.'] + ) + subtask.output = 'Injecting into container...' + await containers.appTarget.putArchive(tgzPath, { + path: '/workspace' + }) + await fs.remove(tgzPath) + subtask.title = `Imported working files into target Datatracker docker container (dt-diff-app-target) successfully.` + } + } + ], + { + concurrent: true, + rendererOptions: { + collapse: false + } } - } - ], { - concurrent: true, - rendererOptions: { - collapse: false - } - }) + ) }, // ------------------- // Run prepare scripts // ------------------- { title: 'Prepare Datatracker instances', - task: (ctx, task) => task.newListr([ - { - title: 'Preparing source Datatracker instance...', - task: async (subctx, subtask) => { - await executeCommand(subtask, containers.appSource, ['bash', '-c', 'chmod +x ./dev/diff/prepare.sh']) - await executeCommand(subtask, containers.appSource, ['bash', './dev/diff/prepare.sh']) - subtask.title = `Preparing source Datatracker instance - Running checks...` - await executeCommand(subtask, containers.appSource, ['bash', '-c', './ietf/manage.py check']) - subtask.title = `Preparing source Datatracker instance - Applying migrations...` - await executeCommand(subtask, containers.appSource, ['bash', '-c', './ietf/manage.py migrate']) - subtask.title = `Source Datatracker instance is now ready.` - } - }, - { - title: 'Preparing target Datatracker instance...', - task: async (subctx, subtask) => { - await executeCommand(subtask, containers.appTarget, ['bash', '-c', 'chmod +x ./dev/diff/prepare.sh']) - await executeCommand(subtask, containers.appTarget, ['bash', './dev/diff/prepare.sh']) - subtask.title = `Run target Datatracker instance - Running checks...` - await executeCommand(subtask, containers.appTarget, ['bash', '-c', './ietf/manage.py check']) - subtask.title = `Run target Datatracker instance - Applying migrations...` - await executeCommand(subtask, containers.appTarget, ['bash', '-c', './ietf/manage.py migrate']) - subtask.title = `Run target Datatracker instance - Starting server...` - executeCommand(subtask, containers.appTarget, ['bash', '-c', './ietf/manage.py runserver 0.0.0.0:8000 --settings=settings_local']) - subtask.title = `Run target Datatracker instance - Waiting for server to accept connections...` - await executeCommand(subtask, containers.appTarget, ['bash', '-c', '/usr/local/bin/wait-for localhost:8000 -t 300']) - subtask.title = `Target Datatracker instance is now ready and accepting connections.` + task: (ctx, task) => + task.newListr( + [ + { + title: 'Preparing source Datatracker instance...', + task: async (subctx, subtask) => { + await executeCommand(subtask, containers.appSource, [ + 'bash', + '-c', + 'chmod +x ./dev/diff/prepare.sh' + ]) + await executeCommand(subtask, containers.appSource, [ + 'bash', + './dev/diff/prepare.sh' + ]) + subtask.title = `Source Datatracker instance is now ready.` + } + }, + { + title: 'Preparing target Datatracker instance...', + task: async (subctx, subtask) => { + await executeCommand(subtask, containers.appTarget, [ + 'bash', + '-c', + 'chmod +x ./dev/diff/prepare.sh' + ]) + await executeCommand(subtask, containers.appTarget, [ + 'bash', + './dev/diff/prepare.sh' + ]) + subtask.title = `Run target Datatracker instance - Starting server...` + executeCommand(subtask, containers.appTarget, [ + 'bash', + '-c', + './ietf/manage.py runserver 0.0.0.0:8000 --settings=settings_local' + ]) + subtask.title = `Run target Datatracker instance - Waiting for server to accept connections...` + await executeCommand(subtask, containers.appTarget, [ + 'bash', + '-c', + '/usr/local/bin/wait-for localhost:8000 -t 300' + ]) + subtask.title = `Target Datatracker instance is now ready and accepting connections.` + } + } + ], + { + concurrent: true, + rendererOptions: { + collapse: false + } } - } - ], { - concurrent: true, - rendererOptions: { - collapse: false - } - }) + ) }, // -------------- // Run crawl tool @@ -738,7 +924,7 @@ async function main () { task: async (ctx, task) => { task.title = 'Running crawl... (Press F10 to cancel)' task.output = 'Starting ./bin/test-crawl... (Results will start appearing soon)' - + const startMs = performance.now() config.options.push('--settings=ietf.settings_testcrawl') @@ -751,8 +937,12 @@ async function main () { const execPromise = new Promise(async (resolve, reject) => { // Handle stream output const logStream = new PassThrough() - logStream.on('data', chunk => { - const logLines = chunk.toString('utf8').trim().split('\n').filter(l => l.trim()) + logStream.on('data', (chunk) => { + const logLines = chunk + .toString('utf8') + .trim() + .split('\n') + .filter((l) => l.trim()) // Check for DIFF mentions if (logLines.length > 0) { linesScanned += logLines.length @@ -766,7 +956,7 @@ async function main () { } }) // Handle error stream - logStream.on('error', chunk => { + logStream.on('error', (chunk) => { task.output = chunk.toString('utf8') errStack.push(chunk.toString('utf8')) }) @@ -813,7 +1003,6 @@ async function main () { ]) await tasks.run() - } catch (err) { console.error(chalk.redBright(err.message)) } diff --git a/dev/diff/package-lock.json b/dev/diff/package-lock.json index 96ce2b54818..585f4d4edfe 100644 --- a/dev/diff/package-lock.json +++ b/dev/diff/package-lock.json @@ -6,88 +6,276 @@ "": { "name": "diff", "dependencies": { - "chalk": "^5.0.1", - "dockerode": "^3.3.3", - "enquirer": "^2.3.6", - "extract-zip": "^2.0.1", - "fs-extra": "^10.1.0", - "got": "^12.3.1", - "keypress": "^0.2.1", - "listr2": "^5.0.2", - "lodash-es": "^4.17.21", - "luxon": "^3.0.1", - "pretty-bytes": "^6.0.0", - "tar": "^6.1.11", - "yargs": "^17.5.1" + "chalk": "5.6.2", + "dockerode": "5.0.1", + "enquirer": "2.4.1", + "extract-zip": "2.0.1", + "fs-extra": "11.3.6", + "got": "15.1.0", + "keypress": "0.2.1", + "listr2": "10.2.2", + "lodash-es": "4.18.1", + "luxon": "3.7.2", + "pretty-bytes": "7.1.0", + "tar": "7.5.19", + "yargs": "18.0.0" }, "engines": { - "node": ">=16" + "node": ">=26" } }, - "node_modules/@sindresorhus/is": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-5.3.0.tgz", - "integrity": "sha512-CX6t4SYQ37lzxicAqsBtxA3OseeoVrh9cSJ5PFYam0GksYlupRfy1A+Q4aYD3zvcfECLc0zO2u+ZnR2UYKvCrw==", + "node_modules/@balena/dockerignore": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@balena/dockerignore/-/dockerignore-1.0.2.tgz", + "integrity": "sha512-wMue2Sy4GAVTk6Ic4tJVcnfdau+gx2EnG7S+uAEe+TWJFqE4YoWN4/H8MSLj4eYJKxGg26lZwboEniNiNwZQ6Q==" + }, + "node_modules/@grpc/grpc-js": { + "version": "1.12.5", + "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.12.5.tgz", + "integrity": "sha512-d3iiHxdpg5+ZcJ6jnDSOT8Z0O0VMVGy34jAnYLUX8yd36b1qn8f1TwOA/Lc7TsOh03IkPJ38eGI5qD2EjNkoEA==", + "license": "Apache-2.0", + "dependencies": { + "@grpc/proto-loader": "^0.7.13", + "@js-sdsl/ordered-map": "^4.4.2" + }, "engines": { - "node": ">=14.16" + "node": ">=12.10.0" + } + }, + "node_modules/@grpc/proto-loader": { + "version": "0.7.13", + "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.7.13.tgz", + "integrity": "sha512-AiXO/bfe9bmxBjxxtYxFAXGZvMaN5s8kO+jBHAJCON8rJoB5YS/D6X7ZNc6XQkuHNmyl4CYaMI1fJ/Gn27RGGw==", + "license": "Apache-2.0", + "dependencies": { + "lodash.camelcase": "^4.3.0", + "long": "^5.0.0", + "protobufjs": "^7.2.5", + "yargs": "^17.7.2" + }, + "bin": { + "proto-loader-gen-types": "build/bin/proto-loader-gen-types.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@grpc/proto-loader/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" }, "funding": { - "url": "https://github.com/sindresorhus/is?sponsor=1" + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/@szmarczak/http-timer": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-5.0.1.tgz", - "integrity": "sha512-+PmQX0PiAYPMeVYe237LJAYvOMYW1j2rH5YROyS3b4CTVJum34HfRvKvAzozHAQG0TnHNdUfY9nCeUyRAs//cw==", + "node_modules/@grpc/proto-loader/node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "license": "ISC", "dependencies": { - "defer-to-connect": "^2.0.1" + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" }, "engines": { - "node": ">=14.16" + "node": ">=12" + } + }, + "node_modules/@grpc/proto-loader/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "license": "MIT", + "engines": { + "node": ">=8" } }, - "node_modules/@types/cacheable-request": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.2.tgz", - "integrity": "sha512-B3xVo+dlKM6nnKTcmm5ZtY/OL8bOAOd2Olee9M1zft65ox50OzjEHW91sDiU9j6cvW8Ejg1/Qkf4xd2kugApUA==", + "node_modules/@grpc/proto-loader/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "license": "MIT", "dependencies": { - "@types/http-cache-semantics": "*", - "@types/keyv": "*", - "@types/node": "*", - "@types/responselike": "*" + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" } }, - "node_modules/@types/http-cache-semantics": { + "node_modules/@grpc/proto-loader/node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/@grpc/proto-loader/node_modules/yargs": { + "version": "17.7.3", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.3.tgz", + "integrity": "sha512-GZtjxm/J/4TSxuL3FNYjCmLktBTnIw/rVmKSIyKeYAZpmJB2ig9VauCC5xsa82GNKVKDAqpOn3KVzNt0zmrU0g==", + "license": "MIT", + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@grpc/proto-loader/node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/@isaacs/fs-minipass": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.1.tgz", - "integrity": "sha512-SZs7ekbP8CN0txVG2xVRH6EgKmEm31BOxA07vkFaETzZz1xh+cbt8BcI0slpymvwhx5dlFnQG2rTlPVQn+iRPQ==" + "resolved": "https://registry.npmjs.org/@isaacs/fs-minipass/-/fs-minipass-4.0.1.tgz", + "integrity": "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==", + "dependencies": { + "minipass": "^7.0.4" + }, + "engines": { + "node": ">=18.0.0" + } }, - "node_modules/@types/json-buffer": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/json-buffer/-/json-buffer-3.0.0.tgz", - "integrity": "sha512-3YP80IxxFJB4b5tYC2SUPwkg0XQLiu0nWvhRgEatgjf+29IcWO9X1k8xRv5DGssJ/lCrjYTjQPcobJr2yWIVuQ==" + "node_modules/@js-sdsl/ordered-map": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/@js-sdsl/ordered-map/-/ordered-map-4.4.2.tgz", + "integrity": "sha512-iUKgm52T8HOE/makSxjqoWhe95ZJA1/G1sYsGev2JDKUSS14KAgg1LHb+Ba+IPow0xflbnSkOsZcO08C7w1gYw==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/js-sdsl" + } + }, + "node_modules/@keyv/serialize": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@keyv/serialize/-/serialize-1.1.1.tgz", + "integrity": "sha512-dXn3FZhPv0US+7dtJsIi2R+c7qWYiReoEh5zUntWCf4oSpMNib8FDhSoed6m3QyZdx5hK7iLFkYk3rNxwt8vTA==", + "license": "MIT" + }, + "node_modules/@protobufjs/aspromise": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", + "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==", + "license": "BSD-3-Clause" }, - "node_modules/@types/keyv": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.4.tgz", - "integrity": "sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==", + "node_modules/@protobufjs/base64": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", + "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/codegen": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", + "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/eventemitter": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", + "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/fetch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", + "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==", + "license": "BSD-3-Clause", "dependencies": { - "@types/node": "*" + "@protobufjs/aspromise": "^1.1.1", + "@protobufjs/inquire": "^1.1.0" + } + }, + "node_modules/@protobufjs/float": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", + "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/inquire": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", + "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/path": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", + "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/pool": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", + "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/utf8": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", + "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==", + "license": "BSD-3-Clause" + }, + "node_modules/@sec-ant/readable-stream": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@sec-ant/readable-stream/-/readable-stream-0.4.1.tgz", + "integrity": "sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg==", + "license": "MIT" + }, + "node_modules/@sindresorhus/is": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-8.1.0.tgz", + "integrity": "sha512-2SX/1jW6CIMAiebvVv5ZInoCEuWQmMyBoJXXGC6Vjakjp/fpxP5eHs7/V6WKuPEIbuK06+VpjH+vjLQhr98rDQ==", + "license": "MIT", + "engines": { + "node": ">=22" + }, + "funding": { + "url": "https://github.com/sindresorhus/is?sponsor=1" } }, + "node_modules/@types/http-cache-semantics": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.2.0.tgz", + "integrity": "sha512-L3LgimLHXtGkWikKnsPg0/VFx9OGZaC+eN1u4r+OB1XRqH3meBIAVC2zr1WdMH+RHmnRkqliQAOHNJ/E0j/e0Q==", + "license": "MIT" + }, "node_modules/@types/node": { "version": "18.6.5", "resolved": "https://registry.npmjs.org/@types/node/-/node-18.6.5.tgz", "integrity": "sha512-Xjt5ZGUa5WusGZJ4WJPbOT8QOqp6nDynVFRKcUt32bOgvXEoc6o085WNkYTMO7ifAj2isEfQQ2cseE+wT6jsRw==" }, - "node_modules/@types/responselike": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.0.tgz", - "integrity": "sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA==", - "dependencies": { - "@types/node": "*" - } - }, "node_modules/@types/yauzl": { "version": "2.10.0", "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.0.tgz", @@ -97,42 +285,58 @@ "@types/node": "*" } }, - "node_modules/aggregate-error": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", - "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", + "node_modules/ansi-colors": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", + "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", + "engines": { + "node": ">=6" + } + }, + "node_modules/ansi-escapes": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-7.3.0.tgz", + "integrity": "sha512-BvU8nYgGQBxcmMuEeUEmNTvrMVjJNSH7RgW24vXexN4Ven6qCvy4TntnvlnwnMLTVlcRQQdbRY8NKnaIoeWDNg==", + "license": "MIT", "dependencies": { - "clean-stack": "^2.0.0", - "indent-string": "^4.0.0" + "environment": "^1.0.0" }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "engines": { "node": ">=8" } }, - "node_modules/ansi-colors": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", - "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", + "node_modules/ansi-styles": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", + "license": "MIT", "engines": { - "node": ">=6" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, "node_modules/asn1": { "version": "0.2.6", "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==", + "license": "MIT", "dependencies": { "safer-buffer": "~2.1.0" } }, - "node_modules/astral-regex": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", - "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", - "engines": { - "node": ">=8" - } - }, "node_modules/base64-js": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", @@ -150,16 +354,53 @@ "type": "consulting", "url": "https://feross.org/support" } - ] + ], + "license": "MIT" }, "node_modules/bcrypt-pbkdf": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", "integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==", + "license": "BSD-3-Clause", "dependencies": { "tweetnacl": "^0.14.3" } }, + "node_modules/bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "license": "MIT", + "dependencies": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, "node_modules/buffer-crc32": { "version": "0.2.13", "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", @@ -169,65 +410,57 @@ } }, "node_modules/buildcheck": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/buildcheck/-/buildcheck-0.0.3.tgz", - "integrity": "sha512-pziaA+p/wdVImfcbsZLNF32EiWyujlQLwolMqUQE8xpKNOH7KmZQaY8sXN7DGOEzPAElo9QTaeNRfGnf3iOJbA==", + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/buildcheck/-/buildcheck-0.0.7.tgz", + "integrity": "sha512-lHblz4ahamxpTmnsk+MNTRWsjYKv965MwOrSJyeD588rR3Jcu7swE+0wN5F+PbL5cjgu/9ObkhfzEPuofEMwLA==", "optional": true, "engines": { "node": ">=10.0.0" } }, - "node_modules/cacheable-lookup": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-6.1.0.tgz", - "integrity": "sha512-KJ/Dmo1lDDhmW2XDPMo+9oiy/CeqosPguPCrgcVzKyZrL6pM1gU2GmPY/xo6OQPTUaA/c0kwHuywB4E6nmT9ww==", + "node_modules/byte-counter": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/byte-counter/-/byte-counter-0.1.0.tgz", + "integrity": "sha512-jheRLVMeUKrDBjVw2O5+k4EvR4t9wtxHL+bo/LxfkxsVeuGMy3a5SEGgXdAFA4FSzTrU8rQXQIrsZ3oBq5a0pQ==", + "license": "MIT", "engines": { - "node": ">=10.6.0" + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/cacheable-request": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.2.tgz", - "integrity": "sha512-pouW8/FmiPQbuGpkXQ9BAPv/Mo5xDGANgSNXzTzJ8DrKGuXOssM4wIQRjfanNRh3Yu5cfYPvcorqbhg2KIJtew==", - "dependencies": { - "clone-response": "^1.0.2", - "get-stream": "^5.1.0", - "http-cache-semantics": "^4.0.0", - "keyv": "^4.0.0", - "lowercase-keys": "^2.0.0", - "normalize-url": "^6.0.1", - "responselike": "^2.0.0" - }, + "node_modules/cacheable-lookup": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-7.0.0.tgz", + "integrity": "sha512-+qJyx4xiKra8mZrcwhjMRMUhD5NR1R8esPkzIYxX96JiecFoxAXFuz/GpR3+ev4PE1WamHip78wV0vcmPQtp8w==", "engines": { - "node": ">=8" + "node": ">=14.16" } }, - "node_modules/cacheable-request/node_modules/get-stream": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", - "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "node_modules/cacheable-request": { + "version": "13.0.19", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-13.0.19.tgz", + "integrity": "sha512-SVXGH037+Mo1aIMO5B2UcleR43FGjFdN+M8JObSyEoQ2Mn4CODRWx28gN5jiTF0n5ItsgtIZfyargMNs8GX4kg==", + "license": "MIT", "dependencies": { - "pump": "^3.0.0" + "@types/http-cache-semantics": "^4.2.0", + "get-stream": "^9.0.1", + "http-cache-semantics": "^4.2.0", + "keyv": "^5.6.0", + "mimic-response": "^4.0.0", + "normalize-url": "^8.1.1", + "responselike": "^4.0.2" }, "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/cacheable-request/node_modules/lowercase-keys": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", - "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", - "engines": { - "node": ">=8" + "node": ">=18" } }, "node_modules/chalk": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.0.1.tgz", - "integrity": "sha512-Fo07WOYGqMfCWHOzSXOt2CxDbC6skS/jO9ynEcmpANMoPrD+W1r1K6Vx7iNm+AQmETU1Xr2t+n8nzkV9t6xh3w==", + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz", + "integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==", + "license": "MIT", "engines": { "node": "^12.17.0 || ^14.13 || >=16.0.0" }, @@ -238,160 +471,138 @@ "node_modules/chownr": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", - "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==" + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", + "license": "ISC" }, - "node_modules/clean-stack": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", - "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "node_modules/chunk-data": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/chunk-data/-/chunk-data-0.1.0.tgz", + "integrity": "sha512-zFyPtyC0SZ6Zu79b9sOYtXZcgrsXe0RpePrzRyj52hYVFG1+Rk6rBqjjOEk+GNQwc3PIX+86teQMok970pod1g==", + "license": "MIT", "engines": { - "node": ">=6" + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/cli-truncate": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-2.1.0.tgz", - "integrity": "sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==", + "node_modules/cli-cursor": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-5.0.0.tgz", + "integrity": "sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw==", + "license": "MIT", "dependencies": { - "slice-ansi": "^3.0.0", - "string-width": "^4.2.0" + "restore-cursor": "^5.0.0" }, "engines": { - "node": ">=8" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/cli-truncate/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/cli-truncate/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" - }, - "node_modules/cli-truncate/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "node_modules/cli-truncate": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-5.2.0.tgz", + "integrity": "sha512-xRwvIOMGrfOAnM1JYtqQImuaNtDEv9v6oIYAs4LIHwTiKee8uwvIi363igssOC0O5U04i4AlENs79LQLu9tEMw==", + "license": "MIT", "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" + "slice-ansi": "^8.0.0", + "string-width": "^8.2.0" }, "engines": { - "node": ">=8" - } - }, - "node_modules/cli-truncate/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dependencies": { - "ansi-regex": "^5.0.1" + "node": ">=20" }, - "engines": { - "node": ">=8" + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-9.0.1.tgz", + "integrity": "sha512-k7ndgKhwoQveBL+/1tqGJYNz097I7WOvwbmmU2AR5+magtbjPWQTS1C5vzGkBC8Ym8UWRzfKUzUUqFLypY4Q+w==", + "license": "ISC", "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" - } - }, - "node_modules/cliui/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "string-width": "^7.2.0", + "strip-ansi": "^7.1.0", + "wrap-ansi": "^9.0.0" + }, "engines": { - "node": ">=8" + "node": ">=20" } }, - "node_modules/cliui/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dependencies": { - "color-convert": "^2.0.1" - }, + "node_modules/cliui/node_modules/ansi-regex": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "license": "MIT", "engines": { - "node": ">=8" + "node": ">=12" }, "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "url": "https://github.com/chalk/ansi-regex?sponsor=1" } }, "node_modules/cliui/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + "version": "10.6.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz", + "integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==", + "license": "MIT" }, "node_modules/cliui/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", + "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", + "license": "MIT", "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" }, "engines": { - "node": ">=8" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/cliui/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz", + "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", + "license": "MIT", "dependencies": { - "ansi-regex": "^5.0.1" + "ansi-regex": "^6.2.2" }, "engines": { - "node": ">=8" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, "node_modules/cliui/node_modules/wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.2.tgz", + "integrity": "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==", + "license": "MIT", "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" + "ansi-styles": "^6.2.1", + "string-width": "^7.0.0", + "strip-ansi": "^7.1.0" }, "engines": { - "node": ">=10" + "node": ">=18" }, "funding": { "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, - "node_modules/clone-response": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.3.tgz", - "integrity": "sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA==", - "dependencies": { - "mimic-response": "^1.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "license": "MIT", "dependencies": { "color-name": "~1.1.4" }, @@ -402,34 +613,18 @@ "node_modules/color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "node_modules/colorette": { - "version": "2.0.19", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.19.tgz", - "integrity": "sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ==" - }, - "node_modules/compress-brotli": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/compress-brotli/-/compress-brotli-1.3.8.tgz", - "integrity": "sha512-lVcQsjhxhIXsuupfy9fmZUFtAIdBmXA7EGY6GBdgZ++qkM9zG4YFT8iU7FoBxzryNDMOpD1HIFHUSX4D87oqhQ==", - "dependencies": { - "@types/json-buffer": "~3.0.0", - "json-buffer": "~3.0.1" - }, - "engines": { - "node": ">= 12" - } + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "license": "MIT" }, "node_modules/cpu-features": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/cpu-features/-/cpu-features-0.0.4.tgz", - "integrity": "sha512-fKiZ/zp1mUwQbnzb9IghXtHtDoTMtNeb8oYGx6kX2SYfhnG0HNdBEBIzB9b5KlXu5DQPhfy3mInbBxFcgwAr3A==", + "version": "0.0.10", + "resolved": "https://registry.npmjs.org/cpu-features/-/cpu-features-0.0.10.tgz", + "integrity": "sha512-9IkYqtX3YHPCzoVg1Py+o9057a3i0fp7S530UWokCSaFVTc7CwXPRiOjRjBQQ18ZCNafx78YfnG+HALxtVmOGA==", "hasInstallScript": true, "optional": true, "dependencies": { - "buildcheck": "0.0.3", - "nan": "^2.15.0" + "buildcheck": "~0.0.6", + "nan": "^2.19.0" }, "engines": { "node": ">=10.0.0" @@ -452,64 +647,58 @@ } }, "node_modules/decompress-response": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", - "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-10.0.0.tgz", + "integrity": "sha512-oj7KWToJuuxlPr7VV0vabvxEIiqNMo+q0NueIiL3XhtwC6FVOX7Hr1c0C4eD0bmf7Zr+S/dSf2xvkH3Ad6sU3Q==", + "license": "MIT", "dependencies": { - "mimic-response": "^3.1.0" + "mimic-response": "^4.0.0" }, "engines": { - "node": ">=10" + "node": ">=20" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/decompress-response/node_modules/mimic-response": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", - "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/defer-to-connect": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", - "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==", - "engines": { - "node": ">=10" - } - }, "node_modules/docker-modem": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/docker-modem/-/docker-modem-3.0.5.tgz", - "integrity": "sha512-x1E6jxWdtoK3+ifAUWj4w5egPdTDGBpesSCErm+aKET5BnnEOvDtTP6GxcnMB1zZiv2iQ0qJZvJie+1wfIRg6Q==", + "version": "5.0.7", + "resolved": "https://registry.npmjs.org/docker-modem/-/docker-modem-5.0.7.tgz", + "integrity": "sha512-XJgGhoR/CLpqshm4d3L7rzH6t8NgDFUIIpztYlLHIApeJjMZKYJMz2zxPsYxnejq5h3ELYSw/RBsi3t5h7gNTA==", + "license": "Apache-2.0", "dependencies": { "debug": "^4.1.1", "readable-stream": "^3.5.0", "split-ca": "^1.0.1", - "ssh2": "^1.4.0" + "ssh2": "^1.15.0" }, "engines": { "node": ">= 8.0" } }, "node_modules/dockerode": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/dockerode/-/dockerode-3.3.3.tgz", - "integrity": "sha512-lvKV6/NGf2/CYLt5V4c0fd6Fl9XZSCo1Z2HBT9ioKrKLMB2o+gA62Uza8RROpzGvYv57KJx2dKu+ZwSpB//OIA==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/dockerode/-/dockerode-5.0.1.tgz", + "integrity": "sha512-avsq/xk4YPIrn0CgleX5bjT9Y8IT1p9PxrNQ++RBQ2WEyFfHCTDsT9kmyxz+H/axnjAwg8wJWEIuPGOUuNupiA==", + "license": "Apache-2.0", "dependencies": { - "docker-modem": "^3.0.0", - "tar-fs": "~2.0.1" + "@balena/dockerignore": "^1.0.2", + "@grpc/grpc-js": "^1.11.1", + "@grpc/proto-loader": "^0.7.13", + "docker-modem": "^5.0.7", + "protobufjs": "^7.3.2", + "tar-fs": "^2.1.4" }, "engines": { - "node": ">= 8.0" + "node": ">= 14.17" } }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "license": "MIT" + }, "node_modules/end-of-stream": { "version": "1.4.4", "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", @@ -519,16 +708,29 @@ } }, "node_modules/enquirer": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", - "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.4.1.tgz", + "integrity": "sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==", "dependencies": { - "ansi-colors": "^4.1.1" + "ansi-colors": "^4.1.1", + "strip-ansi": "^6.0.1" }, "engines": { "node": ">=8.6" } }, + "node_modules/environment": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/environment/-/environment-1.1.0.tgz", + "integrity": "sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/escalade": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", @@ -537,6 +739,12 @@ "node": ">=6" } }, + "node_modules/eventemitter3": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.4.tgz", + "integrity": "sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw==", + "license": "MIT" + }, "node_modules/extract-zip": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", @@ -578,41 +786,24 @@ "pend": "~1.2.0" } }, - "node_modules/form-data-encoder": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-2.0.1.tgz", - "integrity": "sha512-Oy+P9w5mnO4TWXVgUiQvggNKPI9/ummcSt5usuIV6HkaLKigwzPpoenhEqmGmx3zHqm6ZLJ+CR/99N8JLinaEw==", - "engines": { - "node": ">= 14.17" - } - }, "node_modules/fs-constants": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", - "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==" + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", + "license": "MIT" }, "node_modules/fs-extra": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", - "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "version": "11.3.6", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.6.tgz", + "integrity": "sha512-w8ZNZr2mKIc7qeNaQ9AVPT1+iFaI+Avd4xudVOvdDJ8VytREi1Ft5Ih7hd9jjehod8vAM5GMsfQ/TpPf4EyoEA==", + "license": "MIT", "dependencies": { "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", "universalify": "^2.0.0" }, "engines": { - "node": ">=12" - } - }, - "node_modules/fs-minipass": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", - "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">= 8" + "node": ">=14.14" } }, "node_modules/get-caller-file": { @@ -623,38 +814,55 @@ "node": "6.* || 8.* || >= 10.*" } }, - "node_modules/get-stream": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", - "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "node_modules/get-east-asian-width": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.6.0.tgz", + "integrity": "sha512-QRbvDIbx6YklUe6RxeTeleMR0yv3cYH6PsPZHcnVn7xv7zO1BHN8r0XETu8n6Ye3Q+ahtSarc3WgtNWmehIBfA==", + "license": "MIT", "engines": { - "node": ">=10" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/got": { - "version": "12.3.1", - "resolved": "https://registry.npmjs.org/got/-/got-12.3.1.tgz", - "integrity": "sha512-tS6+JMhBh4iXMSXF6KkIsRxmloPln31QHDlcb6Ec3bzxjjFJFr/8aXdpyuLmVc9I4i2HyBHYw1QU5K1ruUdpkw==", - "dependencies": { - "@sindresorhus/is": "^5.2.0", - "@szmarczak/http-timer": "^5.0.1", - "@types/cacheable-request": "^6.0.2", - "@types/responselike": "^1.0.0", - "cacheable-lookup": "^6.0.4", - "cacheable-request": "^7.0.2", - "decompress-response": "^6.0.0", - "form-data-encoder": "^2.0.1", - "get-stream": "^6.0.1", - "http2-wrapper": "^2.1.10", - "lowercase-keys": "^3.0.0", - "p-cancelable": "^3.0.0", - "responselike": "^2.0.0" + "node_modules/get-stream": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-9.0.1.tgz", + "integrity": "sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA==", + "license": "MIT", + "dependencies": { + "@sec-ant/readable-stream": "^0.4.1", + "is-stream": "^4.0.1" }, "engines": { - "node": ">=14.16" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/got": { + "version": "15.1.0", + "resolved": "https://registry.npmjs.org/got/-/got-15.1.0.tgz", + "integrity": "sha512-DG+DAAkRtno+oDr/GBsliAkhN9+zczOPM5qXk3efDZY3qvyRnZU+NwQlb/IOY6cSnxxTR9z3aHCcShJyjb0hJA==", + "license": "MIT", + "dependencies": { + "@sindresorhus/is": "^8.0.0", + "byte-counter": "^0.1.0", + "cacheable-lookup": "^7.0.0", + "cacheable-request": "^13.0.18", + "chunk-data": "^0.1.0", + "decompress-response": "^10.0.0", + "http2-wrapper": "^2.2.1", + "keyv": "^5.6.0", + "lowercase-keys": "^4.0.1", + "responselike": "^4.0.2", + "type-fest": "^5.6.0", + "uint8array-extras": "^1.5.0" + }, + "engines": { + "node": ">=22" }, "funding": { "url": "https://github.com/sindresorhus/got?sponsor=1" @@ -666,14 +874,16 @@ "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==" }, "node_modules/http-cache-semantics": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", - "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==" + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.2.0.tgz", + "integrity": "sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ==", + "license": "BSD-2-Clause" }, "node_modules/http2-wrapper": { - "version": "2.1.11", - "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-2.1.11.tgz", - "integrity": "sha512-aNAk5JzLturWEUiuhAN73Jcbq96R7rTitAoXV54FYMatvihnpD2+6PUgU4ce3D/m5VDbw+F5CsyKSF176ptitQ==", + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-2.2.1.tgz", + "integrity": "sha512-V5nVw1PAOgfI3Lmeaj2Exmeg7fenjhRUgz1lPSezy1CuhPYbgQtbQj4jZfEAEMlaL+vupsvhjqCyjzob0yxsmQ==", + "license": "MIT", "dependencies": { "quick-lru": "^5.1.1", "resolve-alpn": "^1.2.0" @@ -699,375 +909,273 @@ "type": "consulting", "url": "https://feross.org/support" } - ] - }, - "node_modules/indent-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", - "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", - "engines": { - "node": ">=8" - } + ], + "license": "BSD-3-Clause" }, "node_modules/inherits": { "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "engines": { - "node": ">=8" - } - }, - "node_modules/json-buffer": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", - "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==" - }, - "node_modules/jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", - "dependencies": { - "universalify": "^2.0.0" - }, - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/keypress": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/keypress/-/keypress-0.2.1.tgz", - "integrity": "sha512-HjorDJFNhnM4SicvaUXac0X77NiskggxJdesG72+O5zBKpSqKFCrqmndKVqpu3pFqkla0St6uGk8Ju0sCurrmg==" - }, - "node_modules/keyv": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.3.3.tgz", - "integrity": "sha512-AcysI17RvakTh8ir03+a3zJr5r0ovnAH/XTXei/4HIv3bL2K/jzvgivLK9UuI/JbU1aJjM3NSAnVvVVd3n+4DQ==", - "dependencies": { - "compress-brotli": "^1.3.8", - "json-buffer": "3.0.1" - } - }, - "node_modules/listr2": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/listr2/-/listr2-5.0.2.tgz", - "integrity": "sha512-/yIYitiJgIkzVIKqQc+Dpcpwaj4PjeW/hSi7/xoGJ5mil7vQYedr5kKuEyLhANlnifCcumafnIR6azpb8loODw==", - "dependencies": { - "cli-truncate": "^2.1.0", - "colorette": "^2.0.19", - "log-update": "^4.0.0", - "p-map": "^4.0.0", - "rfdc": "^1.3.0", - "rxjs": "^7.5.6", - "through": "^2.3.8", - "wrap-ansi": "^7.0.0" - }, - "engines": { - "node": "^14.13.1 || >=16.0.0" - }, - "peerDependencies": { - "enquirer": ">= 2.3.0 < 3" - }, - "peerDependenciesMeta": { - "enquirer": { - "optional": true - } - } - }, - "node_modules/listr2/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/listr2/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/listr2/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "license": "ISC" }, - "node_modules/listr2/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "node_modules/is-fullwidth-code-point": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-5.1.0.tgz", + "integrity": "sha512-5XHYaSyiqADb4RnZ1Bdad6cPp8Toise4TzEjcOYDHZkTCbKgiUl7WTUCpNWHuxmDt91wnsZBc9xinNzopv3JMQ==", + "license": "MIT", "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" + "get-east-asian-width": "^1.3.1" }, "engines": { - "node": ">=8" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/listr2/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dependencies": { - "ansi-regex": "^5.0.1" - }, + "node_modules/is-stream": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-4.0.1.tgz", + "integrity": "sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A==", + "license": "MIT", "engines": { - "node": ">=8" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/listr2/node_modules/wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" + "universalify": "^2.0.0" }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + "optionalDependencies": { + "graceful-fs": "^4.1.6" } }, - "node_modules/lodash-es": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz", - "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==" + "node_modules/keypress": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/keypress/-/keypress-0.2.1.tgz", + "integrity": "sha512-HjorDJFNhnM4SicvaUXac0X77NiskggxJdesG72+O5zBKpSqKFCrqmndKVqpu3pFqkla0St6uGk8Ju0sCurrmg==" }, - "node_modules/log-update": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/log-update/-/log-update-4.0.0.tgz", - "integrity": "sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg==", + "node_modules/keyv": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-5.6.0.tgz", + "integrity": "sha512-CYDD3SOtsHtyXeEORYRx2qBtpDJFjRTGXUtmNEMGyzYOKj1TE3tycdlho7kA1Ufx9OYWZzg52QFBGALTirzDSw==", + "license": "MIT", "dependencies": { - "ansi-escapes": "^4.3.0", - "cli-cursor": "^3.1.0", - "slice-ansi": "^4.0.0", - "wrap-ansi": "^6.2.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "@keyv/serialize": "^1.1.1" } }, - "node_modules/log-update/node_modules/ansi-escapes": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", - "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "node_modules/listr2": { + "version": "10.2.2", + "resolved": "https://registry.npmjs.org/listr2/-/listr2-10.2.2.tgz", + "integrity": "sha512-JtNtbZj8q5BnDMR7trpwvwk3RIrANtIVzEUm8w7amp6xelLgyuq+4WZoTH913XaQAoH/cNdYhaNzBPA2U3xbDw==", + "license": "MIT", "dependencies": { - "type-fest": "^0.21.3" + "cli-truncate": "^5.2.0", + "eventemitter3": "^5.0.4", + "log-update": "^6.1.0", + "rfdc": "^1.4.1", + "wrap-ansi": "^10.0.0" }, "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=22.13.0" } }, - "node_modules/log-update/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "engines": { - "node": ">=8" - } + "node_modules/lodash-es": { + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.18.1.tgz", + "integrity": "sha512-J8xewKD/Gk22OZbhpOVSwcs60zhd95ESDwezOFuA3/099925PdHJ7OFHNTGtajL3AlZkykD32HykiMo+BIBI8A==", + "license": "MIT" }, - "node_modules/log-update/node_modules/ansi-styles": { + "node_modules/lodash.camelcase": { "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", + "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==", + "license": "MIT" + }, + "node_modules/log-update": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/log-update/-/log-update-6.1.0.tgz", + "integrity": "sha512-9ie8ItPR6tjY5uYJh8K/Zrv/RMZ5VOlOWvtZdEHYSTFKZfIBPQa9tOAEeAWhd+AnIneLJ22w5fjOYtoutpWq5w==", + "license": "MIT", "dependencies": { - "color-convert": "^2.0.1" + "ansi-escapes": "^7.0.0", + "cli-cursor": "^5.0.0", + "slice-ansi": "^7.1.0", + "strip-ansi": "^7.1.0", + "wrap-ansi": "^9.0.0" }, "engines": { - "node": ">=8" + "node": ">=18" }, "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/log-update/node_modules/cli-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", - "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", - "dependencies": { - "restore-cursor": "^3.1.0" - }, + "node_modules/log-update/node_modules/ansi-regex": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "license": "MIT", "engines": { - "node": ">=8" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" } }, "node_modules/log-update/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" - }, - "node_modules/log-update/node_modules/restore-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", - "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", - "dependencies": { - "onetime": "^5.1.0", - "signal-exit": "^3.0.2" - }, - "engines": { - "node": ">=8" - } + "version": "10.6.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz", + "integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==", + "license": "MIT" }, "node_modules/log-update/node_modules/slice-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", - "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-7.1.2.tgz", + "integrity": "sha512-iOBWFgUX7caIZiuutICxVgX1SdxwAVFFKwt1EvMYYec/NWO5meOJ6K5uQxhrYBdQJne4KxiqZc+KptFOWFSI9w==", + "license": "MIT", "dependencies": { - "ansi-styles": "^4.0.0", - "astral-regex": "^2.0.0", - "is-fullwidth-code-point": "^3.0.0" + "ansi-styles": "^6.2.1", + "is-fullwidth-code-point": "^5.0.0" }, "engines": { - "node": ">=10" + "node": ">=18" }, "funding": { "url": "https://github.com/chalk/slice-ansi?sponsor=1" } }, "node_modules/log-update/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", + "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", + "license": "MIT", "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" }, "engines": { - "node": ">=8" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/log-update/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz", + "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", + "license": "MIT", "dependencies": { - "ansi-regex": "^5.0.1" + "ansi-regex": "^6.2.2" }, "engines": { - "node": ">=8" - } - }, - "node_modules/log-update/node_modules/type-fest": { - "version": "0.21.3", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", - "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", - "engines": { - "node": ">=10" + "node": ">=12" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, "node_modules/log-update/node_modules/wrap-ansi": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", - "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.2.tgz", + "integrity": "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==", + "license": "MIT", "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" + "ansi-styles": "^6.2.1", + "string-width": "^7.0.0", + "strip-ansi": "^7.1.0" }, "engines": { - "node": ">=8" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, + "node_modules/long": { + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/long/-/long-5.2.4.tgz", + "integrity": "sha512-qtzLbJE8hq7VabR3mISmVGtoXP8KGc2Z/AT8OuqlYD7JTR3oqrgwdjnk07wpj1twXxYmgDXgoKVWUG/fReSzHg==", + "license": "Apache-2.0" + }, "node_modules/lowercase-keys": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-3.0.0.tgz", - "integrity": "sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-4.0.1.tgz", + "integrity": "sha512-wI9Nui/L8VfADa/cr/7NQruaASk1k23/Uh1khQ02BCVYiiy8F4AhOGnQzJy3Fl/c44GnYSbZHv8g7EcG3kJ1Qg==", + "license": "MIT", "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + "node": ">=20" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/luxon": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/luxon/-/luxon-3.0.1.tgz", - "integrity": "sha512-hF3kv0e5gwHQZKz4wtm4c+inDtyc7elkanAsBq+fundaCdUBNJB1dHEGUZIM6SfSBUlbVFduPwEtNjFK8wLtcw==", + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/luxon/-/luxon-3.7.2.tgz", + "integrity": "sha512-vtEhXh/gNjI9Yg1u4jX/0YVPMvxzHuGgCm6tC5kZyb08yjGWGnqAjGJvcXbqQR2P3MyMEFnRbpcdFS6PBcLqew==", + "license": "MIT", "engines": { "node": ">=12" } }, - "node_modules/mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "node_modules/mimic-function": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/mimic-function/-/mimic-function-5.0.1.tgz", + "integrity": "sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==", + "license": "MIT", "engines": { - "node": ">=6" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/mimic-response": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", - "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-4.0.0.tgz", + "integrity": "sha512-e5ISH9xMYU0DzrT+jl8q2ze9D6eWBto+I8CNpe+VI+K2J/F/k3PdkdTdz4wvGVH4NTpo+NRYTVIuMQEMMcsLqg==", + "license": "MIT", "engines": { - "node": ">=4" + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/minipass": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.4.tgz", - "integrity": "sha512-I9WPbWHCGu8W+6k1ZiGpPu0GkoKBeorkfKNuAFBNS1HNFJvke82sxvI5bzcCNpWPorkOO5QQ+zomzzwRxejXiw==", - "dependencies": { - "yallist": "^4.0.0" - }, + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", "engines": { - "node": ">=8" + "node": ">=16 || 14 >=14.17" } }, "node_modules/minizlib": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", - "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-3.1.0.tgz", + "integrity": "sha512-KZxYo1BUkWD2TVFLr0MQoM8vUUigWD3LlD83a/75BqC+4qE0Hb1Vo5v1FgcfaNXvfXzr+5EhQ6ing/CaBijTlw==", + "license": "MIT", "dependencies": { - "minipass": "^3.0.0", - "yallist": "^4.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "bin": { - "mkdirp": "bin/cmd.js" + "minipass": "^7.1.2" }, "engines": { - "node": ">=10" + "node": ">= 18" } }, "node_modules/mkdirp-classic": { "version": "0.5.3", "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", - "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==" + "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", + "license": "MIT" }, "node_modules/ms": { "version": "2.1.2", @@ -1075,17 +1183,19 @@ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, "node_modules/nan": { - "version": "2.16.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.16.0.tgz", - "integrity": "sha512-UdAqHyFngu7TfQKsCBgAA6pWDkT8MAO7d0jyOecVhN5354xbLqdn8mV9Tat9gepAupm0bt2DbeaSC8vS52MuFA==", + "version": "2.28.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.28.0.tgz", + "integrity": "sha512-fTsDz99OTq2sVePhGdp4qQhggZFtKr64ZNVyVajRKtMOkJxYekplBh577PiJB12v/D3s2E5cGtOI45LWp6rnLQ==", + "license": "MIT", "optional": true }, "node_modules/normalize-url": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", - "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==", + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-8.1.1.tgz", + "integrity": "sha512-JYc0DPlpGWB40kH5g07gGTrYuMqV653k3uBKY6uITPWds3M0ov3GaWGp9lbE3Bzngx8+XkfzgvASb9vk9JDFXQ==", + "license": "MIT", "engines": { - "node": ">=10" + "node": ">=14.16" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -1100,36 +1210,15 @@ } }, "node_modules/onetime": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", - "dependencies": { - "mimic-fn": "^2.1.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-cancelable": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-3.0.0.tgz", - "integrity": "sha512-mlVgR3PGuzlo0MmTdk4cXqXWlwQDLnONTAg6sm62XkMJEiRxN3GL3SffkYvqwonbkJBcrI7Uvv5Zh9yjvn2iUw==", - "engines": { - "node": ">=12.20" - } - }, - "node_modules/p-map": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", - "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-7.0.0.tgz", + "integrity": "sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==", + "license": "MIT", "dependencies": { - "aggregate-error": "^3.0.0" + "mimic-function": "^5.0.0" }, "engines": { - "node": ">=10" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -1141,16 +1230,41 @@ "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==" }, "node_modules/pretty-bytes": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-6.0.0.tgz", - "integrity": "sha512-6UqkYefdogmzqAZWzJ7laYeJnaXDy2/J+ZqiiMtS7t7OfpXWTlaeGMwX8U6EFvPV/YWWEKRkS8hKS4k60WHTOg==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-7.1.0.tgz", + "integrity": "sha512-nODzvTiYVRGRqAOvE84Vk5JDPyyxsVk0/fbA/bq7RqlnhksGpset09XTxbpvLTIjoaF7K8Z8DG8yHtKGTPSYRw==", + "license": "MIT", "engines": { - "node": "^14.13.1 || >=16.0.0" + "node": ">=20" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/protobufjs": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.4.0.tgz", + "integrity": "sha512-mRUWCc3KUU4w1jU8sGxICXH/gNS94DvI1gxqDvBzhj1JpcsimQkYiOJfwsPUykUI5ZaspFbSgmBLER8IrQ3tqw==", + "hasInstallScript": true, + "license": "BSD-3-Clause", + "dependencies": { + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/codegen": "^2.0.4", + "@protobufjs/eventemitter": "^1.1.0", + "@protobufjs/fetch": "^1.1.0", + "@protobufjs/float": "^1.0.2", + "@protobufjs/inquire": "^1.1.0", + "@protobufjs/path": "^1.1.2", + "@protobufjs/pool": "^1.1.0", + "@protobufjs/utf8": "^1.1.0", + "@types/node": ">=13.7.0", + "long": "^5.0.0" + }, + "engines": { + "node": ">=12.0.0" + } + }, "node_modules/pump": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", @@ -1164,6 +1278,7 @@ "version": "5.1.1", "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", + "license": "MIT", "engines": { "node": ">=10" }, @@ -1172,9 +1287,10 @@ } }, "node_modules/readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "license": "MIT", "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", @@ -1188,6 +1304,7 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -1195,40 +1312,58 @@ "node_modules/resolve-alpn": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz", - "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==" + "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==", + "license": "MIT" }, "node_modules/responselike": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.1.tgz", - "integrity": "sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-4.0.2.tgz", + "integrity": "sha512-cGk8IbWEAnaCpdAt1BHzJ3Ahz5ewDJa0KseTsE3qIRMJ3C698W8psM7byCeWVpd/Ha7FUYzuRVzXoKoM6nRUbA==", + "license": "MIT", "dependencies": { - "lowercase-keys": "^2.0.0" + "lowercase-keys": "^3.0.0" + }, + "engines": { + "node": ">=20" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/responselike/node_modules/lowercase-keys": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", - "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-3.0.0.tgz", + "integrity": "sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ==", + "license": "MIT", "engines": { - "node": ">=8" + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/rfdc": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.3.0.tgz", - "integrity": "sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==" - }, - "node_modules/rxjs": { - "version": "7.5.6", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.5.6.tgz", - "integrity": "sha512-dnyv2/YsXhnm461G+R/Pe5bWP41Nm6LBXEYWI6eiFP4fiwx6WRI/CD0zbdVAudd9xwLEF2IDcKXLHit0FYjUzw==", + "node_modules/restore-cursor": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-5.1.0.tgz", + "integrity": "sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==", + "license": "MIT", "dependencies": { - "tslib": "^2.1.0" + "onetime": "^7.0.0", + "signal-exit": "^4.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/rfdc": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz", + "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==", + "license": "MIT" + }, "node_modules/safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", @@ -1246,106 +1381,174 @@ "type": "consulting", "url": "https://feross.org/support" } - ] + ], + "license": "MIT" }, "node_modules/safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "license": "MIT" }, "node_modules/signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" - }, - "node_modules/slice-ansi": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-3.0.0.tgz", - "integrity": "sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==", - "dependencies": { - "ansi-styles": "^4.0.0", - "astral-regex": "^2.0.0", - "is-fullwidth-code-point": "^3.0.0" - }, + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "license": "ISC", "engines": { - "node": ">=8" + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/slice-ansi/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "node_modules/slice-ansi": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-8.0.0.tgz", + "integrity": "sha512-stxByr12oeeOyY2BlviTNQlYV5xOj47GirPr4yA1hE9JCtxfQN0+tVbkxwCtYDQWhEKWFHsEK48ORg5jrouCAg==", + "license": "MIT", "dependencies": { - "color-convert": "^2.0.1" + "ansi-styles": "^6.2.3", + "is-fullwidth-code-point": "^5.1.0" }, "engines": { - "node": ">=8" + "node": ">=20" }, "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "url": "https://github.com/chalk/slice-ansi?sponsor=1" } }, "node_modules/split-ca": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/split-ca/-/split-ca-1.0.1.tgz", - "integrity": "sha512-Q5thBSxp5t8WPTTJQS59LrGqOZqOsrhDGDVm8azCqIBjSBd7nd9o2PM+mDulQQkh8h//4U6hFZnc/mul8t5pWQ==" + "integrity": "sha512-Q5thBSxp5t8WPTTJQS59LrGqOZqOsrhDGDVm8azCqIBjSBd7nd9o2PM+mDulQQkh8h//4U6hFZnc/mul8t5pWQ==", + "license": "ISC" }, "node_modules/ssh2": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/ssh2/-/ssh2-1.11.0.tgz", - "integrity": "sha512-nfg0wZWGSsfUe/IBJkXVll3PEZ//YH2guww+mP88gTpuSU4FtZN7zu9JoeTGOyCNx2dTDtT9fOpWwlzyj4uOOw==", + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/ssh2/-/ssh2-1.17.0.tgz", + "integrity": "sha512-wPldCk3asibAjQ/kziWQQt1Wh3PgDFpC0XpwclzKcdT1vql6KeYxf5LIt4nlFkUeR8WuphYMKqUA56X4rjbfgQ==", "hasInstallScript": true, "dependencies": { - "asn1": "^0.2.4", - "bcrypt-pbkdf": "^1.0.2" + "asn1": "^0.2.6", + "bcrypt-pbkdf": "^1.0.2" + }, + "engines": { + "node": ">=10.16.0" + }, + "optionalDependencies": { + "cpu-features": "~0.0.10", + "nan": "^2.23.0" + } + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/string-width": { + "version": "8.2.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-8.2.2.tgz", + "integrity": "sha512-GaPUh5gfdrYzqeVNZvUfT23vYYxXzKYidUcnMtJg/3rxRV63EFZy3k6xfKlmfeJD0176lnUV/Usr3XcwSvFzpg==", + "license": "MIT", + "dependencies": { + "get-east-asian-width": "^1.5.0", + "strip-ansi": "^7.1.2" + }, + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/string-width/node_modules/ansi-regex": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/string-width/node_modules/strip-ansi": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz", + "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.2.2" }, "engines": { - "node": ">=10.16.0" + "node": ">=12" }, - "optionalDependencies": { - "cpu-features": "~0.0.4", - "nan": "^2.16.0" + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, - "node_modules/string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dependencies": { - "safe-buffer": "~5.2.0" + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/tagged-tag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/tagged-tag/-/tagged-tag-1.0.0.tgz", + "integrity": "sha512-yEFYrVhod+hdNyx7g5Bnkkb0G6si8HJurOoOEgC8B/O0uXLHlaey/65KRv6cuWBNhBgHKAROVpc7QyYqE5gFng==", + "license": "MIT", + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/tar": { - "version": "6.1.11", - "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.11.tgz", - "integrity": "sha512-an/KZQzQUkZCkuoAA64hM92X0Urb6VpRhAFllDzz44U2mcD5scmT3zBc4VgVpkugF580+DQn8eAFSyoQt0tznA==", + "version": "7.5.19", + "resolved": "https://registry.npmjs.org/tar/-/tar-7.5.19.tgz", + "integrity": "sha512-4LeEWl96twnS2Q7Bz4MGqgazLqO+hJN63GZxXoIqh1T3VweYD997gbU1ItNsQafqqXTXd5WFyFdReLtwvRBNiw==", + "license": "BlueOak-1.0.0", "dependencies": { - "chownr": "^2.0.0", - "fs-minipass": "^2.0.0", - "minipass": "^3.0.0", - "minizlib": "^2.1.1", - "mkdirp": "^1.0.3", - "yallist": "^4.0.0" + "@isaacs/fs-minipass": "^4.0.0", + "chownr": "^3.0.0", + "minipass": "^7.1.2", + "minizlib": "^3.1.0", + "yallist": "^5.0.0" }, "engines": { - "node": ">= 10" + "node": ">=18" } }, "node_modules/tar-fs": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.0.1.tgz", - "integrity": "sha512-6tzWDMeroL87uF/+lin46k+Q+46rAJ0SyPGz7OW7wTgblI273hsBqk2C1j0/xNadNLKDTUL9BukSjB7cwgmlPA==", + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.5.tgz", + "integrity": "sha512-OboTd8mmMhZDNPV+UjQcK9yKAatXu2aJ+r1w4im1Otd4M4fl2hwvdoXUxIYHFTHWK/3y3FarBP70v3vwmGlOxw==", + "license": "MIT", "dependencies": { "chownr": "^1.1.1", "mkdirp-classic": "^0.5.2", "pump": "^3.0.0", - "tar-stream": "^2.0.0" + "tar-stream": "^2.1.4" } }, "node_modules/tar-stream": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", + "license": "MIT", "dependencies": { "bl": "^4.0.3", "end-of-stream": "^1.4.1", @@ -1357,61 +1560,46 @@ "node": ">=6" } }, - "node_modules/tar-stream/node_modules/bl": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", - "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", - "dependencies": { - "buffer": "^5.5.0", - "inherits": "^2.0.4", - "readable-stream": "^3.4.0" - } - }, - "node_modules/tar-stream/node_modules/buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" - } - }, "node_modules/tar/node_modules/chownr": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", - "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-3.0.0.tgz", + "integrity": "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==", "engines": { - "node": ">=10" + "node": ">=18" } }, - "node_modules/through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==" - }, - "node_modules/tslib": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", - "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==" - }, "node_modules/tweetnacl": { "version": "0.14.5", "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==" + "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==", + "license": "Unlicense" + }, + "node_modules/type-fest": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-5.8.0.tgz", + "integrity": "sha512-YGYEVz3Fm5iy/AybuA0oyNFq7H4CgQNfRp/qfe8nurE1kuCeNm3/vfm9X4Mtl+qLyaKJUh5xrFZwogr41SMjYA==", + "license": "(MIT OR CC0-1.0)", + "dependencies": { + "tagged-tag": "^1.0.0" + }, + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/uint8array-extras": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/uint8array-extras/-/uint8array-extras-1.5.0.tgz", + "integrity": "sha512-rvKSBiC5zqCCiDZ9kAOszZcDvdAHwwIKJG33Ykj43OKcWsnmcBRL09YTU4nOeHZ8Y2a7l1MgTd08SBe9A8Qj6A==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, "node_modules/universalify": { "version": "2.0.0", @@ -1424,7 +1612,52 @@ "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "license": "MIT" + }, + "node_modules/wrap-ansi": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-10.0.0.tgz", + "integrity": "sha512-SGcvg80f0wUy2/fXES19feHMz8E0JoXv2uNgHOu4Dgi2OrCy1lqwFYEJz1BLbDI0exjPMe/ZdzZ/YpGECBG/aQ==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.2.3", + "string-width": "^8.2.0", + "strip-ansi": "^7.1.2" + }, + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-regex": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/strip-ansi": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz", + "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.2.2" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } }, "node_modules/wrappy": { "version": "1.0.2", @@ -1440,70 +1673,87 @@ } }, "node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-5.0.0.tgz", + "integrity": "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==", + "engines": { + "node": ">=18" + } }, "node_modules/yargs": { - "version": "17.5.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.5.1.tgz", - "integrity": "sha512-t6YAJcxDkNX7NFYiVtKvWUz8l+PaKTLiL63mJYWR2GnHq2gjEWISzsLp9wg3aY36dY1j+gfIEL3pIF+XlJJfbA==", + "version": "18.0.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-18.0.0.tgz", + "integrity": "sha512-4UEqdc2RYGHZc7Doyqkrqiln3p9X2DZVxaGbwhn2pi7MrRagKaOcIKe8L3OxYcbhXLgLFUS3zAYuQjKBQgmuNg==", + "license": "MIT", "dependencies": { - "cliui": "^7.0.2", + "cliui": "^9.0.1", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.3", + "string-width": "^7.2.0", "y18n": "^5.0.5", - "yargs-parser": "^21.0.0" + "yargs-parser": "^22.0.0" }, "engines": { - "node": ">=12" + "node": "^20.19.0 || ^22.12.0 || >=23" } }, "node_modules/yargs-parser": { - "version": "21.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", - "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "version": "22.0.0", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-22.0.0.tgz", + "integrity": "sha512-rwu/ClNdSMpkSrUb+d6BRsSkLUq1fmfsY6TOpYzTwvwkg1/NRG85KBy3kq++A8LKQwX6lsu+aWad+2khvuXrqw==", + "license": "ISC", "engines": { - "node": ">=12" + "node": "^20.19.0 || ^22.12.0 || >=23" } }, "node_modules/yargs/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "license": "MIT", "engines": { - "node": ">=8" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" } }, "node_modules/yargs/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + "version": "10.6.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz", + "integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==", + "license": "MIT" }, "node_modules/yargs/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", + "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", + "license": "MIT", "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" }, "engines": { - "node": ">=8" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/yargs/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz", + "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", + "license": "MIT", "dependencies": { - "ansi-regex": "^5.0.1" + "ansi-regex": "^6.2.2" }, "engines": { - "node": ">=8" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, "node_modules/yauzl": { @@ -1517,61 +1767,187 @@ } }, "dependencies": { - "@sindresorhus/is": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-5.3.0.tgz", - "integrity": "sha512-CX6t4SYQ37lzxicAqsBtxA3OseeoVrh9cSJ5PFYam0GksYlupRfy1A+Q4aYD3zvcfECLc0zO2u+ZnR2UYKvCrw==" + "@balena/dockerignore": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@balena/dockerignore/-/dockerignore-1.0.2.tgz", + "integrity": "sha512-wMue2Sy4GAVTk6Ic4tJVcnfdau+gx2EnG7S+uAEe+TWJFqE4YoWN4/H8MSLj4eYJKxGg26lZwboEniNiNwZQ6Q==" }, - "@szmarczak/http-timer": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-5.0.1.tgz", - "integrity": "sha512-+PmQX0PiAYPMeVYe237LJAYvOMYW1j2rH5YROyS3b4CTVJum34HfRvKvAzozHAQG0TnHNdUfY9nCeUyRAs//cw==", + "@grpc/grpc-js": { + "version": "1.12.5", + "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.12.5.tgz", + "integrity": "sha512-d3iiHxdpg5+ZcJ6jnDSOT8Z0O0VMVGy34jAnYLUX8yd36b1qn8f1TwOA/Lc7TsOh03IkPJ38eGI5qD2EjNkoEA==", "requires": { - "defer-to-connect": "^2.0.1" + "@grpc/proto-loader": "^0.7.13", + "@js-sdsl/ordered-map": "^4.4.2" } }, - "@types/cacheable-request": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.2.tgz", - "integrity": "sha512-B3xVo+dlKM6nnKTcmm5ZtY/OL8bOAOd2Olee9M1zft65ox50OzjEHW91sDiU9j6cvW8Ejg1/Qkf4xd2kugApUA==", + "@grpc/proto-loader": { + "version": "0.7.13", + "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.7.13.tgz", + "integrity": "sha512-AiXO/bfe9bmxBjxxtYxFAXGZvMaN5s8kO+jBHAJCON8rJoB5YS/D6X7ZNc6XQkuHNmyl4CYaMI1fJ/Gn27RGGw==", "requires": { - "@types/http-cache-semantics": "*", - "@types/keyv": "*", - "@types/node": "*", - "@types/responselike": "*" + "lodash.camelcase": "^4.3.0", + "long": "^5.0.0", + "protobufjs": "^7.2.5", + "yargs": "^17.7.2" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "requires": { + "color-convert": "^2.0.1" + } + }, + "cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + } + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" + }, + "string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + } + }, + "wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } + }, + "yargs": { + "version": "17.7.3", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.3.tgz", + "integrity": "sha512-GZtjxm/J/4TSxuL3FNYjCmLktBTnIw/rVmKSIyKeYAZpmJB2ig9VauCC5xsa82GNKVKDAqpOn3KVzNt0zmrU0g==", + "requires": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + } + }, + "yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==" + } } }, - "@types/http-cache-semantics": { + "@isaacs/fs-minipass": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.1.tgz", - "integrity": "sha512-SZs7ekbP8CN0txVG2xVRH6EgKmEm31BOxA07vkFaETzZz1xh+cbt8BcI0slpymvwhx5dlFnQG2rTlPVQn+iRPQ==" + "resolved": "https://registry.npmjs.org/@isaacs/fs-minipass/-/fs-minipass-4.0.1.tgz", + "integrity": "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==", + "requires": { + "minipass": "^7.0.4" + } }, - "@types/json-buffer": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/json-buffer/-/json-buffer-3.0.0.tgz", - "integrity": "sha512-3YP80IxxFJB4b5tYC2SUPwkg0XQLiu0nWvhRgEatgjf+29IcWO9X1k8xRv5DGssJ/lCrjYTjQPcobJr2yWIVuQ==" + "@js-sdsl/ordered-map": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/@js-sdsl/ordered-map/-/ordered-map-4.4.2.tgz", + "integrity": "sha512-iUKgm52T8HOE/makSxjqoWhe95ZJA1/G1sYsGev2JDKUSS14KAgg1LHb+Ba+IPow0xflbnSkOsZcO08C7w1gYw==" + }, + "@keyv/serialize": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@keyv/serialize/-/serialize-1.1.1.tgz", + "integrity": "sha512-dXn3FZhPv0US+7dtJsIi2R+c7qWYiReoEh5zUntWCf4oSpMNib8FDhSoed6m3QyZdx5hK7iLFkYk3rNxwt8vTA==" + }, + "@protobufjs/aspromise": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", + "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==" }, - "@types/keyv": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.4.tgz", - "integrity": "sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==", + "@protobufjs/base64": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", + "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==" + }, + "@protobufjs/codegen": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", + "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==" + }, + "@protobufjs/eventemitter": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", + "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==" + }, + "@protobufjs/fetch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", + "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==", "requires": { - "@types/node": "*" + "@protobufjs/aspromise": "^1.1.1", + "@protobufjs/inquire": "^1.1.0" } }, + "@protobufjs/float": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", + "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==" + }, + "@protobufjs/inquire": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", + "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==" + }, + "@protobufjs/path": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", + "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==" + }, + "@protobufjs/pool": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", + "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==" + }, + "@protobufjs/utf8": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", + "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==" + }, + "@sec-ant/readable-stream": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@sec-ant/readable-stream/-/readable-stream-0.4.1.tgz", + "integrity": "sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg==" + }, + "@sindresorhus/is": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-8.1.0.tgz", + "integrity": "sha512-2SX/1jW6CIMAiebvVv5ZInoCEuWQmMyBoJXXGC6Vjakjp/fpxP5eHs7/V6WKuPEIbuK06+VpjH+vjLQhr98rDQ==" + }, + "@types/http-cache-semantics": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.2.0.tgz", + "integrity": "sha512-L3LgimLHXtGkWikKnsPg0/VFx9OGZaC+eN1u4r+OB1XRqH3meBIAVC2zr1WdMH+RHmnRkqliQAOHNJ/E0j/e0Q==" + }, "@types/node": { "version": "18.6.5", "resolved": "https://registry.npmjs.org/@types/node/-/node-18.6.5.tgz", "integrity": "sha512-Xjt5ZGUa5WusGZJ4WJPbOT8QOqp6nDynVFRKcUt32bOgvXEoc6o085WNkYTMO7ifAj2isEfQQ2cseE+wT6jsRw==" }, - "@types/responselike": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.0.tgz", - "integrity": "sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA==", - "requires": { - "@types/node": "*" - } - }, "@types/yauzl": { "version": "2.10.0", "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.0.tgz", @@ -1581,20 +1957,29 @@ "@types/node": "*" } }, - "aggregate-error": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", - "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", - "requires": { - "clean-stack": "^2.0.0", - "indent-string": "^4.0.0" - } - }, "ansi-colors": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==" }, + "ansi-escapes": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-7.3.0.tgz", + "integrity": "sha512-BvU8nYgGQBxcmMuEeUEmNTvrMVjJNSH7RgW24vXexN4Ven6qCvy4TntnvlnwnMLTVlcRQQdbRY8NKnaIoeWDNg==", + "requires": { + "environment": "^1.0.0" + } + }, + "ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==" + }, + "ansi-styles": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==" + }, "asn1": { "version": "0.2.6", "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", @@ -1603,11 +1988,6 @@ "safer-buffer": "~2.1.0" } }, - "astral-regex": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", - "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==" - }, "base64-js": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", @@ -1621,171 +2001,142 @@ "tweetnacl": "^0.14.3" } }, + "bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "requires": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "requires": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, "buffer-crc32": { "version": "0.2.13", "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==" }, "buildcheck": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/buildcheck/-/buildcheck-0.0.3.tgz", - "integrity": "sha512-pziaA+p/wdVImfcbsZLNF32EiWyujlQLwolMqUQE8xpKNOH7KmZQaY8sXN7DGOEzPAElo9QTaeNRfGnf3iOJbA==", + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/buildcheck/-/buildcheck-0.0.7.tgz", + "integrity": "sha512-lHblz4ahamxpTmnsk+MNTRWsjYKv965MwOrSJyeD588rR3Jcu7swE+0wN5F+PbL5cjgu/9ObkhfzEPuofEMwLA==", "optional": true }, + "byte-counter": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/byte-counter/-/byte-counter-0.1.0.tgz", + "integrity": "sha512-jheRLVMeUKrDBjVw2O5+k4EvR4t9wtxHL+bo/LxfkxsVeuGMy3a5SEGgXdAFA4FSzTrU8rQXQIrsZ3oBq5a0pQ==" + }, "cacheable-lookup": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-6.1.0.tgz", - "integrity": "sha512-KJ/Dmo1lDDhmW2XDPMo+9oiy/CeqosPguPCrgcVzKyZrL6pM1gU2GmPY/xo6OQPTUaA/c0kwHuywB4E6nmT9ww==" + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-7.0.0.tgz", + "integrity": "sha512-+qJyx4xiKra8mZrcwhjMRMUhD5NR1R8esPkzIYxX96JiecFoxAXFuz/GpR3+ev4PE1WamHip78wV0vcmPQtp8w==" }, "cacheable-request": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.2.tgz", - "integrity": "sha512-pouW8/FmiPQbuGpkXQ9BAPv/Mo5xDGANgSNXzTzJ8DrKGuXOssM4wIQRjfanNRh3Yu5cfYPvcorqbhg2KIJtew==", + "version": "13.0.19", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-13.0.19.tgz", + "integrity": "sha512-SVXGH037+Mo1aIMO5B2UcleR43FGjFdN+M8JObSyEoQ2Mn4CODRWx28gN5jiTF0n5ItsgtIZfyargMNs8GX4kg==", "requires": { - "clone-response": "^1.0.2", - "get-stream": "^5.1.0", - "http-cache-semantics": "^4.0.0", - "keyv": "^4.0.0", - "lowercase-keys": "^2.0.0", - "normalize-url": "^6.0.1", - "responselike": "^2.0.0" - }, - "dependencies": { - "get-stream": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", - "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", - "requires": { - "pump": "^3.0.0" - } - }, - "lowercase-keys": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", - "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==" - } + "@types/http-cache-semantics": "^4.2.0", + "get-stream": "^9.0.1", + "http-cache-semantics": "^4.2.0", + "keyv": "^5.6.0", + "mimic-response": "^4.0.0", + "normalize-url": "^8.1.1", + "responselike": "^4.0.2" } }, "chalk": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.0.1.tgz", - "integrity": "sha512-Fo07WOYGqMfCWHOzSXOt2CxDbC6skS/jO9ynEcmpANMoPrD+W1r1K6Vx7iNm+AQmETU1Xr2t+n8nzkV9t6xh3w==" + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz", + "integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==" }, "chownr": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==" }, - "clean-stack": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", - "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==" + "chunk-data": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/chunk-data/-/chunk-data-0.1.0.tgz", + "integrity": "sha512-zFyPtyC0SZ6Zu79b9sOYtXZcgrsXe0RpePrzRyj52hYVFG1+Rk6rBqjjOEk+GNQwc3PIX+86teQMok970pod1g==" + }, + "cli-cursor": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-5.0.0.tgz", + "integrity": "sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw==", + "requires": { + "restore-cursor": "^5.0.0" + } }, "cli-truncate": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-2.1.0.tgz", - "integrity": "sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-5.2.0.tgz", + "integrity": "sha512-xRwvIOMGrfOAnM1JYtqQImuaNtDEv9v6oIYAs4LIHwTiKee8uwvIi363igssOC0O5U04i4AlENs79LQLu9tEMw==", "requires": { - "slice-ansi": "^3.0.0", - "string-width": "^4.2.0" - }, - "dependencies": { - "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==" - }, - "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" - }, - "string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - } - }, - "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "requires": { - "ansi-regex": "^5.0.1" - } - } + "slice-ansi": "^8.0.0", + "string-width": "^8.2.0" } }, "cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-9.0.1.tgz", + "integrity": "sha512-k7ndgKhwoQveBL+/1tqGJYNz097I7WOvwbmmU2AR5+magtbjPWQTS1C5vzGkBC8Ym8UWRzfKUzUUqFLypY4Q+w==", "requires": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" + "string-width": "^7.2.0", + "strip-ansi": "^7.1.0", + "wrap-ansi": "^9.0.0" }, "dependencies": { "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==" - }, - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "requires": { - "color-convert": "^2.0.1" - } + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==" }, "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + "version": "10.6.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz", + "integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==" }, "string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", + "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" } }, "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz", + "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", "requires": { - "ansi-regex": "^5.0.1" + "ansi-regex": "^6.2.2" } }, "wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.2.tgz", + "integrity": "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==", "requires": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" + "ansi-styles": "^6.2.1", + "string-width": "^7.0.0", + "strip-ansi": "^7.1.0" } } } }, - "clone-response": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.3.tgz", - "integrity": "sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA==", - "requires": { - "mimic-response": "^1.0.0" - } - }, "color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -1799,28 +2150,14 @@ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, - "colorette": { - "version": "2.0.19", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.19.tgz", - "integrity": "sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ==" - }, - "compress-brotli": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/compress-brotli/-/compress-brotli-1.3.8.tgz", - "integrity": "sha512-lVcQsjhxhIXsuupfy9fmZUFtAIdBmXA7EGY6GBdgZ++qkM9zG4YFT8iU7FoBxzryNDMOpD1HIFHUSX4D87oqhQ==", - "requires": { - "@types/json-buffer": "~3.0.0", - "json-buffer": "~3.0.1" - } - }, "cpu-features": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/cpu-features/-/cpu-features-0.0.4.tgz", - "integrity": "sha512-fKiZ/zp1mUwQbnzb9IghXtHtDoTMtNeb8oYGx6kX2SYfhnG0HNdBEBIzB9b5KlXu5DQPhfy3mInbBxFcgwAr3A==", + "version": "0.0.10", + "resolved": "https://registry.npmjs.org/cpu-features/-/cpu-features-0.0.10.tgz", + "integrity": "sha512-9IkYqtX3YHPCzoVg1Py+o9057a3i0fp7S530UWokCSaFVTc7CwXPRiOjRjBQQ18ZCNafx78YfnG+HALxtVmOGA==", "optional": true, "requires": { - "buildcheck": "0.0.3", - "nan": "^2.15.0" + "buildcheck": "~0.0.6", + "nan": "^2.19.0" } }, "debug": { @@ -1832,45 +2169,42 @@ } }, "decompress-response": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", - "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-10.0.0.tgz", + "integrity": "sha512-oj7KWToJuuxlPr7VV0vabvxEIiqNMo+q0NueIiL3XhtwC6FVOX7Hr1c0C4eD0bmf7Zr+S/dSf2xvkH3Ad6sU3Q==", "requires": { - "mimic-response": "^3.1.0" - }, - "dependencies": { - "mimic-response": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", - "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==" - } + "mimic-response": "^4.0.0" } }, - "defer-to-connect": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", - "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==" - }, "docker-modem": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/docker-modem/-/docker-modem-3.0.5.tgz", - "integrity": "sha512-x1E6jxWdtoK3+ifAUWj4w5egPdTDGBpesSCErm+aKET5BnnEOvDtTP6GxcnMB1zZiv2iQ0qJZvJie+1wfIRg6Q==", + "version": "5.0.7", + "resolved": "https://registry.npmjs.org/docker-modem/-/docker-modem-5.0.7.tgz", + "integrity": "sha512-XJgGhoR/CLpqshm4d3L7rzH6t8NgDFUIIpztYlLHIApeJjMZKYJMz2zxPsYxnejq5h3ELYSw/RBsi3t5h7gNTA==", "requires": { "debug": "^4.1.1", "readable-stream": "^3.5.0", "split-ca": "^1.0.1", - "ssh2": "^1.4.0" + "ssh2": "^1.15.0" } }, "dockerode": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/dockerode/-/dockerode-3.3.3.tgz", - "integrity": "sha512-lvKV6/NGf2/CYLt5V4c0fd6Fl9XZSCo1Z2HBT9ioKrKLMB2o+gA62Uza8RROpzGvYv57KJx2dKu+ZwSpB//OIA==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/dockerode/-/dockerode-5.0.1.tgz", + "integrity": "sha512-avsq/xk4YPIrn0CgleX5bjT9Y8IT1p9PxrNQ++RBQ2WEyFfHCTDsT9kmyxz+H/axnjAwg8wJWEIuPGOUuNupiA==", "requires": { - "docker-modem": "^3.0.0", - "tar-fs": "~2.0.1" + "@balena/dockerignore": "^1.0.2", + "@grpc/grpc-js": "^1.11.1", + "@grpc/proto-loader": "^0.7.13", + "docker-modem": "^5.0.7", + "protobufjs": "^7.3.2", + "tar-fs": "^2.1.4" } }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, "end-of-stream": { "version": "1.4.4", "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", @@ -1880,18 +2214,29 @@ } }, "enquirer": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", - "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.4.1.tgz", + "integrity": "sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==", "requires": { - "ansi-colors": "^4.1.1" + "ansi-colors": "^4.1.1", + "strip-ansi": "^6.0.1" } }, + "environment": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/environment/-/environment-1.1.0.tgz", + "integrity": "sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q==" + }, "escalade": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==" }, + "eventemitter3": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.4.tgz", + "integrity": "sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw==" + }, "extract-zip": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", @@ -1921,62 +2266,57 @@ "pend": "~1.2.0" } }, - "form-data-encoder": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-2.0.1.tgz", - "integrity": "sha512-Oy+P9w5mnO4TWXVgUiQvggNKPI9/ummcSt5usuIV6HkaLKigwzPpoenhEqmGmx3zHqm6ZLJ+CR/99N8JLinaEw==" - }, "fs-constants": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==" }, "fs-extra": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", - "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "version": "11.3.6", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.6.tgz", + "integrity": "sha512-w8ZNZr2mKIc7qeNaQ9AVPT1+iFaI+Avd4xudVOvdDJ8VytREi1Ft5Ih7hd9jjehod8vAM5GMsfQ/TpPf4EyoEA==", "requires": { "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", "universalify": "^2.0.0" } }, - "fs-minipass": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", - "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", - "requires": { - "minipass": "^3.0.0" - } - }, "get-caller-file": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==" }, + "get-east-asian-width": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.6.0.tgz", + "integrity": "sha512-QRbvDIbx6YklUe6RxeTeleMR0yv3cYH6PsPZHcnVn7xv7zO1BHN8r0XETu8n6Ye3Q+ahtSarc3WgtNWmehIBfA==" + }, "get-stream": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", - "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==" + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-9.0.1.tgz", + "integrity": "sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA==", + "requires": { + "@sec-ant/readable-stream": "^0.4.1", + "is-stream": "^4.0.1" + } }, "got": { - "version": "12.3.1", - "resolved": "https://registry.npmjs.org/got/-/got-12.3.1.tgz", - "integrity": "sha512-tS6+JMhBh4iXMSXF6KkIsRxmloPln31QHDlcb6Ec3bzxjjFJFr/8aXdpyuLmVc9I4i2HyBHYw1QU5K1ruUdpkw==", + "version": "15.1.0", + "resolved": "https://registry.npmjs.org/got/-/got-15.1.0.tgz", + "integrity": "sha512-DG+DAAkRtno+oDr/GBsliAkhN9+zczOPM5qXk3efDZY3qvyRnZU+NwQlb/IOY6cSnxxTR9z3aHCcShJyjb0hJA==", "requires": { - "@sindresorhus/is": "^5.2.0", - "@szmarczak/http-timer": "^5.0.1", - "@types/cacheable-request": "^6.0.2", - "@types/responselike": "^1.0.0", - "cacheable-lookup": "^6.0.4", - "cacheable-request": "^7.0.2", - "decompress-response": "^6.0.0", - "form-data-encoder": "^2.0.1", - "get-stream": "^6.0.1", - "http2-wrapper": "^2.1.10", - "lowercase-keys": "^3.0.0", - "p-cancelable": "^3.0.0", - "responselike": "^2.0.0" + "@sindresorhus/is": "^8.0.0", + "byte-counter": "^0.1.0", + "cacheable-lookup": "^7.0.0", + "cacheable-request": "^13.0.18", + "chunk-data": "^0.1.0", + "decompress-response": "^10.0.0", + "http2-wrapper": "^2.2.1", + "keyv": "^5.6.0", + "lowercase-keys": "^4.0.1", + "responselike": "^4.0.2", + "type-fest": "^5.6.0", + "uint8array-extras": "^1.5.0" } }, "graceful-fs": { @@ -1985,14 +2325,14 @@ "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==" }, "http-cache-semantics": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", - "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==" + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.2.0.tgz", + "integrity": "sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ==" }, "http2-wrapper": { - "version": "2.1.11", - "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-2.1.11.tgz", - "integrity": "sha512-aNAk5JzLturWEUiuhAN73Jcbq96R7rTitAoXV54FYMatvihnpD2+6PUgU4ce3D/m5VDbw+F5CsyKSF176ptitQ==", + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-2.2.1.tgz", + "integrity": "sha512-V5nVw1PAOgfI3Lmeaj2Exmeg7fenjhRUgz1lPSezy1CuhPYbgQtbQj4jZfEAEMlaL+vupsvhjqCyjzob0yxsmQ==", "requires": { "quick-lru": "^5.1.1", "resolve-alpn": "^1.2.0" @@ -2003,25 +2343,23 @@ "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" }, - "indent-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", - "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==" - }, "inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-5.1.0.tgz", + "integrity": "sha512-5XHYaSyiqADb4RnZ1Bdad6cPp8Toise4TzEjcOYDHZkTCbKgiUl7WTUCpNWHuxmDt91wnsZBc9xinNzopv3JMQ==", + "requires": { + "get-east-asian-width": "^1.3.1" + } }, - "json-buffer": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", - "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==" + "is-stream": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-4.0.1.tgz", + "integrity": "sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A==" }, "jsonfile": { "version": "6.1.0", @@ -2038,223 +2376,134 @@ "integrity": "sha512-HjorDJFNhnM4SicvaUXac0X77NiskggxJdesG72+O5zBKpSqKFCrqmndKVqpu3pFqkla0St6uGk8Ju0sCurrmg==" }, "keyv": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.3.3.tgz", - "integrity": "sha512-AcysI17RvakTh8ir03+a3zJr5r0ovnAH/XTXei/4HIv3bL2K/jzvgivLK9UuI/JbU1aJjM3NSAnVvVVd3n+4DQ==", + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-5.6.0.tgz", + "integrity": "sha512-CYDD3SOtsHtyXeEORYRx2qBtpDJFjRTGXUtmNEMGyzYOKj1TE3tycdlho7kA1Ufx9OYWZzg52QFBGALTirzDSw==", "requires": { - "compress-brotli": "^1.3.8", - "json-buffer": "3.0.1" + "@keyv/serialize": "^1.1.1" } }, "listr2": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/listr2/-/listr2-5.0.2.tgz", - "integrity": "sha512-/yIYitiJgIkzVIKqQc+Dpcpwaj4PjeW/hSi7/xoGJ5mil7vQYedr5kKuEyLhANlnifCcumafnIR6azpb8loODw==", + "version": "10.2.2", + "resolved": "https://registry.npmjs.org/listr2/-/listr2-10.2.2.tgz", + "integrity": "sha512-JtNtbZj8q5BnDMR7trpwvwk3RIrANtIVzEUm8w7amp6xelLgyuq+4WZoTH913XaQAoH/cNdYhaNzBPA2U3xbDw==", "requires": { - "cli-truncate": "^2.1.0", - "colorette": "^2.0.19", - "log-update": "^4.0.0", - "p-map": "^4.0.0", - "rfdc": "^1.3.0", - "rxjs": "^7.5.6", - "through": "^2.3.8", - "wrap-ansi": "^7.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==" - }, - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "requires": { - "color-convert": "^2.0.1" - } - }, - "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" - }, - "string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - } - }, - "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "requires": { - "ansi-regex": "^5.0.1" - } - }, - "wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "requires": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - } - } + "cli-truncate": "^5.2.0", + "eventemitter3": "^5.0.4", + "log-update": "^6.1.0", + "rfdc": "^1.4.1", + "wrap-ansi": "^10.0.0" } }, "lodash-es": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz", - "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==" + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.18.1.tgz", + "integrity": "sha512-J8xewKD/Gk22OZbhpOVSwcs60zhd95ESDwezOFuA3/099925PdHJ7OFHNTGtajL3AlZkykD32HykiMo+BIBI8A==" + }, + "lodash.camelcase": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", + "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==" }, "log-update": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/log-update/-/log-update-4.0.0.tgz", - "integrity": "sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/log-update/-/log-update-6.1.0.tgz", + "integrity": "sha512-9ie8ItPR6tjY5uYJh8K/Zrv/RMZ5VOlOWvtZdEHYSTFKZfIBPQa9tOAEeAWhd+AnIneLJ22w5fjOYtoutpWq5w==", "requires": { - "ansi-escapes": "^4.3.0", - "cli-cursor": "^3.1.0", - "slice-ansi": "^4.0.0", - "wrap-ansi": "^6.2.0" + "ansi-escapes": "^7.0.0", + "cli-cursor": "^5.0.0", + "slice-ansi": "^7.1.0", + "strip-ansi": "^7.1.0", + "wrap-ansi": "^9.0.0" }, "dependencies": { - "ansi-escapes": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", - "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", - "requires": { - "type-fest": "^0.21.3" - } - }, "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==" - }, - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "requires": { - "color-convert": "^2.0.1" - } - }, - "cli-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", - "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", - "requires": { - "restore-cursor": "^3.1.0" - } + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==" }, "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" - }, - "restore-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", - "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", - "requires": { - "onetime": "^5.1.0", - "signal-exit": "^3.0.2" - } + "version": "10.6.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz", + "integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==" }, "slice-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", - "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-7.1.2.tgz", + "integrity": "sha512-iOBWFgUX7caIZiuutICxVgX1SdxwAVFFKwt1EvMYYec/NWO5meOJ6K5uQxhrYBdQJne4KxiqZc+KptFOWFSI9w==", "requires": { - "ansi-styles": "^4.0.0", - "astral-regex": "^2.0.0", - "is-fullwidth-code-point": "^3.0.0" + "ansi-styles": "^6.2.1", + "is-fullwidth-code-point": "^5.0.0" } }, "string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", + "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" } }, "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz", + "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", "requires": { - "ansi-regex": "^5.0.1" + "ansi-regex": "^6.2.2" } }, - "type-fest": { - "version": "0.21.3", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", - "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==" - }, "wrap-ansi": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", - "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.2.tgz", + "integrity": "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==", "requires": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" + "ansi-styles": "^6.2.1", + "string-width": "^7.0.0", + "strip-ansi": "^7.1.0" } } } }, + "long": { + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/long/-/long-5.2.4.tgz", + "integrity": "sha512-qtzLbJE8hq7VabR3mISmVGtoXP8KGc2Z/AT8OuqlYD7JTR3oqrgwdjnk07wpj1twXxYmgDXgoKVWUG/fReSzHg==" + }, "lowercase-keys": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-3.0.0.tgz", - "integrity": "sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ==" + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-4.0.1.tgz", + "integrity": "sha512-wI9Nui/L8VfADa/cr/7NQruaASk1k23/Uh1khQ02BCVYiiy8F4AhOGnQzJy3Fl/c44GnYSbZHv8g7EcG3kJ1Qg==" }, "luxon": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/luxon/-/luxon-3.0.1.tgz", - "integrity": "sha512-hF3kv0e5gwHQZKz4wtm4c+inDtyc7elkanAsBq+fundaCdUBNJB1dHEGUZIM6SfSBUlbVFduPwEtNjFK8wLtcw==" + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/luxon/-/luxon-3.7.2.tgz", + "integrity": "sha512-vtEhXh/gNjI9Yg1u4jX/0YVPMvxzHuGgCm6tC5kZyb08yjGWGnqAjGJvcXbqQR2P3MyMEFnRbpcdFS6PBcLqew==" }, - "mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==" + "mimic-function": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/mimic-function/-/mimic-function-5.0.1.tgz", + "integrity": "sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==" }, "mimic-response": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", - "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==" + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-4.0.0.tgz", + "integrity": "sha512-e5ISH9xMYU0DzrT+jl8q2ze9D6eWBto+I8CNpe+VI+K2J/F/k3PdkdTdz4wvGVH4NTpo+NRYTVIuMQEMMcsLqg==" }, "minipass": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.4.tgz", - "integrity": "sha512-I9WPbWHCGu8W+6k1ZiGpPu0GkoKBeorkfKNuAFBNS1HNFJvke82sxvI5bzcCNpWPorkOO5QQ+zomzzwRxejXiw==", - "requires": { - "yallist": "^4.0.0" - } + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==" }, "minizlib": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", - "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-3.1.0.tgz", + "integrity": "sha512-KZxYo1BUkWD2TVFLr0MQoM8vUUigWD3LlD83a/75BqC+4qE0Hb1Vo5v1FgcfaNXvfXzr+5EhQ6ing/CaBijTlw==", "requires": { - "minipass": "^3.0.0", - "yallist": "^4.0.0" + "minipass": "^7.1.2" } }, - "mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==" - }, "mkdirp-classic": { "version": "0.5.3", "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", @@ -2266,15 +2515,15 @@ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, "nan": { - "version": "2.16.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.16.0.tgz", - "integrity": "sha512-UdAqHyFngu7TfQKsCBgAA6pWDkT8MAO7d0jyOecVhN5354xbLqdn8mV9Tat9gepAupm0bt2DbeaSC8vS52MuFA==", + "version": "2.28.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.28.0.tgz", + "integrity": "sha512-fTsDz99OTq2sVePhGdp4qQhggZFtKr64ZNVyVajRKtMOkJxYekplBh577PiJB12v/D3s2E5cGtOI45LWp6rnLQ==", "optional": true }, "normalize-url": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", - "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==" + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-8.1.1.tgz", + "integrity": "sha512-JYc0DPlpGWB40kH5g07gGTrYuMqV653k3uBKY6uITPWds3M0ov3GaWGp9lbE3Bzngx8+XkfzgvASb9vk9JDFXQ==" }, "once": { "version": "1.4.0", @@ -2285,24 +2534,11 @@ } }, "onetime": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", - "requires": { - "mimic-fn": "^2.1.0" - } - }, - "p-cancelable": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-3.0.0.tgz", - "integrity": "sha512-mlVgR3PGuzlo0MmTdk4cXqXWlwQDLnONTAg6sm62XkMJEiRxN3GL3SffkYvqwonbkJBcrI7Uvv5Zh9yjvn2iUw==" - }, - "p-map": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", - "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-7.0.0.tgz", + "integrity": "sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==", "requires": { - "aggregate-error": "^3.0.0" + "mimic-function": "^5.0.0" } }, "pend": { @@ -2311,9 +2547,28 @@ "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==" }, "pretty-bytes": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-6.0.0.tgz", - "integrity": "sha512-6UqkYefdogmzqAZWzJ7laYeJnaXDy2/J+ZqiiMtS7t7OfpXWTlaeGMwX8U6EFvPV/YWWEKRkS8hKS4k60WHTOg==" + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-7.1.0.tgz", + "integrity": "sha512-nODzvTiYVRGRqAOvE84Vk5JDPyyxsVk0/fbA/bq7RqlnhksGpset09XTxbpvLTIjoaF7K8Z8DG8yHtKGTPSYRw==" + }, + "protobufjs": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.4.0.tgz", + "integrity": "sha512-mRUWCc3KUU4w1jU8sGxICXH/gNS94DvI1gxqDvBzhj1JpcsimQkYiOJfwsPUykUI5ZaspFbSgmBLER8IrQ3tqw==", + "requires": { + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/codegen": "^2.0.4", + "@protobufjs/eventemitter": "^1.1.0", + "@protobufjs/fetch": "^1.1.0", + "@protobufjs/float": "^1.0.2", + "@protobufjs/inquire": "^1.1.0", + "@protobufjs/path": "^1.1.2", + "@protobufjs/pool": "^1.1.0", + "@protobufjs/utf8": "^1.1.0", + "@types/node": ">=13.7.0", + "long": "^5.0.0" + } }, "pump": { "version": "3.0.0", @@ -2330,9 +2585,9 @@ "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==" }, "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", "requires": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", @@ -2350,33 +2605,34 @@ "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==" }, "responselike": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.1.tgz", - "integrity": "sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-4.0.2.tgz", + "integrity": "sha512-cGk8IbWEAnaCpdAt1BHzJ3Ahz5ewDJa0KseTsE3qIRMJ3C698W8psM7byCeWVpd/Ha7FUYzuRVzXoKoM6nRUbA==", "requires": { - "lowercase-keys": "^2.0.0" + "lowercase-keys": "^3.0.0" }, "dependencies": { "lowercase-keys": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", - "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==" + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-3.0.0.tgz", + "integrity": "sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ==" } } }, - "rfdc": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.3.0.tgz", - "integrity": "sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==" - }, - "rxjs": { - "version": "7.5.6", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.5.6.tgz", - "integrity": "sha512-dnyv2/YsXhnm461G+R/Pe5bWP41Nm6LBXEYWI6eiFP4fiwx6WRI/CD0zbdVAudd9xwLEF2IDcKXLHit0FYjUzw==", + "restore-cursor": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-5.1.0.tgz", + "integrity": "sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==", "requires": { - "tslib": "^2.1.0" + "onetime": "^7.0.0", + "signal-exit": "^4.1.0" } }, + "rfdc": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz", + "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==" + }, "safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", @@ -2388,28 +2644,17 @@ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, "signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==" }, "slice-ansi": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-3.0.0.tgz", - "integrity": "sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==", + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-8.0.0.tgz", + "integrity": "sha512-stxByr12oeeOyY2BlviTNQlYV5xOj47GirPr4yA1hE9JCtxfQN0+tVbkxwCtYDQWhEKWFHsEK48ORg5jrouCAg==", "requires": { - "ansi-styles": "^4.0.0", - "astral-regex": "^2.0.0", - "is-fullwidth-code-point": "^3.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "requires": { - "color-convert": "^2.0.1" - } - } + "ansi-styles": "^6.2.3", + "is-fullwidth-code-point": "^5.1.0" } }, "split-ca": { @@ -2418,14 +2663,14 @@ "integrity": "sha512-Q5thBSxp5t8WPTTJQS59LrGqOZqOsrhDGDVm8azCqIBjSBd7nd9o2PM+mDulQQkh8h//4U6hFZnc/mul8t5pWQ==" }, "ssh2": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/ssh2/-/ssh2-1.11.0.tgz", - "integrity": "sha512-nfg0wZWGSsfUe/IBJkXVll3PEZ//YH2guww+mP88gTpuSU4FtZN7zu9JoeTGOyCNx2dTDtT9fOpWwlzyj4uOOw==", + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/ssh2/-/ssh2-1.17.0.tgz", + "integrity": "sha512-wPldCk3asibAjQ/kziWQQt1Wh3PgDFpC0XpwclzKcdT1vql6KeYxf5LIt4nlFkUeR8WuphYMKqUA56X4rjbfgQ==", "requires": { - "asn1": "^0.2.4", + "asn1": "^0.2.6", "bcrypt-pbkdf": "^1.0.2", - "cpu-features": "~0.0.4", - "nan": "^2.16.0" + "cpu-features": "~0.0.10", + "nan": "^2.23.0" } }, "string_decoder": { @@ -2436,35 +2681,71 @@ "safe-buffer": "~5.2.0" } }, + "string-width": { + "version": "8.2.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-8.2.2.tgz", + "integrity": "sha512-GaPUh5gfdrYzqeVNZvUfT23vYYxXzKYidUcnMtJg/3rxRV63EFZy3k6xfKlmfeJD0176lnUV/Usr3XcwSvFzpg==", + "requires": { + "get-east-asian-width": "^1.5.0", + "strip-ansi": "^7.1.2" + }, + "dependencies": { + "ansi-regex": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==" + }, + "strip-ansi": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz", + "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", + "requires": { + "ansi-regex": "^6.2.2" + } + } + } + }, + "strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "requires": { + "ansi-regex": "^5.0.1" + } + }, + "tagged-tag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/tagged-tag/-/tagged-tag-1.0.0.tgz", + "integrity": "sha512-yEFYrVhod+hdNyx7g5Bnkkb0G6si8HJurOoOEgC8B/O0uXLHlaey/65KRv6cuWBNhBgHKAROVpc7QyYqE5gFng==" + }, "tar": { - "version": "6.1.11", - "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.11.tgz", - "integrity": "sha512-an/KZQzQUkZCkuoAA64hM92X0Urb6VpRhAFllDzz44U2mcD5scmT3zBc4VgVpkugF580+DQn8eAFSyoQt0tznA==", + "version": "7.5.19", + "resolved": "https://registry.npmjs.org/tar/-/tar-7.5.19.tgz", + "integrity": "sha512-4LeEWl96twnS2Q7Bz4MGqgazLqO+hJN63GZxXoIqh1T3VweYD997gbU1ItNsQafqqXTXd5WFyFdReLtwvRBNiw==", "requires": { - "chownr": "^2.0.0", - "fs-minipass": "^2.0.0", - "minipass": "^3.0.0", - "minizlib": "^2.1.1", - "mkdirp": "^1.0.3", - "yallist": "^4.0.0" + "@isaacs/fs-minipass": "^4.0.0", + "chownr": "^3.0.0", + "minipass": "^7.1.2", + "minizlib": "^3.1.0", + "yallist": "^5.0.0" }, "dependencies": { "chownr": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", - "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==" + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-3.0.0.tgz", + "integrity": "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==" } } }, "tar-fs": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.0.1.tgz", - "integrity": "sha512-6tzWDMeroL87uF/+lin46k+Q+46rAJ0SyPGz7OW7wTgblI273hsBqk2C1j0/xNadNLKDTUL9BukSjB7cwgmlPA==", + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.5.tgz", + "integrity": "sha512-OboTd8mmMhZDNPV+UjQcK9yKAatXu2aJ+r1w4im1Otd4M4fl2hwvdoXUxIYHFTHWK/3y3FarBP70v3vwmGlOxw==", "requires": { "chownr": "^1.1.1", "mkdirp-classic": "^0.5.2", "pump": "^3.0.0", - "tar-stream": "^2.0.0" + "tar-stream": "^2.1.4" } }, "tar-stream": { @@ -2477,44 +2758,26 @@ "fs-constants": "^1.0.0", "inherits": "^2.0.3", "readable-stream": "^3.1.1" - }, - "dependencies": { - "bl": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", - "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", - "requires": { - "buffer": "^5.5.0", - "inherits": "^2.0.4", - "readable-stream": "^3.4.0" - } - }, - "buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "requires": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" - } - } } }, - "through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==" - }, - "tslib": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", - "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==" - }, "tweetnacl": { "version": "0.14.5", "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==" }, + "type-fest": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-5.8.0.tgz", + "integrity": "sha512-YGYEVz3Fm5iy/AybuA0oyNFq7H4CgQNfRp/qfe8nurE1kuCeNm3/vfm9X4Mtl+qLyaKJUh5xrFZwogr41SMjYA==", + "requires": { + "tagged-tag": "^1.0.0" + } + }, + "uint8array-extras": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/uint8array-extras/-/uint8array-extras-1.5.0.tgz", + "integrity": "sha512-rvKSBiC5zqCCiDZ9kAOszZcDvdAHwwIKJG33Ykj43OKcWsnmcBRL09YTU4nOeHZ8Y2a7l1MgTd08SBe9A8Qj6A==" + }, "universalify": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", @@ -2525,6 +2788,31 @@ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" }, + "wrap-ansi": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-10.0.0.tgz", + "integrity": "sha512-SGcvg80f0wUy2/fXES19feHMz8E0JoXv2uNgHOu4Dgi2OrCy1lqwFYEJz1BLbDI0exjPMe/ZdzZ/YpGECBG/aQ==", + "requires": { + "ansi-styles": "^6.2.3", + "string-width": "^8.2.0", + "strip-ansi": "^7.1.2" + }, + "dependencies": { + "ansi-regex": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==" + }, + "strip-ansi": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz", + "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", + "requires": { + "ansi-regex": "^6.2.2" + } + } + } + }, "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", @@ -2536,58 +2824,57 @@ "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==" }, "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-5.0.0.tgz", + "integrity": "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==" }, "yargs": { - "version": "17.5.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.5.1.tgz", - "integrity": "sha512-t6YAJcxDkNX7NFYiVtKvWUz8l+PaKTLiL63mJYWR2GnHq2gjEWISzsLp9wg3aY36dY1j+gfIEL3pIF+XlJJfbA==", + "version": "18.0.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-18.0.0.tgz", + "integrity": "sha512-4UEqdc2RYGHZc7Doyqkrqiln3p9X2DZVxaGbwhn2pi7MrRagKaOcIKe8L3OxYcbhXLgLFUS3zAYuQjKBQgmuNg==", "requires": { - "cliui": "^7.0.2", + "cliui": "^9.0.1", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.3", + "string-width": "^7.2.0", "y18n": "^5.0.5", - "yargs-parser": "^21.0.0" + "yargs-parser": "^22.0.0" }, "dependencies": { "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==" + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==" }, "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + "version": "10.6.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz", + "integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==" }, "string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", + "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" } }, "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz", + "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", "requires": { - "ansi-regex": "^5.0.1" + "ansi-regex": "^6.2.2" } } } }, "yargs-parser": { - "version": "21.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", - "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==" + "version": "22.0.0", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-22.0.0.tgz", + "integrity": "sha512-rwu/ClNdSMpkSrUb+d6BRsSkLUq1fmfsY6TOpYzTwvwkg1/NRG85KBy3kq++A8LKQwX6lsu+aWad+2khvuXrqw==" }, "yauzl": { "version": "2.10.0", diff --git a/dev/diff/package.json b/dev/diff/package.json index 43d37545f92..6400491ffe0 100644 --- a/dev/diff/package.json +++ b/dev/diff/package.json @@ -2,21 +2,21 @@ "name": "diff", "type": "module", "dependencies": { - "chalk": "^5.0.1", - "dockerode": "^3.3.3", - "enquirer": "^2.3.6", - "extract-zip": "^2.0.1", - "fs-extra": "^10.1.0", - "got": "^12.3.1", - "keypress": "^0.2.1", - "listr2": "^5.0.2", - "lodash-es": "^4.17.21", - "luxon": "^3.0.1", - "pretty-bytes": "^6.0.0", - "tar": "^6.1.11", - "yargs": "^17.5.1" + "chalk": "5.6.2", + "dockerode": "5.0.1", + "enquirer": "2.4.1", + "extract-zip": "2.0.1", + "fs-extra": "11.3.6", + "got": "15.1.0", + "keypress": "0.2.1", + "listr2": "10.2.2", + "lodash-es": "4.18.1", + "luxon": "3.7.2", + "pretty-bytes": "7.1.0", + "tar": "7.5.19", + "yargs": "18.0.0" }, "engines": { - "node": ">=16" + "node": ">=26" } } diff --git a/dev/diff/prepare.sh b/dev/diff/prepare.sh index 1549155caa7..b80e87544d9 100644 --- a/dev/diff/prepare.sh +++ b/dev/diff/prepare.sh @@ -4,11 +4,15 @@ echo "Fixing permissions..." chmod -R 777 ./ echo "Ensure all requirements.txt packages are installed..." pip --disable-pip-version-check --no-cache-dir install -r requirements.txt -echo "Compiling native node packages..." -yarn rebuild +echo "Installing node packages..." +npm install echo "Building static assets..." -yarn build -yarn legacy:build +npm run build +npm run legacy:build echo "Creating data directories..." chmod +x ./docker/scripts/app-create-dirs.sh ./docker/scripts/app-create-dirs.sh + +./ietf/manage.py check +./ietf/manage.py migrate --fake-initial + diff --git a/dev/diff/settings_local.py b/dev/diff/settings_local.py index 902fc54d14d..c255cac23dc 100644 --- a/dev/diff/settings_local.py +++ b/dev/diff/settings_local.py @@ -1,35 +1,25 @@ # Copyright The IETF Trust 2007-2019, All Rights Reserved # -*- coding: utf-8 -*- -from ietf.settings import * # pyflakes:ignore +from ietf.settings import * # pyflakes:ignore ALLOWED_HOSTS = ['*'] DATABASES = { 'default': { 'HOST': '__DBHOST__', - 'PORT': 3306, - 'NAME': 'ietf_utf8', - 'ENGINE': 'django.db.backends.mysql', + 'PORT': 5432, + 'NAME': 'datatracker', + 'ENGINE': 'django.db.backends.postgresql', 'USER': 'django', 'PASSWORD': 'RkTkDPFnKpko', - 'OPTIONS': { - 'sql_mode': 'STRICT_TRANS_TABLES', - 'init_command': 'SET storage_engine=InnoDB; SET names "utf8"', - }, }, } -DATABASE_TEST_OPTIONS = { - 'init_command': 'SET storage_engine=InnoDB', -} IDSUBMIT_IDNITS_BINARY = "/usr/local/bin/idnits" IDSUBMIT_REPOSITORY_PATH = "test/id/" IDSUBMIT_STAGING_PATH = "test/staging/" -INTERNET_DRAFT_ARCHIVE_DIR = "test/archive/" -INTERNET_ALL_DRAFTS_ARCHIVE_DIR = "test/archive/" -RFC_PATH = "test/rfc/" AGENDA_PATH = '/assets/www6s/proceedings/' MEETINGHOST_LOGO_PATH = AGENDA_PATH @@ -47,7 +37,6 @@ SUBMIT_YANG_CATALOG_MODEL_DIR = '/assets/ietf-ftp/yang/catalogmod/' SUBMIT_YANG_DRAFT_MODEL_DIR = '/assets/ietf-ftp/yang/draftmod/' -SUBMIT_YANG_INVAL_MODEL_DIR = '/assets/ietf-ftp/yang/invalmod/' SUBMIT_YANG_IANA_MODEL_DIR = '/assets/ietf-ftp/yang/ianamod/' SUBMIT_YANG_RFC_MODEL_DIR = '/assets/ietf-ftp/yang/rfcmod/' @@ -67,8 +56,11 @@ BOFREQ_PATH = '/assets/ietf-ftp/bofreq/' CONFLICT_REVIEW_PATH = '/assets/ietf-ftp/conflict-reviews/' STATUS_CHANGE_PATH = '/assets/ietf-ftp/status-changes/' -INTERNET_DRAFT_ARCHIVE_DIR = '/assets/ietf-ftp/internet-drafts/' +INTERNET_DRAFT_ARCHIVE_DIR = '/assets/collection/draft-archive' INTERNET_ALL_DRAFTS_ARCHIVE_DIR = '/assets/ietf-ftp/internet-drafts/' +BIBXML_BASE_PATH = '/assets/ietfdata/derived/bibxml' +FTP_DIR = '/assets/ftp' +NFS_METRICS_TMP_DIR = '/assets/tmp' NOMCOM_PUBLIC_KEYS_DIR = 'data/nomcom_keys/public_keys/' SLIDE_STAGING_PATH = 'test/staging/' diff --git a/dev/k8s-get-deploy-name/.gitignore b/dev/k8s-get-deploy-name/.gitignore new file mode 100644 index 00000000000..07e6e472cc7 --- /dev/null +++ b/dev/k8s-get-deploy-name/.gitignore @@ -0,0 +1 @@ +/node_modules diff --git a/dev/k8s-get-deploy-name/.npmrc b/dev/k8s-get-deploy-name/.npmrc new file mode 100644 index 00000000000..fcbbb678280 --- /dev/null +++ b/dev/k8s-get-deploy-name/.npmrc @@ -0,0 +1,5 @@ +audit = false +fund = false +save-exact = true +save-prefix = "" +update-notifier = false diff --git a/dev/k8s-get-deploy-name/README.md b/dev/k8s-get-deploy-name/README.md new file mode 100644 index 00000000000..a6605e4dd2c --- /dev/null +++ b/dev/k8s-get-deploy-name/README.md @@ -0,0 +1,16 @@ +# Datatracker Get Deploy Name + +This tool process and slugify a git branch into an appropriate subdomain name. + +## Usage + +1. From the `dev/k8s-get-deploy-name` directory, install the dependencies: +```sh +npm install +``` +2. Run the command: (replacing the `branch` argument) +```sh +node /cli.js --branch feat/fooBar-123 +``` + +The subdomain name will be output. It can then be used in a workflow as a namespace name and subdomain value. diff --git a/dev/k8s-get-deploy-name/cli.js b/dev/k8s-get-deploy-name/cli.js new file mode 100644 index 00000000000..b6c3b5119ef --- /dev/null +++ b/dev/k8s-get-deploy-name/cli.js @@ -0,0 +1,22 @@ +#!/usr/bin/env node + +import yargs from 'yargs/yargs' +import { hideBin } from 'yargs/helpers' +import slugify from 'slugify' + +const argv = yargs(hideBin(process.argv)).argv + +let branch = argv.branch +if (!branch) { + throw new Error('Missing --branch argument!') +} +if (branch.indexOf('/') >= 0) { + branch = branch.split('/').slice(1).join('-') +} +branch = slugify(branch, { lower: true, strict: true }) +if (branch.length < 1) { + throw new Error('Branch name is empty!') +} +process.stdout.write(`dt-${branch}`) + +process.exit(0) diff --git a/dev/k8s-get-deploy-name/package-lock.json b/dev/k8s-get-deploy-name/package-lock.json new file mode 100644 index 00000000000..3a6054988e4 --- /dev/null +++ b/dev/k8s-get-deploy-name/package-lock.json @@ -0,0 +1,276 @@ +{ + "name": "k8s-get-deploy-name", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "name": "k8s-get-deploy-name", + "dependencies": { + "slugify": "1.6.9", + "yargs": "18.0.0" + } + }, + "node_modules/ansi-regex": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/ansi-styles": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/cliui": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-9.0.1.tgz", + "integrity": "sha512-k7ndgKhwoQveBL+/1tqGJYNz097I7WOvwbmmU2AR5+magtbjPWQTS1C5vzGkBC8Ym8UWRzfKUzUUqFLypY4Q+w==", + "license": "ISC", + "dependencies": { + "string-width": "^7.2.0", + "strip-ansi": "^7.1.0", + "wrap-ansi": "^9.0.0" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/emoji-regex": { + "version": "10.6.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz", + "integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==", + "license": "MIT" + }, + "node_modules/escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "engines": { + "node": ">=6" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-east-asian-width": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.6.0.tgz", + "integrity": "sha512-QRbvDIbx6YklUe6RxeTeleMR0yv3cYH6PsPZHcnVn7xv7zO1BHN8r0XETu8n6Ye3Q+ahtSarc3WgtNWmehIBfA==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/slugify": { + "version": "1.6.9", + "resolved": "https://registry.npmjs.org/slugify/-/slugify-1.6.9.tgz", + "integrity": "sha512-vZ7rfeehZui7wQs438JXBckYLkIIdfHOXsaVEUMyS5fHo1483l1bMdo0EDSWYclY0yZKFOipDy4KHuKs6ssvdg==", + "license": "MIT", + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/string-width": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", + "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", + "license": "MIT", + "dependencies": { + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/strip-ansi": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz", + "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.2.2" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.2.tgz", + "integrity": "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.2.1", + "string-width": "^7.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs": { + "version": "18.0.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-18.0.0.tgz", + "integrity": "sha512-4UEqdc2RYGHZc7Doyqkrqiln3p9X2DZVxaGbwhn2pi7MrRagKaOcIKe8L3OxYcbhXLgLFUS3zAYuQjKBQgmuNg==", + "license": "MIT", + "dependencies": { + "cliui": "^9.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "string-width": "^7.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^22.0.0" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=23" + } + }, + "node_modules/yargs-parser": { + "version": "22.0.0", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-22.0.0.tgz", + "integrity": "sha512-rwu/ClNdSMpkSrUb+d6BRsSkLUq1fmfsY6TOpYzTwvwkg1/NRG85KBy3kq++A8LKQwX6lsu+aWad+2khvuXrqw==", + "license": "ISC", + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=23" + } + } + }, + "dependencies": { + "ansi-regex": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==" + }, + "ansi-styles": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==" + }, + "cliui": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-9.0.1.tgz", + "integrity": "sha512-k7ndgKhwoQveBL+/1tqGJYNz097I7WOvwbmmU2AR5+magtbjPWQTS1C5vzGkBC8Ym8UWRzfKUzUUqFLypY4Q+w==", + "requires": { + "string-width": "^7.2.0", + "strip-ansi": "^7.1.0", + "wrap-ansi": "^9.0.0" + } + }, + "emoji-regex": { + "version": "10.6.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz", + "integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==" + }, + "escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==" + }, + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==" + }, + "get-east-asian-width": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.6.0.tgz", + "integrity": "sha512-QRbvDIbx6YklUe6RxeTeleMR0yv3cYH6PsPZHcnVn7xv7zO1BHN8r0XETu8n6Ye3Q+ahtSarc3WgtNWmehIBfA==" + }, + "slugify": { + "version": "1.6.9", + "resolved": "https://registry.npmjs.org/slugify/-/slugify-1.6.9.tgz", + "integrity": "sha512-vZ7rfeehZui7wQs438JXBckYLkIIdfHOXsaVEUMyS5fHo1483l1bMdo0EDSWYclY0yZKFOipDy4KHuKs6ssvdg==" + }, + "string-width": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", + "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", + "requires": { + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" + } + }, + "strip-ansi": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz", + "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", + "requires": { + "ansi-regex": "^6.2.2" + } + }, + "wrap-ansi": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.2.tgz", + "integrity": "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==", + "requires": { + "ansi-styles": "^6.2.1", + "string-width": "^7.0.0", + "strip-ansi": "^7.1.0" + } + }, + "y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==" + }, + "yargs": { + "version": "18.0.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-18.0.0.tgz", + "integrity": "sha512-4UEqdc2RYGHZc7Doyqkrqiln3p9X2DZVxaGbwhn2pi7MrRagKaOcIKe8L3OxYcbhXLgLFUS3zAYuQjKBQgmuNg==", + "requires": { + "cliui": "^9.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "string-width": "^7.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^22.0.0" + } + }, + "yargs-parser": { + "version": "22.0.0", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-22.0.0.tgz", + "integrity": "sha512-rwu/ClNdSMpkSrUb+d6BRsSkLUq1fmfsY6TOpYzTwvwkg1/NRG85KBy3kq++A8LKQwX6lsu+aWad+2khvuXrqw==" + } + } +} diff --git a/dev/k8s-get-deploy-name/package.json b/dev/k8s-get-deploy-name/package.json new file mode 100644 index 00000000000..597820bc077 --- /dev/null +++ b/dev/k8s-get-deploy-name/package.json @@ -0,0 +1,8 @@ +{ + "name": "k8s-get-deploy-name", + "type": "module", + "dependencies": { + "slugify": "1.6.9", + "yargs": "18.0.0" + } +} diff --git a/dev/legacy/add-old-drafts-from-archive.py b/dev/legacy/add-old-drafts-from-archive.py new file mode 100644 index 00000000000..f09c3b4558d --- /dev/null +++ b/dev/legacy/add-old-drafts-from-archive.py @@ -0,0 +1,157 @@ +#!/usr/bin/env python +import sys + +print("This is only here as documention - please read the file") +sys.exit(0) + +# #!/usr/bin/env python +# # Copyright The IETF Trust 2017-2019, All Rights Reserved + +# import datetime +# import os +# import sys +# from pathlib import Path +# from contextlib import closing + +# os.environ["DJANGO_SETTINGS_MODULE"] = "ietf.settings" + +# import django +# django.setup() + +# from django.conf import settings +# from django.core.validators import validate_email, ValidationError +# from ietf.utils.draft import PlaintextDraft +# from ietf.submit.utils import update_authors +# from ietf.utils.timezone import date_today + +# import debug # pyflakes:ignore + +# from ietf.doc.models import Document, NewRevisionDocEvent, DocEvent, State +# from ietf.person.models import Person + +# system = Person.objects.get(name="(System)") +# expired = State.objects.get(type='draft',slug='expired') + +# names = set() +# print 'collecting draft names ...' +# versions = 0 +# for p in Path(settings.INTERNET_DRAFT_PATH).glob('draft*.txt'): +# n = str(p).split('/')[-1].split('-') +# if n[-1][:2].isdigit(): +# name = '-'.join(n[:-1]) +# if '--' in name or '.txt' in name or '[' in name or '=' in name or '&' in name: +# continue +# if name.startswith('draft-draft-'): +# continue +# if name == 'draft-ietf-trade-iotp-v1_0-dsig': +# continue +# if len(n[-1]) != 6: +# continue +# if name.startswith('draft-mlee-'): +# continue +# names.add('-'.join(n[:-1])) + +# count=0 +# print 'iterating through names ...' +# for name in sorted(names): +# if not Document.objects.filter(name=name).exists(): +# paths = list(Path(settings.INTERNET_DRAFT_PATH).glob('%s-??.txt'%name)) +# paths.sort() +# doc = None +# for p in paths: +# n = str(p).split('/')[-1].split('-') +# rev = n[-1][:2] +# with open(str(p)) as txt_file: +# raw = txt_file.read() +# try: +# text = raw.decode('utf8') +# except UnicodeDecodeError: +# text = raw.decode('latin1') +# try: +# draft = PlaintextDraft(text, txt_file.name, name_from_source=True) +# except Exception as e: +# print name, rev, "Can't parse", p,":",e +# continue +# if draft.errors and draft.errors.keys()!=['draftname',]: +# print "Errors - could not process", name, rev, datetime.datetime.fromtimestamp(p.stat().st_mtime, datetime.timezone.utc), draft.errors, draft.get_title().encode('utf8') +# else: +# time = datetime.datetime.fromtimestamp(p.stat().st_mtime, datetime.timezone.utc) +# if not doc: +# doc = Document.objects.create(name=name, +# time=time, +# type_id='draft', +# title=draft.get_title(), +# abstract=draft.get_abstract(), +# rev = rev, +# pages=draft.get_pagecount(), +# words=draft.get_wordcount(), +# expires=time+datetime.timedelta(settings.INTERNET_DRAFT_DAYS_TO_EXPIRE), +# ) +# DocAlias.objects.create(name=doc.name).docs.add(doc) +# doc.states.add(expired) +# # update authors +# authors = [] +# for author in draft.get_author_list(): +# full_name, first_name, middle_initial, last_name, name_suffix, email, country, company = author + +# author_name = full_name.replace("\n", "").replace("\r", "").replace("<", "").replace(">", "").strip() + +# if email: +# try: +# validate_email(email) +# except ValidationError: +# email = "" + +# def turn_into_unicode(s): +# if s is None: +# return u"" + +# if isinstance(s, unicode): +# return s +# else: +# try: +# return s.decode("utf-8") +# except UnicodeDecodeError: +# try: +# return s.decode("latin-1") +# except UnicodeDecodeError: +# return "" + +# author_name = turn_into_unicode(author_name) +# email = turn_into_unicode(email) +# company = turn_into_unicode(company) + +# authors.append({ +# "name": author_name, +# "email": email, +# "affiliation": company, +# "country": country +# }) +# dummysubmission=type('', (), {})() #https://stackoverflow.com/questions/19476816/creating-an-empty-object-in-python +# dummysubmission.authors = authors +# update_authors(doc,dummysubmission) + +# # add a docevent with words explaining where this came from +# events = [] +# e = NewRevisionDocEvent.objects.create( +# type="new_revision", +# doc=doc, +# rev=rev, +# by=system, +# desc="New version available: %s-%s.txt" % (doc.name, doc.rev), +# time=time, +# ) +# events.append(e) +# e = DocEvent.objects.create( +# type="comment", +# doc = doc, +# rev = rev, +# by = system, +# desc = "Revision added from id-archive on %s by %s"%(date_today(),sys.argv[0]), +# time=time, +# ) +# events.append(e) +# doc.time = time +# doc.rev = rev +# doc.save_with_history(events) +# print "Added",name, rev diff --git a/dev/legacy/notes/notes.html b/dev/legacy/notes/notes.html index 85980a5b1bb..cb10a18689d 100644 --- a/dev/legacy/notes/notes.html +++ b/dev/legacy/notes/notes.html @@ -355,7 +355,7 @@

Introduction

in one place.

With my recent investigations of code analysis tools, I thought it might be a good idea to start collecting these in one place for the project.

-
+
Henrik <henrik@levkowetz.com>, 23 Mar 2014
@@ -398,8 +398,9 @@

PyChecker

do the right thing, but once it was made to run on the datatracker code, and ignore the django code, it didn't report anything that PyFlakes hadn't already caught.

-
-Henrik <henrik@levkowetz.com>, 23 Mar 2014
+
+ Henrik <henrik@levkowetz.com>, 23 Mar 2014 +
diff --git a/dev/legacy/recalculate-rfc-authors-snapshot b/dev/legacy/recalculate-rfc-authors-snapshot new file mode 100644 index 00000000000..cbe7a7a2f3b --- /dev/null +++ b/dev/legacy/recalculate-rfc-authors-snapshot @@ -0,0 +1,8346 @@ +#!/bin/sh + +echo "This is only here as documentation. Please read the file" +exit + +# #!/usr/bin/env python + +# """DANGER, WILL ROBINSON + +# This code was used in the construction of person migrations 0016 through 0019 +# and doc migration 0029 The original intent was to provide a utility that could +# be run periodically, but the need for manual inspection of the results was too +# great. It is here as a _starting point_ for future exploration of updating rfc +# documentauthor sets. Be careful to check that assumptions haven't changed in +# the interim. + +# """ + +# import os, sys +# import django +# import argparse +# from collections import namedtuple +# import subprocess +# from tempfile import mkstemp + +# basedir = os.path.abspath(os.path.join(os.path.dirname(os.path.abspath(__file__)), '../..')) +# sys.path.insert(0, basedir) +# os.environ.setdefault("DJANGO_SETTINGS_MODULE", "ietf.settings") + +# django.setup() + +# from ietf.person.models import Email, Person +# from ietf.doc.models import Document +# from ietf import settings + +# import debug + +# # This is a snapshot dump from the RFC Editor in late April 2017 +# rfced_data = """RFC1 || S. Crocker || +# RFC2 || B. Duvall || +# RFC3 || S.D. Crocker || +# RFC4 || E.B. Shapiro || +# RFC5 || J. Rulifson || +# RFC6 || S.D. Crocker || +# RFC7 || G. Deloche || +# RFC8 || G. Deloche || +# RFC9 || G. Deloche || +# RFC10 || S.D. Crocker || +# RFC11 || G. Deloche || +# RFC12 || M. Wingfield || +# RFC13 || V. Cerf || +# RFC14 || || +# RFC15 || C.S. Carr || +# RFC16 || S. Crocker || +# RFC17 || J.E. Kreznar || +# RFC18 || V. Cerf || +# RFC19 || J.E. Kreznar || +# RFC20 || V.G. Cerf || +# RFC21 || V.G. Cerf || +# RFC22 || V.G. Cerf || +# RFC23 || G. Gregg || +# RFC24 || S.D. Crocker || +# RFC25 || S.D. Crocker || +# RFC26 || || +# RFC27 || S.D. Crocker || +# RFC28 || W.K. English || +# RFC29 || R.E. Kahn || +# RFC30 || S.D. Crocker || +# RFC31 || D. Bobrow, W.R. Sutherland || +# RFC32 || J. Cole || +# RFC33 || S.D. Crocker || +# RFC34 || W.K. English || +# RFC35 || S.D. Crocker || +# RFC36 || S.D. Crocker || +# RFC37 || S.D. Crocker || +# RFC38 || S.M. Wolfe || +# RFC39 || E. Harslem, J.F. Heafner || +# RFC40 || E. Harslem, J.F. Heafner || +# RFC41 || J.T. Melvin || +# RFC42 || E. Ancona || +# RFC43 || A.G. Nemeth || +# RFC44 || A. Shoshani, R. Long, A. Landsberg || +# RFC45 || J. Postel, S.D. Crocker || +# RFC46 || E. Meyer || +# RFC47 || J. Postel, S. Crocker || +# RFC48 || J. Postel, S.D. Crocker || +# RFC49 || E. Meyer || +# RFC50 || E. Harslen, J. Heafner || +# RFC51 || M. Elie || +# RFC52 || J. Postel, S.D. Crocker || +# RFC53 || S.D. Crocker || +# RFC54 || S.D. Crocker, J. Postel, J. Newkirk, M. Kraley || +# RFC55 || J. Newkirk, M. Kraley, J. Postel, S.D. Crocker || +# RFC56 || E. Belove, D. Black, R. Flegal, L.G. Farquar || +# RFC57 || M. Kraley, J. Newkirk || +# RFC58 || T.P. Skinner || +# RFC59 || E. Meyer || +# RFC60 || R. Kalin || +# RFC61 || D.C. Walden || +# RFC62 || D.C. Walden || +# RFC63 || V.G. Cerf || +# RFC64 || M. Elie || +# RFC65 || D.C. Walden || +# RFC66 || S.D. Crocker || +# RFC67 || W.R. Crowther || +# RFC68 || M. Elie || +# RFC69 || A.K. Bhushan || +# RFC70 || S.D. Crocker || +# RFC71 || T. Schipper || +# RFC72 || R.D. Bressler || +# RFC73 || S.D. Crocker || +# RFC74 || J.E. White || +# RFC75 || S.D. Crocker || +# RFC76 || J. Bouknight, J. Madden, G.R. Grossman || +# RFC77 || J. Postel || +# RFC78 || E. Harslem, J.F. Heafner, J.E. White || +# RFC79 || E. Meyer || +# RFC80 || E. Harslem, J.F. Heafner || +# RFC81 || J. Bouknight || +# RFC82 || E. Meyer || +# RFC83 || R.H. Anderson, E. Harslem, J.F. Heafner || +# RFC84 || J.B. North || +# RFC85 || S.D. Crocker || +# RFC86 || S.D. Crocker || +# RFC87 || A. Vezza || +# RFC88 || R.T. Braden, S.M. Wolfe || +# RFC89 || R.M. Metcalfe || +# RFC90 || R.T. Braden || +# RFC91 || G.H. Mealy || +# RFC92 || || +# RFC93 || A.M. McKenzie || +# RFC94 || E. Harslem, J.F. Heafner || +# RFC95 || S. Crocker || +# RFC96 || R.W. Watson || +# RFC97 || J.T. Melvin, R.W. Watson || +# RFC98 || E. Meyer, T. Skinner || +# RFC99 || P.M. Karp || +# RFC100 || P.M. Karp || +# RFC101 || R.W. Watson || +# RFC102 || S.D. Crocker || +# RFC103 || R.B. Kalin || +# RFC104 || J.B. Postel, S.D. Crocker || +# RFC105 || J.E. White || +# RFC106 || T.C. O'Sullivan || +# RFC107 || R.D. Bressler, S.D. Crocker, W.R. Crowther, G.R. Grossman, R.S. Tomlinson, J.E. White || +# RFC108 || R.W. Watson || +# RFC109 || J. Winett || +# RFC110 || J. Winett || +# RFC111 || S.D. Crocker || +# RFC112 || T.C. O'Sullivan || +# RFC113 || E. Harslem, J.F. Heafner, J.E. White || +# RFC114 || A.K. Bhushan || +# RFC115 || R.W. Watson, J.B. North || +# RFC116 || S.D. Crocker || +# RFC117 || J. Wong || +# RFC118 || R.W. Watson || +# RFC119 || M. Krilanovich || +# RFC120 || M. Krilanovich || +# RFC121 || M. Krilanovich || +# RFC122 || J.E. White || +# RFC123 || S.D. Crocker || +# RFC124 || J.T. Melvin || +# RFC125 || J. McConnell || +# RFC126 || J. McConnell || +# RFC127 || J. Postel || +# RFC128 || J. Postel || +# RFC129 || E. Harslem, J. Heafner, E. Meyer || +# RFC130 || J.F. Heafner || +# RFC131 || E. Harslem, J.F. Heafner || +# RFC132 || J.E. White || +# RFC133 || R.L. Sunberg || +# RFC134 || A. Vezza || +# RFC135 || W. Hathaway || +# RFC136 || R.E. Kahn || +# RFC137 || T.C. O'Sullivan || +# RFC138 || R.H. Anderson, V.G. Cerf, E. Harslem, J.F. Heafner, J. Madden, R.M. Metcalfe, A. Shoshani, J.E. White, D.C.M. Wood || +# RFC139 || T.C. O'Sullivan || +# RFC140 || S.D. Crocker || +# RFC141 || E. Harslem, J.F. Heafner || +# RFC142 || C. Kline, J. Wong || +# RFC143 || W. Naylor, J. Wong, C. Kline, J. Postel || +# RFC144 || A. Shoshani || +# RFC145 || J. Postel || +# RFC146 || P.M. Karp, D.B. McKay, D.C.M. Wood || +# RFC147 || J.M. Winett || +# RFC148 || A.K. Bhushan || +# RFC149 || S.D. Crocker || +# RFC150 || R.B. Kalin || +# RFC151 || A. Shoshani || +# RFC152 || M. Wilber || +# RFC153 || J.T. Melvin, R.W. Watson || +# RFC154 || S.D. Crocker || +# RFC155 || J.B. North || +# RFC156 || J. Bouknight || +# RFC157 || V.G. Cerf || +# RFC158 || T.C. O'Sullivan || +# RFC159 || || +# RFC160 || Network Information Center. Stanford Research Institute || +# RFC161 || A. Shoshani || +# RFC162 || M. Kampe || +# RFC163 || V.G. Cerf || +# RFC164 || J.F. Heafner || +# RFC165 || J. Postel || +# RFC166 || R.H. Anderson, V.G. Cerf, E. Harslem, J.F. Heafner, J. Madden, R.M. Metcalfe, A. Shoshani, J.E. White, D.C.M. Wood || +# RFC167 || A.K. Bhushan, R.M. Metcalfe, J.M. Winett || +# RFC168 || J.B. North || +# RFC169 || S.D. Crocker || +# RFC170 || Network Information Center. Stanford Research Institute || +# RFC171 || A. Bhushan, B. Braden, W. Crowther, E. Harslem, J. Heafner, A. McKenize, J. Melvin, B. Sundberg, D. Watson, J. White || +# RFC172 || A. Bhushan, B. Braden, W. Crowther, E. Harslem, J. Heafner, A. McKenzie, J. Melvin, B. Sundberg, D. Watson, J. White || +# RFC173 || P.M. Karp, D.B. McKay || +# RFC174 || J. Postel, V.G. Cerf || +# RFC175 || E. Harslem, J.F. Heafner || +# RFC176 || A.K. Bhushan, R. Kanodia, R.M. Metcalfe, J. Postel || +# RFC177 || J. McConnell || +# RFC178 || I.W. Cotton || +# RFC179 || A.M. McKenzie || +# RFC180 || A.M. McKenzie || +# RFC181 || J. McConnell || +# RFC182 || J.B. North || +# RFC183 || J.M. Winett || +# RFC184 || K.C. Kelley || +# RFC185 || J.B. North || +# RFC186 || J.C. Michener || +# RFC187 || D.B. McKay, D.P. Karp || +# RFC188 || P.M. Karp, D.B. McKay || +# RFC189 || R.T. Braden || +# RFC190 || L.P. Deutsch || +# RFC191 || C.H. Irby || +# RFC192 || R.W. Watson || +# RFC193 || E. Harslem, J.F. Heafner || +# RFC194 || V. Cerf, E. Harslem, J. Heafner, B. Metcalfe, J. White || +# RFC195 || G.H. Mealy || +# RFC196 || R.W. Watson || +# RFC197 || A. Shoshani, E. Harslem || +# RFC198 || J.F. Heafner || +# RFC199 || T. Williams || +# RFC200 || J.B. North || +# RFC201 || || +# RFC202 || S.M. Wolfe, J. Postel || +# RFC203 || R.B. Kalin || +# RFC204 || J. Postel || +# RFC205 || R.T. Braden || +# RFC206 || J. White || +# RFC207 || A. Vezza || +# RFC208 || A.M. McKenzie || +# RFC209 || B. Cosell || +# RFC210 || W. Conrad || +# RFC211 || J.B. North || +# RFC212 || Information Sciences Institute University of Southern California || +# RFC213 || B. Cosell || +# RFC214 || E. Harslem || +# RFC215 || A.M. McKenzie || +# RFC216 || J.E. White || +# RFC217 || J.E. White || +# RFC218 || B. Cosell || +# RFC219 || R. Winter || +# RFC220 || || +# RFC221 || R.W. Watson || +# RFC222 || R.M. Metcalfe || +# RFC223 || J.T. Melvin, R.W. Watson || +# RFC224 || A.M. McKenzie || +# RFC225 || E. Harslem, R. Stoughton || +# RFC226 || P.M. Karp || +# RFC227 || J.F. Heafner, E. Harslem || +# RFC228 || D.C. Walden || +# RFC229 || J. Postel || +# RFC230 || T. Pyke || +# RFC231 || J.F. Heafner, E. Harslem || +# RFC232 || A. Vezza || +# RFC233 || A. Bhushan, R. Metcalfe || +# RFC234 || A. Vezza || +# RFC235 || E. Westheimer || +# RFC236 || J. Postel || +# RFC237 || R.W. Watson || +# RFC238 || R.T. Braden || +# RFC239 || R.T. Braden || +# RFC240 || A.M. McKenzie || +# RFC241 || A.M. McKenzie || +# RFC242 || L. Haibt, A.P. Mullery || +# RFC243 || A.P. Mullery || +# RFC244 || || +# RFC245 || C. Falls || +# RFC246 || A. Vezza || +# RFC247 || P.M. Karp || +# RFC248 || || +# RFC249 || R.F. Borelli || +# RFC250 || H. Brodie || +# RFC251 || D. Stern || +# RFC252 || E. Westheimer || +# RFC253 || J.A. Moorer || +# RFC254 || A. Bhushan || +# RFC255 || E. Westheimer || +# RFC256 || B. Cosell || +# RFC257 || || +# RFC258 || || +# RFC259 || || +# RFC260 || || +# RFC261 || || +# RFC262 || || +# RFC263 || A.M. McKenzie || +# RFC264 || A. Bhushan, B. Braden, W. Crowther, E. Harslem, J. Heafner, A. McKenize, B. Sundberg, D. Watson, J. White || +# RFC265 || A. Bhushan, B. Braden, W. Crowther, E. Harslem, J. Heafner, A. McKenzie, J. Melvin, B. Sundberg, D. Watson, J. White || +# RFC266 || E. Westheimer || +# RFC267 || E. Westheimer || +# RFC268 || J. Postel || +# RFC269 || H. Brodie || +# RFC270 || A.M. McKenzie || +# RFC271 || B. Cosell || +# RFC272 || || +# RFC273 || R.W. Watson || +# RFC274 || E. Forman || +# RFC275 || || +# RFC276 || R.W. Watson || +# RFC277 || || +# RFC278 || A.K. Bhushan, R.T. Braden, E. Harslem, J.F. Heafner, A.M. McKenzie, J.T. Melvin, R.L. Sundberg, R.W. Watson, J.E. White || +# RFC279 || || +# RFC280 || R.W. Watson || +# RFC281 || A.M. McKenzie || +# RFC282 || M.A. Padlipsky || +# RFC283 || R.T. Braden || +# RFC284 || || +# RFC285 || D. Huff || +# RFC286 || E. Forman || +# RFC287 || E. Westheimer || +# RFC288 || E. Westheimer || +# RFC289 || R.W. Watson || +# RFC290 || A.P. Mullery || +# RFC291 || D.B. McKay || +# RFC292 || J.C. Michener, I.W. Cotton, K.C. Kelley, D.E. Liddle, E. Meyer || +# RFC293 || E. Westheimer || +# RFC294 || A.K. Bhushan || +# RFC295 || J. Postel || +# RFC296 || D.E. Liddle || +# RFC297 || D.C. Walden || +# RFC298 || E. Westheimer || +# RFC299 || D. Hopkin || +# RFC300 || J.B. North || +# RFC301 || R. Alter || +# RFC302 || R.F. Bryan || +# RFC303 || Network Information Center. Stanford Research Institute || +# RFC304 || D.B. McKay || +# RFC305 || R. Alter || +# RFC306 || E. Westheimer || +# RFC307 || E. Harslem || +# RFC308 || M. Seriff || +# RFC309 || A.K. Bhushan || +# RFC310 || A.K. Bhushan || +# RFC311 || R.F. Bryan || +# RFC312 || A.M. McKenzie || +# RFC313 || T.C. O'Sullivan || +# RFC314 || I.W. Cotton || +# RFC315 || E. Westheimer || +# RFC316 || D.B. McKay, A.P. Mullery || +# RFC317 || J. Postel || +# RFC318 || J. Postel || +# RFC319 || E. Westheimer || +# RFC320 || R. Reddy || +# RFC321 || P.M. Karp || +# RFC322 || V. Cerf, J. Postel || +# RFC323 || V. Cerf || +# RFC324 || J. Postel || +# RFC325 || G. Hicks || +# RFC326 || E. Westheimer || +# RFC327 || A.K. Bhushan || +# RFC328 || J. Postel || +# RFC329 || Network Information Center. Stanford Research Institute || +# RFC330 || E. Westheimer || +# RFC331 || J.M. McQuillan || +# RFC332 || E. Westheimer || +# RFC333 || R.D. Bressler, D. Murphy, D.C. Walden || +# RFC334 || A.M. McKenzie || +# RFC335 || R.F. Bryan || +# RFC336 || I.W. Cotton || +# RFC337 || || +# RFC338 || R.T. Braden || +# RFC339 || R. Thomas || +# RFC340 || T.C. O'Sullivan || +# RFC341 || || +# RFC342 || E. Westheimer || +# RFC343 || A.M. McKenzie || +# RFC344 || E. Westheimer || +# RFC345 || K.C. Kelley || +# RFC346 || J. Postel || +# RFC347 || J. Postel || +# RFC348 || J. Postel || +# RFC349 || J. Postel || +# RFC350 || R. Stoughton || +# RFC351 || D. Crocker || +# RFC352 || D. Crocker || +# RFC353 || E. Westheimer || +# RFC354 || A.K. Bhushan || +# RFC355 || J. Davidson || +# RFC356 || R. Alter || +# RFC357 || J. Davidson || +# RFC358 || || +# RFC359 || D.C. Walden || +# RFC360 || C. Holland || +# RFC361 || R.D. Bressler || +# RFC362 || E. Westheimer || +# RFC363 || Network Information Center. Stanford Research Institute || +# RFC364 || M.D. Abrams || +# RFC365 || D.C. Walden || +# RFC366 || E. Westheimer || +# RFC367 || E. Westheimer || +# RFC368 || R.T. Braden || +# RFC369 || J.R. Pickens || +# RFC370 || E. Westheimer || +# RFC371 || R.E. Kahn || +# RFC372 || R.W. Watson || +# RFC373 || J. McCarthy || +# RFC374 || A.M. McKenzie || +# RFC375 || || +# RFC376 || E. Westheimer || +# RFC377 || R.T. Braden || +# RFC378 || A.M. McKenzie || +# RFC379 || R. Braden || +# RFC380 || || +# RFC381 || J.M. McQuillan || +# RFC382 || L. McDaniel || +# RFC383 || || +# RFC384 || J.B. North || +# RFC385 || A.K. Bhushan || +# RFC386 || B. Cosell, D.C. Walden || +# RFC387 || K.C. Kelley, J. Meir || +# RFC388 || V. Cerf || +# RFC389 || B. Noble || +# RFC390 || R.T. Braden || +# RFC391 || A.M. McKenzie || +# RFC392 || G. Hicks, B.D. Wessler || +# RFC393 || J.M. Winett || +# RFC394 || J.M. McQuillan || +# RFC395 || J.M. McQuillan || +# RFC396 || S. Bunch || +# RFC397 || || +# RFC398 || J.R. Pickens, E. Faeh || +# RFC399 || M. Krilanovich || +# RFC400 || A.M. McKenzie || +# RFC401 || J. Hansen || +# RFC402 || J.B. North || +# RFC403 || G. Hicks || +# RFC404 || A.M. McKenzie || +# RFC405 || A.M. McKenzie || +# RFC406 || J.M. McQuillan || +# RFC407 || R.D. Bressler, R. Guida, A.M. McKenzie || +# RFC408 || A.D. Owen, J. Postel || +# RFC409 || J.E. White || +# RFC410 || J.M. McQuillan || +# RFC411 || M.A. Padlipsky || +# RFC412 || G. Hicks || +# RFC413 || A.M. McKenzie || +# RFC414 || A.K. Bhushan || +# RFC415 || H. Murray || +# RFC416 || J.C. Norton || +# RFC417 || J. Postel, C. Kline || +# RFC418 || W. Hathaway || +# RFC419 || A. Vezza || +# RFC420 || H. Murray || +# RFC421 || A.M. McKenzie || +# RFC422 || A.M. McKenzie || +# RFC423 || B. Noble || +# RFC424 || || +# RFC425 || R.D. Bressler || +# RFC426 || R. Thomas || +# RFC427 || || +# RFC428 || || +# RFC429 || J. Postel || +# RFC430 || R.T. Braden || +# RFC431 || M. Krilanovich || +# RFC432 || N. Neigus || +# RFC433 || J. Postel || +# RFC434 || A.M. McKenzie || +# RFC435 || B. Cosell, D.C. Walden || +# RFC436 || M. Krilanovich || +# RFC437 || E. Faeh || +# RFC438 || R. Thomas, R. Clements || +# RFC439 || V. Cerf || +# RFC440 || D.C. Walden || +# RFC441 || R.D. Bressler, R. Thomas || +# RFC442 || V. Cerf || +# RFC443 || A.M. McKenzie || +# RFC444 || || +# RFC445 || A.M. McKenzie || +# RFC446 || L.P. Deutsch || +# RFC447 || A.M. McKenzie || +# RFC448 || R.T. Braden || +# RFC449 || D.C. Walden || +# RFC450 || M.A. Padlipsky || +# RFC451 || M.A. Padlipsky || +# RFC452 || J. Winett || +# RFC453 || M.D. Kudlick || +# RFC454 || A.M. McKenzie || +# RFC455 || A.M. McKenzie || +# RFC456 || M.D. Kudlick || +# RFC457 || D.C. Walden || +# RFC458 || R.D. Bressler, R. Thomas || +# RFC459 || W. Kantrowitz || +# RFC460 || C. Kline || +# RFC461 || A.M. McKenzie || +# RFC462 || J. Iseli, D. Crocker || +# RFC463 || A.K. Bhushan || +# RFC464 || M.D. Kudlick || +# RFC465 || || +# RFC466 || J.M. Winett || +# RFC467 || J.D. Burchfiel, R.S. Tomlinson || +# RFC468 || R.T. Braden || +# RFC469 || M.D. Kudlick || +# RFC470 || R. Thomas || +# RFC471 || R. Thomas || +# RFC472 || S. Bunch || +# RFC473 || D.C. Walden || +# RFC474 || S. Bunch || +# RFC475 || A.K. Bhushan || +# RFC476 || A.M. McKenzie || +# RFC477 || M. Krilanovich || +# RFC478 || R.D. Bressler, R. Thomas || +# RFC479 || J.E. White || +# RFC480 || J.E. White || +# RFC481 || || +# RFC482 || A.M. McKenzie || +# RFC483 || M.D. Kudlick || +# RFC484 || || +# RFC485 || J.R. Pickens || +# RFC486 || R.D. Bressler || +# RFC487 || R.D. Bressler || +# RFC488 || M.F. Auerbach || +# RFC489 || J. Postel || +# RFC490 || J.R. Pickens || +# RFC491 || M.A. Padlipsky || +# RFC492 || E. Meyer || +# RFC493 || J.C. Michener, I.W. Cotton, K.C. Kelley, D.E. Liddle, E. Meyer || +# RFC494 || D.C. Walden || +# RFC495 || A.M. McKenzie || +# RFC496 || M.F. Auerbach || +# RFC497 || A.M. McKenzie || +# RFC498 || R.T. Braden || +# RFC499 || B.R. Reussow || +# RFC500 || A. Shoshani, I. Spiegler || +# RFC501 || K.T. Pogran || +# RFC502 || || +# RFC503 || N. Neigus, J. Postel || +# RFC504 || R. Thomas || +# RFC505 || M.A. Padlipsky || +# RFC506 || M.A. Padlipsky || +# RFC507 || || +# RFC508 || L. Pfeifer, J. McAfee || +# RFC509 || A.M. McKenzie || +# RFC510 || J.E. White || +# RFC511 || J.B. North || +# RFC512 || W. Hathaway || +# RFC513 || W. Hathaway || +# RFC514 || W. Kantrowitz || +# RFC515 || R. Winter || +# RFC516 || J. Postel || +# RFC517 || || +# RFC518 || N. Vaughan, E.J. Feinler || +# RFC519 || J.R. Pickens || +# RFC520 || J.D. Day || +# RFC521 || A.M. McKenzie || +# RFC522 || A.M. McKenzie || +# RFC523 || A.K. Bhushan || +# RFC524 || J.E. White || +# RFC525 || W. Parrish, J.R. Pickens || +# RFC526 || W.K. Pratt || +# RFC527 || R. Merryman || +# RFC528 || J.M. McQuillan || +# RFC529 || A.M. McKenzie, R. Thomas, R.S. Tomlinson, K.T. Pogran || +# RFC530 || A.K. Bhushan || +# RFC531 || M.A. Padlipsky || +# RFC532 || R.G. Merryman || +# RFC533 || D.C. Walden || +# RFC534 || D.C. Walden || +# RFC535 || R. Thomas || +# RFC536 || || +# RFC537 || S. Bunch || +# RFC538 || A.M. McKenzie || +# RFC539 || D. Crocker, J. Postel || +# RFC540 || || +# RFC541 || || +# RFC542 || N. Neigus || +# RFC543 || N.D. Meyer || +# RFC544 || N.D. Meyer, K. Kelley || +# RFC545 || J.R. Pickens || +# RFC546 || R. Thomas || +# RFC547 || D.C. Walden || +# RFC548 || D.C. Walden || +# RFC549 || J.C. Michener || +# RFC550 || L.P. Deutsch || +# RFC551 || Y. Feinroth, R. Fink || +# RFC552 || A.D. Owen || +# RFC553 || C.H. Irby, K. Victor || +# RFC554 || || +# RFC555 || J.E. White || +# RFC556 || A.M. McKenzie || +# RFC557 || B.D. Wessler || +# RFC558 || || +# RFC559 || A.K. Bushan || +# RFC560 || D. Crocker, J. Postel || +# RFC561 || A.K. Bhushan, K.T. Pogran, R.S. Tomlinson, J.E. White || +# RFC562 || A.M. McKenzie || +# RFC563 || J. Davidson || +# RFC564 || || +# RFC565 || D. Cantor || +# RFC566 || A.M. McKenzie || +# RFC567 || L.P. Deutsch || +# RFC568 || J.M. McQuillan || +# RFC569 || M.A. Padlipsky || +# RFC570 || J.R. Pickens || +# RFC571 || R. Braden || +# RFC572 || || +# RFC573 || A. Bhushan || +# RFC574 || M. Krilanovich || +# RFC575 || || +# RFC576 || K. Victor || +# RFC577 || D. Crocker || +# RFC578 || A.K. Bhushan, N.D. Ryan || +# RFC579 || A.M. McKenzie || +# RFC580 || J. Postel || +# RFC581 || D. Crocker, J. Postel || +# RFC582 || R. Clements || +# RFC583 || || +# RFC584 || J. Iseli, D. Crocker, N. Neigus || +# RFC585 || D. Crocker, N. Neigus, E.J. Feinler, J. Iseli || +# RFC586 || A.M. McKenzie || +# RFC587 || J. Postel || +# RFC588 || A. Stokes || +# RFC589 || R.T. Braden || +# RFC590 || M.A. Padlipsky || +# RFC591 || D.C. Walden || +# RFC592 || R.W. Watson || +# RFC593 || A.M. McKenzie, J. Postel || +# RFC594 || J.D. Burchfiel || +# RFC595 || W. Hathaway || +# RFC596 || E.A. Taft || +# RFC597 || N. Neigus, E.J. Feinler || +# RFC598 || Network Information Center. Stanford Research Institute || +# RFC599 || R.T. Braden || +# RFC600 || A. Berggreen || +# RFC601 || A.M. McKenzie || +# RFC602 || R.M. Metcalfe || +# RFC603 || J.D. Burchfiel || +# RFC604 || J. Postel || +# RFC605 || || +# RFC606 || L.P. Deutsch || +# RFC607 || M. Krilanovich, G. Gregg || +# RFC608 || M.D. Kudlick || +# RFC609 || B. Ferguson || +# RFC610 || R. Winter, J. Hill, W. Greiff || +# RFC611 || D.C. Walden || +# RFC612 || A.M. McKenzie || +# RFC613 || A.M. McKenzie || +# RFC614 || K.T. Pogran, N. Neigus || +# RFC615 || D. Crocker || +# RFC616 || D. Walden || +# RFC617 || E.A. Taft || +# RFC618 || E.A. Taft || +# RFC619 || W. Naylor, H. Opderbeck || +# RFC620 || B. Ferguson || +# RFC621 || M.D. Kudlick || +# RFC622 || A.M. McKenzie || +# RFC623 || M. Krilanovich || +# RFC624 || M. Krilanovich, G. Gregg, W. Hathaway, J.E. White || +# RFC625 || M.D. Kudlick, E.J. Feinler || +# RFC626 || L. Kleinrock, H. Opderbeck || +# RFC627 || M.D. Kudlick, E.J. Feinler || +# RFC628 || M.L. Keeney || +# RFC629 || J.B. North || +# RFC630 || J. Sussman || +# RFC631 || A. Danthine || +# RFC632 || H. Opderbeck || +# RFC633 || A.M. McKenzie || +# RFC634 || A.M. McKenzie || +# RFC635 || V. Cerf || +# RFC636 || J.D. Burchfiel, B. Cosell, R.S. Tomlinson, D.C. Walden || +# RFC637 || A.M. McKenzie || +# RFC638 || A.M. McKenzie || +# RFC639 || || +# RFC640 || J. Postel || +# RFC641 || || +# RFC642 || J.D. Burchfiel || +# RFC643 || E. Mader || +# RFC644 || R. Thomas || +# RFC645 || D. Crocker || +# RFC646 || || +# RFC647 || M.A. Padlipsky || +# RFC648 || || +# RFC649 || || +# RFC650 || || +# RFC651 || D. Crocker || +# RFC652 || D. Crocker || +# RFC653 || D. Crocker || +# RFC654 || D. Crocker || +# RFC655 || D. Crocker || +# RFC656 || D. Crocker || +# RFC657 || D. Crocker || +# RFC658 || D. Crocker || +# RFC659 || J. Postel || +# RFC660 || D.C. Walden || +# RFC661 || J. Postel || +# RFC662 || R. Kanodia || +# RFC663 || R. Kanodia || +# RFC664 || || +# RFC665 || || +# RFC666 || M.A. Padlipsky || +# RFC667 || S.G. Chipman || +# RFC668 || || +# RFC669 || D.W. Dodds || +# RFC670 || || +# RFC671 || R. Schantz || +# RFC672 || R. Schantz || +# RFC673 || || +# RFC674 || J. Postel, J.E. White || +# RFC675 || V. Cerf, Y. Dalal, C. Sunshine || +# RFC676 || || +# RFC677 || P.R. Johnson, R. Thomas || +# RFC678 || J. Postel || +# RFC679 || D.W. Dodds || +# RFC680 || T.H. Myer, D.A. Henderson || +# RFC681 || S. Holmgren || +# RFC682 || || +# RFC683 || R. Clements || +# RFC684 || R. Schantz || +# RFC685 || M. Beeler || +# RFC686 || B. Harvey || +# RFC687 || D.C. Walden || +# RFC688 || D.C. Walden || +# RFC689 || R. Clements || +# RFC690 || J. Postel || +# RFC691 || B. Harvey || +# RFC692 || S.M. Wolfe || +# RFC693 || || +# RFC694 || J. Postel || +# RFC695 || M. Krilanovich || +# RFC696 || V.G. Cerf || +# RFC697 || J. Lieb || +# RFC698 || T. Mock || +# RFC699 || J. Postel, J. Vernon || +# RFC700 || E. Mader, W.W. Plummer, R.S. Tomlinson || +# RFC701 || D.W. Dodds || +# RFC702 || D.W. Dodds || +# RFC703 || D.W. Dodds || +# RFC704 || P.J. Santos || +# RFC705 || R.F. Bryan || +# RFC706 || J. Postel || +# RFC707 || J.E. White || +# RFC708 || J.E. White || +# RFC709 || || +# RFC710 || || +# RFC711 || || +# RFC712 || J.E. Donnelley || +# RFC713 || J. Haverty || +# RFC714 || A.M. McKenzie || +# RFC715 || || +# RFC716 || D.C. Walden, J. Levin || +# RFC717 || J. Postel || +# RFC718 || J. Postel || +# RFC719 || J. Postel || +# RFC720 || D. Crocker || +# RFC721 || L.L. Garlick || +# RFC722 || J. Haverty || +# RFC723 || || +# RFC724 || D. Crocker, K.T. Pogran, J. Vittal, D.A. Henderson || +# RFC725 || J.D. Day, G.R. Grossman || +# RFC726 || J. Postel, D. Crocker || +# RFC727 || M.R. Crispin || +# RFC728 || J.D. Day || +# RFC729 || D. Crocker || +# RFC730 || J. Postel || +# RFC731 || J.D. Day || +# RFC732 || J.D. Day || +# RFC733 || D. Crocker, J. Vittal, K.T. Pogran, D.A. Henderson || +# RFC734 || M.R. Crispin || +# RFC735 || D. Crocker, R.H. Gumpertz || +# RFC736 || M.R. Crispin || +# RFC737 || K. Harrenstien || +# RFC738 || K. Harrenstien || +# RFC739 || J. Postel || +# RFC740 || R.T. Braden || +# RFC741 || D. Cohen || +# RFC742 || K. Harrenstien || +# RFC743 || K. Harrenstien || +# RFC744 || J. Sattley || +# RFC745 || M. Beeler || +# RFC746 || R. Stallman || +# RFC747 || M.R. Crispin || +# RFC748 || M.R. Crispin || +# RFC749 || B. Greenberg || +# RFC750 || J. Postel || +# RFC751 || P.D. Lebling || +# RFC752 || M.R. Crispin || +# RFC753 || J. Postel || +# RFC754 || J. Postel || +# RFC755 || J. Postel || +# RFC756 || J.R. Pickens, E.J. Feinler, J.E. Mathis || +# RFC757 || D.P. Deutsch || +# RFC758 || J. Postel || +# RFC759 || J. Postel || +# RFC760 || J. Postel || +# RFC761 || J. Postel || +# RFC762 || J. Postel || +# RFC763 || M.D. Abrams || +# RFC764 || J. Postel || +# RFC765 || J. Postel || +# RFC766 || J. Postel || +# RFC767 || J. Postel || +# RFC768 || J. Postel || +# RFC769 || J. Postel || +# RFC770 || J. Postel || +# RFC771 || V.G. Cerf, J. Postel || +# RFC772 || S. Sluizer, J. Postel || +# RFC773 || V.G. Cerf || +# RFC774 || J. Postel || +# RFC775 || D. Mankins, D. Franklin, A.D. Owen || +# RFC776 || J. Postel || +# RFC777 || J. Postel || +# RFC778 || D.L. Mills || +# RFC779 || E. Killian || +# RFC780 || S. Sluizer, J. Postel || +# RFC781 || Z. Su || +# RFC782 || J. Nabielsky, A.P. Skelton || +# RFC783 || K.R. Sollins || +# RFC784 || S. Sluizer, J. Postel || +# RFC785 || S. Sluizer, J. Postel || +# RFC786 || S. Sluizer, J. Postel || +# RFC787 || A.L. Chapin || +# RFC788 || J. Postel || +# RFC789 || E.C. Rosen || +# RFC790 || J. Postel || +# RFC791 || J. Postel || +# RFC792 || J. Postel || +# RFC793 || J. Postel || +# RFC794 || V.G. Cerf || +# RFC795 || J. Postel || +# RFC796 || J. Postel || +# RFC797 || A.R. Katz || +# RFC798 || A.R. Katz || +# RFC799 || D.L. Mills || +# RFC800 || J. Postel, J. Vernon || +# RFC801 || J. Postel || +# RFC802 || A.G. Malis || +# RFC803 || A. Agarwal, M.J. O'Connor, D.L. Mills || +# RFC804 || International Telegraph and Telephone Consultative Committee of the International Telecommunication Union || +# RFC805 || J. Postel || +# RFC806 || National Bureau of Standards || +# RFC807 || J. Postel || +# RFC808 || J. Postel || +# RFC809 || T. Chang || +# RFC810 || E.J. Feinler, K. Harrenstien, Z. Su, V. White || +# RFC811 || K. Harrenstien, V. White, E.J. Feinler || +# RFC812 || K. Harrenstien, V. White || +# RFC813 || D.D. Clark || +# RFC814 || D.D. Clark || +# RFC815 || D.D. Clark || +# RFC816 || D.D. Clark || +# RFC817 || D.D. Clark || +# RFC818 || J. Postel || +# RFC819 || Z. Su, J. Postel || +# RFC820 || J. Postel || +# RFC821 || J. Postel || +# RFC822 || D. Crocker || +# RFC823 || R.M. Hinden, A. Sheltzer || bob.hinden@gmail.com +# RFC824 || W.I. MacGregor, D.C. Tappan || +# RFC825 || J. Postel || +# RFC826 || D. Plummer || +# RFC827 || E.C. Rosen || +# RFC828 || K. Owen || +# RFC829 || V.G. Cerf || +# RFC830 || Z. Su || +# RFC831 || R.T. Braden || +# RFC832 || D. Smallberg || +# RFC833 || D. Smallberg || +# RFC834 || D. Smallberg || +# RFC835 || D. Smallberg || +# RFC836 || D. Smallberg || +# RFC837 || D. Smallberg || +# RFC838 || D. Smallberg || +# RFC839 || D. Smallberg || +# RFC840 || J. Postel || +# RFC841 || National Bureau of Standards || +# RFC842 || D. Smallberg || +# RFC843 || D. Smallberg || +# RFC844 || R. Clements || +# RFC845 || D. Smallberg || +# RFC846 || D. Smallberg || +# RFC847 || A. Westine, D. Smallberg, J. Postel || +# RFC848 || D. Smallberg || +# RFC849 || M.R. Crispin || +# RFC850 || M.R. Horton || +# RFC851 || A.G. Malis || +# RFC852 || A.G. Malis || +# RFC853 || || +# RFC854 || J. Postel, J.K. Reynolds || +# RFC855 || J. Postel, J.K. Reynolds || +# RFC856 || J. Postel, J. Reynolds || +# RFC857 || J. Postel, J. Reynolds || +# RFC858 || J. Postel, J. Reynolds || +# RFC859 || J. Postel, J. Reynolds || +# RFC860 || J. Postel, J. Reynolds || +# RFC861 || J. Postel, J. Reynolds || +# RFC862 || J. Postel || +# RFC863 || J. Postel || +# RFC864 || J. Postel || +# RFC865 || J. Postel || +# RFC866 || J. Postel || +# RFC867 || J. Postel || +# RFC868 || J. Postel, K. Harrenstien || +# RFC869 || R. Hinden || bob.hinden@gmail.com +# RFC870 || J.K. Reynolds, J. Postel || +# RFC871 || M.A. Padlipsky || +# RFC872 || M.A. Padlipsky || +# RFC873 || M.A. Padlipsky || +# RFC874 || M.A. Padlipsky || +# RFC875 || M.A. Padlipsky || +# RFC876 || D. Smallberg || +# RFC877 || J.T. Korb || +# RFC878 || A.G. Malis || +# RFC879 || J. Postel || +# RFC880 || J.K. Reynolds, J. Postel || +# RFC881 || J. Postel || +# RFC882 || P.V. Mockapetris || +# RFC883 || P.V. Mockapetris || +# RFC884 || M. Solomon, E. Wimmers || +# RFC885 || J. Postel || +# RFC886 || M.T. Rose || +# RFC887 || M. Accetta || +# RFC888 || L. Seamonson, E.C. Rosen || +# RFC889 || D.L. Mills || +# RFC890 || J. Postel || +# RFC891 || D.L. Mills || +# RFC892 || International Organization for Standardization || +# RFC893 || S. Leffler, M.J. Karels || +# RFC894 || C. Hornig || +# RFC895 || J. Postel || +# RFC896 || J. Nagle || +# RFC897 || J. Postel || +# RFC898 || R.M. Hinden, J. Postel, M. Muuss, J.K. Reynolds || bob.hinden@gmail.com +# RFC899 || J. Postel, A. Westine || +# RFC900 || J.K. Reynolds, J. Postel || +# RFC901 || J.K. Reynolds, J. Postel || +# RFC902 || J.K. Reynolds, J. Postel || +# RFC903 || R. Finlayson, T. Mann, J.C. Mogul, M. Theimer || +# RFC904 || D.L. Mills || +# RFC905 || ISO || +# RFC906 || R. Finlayson || +# RFC907 || Bolt Beranek and Newman Laboratories || +# RFC908 || D. Velten, R.M. Hinden, J. Sax || bob.hinden@gmail.com +# RFC909 || C. Welles, W. Milliken || +# RFC910 || H.C. Forsdick || +# RFC911 || P. Kirton || +# RFC912 || M. St. Johns || +# RFC913 || M. Lottor || +# RFC914 || D.J. Farber, G. Delp, T.M. Conte || +# RFC915 || M.A. Elvy, R. Nedved || +# RFC916 || G.G. Finn || +# RFC917 || J.C. Mogul || +# RFC918 || J.K. Reynolds || +# RFC919 || J.C. Mogul || +# RFC920 || J. Postel, J.K. Reynolds || +# RFC921 || J. Postel || +# RFC922 || J.C. Mogul || +# RFC923 || J.K. Reynolds, J. Postel || +# RFC924 || J.K. Reynolds, J. Postel || +# RFC925 || J. Postel || +# RFC926 || International Organization for Standardization || +# RFC927 || B.A. Anderson || +# RFC928 || M.A. Padlipsky || +# RFC929 || J. Lilienkamp, R. Mandell, M.A. Padlipsky || +# RFC930 || M. Solomon, E. Wimmers || +# RFC931 || M. St. Johns || +# RFC932 || D.D. Clark || +# RFC933 || S. Silverman || +# RFC934 || M.T. Rose, E.A. Stefferud || +# RFC935 || J.G. Robinson || +# RFC936 || M.J. Karels || +# RFC937 || M. Butler, J. Postel, D. Chase, J. Goldberger, J.K. Reynolds || +# RFC938 || T. Miller || +# RFC939 || National Research Council || +# RFC940 || Gateway Algorithms and Data Structures Task Force || +# RFC941 || International Organization for Standardization || +# RFC942 || National Research Council || +# RFC943 || J.K. Reynolds, J. Postel || +# RFC944 || J.K. Reynolds, J. Postel || +# RFC945 || J. Postel || +# RFC946 || R. Nedved || +# RFC947 || K. Lebowitz, D. Mankins || +# RFC948 || I. Winston || +# RFC949 || M.A. Padlipsky || +# RFC950 || J.C. Mogul, J. Postel || +# RFC951 || W.J. Croft, J. Gilmore || +# RFC952 || K. Harrenstien, M.K. Stahl, E.J. Feinler || +# RFC953 || K. Harrenstien, M.K. Stahl, E.J. Feinler || +# RFC954 || K. Harrenstien, M.K. Stahl, E.J. Feinler || +# RFC955 || R.T. Braden || +# RFC956 || D.L. Mills || +# RFC957 || D.L. Mills || +# RFC958 || D.L. Mills || +# RFC959 || J. Postel, J. Reynolds || +# RFC960 || J.K. Reynolds, J. Postel || +# RFC961 || J.K. Reynolds, J. Postel || +# RFC962 || M.A. Padlipsky || +# RFC963 || D.P. Sidhu || +# RFC964 || D.P. Sidhu, T. Blumer || +# RFC965 || L. Aguilar || +# RFC966 || S.E. Deering, D.R. Cheriton || +# RFC967 || M.A. Padlipsky || +# RFC968 || V.G. Cerf || +# RFC969 || D.D. Clark, M.L. Lambert, L. Zhang || +# RFC970 || J. Nagle || +# RFC971 || A.L. DeSchon || +# RFC972 || F.J. Wancho || +# RFC973 || P.V. Mockapetris || +# RFC974 || C. Partridge || +# RFC975 || D.L. Mills || +# RFC976 || M.R. Horton || +# RFC977 || B. Kantor, P. Lapsley || +# RFC978 || J.K. Reynolds, R. Gillman, W.A. Brackenridge, A. Witkowski, J. Postel || +# RFC979 || A.G. Malis || +# RFC980 || O.J. Jacobsen, J. Postel || +# RFC981 || D.L. Mills || +# RFC982 || H.W. Braun || +# RFC983 || D.E. Cass, M.T. Rose || +# RFC984 || D.D. Clark, M.L. Lambert || +# RFC985 || National Science Foundation, Network Technical Advisory Group || +# RFC986 || R.W. Callon, H.W. Braun || +# RFC987 || S.E. Kille || +# RFC988 || S.E. Deering || +# RFC989 || J. Linn || +# RFC990 || J.K. Reynolds, J. Postel || +# RFC991 || J.K. Reynolds, J. Postel || +# RFC992 || K.P. Birman, T.A. Joseph || +# RFC993 || D.D. Clark, M.L. Lambert || +# RFC994 || International Organization for Standardization || +# RFC995 || International Organization for Standardization || +# RFC996 || D.L. Mills || +# RFC997 || J.K. Reynolds, J. Postel || +# RFC998 || D.D. Clark, M.L. Lambert, L. Zhang || +# RFC999 || A. Westine, J. Postel || +# RFC1000 || J.K. Reynolds, J. Postel || +# RFC1001 || NetBIOS Working Group in the Defense Advanced Research Projects Agency, Internet Activities Board, End-to-End Services Task Force || +# RFC1002 || NetBIOS Working Group in the Defense Advanced Research Projects Agency, Internet Activities Board, End-to-End Services Task Force || +# RFC1003 || A.R. Katz || +# RFC1004 || D.L. Mills || +# RFC1005 || A. Khanna, A.G. Malis || +# RFC1006 || M.T. Rose, D.E. Cass || +# RFC1007 || W. McCoy || +# RFC1008 || W. McCoy || +# RFC1009 || R.T. Braden, J. Postel || +# RFC1010 || J.K. Reynolds, J. Postel || +# RFC1011 || J.K. Reynolds, J. Postel || +# RFC1012 || J.K. Reynolds, J. Postel || +# RFC1013 || R.W. Scheifler || +# RFC1014 || Sun Microsystems || +# RFC1015 || B.M. Leiner || +# RFC1016 || W. Prue, J. Postel || +# RFC1017 || B.M. Leiner || +# RFC1018 || A.M. McKenzie || +# RFC1019 || D. Arnon || +# RFC1020 || S. Romano, M.K. Stahl || +# RFC1021 || C. Partridge, G. Trewitt || +# RFC1022 || C. Partridge, G. Trewitt || +# RFC1023 || G. Trewitt, C. Partridge || +# RFC1024 || C. Partridge, G. Trewitt || +# RFC1025 || J. Postel || +# RFC1026 || S.E. Kille || +# RFC1027 || S. Carl-Mitchell, J.S. Quarterman || +# RFC1028 || J. Davin, J.D. Case, M. Fedor, M.L. Schoffstall || +# RFC1029 || G. Parr || +# RFC1030 || M.L. Lambert || +# RFC1031 || W.D. Lazear || +# RFC1032 || M.K. Stahl || +# RFC1033 || M. Lottor || +# RFC1034 || P.V. Mockapetris || +# RFC1035 || P.V. Mockapetris || +# RFC1036 || M.R. Horton, R. Adams || +# RFC1037 || B. Greenberg, S. Keene || +# RFC1038 || M. St. Johns || +# RFC1039 || D. Latham || +# RFC1040 || J. Linn || +# RFC1041 || Y. Rekhter || +# RFC1042 || J. Postel, J.K. Reynolds || +# RFC1043 || A. Yasuda, T. Thompson || +# RFC1044 || K. Hardwick, J. Lekashman || +# RFC1045 || D.R. Cheriton || +# RFC1046 || W. Prue, J. Postel || +# RFC1047 || C. Partridge || +# RFC1048 || P.A. Prindeville || +# RFC1049 || M.A. Sirbu || +# RFC1050 || Sun Microsystems || +# RFC1051 || P.A. Prindeville || +# RFC1052 || V.G. Cerf || +# RFC1053 || S. Levy, T. Jacobson || +# RFC1054 || S.E. Deering || +# RFC1055 || J.L. Romkey || +# RFC1056 || M.L. Lambert || +# RFC1057 || Sun Microsystems || +# RFC1058 || C.L. Hedrick || +# RFC1059 || D.L. Mills || +# RFC1060 || J.K. Reynolds, J. Postel || +# RFC1061 || || +# RFC1062 || S. Romano, M.K. Stahl, M. Recker || +# RFC1063 || J.C. Mogul, C.A. Kent, C. Partridge, K. McCloghrie || +# RFC1064 || M.R. Crispin || +# RFC1065 || K. McCloghrie, M.T. Rose || +# RFC1066 || K. McCloghrie, M.T. Rose || +# RFC1067 || J.D. Case, M. Fedor, M.L. Schoffstall, J. Davin || +# RFC1068 || A.L. DeSchon, R.T. Braden || +# RFC1069 || R.W. Callon, H.W. Braun || +# RFC1070 || R.A. Hagens, N.E. Hall, M.T. Rose || hagens@cs.wisc.edu, nhall@cs.wisc.edu +# RFC1071 || R.T. Braden, D.A. Borman, C. Partridge || +# RFC1072 || V. Jacobson, R.T. Braden || +# RFC1073 || D. Waitzman || +# RFC1074 || J. Rekhter || +# RFC1075 || D. Waitzman, C. Partridge, S.E. Deering || +# RFC1076 || G. Trewitt, C. Partridge || +# RFC1077 || B.M. Leiner || +# RFC1078 || M. Lottor || +# RFC1079 || C.L. Hedrick || +# RFC1080 || C.L. Hedrick || +# RFC1081 || M.T. Rose || +# RFC1082 || M.T. Rose || +# RFC1083 || Defense Advanced Research Projects Agency, Internet Activities Board || +# RFC1084 || J.K. Reynolds || JKREYNOLDS@ISI.EDU +# RFC1085 || M.T. Rose || mrose17@gmail.com +# RFC1086 || J.P. Onions, M.T. Rose || JPO@CS.NOTT.AC.UK, mrose17@gmail.com +# RFC1087 || Defense Advanced Research Projects Agency, Internet Activities Board || +# RFC1088 || L.J. McLaughlin || ljm@TWG.COM +# RFC1089 || M. Schoffstall, C. Davin, M. Fedor, J. Case || schoff@stonewall.nyser.net, jrd@ptt.lcs.mit.edu, fedor@patton.NYSER.NET, case@UTKUX1.UTK.EDU +# RFC1090 || R. Ullmann || +# RFC1091 || J. VanBokkelen || +# RFC1092 || J. Rekhter || +# RFC1093 || H.W. Braun || +# RFC1094 || B. Nowicki || +# RFC1095 || U.S. Warrier, L. Besaw || +# RFC1096 || G.A. Marcy || +# RFC1097 || B. Miller || +# RFC1098 || J.D. Case, M. Fedor, M.L. Schoffstall, J. Davin || jrd@ptt.lcs.mit.edu +# RFC1099 || J. Reynolds || JKREY@ISI.EDU +# RFC1100 || Defense Advanced Research Projects Agency, Internet Activities Board || +# RFC1101 || P.V. Mockapetris || +# RFC1102 || D.D. Clark || +# RFC1103 || D. Katz || +# RFC1104 || H.W. Braun || hwb@merit.edu +# RFC1105 || K. Lougheed, Y. Rekhter || +# RFC1106 || R. Fox || rfox@tandem.com +# RFC1107 || K.R. Sollins || SOLLINS@XX.LCS.MIT.EDU +# RFC1108 || S. Kent || +# RFC1109 || V.G. Cerf || CERF@A.ISI.EDU +# RFC1110 || A.M. McKenzie || MCKENZIE@BBN.COM +# RFC1111 || J. Postel || POSTEL@ISI.EDU +# RFC1112 || S.E. Deering || deering@PESCADERO.STANFORD.EDU +# RFC1113 || J. Linn || Linn@ultra.enet.dec.com +# RFC1114 || S.T. Kent, J. Linn || kent@BBN.COM, Linn@ultra.enet.dec.com +# RFC1115 || J. Linn || Linn@ultra.enet.dec.com +# RFC1116 || D.A. Borman || dab@CRAY.COM +# RFC1117 || S. Romano, M.K. Stahl, M. Recker || +# RFC1118 || E. Krol || Krol@UXC.CSO.UIUC.EDU +# RFC1119 || D.L. Mills || +# RFC1120 || V. Cerf || VCERF@NRI.RESTON.VA.US +# RFC1121 || J. Postel, L. Kleinrock, V.G. Cerf, B. Boehm || Postel@ISI.EDU, lk@CS.UCLA.EDU, VCerf@NRI.RESTON.VA.US, boehm@CS.UCLA.EDU +# RFC1122 || R. Braden, Ed. || Braden@ISI.EDU +# RFC1123 || R. Braden, Ed. || Braden@ISI.EDU +# RFC1124 || B.M. Leiner || +# RFC1125 || D. Estrin || +# RFC1126 || M. Little || little@SAIC.COM +# RFC1127 || R.T. Braden || Braden@ISI.EDU +# RFC1128 || D.L. Mills || +# RFC1129 || D.L. Mills || +# RFC1130 || Defense Advanced Research Projects Agency, Internet Activities Board || +# RFC1131 || J. Moy || +# RFC1132 || L.J. McLaughlin || ljm@TWG.COM +# RFC1133 || J.Y. Yu, H.W. Braun || jyy@merit.edu, hwb@merit.edu +# RFC1134 || D. Perkins || rdhobby@ucdavis.edu +# RFC1135 || J.K. Reynolds || JKREY@ISI.EDU +# RFC1136 || S. Hares, D. Katz || +# RFC1137 || S. Kille || S.Kille@Cs.Ucl.AC.UK +# RFC1138 || S.E. Kille || S.Kille@Cs.Ucl.AC.UK +# RFC1139 || R.A. Hagens || hagens@CS.WISC.EDU +# RFC1140 || Defense Advanced Research Projects Agency, Internet Activities Board || +# RFC1141 || T. Mallory, A. Kullberg || tmallory@CCV.BBN.COM, akullberg@BBN.COM +# RFC1142 || D. Oran, Ed. || +# RFC1143 || D.J. Bernstein || +# RFC1144 || V. Jacobson || +# RFC1145 || J. Zweig, C. Partridge || zweig@CS.UIUC.EDU, craig@BBN.COM +# RFC1146 || J. Zweig, C. Partridge || zweig@CS.UIUC.EDU, craig@BBN.COM +# RFC1147 || R.H. Stine || STINE@SPARTA.COM +# RFC1148 || S.E. Kille || S.Kille@Cs.Ucl.AC.UK +# RFC1149 || D. Waitzman || dwaitzman@BBN.COM +# RFC1150 || G.S. Malkin, J.K. Reynolds || gmalkin@proteon.com, jkrey@isi.edu +# RFC1151 || C. Partridge, R.M. Hinden || craig@BBN.COM, bob.hinden@gmail.com +# RFC1152 || C. Partridge || craig@BBN.COM +# RFC1153 || F.J. Wancho || +# RFC1154 || D. Robinson, R. Ullmann || +# RFC1155 || M.T. Rose, K. McCloghrie || mrose17@gmail.com +# RFC1156 || K. McCloghrie, M.T. Rose || mrose17@gmail.com +# RFC1157 || J.D. Case, M. Fedor, M.L. Schoffstall, J. Davin || jrd@ptt.lcs.mit.edu +# RFC1158 || M.T. Rose || +# RFC1159 || R. Nelson || nelson@sun.soe.clarkson.edu +# RFC1160 || V. Cerf || VCERF@NRI.RESTON.VA.US +# RFC1161 || M.T. Rose || +# RFC1162 || G. Satz || +# RFC1163 || K. Lougheed, Y. Rekhter || +# RFC1164 || J.C. Honig, D. Katz, M. Mathis, Y. Rekhter, J.Y. Yu || +# RFC1165 || J. Crowcroft, J.P. Onions || JON@CS.UCL.AC.UK, JPO@CS.NOTT.AC.UK +# RFC1166 || S. Kirkpatrick, M.K. Stahl, M. Recker || +# RFC1167 || V.G. Cerf || vcerf@NRI.Reston.VA.US +# RFC1168 || A. Westine, A.L. DeSchon, J. Postel, C.E. Ward || +# RFC1169 || V.G. Cerf, K.L. Mills || vcerf@nri.reston.va.us, MILLS@ECF.NCSL.NIST.GOV +# RFC1170 || R.B. Fougner || +# RFC1171 || D. Perkins || ddp@andrew.cmu.edu +# RFC1172 || D. Perkins, R. Hobby || rdhobby@ucdavis.edu, ddp@andrew.cmu.edu +# RFC1173 || J. VanBokkelen || jbvb@ftp.com +# RFC1174 || V.G. Cerf || vcerf@nri.reston.va.us +# RFC1175 || K.L. Bowers, T.L. LaQuey, J.K. Reynolds, K. Roubicek, M.K. Stahl, A. Yuan || +# RFC1176 || M.R. Crispin || mrc@Tomobiki-Cho.CAC.Washington.EDU +# RFC1177 || G.S. Malkin, A.N. Marine, J.K. Reynolds || gmalkin@ftp.com, APRIL@NIC.DDN.MIL, jkrey@isi.edu +# RFC1178 || D. Libes || libes@cme.nist.gov +# RFC1179 || L. McLaughlin || ljm@twg.com +# RFC1180 || T.J. Socolofsky, C.J. Kale || TEDS@SPIDER.CO.UK, CLAUDIAK@SPIDER.CO.UK +# RFC1181 || R. Blokzijl || k13@nikhef.nl +# RFC1182 || || +# RFC1183 || C.F. Everhart, L.A. Mamakos, R. Ullmann, P.V. Mockapetris || Craig_Everhart@transarc.com, pvm@isi.edu +# RFC1184 || D.A. Borman || dab@CRAY.COM +# RFC1185 || V. Jacobson, R.T. Braden, L. Zhang || van@CSAM.LBL.GOV, Braden@ISI.EDU, lixia@PARC.XEROX.COM +# RFC1186 || R.L. Rivest || rivest@theory.lcs.mit.edu +# RFC1187 || M.T. Rose, K. McCloghrie, J.R. Davin || mrose17@gmail.com, KZM@HLS.COM, jrd@ptt.lcs.mit.edu +# RFC1188 || D. Katz || dkatz@merit.edu +# RFC1189 || U.S. Warrier, L. Besaw, L. LaBarre, B.D. Handspicker || +# RFC1190 || C. Topolcic || Casner@ISI.Edu, CLynn@BBN.Com, ppark@BBN.COM, Schroder@BBN.Com, Topolcic@BBN.Com +# RFC1191 || J.C. Mogul, S.E. Deering || mogul@decwrl.dec.com, deering@xerox.com +# RFC1192 || B. Kahin || kahin@hulaw.harvard.edu +# RFC1193 || D. Ferrari || ferrari@UCBVAX.BERKELEY.EDU +# RFC1194 || D.P. Zimmerman || dpz@dimacs.rutgers.edu +# RFC1195 || R.W. Callon || +# RFC1196 || D.P. Zimmerman || dpz@dimacs.rutgers.edu +# RFC1197 || M. Sherman || +# RFC1198 || R.W. Scheifler || rws@expo.lcs.mit.edu +# RFC1199 || J. Reynolds || JKREY@ISI.EDU +# RFC1200 || Defense Advanced Research Projects Agency, Internet Activities Board || +# RFC1201 || D. Provan || donp@Novell.Com +# RFC1202 || M.T. Rose || mrose17@gmail.com +# RFC1203 || J. Rice || RICE@SUMEX-AIM.STANFORD.EDU +# RFC1204 || S. Yeh, D. Lee || dlee@netix.com +# RFC1205 || P. Chmielewski || paulc@rchland.iinus1.ibm.com +# RFC1206 || G.S. Malkin, A.N. Marine || gmalkin@ftp.com, APRIL@nic.ddn.mil +# RFC1207 || G.S. Malkin, A.N. Marine, J.K. Reynolds || gmalkin@ftp.com, APRIL@nic.ddn.mil, jkrey@isi.edu +# RFC1208 || O.J. Jacobsen, D.C. Lynch || OLE@CSLI.STANFORD.EDU, Lynch@ISI.EDU +# RFC1209 || D. Piscitello, J. Lawrence || dave@sabre.bellcore.com, jcl@sabre.bellcore.com +# RFC1210 || V.G. Cerf, P.T. Kirstein, B. Randell || +# RFC1211 || A. Westine, J. Postel || Westine@ISI.EDU, Postel@ISI.EDU +# RFC1212 || M.T. Rose, K. McCloghrie || mrose17@gmail.com, kzm@hls.com +# RFC1213 || K. McCloghrie, M. Rose || kzm@hls.com, mrose17@gmail.com +# RFC1214 || L. LaBarre || cel@mbunix.mitre.org +# RFC1215 || M.T. Rose || mrose17@gmail.com +# RFC1216 || P. Richard, P. Kynikos || +# RFC1217 || V.G. Cerf || CERF@NRI.RESTON.VA.US +# RFC1218 || North American Directory Forum || +# RFC1219 || P.F. Tsuchiya || tsuchiya@thumper.bellcore.com +# RFC1220 || F. Baker || fbaker@ACC.COM +# RFC1221 || W. Edmond || wbe@bbn.com +# RFC1222 || H.W. Braun, Y. Rekhter || HWB@SDSC.EDU, Yakov@Watson.IBM.COM +# RFC1223 || J.M. Halpern || +# RFC1224 || L. Steinberg || LOUISS@IBM.COM +# RFC1225 || M.T. Rose || mrose17@gmail.com +# RFC1226 || B. Kantor || brian@UCSD.EDU +# RFC1227 || M.T. Rose || mrose17@gmail.com +# RFC1228 || G. Carpenter, B. Wijnen || +# RFC1229 || K. McCloghrie || kzm@hls.com +# RFC1230 || K. McCloghrie, R. Fox || kzm@hls.com, rfox@synoptics.com +# RFC1231 || K. McCloghrie, R. Fox, E. Decker || kzm@hls.com, rfox@synoptics.com, cire@cisco.com +# RFC1232 || F. Baker, C.P. Kolb || fbaker@acc.com, kolb@psi.com +# RFC1233 || T.A. Cox, K. Tesink || tacox@sabre.bellcore.com, kaj@nvuxr.cc.bellcore.com +# RFC1234 || D. Provan || donp@Novell.Com +# RFC1235 || J. Ioannidis, G. Maguire || ji@cs.columbia.edu, maguire@cs.columbia.edu +# RFC1236 || L. Morales, P. Hasse || lmorales@huachuca-emh8.army.mil, phasse@huachuca-emh8.army.mil +# RFC1237 || R. Colella, E. Gardner, R. Callon || colella@osi3.ncsl.nist.gov, epg@gateway.mitre.org +# RFC1238 || G. Satz || +# RFC1239 || J.K. Reynolds || jkrey@isi.edu +# RFC1240 || C. Shue, W. Haggerty, K. Dobbins || chi@osf.org, bill@comm.wang.com +# RFC1241 || R.A. Woodburn, D.L. Mills || woody@cseic.saic.com, mills@udel.edu +# RFC1242 || S. Bradner || SOB@HARVARD.HARVARD.EDU +# RFC1243 || S. Waldbusser || waldbusser@andrew.cmu.edu +# RFC1244 || J.P. Holbrook, J.K. Reynolds || holbrook@cic.net, JKREY@ISI.EDU +# RFC1245 || J. Moy || +# RFC1246 || J. Moy || +# RFC1247 || J. Moy || jmoy@proteon.com +# RFC1248 || F. Baker, R. Coltun || fbaker@acc.com, rcoltun@ni.umd.edu +# RFC1249 || T. Howes, M. Smith, B. Beecher || tim@umich.edu, mcs@umich.edu, bryan@umich.edu +# RFC1250 || J. Postel || +# RFC1251 || G. Malkin || gmalkin@ftp.com +# RFC1252 || F. Baker, R. Coltun || fbaker@acc.com, rcoltun@ni.umd.edu +# RFC1253 || F. Baker, R. Coltun || fbaker@acc.com, rcoltun@ni.umd.edu +# RFC1254 || A. Mankin, K. Ramakrishnan || +# RFC1255 || The North American Directory Forum || +# RFC1256 || S. Deering, Ed. || deering@xerox.com +# RFC1257 || C. Partridge || craig@SICS.SE +# RFC1258 || B. Kantor || brian@UCSD.EDU +# RFC1259 || M. Kapor || mkapor@eff.org +# RFC1260 || || +# RFC1261 || S. Williamson, L. Nobile || scottw@DIIS.DDN.MIL +# RFC1262 || V.G. Cerf || +# RFC1263 || S. O'Malley, L.L. Peterson || llp@cs.arizona.edu, sean@cs.arizona.edu +# RFC1264 || R.M. Hinden || bob.hinden@gmail.com +# RFC1265 || Y. Rekhter || yakov@watson.ibm.com +# RFC1266 || Y. Rekhter || yakov@watson.ibm.com +# RFC1267 || K. Lougheed, Y. Rekhter || +# RFC1268 || Y. Rekhter, P. Gross || yakov@watson.ibm.com +# RFC1269 || S. Willis, J.W. Burruss || +# RFC1270 || F. Kastenholz || +# RFC1271 || S. Waldbusser || waldbusser@andrew.cmu.edu +# RFC1272 || C. Mills, D. Hirsh, G.R. Ruth || +# RFC1273 || M.F. Schwartz || schwartz@cs.colorado.edu +# RFC1274 || P. Barker, S. Kille || P.Barker@cs.ucl.ac.uk, S.Kille@cs.ucl.ac.uk +# RFC1275 || S.E. Hardcastle-Kille || S.Kille@CS.UCL.AC.UK +# RFC1276 || S.E. Hardcastle-Kille || S.Kille@CS.UCL.AC.UK +# RFC1277 || S.E. Hardcastle-Kille || S.Kille@CS.UCL.AC.UK +# RFC1278 || S.E. Hardcastle-Kille || S.Kille@CS.UCL.AC.UK +# RFC1279 || S.E. Hardcastle-Kille || S.Kille@CS.UCL.AC.UK +# RFC1280 || J. Postel || +# RFC1281 || R. Pethia, S. Crocker, B. Fraser || rdp@cert.sei.cmu.edu, crocker@tis.com, byf@cert.sei.cmu.edu +# RFC1282 || B. Kantor || brian@UCSD.EDU +# RFC1283 || M. Rose || +# RFC1284 || J. Cook, Ed. || kasten@europa.clearpoint.com +# RFC1285 || J. Case || case@CS.UTK.EDU +# RFC1286 || E. Decker, P. Langille, A. Rijsinghani, K. McCloghrie || langille@edwin.enet.dec.com, anil@levers.enet.dec.com, kzm@hls.com +# RFC1287 || D. Clark, L. Chapin, V. Cerf, R. Braden, R. Hobby || ddc@LCS.MIT.EDU, vcerf@nri.reston.va.us, lyman@BBN.COM, braden@isi.edu, rdhobby@ucdavis.edu +# RFC1288 || D. Zimmerman || dpz@dimacs.rutgers.edu +# RFC1289 || J. Saperia || saperia@enet.dec.com +# RFC1290 || J. Martin || jmartin@magnus.acs.ohio-state.edu +# RFC1291 || V. Aggarwal || +# RFC1292 || R. Lang, R. Wright || +# RFC1293 || T. Bradley, C. Brown || +# RFC1294 || T. Bradley, C. Brown, A. Malis || +# RFC1295 || The North American Directory Forum || 0004454742@mcimail.com +# RFC1296 || M. Lottor || mkl@nisc.sri.com +# RFC1297 || D. Johnson || +# RFC1298 || R. Wormley, S. Bostock || bwormley@novell.com, steveb@novell.com +# RFC1299 || M. Kennedy || MKENNEDY@ISI.EDU +# RFC1300 || S. Greenfield || 0004689513@mcimail.com +# RFC1301 || S. Armstrong, A. Freier, K. Marzullo || armstrong@wrc.xerox.com, freier@apple.com, marzullo@cs.cornell.edu +# RFC1302 || D. Sitzler, P. Smith, A. Marine || +# RFC1303 || K. McCloghrie, M. Rose || kzm@hls.com, mrose17@gmail.com +# RFC1304 || T. Cox, Ed., K. Tesink, Ed. || tacox@sabre.bellcore.com, kaj@nvuxr.cc.bellcore.com +# RFC1305 || D. Mills || +# RFC1306 || A. Nicholson, J. Young || droid@cray.com, jsy@cray.com +# RFC1307 || J. Young, A. Nicholson || jsy@cray.com, droid@cray.com +# RFC1308 || C. Weider, J. Reynolds || +# RFC1309 || C. Weider, J. Reynolds, S. Heker || jkrey@isi.edu +# RFC1310 || L. Chapin || +# RFC1311 || J. Postel || +# RFC1312 || R. Nelson, G. Arnold || nelson@crynwr.com, geoff@east.sun.com +# RFC1313 || C. Partridge || craig@aland.bbn.com +# RFC1314 || A. Katz, D. Cohen || Katz@ISI.Edu, Cohen@ISI.Edu +# RFC1315 || C. Brown, F. Baker, C. Carvalho || cbrown@wellfleet.com, fbaker@acc.com, charles@acc.com +# RFC1316 || B. Stewart || rlstewart@eng.xyplex.com +# RFC1317 || B. Stewart || rlstewart@eng.xyplex.com +# RFC1318 || B. Stewart || rlstewart@eng.xyplex.com +# RFC1319 || B. Kaliski || burt@rsa.com +# RFC1320 || R. Rivest || rivest@theory.lcs.mit.edu +# RFC1321 || R. Rivest || rivest@theory.lcs.mit.edu +# RFC1322 || D. Estrin, Y. Rekhter, S. Hotz || estrin@usc.edu, yakov@ibm.com, hotz@usc.edu +# RFC1323 || V. Jacobson, R. Braden, D. Borman || van@CSAM.LBL.GOV, Braden@ISI.EDU +# RFC1324 || D. Reed || +# RFC1325 || G. Malkin, A. Marine || gmalkin@Xylogics.COM, april@nisc.sri.com +# RFC1326 || P. Tsuchiya || tsuchiya@thumper.bellcore.com +# RFC1327 || S. Hardcastle-Kille || +# RFC1328 || S. Hardcastle-Kille || S.Kille@CS.UCL.AC.UK +# RFC1329 || P. Kuehn || thimmela@sniabg.wa.sni.de +# RFC1330 || ESCC X.500/X.400 Task Force, ESnet Site Coordinating Comittee (ESCC), Energy Sciences Network (ESnet) || +# RFC1331 || W. Simpson || bsimpson@ray.lloyd.com +# RFC1332 || G. McGregor || Glenn.McGregor@Merit.edu +# RFC1333 || W. Simpson || bsimpson@ray.lloyd.com +# RFC1334 || B. Lloyd, W. Simpson || Bill.Simpson@um.cc.umich.edu +# RFC1335 || Z. Wang, J. Crowcroft || z.wang@cs.ucl.ac.uk, j.crowcroft@cs.ucl.ac.uk +# RFC1336 || G. Malkin || gmalkin@Xylogics.COM +# RFC1337 || R. Braden || Braden@ISI.EDU +# RFC1338 || V. Fuller, T. Li, J. Yu, K. Varadhan || +# RFC1339 || S. Dorner, P. Resnick || s-dorner@uiuc.edu, presnick@qti.qualcomm.com +# RFC1340 || J. Reynolds, J. Postel || +# RFC1341 || N. Borenstein, N. Freed || +# RFC1342 || K. Moore || moore@cs.utk.edu +# RFC1343 || N. Borenstein || +# RFC1344 || N. Borenstein || +# RFC1345 || K. Simonsen || +# RFC1346 || P. Jones || +# RFC1347 || R. Callon || +# RFC1348 || B. Manning || bmanning@rice.edu +# RFC1349 || P. Almquist || +# RFC1350 || K. Sollins || SOLLINS@LCS.MIT.EDU +# RFC1351 || J. Davin, J. Galvin, K. McCloghrie || jrd@ptt.lcs.mit.edu, galvin@tis.com, kzm@hls.com +# RFC1352 || J. Galvin, K. McCloghrie, J. Davin || galvin@tis.com, kzm@hls.com, jrd@ptt.lcs.mit.edu +# RFC1353 || K. McCloghrie, J. Davin, J. Galvin || kzm@hls.com, jrd@ptt.lcs.mit.edu, galvin@tis.com +# RFC1354 || F. Baker || fbaker@acc.com +# RFC1355 || J. Curran, A. Marine || jcurran@nnsc.nsf.net, april@nisc.sri.com +# RFC1356 || A. Malis, D. Robinson, R. Ullmann || +# RFC1357 || D. Cohen || Cohen@ISI.EDU +# RFC1358 || L. Chapin || lyman@BBN.COM +# RFC1359 || ACM SIGUCCS || martyne@nr-tech.cit.cornell.edu +# RFC1360 || J. Postel || +# RFC1361 || D. Mills || mills@udel.edu +# RFC1362 || M. Allen || MALLEN@NOVELL.COM, brian@ray.lloyd.com +# RFC1363 || C. Partridge || craig@aland.bbn.com +# RFC1364 || K. Varadhan || kannan@oar.net +# RFC1365 || K. Siyan || 72550.1634@compuserve.com +# RFC1366 || E. Gerich || epg@MERIT.EDU +# RFC1367 || C. Topolcic || topolcic@NRI.Reston.VA.US +# RFC1368 || D. McMaster, K. McCloghrie || mcmaster@synoptics.com, kzm@hls.com +# RFC1369 || F. Kastenholz || kasten@ftp.com +# RFC1370 || Internet Architecture Board, L. Chapin || +# RFC1371 || P. Gross || pgross@ans.net +# RFC1372 || C. Hedrick, D. Borman || +# RFC1373 || T. Tignor || tpt2@isi.edu +# RFC1374 || J. Renwick, A. Nicholson || jkr@CRAY.COM, droid@CRAY.COM +# RFC1375 || P. Robinson || +# RFC1376 || S. Senum || sjs@network.com +# RFC1377 || D. Katz || dkatz@cisco.com +# RFC1378 || B. Parker || brad@cayman.com +# RFC1379 || R. Braden || Braden@ISI.EDU +# RFC1380 || P. Gross, P. Almquist || pgross@ans.net, Almquist@JESSICA.STANFORD.EDU +# RFC1381 || D. Throop, F. Baker || throop@dg-rtp.dg.com, fbaker@acc.com +# RFC1382 || D. Throop, Ed. || throop@dg-rtp.dg.com +# RFC1383 || C. Huitema || Christian.Huitema@MIRSA.INRIA.FR +# RFC1384 || P. Barker, S.E. Hardcastle-Kille || P.Barker@CS.UCL.AC.UK, S.Kille@ISODE.COM +# RFC1385 || Z. Wang || z.wang@cs.ucl.ac.uk +# RFC1386 || A. Cooper, J. Postel || +# RFC1387 || G. Malkin || gmalkin@Xylogics.COM +# RFC1388 || G. Malkin || gmalkin@Xylogics.COM +# RFC1389 || G. Malkin, F. Baker || gmalkin@Xylogics.COM, fbaker@acc.com +# RFC1390 || D. Katz || dkatz@cisco.com +# RFC1391 || G. Malkin || gmalkin@Xylogics.COM +# RFC1392 || G. Malkin, T. LaQuey Parker || gmalkin@Xylogics.COM, tracy@utexas.edu +# RFC1393 || G. Malkin || gmalkin@Xylogics.COM +# RFC1394 || P. Robinson || +# RFC1395 || J. Reynolds || jkrey@isi.edu +# RFC1396 || S. Crocker || +# RFC1397 || D. Haskin || +# RFC1398 || F. Kastenholz || kasten@ftp.com +# RFC1399 || J. Elliott || elliott@isi.edu +# RFC1400 || S. Williamson || scottw@internic.net +# RFC1401 || Internet Architecture Board || +# RFC1402 || J. Martin || nic@osu.edu +# RFC1403 || K. Varadhan || +# RFC1404 || B. Stockman || +# RFC1405 || C. Allocchio || Claudio.Allocchio@elettra.Trieste.it +# RFC1406 || F. Baker, Ed., J. Watt, Ed. || fbaker@acc.com, james@newbridge.com +# RFC1407 || T. Cox, K. Tesink || tacox@mail.bellcore.com, kaj@cc.bellcore.com +# RFC1408 || D. Borman, Ed. || dab@CRAY.COM, stevea@isc.com +# RFC1409 || D. Borman, Ed. || dab@CRAY.COM, stevea@isc.com +# RFC1410 || J. Postel, Ed. || +# RFC1411 || D. Borman, Ed. || dab@CRAY.COM, stevea@isc.com +# RFC1412 || K. Alagappan || kannan@sejour.lkg.dec.com, stevea@isc.com +# RFC1413 || M. St. Johns || stjohns@DARPA.MIL +# RFC1414 || M. St. Johns, M. Rose || stjohns@DARPA.MIL, mrose17@gmail.com +# RFC1415 || J. Mindel, R. Slaski || +# RFC1416 || D. Borman, Ed. || dab@CRAY.COM, stevea@isc.com +# RFC1417 || The North American Directory Forum || 0004454742@mcimail.com +# RFC1418 || M. Rose || mrose17@gmail.com +# RFC1419 || G. Minshall, M. Ritter || minshall@wc.novell.com, MWRITTER@applelink.apple.com +# RFC1420 || S. Bostock || +# RFC1421 || J. Linn || 104-8456@mcimail.com +# RFC1422 || S. Kent || kent@BBN.COM +# RFC1423 || D. Balenson || balenson@tis.com +# RFC1424 || B. Kaliski || burt@rsa.com +# RFC1425 || J. Klensin, WG Chair, N. Freed, Ed., M. Rose, E. Stefferud, D. Crocker || +# RFC1426 || J. Klensin, WG Chair, N. Freed, Ed., M. Rose, E. Stefferud, D. Crocker || +# RFC1427 || J. Klensin, WG Chair, N. Freed, Ed., K. Moore || +# RFC1428 || G. Vaudreuil || GVaudre@CNRI.Reston.VA.US +# RFC1429 || E. Thomas || +# RFC1430 || S. Hardcastle-Kille, E. Huizer, V. Cerf, R. Hobby, S. Kent || S.Kille@isode.com, vcerf@cnri.reston.va.us, rdhobby@ucdavis.edu, skent@bbn.com +# RFC1431 || P. Barker || +# RFC1432 || J. Quarterman || jsq@tic.com, mids@tic.com +# RFC1433 || J. Garrett, J. Hagan, J. Wong || jwg@garage.att.com, Hagan@UPENN.EDU, jwong@garage.att.com +# RFC1434 || R. Dixon, D. Kushi || rcdixon@ralvmg.vnet.ibm.com, kushi@watson.ibm.com +# RFC1435 || S. Knowles || stev@ftp.com +# RFC1436 || F. Anklesaria, M. McCahill, P. Lindner, D. Johnson, D. Torrey, B. Albert || fxa@boombox.micro.umn.edu, mpm@boombox.micro.umn.edu, lindner@boombox.micro.umn.edu, dmj@boombox.micro.umn.edu, daniel@boombox.micro.umn.edu, alberti@boombox.micro.umn.edu +# RFC1437 || N. Borenstein, M. Linimon || nsb@bellcore.com, linimon@LONESOME.COM +# RFC1438 || A. Lyman Chapin, C. Huitema || Lyman@BBN.COM, Christian.Huitema@MIRSA.INRIA.FR +# RFC1439 || C. Finseth || Craig.A.Finseth-1@umn.edu +# RFC1440 || R. Troth || troth@rice.edu +# RFC1441 || J. Case, K. McCloghrie, M. Rose, S. Waldbusser || +# RFC1442 || J. Case, K. McCloghrie, M. Rose, S. Waldbusser || +# RFC1443 || J. Case, K. McCloghrie, M. Rose, S. Waldbusser || +# RFC1444 || J. Case, K. McCloghrie, M. Rose, S. Waldbusser || +# RFC1445 || J. Galvin, K. McCloghrie || galvin@tis.com +# RFC1446 || J. Galvin, K. McCloghrie || galvin@tis.com +# RFC1447 || K. McCloghrie, J. Galvin || galvin@tis.com +# RFC1448 || J. Case, K. McCloghrie, M. Rose, S. Waldbusser || +# RFC1449 || J. Case, K. McCloghrie, M. Rose, S. Waldbusser || +# RFC1450 || J. Case, K. McCloghrie, M. Rose, S. Waldbusser || +# RFC1451 || J. Case, K. McCloghrie, M. Rose, S. Waldbusser || +# RFC1452 || J. Case, K. McCloghrie, M. Rose, S. Waldbusser || +# RFC1453 || W. Chimiak || chim@relito.medeng.wfu.edu +# RFC1454 || T. Dixon || dixon@rare.nl +# RFC1455 || D. Eastlake 3rd || +# RFC1456 || Vietnamese Standardization Working Group || +# RFC1457 || R. Housley || Housley.McLean_CSD@Xerox.COM +# RFC1458 || R. Braudes, S. Zabele || rebraudes@tasc.com, gszabele@tasc.com +# RFC1459 || J. Oikarinen, D. Reed || +# RFC1460 || M. Rose || mrose17@gmail.com +# RFC1461 || D. Throop || throop@dg-rtp.dg.com +# RFC1462 || E. Krol, E. Hoffman || e-krol@uiuc.edu, ellen@merit.edu +# RFC1463 || E. Hoffman, L. Jackson || +# RFC1464 || R. Rosenbaum || +# RFC1465 || D. Eppenberger || Eppenberger@switch.ch +# RFC1466 || E. Gerich || epg@MERIT.EDU +# RFC1467 || C. Topolcic || topolcic@CNRI.Reston.VA.US +# RFC1468 || J. Murai, M. Crispin, E. van der Poel || jun@wide.ad.jp, MRC@PANDA.COM, erik@poel.juice.or.jp +# RFC1469 || T. Pusateri || pusateri@cs.duke.edu +# RFC1470 || R. Enger, J. Reynolds || enger@reston.ans.net +# RFC1471 || F. Kastenholz || kasten@ftp.com +# RFC1472 || F. Kastenholz || kasten@ftp.com +# RFC1473 || F. Kastenholz || kasten@ftp.com +# RFC1474 || F. Kastenholz || kasten@ftp.com +# RFC1475 || R. Ullmann || +# RFC1476 || R. Ullmann || +# RFC1477 || M. Steenstrup || +# RFC1478 || M. Steenstrup || +# RFC1479 || M. Steenstrup || +# RFC1480 || A. Cooper, J. Postel || +# RFC1481 || C. Huitema || Christian.Huitema@MIRSA.INRIA.FR +# RFC1482 || M. Knopper, S. Richardson || +# RFC1483 || Juha Heinanen || +# RFC1484 || S. Hardcastle-Kille || S.Kille@ISODE.COM +# RFC1485 || S. Hardcastle-Kille || S.Kille@ISODE.COM +# RFC1486 || M. Rose, C. Malamud || mrose17@gmail.com, carl@malamud.com +# RFC1487 || W. Yeong, T. Howes, S. Kille || yeongw@psilink.com, tim@umich.edu, S.Kille@isode.com +# RFC1488 || T. Howes, S. Kille, W. Yeong, C. Robbins || tim@umich.edu, S.Kille@isode.com, yeongw@psilink.com +# RFC1489 || A. Chernov || ache@astral.msk.su +# RFC1490 || T. Bradley, C. Brown, A. Malis || +# RFC1491 || C. Weider, R. Wright || clw@merit.edu, wright@lbl.gov +# RFC1492 || C. Finseth || Craig.A.Finseth-1@umn.edu +# RFC1493 || E. Decker, P. Langille, A. Rijsinghani, K. McCloghrie || langille@edwin.enet.dec.com, anil@levers.enet.dec.com, kzm@hls.com +# RFC1494 || H. Alvestrand, S. Thompson || Harald.Alvestrand@delab.sintef.no, sjt@gateway.ssw.com +# RFC1495 || H. Alvestrand, S. Kille, R. Miles, M. Rose, S. Thompson || Harald.Alvestrand@delab.sintef.no, S.Kille@ISODE.COM, rsm@spyder.ssw.com, mrose17@gmail.com, sjt@gateway.ssw.com +# RFC1496 || H. Alvestrand, J. Romaguera, K. Jordan || Harald.T.Alvestrand@delab.sintef.no, Kevin.E.Jordan@mercury.oss.arh.cpg.cdc.com, Romaguera@netconsult.ch +# RFC1497 || J. Reynolds || jkrey@isi.edu +# RFC1498 || J. Saltzer || Saltzer@MIT.EDU +# RFC1499 || J. Elliott || elliott@isi.edu +# RFC1500 || J. Postel || +# RFC1501 || E. Brunsen || BRUNSENE@EMAIL.ENMU.EDU +# RFC1502 || H. Alvestrand || Harald.Alvestrand@delab.sintef.no +# RFC1503 || K. McCloghrie, M. Rose || kzm@hls.com, mrose17@gmail.com +# RFC1504 || A. Oppenheimer || Oppenheime1@applelink.apple.com +# RFC1505 || A. Costanzo, D. Robinson, R. Ullmann || +# RFC1506 || J. Houttuin || +# RFC1507 || C. Kaufman || +# RFC1508 || J. Linn || +# RFC1509 || J. Wray || Wray@tuxedo.enet.dec.com +# RFC1510 || J. Kohl, C. Neuman || jtkohl@zk3.dec.com, bcn@isi.edu +# RFC1511 || J. Linn || +# RFC1512 || J. Case, A. Rijsinghani || case@CS.UTK.EDU, anil@levers.enet.dec.com +# RFC1513 || S. Waldbusser || waldbusser@cmu.edu +# RFC1514 || P. Grillo, S. Waldbusser || pl0143@mail.psi.net, waldbusser@cmu.edu +# RFC1515 || D. McMaster, K. McCloghrie, S. Roberts || mcmaster@synoptics.com, kzm@hls.com, sroberts@farallon.com +# RFC1516 || D. McMaster, K. McCloghrie || mcmaster@synoptics.com, kzm@hls.com +# RFC1517 || Internet Engineering Steering Group, R. Hinden || bob.hinden@gmail.com +# RFC1518 || Y. Rekhter, T. Li || yakov@watson.ibm.com, tli@cisco.com +# RFC1519 || V. Fuller, T. Li, J. Yu, K. Varadhan || vaf@Stanford.EDU, tli@cisco.com, jyy@merit.edu, kannan@oar.net +# RFC1520 || Y. Rekhter, C. Topolcic || yakov@watson.ibm.com, topolcic@CNRI.Reston.VA.US +# RFC1521 || N. Borenstein, N. Freed || gvaudre@cnri.reston.va.us +# RFC1522 || K. Moore || moore@cs.utk.edu +# RFC1523 || N. Borenstein || nsb@bellcore.com +# RFC1524 || N. Borenstein || nsb@bellcore.com +# RFC1525 || E. Decker, K. McCloghrie, P. Langille, A. Rijsinghani || kzm@hls.com, langille@edwin.enet.dec.com, anil@levers.enet.dec.com +# RFC1526 || D. Piscitello || dave@mail.bellcore.com +# RFC1527 || G. Cook || cook@path.net +# RFC1528 || C. Malamud, M. Rose || +# RFC1529 || C. Malamud, M. Rose || +# RFC1530 || C. Malamud, M. Rose || +# RFC1531 || R. Droms || droms@bucknell.edu +# RFC1532 || W. Wimer || Walter.Wimer@CMU.EDU +# RFC1533 || S. Alexander, R. Droms || stevea@lachman.com, droms@bucknell.edu +# RFC1534 || R. Droms || droms@bucknell.edu +# RFC1535 || E. Gavron || gavron@aces.com +# RFC1536 || A. Kumar, J. Postel, C. Neuman, P. Danzig, S. Miller || anant@isi.edu, postel@isi.edu, bcn@isi.edu, danzig@caldera.usc.edu, smiller@caldera.usc.edu +# RFC1537 || P. Beertema || Piet.Beertema@cwi.nl, anant@isi.edu +# RFC1538 || W. Behl, B. Sterling, W. Teskey || +# RFC1539 || G. Malkin || gmalkin@Xylogics.COM +# RFC1540 || J. Postel || +# RFC1541 || R. Droms || droms@bucknell.edu +# RFC1542 || W. Wimer || Walter.Wimer@CMU.EDU +# RFC1543 || J. Postel || Postel@ISI.EDU, dwaitzman@BBN.COM +# RFC1544 || M. Rose || mrose17@gmail.com +# RFC1545 || D. Piscitello || dave@mail.bellcore.com +# RFC1546 || C. Partridge, T. Mendez, W. Milliken || craig@bbn.com, tmendez@bbn.com, milliken@bbn.com +# RFC1547 || D. Perkins || Bill.Simpson@um.cc.umich.edu +# RFC1548 || W. Simpson || +# RFC1549 || W. Simpson, Ed. || +# RFC1550 || S. Bradner, A. Mankin || sob@harvard.edu, mankin@cmf.nrl.navy.mil +# RFC1551 || M. Allen || mallen@novell.com, fbaker@acc.com +# RFC1552 || W. Simpson || Bill.Simpson@um.cc.umich.edu +# RFC1553 || S. Mathur, M. Lewis || mathur@telebit.com, Mark.S.Lewis@telebit.com +# RFC1554 || M. Ohta, K. Handa || mohta@cc.titech.ac.jp, handa@etl.go.jp +# RFC1555 || H. Nussbacher, Y. Bourvine || hank@vm.tau.ac.il, yehavi@vms.huji.ac.il +# RFC1556 || H. Nussbacher || hank@vm.tau.ac.il +# RFC1557 || U. Choi, K. Chon, H. Park || uhhyung@kaist.ac.kr, chon@cosmos.kaist.ac.kr, hjpark@dino.media.co.kr +# RFC1558 || T. Howes || tim@umich.edu +# RFC1559 || J. Saperia || saperia@tay.dec.com +# RFC1560 || B. Leiner, Y. Rekhter || leiner@nsipo.nasa.gov, yakov@watson.ibm.com +# RFC1561 || D. Piscitello || wk04464@worldlink.com +# RFC1562 || G. Michaelson, M. Prior || G.Michaelson@cc.uq.oz.au, mrp@itd.adelaide.edu.au +# RFC1563 || N. Borenstein || nsb@bellcore.com +# RFC1564 || P. Barker, R. Hedberg || P.Barker@cs.ucl.ac.uk, Roland.Hedberg@rc.tudelft.nl, Roland.Hedberg@umdac.umu.se +# RFC1565 || S. Kille, N. Freed || S.Kille@isode.com, ned@innosoft.com +# RFC1566 || S. Kille, N. Freed || S.Kille@isode.com, ned@innosoft.com +# RFC1567 || G. Mansfield, S. Kille || glenn@aic.co.jp, S.Kille@isode.com +# RFC1568 || A. Gwinn || allen@mail.cox.smu.edu +# RFC1569 || M. Rose || mrose17@gmail.com +# RFC1570 || W. Simpson, Ed. || +# RFC1571 || D. Borman || dab@CRAY.COM +# RFC1572 || S. Alexander, Ed. || +# RFC1573 || K. McCloghrie, F. Kastenholz || kzm@hls.com, kasten@ftp.com +# RFC1574 || S. Hares, C. Wittbrodt || skh@merit.edu, cjw@magnolia.Stanford.EDU +# RFC1575 || S. Hares, C. Wittbrodt || skh@merit.edu, cjw@magnolia.Stanford.EDU +# RFC1576 || J. Penner || jjp@bscs.com +# RFC1577 || M. Laubach || laubach@hpl.hp.com +# RFC1578 || J. Sellers || sellers@quest.arc.nasa.gov +# RFC1579 || S. Bellovin || smb@research.att.com +# RFC1580 || EARN Staff || earndoc@earncc.earn.net +# RFC1581 || G. Meyer || gerry@spider.co.uk +# RFC1582 || G. Meyer || gerry@spider.co.uk +# RFC1583 || J. Moy || +# RFC1584 || J. Moy || +# RFC1585 || J. Moy || jmoy@proteon.com +# RFC1586 || O. deSouza, M. Rodrigues || osmund.desouza@att.com, manoel.rodrigues@att.com +# RFC1587 || R. Coltun, V. Fuller || rcoltun@rainbow-bridge.com, vaf@Valinor.Stanford.EDU +# RFC1588 || J. Postel, C. Anderson || +# RFC1589 || D. Mills || mills@udel.edu +# RFC1590 || J. Postel || Postel@ISI.EDU +# RFC1591 || J. Postel || Postel@ISI.EDU +# RFC1592 || B. Wijnen, G. Carpenter, K. Curran, A. Sehgal, G. Waters || +# RFC1593 || W. McKenzie, J. Cheng || mckenzie@ralvma.vnet.ibm.com, cheng@ralvm6.vnet.ibm.com +# RFC1594 || A. Marine, J. Reynolds, G. Malkin || amarine@atlas.arc.nasa.gov, jkrey@isi.edu, gmalkin@Xylogics.COM +# RFC1595 || T. Brown, K. Tesink || tacox@mail.bellcore.com, kaj@cc.bellcore.com +# RFC1596 || T. Brown, Ed. || tacox@mail.bellcore.com +# RFC1597 || Y. Rekhter, B. Moskowitz, D. Karrenberg, G. de Groot || yakov@watson.ibm.com, 3858921@mcimail.com, Daniel.Karrenberg@ripe.net, GeertJan.deGroot@ripe.net +# RFC1598 || W. Simpson || Bill.Simpson@um.cc.umich.edu +# RFC1599 || M. Kennedy || MKENNEDY@ISI.EDU +# RFC1600 || J. Postel || +# RFC1601 || C. Huitema || Christian.Huitema@sophia.inria.fr +# RFC1602 || Internet Architecture Board, Internet Engineering Steering Group || Christian.Huitema@MIRSA.INRIA.FR, 0006423401@mcimail.com +# RFC1603 || E. Huizer, D. Crocker || +# RFC1604 || T. Brown, Ed. || tacox@mail.bellcore.com +# RFC1605 || W. Shakespeare || +# RFC1606 || J. Onions || j.onions@nexor.co.uk +# RFC1607 || V. Cerf || vcerf@isoc.org, vinton_cerf@mcimail.com +# RFC1608 || T. Johannsen, G. Mansfield, M. Kosters, S. Sataluri || Thomas.Johannsen@ifn.et.tu-dresden.de, glenn@aic.co.jp, markk@internic.net, sri@qsun.att.com +# RFC1609 || G. Mansfield, T. Johannsen, M. Knopper || glenn@aic.co.jp, Thomas.Johannsen@ifn.et.tu-dresden.de, mak@merit.edu +# RFC1610 || J. Postel || +# RFC1611 || R. Austein, J. Saperia || sra@epilogue.com, saperia@zko.dec.com +# RFC1612 || R. Austein, J. Saperia || sra@epilogue.com, saperia@zko.dec.com +# RFC1613 || J. Forster, G. Satz, G. Glick, R. Day || forster@cisco.com, satz@cisco.com, gglick@cisco.com, R.Day@jnt.ac.uk +# RFC1614 || C. Adie || C.J.Adie@edinburgh.ac.uk +# RFC1615 || J. Houttuin, J. Craigie || +# RFC1616 || RARE WG-MSG Task Force 88, E. Huizer, Ed., J. Romaguera, Ed. || +# RFC1617 || P. Barker, S. Kille, T. Lenggenhager || p.barker@cs.ucl.ac.uk, s.kille@isode.com, lenggenhager@switch.ch +# RFC1618 || W. Simpson || Bill.Simpson@um.cc.umich.edu +# RFC1619 || W. Simpson || Bill.Simpson@um.cc.umich.edu +# RFC1620 || B. Braden, J. Postel, Y. Rekhter || Braden@ISI.EDU, Postel@ISI.EDU, Yakov@WATSON.IBM.COM +# RFC1621 || P. Francis || francis@cactus.ntt.jp +# RFC1622 || P. Francis || francis@cactus.ntt.jp +# RFC1623 || F. Kastenholz || kasten@ftp.com +# RFC1624 || A. Rijsinghani, Ed. || anil@levers.enet.dec.com +# RFC1625 || M. St. Pierre, J. Fullton, K. Gamiel, J. Goldman, B. Kahle, J. Kunze, H. Morris, F. Schiettecatte || saint@wais.com, jim.fullton@cnidr.org, kevin.gamiel@cnidr.org, jonathan@think.com, brewster@wais.com, jak@violet.berkeley.edu, morris@wais.com, francois@wais.com +# RFC1626 || R. Atkinson || atkinson@itd.nrl.navy.mil +# RFC1627 || E. Lear, E. Fair, D. Crocker, T. Kessler || +# RFC1628 || J. Case, Ed. || case@SNMP.COM +# RFC1629 || R. Colella, R. Callon, E. Gardner, Y. Rekhter || colella@nist.gov, callon@wellfleet.com, epg@gateway.mitre.org, yakov@watson.ibm.com +# RFC1630 || T. Berners-Lee || timbl@info.cern.ch +# RFC1631 || K. Egevang, P. Francis || kbe@craycom.dk, francis@cactus.ntt.jp +# RFC1632 || A. Getchell, Ed., S. Sataluri, Ed. || +# RFC1633 || R. Braden, D. Clark, S. Shenker || Braden@ISI.EDU, ddc@LCS.MIT.EDU, Shenker@PARC.XEROX.COM +# RFC1634 || M. Allen || mallen@novell.com, fbaker@acc.com +# RFC1635 || P. Deutsch, A. Emtage, A. Marine || peterd@bunyip.com, bajan@bunyip.com, amarine@atlas.arc.nasa.gov +# RFC1636 || R. Braden, D. Clark, S. Crocker, C. Huitema || Braden@ISI.EDU, ddc@lcs.mit.edu, crocker@tis.com, Christian.Huitema@MIRSA.INRIA.FR +# RFC1637 || B. Manning, R. Colella || bmanning@rice.edu, colella@nist.gov +# RFC1638 || F. Baker, R. Bowen || Rich_Bowen@vnet.ibm.com +# RFC1639 || D. Piscitello || dave@corecom.com +# RFC1640 || S. Crocker || crocker@TIS.COM +# RFC1641 || D. Goldsmith, M. Davis || david_goldsmith@taligent.com, mark_davis@taligent.com +# RFC1642 || D. Goldsmith, M. Davis || david_goldsmith@taligent.com, mark_davis@taligent.com +# RFC1643 || F. Kastenholz || kasten@ftp.com +# RFC1644 || R. Braden || Braden@ISI.EDU +# RFC1645 || A. Gwinn || allen@mail.cox.smu.edu +# RFC1646 || C. Graves, T. Butts, M. Angel || cvg@oc.com, tom@oc.com, angel@oc.com +# RFC1647 || B. Kelly || kellywh@mail.auburn.edu +# RFC1648 || A. Cargille || +# RFC1649 || R. Hagens, A. Hansen || hagens@ans.net, Alf.Hansen@uninett.no +# RFC1650 || F. Kastenholz || kasten@ftp.com +# RFC1651 || J. Klensin, N. Freed, M. Rose, E. Stefferud, D. Crocker || klensin@mci.net, ned@innosoft.com, mrose17@gmail.com, stef@nma.com, dcrocker@sgi.com +# RFC1652 || J. Klensin, N. Freed, M. Rose, E. Stefferud, D. Crocker || klensin@mci.net, ned@innosoft.com, mrose17@gmail.com, stef@nma.com, dcrocker@sgi.com +# RFC1653 || J. Klensin, N. Freed, K. Moore || klensin@mci.net, ned@innosoft.com, moore@cs.utk.edu +# RFC1654 || Y. Rekhter, Ed., T. Li, Ed. || +# RFC1655 || Y. Rekhter, Ed., P. Gross, Ed. || yakov@watson.ibm.com, 0006423401@mcimail.com +# RFC1656 || P. Traina || pst@cisco.com +# RFC1657 || S. Willis, J. Burruss, J. Chu, Ed. || swillis@wellfleet.com, jburruss@wellfleet.com, jychu@watson.ibm.com +# RFC1658 || B. Stewart || rlstewart@eng.xyplex.com +# RFC1659 || B. Stewart || rlstewart@eng.xyplex.com +# RFC1660 || B. Stewart || rlstewart@eng.xyplex.com +# RFC1661 || W. Simpson, Ed. || +# RFC1662 || W. Simpson, Ed. || +# RFC1663 || D. Rand || dave_rand@novell.com +# RFC1664 || C. Allocchio, A. Bonito, B. Cole, S. Giordano, R. Hagens || +# RFC1665 || Z. Kielczewski, Ed., D. Kostick, Ed., K. Shih, Ed. || zbig@eicon.qc.ca, dck2@mail.bellcore.com, kmshih@novell.com +# RFC1666 || Z. Kielczewski, Ed., D. Kostick, Ed., K. Shih, Ed. || zbig@eicon.qc.ca, dck2@mail.bellcore.com, kmshih@novell.com +# RFC1667 || S. Symington, D. Wood, M. Pullen || susan@gateway.mitre.org, wood@mitre.org, mpullen@cs.gmu.edu +# RFC1668 || D. Estrin, T. Li, Y. Rekhter || estrin@usc.edu, tli@cisco.com, yakov@watson.ibm.com +# RFC1669 || J. Curran || jcurran@near.net +# RFC1670 || D. Heagerty || denise@dxcoms.cern.ch +# RFC1671 || B. Carpenter || brian@dxcoms.cern.ch +# RFC1672 || N. Brownlee || n.brownlee@auckland.ac.nz +# RFC1673 || R. Skelton || RSKELTON@msm.epri.com +# RFC1674 || M. Taylor || mark.s.taylor@airdata.com +# RFC1675 || S. Bellovin || smb@research.att.com +# RFC1676 || A. Ghiselli, D. Salomoni, C. Vistoli || Salomoni@infn.it, Vistoli@infn.it, Ghiselli@infn.it +# RFC1677 || B. Adamson || adamson@itd.nrl.navy.mil +# RFC1678 || E. Britton, J. Tavs || brittone@vnet.ibm.com, tavs@vnet.ibm.com +# RFC1679 || D. Green, P. Irey, D. Marlow, K. O'Donoghue || dtgreen@relay.nswc.navy.mil, pirey@relay.nswc.navy.mil, dmarlow@relay.nswc.navy.mil, kodonog@relay.nswc.navy.mil +# RFC1680 || C. Brazdziunas || crb@faline.bellcore.com +# RFC1681 || S. Bellovin || smb@research.att.com +# RFC1682 || J. Bound || bound@zk3.dec.com +# RFC1683 || R. Clark, M. Ammar, K. Calvert || rjc@cc.gatech.edu, ammar@cc.gatech.edu, calvert@cc.gatech.edu +# RFC1684 || P. Jurg || +# RFC1685 || H. Alvestrand || +# RFC1686 || M. Vecchi || mpvecchi@twcable.com +# RFC1687 || E. Fleischman || ericf@atc.boeing.com +# RFC1688 || W. Simpson || Bill.Simpson@um.cc.umich.edu +# RFC1689 || J. Foster, Ed. || +# RFC1690 || G. Huston || Geoff.Huston@aarnet.edu.au +# RFC1691 || W. Turner || wrt1@cornell.edu +# RFC1692 || P. Cameron, D. Crocker, D. Cohen, J. Postel || cameron@xylint.co.uk, dcrocker@sgi.com, Cohen@myricom.com, Postel@ISI.EDU +# RFC1693 || T. Connolly, P. Amer, P. Conrad || connolly@udel.edu, amer@udel.edu, pconrad@udel.edu +# RFC1694 || T. Brown, Ed., K. Tesink, Ed. || tacox@mail.bellcore.com, kaj@cc.bellcore.com +# RFC1695 || M. Ahmed, Ed., K. Tesink, Ed. || mxa@mail.bellcore.com, kaj@cc.bellcore.com +# RFC1696 || J. Barnes, L. Brown, R. Royston, S. Waldbusser || barnes@xylogics.com, brown_l@msm.cdx.mot.com, rroyston@usr.com, swol@andrew.cmu.edu +# RFC1697 || D. Brower, Ed., B. Purvy, A. Daniel, M. Sinykin, J. Smith || daveb@ingres.com, bpurvy@us.oracle.com, anthony@informix.com, msinykin@us.oracle.com, jaysmith@us.oracle.com +# RFC1698 || P. Furniss || P.Furniss@ulcc.ac.uk +# RFC1699 || J. Elliott || elliott@isi.edu +# RFC1700 || J. Reynolds, J. Postel || jkrey@isi.edu, postel@isi.edu +# RFC1701 || S. Hanks, T. Li, D. Farinacci, P. Traina || stan@netsmiths.com, tli@cisco.com, dino@cisco.com, pst@cisco.com +# RFC1702 || S. Hanks, T. Li, D. Farinacci, P. Traina || stan@netsmiths.com, tli@cisco.com, dino@cisco.com, pst@cisco.com +# RFC1703 || M. Rose || mrose17@gmail.com +# RFC1704 || N. Haller, R. Atkinson || +# RFC1705 || R. Carlson, D. Ficarella || RACarlson@anl.gov, ficarell@cpdmfg.cig.mot.com +# RFC1706 || B. Manning, R. Colella || bmanning@isi.edu, colella@nist.gov +# RFC1707 || M. McGovern, R. Ullmann || scrivner@world.std.com, rullmann@crd.lotus.com +# RFC1708 || D. Gowin || drg508@crane-ns.nwscc.sea06.navy.MIL +# RFC1709 || J. Gargano, D. Wasley || jcgargano@ucdavis.edu, dlw@berkeley.edu +# RFC1710 || R. Hinden || bob.hinden@gmail.com +# RFC1711 || J. Houttuin || houttuin@rare.nl +# RFC1712 || C. Farrell, M. Schulze, S. Pleitner, D. Baldoni || craig@cs.curtin.edu.au, mike@cs.curtin.edu.au, pleitner@cs.curtin.edu.au, flint@cs.curtin.edu.au +# RFC1713 || A. Romao || artur@fct.unl.pt +# RFC1714 || S. Williamson, M. Kosters || scottw@internic.net, markk@internic.net +# RFC1715 || C. Huitema || Christian.Huitema@MIRSA.INRIA.FR +# RFC1716 || P. Almquist, F. Kastenholz || +# RFC1717 || K. Sklower, B. Lloyd, G. McGregor, D. Carr || sklower@CS.Berkeley.EDU, brian@lloyd.com, glenn@lloyd.com, dcarr@Newbridge.COM +# RFC1718 || IETF Secretariat, G. Malkin || ietf-info@cnri.reston.va.us, gmalkin@Xylogics.COM +# RFC1719 || P. Gross || phill_gross@mcimail.com +# RFC1720 || J. Postel || +# RFC1721 || G. Malkin || gmalkin@Xylogics.COM +# RFC1722 || G. Malkin || gmalkin@Xylogics.COM +# RFC1723 || G. Malkin || gmalkin@Xylogics.COM +# RFC1724 || G. Malkin, F. Baker || gmalkin@Xylogics.COM, fred@cisco.com +# RFC1725 || J. Myers, M. Rose || mrose17@gmail.com +# RFC1726 || C. Partridge, F. Kastenholz || craig@aland.bbn.com, kasten@ftp.com +# RFC1727 || C. Weider, P. Deutsch || clw@bunyip.com, peterd@bunyip.com +# RFC1728 || C. Weider || clw@bunyip.com +# RFC1729 || C. Lynch || clifford.lynch@ucop.edu +# RFC1730 || M. Crispin || MRC@CAC.Washington.EDU +# RFC1731 || J. Myers || +# RFC1732 || M. Crispin || MRC@CAC.Washington.EDU +# RFC1733 || M. Crispin || MRC@CAC.Washington.EDU +# RFC1734 || J. Myers || +# RFC1735 || J. Heinanen, R. Govindan || Juha.Heinanen@datanet.tele.fi, govindan@isi.edu +# RFC1736 || J. Kunze || jak@violet.berkeley.edu +# RFC1737 || K. Sollins, L. Masinter || masinter@parc.xerox.com, sollins@lcs.mit.edu +# RFC1738 || T. Berners-Lee, L. Masinter, M. McCahill || +# RFC1739 || G. Kessler, S. Shepard || kumquat@hill.com, sds@hill.com +# RFC1740 || P. Faltstrom, D. Crocker, E. Fair || paf@nada.kth.se, dcrocker@mordor.stanford.edu, fair@apple.com +# RFC1741 || P. Faltstrom, D. Crocker, E. Fair || paf@nada.kth.se, dcrocker@mordor.stanford.edu, fair@apple.com +# RFC1742 || S. Waldbusser, K. Frisa || waldbusser@cmu.edu, kfrisa@fore.com +# RFC1743 || K. McCloghrie, E. Decker || kzm@cisco.com, cire@cisco.com +# RFC1744 || G. Huston || Geoff.Huston@aarnet.edu.au +# RFC1745 || K. Varadhan, S. Hares, Y. Rekhter || kannan@isi.edu, skh@merit.edu, yakov@watson.ibm.com +# RFC1746 || B. Manning, D. Perkins || bmanning@isi.edu, dperkins@tenet.edu +# RFC1747 || J. Hilgeman, Chair, S. Nix, A. Bartky, W. Clark, Ed. || jeffh@apertus.com, snix@metaplex.com, alan@sync.com, wclark@cisco.com +# RFC1748 || K. McCloghrie, E. Decker || kzm@cisco.com, cire@cisco.com +# RFC1749 || K. McCloghrie, F. Baker, E. Decker || kzm@cisco.com, fred@cisco.com, cire@cisco.com +# RFC1750 || D. Eastlake 3rd, S. Crocker, J. Schiller || dee@lkg.dec.com, crocker@cybercash.com, jis@mit.edu +# RFC1751 || D. McDonald || danmcd@itd.nrl.navy.mil +# RFC1752 || S. Bradner, A. Mankin || sob@harvard.edu, mankin@isi.edu +# RFC1753 || N. Chiappa || jnc@lcs.mit.edu +# RFC1754 || M. Laubach || laubach@com21.com +# RFC1755 || M. Perez, F. Liaw, A. Mankin, E. Hoffman, D. Grossman, A. Malis || perez@isi.edu, fong@fore.com, mankin@isi.edu, hoffman@isi.edu, dan@merlin.dev.cdx.mot.com, malis@maelstrom.timeplex.com +# RFC1756 || T. Rinne || Timo.Rinne@hut.fi +# RFC1757 || S. Waldbusser || waldbusser@cmu.edu +# RFC1758 || The North American Directory Forum || 0004454742@mcimail.com +# RFC1759 || R. Smith, F. Wright, T. Hastings, S. Zilles, J. Gyllenskog || rlsmith@nb.ppd.ti.com, don@lexmark.com, tom.hastings@alum.mit.edu, szilles@mv.us.adobe.com, jgyllens@hpdmd48.boi.hp.com +# RFC1760 || N. Haller || nmh@bellcore.com +# RFC1761 || B. Callaghan, R. Gilligan || brent.callaghan@eng.sun.com, bob.gilligan@eng.sun.com +# RFC1762 || S. Senum || sjs@digibd.com +# RFC1763 || S. Senum || sjs@digibd.com +# RFC1764 || S. Senum || sjs@digibd.com +# RFC1765 || J. Moy || jmoy@casc.com +# RFC1766 || H. Alvestrand || Harald.T.Alvestrand@uninett.no +# RFC1767 || D. Crocker || +# RFC1768 || D. Marlow || dmarlow@relay.nswc.navy.mil +# RFC1769 || D. Mills || mills@udel.edu +# RFC1770 || C. Graff || bud@fotlan5.fotlan.army.mil +# RFC1771 || Y. Rekhter, T. Li || +# RFC1772 || Y. Rekhter, P. Gross || yakov@watson.ibm.com, 0006423401@mcimail.com +# RFC1773 || P. Traina || pst@cisco.com +# RFC1774 || P. Traina, Ed. || +# RFC1775 || D. Crocker || dcrocker@mordor.stanford.edu +# RFC1776 || S. Crocker || crocker@cybercash.com +# RFC1777 || W. Yeong, T. Howes, S. Kille || yeongw@psilink.com, tim@umich.edu, S.Kille@isode.com +# RFC1778 || T. Howes, S. Kille, W. Yeong, C. Robbins || tim@umich.edu, S.Kille@isode.com, yeongw@psilink.com +# RFC1779 || S. Kille || S.Kille@ISODE.COM +# RFC1780 || J. Postel, Ed. || +# RFC1781 || S. Kille || S.Kille@ISODE.COM +# RFC1782 || G. Malkin, A. Harkin || gmalkin@xylogics.com, ash@cup.hp.com +# RFC1783 || G. Malkin, A. Harkin || gmalkin@xylogics.com, ash@cup.hp.com +# RFC1784 || G. Malkin, A. Harkin || gmalkin@xylogics.com, ash@cup.hp.com +# RFC1785 || G. Malkin, A. Harkin || gmalkin@xylogics.com, ash@cup.hp.com +# RFC1786 || T. Bates, E. Gerich, L. Joncheray, J-M. Jouanigot, D. Karrenberg, M. Terpstra, J. Yu || +# RFC1787 || Y. Rekhter || +# RFC1788 || W. Simpson || +# RFC1789 || C. Yang || cqyang@cs.unt.edu +# RFC1790 || V. Cerf || vcerf@isoc.org +# RFC1791 || T. Sung || tae@novell.Com +# RFC1792 || T. Sung || tae@novell.Com +# RFC1793 || J. Moy || jmoy@casc.com +# RFC1794 || T. Brisco || brisco@rutgers.edu +# RFC1795 || L. Wells, Chair, A. Bartky, Ed. || +# RFC1796 || C. Huitema, J. Postel, S. Crocker || Christian.Huitema@MIRSA.INRIA.FR, Postel@ISI.EDU, crocker@cybercash.com +# RFC1797 || Internet Assigned Numbers Authority (IANA) || iana@isi.edu +# RFC1798 || A. Young || A.Young@isode.com +# RFC1799 || M. Kennedy || MKENNEDY@ISI.EDU +# RFC1800 || J. Postel, Ed. || +# RFC1801 || S. Kille || S.Kille@ISODE.COM +# RFC1802 || H. Alvestrand, K. Jordan, S. Langlois, J. Romaguera || Harald.T.Alvestrand@uninett.no, Kevin.E.Jordan@cdc.com, Sylvain.Langlois@der.edf.fr, Romaguera@NetConsult.ch +# RFC1803 || R. Wright, A. Getchell, T. Howes, S. Sataluri, P. Yee, W. Yeong || +# RFC1804 || G. Mansfield, P. Rajeev, S. Raghavan, T. Howes || glenn@aic.co.jp, rajeev%hss@lando.hns.com, svr@iitm.ernet.in, tim@umich.edu +# RFC1805 || A. Rubin || rubin@bellcore.com +# RFC1806 || R. Troost, S. Dorner || rens@century.com, sdorner@qualcomm.com +# RFC1807 || R. Lasher, D. Cohen || rlasher@forsythe.stanford.edu, Cohen@myri.com +# RFC1808 || R. Fielding || fielding@ics.uci.edu +# RFC1809 || C. Partridge || craig@aland.bbn.com +# RFC1810 || J. Touch || touch@isi.edu +# RFC1811 || Federal Networking Council || execdir@fnc.gov +# RFC1812 || F. Baker, Ed. || +# RFC1813 || B. Callaghan, B. Pawlowski, P. Staubach || brent.callaghan@eng.sun.com, beepy@netapp.com, peter.staubach@eng.sun.com +# RFC1814 || E. Gerich || epg@merit.edu +# RFC1815 || M. Ohta || mohta@cc.titech.ac.jp +# RFC1816 || Federal Networking Council || execdir@fnc.gov +# RFC1817 || Y. Rekhter || yakov@cisco.com +# RFC1818 || J. Postel, T. Li, Y. Rekhter || postel@isi.edu, yakov@cisco.com, tli@cisco.com +# RFC1819 || L. Delgrossi, Ed., L. Berger, Ed. || lberger@bbn.com, luca@andersen.fr, dat@bbn.com, stevej@syzygycomm.com, schaller@heidelbg.ibm.com +# RFC1820 || E. Huizer || Erik.Huizer@SURFnet.nl +# RFC1821 || M. Borden, E. Crawley, B. Davie, S. Batsell || +# RFC1822 || J. Lowe || +# RFC1823 || T. Howes, M. Smith || tim@umich.edu, mcs@umich.edu +# RFC1824 || H. Danisch || danisch@ira.uka.de +# RFC1825 || R. Atkinson || +# RFC1826 || R. Atkinson || +# RFC1827 || R. Atkinson || +# RFC1828 || P. Metzger, W. Simpson || +# RFC1829 || P. Karn, P. Metzger, W. Simpson || +# RFC1830 || G. Vaudreuil || Greg.Vaudreuil@Octel.com +# RFC1831 || R. Srinivasan || raj@eng.sun.com +# RFC1832 || R. Srinivasan || raj@eng.sun.com +# RFC1833 || R. Srinivasan || raj@eng.sun.com +# RFC1834 || J. Gargano, K. Weiss || jcgargano@ucdavis.edu, krweiss@ucdavis.edu +# RFC1835 || P. Deutsch, R. Schoultz, P. Faltstrom, C. Weider || peterd@bunyip.com, schoultz@sunet.se, paf@bunyip.com, clw@bunyip.com +# RFC1836 || S. Kille || S.Kille@ISODE.COM +# RFC1837 || S. Kille || S.Kille@ISODE.COM +# RFC1838 || S. Kille || S.Kille@ISODE.COM +# RFC1839 || || +# RFC1840 || || +# RFC1841 || J. Chapman, D. Coli, A. Harvey, B. Jensen, K. Rowett || joelle@cisco.com, dcoli@cisco.com, agh@cisco.com, bent@cisco.com, krowett@cisco.com +# RFC1842 || Y. Wei, Y. Zhang, J. Li, J. Ding, Y. Jiang || HZRFC@usai.asiainfo.com, zhang@orion.harvard.edu, jian@is.rice.edu, ding@Beijing.AsiaInfo.com, yjj@eng.umd.edu +# RFC1843 || F. Lee || lee@csl.stanford.edu +# RFC1844 || E. Huizer || Erik.Huizer@SURFnet.nl +# RFC1845 || D. Crocker, N. Freed, A. Cargille || dcrocker@mordor.stanford.edu, ned@innosoft.com +# RFC1846 || A. Durand, F. Dupont || Alain.Durand@imag.fr, Francis.Dupont@inria.fr +# RFC1847 || J. Galvin, S. Murphy, S. Crocker, N. Freed || galvin@tis.com, sandy@tis.com, crocker@cybercash.com, ned@innosoft.com +# RFC1848 || S. Crocker, N. Freed, J. Galvin, S. Murphy || crocker@cybercash.com, galvin@tis.com, murphy@tis.com, ned@innosoft.com +# RFC1849 || H. Spencer || henry@zoo.utoronto.ca +# RFC1850 || F. Baker, R. Coltun || fred@cisco.com, rcoltun@rainbow-bridge.com +# RFC1851 || P. Karn, P. Metzger, W. Simpson || +# RFC1852 || P. Metzger, W. Simpson || +# RFC1853 || W. Simpson || +# RFC1854 || N. Freed || ned@innosoft.com +# RFC1855 || S. Hambridge || sallyh@ludwig.sc.intel.com +# RFC1856 || H. Clark || henryc@bbnplanet.com +# RFC1857 || M. Lambert || lambert@psc.edu +# RFC1858 || G. Ziemba, D. Reed, P. Traina || paul@alantec.com, darrenr@cyber.com.au, pst@cisco.com +# RFC1859 || Y. Pouffary || pouffary@taec.enet.dec.com +# RFC1860 || T. Pummill, B. Manning || trop@alantec.com, bmanning@isi.edu +# RFC1861 || A. Gwinn || allen@mail.cox.smu.edu +# RFC1862 || M. McCahill, J. Romkey, M. Schwartz, K. Sollins, T. Verschuren, C. Weider || mpm@boombox.micro.umn.edu, romkey@apocalypse.org, schwartz@cs.colorado.edu, sollins@lcs.mit.edu, Ton.Verschuren@surfnet.nl, clw@bunyip.com +# RFC1863 || D. Haskin || dhaskin@baynetworks.com +# RFC1864 || J. Myers, M. Rose || mrose17@gmail.com +# RFC1865 || W. Houser, J. Griffin, C. Hage || houser.walt@forum.va.gov, agriffin@cpcug.org, carl@chage.com +# RFC1866 || T. Berners-Lee, D. Connolly || timbl@w3.org, connolly@w3.org +# RFC1867 || E. Nebel, L. Masinter || masinter@parc.xerox.com, nebel@xsoft.sd.xerox.com +# RFC1868 || G. Malkin || gmalkin@xylogics.com +# RFC1869 || J. Klensin, N. Freed, M. Rose, E. Stefferud, D. Crocker || klensin@mci.net, ned@innosoft.com, mrose17@gmail.com, stef@nma.com, dcrocker@mordor.stanford.edu +# RFC1870 || J. Klensin, N. Freed, K. Moore || klensin@mci.net, ned@innosoft.com, moore@cs.utk.edu +# RFC1871 || J. Postel || postel@isi.edu +# RFC1872 || E. Levinson || ELevinson@Accurate.com +# RFC1873 || E. Levinson || +# RFC1874 || E. Levinson || ELevinson@Accurate.com +# RFC1875 || N. Berge || Nils.Harald.Berge@nr.no +# RFC1876 || C. Davis, P. Vixie, T. Goodwin, I. Dickinson || ckd@kei.com, paul@vix.com, tim@pipex.net, idickins@fore.co.uk +# RFC1877 || S. Cobb || stevec@microsoft.com +# RFC1878 || T. Pummill, B. Manning || trop@alantec.com, bmanning@isi.edu +# RFC1879 || B. Manning, Ed. || +# RFC1880 || J. Postel, Ed. || +# RFC1881 || IAB, IESG || +# RFC1882 || B. Hancock || hancock@network-1.com +# RFC1883 || S. Deering, R. Hinden || bob.hinden@gmail.com +# RFC1884 || R. Hinden, Ed., S. Deering, Ed. || bob.hinden@gmail.com +# RFC1885 || A. Conta, S. Deering || deering@parc.xerox.com +# RFC1886 || S. Thomson, C. Huitema || set@thumper.bellcore.com, Christian.Huitema@MIRSA.INRIA.FR +# RFC1887 || Y. Rekhter, Ed., T. Li, Ed. || +# RFC1888 || J. Bound, B. Carpenter, D. Harrington, J. Houldsworth, A. Lloyd || +# RFC1889 || Audio-Video Transport Working Group, H. Schulzrinne, S. Casner, R. Frederick, V. Jacobson || schulzrinne@fokus.gmd.de, casner@precept.com, frederic@parc.xerox.com, van@ee.lbl.gov +# RFC1890 || Audio-Video Transport Working Group, H. Schulzrinne || schulzrinne@fokus.gmd.de +# RFC1891 || K. Moore || moore@cs.utk.edu +# RFC1892 || G. Vaudreuil || Greg.Vaudreuil@Octel.com +# RFC1893 || G. Vaudreuil || Greg.Vaudreuil@Octel.com +# RFC1894 || K. Moore, G. Vaudreuil || moore@cs.utk.edu, Greg.Vaudreuil@Octel.Com +# RFC1895 || E. Levinson || ELevinson@Accurate.com +# RFC1896 || P. Resnick, A. Walker || presnick@qti.qualcomm.com, amanda@intercon.com +# RFC1897 || R. Hinden, J. Postel || bob.hinden@gmail.com, postel@isi.edu +# RFC1898 || D. Eastlake 3rd, B. Boesch, S. Crocker, M. Yesil || dee@cybercash.com, boesch@cybercash.com, crocker@cybercash.com, magdalen@cybercash.com +# RFC1899 || J. Elliott || elliott@isi.edu +# RFC1900 || B. Carpenter, Y. Rekhter || brian@dxcoms.cern.ch, yakov@cisco.com +# RFC1901 || J. Case, K. McCloghrie, M. Rose, S. Waldbusser || +# RFC1902 || J. Case, K. McCloghrie, M. Rose, S. Waldbusser || +# RFC1903 || J. Case, K. McCloghrie, M. Rose, S. Waldbusser || +# RFC1904 || J. Case, K. McCloghrie, M. Rose, S. Waldbusser || +# RFC1905 || J. Case, K. McCloghrie, M. Rose, S. Waldbusser || +# RFC1906 || J. Case, K. McCloghrie, M. Rose, S. Waldbusser || +# RFC1907 || J. Case, K. McCloghrie, M. Rose, S. Waldbusser || +# RFC1908 || J. Case, K. McCloghrie, M. Rose, S. Waldbusser || +# RFC1909 || K. McCloghrie, Ed. || +# RFC1910 || G. Waters, Ed. || +# RFC1911 || G. Vaudreuil || Greg.Vaudreuil@Octel.Com +# RFC1912 || D. Barr || barr@math.psu.edu +# RFC1913 || C. Weider, J. Fullton, S. Spero || clw@bunyip.com, fullton@cnidr.org, ses@eit.com +# RFC1914 || P. Faltstrom, R. Schoultz, C. Weider || paf@bunyip.com, schoultz@sunet.se, clw@bunyip.com +# RFC1915 || F. Kastenholz || kasten@ftp.com +# RFC1916 || H. Berkowitz, P. Ferguson, W. Leland, P. Nesser || hcb@clark.net, pferguso@cisco.com, wel@bellcore.com, pjnesser@rocket.com +# RFC1917 || P. Nesser II || pjnesser@martigny.ai.mit.edu +# RFC1918 || Y. Rekhter, B. Moskowitz, D. Karrenberg, G. J. de Groot, E. Lear || yakov@cisco.com, rgm3@is.chrysler.com, Daniel.Karrenberg@ripe.net, GeertJan.deGroot@ripe.net, lear@sgi.com +# RFC1919 || M. Chatel || mchatel@pax.eunet.ch +# RFC1920 || J. Postel || +# RFC1921 || J. Dujonc || J.Y.Dujonc@frcl.bull.fr +# RFC1922 || HF. Zhu, DY. Hu, ZG. Wang, TC. Kao, WCH. Chang, M. Crispin || zhf@net.tsinghua.edu.cn, hdy@tsinghua.edu.cn, tckao@iiidns.iii.org.tw, chung@iiidns.iii.org.tw, MRC@CAC.Washington.EDU +# RFC1923 || J. Halpern, S. Bradner || jhalpern@newbridge.com, sob@harvard.edu +# RFC1924 || R. Elz || kre@munnari.OZ.AU +# RFC1925 || R. Callon || rcallon@baynetworks.com +# RFC1926 || J. Eriksson || bygg@sunet.se +# RFC1927 || C. Rogers || rogers@isi.edu +# RFC1928 || M. Leech, M. Ganis, Y. Lee, R. Kuris, D. Koblas, L. Jones || mleech@bnr.ca +# RFC1929 || M. Leech || mleech@bnr.ca +# RFC1930 || J. Hawkinson, T. Bates || jhawk@bbnplanet.com, Tony.Bates@mci.net +# RFC1931 || D. Brownell || dbrownell@sun.com +# RFC1932 || R. Cole, D. Shur, C. Villamizar || rgc@qsun.att.com, d.shur@att.com, curtis@ans.net +# RFC1933 || R. Gilligan, E. Nordmark || Bob.Gilligan@Eng.Sun.COM, Erik.Nordmark@Eng.Sun.COM +# RFC1934 || K. Smith || ksmith@ascend.com +# RFC1935 || J. Quarterman, S. Carl-Mitchell || tic@tic.com +# RFC1936 || J. Touch, B. Parham || touch@isi.edu, bparham@isi.edu +# RFC1937 || Y. Rekhter, D. Kandlur || yakov@cisco.com, kandlur@watson.ibm.com +# RFC1938 || N. Haller, C. Metz || +# RFC1939 || J. Myers, M. Rose || mrose17@gmail.com +# RFC1940 || D. Estrin, T. Li, Y. Rekhter, K. Varadhan, D. Zappala || estrin@isi.edu, tli@cisco.com, yakov@cisco.com, kannan@isi.edu, daniel@isi.edu +# RFC1941 || J. Sellers, J. Robichaux || julier@internic.net, sellers@quest.arc.nasa.gov +# RFC1942 || D. Raggett || dsr@w3.org +# RFC1943 || B. Jennings || jennings@sandia.gov +# RFC1944 || S. Bradner, J. McQuaid || +# RFC1945 || T. Berners-Lee, R. Fielding, H. Frystyk || timbl@w3.org, fielding@ics.uci.edu, frystyk@w3.org +# RFC1946 || S. Jackowski || Stevej@NetManage.com +# RFC1947 || D. Spinellis || D.Spinellis@senanet.com +# RFC1948 || S. Bellovin || smb@research.att.com +# RFC1949 || A. Ballardie || A.Ballardie@cs.ucl.ac.uk +# RFC1950 || P. Deutsch, J-L. Gailly || +# RFC1951 || P. Deutsch || +# RFC1952 || P. Deutsch || +# RFC1953 || P. Newman, W. Edwards, R. Hinden, E. Hoffman, F. Ching Liaw, T. Lyon, G. Minshall || bob.hinden@gmail.com +# RFC1954 || P. Newman, W. Edwards, R. Hinden, E. Hoffman, F. Ching Liaw, T. Lyon, G. Minshall || bob.hinden@gmail.com +# RFC1955 || R. Hinden || bob.hinden@gmail.com +# RFC1956 || D. Engebretson, R. Plzak || engebred@ncr.disa.mil, plzak@nic.ddn.mil +# RFC1957 || R. Nelson || nelson@crynwr.com +# RFC1958 || B. Carpenter, Ed. || +# RFC1959 || T. Howes, M. Smith || tim@umich.edu, mcs@umich.edu +# RFC1960 || T. Howes || tim@umich.edu +# RFC1961 || P. McMahon || p.v.mcmahon@rea0803.wins.icl.co.uk +# RFC1962 || D. Rand || dlr@daver.bungi.com +# RFC1963 || K. Schneider, S. Venters || kevin@adtran.com, sventers@adtran.com +# RFC1964 || J. Linn || +# RFC1965 || P. Traina || pst@cisco.com +# RFC1966 || T. Bates, R. Chandra || tbates@cisco.com, rchandra@cisco.com +# RFC1967 || K. Schneider, R. Friend || kschneider@adtran.com, rfriend@stac.com +# RFC1968 || G. Meyer || gerry@spider.co.uk +# RFC1969 || K. Sklower, G. Meyer || sklower@CS.Berkeley.EDU, gerry@spider.co.uk +# RFC1970 || T. Narten, E. Nordmark, W. Simpson || +# RFC1971 || S. Thomson, T. Narten || +# RFC1972 || M. Crawford || crawdad@fnal.gov +# RFC1973 || W. Simpson || +# RFC1974 || R. Friend, W. Simpson || rfriend@stac.com +# RFC1975 || D. Schremp, J. Black, J. Weiss || dhs@magna.telco.com, jtb@magna.telco.com, jaw@magna.telco.com +# RFC1976 || K. Schneider, S. Venters || kevin@adtran.com, sventers@adtran.com +# RFC1977 || V. Schryver || vjs@rhyolite.com +# RFC1978 || D. Rand || dave_rand@novell.com +# RFC1979 || J. Woods || jfw@funhouse.com +# RFC1980 || J. Seidman || jim@spyglass.com +# RFC1981 || J. McCann, S. Deering, J. Mogul || deering@parc.xerox.com, mogul@pa.dec.com +# RFC1982 || R. Elz, R. Bush || randy@psg.com +# RFC1983 || G. Malkin, Ed. || +# RFC1984 || IAB, IESG || brian@dxcoms.cern.ch, fred@cisco.com +# RFC1985 || J. De Winter || jack@wildbear.on.ca +# RFC1986 || W. Polites, W. Wollman, D. Woo, R. Langan || +# RFC1987 || P. Newman, W. Edwards, R. Hinden, E. Hoffman, F. Ching Liaw, T. Lyon, G. Minshall || bob.hinden@gmail.com +# RFC1988 || G. McAnally, D. Gilbert, J. Flick || johnf@hprnd.rose.hp.com +# RFC1989 || W. Simpson || +# RFC1990 || K. Sklower, B. Lloyd, G. McGregor, D. Carr, T. Coradetti || sklower@CS.Berkeley.EDU, brian@lloyd.com, glenn@lloyd.com, dcarr@Newbridge.COM, 70761.1664@compuserve.com +# RFC1991 || D. Atkins, W. Stallings, P. Zimmermann || warlord@MIT.EDU, stallings@ACM.org, prz@acm.org +# RFC1992 || I. Castineyra, N. Chiappa, M. Steenstrup || isidro@bbn.com, gnc@ginger.lcs.mit.edu, msteenst@bbn.com +# RFC1993 || A. Barbir, D. Carr, W. Simpson || +# RFC1994 || W. Simpson || +# RFC1995 || M. Ohta || mohta@necom830.hpcl.titech.ac.jp +# RFC1996 || P. Vixie || paul@vix.com +# RFC1997 || R. Chandra, P. Traina, T. Li || pst@cisco.com, rchandra@cisco.com, tli@skat.usc.edu +# RFC1998 || E. Chen, T. Bates || enke@mci.net, tbates@cisco.com +# RFC1999 || J. Elliott || elliott@isi.edu +# RFC2000 || J. Postel, Ed. || +# RFC2001 || W. Stevens || rstevens@noao.edu +# RFC2002 || C. Perkins, Ed. || +# RFC2003 || C. Perkins || perk@watson.ibm.com, solomon@comm.mot.com +# RFC2004 || C. Perkins || perk@watson.ibm.com, solomon@comm.mot.com +# RFC2005 || J. Solomon || solomon@comm.mot.com +# RFC2006 || D. Cong, M. Hamlen, C. Perkins || +# RFC2007 || J. Foster, M. Isaacs, M. Prior || Jill.Foster@newcastle.ac.uk, mmi@dcs.gla.ac.uk, mrp@connect.com.au +# RFC2008 || Y. Rekhter, T. Li || yakov@cisco.com, tli@cisco.com +# RFC2009 || T. Imielinski, J. Navas || +# RFC2010 || B. Manning, P. Vixie || bmanning@isi.edu, paul@vix.com +# RFC2011 || K. McCloghrie, Ed. || +# RFC2012 || K. McCloghrie, Ed. || +# RFC2013 || K. McCloghrie, Ed. || +# RFC2014 || A. Weinrib, J. Postel || +# RFC2015 || M. Elkins || +# RFC2016 || L. Daigle, P. Deutsch, B. Heelan, C. Alpaugh, M. Maclachlan || ura-bunyip@bunyip.com +# RFC2017 || N. Freed, K. Moore, A. Cargille || ned@innosoft.com, moore@cs.utk.edu +# RFC2018 || M. Mathis, J. Mahdavi, S. Floyd, A. Romanow || +# RFC2019 || M. Crawford || crawdad@fnal.gov +# RFC2020 || J. Flick || +# RFC2021 || S. Waldbusser || waldbusser@ins.com +# RFC2022 || G. Armitage || gja@thumper.bellcore.com +# RFC2023 || D. Haskin, E. Allen || +# RFC2024 || D. Chen, Ed., P. Gayek, S. Nix || dchen@vnet.ibm.com, gayek@vnet.ibm.com, snix@metaplex.com +# RFC2025 || C. Adams || cadams@bnr.ca +# RFC2026 || S. Bradner || +# RFC2027 || J. Galvin || +# RFC2028 || R. Hovey, S. Bradner || hovey@wnpv01.enet.dec.com, sob@harvard.edu +# RFC2029 || M. Speer, D. Hoffman || michael.speer@eng.sun.com, don.hoffman@eng.sun.com +# RFC2030 || D. Mills || +# RFC2031 || E. Huizer || +# RFC2032 || T. Turletti, C. Huitema || turletti@sophia.inria.fr, huitema@bellcore.com +# RFC2033 || J. Myers || +# RFC2034 || N. Freed || +# RFC2035 || L. Berc, W. Fenner, R. Frederick, S. McCanne || berc@pa.dec.com, fenner@cmf.nrl.navy.mil, frederick@parc.xerox.com, mccanne@ee.lbl.gov +# RFC2036 || G. Huston || +# RFC2037 || K. McCloghrie, A. Bierman || kzm@cisco.com, andy@yumaworks.com +# RFC2038 || D. Hoffman, G. Fernando, V. Goyal || gerard.fernando@eng.sun.com, goyal@precept.com, don.hoffman@eng.sun.com +# RFC2039 || C. Kalbfleisch || +# RFC2040 || R. Baldwin, R. Rivest || baldwin@rsa.com, rivest@theory.lcs.mit.edu +# RFC2041 || B. Noble, G. Nguyen, M. Satyanarayanan, R. Katz || bnoble@cs.cmu.edu, gnguyen@cs.berkeley.edu, satya@cs.cmu.edu, randy@cs.berkeley.edu +# RFC2042 || B. Manning || bmanning@isi.edu +# RFC2043 || A. Fuqua || fuqua@vnet.ibm.com +# RFC2044 || F. Yergeau || fyergeau@alis.com +# RFC2045 || N. Freed, N. Borenstein || ned@innosoft.com, nsb@nsb.fv.com, Greg.Vaudreuil@Octel.Com +# RFC2046 || N. Freed, N. Borenstein || ned@innosoft.com, nsb@nsb.fv.com, Greg.Vaudreuil@Octel.Com +# RFC2047 || K. Moore || moore@cs.utk.edu +# RFC2048 || N. Freed, J. Klensin, J. Postel || ned@innosoft.com, klensin@mci.net, Postel@ISI.EDU +# RFC2049 || N. Freed, N. Borenstein || ned@innosoft.com, nsb@nsb.fv.com, Greg.Vaudreuil@Octel.Com +# RFC2050 || K. Hubbard, M. Kosters, D. Conrad, D. Karrenberg, J. Postel || kimh@internic.net, markk@internic.net, davidc@APNIC.NET, dfk@RIPE.NET, Postel@ISI.EDU +# RFC2051 || M. Allen, B. Clouston, Z. Kielczewski, W. Kwan, B. Moore || mallen@hq.walldata.com, clouston@cisco.com, zbig@cisco.com, billk@jti.com, remoore@ralvm6.vnet.ibm.com +# RFC2052 || A. Gulbrandsen, P. Vixie || agulbra@troll.no, paul@vix.com +# RFC2053 || E. Der-Danieliantz || edd@acm.org +# RFC2054 || B. Callaghan || brent.callaghan@eng.sun.com +# RFC2055 || B. Callaghan || brent.callaghan@eng.sun.com +# RFC2056 || R. Denenberg, J. Kunze, D. Lynch || +# RFC2057 || S. Bradner || sob@harvard.edu +# RFC2058 || C. Rigney, A. Rubens, W. Simpson, S. Willens || cdr@livingston.com, acr@merit.edu, wsimpson@greendragon.com, steve@livingston.com +# RFC2059 || C. Rigney || cdr@livingston.com +# RFC2060 || M. Crispin || MRC@CAC.Washington.EDU +# RFC2061 || M. Crispin || MRC@CAC.Washington.EDU +# RFC2062 || M. Crispin || MRC@CAC.Washington.EDU +# RFC2063 || N. Brownlee, C. Mills, G. Ruth || cmills@bbn.com, gruth@gte.com +# RFC2064 || N. Brownlee || +# RFC2065 || D. Eastlake 3rd, C. Kaufman || dee@cybercash.com, charlie_kaufman@iris.com +# RFC2066 || R. Gellens || Randy@MV.Unisys.Com +# RFC2067 || J. Renwick || jkr@NetStar.com +# RFC2068 || R. Fielding, J. Gettys, J. Mogul, H. Frystyk, T. Berners-Lee || fielding@ics.uci.edu, jg@w3.org, mogul@wrl.dec.com, frystyk@w3.org, timbl@w3.org +# RFC2069 || J. Franks, P. Hallam-Baker, J. Hostetler, P. Leach, A. Luotonen, E. Sink, L. Stewart || john@math.nwu.edu, hallam@w3.org, jeff@spyglass.com, paulle@microsoft.com, luotonen@netscape.com, eric@spyglass.com, stewart@OpenMarket.com +# RFC2070 || F. Yergeau, G. Nicol, G. Adams, M. Duerst || fyergeau@alis.com, gtn@ebt.com, glenn@spyglass.com, mduerst@ifi.unizh.ch +# RFC2071 || P. Ferguson, H. Berkowitz || pferguso@cisco.com, hcb@clark.net +# RFC2072 || H. Berkowitz || hcb@clark.net +# RFC2073 || Y. Rekhter, P. Lothberg, R. Hinden, S. Deering, J. Postel || bob.hinden@gmail.com +# RFC2074 || A. Bierman, R. Iddon || andy@yumaworks.com, robin_iddon@3mail.3com.com +# RFC2075 || C. Partridge || craig@bbn.com +# RFC2076 || J. Palme || +# RFC2077 || S. Nelson, C. Parks, Mitra || +# RFC2078 || J. Linn || John.Linn@ov.com +# RFC2079 || M. Smith || mcs@netscape.com +# RFC2080 || G. Malkin, R. Minnear || gmalkin@Xylogics.COM, minnear@ipsilon.com +# RFC2081 || G. Malkin || gmalkin@xylogics.com +# RFC2082 || F. Baker, R. Atkinson || rja@cisco.com +# RFC2083 || T. Boutell || boutell@boutell.com +# RFC2084 || G. Bossert, S. Cooper, W. Drummond || bossert@corp.sgi.com, sc@corp.sgi.com, drummond@ieee.org +# RFC2085 || M. Oehler, R. Glenn || mjo@tycho.ncsc.mil, rob.glenn@nist.gov +# RFC2086 || J. Myers || +# RFC2087 || J. Myers || +# RFC2088 || J. Myers || +# RFC2089 || B. Wijnen, D. Levi || +# RFC2090 || A. Emberson || tom@lanworks.com +# RFC2091 || G. Meyer, S. Sherry || +# RFC2092 || S. Sherry, G. Meyer || +# RFC2093 || H. Harney, C. Muckenhirn || +# RFC2094 || H. Harney, C. Muckenhirn || +# RFC2095 || J. Klensin, R. Catoe, P. Krumviede || klensin@mci.net, randy@mci.net, paul@mci.net +# RFC2096 || F. Baker || fred@cisco.com +# RFC2097 || G. Pall || gurdeep@microsoft.com +# RFC2098 || Y. Katsube, K. Nagami, H. Esaki || +# RFC2099 || J. Elliott || elliott@isi.edu +# RFC2100 || J. Ashworth || jra@scfn.thpl.lib.fl.us +# RFC2101 || B. Carpenter, J. Crowcroft, Y. Rekhter || brian@dxcoms.cern.ch, j.crowcroft@cs.ucl.ac.uk, yakov@cisco.com +# RFC2102 || R. Ramanathan || ramanath@bbn.com +# RFC2103 || R. Ramanathan || +# RFC2104 || H. Krawczyk, M. Bellare, R. Canetti || hugo@watson.ibm.com, mihir@cs.ucsd.edu, canetti@watson.ibm.com +# RFC2105 || Y. Rekhter, B. Davie, D. Katz, E. Rosen, G. Swallow || yakov@cisco.com, bsd@cisco.com, dkatz@cisco.com, erosen@cisco.com, swallow@cisco.com +# RFC2106 || S. Chiang, J. Lee, H. Yasuda || schiang@cisco.com, jolee@cisco.com, yasuda@eme068.cow.melco.co.jp +# RFC2107 || K. Hamzeh || kory@ascend.com +# RFC2108 || K. de Graaf, D. Romascanu, D. McMaster, K. McCloghrie || kdegraaf@isd.3com.com, dromasca@gmail.com , mcmaster@cisco.com, kzm@cisco.com +# RFC2109 || D. Kristol, L. Montulli || +# RFC2110 || J. Palme, A. Hopmann || +# RFC2111 || E. Levinson || +# RFC2112 || E. Levinson || +# RFC2113 || D. Katz || +# RFC2114 || S. Chiang, J. Lee, H. Yasuda || schiang@cisco.com, jolee@cisco.com, yasuda@eme068.cow.melco.co.jp +# RFC2115 || C. Brown, F. Baker || +# RFC2116 || C. Apple, K. Rossen || +# RFC2117 || D. Estrin, D. Farinacci, A. Helmy, D. Thaler, S. Deering, M. Handley, V. Jacobson, C. Liu, P. Sharma, L. Wei || +# RFC2118 || G. Pall || +# RFC2119 || S. Bradner || +# RFC2120 || D. Chadwick || +# RFC2121 || G. Armitage || gja@thumper.bellcore.com +# RFC2122 || D. Mavrakis, H. Layec, K. Kartmann || +# RFC2123 || N. Brownlee || +# RFC2124 || P. Amsden, J. Amweg, P. Calato, S. Bensley, G. Lyons || amsden@ctron.com, amsden@ctron.com, amsden@ctron.com, amsden@ctron.com, amsden@ctron.com +# RFC2125 || C. Richards, K. Smith || +# RFC2126 || Y. Pouffary, A. Young || pouffary@taec.enet.dec.com, A.Young@isode.com +# RFC2127 || G. Roeck, Ed. || groeck@cisco.com +# RFC2128 || G. Roeck, Ed. || groeck@cisco.com +# RFC2129 || K. Nagami, Y. Katsube, Y. Shobatake, A. Mogi, S. Matsuzawa, T. Jinmei, H. Esaki || +# RFC2130 || C. Weider, C. Preston, K. Simonsen, H. Alvestrand, R. Atkinson, M. Crispin, P. Svanberg || cweider@microsoft.com, cecilia@well.com, Keld@dkuug.dk, Harald.T.Alvestrand@uninett.no, rja@cisco.com, mrc@cac.washington.edu, psv@nada.kth.se +# RFC2131 || R. Droms || droms@bucknell.edu +# RFC2132 || S. Alexander, R. Droms || sca@engr.sgi.com, droms@bucknell.edu +# RFC2133 || R. Gilligan, S. Thomson, J. Bound, W. Stevens || gilligan@freegate.net, set@thumper.bellcore.com, rstevens@kohala.com +# RFC2134 || ISOC Board of Trustees || +# RFC2135 || ISOC Board of Trustees || +# RFC2136 || P. Vixie, Ed., S. Thomson, Y. Rekhter, J. Bound || yakov@cisco.com, set@thumper.bellcore.com, bound@zk3.dec.com, paul@vix.com +# RFC2137 || D. Eastlake 3rd || dee@cybercash.com +# RFC2138 || C. Rigney, A. Rubens, W. Simpson, S. Willens || cdr@livingston.com, acr@merit.edu, wsimpson@greendragon.com, steve@livingston.com +# RFC2139 || C. Rigney || cdr@livingston.com +# RFC2140 || J. Touch || +# RFC2141 || R. Moats || +# RFC2142 || D. Crocker || +# RFC2143 || B. Elliston || +# RFC2144 || C. Adams || +# RFC2145 || J. C. Mogul, R. Fielding, J. Gettys, H. Frystyk || +# RFC2146 || Federal Networking Council || execdir@fnc.gov +# RFC2147 || D. Borman || +# RFC2148 || H. Alvestrand, P. Jurg || +# RFC2149 || R. Talpade, M. Ammar || +# RFC2150 || J. Max, W. Stickle || jlm@rainfarm.com, wls@rainfarm.com +# RFC2151 || G. Kessler, S. Shepard || +# RFC2152 || D. Goldsmith, M. Davis || goldsmith@apple.com, mark_davis@taligent.com +# RFC2153 || W. Simpson || +# RFC2154 || S. Murphy, M. Badger, B. Wellington || +# RFC2155 || B. Clouston, B. Moore || +# RFC2156 || S. Kille || +# RFC2157 || H. Alvestrand || Harald.T.Alvestrand@uninett.no +# RFC2158 || H. Alvestrand || Harald.T.Alvestrand@uninett.no +# RFC2159 || H. Alvestrand || Harald.T.Alvestrand@uninett.no +# RFC2160 || H. Alvestrand || Harald.T.Alvestrand@uninett.no +# RFC2161 || H. Alvestrand || Harald.T.Alvestrand@uninett.no +# RFC2162 || C. Allocchio || Claudio.Allocchio@elettra.Trieste.it +# RFC2163 || C. Allocchio || +# RFC2164 || S. Kille || S.Kille@ISODE.COM +# RFC2165 || J. Veizades, E. Guttman, C. Perkins, S. Kaplan || cperkins@Corp.sun.com +# RFC2166 || D. Bryant, P. Brittain || +# RFC2167 || S. Williamson, M. Kosters, D. Blacka, J. Singh, K. Zeilstra || +# RFC2168 || R. Daniel, M. Mealling || +# RFC2169 || R. Daniel || +# RFC2170 || W. Almesberger, J. Le Boudec, P. Oechslin || +# RFC2171 || K. Murakami, M. Maruyama || +# RFC2172 || M. Maruyama, K. Murakami || +# RFC2173 || K. Murakami, M. Maruyama || +# RFC2174 || K. Murakami, M. Maruyama || +# RFC2175 || K. Murakami, M. Maruyama || +# RFC2176 || K. Murakami, M. Maruyama || +# RFC2177 || B. Leiba || +# RFC2178 || J. Moy || jmoy@casc.com +# RFC2179 || A. Gwinn || allen@mail.cox.smu.edu, ssh@wwsi.com +# RFC2180 || M. Gahrns || mikega@microsoft.com +# RFC2181 || R. Elz, R. Bush || kre@munnari.OZ.AU, randy@psg.com +# RFC2182 || R. Elz, R. Bush, S. Bradner, M. Patton || kre@munnari.OZ.AU, randy@psg.com, sob@harvard.edu, MAP@POBOX.COM +# RFC2183 || R. Troost, S. Dorner, K. Moore, Ed. || rens@century.com, sdorner@qualcomm.com +# RFC2184 || N. Freed, K. Moore || +# RFC2185 || R. Callon, D. Haskin || +# RFC2186 || D. Wessels, K. Claffy || wessels@nlanr.net, kc@nlanr.net +# RFC2187 || D. Wessels, K. Claffy || wessels@nlanr.net, kc@nlanr.net +# RFC2188 || M. Banan, M. Taylor, J. Cheng || +# RFC2189 || A. Ballardie || +# RFC2190 || C. Zhu || czhu@ibeam.intel.com +# RFC2191 || G. Armitage || gja@dnrc.bell-labs.com +# RFC2192 || C. Newman || chris.newman@innosoft.com +# RFC2193 || M. Gahrns || mikega@microsoft.com +# RFC2194 || B. Aboba, J. Lu, J. Alsop, J. Ding, W. Wang || bernarda@microsoft.com, juanlu@aimnet.net, jalsop@ipass.com, ding@bjai.asiainfo.com, weiwang@merit.edu +# RFC2195 || J. Klensin, R. Catoe, P. Krumviede || klensin@mci.net, randy@mci.net, paul@mci.net +# RFC2196 || B. Fraser || +# RFC2197 || N. Freed || ned.freed@innosoft.com +# RFC2198 || C. Perkins, I. Kouvelas, O. Hodson, V. Hardman, M. Handley, J.C. Bolot, A. Vega-Garcia, S. Fosse-Parisis || mjh@isi.edu +# RFC2199 || A. Ramos || ramos@isi.edu +# RFC2200 || J. Postel || +# RFC2201 || A. Ballardie || +# RFC2202 || P. Cheng, R. Glenn || pau@watson.ibm.com, rob.glenn@nist.gov +# RFC2203 || M. Eisler, A. Chiu, L. Ling || mre@eng.sun.com, hacker@eng.sun.com, lling@eng.sun.com +# RFC2204 || D. Nash || dnash@ford.com +# RFC2205 || R. Braden, Ed., L. Zhang, S. Berson, S. Herzog, S. Jamin || Braden@ISI.EDU, lixia@cs.ucla.edu, Berson@ISI.EDU, Herzog@WATSON.IBM.COM, jamin@EECS.UMICH.EDU +# RFC2206 || F. Baker, J. Krawczyk, A. Sastry || fred@cisco.com, jjk@tiac.net, arun@cisco.com +# RFC2207 || L. Berger, T. O'Malley || timo@bbn.com +# RFC2208 || A. Mankin, Ed., F. Baker, B. Braden, S. Bradner, M. O'Dell, A. Romanow, A. Weinrib, L. Zhang || aweinrib@ibeam.intel.com, braden@isi.edu, lixia@cs.ucla.edu, allyn@eng.sun.com, mo@uu.net +# RFC2209 || R. Braden, L. Zhang || Braden@ISI.EDU, lixia@cs.ucla.edu +# RFC2210 || J. Wroclawski || jtw@lcs.mit.edu +# RFC2211 || J. Wroclawski || jtw@lcs.mit.edu +# RFC2212 || S. Shenker, C. Partridge, R. Guerin || shenker@parc.xerox.com, craig@bbn.com, guerin@watson.ibm.com +# RFC2213 || F. Baker, J. Krawczyk, A. Sastry || fred@cisco.com, jjk@tiac.net, arun@cisco.com +# RFC2214 || F. Baker, J. Krawczyk, A. Sastry || fred@cisco.com, jjk@tiac.net, arun@cisco.com +# RFC2215 || S. Shenker, J. Wroclawski || shenker@parc.xerox.com, jtw@lcs.mit.edu +# RFC2216 || S. Shenker, J. Wroclawski || shenker@parc.xerox.com, jtw@lcs.mit.edu +# RFC2217 || G. Clark || glenc@cisco.com +# RFC2218 || T. Genovese, B. Jennings || TonyG@Microsoft.com, jennings@sandia.gov +# RFC2219 || M. Hamilton, R. Wright || m.t.hamilton@lut.ac.uk, wright@lbl.gov +# RFC2220 || R. Guenther || rgue@loc.gov +# RFC2221 || M. Gahrns || mikega@microsoft.com +# RFC2222 || J. Myers || jgmyers@netscape.com +# RFC2223 || J. Postel, J. Reynolds || Postel@ISI.EDU, jkrey@isi.edu, dwaitzman@BBN.COM +# RFC2224 || B. Callaghan || brent.callaghan@eng.sun.com +# RFC2225 || M. Laubach, J. Halpern || +# RFC2226 || T. Smith, G. Armitage || tjsmith@vnet.ibm.com, gja@lucent.com +# RFC2227 || J. Mogul, P. Leach || mogul@wrl.dec.com, paulle@microsoft.com +# RFC2228 || M. Horowitz, S. Lunt || marc@cygnus.com +# RFC2229 || R. Faith, B. Martin || faith@cs.unc.edu, bamartin@miranda.org +# RFC2230 || R. Atkinson || +# RFC2231 || N. Freed, K. Moore || ned.freed@innosoft.com, moore@cs.utk.edu +# RFC2232 || B. Clouston, Ed., B. Moore, Ed. || clouston@cisco.com, remoore@ralvm6.vnet.ibm.com +# RFC2233 || K. McCloghrie, F. Kastenholz || kzm@cisco.com, kasten@ftp.com +# RFC2234 || D. Crocker, Ed., P. Overell || dcrocker@bbiw.net, paul@bayleaf.org.uk +# RFC2235 || R. Zakon || zakon@info.isoc.org +# RFC2236 || W. Fenner || fenner@parc.xerox.com +# RFC2237 || K. Tamaru || kenzat@microsoft.com +# RFC2238 || B. Clouston, Ed., B. Moore, Ed. || clouston@cisco.com, remoore@ralvm6.vnet.ibm.com +# RFC2239 || K. de Graaf, D. Romascanu, D. McMaster, K. McCloghrie, S. Roberts || kdegraaf@isd.3com.com, dromasca@gmail.com , mcmaster@cisco.com, kzm@cisco.com, sroberts@farallon.com +# RFC2240 || O. Vaughan || owain@vaughan.com +# RFC2241 || D. Provan || donp@Novell.Com +# RFC2242 || R. Droms, K. Fong || +# RFC2243 || C. Metz || +# RFC2244 || C. Newman, J. G. Myers || +# RFC2245 || C. Newman || +# RFC2246 || T. Dierks, C. Allen || tdierks@certicom.com, pck@netcom.com, relyea@netscape.com, jar@netscape.com, msabin@netcom.com, dansimon@microsoft.com, tomw@netscape.com, hugo@watson.ibm.com +# RFC2247 || S. Kille, M. Wahl, A. Grimstad, R. Huber, S. Sataluri || S.Kille@ISODE.COM, M.Wahl@critical-angle.com, alg@att.com, rvh@att.com, sri@att.com +# RFC2248 || N. Freed, S. Kille || ned.freed@innosoft.com, S.Kille@isode.com +# RFC2249 || N. Freed, S. Kille || ned.freed@innosoft.com, S.Kille@isode.com +# RFC2250 || D. Hoffman, G. Fernando, V. Goyal, M. Civanlar || gerard.fernando@eng.sun.com, goyal@precept.com, don.hoffman@eng.sun.com, civanlar@research.att.com +# RFC2251 || M. Wahl, T. Howes, S. Kille || M.Wahl@critical-angle.com, howes@netscape.com, S.Kille@isode.com +# RFC2252 || M. Wahl, A. Coulbeck, T. Howes, S. Kille || M.Wahl@critical-angle.com, A.Coulbeck@isode.com, howes@netscape.com, S.Kille@isode.com +# RFC2253 || M. Wahl, S. Kille, T. Howes || M.Wahl@critical-angle.com, S.Kille@ISODE.COM, howes@netscape.com +# RFC2254 || T. Howes || howes@netscape.com +# RFC2255 || T. Howes, M. Smith || howes@netscape.com, mcs@netscape.com +# RFC2256 || M. Wahl || M.Wahl@critical-angle.com +# RFC2257 || M. Daniele, B. Wijnen, D. Francisco || daniele@zk3.dec.com, wijnen@vnet.ibm.com, dfrancis@cisco.com +# RFC2258 || J. Ordille || joann@bell-labs.com +# RFC2259 || J. Elliott, J. Ordille || jim@apocalypse.org, joann@bell-labs.com +# RFC2260 || T. Bates, Y. Rekhter || tbates@cisco.com, yakov@cisco.com +# RFC2261 || D. Harrington, R. Presuhn, B. Wijnen || +# RFC2262 || J. Case, D. Harrington, R. Presuhn, B. Wijnen || +# RFC2263 || D. Levi, P. Meyer, B. Stewart || +# RFC2264 || U. Blumenthal, B. Wijnen || +# RFC2265 || B. Wijnen, R. Presuhn, K. McCloghrie || +# RFC2266 || J. Flick || +# RFC2267 || P. Ferguson, D. Senie || ferguson@cisco.com, dts@senie.com +# RFC2268 || R. Rivest || rsa-labs@rsa.com +# RFC2269 || G. Armitage || gja@lucent.com +# RFC2270 || J. Stewart, T. Bates, R. Chandra, E. Chen || jstewart@isi.edu, tbates@cisco.com, rchandra@cisco.com, enkechen@cisco.com +# RFC2271 || D. Harrington, R. Presuhn, B. Wijnen || +# RFC2272 || J. Case, D. Harrington, R. Presuhn, B. Wijnen || +# RFC2273 || D. Levi, P. Meyer, B. Stewart || +# RFC2274 || U. Blumenthal, B. Wijnen || +# RFC2275 || B. Wijnen, R. Presuhn, K. McCloghrie || +# RFC2276 || K. Sollins || sollins@lcs.mit.edu +# RFC2277 || H. Alvestrand || Harald.T.Alvestrand@uninett.no +# RFC2278 || N. Freed, J. Postel || ned.freed@innosoft.com, Postel@ISI.EDU +# RFC2279 || F. Yergeau || fyergeau@alis.com +# RFC2280 || C. Alaettinoglu, T. Bates, E. Gerich, D. Karrenberg, D. Meyer, M. Terpstra, C. Villamizar || cengiz@isi.edu, tbates@cisco.com, epg@home.net, dfk@ripe.net, meyer@antc.uoregon.edu, marten@BayNetworks.com, curtis@ans.net +# RFC2281 || T. Li, B. Cole, P. Morton, D. Li || tli@juniper.net, cole@juniper.net, pmorton@cisco.com, dawnli@cisco.com +# RFC2282 || J. Galvin || +# RFC2283 || T. Bates, R. Chandra, D. Katz, Y. Rekhter || +# RFC2284 || L. Blunk, J. Vollbrecht || ljb@merit.edu, jrv@merit.edu +# RFC2285 || R. Mandeville || bob.mandeville@eunet.fr +# RFC2286 || J. Kapp || skapp@reapertech.com +# RFC2287 || C. Krupczak, J. Saperia || cheryl@empiretech.com +# RFC2288 || C. Lynch, C. Preston, R. Daniel || cliff@cni.org, cecilia@well.com, rdaniel@acl.lanl.gov +# RFC2289 || N. Haller, C. Metz, P. Nesser, M. Straw || +# RFC2290 || J. Solomon, S. Glass || solomon@comm.mot.com, glass@ftp.com +# RFC2291 || J. Slein, F. Vitali, E. Whitehead, D. Durand || slein@wrc.xerox.com, fabio@cs.unibo.it, ejw@ics.uci.edu, dgd@cs.bu.edu +# RFC2292 || W. Stevens, M. Thomas || rstevens@kohala.com, matt.thomas@altavista-software.com +# RFC2293 || S. Kille || S.Kille@ISODE.COM +# RFC2294 || S. Kille || S.Kille@ISODE.COM +# RFC2295 || K. Holtman, A. Mutz || koen@win.tue.nl, mutz@hpl.hp.com +# RFC2296 || K. Holtman, A. Mutz || koen@win.tue.nl, mutz@hpl.hp.com +# RFC2297 || P. Newman, W. Edwards, R. Hinden, E. Hoffman, F. Ching Liaw, T. Lyon, G. Minshall || bob.hinden@gmail.com +# RFC2298 || R. Fajman || raf@cu.nih.gov +# RFC2299 || A. Ramos || ramos@isi.edu +# RFC2300 || J. Postel || Postel@ISI.EDU +# RFC2301 || L. McIntyre, S. Zilles, R. Buckley, D. Venable, G. Parsons, J. Rafferty || +# RFC2302 || G. Parsons, J. Rafferty, S. Zilles || +# RFC2303 || C. Allocchio || +# RFC2304 || C. Allocchio || +# RFC2305 || K. Toyoda, H. Ohno, J. Murai, D. Wing || +# RFC2306 || G. Parsons, J. Rafferty || +# RFC2307 || L. Howard || lukeh@xedoc.com +# RFC2308 || M. Andrews || Mark.Andrews@cmis.csiro.au +# RFC2309 || B. Braden, D. Clark, J. Crowcroft, B. Davie, S. Deering, D. Estrin, S. Floyd, V. Jacobson, G. Minshall, C. Partridge, L. Peterson, K. Ramakrishnan, S. Shenker, J. Wroclawski, L. Zhang || Braden@ISI.EDU, DDC@lcs.mit.edu, Jon.Crowcroft@cs.ucl.ac.uk, bdavie@cisco.com, deering@cisco.com, Estrin@usc.edu, Floyd@ee.lbl.gov, Van@ee.lbl.gov, Minshall@fiberlane.com, craig@bbn.com, LLP@cs.arizona.edu, KKRama@research.att.com, Shenker@parc.xerox.com, JTW@lcs.mit.edu, Lixia@cs.ucla.edu +# RFC2310 || K. Holtman || koen@win.tue.nl +# RFC2311 || S. Dusse, P. Hoffman, B. Ramsdell, L. Lundblade, L. Repka || spock@rsa.com, phoffman@imc.org, blaker@deming.com, lgl@qualcomm.com, repka@netscape.com +# RFC2312 || S. Dusse, P. Hoffman, B. Ramsdell, J. Weinstein || spock@rsa.com, phoffman@imc.org, blaker@deming.com, jsw@netscape.com +# RFC2313 || B. Kaliski || burt@rsa.com +# RFC2314 || B. Kaliski || burt@rsa.com +# RFC2315 || B. Kaliski || burt@rsa.com +# RFC2316 || S. Bellovin || +# RFC2317 || H. Eidnes, G. de Groot, P. Vixie || Havard.Eidnes@runit.sintef.no, GeertJan.deGroot@bsdi.com, paul@vix.com +# RFC2318 || H. Lie, B. Bos, C. Lilley || howcome@w3.org, bert@w3.org, chris@w3.org +# RFC2319 || KOI8-U Working Group || +# RFC2320 || M. Greene, J. Luciani, K. White, T. Kuo || maria@xedia.com, luciani@baynetworks.com, kennethw@vnet.ibm.com, ted_kuo@Baynetworks.com +# RFC2321 || A. Bressen || bressen@leftbank.com +# RFC2322 || K. van den Hout, A. Koopal, R. van Mook || koos@cetis.hvu.nl, andre@NL.net, remco@sateh.com +# RFC2323 || A. Ramos || ramos@isi.edu +# RFC2324 || L. Masinter || masinter@parc.xerox.com +# RFC2325 || M. Slavitch || slavitch@loran.com +# RFC2326 || H. Schulzrinne, A. Rao, R. Lanphier || schulzrinne@cs.columbia.edu, anup@netscape.com, robla@real.com +# RFC2327 || M. Handley, V. Jacobson || +# RFC2328 || J. Moy || jmoy@casc.com +# RFC2329 || J. Moy || jmoy@casc.com +# RFC2330 || V. Paxson, G. Almes, J. Mahdavi, M. Mathis || vern@ee.lbl.gov, almes@advanced.org, mahdavi@psc.edu, mathis@psc.edu +# RFC2331 || M. Maher || maher@isi.edu +# RFC2332 || J. Luciani, D. Katz, D. Piscitello, B. Cole, N. Doraswamy || dkatz@cisco.com, luciani@baynetworks.com, bcole@jnx.com, naganand@baynetworks.com +# RFC2333 || D. Cansever || dcansever@gte.com +# RFC2334 || J. Luciani, G. Armitage, J. Halpern, N. Doraswamy || luciani@baynetworks.com, gja@lucent.com, jhalpern@Newbridge.COM, naganand@baynetworks.com +# RFC2335 || J. Luciani || luciani@baynetworks.com +# RFC2336 || J. Luciani || +# RFC2337 || D. Farinacci, D. Meyer, Y. Rekhter || +# RFC2338 || S. Knight, D. Weaver, D. Whipple, R. Hinden, D. Mitzel, P. Hunt, P. Higginson, M. Shand, A. Lindem || Steven.Knight@ascend.com, Doug.Weaver@ascend.com, dwhipple@microsoft.com, bob.hinden@gmail.com, mitzel@iprg.nokia.com, hunt@iprg.nokia.com, higginson@mail.dec.com, shand@mail.dec.com +# RFC2339 || The Internet Society, Sun Microsystems || +# RFC2340 || B. Jamoussi, D. Jamieson, D. Williston, S. Gabe || jamoussi@Nortel.ca, djamies@Nortel.ca, danwil@Nortel.ca, spgabe@Nortel.ca +# RFC2341 || A. Valencia, M. Littlewood, T. Kolar || tkolar@cisco.com, littlewo@cisco.com, valencia@cisco.com +# RFC2342 || M. Gahrns, C. Newman || mikega@microsoft.com, chris.newman@innosoft.com +# RFC2343 || M. Civanlar, G. Cash, B. Haskell || civanlar@research.att.com, glenn@research.att.com, bgh@research.att.com +# RFC2344 || G. Montenegro, Ed. || +# RFC2345 || J. Klensin, T. Wolf, G. Oglesby || klensin@mci.net, ted@usa.net, gary@mci.net +# RFC2346 || J. Palme || jpalme@dsv.su.se +# RFC2347 || G. Malkin, A. Harkin || gmalkin@baynetworks.com, ash@cup.hp.com +# RFC2348 || G. Malkin, A. Harkin || gmalkin@baynetworks.com, ash@cup.hp.com +# RFC2349 || G. Malkin, A. Harkin || gmalkin@baynetworks.com, ash@cup.hp.com +# RFC2350 || N. Brownlee, E. Guttman || n.brownlee@auckland.ac.nz, Erik.Guttman@sun.com +# RFC2351 || A. Robert || arobert@par1.par.sita.int +# RFC2352 || O. Vaughan || owain@vaughan.com +# RFC2353 || G. Dudley || dudleyg@us.ibm.com +# RFC2354 || C. Perkins, O. Hodson || c.perkins@cs.ucl.ac.uk, o.hodson@cs.ucl.ac.uk +# RFC2355 || B. Kelly || kellywh@mail.auburn.edu +# RFC2356 || G. Montenegro, V. Gupta || gabriel.montenegro@Eng.Sun.COM, vipul.gupta@Eng.Sun.COM +# RFC2357 || A. Mankin, A. Romanow, S. Bradner, V. Paxson || mankin@east.isi.edu, allyn@mci.net, sob@harvard.edu, vern@ee.lbl.gov +# RFC2358 || J. Flick, J. Johnson || johnf@hprnd.rose.hp.com, jeff@redbacknetworks.com +# RFC2359 || J. Myers || jgmyers@netscape.com +# RFC2360 || G. Scott || +# RFC2361 || E. Fleischman || ericfl@microsoft.com, Eric.Fleischman@PSS.Boeing.com +# RFC2362 || D. Estrin, D. Farinacci, A. Helmy, D. Thaler, S. Deering, M. Handley, V. Jacobson, C. Liu, P. Sharma, L. Wei || estrin@usc.edu, dino@cisco.com, ahelmy@catarina.usc.edu, thalerd@eecs.umich.edu, deering@parc.xerox.com, m.handley@cs.ucl.ac.uk, van@ee.lbl.gov, charley@catarina.usc.edu, puneet@catarina.usc.edu, lwei@cisco.com +# RFC2363 || G. Gross, M. Kaycee, A. Li, A. Malis, J. Stephens || gmgross@lucent.com, mjk@nj.paradyne.com, alin@shastanets.com, malis@ascend.com, john@cayman.com +# RFC2364 || G. Gross, M. Kaycee, A. Li, A. Malis, J. Stephens || gmgross@lucent.com, mjk@nj.paradyne.com, alin@shastanets.com, malis@ascend.com, john@cayman.com +# RFC2365 || D. Meyer || dmm@cisco.com +# RFC2366 || C. Chung, M. Greene || cchung@tieo.saic.com +# RFC2367 || D. McDonald, C. Metz, B. Phan || danmcd@eng.sun.com, cmetz@inner.net, phan@itd.nrl.navy.mil +# RFC2368 || P. Hoffman, L. Masinter, J. Zawinski || +# RFC2369 || G. Neufeld, J. Baer || +# RFC2370 || R. Coltun || +# RFC2371 || J. Lyon, K. Evans, J. Klein || JimLyon@Microsoft.Com, Keith.Evans@Tandem.Com, Johannes.Klein@Tandem.Com +# RFC2372 || K. Evans, J. Klein, J. Lyon || Keith.Evans@Tandem.Com, Johannes.Klein@Tandem.Com, JimLyon@Microsoft.Com +# RFC2373 || R. Hinden, S. Deering || bob.hinden@gmail.com +# RFC2374 || R. Hinden, M. O'Dell, S. Deering || bob.hinden@gmail.com, mo@uunet.uu.net, deering@cisco.com +# RFC2375 || R. Hinden, S. Deering || bob.hinden@gmail.com, deering@cisco.com +# RFC2376 || E. Whitehead, M. Murata || +# RFC2377 || A. Grimstad, R. Huber, S. Sataluri, M. Wahl || alg@att.com, rvh@att.com, srs@lucent.com, M.Wahl@critical-angle.com +# RFC2378 || R. Hedberg, P. Pomes || Roland.Hedberg@umdac.umu.se, ppomes@qualcomm.com +# RFC2379 || L. Berger || lberger@fore.com +# RFC2380 || L. Berger || lberger@fore.com +# RFC2381 || M. Garrett, M. Borden || mwg@bellcore.com, mborden@baynetworks.com +# RFC2382 || E. Crawley, Ed., L. Berger, S. Berson, F. Baker, M. Borden, J. Krawczyk || esc@argon.com, lberger@fore.com, berson@isi.edu, fred@cisco.com, mborden@baynetworks.com, jj@arrowpoint.com +# RFC2383 || M. Suzuki || suzuki@nal.ecl.net +# RFC2384 || R. Gellens || Randy@Qualcomm.Com +# RFC2385 || A. Heffernan || ahh@cisco.com +# RFC2386 || E. Crawley, R. Nair, B. Rajagopalan, H. Sandick || +# RFC2387 || E. Levinson || XIson@cnj.digex.com +# RFC2388 || L. Masinter || masinter@parc.xerox.com +# RFC2389 || P. Hethmon, R. Elz || +# RFC2390 || T. Bradley, C. Brown, A. Malis || tbradley@avici.com, cbrown@juno.com, malis@ascend.com +# RFC2391 || P. Srisuresh, D. Gan || suresh@ra.lucent.com, dhg@juniper.net +# RFC2392 || E. Levinson || XIson@cnj.digex.net +# RFC2393 || A. Shacham, R. Monsour, R. Pereira, M. Thomas || shacham@cisco.com, rmonsour@hifn.com, rpereira@timestep.com, matt.thomas@altavista-software.com, naganand@baynetworks.com +# RFC2394 || R. Pereira || +# RFC2395 || R. Friend, R. Monsour || rfriend@hifn.com, rmonsour@hifn.com +# RFC2396 || T. Berners-Lee, R. Fielding, L. Masinter || timbl@w3.org, fielding@ics.uci.edu, masinter@parc.xerox.com +# RFC2397 || L. Masinter || +# RFC2398 || S. Parker, C. Schmechel || sparker@eng.sun.com, cschmec@eng.sun.com +# RFC2399 || A. Ramos || ramos@isi.edu +# RFC2400 || J. Postel, J. Reynolds || Postel@ISI.EDU, JKRey@ISI.EDU +# RFC2401 || S. Kent, R. Atkinson || +# RFC2402 || S. Kent, R. Atkinson || +# RFC2403 || C. Madson, R. Glenn || +# RFC2404 || C. Madson, R. Glenn || +# RFC2405 || C. Madson, N. Doraswamy || +# RFC2406 || S. Kent, R. Atkinson || +# RFC2407 || D. Piper || ddp@network-alchemy.com +# RFC2408 || D. Maughan, M. Schertler, M. Schneider, J. Turner || wdm@tycho.ncsc.mil, mss@tycho.ncsc.mil, mjs@securify.com, jeff.turner@raba.com +# RFC2409 || D. Harkins, D. Carrel || dharkins@cisco.com, carrel@ipsec.org +# RFC2410 || R. Glenn, S. Kent || +# RFC2411 || R. Thayer, N. Doraswamy, R. Glenn || naganand@baynetworks.com, rob.glenn@nist.gov +# RFC2412 || H. Orman || ho@darpa.mil +# RFC2413 || S. Weibel, J. Kunze, C. Lagoze, M. Wolf || weibel@oclc.org, jak@ckm.ucsf.edu, lagoze@cs.cornell.edu, misha.wolf@reuters.com +# RFC2414 || M. Allman, S. Floyd, C. Partridge || mallman@lerc.nasa.gov, floyd@ee.lbl.gov, craig@bbn.com +# RFC2415 || K. Poduri, K. Nichols || kpoduri@Baynetworks.com, knichols@baynetworks.com +# RFC2416 || T. Shepard, C. Partridge || shep@alum.mit.edu, craig@bbn.com +# RFC2417 || C. Chung, M. Greene || chihschung@aol.com, maria@xedia.com +# RFC2418 || S. Bradner || +# RFC2419 || K. Sklower, G. Meyer || sklower@CS.Berkeley.EDU +# RFC2420 || H. Kummert || kummert@nentec.de +# RFC2421 || G. Vaudreuil, G. Parsons || Glenn.Parsons@Nortel.ca, GregV@Lucent.Com +# RFC2422 || G. Vaudreuil, G. Parsons || Glenn.Parsons@Nortel.ca, GregV@Lucent.Com +# RFC2423 || G. Vaudreuil, G. Parsons || Glenn.Parsons@Nortel.ca, GregV@Lucent.Com +# RFC2424 || G. Vaudreuil, G. Parsons || Glenn.Parsons@Nortel.ca, GregV@Lucent.Com +# RFC2425 || T. Howes, M. Smith, F. Dawson || howes@netscape.com, mcs@netscape.com, frank_dawson@lotus.com +# RFC2426 || F. Dawson, T. Howes || +# RFC2427 || C. Brown, A. Malis || cbrown@juno.com, malis@ascend.com +# RFC2428 || M. Allman, S. Ostermann, C. Metz || mallman@lerc.nasa.gov, ostermann@cs.ohiou.edu, cmetz@inner.net +# RFC2429 || C. Bormann, L. Cline, G. Deisher, T. Gardos, C. Maciocco, D. Newell, J. Ott, G. Sullivan, S. Wenger, C. Zhu || +# RFC2430 || T. Li, Y. Rekhter || tli@juniper.net, yakov@cisco.com +# RFC2431 || D. Tynan || dtynan@claddagh.ie +# RFC2432 || K. Dubray || kdubray@ironbridgenetworks.com +# RFC2433 || G. Zorn, S. Cobb || glennz@microsoft.com, stevec@microsoft.com +# RFC2434 || T. Narten, H. Alvestrand || narten@raleigh.ibm.com, Harald@Alvestrand.no +# RFC2435 || L. Berc, W. Fenner, R. Frederick, S. McCanne, P. Stewart || berc@pa.dec.com, fenner@parc.xerox.com, frederick@parc.xerox.com, mccanne@cs.berkeley.edu, stewart@parc.xerox.com +# RFC2436 || R. Brett, S. Bradner, G. Parsons || rfbrett@nortel.ca, sob@harvard.edu, Glenn.Parsons@Nortel.ca +# RFC2437 || B. Kaliski, J. Staddon || burt@rsa.com, jstaddon@rsa.com +# RFC2438 || M. O'Dell, H. Alvestrand, B. Wijnen, S. Bradner || mo@uu.net, Harald.Alvestrand@maxware.no, wijnen@vnet.ibm.com, sob@harvard.edu +# RFC2439 || C. Villamizar, R. Chandra, R. Govindan || curtis@ans.net, rchandra@cisco.com, govindan@isi.edu +# RFC2440 || J. Callas, L. Donnerhacke, H. Finney, R. Thayer || +# RFC2441 || D. Cohen || cohen@myri.com +# RFC2442 || N. Freed, D. Newman, J. Belissent, M. Hoy || ned.freed@innosoft.com, dan.newman@innosoft.com, jacques.belissent@eng.sun.com +# RFC2443 || J. Luciani, A. Gallo || luciani@baynetworks.com, gallo@raleigh.ibm.com +# RFC2444 || C. Newman || chris.newman@innosoft.com +# RFC2445 || F. Dawson, D. Stenerson || +# RFC2446 || S. Silverberg, S. Mansour, F. Dawson, R. Hopson || +# RFC2447 || F. Dawson, S. Mansour, S. Silverberg || +# RFC2448 || M. Civanlar, G. Cash, B. Haskell || civanlar@research.att.com, glenn@research.att.com, bgh@research.att.com +# RFC2449 || R. Gellens, C. Newman, L. Lundblade || randy@qualcomm.com, chris.newman@innosoft.com, lgl@qualcomm.com +# RFC2450 || R. Hinden || bob.hinden@gmail.com +# RFC2451 || R. Pereira, R. Adams || +# RFC2452 || M. Daniele || daniele@zk3.dec.com +# RFC2453 || G. Malkin || gmalkin@baynetworks.com +# RFC2454 || M. Daniele || daniele@zk3.dec.com +# RFC2455 || B. Clouston, B. Moore || clouston@cisco.com, remoore@us.ibm.com +# RFC2456 || B. Clouston, B. Moore || clouston@cisco.com, remoore@us.ibm.com +# RFC2457 || B. Clouston, B. Moore || clouston@cisco.com, remoore@us.ibm.com +# RFC2458 || H. Lu, M. Krishnaswamy, L. Conroy, S. Bellovin, F. Burg, A. DeSimone, K. Tewani, P. Davidson, H. Schulzrinne, K. Vishwanathan || smb@research.att.com, fburg@hogpb.att.com, lwc@roke.co.uk, pauldav@nortel.ca, murali@bell-labs.com, hui-lan.lu@bell-labs.com, schulzrinne@cs.columbia.edu, tewani@att.com, kumar@isochrone.com +# RFC2459 || R. Housley, W. Ford, W. Polk, D. Solo || housley@spyrus.com, wford@verisign.com, wpolk@nist.gov, david.solo@citicorp.com +# RFC2460 || S. Deering, R. Hinden || deering@cisco.com, bob.hinden@gmail.com +# RFC2461 || T. Narten, E. Nordmark, W. Simpson || narten@raleigh.ibm.com, nordmark@sun.com, Bill.Simpson@um.cc.umich.edu +# RFC2462 || S. Thomson, T. Narten || +# RFC2463 || A. Conta, S. Deering || aconta@lucent.com, deering@cisco.com +# RFC2464 || M. Crawford || crawdad@fnal.gov +# RFC2465 || D. Haskin, S. Onishi || dhaskin@baynetworks.com, sonishi@baynetworks.com +# RFC2466 || D. Haskin, S. Onishi || dhaskin@baynetworks.com, sonishi@baynetworks.com +# RFC2467 || M. Crawford || crawdad@fnal.gov +# RFC2468 || V. Cerf || vcerf@mci.net +# RFC2469 || T. Narten, C. Burton || narten@raleigh.ibm.com, burton@rtp.vnet.ibm.com +# RFC2470 || M. Crawford, T. Narten, S. Thomas || crawdad@fnal.gov, narten@raleigh.ibm.com, stephen.thomas@transnexus.com +# RFC2471 || R. Hinden, R. Fink, J. Postel || bob.hinden@gmail.com, rlfink@lbl.gov +# RFC2472 || D. Haskin, E. Allen || dhaskin@baynetworks.com, eallen@baynetworks.com +# RFC2473 || A. Conta, S. Deering || aconta@lucent.com, deering@cisco.com +# RFC2474 || K. Nichols, S. Blake, F. Baker, D. Black || kmn@cisco.com, slblake@torrentnet.com, fred@cisco.com, black_david@emc.com +# RFC2475 || S. Blake, D. Black, M. Carlson, E. Davies, Z. Wang, W. Weiss || slblake@torrentnet.com, black_david@emc.com, mark.carlson@sun.com, elwynd@nortel.co.uk, zhwang@bell-labs.com, wweiss@lucent.com +# RFC2476 || R. Gellens, J. Klensin || Randy@Qualcomm.Com, klensin@mci.net +# RFC2477 || B. Aboba, G. Zorn || bernarda@microsoft.com, glennz@microsoft.com +# RFC2478 || E. Baize, D. Pinkas || +# RFC2479 || C. Adams || cadams@entrust.com +# RFC2480 || N. Freed || ned.freed@innosoft.com +# RFC2481 || K. Ramakrishnan, S. Floyd || +# RFC2482 || K. Whistler, G. Adams || kenw@sybase.com, glenn@spyglass.com +# RFC2483 || M. Mealling, R. Daniel || michaelm@rwhois.net, rdaniel@lanl.gov +# RFC2484 || G. Zorn || glennz@microsoft.com +# RFC2485 || S. Drach || drach@sun.com +# RFC2486 || B. Aboba, M. Beadles || bernarda@microsoft.com, mbeadles@wcom.net +# RFC2487 || P. Hoffman || phoffman@imc.org +# RFC2488 || M. Allman, D. Glover, L. Sanchez || mallman@lerc.nasa.gov, Daniel.R.Glover@lerc.nasa.gov, lsanchez@ir.bbn.com +# RFC2489 || R. Droms || droms@bucknell.edu +# RFC2490 || M. Pullen, R. Malghan, L. Lavu, G. Duan, J. Ma, H. Nah || mpullen@gmu.edu, rmalghan@bacon.gmu.edu, llavu@bacon.gmu.edu, gduan@us.oracle.com, jma@newbridge.com, hnah@bacon.gmu.edu +# RFC2491 || G. Armitage, P. Schulter, M. Jork, G. Harter || gja@lucent.com, paschulter@acm.org, jork@kar.dec.com, harter@zk3.dec.com +# RFC2492 || G. Armitage, P. Schulter, M. Jork || gja@lucent.com, paschulter@acm.org, jork@kar.dec.com +# RFC2493 || K. Tesink, Ed. || kaj@bellcore.com +# RFC2494 || D. Fowler, Ed. || davef@newbridge.com +# RFC2495 || D. Fowler, Ed. || davef@newbridge.com +# RFC2496 || D. Fowler, Ed. || davef@newbridge.com +# RFC2497 || I. Souvatzis || is@netbsd.org +# RFC2498 || J. Mahdavi, V. Paxson || mahdavi@psc.edu, vern@ee.lbl.gov +# RFC2499 || A. Ramos || ramos@isi.edu +# RFC2500 || J. Reynolds, R. Braden || +# RFC2501 || S. Corson, J. Macker || corson@isr.umd.edu, macker@itd.nrl.navy.mil +# RFC2502 || M. Pullen, M. Myjak, C. Bouwens || mpullen@gmu.edu, mmyjak@virtualworkshop.com, christina.bouwens@cpmx.mail.saic.com +# RFC2503 || R. Moulton, M. Needleman || ruth@muswell.demon.co.uk +# RFC2504 || E. Guttman, L. Leong, G. Malkin || erik.guttman@sun.com, lorna@colt.net, gmalkin@baynetworks.com +# RFC2505 || G. Lindberg || +# RFC2506 || K. Holtman, A. Mutz, T. Hardie || koen@win.tue.nl, andy_mutz@hp.com, hardie@equinix.com +# RFC2507 || M. Degermark, B. Nordgren, S. Pink || micke@sm.luth.se, bcn@lulea.trab.se, steve@sm.luth.se +# RFC2508 || S. Casner, V. Jacobson || casner@cisco.com, van@cisco.com +# RFC2509 || M. Engan, S. Casner, C. Bormann || engan@effnet.com, casner@cisco.com, cabo@tzi.org +# RFC2510 || C. Adams, S. Farrell || cadams@entrust.com, stephen.farrell@sse.ie +# RFC2511 || M. Myers, C. Adams, D. Solo, D. Kemp || mmyers@verisign.com, cadams@entrust.com, david.solo@citicorp.com, dpkemp@missi.ncsc.mil +# RFC2512 || K. McCloghrie, J. Heinanen, W. Greene, A. Prasad || kzm@cisco.com, jh@telia.fi, wedge.greene@mci.com, aprasad@cisco.com +# RFC2513 || K. McCloghrie, J. Heinanen, W. Greene, A. Prasad || kzm@cisco.com, jh@telia.fi, wedge.greene@mci.com, aprasad@cisco.com +# RFC2514 || M. Noto, E. Spiegel, K. Tesink || mspiegel@cisco.com, kaj@bellcore.com +# RFC2515 || K. Tesink, Ed || kaj@bellcore.com +# RFC2516 || L. Mamakos, K. Lidl, J. Evarts, D. Carrel, D. Simone, R. Wheeler || louie@uu.net, lidl@uu.net, jde@uu.net, carrel@RedBack.net, dan@RedBack.net, ross@routerware.com +# RFC2517 || R. Moats, R. Huber || jayhawk@att.com, rvh@att.com +# RFC2518 || Y. Goland, E. Whitehead, A. Faizi, S. Carter, D. Jensen || yarong@microsoft.com, ejw@ics.uci.edu, asad@netscape.com, srcarter@novell.com, dcjensen@novell.com +# RFC2519 || E. Chen, J. Stewart || enkechen@cisco.com, jstewart@juniper.net +# RFC2520 || J. Luciani, H. Suzuki, N. Doraswamy, D. Horton || luciani@baynetworks.com, hsuzuki@cisco.com, naganand@baynetworks.com, d.horton@citr.com.au +# RFC2521 || P. Karn, W. Simpson || +# RFC2522 || P. Karn, W. Simpson || +# RFC2523 || P. Karn, W. Simpson || +# RFC2524 || M. Banan || +# RFC2525 || V. Paxson, M. Allman, S. Dawson, W. Fenner, J. Griner, I. Heavens, K. Lahey, J. Semke, B. Volz || vern@aciri.org, sdawson@eecs.umich.edu, fenner@parc.xerox.com, jgriner@grc.nasa.gov, ian@spider.com, kml@nas.nasa.gov, semke@psc.edu, volz@process.com +# RFC2526 || D. Johnson, S. Deering || dbj@cs.cmu.edu, deering@cisco.com +# RFC2527 || S. Chokhani, W. Ford || +# RFC2528 || R. Housley, W. Polk || housley@spyrus.com, wpolk@nist.gov +# RFC2529 || B. Carpenter, C. Jung || brian@hursley.ibm.com, cmj@3Com.com +# RFC2530 || D. Wing || dwing-ietf@fuggles.com +# RFC2531 || G. Klyne, L. McIntyre || GK@ACM.ORG, Lloyd.McIntyre@pahv.xerox.com +# RFC2532 || L. Masinter, D. Wing || masinter@parc.xerox.com, dwing-ietf@fuggles.com +# RFC2533 || G. Klyne || GK@ACM.ORG +# RFC2534 || L. Masinter, D. Wing, A. Mutz, K. Holtman || masinter@parc.xerox.com, dwing-ietf@fuggles.com, koen@win.tue.nl +# RFC2535 || D. Eastlake 3rd || dee3@us.ibm.com +# RFC2536 || D. Eastlake 3rd || dee3@us.ibm.com +# RFC2537 || D. Eastlake 3rd || dee3@us.ibm.com +# RFC2538 || D. Eastlake 3rd, O. Gudmundsson || dee3@us.ibm.com, ogud@tislabs.com +# RFC2539 || D. Eastlake 3rd || dee3@us.ibm.com +# RFC2540 || D. Eastlake 3rd || dee3@us.ibm.com +# RFC2541 || D. Eastlake 3rd || dee3@us.ibm.com +# RFC2542 || L. Masinter || masinter@parc.xerox.com +# RFC2543 || M. Handley, H. Schulzrinne, E. Schooler, J. Rosenberg || +# RFC2544 || S. Bradner, J. McQuaid || +# RFC2545 || P. Marques, F. Dupont || +# RFC2546 || A. Durand, B. Buclin || Alain.Durand@imag.fr, Bertrand.Buclin@ch.att.com +# RFC2547 || E. Rosen, Y. Rekhter || erosen@cisco.com, yakov@cisco.com +# RFC2548 || G. Zorn || +# RFC2549 || D. Waitzman || djw@vineyard.net +# RFC2550 || S. Glassman, M. Manasse, J. Mogul || steveg@pa.dec.com, msm@pa.dec.com, mogul@pa.dec.com +# RFC2551 || S. Bradner || +# RFC2552 || M. Blinov, M. Bessonov, C. Clissmann || mch@net-cs.ucd.ie, mikeb@net-cs.ucd.ie, ciaranc@net-cs.ucd.ie +# RFC2553 || R. Gilligan, S. Thomson, J. Bound, W. Stevens || gilligan@freegate.com, set@thumper.bellcore.com, bound@zk3.dec.com, rstevens@kohala.com +# RFC2554 || J. Myers || jgmyers@netscape.com +# RFC2555 || RFC Editor, et al. || braden@isi.edu, jkrey@isi.edu, crocker@mbl.edu, vcerf@mci.net, feinler@juno.com, celeste@isi.edu +# RFC2556 || S. Bradner || sob@harvard.edu +# RFC2557 || J. Palme, A. Hopmann, N. Shelness || jpalme@dsv.su.se, alexhop@microsoft.com, Shelness@lotus.com, stef@nma.com +# RFC2558 || K. Tesink || kaj@research.telcordia.com +# RFC2559 || S. Boeyen, T. Howes, P. Richard || sharon.boeyen@entrust.com, howes@netscape.com, patr@xcert.com +# RFC2560 || M. Myers, R. Ankney, A. Malpani, S. Galperin, C. Adams || mmyers@verisign.com, rankney@erols.com, ambarish@valicert.com, galperin@mycfo.com, cadams@entrust.com +# RFC2561 || K. White, R. Moore || kennethw@vnet.ibm.com, remoore@us.ibm.com +# RFC2562 || K. White, R. Moore || kennethw@vnet.ibm.com, remoore@us.ibm.com +# RFC2563 || R. Troll || rtroll@corp.home.net +# RFC2564 || C. Kalbfleisch, C. Krupczak, R. Presuhn, J. Saperia || cwk@verio.net, cheryl@empiretech.com, randy_presuhn@bmc.com, saperia@mediaone.net +# RFC2565 || R. Herriot, Ed., S. Butler, P. Moore, R. Turner || rherriot@pahv.xerox.com, sbutler@boi.hp.com, paulmo@microsoft.com, rturner@sharplabs.com, rherriot@pahv.xerox.com +# RFC2566 || R. deBry, T. Hastings, R. Herriot, S. Isaacson, P. Powell || sisaacson@novell.com, tom.hastings@alum.mit.edu, robert.herriot@pahv.xerox.com, debryro@uvsc.edu, papowell@astart.com +# RFC2567 || F. Wright || +# RFC2568 || S. Zilles || +# RFC2569 || R. Herriot, Ed., T. Hastings, N. Jacobs, J. Martin || rherriot@pahv.xerox.com, Norm.Jacobs@Central.sun.com, tom.hastings@alum.mit.edu, jkm@underscore.com +# RFC2570 || J. Case, R. Mundy, D. Partain, B. Stewart || +# RFC2571 || B. Wijnen, D. Harrington, R. Presuhn || +# RFC2572 || J. Case, D. Harrington, R. Presuhn, B. Wijnen || +# RFC2573 || D. Levi, P. Meyer, B. Stewart || +# RFC2574 || U. Blumenthal, B. Wijnen || +# RFC2575 || B. Wijnen, R. Presuhn, K. McCloghrie || +# RFC2576 || R. Frye, D. Levi, S. Routhier, B. Wijnen || +# RFC2577 || M. Allman, S. Ostermann || mallman@grc.nasa.gov, ostermann@cs.ohiou.edu +# RFC2578 || K. McCloghrie, Ed., D. Perkins, Ed., J. Schoenwaelder, Ed. || +# RFC2579 || K. McCloghrie, Ed., D. Perkins, Ed., J. Schoenwaelder, Ed. || +# RFC2580 || K. McCloghrie, Ed., D. Perkins, Ed., J. Schoenwaelder, Ed. || +# RFC2581 || M. Allman, V. Paxson, W. Stevens || mallman@grc.nasa.gov, vern@aciri.org, rstevens@kohala.com +# RFC2582 || S. Floyd, T. Henderson || +# RFC2583 || R. Carlson, L. Winkler || RACarlson@anl.gov, lwinkler@anl.gov +# RFC2584 || B. Clouston, B. Moore || clouston@cisco.com, remoore@us.ibm.com +# RFC2585 || R. Housley, P. Hoffman || housley@spyrus.com, phoffman@imc.org +# RFC2586 || J. Salsman, H. Alvestrand || James@bovik.org, Harald.T.Alvestrand@uninett.no +# RFC2587 || S. Boeyen, T. Howes, P. Richard || sharon.boeyen@entrust.com, howes@netscape.com, patr@xcert.com +# RFC2588 || R. Finlayson || finlayson@live.com +# RFC2589 || Y. Yaacovi, M. Wahl, T. Genovese || yoramy@microsoft.com, tonyg@microsoft.com +# RFC2590 || A. Conta, A. Malis, M. Mueller || aconta@lucent.com, malis@ascend.com, memueller@lucent.com +# RFC2591 || D. Levi, J. Schoenwaelder || +# RFC2592 || D. Levi, J. Schoenwaelder || +# RFC2593 || J. Schoenwaelder, J. Quittek || schoenw@ibr.cs.tu-bs.de, quittek@ccrle.nec.de +# RFC2594 || H. Hazewinkel, C. Kalbfleisch, J. Schoenwaelder || +# RFC2595 || C. Newman || chris.newman@innosoft.com +# RFC2596 || M. Wahl, T. Howes || M.Wahl@innosoft.com, howes@netscape.com +# RFC2597 || J. Heinanen, F. Baker, W. Weiss, J. Wroclawski || jh@telia.fi, fred@cisco.com, wweiss@lucent.com, jtw@lcs.mit.edu +# RFC2598 || V. Jacobson, K. Nichols, K. Poduri || van@cisco.com, kmn@cisco.com, kpoduri@baynetworks.com +# RFC2599 || A. DeLaCruz || delacruz@isi.edu +# RFC2600 || J. Reynolds, R. Braden || +# RFC2601 || M. Davison || mike.davison@cisco.com +# RFC2602 || M. Davison || mike.davison@cisco.com +# RFC2603 || M. Davison || mike.davison@cisco.com +# RFC2604 || R. Gellens || randy@qualcomm.com +# RFC2605 || G. Mansfield, S. Kille || glenn@cysols.com, Steve.Kille@MessagingDirect.com +# RFC2606 || D. Eastlake 3rd, A. Panitz || dee3@us.ibm.com, buglady@fuschia.net +# RFC2607 || B. Aboba, J. Vollbrecht || bernarda@microsoft.com, jrv@merit.edu +# RFC2608 || E. Guttman, C. Perkins, J. Veizades, M. Day || Erik.Guttman@sun.com, cperkins@sun.com, veizades@home.net, mday@vinca.com +# RFC2609 || E. Guttman, C. Perkins, J. Kempf || erik.guttman@sun.com, cperkins@sun.com, james.kempf@sun.com +# RFC2610 || C. Perkins, E. Guttman || Charles.Perkins@Sun.Com, Erik.Guttman@Sun.Com +# RFC2611 || L. Daigle, D. van Gulik, R. Iannella, P. Faltstrom || leslie@thinkingcat.com, Dirk.vanGulik@jrc.it, renato@dstc.edu.au, paf@swip.net +# RFC2612 || C. Adams, J. Gilchrist || carlisle.adams@entrust.com, jeff.gilchrist@entrust.com +# RFC2613 || R. Waterman, B. Lahaye, D. Romascanu, S. Waldbusser || rich@allot.com, dromasca@gmail.com , waldbusser@ins.com +# RFC2614 || J. Kempf, E. Guttman || james.kempf@sun.com, erik.guttman@sun.com +# RFC2615 || A. Malis, W. Simpson || malis@ascend.com, wsimpson@GreenDragon.com +# RFC2616 || R. Fielding, J. Gettys, J. Mogul, H. Frystyk, L. Masinter, P. Leach, T. Berners-Lee || fielding@ics.uci.edu, jg@w3.org, mogul@wrl.dec.com, frystyk@w3.org, masinter@parc.xerox.com, paulle@microsoft.com, timbl@w3.org +# RFC2617 || J. Franks, P. Hallam-Baker, J. Hostetler, S. Lawrence, P. Leach, A. Luotonen, L. Stewart || john@math.nwu.edu, pbaker@verisign.com, jeff@AbiSource.com, lawrence@agranat.com, paulle@microsoft.com, stewart@OpenMarket.com +# RFC2618 || B. Aboba, G. Zorn || bernarda@microsoft.com, glennz@microsoft.com +# RFC2619 || G. Zorn, B. Aboba || bernarda@microsoft.com, glennz@microsoft.com +# RFC2620 || B. Aboba, G. Zorn || bernarda@microsoft.com, glennz@microsoft.com +# RFC2621 || G. Zorn, B. Aboba || bernarda@microsoft.com, glennz@microsoft.com +# RFC2622 || C. Alaettinoglu, C. Villamizar, E. Gerich, D. Kessens, D. Meyer, T. Bates, D. Karrenberg, M. Terpstra || cengiz@isi.edu, curtis@avici.com, epg@home.net, David.Kessens@qwest.net, meyer@antc.uoregon.edu, tbates@cisco.com, dfk@ripe.net, marten@BayNetworks.com +# RFC2623 || M. Eisler || mre@eng.sun.com +# RFC2624 || S. Shepler || spencer.shepler@eng.sun.com +# RFC2625 || M. Rajagopal, R. Bhagwat, W. Rickard || murali@gadzoox.com, raj@gadzoox.com, wayne@gadzoox.com +# RFC2626 || P. Nesser II || +# RFC2627 || D. Wallner, E. Harder, R. Agee || dmwalln@orion.ncsc.mil, ejh@tycho.ncsc.mil +# RFC2628 || V. Smyslov || svan@trustworks.com +# RFC2629 || M. Rose || mrose17@gmail.com +# RFC2630 || R. Housley || housley@spyrus.com +# RFC2631 || E. Rescorla || ekr@rtfm.com +# RFC2632 || B. Ramsdell, Ed. || +# RFC2633 || B. Ramsdell, Ed. || +# RFC2634 || P. Hoffman, Ed. || phoffman@imc.org +# RFC2635 || S. Hambridge, A. Lunde || +# RFC2636 || R. Gellens || randy@qualcomm.com +# RFC2637 || K. Hamzeh, G. Pall, W. Verthein, J. Taarud, W. Little, G. Zorn || kory@ascend.com, gurdeep@microsoft.com, glennz@microsoft.com +# RFC2638 || K. Nichols, V. Jacobson, L. Zhang || kmn@cisco.com, van@cisco.com, lixia@cs.ucla.edu +# RFC2639 || T. Hastings, C. Manros || tom.hastings@alum.mit.edu, manros@cp10.es.xerox.com +# RFC2640 || B. Curtin || curtinw@ftm.disa.mil +# RFC2641 || D. Hamilton, D. Ruffen || daveh@ctron.com, ruffen@ctron.com +# RFC2642 || L. Kane || lkane@ctron.com +# RFC2643 || D. Ruffen, T. Len, J. Yanacek || ruffen@ctron.com, len@ctron.com, jyanacek@ctron.com +# RFC2644 || D. Senie || dts@senie.com +# RFC2645 || R. Gellens || randy@qualcomm.com +# RFC2646 || R. Gellens, Ed. || +# RFC2647 || D. Newman || +# RFC2648 || R. Moats || jayhawk@att.com +# RFC2649 || B. Greenblatt, P. Richard || bgreenblatt@directory-applications.com, patr@xcert.com +# RFC2650 || D. Meyer, J. Schmitz, C. Orange, M. Prior, C. Alaettinoglu || dmm@cisco.com, SchmitzJo@aol.com, orange@spiritone.com, mrp@connect.com.au, cengiz@isi.edu +# RFC2651 || J. Allen, M. Mealling || jeff.allen@acm.org, michael.mealling@RWhois.net +# RFC2652 || J. Allen, M. Mealling || jeff.allen@acm.org, michael.mealling@RWhois.net +# RFC2653 || J. Allen, P. Leach, R. Hedberg || jeff.allen@acm.org, paulle@microsoft.com, roland@catalogix.ac.se +# RFC2654 || R. Hedberg, B. Greenblatt, R. Moats, M. Wahl || roland@catalogix.ac.se, bgreenblatt@directory-applications.com, jayhawk@att.com +# RFC2655 || T. Hardie, M. Bowman, D. Hardy, M. Schwartz, D. Wessels || hardie@equinix.com, mic@transarc.com, dhardy@netscape.com, wessels@nlanr.net +# RFC2656 || T. Hardie || hardie@equinix.com +# RFC2657 || R. Hedberg || roland@catalogix.ac.se +# RFC2658 || K. McKay || kylem@qualcomm.com +# RFC2659 || E. Rescorla, A. Schiffman || ekr@rtfm.com, ams@terisa.com +# RFC2660 || E. Rescorla, A. Schiffman || ekr@rtfm.com, ams@terisa.com +# RFC2661 || W. Townsley, A. Valencia, A. Rubens, G. Pall, G. Zorn, B. Palter || gurdeep@microsoft.com, palter@zev.net, acr@del.com, townsley@cisco.com, vandys@cisco.com, gwz@acm.org +# RFC2662 || G. Bathrick, F. Ly || bathricg@agcs.com, faye@coppermountain.com +# RFC2663 || P. Srisuresh, M. Holdrege || srisuresh@lucent.com, holdrege@lucent.com +# RFC2664 || R. Plzak, A. Wells, E. Krol || plzakr@saic.com, awel@cs.wisc.edu, krol@uiuc.edu +# RFC2665 || J. Flick, J. Johnson || johnf@rose.hp.com, jeff@redbacknetworks.com +# RFC2666 || J. Flick || johnf@rose.hp.com +# RFC2667 || D. Thaler || dthaler@microsoft.com +# RFC2668 || A. Smith, J. Flick, K. de Graaf, D. Romascanu, D. McMaster, K. McCloghrie, S. Roberts || andrew@extremenetworks.com, johnf@rose.hp.com, kdegraaf@argon.com, dromasca@gmail.com , mcmaster@cisco.com, kzm@cisco.com, sroberts@farallon.com +# RFC2669 || M. St. Johns, Ed. || stjohns@corp.home.net +# RFC2670 || M. St. Johns, Ed. || stjohns@corp.home.net +# RFC2671 || P. Vixie || vixie@isc.org +# RFC2672 || M. Crawford || crawdad@fnal.gov +# RFC2673 || M. Crawford || crawdad@fnal.gov +# RFC2674 || E. Bell, A. Smith, P. Langille, A. Rijhsinghani, K. McCloghrie || Les_Bell@3Com.com, andrew@extremenetworks.com, langille@newbridge.com, anil@cabletron.com, kzm@cisco.com +# RFC2675 || D. Borman, S. Deering, R. Hinden || dab@bsdi.com, deering@cisco.com, bob.hinden@gmail.com +# RFC2676 || G. Apostolopoulos, S. Kama, D. Williams, R. Guerin, A. Orda, T. Przygienda || georgeap@watson.ibm.com, guerin@ee.upenn.edu, ariel@ee.technion.ac.il, dougw@watson.ibm.com +# RFC2677 || M. Greene, J. Cucchiara, J. Luciani || luciani@baynetworks.com, maria@xedia.com, joan@ironbridgenetworks.com +# RFC2678 || J. Mahdavi, V. Paxson || mahdavi@psc.edu, vern@ee.lbl.gov +# RFC2679 || G. Almes, S. Kalidindi, M. Zekauskas || almes@advanced.org, kalidindi@advanced.org, matt@advanced.org +# RFC2680 || G. Almes, S. Kalidindi, M. Zekauskas || almes@advanced.org, kalidindi@advanced.org, matt@advanced.org +# RFC2681 || G. Almes, S. Kalidindi, M. Zekauskas || almes@advanced.org, kalidindi@advanced.org, matt@advanced.org +# RFC2682 || I. Widjaja, A. Elwalid || indra.widjaja@fnc.fujitsu.com, anwar@lucent.com +# RFC2683 || B. Leiba || leiba@watson.ibm.com +# RFC2684 || D. Grossman, J. Heinanen || dan@dma.isg.mot.com, jh@telia.fi +# RFC2685 || B. Fox, B. Gleeson || barbarafox@lucent.com, bgleeson@shastanets.com +# RFC2686 || C. Bormann || cabo@tzi.org +# RFC2687 || C. Bormann || cabo@tzi.org +# RFC2688 || S. Jackowski, D. Putzolu, E. Crawley, B. Davie || stevej@DeterministicNetworks.com, David.Putzolu@intel.com, esc@argon.com, bdavie@cisco.com +# RFC2689 || C. Bormann || cabo@tzi.org +# RFC2690 || S. Bradner || +# RFC2691 || S. Bradner || +# RFC2692 || C. Ellison || carl.m.ellison@intel.com +# RFC2693 || C. Ellison, B. Frantz, B. Lampson, R. Rivest, B. Thomas, T. Ylonen || carl.m.ellison@intel.com, frantz@netcom.com, blampson@microsoft.com, rivest@theory.lcs.mit.edu, bt0008@sbc.com, ylo@ssh.fi +# RFC2694 || P. Srisuresh, G. Tsirtsis, P. Akkiraju, A. Heffernan || srisuresh@yahoo.com, george@gideon.bt.co.uk, spa@cisco.com, ahh@juniper.net +# RFC2695 || A. Chiu || +# RFC2696 || C. Weider, A. Herron, A. Anantha, T. Howes || cweider@microsoft.com, andyhe@microsoft.com, anoopa@microsoft.com, howes@netscape.com +# RFC2697 || J. Heinanen, R. Guerin || jh@telia.fi, guerin@ee.upenn.edu +# RFC2698 || J. Heinanen, R. Guerin || jh@telia.fi, guerin@ee.upenn.edu +# RFC2699 || S. Ginoza || ginoza@isi.edu +# RFC2700 || J. Reynolds, R. Braden || +# RFC2701 || G. Malkin || +# RFC2702 || D. Awduche, J. Malcolm, J. Agogbua, M. O'Dell, J. McManus || awduche@uu.net, jmalcolm@uu.net, ja@uu.net, mo@uu.net, jmcmanus@uu.net +# RFC2703 || G. Klyne || GK@ACM.ORG +# RFC2704 || M. Blaze, J. Feigenbaum, J. Ioannidis, A. Keromytis || mab@research.att.com, jf@research.att.com, ji@research.att.com, angelos@dsl.cis.upenn.edu +# RFC2705 || M. Arango, A. Dugan, I. Elliott, C. Huitema, S. Pickett || marango@rslcom.com, andrew.dugan@l3.com, ike.elliott@l3.com, huitema@research.telcordia.com, ScottP@vertical.com +# RFC2706 || D. Eastlake 3rd, T. Goldstein || dee3@us.ibm.com, tgoldstein@brodia.com +# RFC2707 || R. Bergman, T. Hastings, S. Isaacson, H. Lewis || rbergma@dpc.com, tom.hastings@alum.mit.edu, scott_isaacson@novell.com, harryl@us.ibm.com +# RFC2708 || R. Bergman || rbergman@dpc.com, tom.hastings@alum.mit.edu, scott_isaacson@novell.com, harryl@us.ibm.com, bpenteco@boi.hp.com +# RFC2709 || P. Srisuresh || srisuresh@lucent.com +# RFC2710 || S. Deering, W. Fenner, B. Haberman || deering@cisco.com, fenner@research.att.com, haberman@raleigh.ibm.com +# RFC2711 || C. Partridge, A. Jackson || craig@bbn.com, awjacks@bbn.com +# RFC2712 || A. Medvinsky, M. Hur || amedvins@excitecorp.com, matt.hur@cybersafe.com +# RFC2713 || V. Ryan, S. Seligman, R. Lee || vincent.ryan@ireland.sun.com, scott.seligman@eng.sun.com, rosanna.lee@eng.sun.com +# RFC2714 || V. Ryan, R. Lee, S. Seligman || vincent.ryan@ireland.sun.com, rosanna.lee@eng.sun.com, scott.seligman@eng.sun.com +# RFC2715 || D. Thaler || dthaler@microsoft.com +# RFC2716 || B. Aboba, D. Simon || bernarda@microsoft.com, dansimon@microsoft.com +# RFC2717 || R. Petke, I. King || rpetke@wcom.net, iking@microsoft.com +# RFC2718 || L. Masinter, H. Alvestrand, D. Zigmond, R. Petke || masinter@parc.xerox.com, harald.alvestrand@maxware.no, djz@corp.webtv.net, rpetke@wcom.net +# RFC2719 || L. Ong, I. Rytina, M. Garcia, H. Schwarzbauer, L. Coene, H. Lin, I. Juhasz, M. Holdrege, C. Sharp || long@nortelnetworks.com, ian.rytina@ericsson.com, holdrege@lucent.com, lode.coene@siemens.atea.be, Miguel.A.Garcia@ericsson.com, chsharp@cisco.com, imre.i.juhasz@telia.se, hlin@research.telcordia.com, HannsJuergen.Schwarzbauer@icn.siemens.de +# RFC2720 || N. Brownlee || n.brownlee@auckland.ac.nz +# RFC2721 || N. Brownlee || n.brownlee@auckland.ac.nz +# RFC2722 || N. Brownlee, C. Mills, G. Ruth || n.brownlee@auckland.ac.nz, cmills@gte.com, gruth@bbn.com +# RFC2723 || N. Brownlee || n.brownlee@auckland.ac.nz +# RFC2724 || S. Handelman, S. Stibler, N. Brownlee, G. Ruth || swhandel@us.ibm.com, stibler@us.ibm.com, n.brownlee@auckland.ac.nz, gruth@bbn.com +# RFC2725 || C. Villamizar, C. Alaettinoglu, D. Meyer, S. Murphy || curtis@avici.com, cengiz@ISI.EDU, dmm@cisco.com, sandy@tis.com +# RFC2726 || J. Zsako || zsako@banknet.net +# RFC2727 || J. Galvin || +# RFC2728 || R. Panabaker, S. Wegerif, D. Zigmond || +# RFC2729 || P. Bagnall, R. Briscoe, A. Poppitt || pete@surfaceeffect.com, bob.briscoe@bt.com, apoppitt@jungle.bt.co.uk +# RFC2730 || S. Hanna, B. Patel, M. Shah || steve.hanna@sun.com, baiju.v.patel@intel.com, munils@microsoft.com +# RFC2731 || J. Kunze || jak@ckm.ucsf.edu +# RFC2732 || R. Hinden, B. Carpenter, L. Masinter || bob.hinden@gmail.com, brian@icair.org, LMM@acm.org +# RFC2733 || J. Rosenberg, H. Schulzrinne || schulzrinne@cs.columbia.edu +# RFC2734 || P. Johansson || +# RFC2735 || B. Fox, B. Petri || bfox@equipecom.com, bernhard.petri@icn.siemens.de +# RFC2736 || M. Handley, C. Perkins || mjh@aciri.org, C.Perkins@cs.ucl.ac.uk +# RFC2737 || K. McCloghrie, A. Bierman || kzm@cisco.com, andy@yumaworks.com +# RFC2738 || G. Klyne || GK@ACM.ORG +# RFC2739 || T. Small, D. Hennessy, F. Dawson || +# RFC2740 || R. Coltun, D. Ferguson, J. Moy || rcoltun@siara.com, dennis@juniper.com, jmoy@sycamorenet.com +# RFC2741 || M. Daniele, B. Wijnen, M. Ellison, D. Francisco || daniele@zk3.dec.com, wijnen@vnet.ibm.com, ellison@world.std.com, dfrancis@cisco.com +# RFC2742 || L. Heintz, S. Gudur, M. Ellison || lheintz@cisco.com, sgudur@hotmail.com +# RFC2743 || J. Linn || +# RFC2744 || J. Wray || John_Wray@Iris.com +# RFC2745 || A. Terzis, B. Braden, S. Vincent, L. Zhang || terzis@cs.ucla.edu, braden@isi.edu, svincent@cisco.com, lixia@cs.ucla.edu +# RFC2746 || A. Terzis, J. Krawczyk, J. Wroclawski, L. Zhang || jj@arrowpoint.com, jtw@lcs.mit.edu, lixia@cs.ucla.edu, terzis@cs.ucla.edu +# RFC2747 || F. Baker, B. Lindell, M. Talwar || fred@cisco.com, lindell@ISI.EDU, mohitt@microsoft.com +# RFC2748 || D. Durham, Ed., J. Boyle, R. Cohen, S. Herzog, R. Rajan, A. Sastry || +# RFC2749 || S. Herzog, Ed., J. Boyle, R. Cohen, D. Durham, R. Rajan, A. Sastry || +# RFC2750 || S. Herzog || +# RFC2751 || S. Herzog || +# RFC2752 || S. Yadav, R. Yavatkar, R. Pabbati, P. Ford, T. Moore, S. Herzog || +# RFC2753 || R. Yavatkar, D. Pendarakis, R. Guerin || raj.yavatkar@intel.com, dimitris@watson.ibm.com, guerin@ee.upenn.edu +# RFC2754 || C. Alaettinoglu, C. Villamizar, R. Govindan || cengiz@isi.edu, curtis@avici.com, govindan@isi.edu +# RFC2755 || A. Chiu, M. Eisler, B. Callaghan || alex.chiu@Eng.sun.com, michael.eisler@Eng.sun.com, brent.callaghan@Eng.sun.com +# RFC2756 || P. Vixie, D. Wessels || vixie@isc.org, wessels@nlanr.net +# RFC2757 || G. Montenegro, S. Dawkins, M. Kojo, V. Magret, N. Vaidya || gab@sun.com, sdawkins@nortel.com, kojo@cs.helsinki.fi, vincent.magret@aud.alcatel.com, vaidya@cs.tamu.edu +# RFC2758 || K. White || wkenneth@us.ibm.com +# RFC2759 || G. Zorn || gwz@acm.org +# RFC2760 || M. Allman, Ed., S. Dawkins, D. Glover, J. Griner, D. Tran, T. Henderson, J. Heidemann, J. Touch, H. Kruse, S. Ostermann, K. Scott, J. Semke || mallman@grc.nasa.gov, Spencer.Dawkins.sdawkins@nt.com, Daniel.R.Glover@grc.nasa.gov, jgriner@grc.nasa.gov, dtran@grc.nasa.gov, tomh@cs.berkeley.edu, johnh@isi.edu, touch@isi.edu, hkruse1@ohiou.edu, ostermann@cs.ohiou.edu, kscott@mitre.org, semke@psc.edu +# RFC2761 || J. Dunn, C. Martin || +# RFC2762 || J. Rosenberg, H. Schulzrinne || jdrosen@dynamicsoft.com, schulzrinne@cs.columbia.edu +# RFC2763 || N. Shen, H. Smit || naiming@siara.com, hsmit@cisco.com +# RFC2764 || B. Gleeson, A. Lin, J. Heinanen, G. Armitage, A. Malis || +# RFC2765 || E. Nordmark || nordmark@sun.com +# RFC2766 || G. Tsirtsis, P. Srisuresh || george.tsirtsis@bt.com, srisuresh@yahoo.com +# RFC2767 || K. Tsuchiya, H. Higuchi, Y. Atarashi || tsuchi@ebina.hitachi.co.jp, h-higuti@ebina.hitachi.co.jp, atarashi@ebina.hitachi.co.jp +# RFC2768 || B. Aiken, J. Strassner, B. Carpenter, I. Foster, C. Lynch, J. Mambretti, R. Moore, B. Teitelbaum || raiken@cisco.com, raiken@cisco.com, johns@cisco.com, brian@hursley.ibm.com, foster@mcs.anl.gov, cliff@cni.org, j-mambretti@nwu.edu, moore@sdsc.edu, ben@internet2.edu +# RFC2769 || C. Villamizar, C. Alaettinoglu, R. Govindan, D. Meyer || curtis@avici.com, cengiz@ISI.EDU, govindan@ISI.EDU, dmm@cisco.com +# RFC2770 || D. Meyer, P. Lothberg || dmm@cisco.com, roll@sprint.net +# RFC2771 || R. Finlayson || finlayson@live.com +# RFC2772 || R. Rockell, R. Fink || rrockell@sprint.net, fink@es.net +# RFC2773 || R. Housley, P. Yee, W. Nace || housley@spyrus.com, yee@spyrus.com +# RFC2774 || H. Nielsen, P. Leach, S. Lawrence || frystyk@microsoft.com, paulle@microsoft.com, lawrence@agranat.com +# RFC2775 || B. Carpenter || brian@icair.org +# RFC2776 || M. Handley, D. Thaler, R. Kermode || mjh@aciri.org, dthaler@microsoft.com, Roger.Kermode@motorola.com +# RFC2777 || D. Eastlake 3rd || Donald.Eastlake@motorola.com +# RFC2778 || M. Day, J. Rosenberg, H. Sugano || mday@alum.mit.edu, suga@flab.fujitsu.co.jp +# RFC2779 || M. Day, S. Aggarwal, G. Mohr, J. Vincent || mday@alum.mit.edu, sonuag@microsoft.com, gojomo@usa.net, jesse@intonet.com +# RFC2780 || S. Bradner, V. Paxson || sob@harvard.edu, vern@aciri.org +# RFC2781 || P. Hoffman, F. Yergeau || phoffman@imc.org, fyergeau@alis.com +# RFC2782 || A. Gulbrandsen, P. Vixie, L. Esibov || arnt@troll.no, levone@microsoft.com +# RFC2783 || J. Mogul, D. Mills, J. Brittenson, J. Stone, U. Windl || mogul@wrl.dec.com, mills@udel.edu, jonathan@dsg.stanford.edu, ulrich.windl@rz.uni-regensburg.de +# RFC2784 || D. Farinacci, T. Li, S. Hanks, D. Meyer, P. Traina || dino@procket.com, tony1@home.net, stan_hanks@enron.net, dmm@cisco.com, pst@juniper.net +# RFC2785 || R. Zuccherato || robert.zuccherato@entrust.com +# RFC2786 || M. St. Johns || stjohns@corp.home.net +# RFC2787 || B. Jewell, D. Chuang || bjewell@coppermountain.com, david_chuang@cosinecom.com +# RFC2788 || N. Freed, S. Kille || ned.freed@innosoft.com, Steve.Kille@MessagingDirect.com +# RFC2789 || N. Freed, S. Kille || ned.freed@innosoft.com, Steve.Kille@MessagingDirect.com +# RFC2790 || S. Waldbusser, P. Grillo || waldbusser@ins.com +# RFC2791 || J. Yu || jyy@cosinecom.com +# RFC2792 || M. Blaze, J. Ioannidis, A. Keromytis || +# RFC2793 || G. Hellstrom || gunnar.hellstrom@omnitor.se +# RFC2794 || P. Calhoun, C. Perkins || +# RFC2795 || S. Christey || steqve@shore.net +# RFC2796 || T. Bates, R. Chandra, E. Chen || tbates@cisco.com, rchandra@redback.com, enke@redback.com +# RFC2797 || M. Myers, X. Liu, J. Schaad, J. Weinstein || mmyers@verisign.com, xliu@cisco.com, jimsch@nwlink.com, jsw@meer.net +# RFC2798 || M. Smith || mcs@netscape.com +# RFC2799 || S. Ginoza || ginoza@isi.edu +# RFC2800 || J. Reynolds, R. Braden, S. Ginoza || +# RFC2801 || D. Burdett || david.burdett@commerceone.com +# RFC2802 || K. Davidson, Y. Kawatsura || kent@differential.com, kawatura@bisd.hitachi.co.jp +# RFC2803 || H. Maruyama, K. Tamura, N. Uramoto || maruyama@jp.ibm.com, kent@trl.ibm.co.jp, uramoto@jp.ibm.com +# RFC2804 || IAB, IESG || fred@cisco.com, brian@icair.org +# RFC2805 || N. Greene, M. Ramalho, B. Rosen || ngreene@nortelnetworks.com, mramalho@cisco.com, brosen@eng.fore.com +# RFC2806 || A. Vaha-Sipila || avs@iki.fi +# RFC2807 || J. Reagle || reagle@w3.org +# RFC2808 || M. Nystrom || magnus@rsasecurity.com +# RFC2809 || B. Aboba, G. Zorn || bernarda@microsoft.com, gwz@cisco.com +# RFC2810 || C. Kalt || Christophe.Kalt@gmail.com +# RFC2811 || C. Kalt || Christophe.Kalt@gmail.com +# RFC2812 || C. Kalt || Christophe.Kalt@gmail.com +# RFC2813 || C. Kalt || Christophe.Kalt@gmail.com +# RFC2814 || R. Yavatkar, D. Hoffman, Y. Bernet, F. Baker, M. Speer || yavatkar@ibeam.intel.com, yoramb@microsoft.com, fred@cisco.com, speer@Eng.Sun.COM +# RFC2815 || M. Seaman, A. Smith, E. Crawley, J. Wroclawski || andrew@extremenetworks.com, jtw@lcs.mit.edu +# RFC2816 || A. Ghanwani, J. Pace, V. Srinivasan, A. Smith, M. Seaman || aghanwan@nortelnetworks.com, pacew@us.ibm.com, vijay@cosinecom.com, andrew@extremenetworks.com +# RFC2817 || R. Khare, S. Lawrence || rohit@4K-associates.com, lawrence@agranat.com +# RFC2818 || E. Rescorla || ekr@rtfm.com +# RFC2819 || S. Waldbusser || +# RFC2820 || E. Stokes, D. Byrne, B. Blakley, P. Behera || blakley@dascom.com, stokes@austin.ibm.com, djbyrne@us.ibm.com, prasanta@netscape.com +# RFC2821 || J. Klensin, Ed. || +# RFC2822 || P. Resnick, Ed. || presnick@qti.qualcomm.com +# RFC2823 || J. Carlson, P. Langner, E. Hernandez-Valencia, J. Manchester || james.d.carlson@sun.com, plangner@lucent.com, enrique@lucent.com, sterling@hotair.hobl.lucent.com +# RFC2824 || J. Lennox, H. Schulzrinne || lennox@cs.columbia.edu, schulzrinne@cs.columbia.edu +# RFC2825 || IAB, L. Daigle, Ed. || iab@iab.org +# RFC2826 || Internet Architecture Board || iab@iab.org +# RFC2827 || P. Ferguson, D. Senie || ferguson@cisco.com, dts@senie.com +# RFC2828 || R. Shirey || rshirey@bbn.com +# RFC2829 || M. Wahl, H. Alvestrand, J. Hodges, R. Morgan || M.Wahl@innosoft.com, Harald@Alvestrand.no, JHodges@oblix.com, rlmorgan@washington.edu +# RFC2830 || J. Hodges, R. Morgan, M. Wahl || JHodges@oblix.com, rlmorgan@washington.edu, M.Wahl@innosoft.com +# RFC2831 || P. Leach, C. Newman || paulle@microsoft.com, chris.newman@innosoft.com +# RFC2832 || S. Hollenbeck, M. Srivastava || shollenb@netsol.com, manojs@netsol.com +# RFC2833 || H. Schulzrinne, S. Petrack || schulzrinne@cs.columbia.edu, scott.petrack@metatel.com +# RFC2834 || J.-M. Pittet || jmp@sgi.com +# RFC2835 || J.-M. Pittet || jmp@sgi.com +# RFC2836 || S. Brim, B. Carpenter, F. Le Faucheur || sbrim@cisco.com, brian@icair.org, flefauch@cisco.com +# RFC2837 || K. Teow || +# RFC2838 || D. Zigmond, M. Vickers || djz@corp.webtv.net, mav@liberate.com +# RFC2839 || F. da Cruz, J. Altman || +# RFC2840 || J. Altman, F. da Cruz || +# RFC2841 || P. Metzger, W. Simpson || +# RFC2842 || R. Chandra, J. Scudder || rchandra@redback.com, jgs@cisco.com +# RFC2843 || P. Droz, T. Przygienda || dro@zurich.ibm.com, prz@siara.com +# RFC2844 || T. Przygienda, P. Droz, R. Haas || prz@siara.com, dro@zurich.ibm.com, rha@zurich.ibm.com +# RFC2845 || P. Vixie, O. Gudmundsson, D. Eastlake 3rd, B. Wellington || vixie@isc.org, ogud@tislabs.com, dee3@torque.pothole.com, Brian.Wellington@nominum.com +# RFC2846 || C. Allocchio || +# RFC2847 || M. Eisler || mike@eisler.com +# RFC2848 || S. Petrack, L. Conroy || scott.petrack@metatel.com, lwc@roke.co.uk +# RFC2849 || G. Good || ggood@netscape.com +# RFC2850 || Internet Architecture Board, B. Carpenter, Ed. || brian@icair.org +# RFC2851 || M. Daniele, B. Haberman, S. Routhier, J. Schoenwaelder || daniele@zk3.dec.com, haberman@nortelnetworks.com, sar@epilogue.com, schoenw@ibr.cs.tu-bs.de +# RFC2852 || D. Newman || dan.newman@sun.com +# RFC2853 || J. Kabat, M. Upadhyay || jackk@valicert.com, mdu@eng.sun.com +# RFC2854 || D. Connolly, L. Masinter || connolly@w3.org, LM@att.com +# RFC2855 || K. Fujisawa || fujisawa@sm.sony.co.jp +# RFC2856 || A. Bierman, K. McCloghrie, R. Presuhn || andy@yumaworks.com, kzm@cisco.com, rpresuhn@bmc.com +# RFC2857 || A. Keromytis, N. Provos || angelos@dsl.cis.upenn.edu, provos@citi.umich.edu, rgm@icsa.net, tytso@valinux.com +# RFC2858 || T. Bates, Y. Rekhter, R. Chandra, D. Katz || tbates@cisco.com, rchandra@redback.com, dkatz@jnx.com, yakov@cisco.com +# RFC2859 || W. Fang, N. Seddigh, B. Nandy || wfang@cs.princeton.edu, nseddigh@nortelnetworks.com, bnandy@nortelnetworks.com +# RFC2860 || B. Carpenter, F. Baker, M. Roberts || brian@icair.org, fred@cisco.com, roberts@icann.org +# RFC2861 || M. Handley, J. Padhye, S. Floyd || mjh@aciri.org, padhye@aciri.org, floyd@aciri.org +# RFC2862 || M. Civanlar, G. Cash || civanlar@research.att.com, glenn@research.att.com +# RFC2863 || K. McCloghrie, F. Kastenholz || kzm@cisco.com, kasten@argon.com +# RFC2864 || K. McCloghrie, G. Hanson || kzm@cisco.com, gary_hanson@adc.com +# RFC2865 || C. Rigney, S. Willens, A. Rubens, W. Simpson || cdr@telemancy.com, acr@merit.edu, wsimpson@greendragon.com, steve@livingston.com +# RFC2866 || C. Rigney || cdr@telemancy.com +# RFC2867 || G. Zorn, B. Aboba, D. Mitton || gwz@cisco.com, dmitton@nortelnetworks.com, aboba@internaut.com +# RFC2868 || G. Zorn, D. Leifer, A. Rubens, J. Shriver, M. Holdrege, I. Goyret || gwz@cisco.com, leifer@del.com, John.Shriver@intel.com, acr@del.com, matt@ipverse.com, igoyret@lucent.com +# RFC2869 || C. Rigney, W. Willats, P. Calhoun || cdr@telemancy.com, ward@cyno.com, pcalhoun@eng.sun.com, arubens@tutsys.com, bernarda@microsoft.com +# RFC2870 || R. Bush, D. Karrenberg, M. Kosters, R. Plzak || randy@psg.com, daniel.karrenberg@ripe.net, markk@netsol.com, plzakr@saic.com +# RFC2871 || J. Rosenberg, H. Schulzrinne || +# RFC2872 || Y. Bernet, R. Pabbati || yoramb@microsoft.com, rameshpa@microsoft.com +# RFC2873 || X. Xiao, A. Hannan, V. Paxson, E. Crabbe || xipeng@gblx.net, alan@ivmg.net, edc@explosive.net, vern@aciri.org +# RFC2874 || M. Crawford, C. Huitema || crawdad@fnal.gov, huitema@microsoft.com +# RFC2875 || H. Prafullchandra, J. Schaad || hemma@cp.net, jimsch@exmsft.com +# RFC2876 || J. Pawling || john.pawling@wang.com +# RFC2877 || T. Murphy Jr., P. Rieth, J. Stevens || murphyte@us.ibm.com, rieth@us.ibm.com, jssteven@us.ibm.com +# RFC2878 || M. Higashiyama, F. Baker || Mitsuru.Higashiyama@yy.anritsu.co.jp, fred.baker@cisco.com +# RFC2879 || G. Klyne, L. McIntyre || GK@ACM.ORG, Lloyd.McIntyre@pahv.xerox.com +# RFC2880 || L. McIntyre, G. Klyne || Lloyd.McIntyre@pahv.xerox.com, GK@ACM.ORG +# RFC2881 || D. Mitton, M. Beadles || dmitton@nortelnetworks.com, mbeadles@smartpipes.com +# RFC2882 || D. Mitton || dmitton@nortelnetworks.com +# RFC2883 || S. Floyd, J. Mahdavi, M. Mathis, M. Podolsky || floyd@aciri.org, mahdavi@novell.com, mathis@psc.edu, podolsky@eecs.berkeley.edu +# RFC2884 || J. Hadi Salim, U. Ahmed || hadi@nortelnetworks.com, ahmed@sce.carleton.ca +# RFC2885 || F. Cuervo, N. Greene, C. Huitema, A. Rayhan, B. Rosen, J. Segers || +# RFC2886 || T. Taylor || tom.taylor.stds@gmail.com +# RFC2887 || M. Handley, S. Floyd, B. Whetten, R. Kermode, L. Vicisano, M. Luby || mjh@aciri.org, floyd@aciri.org, whetten@talarian.com, Roger.Kermode@motorola.com, lorenzo@cisco.com, luby@digitalfountain.com +# RFC2888 || P. Srisuresh || srisuresh@yahoo.com +# RFC2889 || R. Mandeville, J. Perser || bob@cqos.com, jerry_perser@netcomsystems.com +# RFC2890 || G. Dommety || gdommety@cisco.com +# RFC2891 || T. Howes, M. Wahl, A. Anantha || anoopa@microsoft.com, howes@loudcloud.com, Mark.Wahl@sun.com +# RFC2892 || D. Tsiang, G. Suwala || tsiang@cisco.com, gsuwala@cisco.com +# RFC2893 || R. Gilligan, E. Nordmark || gilligan@freegate.com, nordmark@eng.sun.com +# RFC2894 || M. Crawford || crawdad@fnal.gov +# RFC2895 || A. Bierman, C. Bucci, R. Iddon || andy@yumaworks.com, cbucci@cisco.com +# RFC2896 || A. Bierman, C. Bucci, R. Iddon || andy@yumaworks.com, cbucci@cisco.com +# RFC2897 || D. Cromwell || cromwell@nortelnetworks.com +# RFC2898 || B. Kaliski || bkaliski@rsasecurity.com +# RFC2899 || S. Ginoza || ginoza@isi.edu +# RFC2900 || J. Reynolds, R. Braden, S. Ginoza || +# RFC2901 || Z. Wenzel, J. Klensin, R. Bush, S. Huter || zita@nsrc.org, klensin@nsrc.org, randy@nsrc.org, sghuter@nsrc.org +# RFC2902 || S. Deering, S. Hares, C. Perkins, R. Perlman || deering@cisco.com, skh@nexthop.com, Radia.Perlman@sun.com, Charles.Perkins@nokia.com +# RFC2903 || C. de Laat, G. Gross, L. Gommans, J. Vollbrecht, D. Spence || delaat@phys.uu.nl, gmgross@lucent.com, jrv@interlinknetworks.com, dspence@interlinknetworks.com +# RFC2904 || J. Vollbrecht, P. Calhoun, S. Farrell, L. Gommans, G. Gross, B. de Bruijn, C. de Laat, M. Holdrege, D. Spence || pcalhoun@eng.sun.com, stephen.farrell@baltimore.ie, betty@euronet.nl, delaat@phys.uu.nl, matt@ipverse.com, dspence@interlinknetworks.com +# RFC2905 || J. Vollbrecht, P. Calhoun, S. Farrell, L. Gommans, G. Gross, B. de Bruijn, C. de Laat, M. Holdrege, D. Spence || jrv@interlinknetworks.com, pcalhoun@eng.sun.com, stephen.farrell@baltimore.ie, gmgross@lucent.com, betty@euronet.nl, delaat@phys.uu.nl, matt@ipverse.com, dspence@interlinknetworks.com +# RFC2906 || S. Farrell, J. Vollbrecht, P. Calhoun, L. Gommans, G. Gross, B. de Bruijn, C. de Laat, M. Holdrege, D. Spence || stephen.farrell@baltimore.ie, jrv@interlinknetworks.com, pcalhoun@eng.sun.com, gmgross@lucent.com, betty@euronet.nl, delaat@phys.uu.nl, matt@ipverse.com, dspence@interlinknetworks.com +# RFC2907 || R. Kermode || Roger.Kermode@motorola.com +# RFC2908 || D. Thaler, M. Handley, D. Estrin || dthaler@microsoft.com, mjh@aciri.org, estrin@usc.edu +# RFC2909 || P. Radoslavov, D. Estrin, R. Govindan, M. Handley, S. Kumar, D. Thaler || pavlin@catarina.usc.edu, estrin@isi.edu, govindan@isi.edu, mjh@aciri.org, kkumar@usc.edu, dthaler@microsoft.com +# RFC2910 || R. Herriot, Ed., S. Butler, P. Moore, R. Turner, J. Wenn || robert.herriot@pahv.xerox.com, sbutler@boi.hp.com, pmoore@peerless.com, jwenn@cp10.es.xerox.com, tom.hastings@alum.mit.edu, robert.herriot@pahv.xerox.com +# RFC2911 || T. Hastings, Ed., R. Herriot, R. deBry, S. Isaacson, P. Powell || sisaacson@novell.com, tom.hastings@alum.mit.edu, robert.herriot@pahv.xerox.com, debryro@uvsc.edu, papowell@astart.com +# RFC2912 || G. Klyne || GK@ACM.ORG +# RFC2913 || G. Klyne || GK@ACM.ORG +# RFC2914 || S. Floyd || +# RFC2915 || M. Mealling, R. Daniel || michaelm@netsol.com, rdaniel@datafusion.net +# RFC2916 || P. Faltstrom || paf@cisco.com +# RFC2917 || K. Muthukrishnan, A. Malis || mkarthik@lucent.com, Andy.Malis@vivacenetworks.com +# RFC2918 || E. Chen || enke@redback.com +# RFC2919 || R. Chandhok, G. Wenger || chandhok@qualcomm.com, gwenger@qualcomm.com +# RFC2920 || N. Freed || ned.freed@innosoft.com +# RFC2921 || B. Fink || fink@es.net +# RFC2922 || A. Bierman, K. Jones || andy@yumaworks.com, kejones@nortelnetworks.com +# RFC2923 || K. Lahey || +# RFC2924 || N. Brownlee, A. Blount || n.brownlee@auckland.ac.nz, blount@alum.mit.edu +# RFC2925 || K. White || wkenneth@us.ibm.com +# RFC2926 || J. Kempf, R. Moats, P. St. Pierre || james.kempf@sun.com, rmoats@coreon.net, Pete.StPierre@Eng.Sun.COM +# RFC2927 || M. Wahl || Mark.Wahl@sun.com +# RFC2928 || R. Hinden, S. Deering, R. Fink, T. Hain || bob.hinden@gmail.com, deering@cisco.com, rlfink@lbl.gov, tonyhain@microsoft.com +# RFC2929 || D. Eastlake 3rd, E. Brunner-Williams, B. Manning || Donald.Eastlake@motorola.com, brunner@engage.com, bmanning@isi.edu +# RFC2930 || D. Eastlake 3rd || Donald.Eastlake@motorola.com +# RFC2931 || D. Eastlake 3rd || Donald.Eastlake@motorola.com +# RFC2932 || K. McCloghrie, D. Farinacci, D. Thaler || kzm@cisco.com, dthaler@microsoft.com +# RFC2933 || K. McCloghrie, D. Farinacci, D. Thaler || kzm@cisco.com, dthaler@microsoft.com +# RFC2934 || K. McCloghrie, D. Farinacci, D. Thaler, B. Fenner || kzm@cisco.com, dthaler@microsoft.com, fenner@research.att.com +# RFC2935 || D. Eastlake 3rd, C. Smith || Donald.Eastlake@motorola.com, chris.smith@royalbank.com +# RFC2936 || D. Eastlake 3rd, C. Smith, D. Soroka || Donald.Eastlake@motorola.com, chris.smith@royalbank.com, dsoroka@us.ibm.com +# RFC2937 || C. Smith || cs@Eng.Sun.COM +# RFC2938 || G. Klyne, L. Masinter || GK@ACM.ORG, LMM@acm.org +# RFC2939 || R. Droms || droms@bucknell.edu +# RFC2940 || A. Smith, D. Partain, J. Seligson || David.Partain@ericsson.com, jseligso@nortelnetworks.com +# RFC2941 || T. Ts'o, Ed., J. Altman || tytso@mit.edu, jaltman@columbia.edu +# RFC2942 || T. Ts'o || +# RFC2943 || R. Housley, T. Horting, P. Yee || housley@spyrus.com, thorting@spyrus.com, yee@spyrus.com +# RFC2944 || T. Wu || tjw@cs.Stanford.EDU +# RFC2945 || T. Wu || tjw@cs.Stanford.EDU +# RFC2946 || T. Ts'o || tytso@mit.edu +# RFC2947 || J. Altman || jaltman@columbia.edu +# RFC2948 || J. Altman || jaltman@columbia.edu +# RFC2949 || J. Altman || jaltman@columbia.edu +# RFC2950 || J. Altman || jaltman@columbia.edu +# RFC2951 || R. Housley, T. Horting, P. Yee || housley@spyrus.com, thorting@spyrus.com, yee@spyrus.com +# RFC2952 || T. Ts'o || tytso@mit.edu +# RFC2953 || T. Ts'o || tytso@mit.edu +# RFC2954 || K. Rehbehn, D. Fowler || krehbehn@megisto.com, fowler@syndesis.com +# RFC2955 || K. Rehbehn, O. Nicklass, G. Mouradian || krehbehn@megisto.com, orly_n@rad.co.il, gvm@att.com +# RFC2956 || M. Kaat || Marijke.Kaat@surfnet.nl +# RFC2957 || L. Daigle, P. Faltstrom || paf@cisco.com +# RFC2958 || L. Daigle, P. Faltstrom || paf@cisco.com +# RFC2959 || M. Baugher, B. Strahm, I. Suconick || mbaugher@passedge.com, Bill.Strahm@intel.com, irina@ennovatenetworks.com +# RFC2960 || R. Stewart, Q. Xie, K. Morneault, C. Sharp, H. Schwarzbauer, T. Taylor, I. Rytina, M. Kalla, L. Zhang, V. Paxson || randall@lakerest.net, qxie1@email.mot.com, kmorneau@cisco.com, chsharp@cisco.com, HannsJuergen.Schwarzbauer@icn.siemens.de, tom.taylor.stds@gmail.com, ian.rytina@ericsson.com, mkalla@telcordia.com, lixia@cs.ucla.edu, vern@aciri.org +# RFC2961 || L. Berger, D. Gan, G. Swallow, P. Pan, F. Tommasi, S. Molendini || lberger@labn.net, swallow@cisco.com, franco.tommasi@unile.it, molendini@ultra5.unile.it +# RFC2962 || D. Raz, J. Schoenwaelder, B. Sugla || raz@lucent.com, schoenw@ibr.cs.tu-bs.de, sugla@ispsoft.com +# RFC2963 || O. Bonaventure, S. De Cnodder || Olivier.Bonaventure@info.fundp.ac.be, stefaan.de_cnodder@alcatel.be +# RFC2964 || K. Moore, N. Freed || moore@cs.utk.edu, ned.freed@innosoft.com +# RFC2965 || D. Kristol, L. Montulli || +# RFC2966 || T. Li, T. Przygienda, H. Smit || tli@procket.com, prz@redback.com, henk@procket.com +# RFC2967 || L. Daigle, R. Hedberg || leslie@thinkingcat.com, Roland@catalogix.se +# RFC2968 || L. Daigle, T. Eklof || leslie@thinkingcat.com, thommy.eklof@hotsip.com +# RFC2969 || T. Eklof, L. Daigle || thommy.eklof@hotsip.com, leslie@thinkingcat.com +# RFC2970 || L. Daigle, T. Eklof || leslie@thinkingcat.com, thommy.eklof@hotsip.com +# RFC2971 || T. Showalter || tjs@mirapoint.com +# RFC2972 || N. Popp, M. Mealling, L. Masinter, K. Sollins || LMM@acm.org, michaelm@netsol.com, nico@realnames.com, sollins@lcs.mit.edu +# RFC2973 || R. Balay, D. Katz, J. Parker || Rajesh.Balay@cosinecom.com, dkatz@juniper.net, jparker@axiowave.com +# RFC2974 || M. Handley, C. Perkins, E. Whelan || mjh@aciri.org, csp@isi.edu, e.whelan@cs.ucl.ac.uk +# RFC2975 || B. Aboba, J. Arkko, D. Harrington || bernarda@microsoft.com, Jari.Arkko@ericsson.com, dbh@cabletron.com +# RFC2976 || S. Donovan || +# RFC2977 || S. Glass, T. Hiller, S. Jacobs, C. Perkins || +# RFC2978 || N. Freed, J. Postel || ned.freed@innosoft.com +# RFC2979 || N. Freed || ned.freed@innosoft.com +# RFC2980 || S. Barber || sob@academ.com +# RFC2981 || R. Kavasseri, Ed. || ramk@cisco.com +# RFC2982 || R. Kavasseri, Ed. || ramk@cisco.com +# RFC2983 || D. Black || black_david@emc.com +# RFC2984 || C. Adams || cadams@entrust.com +# RFC2985 || M. Nystrom, B. Kaliski || magnus@rsasecurity.com, bkaliski@rsasecurity.com +# RFC2986 || M. Nystrom, B. Kaliski || magnus@rsasecurity.com, bkaliski@rsasecurity.com +# RFC2987 || P. Hoffman || phoffman@imc.org +# RFC2988 || V. Paxson, M. Allman || vern@aciri.org, mallman@grc.nasa.gov +# RFC2989 || B. Aboba, P. Calhoun, S. Glass, T. Hiller, P. McCann, H. Shiino, P. Walsh, G. Zorn, G. Dommety, C. Perkins, B. Patil, D. Mitton, S. Manning, M. Beadles, X. Chen, S. Sivalingham, A. Hameed, M. Munson, S. Jacobs, B. Lim, B. Hirschman, R. Hsu, H. Koo, M. Lipford, E. Campbell, Y. Xu, S. Baba, E. Jaques || bernarda@microsoft.com, pcalhoun@eng.sun.com, steven.glass@sun.com, tom.hiller@lucent.com, mccap@lucent.com, hshiino@lucent.com, walshp@lucent.com, gwz@cisco.com, gdommety@cisco.com, charliep@iprg.nokia.com, Basavaraj.Patil@nokia.com, dmitton@nortelnetworks.com, smanning@nortelnetworks.com, mbeadles@smartpipes.com, xing.chen@usa.alcatel.com, s.sivalingham@ericsson.com, none, mmunson@mobilnet.gte.com, sjacobs@gte.com, bklim@lgic.co.kr, qa4053@email.mot.com, rhsu@qualcomm.com, hskoo@sta.samsung.com, mlipfo01@sprintspectrum.com, ed_campbell@3com.com, yxu@watercove.com, sbaba@tari.toshiba.com, ejaques@akamail.com +# RFC2990 || G. Huston || gih@telstra.net +# RFC2991 || D. Thaler, C. Hopps || dthaler@dthaler.microsoft.com, chopps@nexthop.com +# RFC2992 || C. Hopps || chopps@nexthop.com +# RFC2993 || T. Hain || tonyhain@microsoft.com +# RFC2994 || H. Ohta, M. Matsui || hidenori@iss.isl.melco.co.jp, matsui@iss.isl.melco.co.jp +# RFC2995 || H. Lu, Ed., I. Faynberg, J. Voelker, M. Weissman, W. Zhang, S. Rhim, J. Hwang, S. Ago, S. Moeenuddin, S. Hadvani, S. Nyckelgard, J. Yoakum, L. Robart || faynberg@lucent.com, huilanlu@lucent.com, jvoelker@lucent.com, maw1@lucent.com, wzz@lucent.com, syrhim@kt.co.kr, jkhwang@kt.co.kr, ago@ssf.abk.nec.co.jp, moeen@asl.dl.nec.com, hadvani@asl.dl.nec.com, soren.m.nyckelgard@telia.se, yoakum@nortelnetworks.com, robart@nortelnetworks.com +# RFC2996 || Y. Bernet || yoramb@microsoft.com +# RFC2997 || Y. Bernet, A. Smith, B. Davie || Yoramb@microsoft.com, bsd@cisco.com +# RFC2998 || Y. Bernet, P. Ford, R. Yavatkar, F. Baker, L. Zhang, M. Speer, R. Braden, B. Davie, J. Wroclawski, E. Felstaine || yoramb@microsoft.com, raj.yavatkar@intel.com, peterf@microsoft.com, fred@cisco.com, lixia@cs.ucla.edu, speer@Eng.Sun.COM, braden@isi.edu, bsd@cisco.com, jtw@lcs.mit.edu +# RFC2999 || S. Ginoza || ginoza@isi.edu +# RFC3000 || J. Reynolds, R. Braden, S. Ginoza, L. Shiota || +# RFC3001 || M. Mealling || michaelm@netsol.com +# RFC3002 || D. Mitzel || mitzel@iprg.nokia.com +# RFC3003 || M. Nilsson || nilsson@id3.org +# RFC3004 || G. Stump, R. Droms, Y. Gu, R. Vyaghrapuri, A. Demirtjis, B. Beser, J. Privat || stumpga@us.ibm.com, rdroms@cisco.com, yegu@microsoft.com, rameshv@microsoft.com, annd@microsoft.com +# RFC3005 || S. Harris || srh@merit.edu +# RFC3006 || B. Davie, C. Iturralde, D. Oran, S. Casner, J. Wroclawski || bsd@cisco.com, cei@cisco.com, oran@cisco.com, casner@acm.org, jtw@lcs.mit.edu +# RFC3007 || B. Wellington || Brian.Wellington@nominum.com +# RFC3008 || B. Wellington || Brian.Wellington@nominum.com +# RFC3009 || J. Rosenberg, H. Schulzrinne || jdrosen@dynamicsoft.com, schulzrinne@cs.columbia.edu +# RFC3010 || S. Shepler, B. Callaghan, D. Robinson, R. Thurlow, C. Beame, M. Eisler, D. Noveck || beame@bws.com, brent.callaghan@sun.com, mike@eisler.com, david.robinson@sun.com, robert.thurlow@sun.com +# RFC3011 || G. Waters || +# RFC3012 || C. Perkins, P. Calhoun || +# RFC3013 || T. Killalea || tomk@neart.org +# RFC3014 || R. Kavasseri || ramk@cisco.com +# RFC3015 || F. Cuervo, N. Greene, A. Rayhan, C. Huitema, B. Rosen, J. Segers || +# RFC3016 || Y. Kikuchi, T. Nomura, S. Fukunaga, Y. Matsui, H. Kimata || yoshihiro.kikuchi@toshiba.co.jp, matsui@drl.mei.co.jp, t-nomura@ccm.cl.nec.co.jp, fukunaga444@oki.co.jp, kimata@nttvdt.hil.ntt.co.jp +# RFC3017 || M. Riegel, G. Zorn || maximilian.riegel@icn.siemens.de, gwz@cisco.com +# RFC3018 || A. Bogdanov || a_bogdanov@iname.ru +# RFC3019 || B. Haberman, R. Worzella || haberman@nortelnetworks.com, worzella@us.ibm.com +# RFC3020 || P. Pate, B. Lynch, K. Rehbehn || prayson.pate@overturenetworks.com, bob.lynch@overturenetworks.com, krehbehn@megisto.com +# RFC3021 || A. Retana, R. White, V. Fuller, D. McPherson || aretana@cisco.com, riw@cisco.com, vaf@valinor.barrnet.net, danny@ambernetworks.com +# RFC3022 || P. Srisuresh, K. Egevang || srisuresh@yahoo.com, kjeld.egevang@intel.com +# RFC3023 || M. Murata, S. St. Laurent, D. Kohn || mmurata@trl.ibm.co.jp, simonstl@simonstl.com, dan@dankohn.com +# RFC3024 || G. Montenegro, Ed. || +# RFC3025 || G. Dommety, K. Leung || gdommety@cisco.com, kleung@cisco.com +# RFC3026 || R. Blane || Roy_Blane@inmarsat.com +# RFC3027 || M. Holdrege, P. Srisuresh || matt@ipverse.com, srisuresh@yahoo.com +# RFC3028 || T. Showalter || tjs@mirapoint.com +# RFC3029 || C. Adams, P. Sylvester, M. Zolotarev, R. Zuccherato || cadams@entrust.com, mzolotarev@baltimore.com, peter.sylvester@edelweb.fr, robert.zuccherato@entrust.com +# RFC3030 || G. Vaudreuil || GregV@ieee.org +# RFC3031 || E. Rosen, A. Viswanathan, R. Callon || erosen@cisco.com, arun@force10networks.com, rcallon@juniper.net +# RFC3032 || E. Rosen, D. Tappan, G. Fedorkow, Y. Rekhter, D. Farinacci, T. Li, A. Conta || erosen@cisco.com, tappan@cisco.com, yakov@juniper.net, fedorkow@cisco.com, dino@procket.com, tli@procket.com, aconta@txc.com +# RFC3033 || M. Suzuki || suzuki.muneyoshi@lab.ntt.co.jp +# RFC3034 || A. Conta, P. Doolan, A. Malis || aconta@txc.com, pdoolan@ennovatenetworks.com, Andy.Malis@vivacenetworks.com +# RFC3035 || B. Davie, J. Lawrence, K. McCloghrie, E. Rosen, G. Swallow, Y. Rekhter, P. Doolan || bsd@cisco.com, pdoolan@ennovatenetworks.com, jlawrenc@cisco.com, kzm@cisco.com, yakov@juniper.net, erosen@cisco.com, swallow@cisco.com +# RFC3036 || L. Andersson, P. Doolan, N. Feldman, A. Fredette, B. Thomas || loa.andersson@nortelnetworks.com, pdoolan@ennovatenetworks.com, nkf@us.ibm.com, fredette@photonex.com, rhthomas@cisco.com +# RFC3037 || B. Thomas, E. Gray || ewgray@mindspring.com, rhthomas@cisco.com +# RFC3038 || K. Nagami, Y. Katsube, N. Demizu, H. Esaki, P. Doolan || ken.nagami@toshiba.co.jp, demizu@dd.iij4u.or.jp, hiroshi@wide.ad.jp, yasuhiro.katsube@toshiba.co.jp, pdoolan@ennovatenetworks.com +# RFC3039 || S. Santesson, W. Polk, P. Barzin, M. Nystrom || stefan@addtrust.com, wpolk@nist.gov, barzin@secude.com, magnus@rsasecurity.com +# RFC3040 || I. Cooper, I. Melve, G. Tomlinson || icooper@equinix.com, Ingrid.Melve@uninett.no, gary.tomlinson@cacheflow.com +# RFC3041 || T. Narten, R. Draves || narten@raleigh.ibm.com, richdr@microsoft.com +# RFC3042 || M. Allman, H. Balakrishnan, S. Floyd || mallman@grc.nasa.gov, hari@lcs.mit.edu, floyd@aciri.org +# RFC3043 || M. Mealling || michaelm@netsol.com +# RFC3044 || S. Rozenfeld || +# RFC3045 || M. Meredith || mark_meredith@novell.com +# RFC3046 || M. Patrick || michael.patrick@motorola.com +# RFC3047 || P. Luthi || luthip@pictel.com +# RFC3048 || B. Whetten, L. Vicisano, R. Kermode, M. Handley, S. Floyd, M. Luby || whetten@talarian.com, lorenzo@cisco.com, Roger.Kermode@motorola.com, mjh@aciri.org, luby@digitalfountain.com +# RFC3049 || J. Naugle, K. Kasthurirangan, G. Ledford || jnaugle@us.ibm.com, kasthuri@us.ibm.com, gledford@zephyrcorp.com +# RFC3050 || J. Lennox, H. Schulzrinne, J. Rosenberg || lennox@cs.columbia.edu, jdrosen@dynamicsoft.com, schulzrinne@cs.columbia.edu +# RFC3051 || J. Heath, J. Border || jheath@hns.com, border@hns.com +# RFC3052 || M. Eder, S. Nag || michael.eder@nokia.com, thinker@monmouth.com +# RFC3053 || A. Durand, P. Fasano, I. Guardini, D. Lento || Alain.Durand@sun.com, paolo.fasano@cselt.it, ivano.guardini@cselt.it, dlento@mail.tim.it +# RFC3054 || P. Blatherwick, R. Bell, P. Holland || blather@nortelnetworks.com, rtbell@cisco.com, phil.holland@circa.ca +# RFC3055 || M. Krishnaswamy, D. Romascanu || murali@lucent.com, dromasca@gmail.com +# RFC3056 || B. Carpenter, K. Moore || brian@icair.org, moore@cs.utk.edu +# RFC3057 || K. Morneault, S. Rengasami, M. Kalla, G. Sidebottom || kmorneau@cisco.com, mkalla@telcordia.com, srengasa@telcordia.com, gregside@nortelnetworks.com +# RFC3058 || S. Teiwes, P. Hartmann, D. Kuenzi || stephan.teiwes@it-sec.com, peter.hartmann@it-sec.com, dkuenzi@724.com +# RFC3059 || E. Guttman || Erik.Guttman@sun.com +# RFC3060 || B. Moore, E. Ellesson, J. Strassner, A. Westerinen || eellesson@lboard.com, remoore@us.ibm.com, johns@cisco.com, andreaw@cisco.com +# RFC3061 || M. Mealling || michaelm@netsol.com +# RFC3062 || K. Zeilenga || Kurt@OpenLDAP.org +# RFC3063 || Y. Ohba, Y. Katsube, E. Rosen, P. Doolan || yoshihiro.ohba@toshiba.co.jp, yasuhiro.katsube@toshiba.co.jp, erosen@cisco.com, pdoolan@ennovatenetworks.com +# RFC3064 || B. Foster || bfoster@cisco.com +# RFC3065 || P. Traina, D. McPherson, J. Scudder || danny@ambernetworks.com, jgs@cisco.com +# RFC3066 || H. Alvestrand || Harald@Alvestrand.no +# RFC3067 || J. Arvidsson, A. Cormack, Y. Demchenko, J. Meijer || Jimmy.J.Arvidsson@telia.se, Andrew.Cormack@ukerna.ac.uk, demch@terena.nl, jan.meijer@surfnet.nl +# RFC3068 || C. Huitema || huitema@microsoft.com +# RFC3069 || D. McPherson, B. Dykes || danny@ambernetworks.com, bdykes@onesecure.com +# RFC3070 || V. Rawat, R. Tio, S. Nanji, R. Verma || vrawat@oni.com, tor@redback.com, rverma@dc.com, suhail@redback.com +# RFC3071 || J. Klensin || klensin@jck.com +# RFC3072 || M. Wildgrube || max@wildgrube.com +# RFC3073 || J. Collins || jcollins@bitstream.com +# RFC3074 || B. Volz, S. Gonczi, T. Lemon, R. Stevens || bernie.volz@ericsson.com, steve.gonczi@networkengines.com, ted.lemon@nominum.com, robs@join.com +# RFC3075 || D. Eastlake 3rd, J. Reagle, D. Solo || Donald.Eastlake@motorola.com, reagle@w3.org, dsolo@alum.mit.edu +# RFC3076 || J. Boyer || jboyer@PureEdge.com +# RFC3077 || E. Duros, W. Dabbous, H. Izumiyama, N. Fujii, Y. Zhang || +# RFC3078 || G. Pall, G. Zorn || gurdeep@microsoft.com, gwz@cisco.com +# RFC3079 || G. Zorn || gwz@cisco.com +# RFC3080 || M. Rose || mrose17@gmail.com +# RFC3081 || M. Rose || mrose17@gmail.com +# RFC3082 || J. Kempf, J. Goldschmidt || james.kempf@sun.com, jason.goldschmidt@sun.com +# RFC3083 || R. Woundy || rwoundy@cisco.com +# RFC3084 || K. Chan, J. Seligson, D. Durham, S. Gai, K. McCloghrie, S. Herzog, F. Reichmeyer, R. Yavatkar, A. Smith || khchan@nortelnetworks.com, sgai@cisco.com, Herzog@iphighway.com, kzm@cisco.com, franr@pfn.com, raj.yavatkar@intel.com, andrew@allegronetworks.com +# RFC3085 || A. Coates, D. Allen, D. Rivers-Moore || tony.coates@reuters.com, ho73@dial.pipex.com, daniel.rivers-moore@rivcom.com +# RFC3086 || K. Nichols, B. Carpenter || nichols@packetdesign.com, brian@icair.org +# RFC3087 || B. Campbell, R. Sparks || bcampbell@dynamicsoft.com, rsparks@dynamicsoft.com +# RFC3088 || K. Zeilenga || kurt@openldap.org +# RFC3089 || H. Kitamura || kitamura@da.jp.nec.com +# RFC3090 || E. Lewis || lewis@tislabs.com +# RFC3091 || H. Kennedy || kennedyh@engin.umich.edu +# RFC3092 || D. Eastlake 3rd, C. Manros, E. Raymond || Donald.Eastlake@motorola.com, manros@cp10.es.xerox.com, esr@thyrsus.com +# RFC3093 || M. Gaynor, S. Bradner || +# RFC3094 || D. Sprague, R. Benedyk, D. Brendes, J. Keller || david.sprague@tekelec.com, dan.brendes@tekelec.com, robby.benedyk@tekelec.com, joe.keller@tekelec.com +# RFC3095 || C. Bormann, C. Burmeister, M. Degermark, H. Fukushima, H. Hannu, L-E. Jonsson, R. Hakenberg, T. Koren, K. Le, Z. Liu, A. Martensson, A. Miyazaki, K. Svanbro, T. Wiebke, T. Yoshimura, H. Zheng || cabo@tzi.org, burmeister@panasonic.de, micke@cs.arizona.edu, fukusima@isl.mei.co.jp, hans.hannu@ericsson.com, lars-erik.jonsson@ericsson.com, hakenberg@panasonic.de, tmima@cisco.com, khiem.le@nokia.com, zhigang.liu@nokia.com, anton.martensson@era.ericsson.se, akihiro@isl.mei.co.jp, krister.svanbro@ericsson.com, wiebke@panasonic.de, yoshi@spg.yrp.nttdocomo.co.jp, haihong.zheng@nokia.com +# RFC3096 || M. Degermark, Ed. || +# RFC3097 || R. Braden, L. Zhang || Braden@ISI.EDU, lixia@cs.ucla.edu +# RFC3098 || T. Gavin, D. Eastlake 3rd, S. Hambridge || tedgavin@newsguy.com, Donald.Eastlake@motorola.com, sallyh@ludwig.sc.intel.com +# RFC3099 || S. Ginoza || ginoza@isi.edu +# RFC3100 || || +# RFC3101 || P. Murphy || pmurphy@noc.usgs.net +# RFC3102 || M. Borella, J. Lo, D. Grabelsky, G. Montenegro || mike_borella@commworks.com, yidarlo@yahoo.com, david_grabelsky@commworks.com, gab@sun.com +# RFC3103 || M. Borella, D. Grabelsky, J. Lo, K. Taniguchi || mike_borella@commworks.com, david_grabelsky@commworks.com, yidarlo@yahoo.com, taniguti@ccrl.sj.nec.com +# RFC3104 || G. Montenegro, M. Borella || gab@sun.com, mike_borella@commworks.com +# RFC3105 || J. Kempf, G. Montenegro || gab@sun.com +# RFC3106 || D. Eastlake 3rd, T. Goldstein || Donald.Eastlake@motorola.com, tgoldstein@brodia.com +# RFC3107 || Y. Rekhter, E. Rosen || yakov@juniper.net, erosen@cisco.com +# RFC3108 || R. Kumar, M. Mostafa || rkumar@cisco.com, mmostafa@cisco.com +# RFC3109 || R. Braden, R. Bush, J. Klensin || braden@isi.edu, randy@psg.com, klensin@jck.com +# RFC3110 || D. Eastlake 3rd || Donald.Eastlake@motorola.com +# RFC3111 || E. Guttman || Erik.Guttman@germany.sun.com +# RFC3112 || K. Zeilenga || Kurt@OpenLDAP.org +# RFC3113 || K. Rosenbrock, R. Sanmugam, S. Bradner, J. Klensin || rosenbrock@etsi.fr, sob@harvard.edu, 3GPPContact@etsi.fr +# RFC3114 || W. Nicolls || wnicolls@forsythesolutions.com +# RFC3115 || G. Dommety, K. Leung || gdommety@cisco.com, kleung@cisco.com +# RFC3116 || J. Dunn, C. Martin || Jeffrey.Dunn@worldnet.att.net, Cynthia.E.Martin@worldnet.att.net +# RFC3117 || M. Rose || mrose17@gmail.com +# RFC3118 || R. Droms, Ed., W. Arbaugh, Ed. || +# RFC3119 || R. Finlayson || finlayson@live.com +# RFC3120 || K. Best, N. Walsh || karl.best@oasis-open.org, Norman.Walsh@East.Sun.COM +# RFC3121 || K. Best, N. Walsh || karl.best@oasis-open.org, Norman.Walsh@East.Sun.COM +# RFC3122 || A. Conta || aconta@txc.com +# RFC3123 || P. Koch || pk@TechFak.Uni-Bielefeld.DE +# RFC3124 || H. Balakrishnan, S. Seshan || hari@lcs.mit.edu, srini@cmu.edu +# RFC3125 || J. Ross, D. Pinkas, N. Pope || harri.rasilainen@etsi.fr, ross@secstan.com, Denis.Pinkas@bull.net, pope@secstan.com +# RFC3126 || D. Pinkas, J. Ross, N. Pope || harri.rasilainen@etsi.fr, Denis.Pinkas@bull.net, ross@secstan.com, pope@secstan.com +# RFC3127 || D. Mitton, M. St.Johns, S. Barkley, D. Nelson, B. Patil, M. Stevens, B. Wolff || dmitton@nortelnetworks.com, stjohns@rainmakertechnologies.com, stuartb@uu.net, dnelson@enterasys.com, Basavaraj.Patil@nokia.com, mstevens@ellacoya.com, barney@databus.com +# RFC3128 || I. Miller || Ian_Miller@singularis.ltd.uk +# RFC3129 || M. Thomas || mat@cisco.com +# RFC3130 || E. Lewis || +# RFC3131 || S. Bradner, P. Calhoun, H. Cuschieri, S. Dennett, G. Flynn, M. Lipford, M. McPheters || sob@harvard.edu, pcalhoun@eng.sun.com, hcuschie@tia.eia.org, S.Dennett@motorola.com, gerry.flynn@verizonwireless.com, mjmcpheters@lucent.com +# RFC3132 || J. Kempf || +# RFC3133 || J. Dunn, C. Martin || +# RFC3134 || J. Dunn, C. Martin || +# RFC3135 || J. Border, M. Kojo, J. Griner, G. Montenegro, Z. Shelby || border@hns.com, kojo@cs.helsinki.fi, jgriner@grc.nasa.gov, gab@sun.com, zach.shelby@ee.oulu.fi +# RFC3136 || L. Slutsman, Ed., I. Faynberg, H. Lu, M. Weissman || faynberg@lucent.com, huilanlu@lucent.com, maw1@lucent.com, lslutsman@att.com +# RFC3137 || A. Retana, L. Nguyen, R. White, A. Zinin, D. McPherson || aretana@cisco.com, lhnguyen@cisco.com, riw@cisco.com, azinin@nexsi.com, danny@ambernetworks.com +# RFC3138 || D. Meyer || dmm@sprint.net +# RFC3139 || L. Sanchez, K. McCloghrie, J. Saperia || kzm@cisco.com, lsanchez@megisto.com, saperia@jdscons.com +# RFC3140 || D. Black, S. Brim, B. Carpenter, F. Le Faucheur || black_david@emc.com, sbrim@cisco.com, brian@icair.org, flefauch@cisco.com +# RFC3141 || T. Hiller, P. Walsh, X. Chen, M. Munson, G. Dommety, S. Sivalingham, B. Lim, P. McCann, H. Shiino, B. Hirschman, S. Manning, R. Hsu, H. Koo, M. Lipford, P. Calhoun, C. Lo, E. Jaques, E. Campbell, Y.Xu,S.Baba,T.Ayaki,T.Seki,A.Hameed || pcalhoun@eng.sun.com, gdommety@cisco.com, tom.hiller@lucent.com, rhsu@qualcomm.com, mlipfo01@sprintspectrum.com, serge@awardsolutions.com, mccap@lucent.com, mmunson@gte.net, hskoo@sta.samsung.com, walshp@lucent.com, yxu@watercove.com, qa4053@email.mot.com, ejaques@akamail.com, s.sivalingham@ericsson.com, xing.chen@usa.alcatel.com, bklim@lge.com, hshiino@lucent.com, sbaba@tari.toshiba.com, ayaki@ddi.co.jp, Charles.Lo@vodafone-us.com, t-seki@kddi.com +# RFC3142 || J. Hagino, K. Yamamoto || itojun@iijlab.net, kazu@iijlab.net +# RFC3143 || I. Cooper, J. Dilley || icooper@equinix.com, jad@akamai.com +# RFC3144 || D. Romascanu || dromasca@gmail.com +# RFC3145 || R. Verma, M. Verma, J. Carlson || rverma@dc.com, Madhvi_Verma@3com.com, james.d.carlson@sun.com +# RFC3146 || K. Fujisawa, A. Onoe || fujisawa@sm.sony.co.jp, onoe@sm.sony.co.jp +# RFC3147 || P. Christian || christi@nortelnetworks.com +# RFC3148 || M. Mathis, M. Allman || mathis@psc.edu, mallman@bbn.com +# RFC3149 || A. Srinath, G. Levendel, K. Fritz, R. Kalyanaram || Ashok.Srinath@sylantro.com, Gil.Levendel@sylantro.com, Kent.Fritz@sylantro.com, Raghuraman.Kal@wipro.com +# RFC3150 || S. Dawkins, G. Montenegro, M. Kojo, V. Magret || spencer.dawkins@fnc.fujitsu.com, gab@sun.com, kojo@cs.helsinki.fi, vincent.magret@alcatel.com +# RFC3151 || N. Walsh, J. Cowan, P. Grosso || Norman.Walsh@East.Sun.COM, jcowan@reutershealth.com, pgrosso@arbortext.com +# RFC3152 || R. Bush || randy@psg.com +# RFC3153 || R. Pazhyannur, I. Ali, C. Fox || pazhynnr@cig.mot.com, fia225@email.mot.com, fox@cisco.com +# RFC3154 || J. Kempf, C. Castelluccia, P. Mutaf, N. Nakajima, Y. Ohba, R. Ramjee, Y. Saifullah, B. Sarikaya, X. Xu || James.Kempf@Sun.COM, pars.mutaf@inria.fr, claude.castelluccia@inria.fr, nnakajima@tari.toshiba.com, yohba@tari.toshiba.com, ramjee@bell-labs.com, Yousuf.Saifullah@nokia.com, Behcet.Sarikaya@usa.alcatel.com +# RFC3155 || S. Dawkins, G. Montenegro, M. Kojo, V. Magret, N. Vaidya || spencer.dawkins@fnc.fujitsu.com, gab@sun.com, kojo@cs.helsinki.fi, vincent.magret@alcatel.com +# RFC3156 || M. Elkins, D. Del Torto, R. Levien, T. Roessler || +# RFC3157 || A. Arsenault, S. Farrell || aarsenault@dvnet.com, stephen.farrell@baltimore.ie +# RFC3158 || C. Perkins, J. Rosenberg, H. Schulzrinne || csp@isi.edu, jdrosen@dynamicsoft.com, schulzrinne@cs.columbia.edu +# RFC3159 || K. McCloghrie, M. Fine, J. Seligson, K. Chan, S. Hahn, R. Sahita, A. Smith, F. Reichmeyer || mfine@cisco.com, jseligso@nortelnetworks.com, khchan@nortelnetworks.com, scott.hahn@intel.com, ravi.sahita@intel.com, andrew@allegronetworks.com, franr@pfn.com +# RFC3160 || S. Harris || +# RFC3161 || C. Adams, P. Cain, D. Pinkas, R. Zuccherato || cadams@entrust.com, pcain@bbn.com, Denis.Pinkas@bull.net, robert.zuccherato@entrust.com +# RFC3162 || B. Aboba, G. Zorn, D. Mitton || bernarda@microsoft.com, gwz@cisco.com +# RFC3163 || R. Zuccherato, M. Nystrom || robert.zuccherato@entrust.com, magnus@rsasecurity.com +# RFC3164 || C. Lonvick || clonvick@cisco.com +# RFC3165 || D. Levi, J. Schoenwaelder || +# RFC3166 || D. Meyer, J. Scudder || dmm@sprint.net, jgs@cisco.com +# RFC3167 || D. Meyer, J. Scudder || dmm@sprint.net, jgs@cisco.com +# RFC3168 || K. Ramakrishnan, S. Floyd, D. Black || kk@teraoptic.com, floyd@aciri.org, black_david@emc.com +# RFC3169 || M. Beadles, D. Mitton || dmitton@nortelnetworks.com +# RFC3170 || B. Quinn, K. Almeroth || bquinn@celoxnetworks.com, almeroth@cs.ucsb.edu +# RFC3171 || Z. Albanna, K. Almeroth, D. Meyer, M. Schipper || zaid@juniper.net, almeroth@cs.ucsb.edu, dmm@sprint.net, iana@iana.org +# RFC3172 || G. Huston, Ed. || +# RFC3173 || A. Shacham, B. Monsour, R. Pereira, M. Thomas || shacham@shacham.net, bob@bobmonsour.com, royp@cisco.com, matt@3am-software.com +# RFC3174 || D. Eastlake 3rd, P. Jones || Donald.Eastlake@motorola.com, paulej@packetizer.com +# RFC3175 || F. Baker, C. Iturralde, F. Le Faucheur, B. Davie || fred@cisco.com, cei@cisco.com, flefauch@cisco.com, bdavie@cisco.com +# RFC3176 || P. Phaal, S. Panchen, N. McKee || peter_phaal@INMON.COM, sonia_panchen@INMON.COM, neil_mckee@INMON.COM +# RFC3177 || IAB, IESG || +# RFC3178 || J. Hagino, H. Snyder || itojun@iijlab.net, hal@vailsys.com +# RFC3179 || J. Schoenwaelder, J. Quittek || schoenw@ibr.cs.tu-bs.de, quittek@ccrle.nec.de +# RFC3180 || D. Meyer, P. Lothberg || dmm@sprint.net, roll@sprint.net +# RFC3181 || S. Herzog || herzog@policyconsulting.com +# RFC3182 || S. Yadav, R. Yavatkar, R. Pabbati, P. Ford, T. Moore, S. Herzog, R. Hess || Satyendra.Yadav@intel.com, Raj.Yavatkar@intel.com, rameshpa@microsoft.com, peterf@microsoft.com, timmoore@microsoft.com, herzog@policyconsulting.com, rodney.hess@intel.com +# RFC3183 || T. Dean, W. Ottaway || tbdean@QinetiQ.com, wjottaway@QinetiQ.com +# RFC3184 || S. Harris || srh@merit.edu +# RFC3185 || S. Farrell, S. Turner || stephen.farrell@baltimore.ie, turners@ieca.com +# RFC3186 || S. Shimizu, T. Kawano, K. Murakami, E. Beier || shimizu@ntt-20.ecl.net, kawano@core.ecl.net, murakami@ntt-20.ecl.net, Beier@bina.de +# RFC3187 || J. Hakala, H. Walravens || juha.hakala@helsinki.fi, hartmut.walravens@sbb.spk-berlin.de +# RFC3188 || J. Hakala || juha.hakala@helsinki.fi +# RFC3189 || K. Kobayashi, A. Ogawa, S. Casner, C. Bormann || ikob@koganei.wide.ad.jp, akimichi@sfc.wide.ad.jp, casner@acm.org, cabo@tzi.org +# RFC3190 || K. Kobayashi, A. Ogawa, S. Casner, C. Bormann || ikob@koganei.wide.ad.jp, akimichi@sfc.wide.ad.jp, casner@acm.org, cabo@tzi.org +# RFC3191 || C. Allocchio || +# RFC3192 || C. Allocchio || +# RFC3193 || B. Patel, B. Aboba, W. Dixon, G. Zorn, S. Booth || baiju.v.patel@intel.com, bernarda@microsoft.com, wdixon@microsoft.com, gwz@cisco.com, ebooth@cisco.com +# RFC3194 || A. Durand, C. Huitema || +# RFC3195 || D. New, M. Rose || dnew@san.rr.com, mrose17@gmail.com +# RFC3196 || T. Hastings, C. Manros, P. Zehler, C. Kugler, H. Holst || tom.hastings@alum.mit.edu, Kugler@us.ibm.com, hh@I-data.com, Peter.Zehler@xerox.com +# RFC3197 || R. Austein || sra@hactrn.net +# RFC3198 || A. Westerinen, J. Schnizlein, J. Strassner, M. Scherling, B. Quinn, S. Herzog, A. Huynh, M. Carlson, J. Perry, S. Waldbusser || andreaw@cisco.com, john.schnizlein@cisco.com, john.strassner@intelliden.com, mscherling@xcert.com, bquinn@celoxnetworks.com, jay.perry@netapp.com, herzog@PolicyConsulting.com, mark.carlson@sun.com, waldbusser@nextbeacon.com +# RFC3199 || S. Ginoza || ginoza@isi.edu +# RFC3200 || || +# RFC3201 || R. Steinberger, O. Nicklass || robert.steinberger@fnc.fujitsu.com, Orly_n@rad.co.il +# RFC3202 || R. Steinberger, O. Nicklass || robert.steinberger@fnc.fujitsu.com, Orly_n@rad.co.il +# RFC3203 || Y. T'Joens, C. Hublet, P. De Schrijver || yves.tjoens@alcatel.be, p2@mind.be, Christian.Hublet@alcatel.be +# RFC3204 || E. Zimmerer, J. Peterson, A. Vemuri, L. Ong, F. Audet, M. Watson, M. Zonoun || eric_zimmerer@yahoo.com, Aparna.Vemuri@Qwest.com, jon.peterson@neustar.com, lyndon_ong@yahoo.com, mzonoun@nortelnetworks.com, audet@nortelnetworks.com, mwatson@nortelnetworks.com +# RFC3205 || K. Moore || moore@cs.utk.edu +# RFC3206 || R. Gellens || randy@qualcomm.com +# RFC3207 || P. Hoffman || phoffman@imc.org +# RFC3208 || T. Speakman, J. Crowcroft, J. Gemmell, D. Farinacci, S. Lin, D. Leshchiner, M. Luby, T. Montgomery, L. Rizzo, A. Tweedly, N. Bhaskar, R. Edmonstone, R. Sumanasekera, L. Vicisano || speakman@cisco.com, dino@procket.com, steven@juniper.net, agt@cisco.com, nbhaskar@cisco.com, redmonst@cisco.com, rajitha@cisco.com, lorenzo@cisco.com, j.crowcroft@cs.ucl.ac.uk, jgemmell@microsoft.com, dleshc@tibco.com, luby@digitalfountain.com, todd@talarian.com, luigi@iet.unipi.it +# RFC3209 || D. Awduche, L. Berger, D. Gan, T. Li, V. Srinivasan, G. Swallow || awduche@movaz.com, lberger@movaz.com, dhg@juniper.net, tli@procket.com, vsriniva@cosinecom.com, swallow@cisco.com +# RFC3210 || D. Awduche, A. Hannan, X. Xiao || awduche@movaz.com, alan@routingloop.com, xxiao@photuris.com +# RFC3211 || P. Gutmann || pgut001@cs.auckland.ac.nz +# RFC3212 || B. Jamoussi, Ed., L. Andersson, R. Callon, R. Dantu, L. Wu, P. Doolan, T. Worster, N. Feldman, A. Fredette, M. Girish, E. Gray, J. Heinanen, T. Kilty, A. Malis || loa.andersson@utfors.se, rcallon@juniper.net, rdantu@netrake.com, pdoolan@acm.org, Nkf@us.ibm.com, afredette@charter.net, eric.gray@sandburst.com, jh@song.fi, tim-kilty@mediaone.net, Andy.Malis@vivacenetworks.com, muckai@atoga.com, fsb@thefsb.org, liwwu@cisco.com +# RFC3213 || J. Ash, M. Girish, E. Gray, B. Jamoussi, G. Wright || gash@att.com, eric.gray@sandburst.com, gwright@nortelnetworks.com, muckai@atoga.com, Jamoussi@nortelnetworks.com +# RFC3214 || J. Ash, Y. Lee, P. Ashwood-Smith, B. Jamoussi, D. Fedyk, D. Skalecki, L. Li || gash@att.com, jamoussi@NortelNetworks.com, petera@NortelNetworks.com, dareks@nortelnetworks.com, ylee@ceterusnetworks.com, lili@ss8networks.com, dwfedyk@nortelnetworks.com +# RFC3215 || C. Boscher, P. Cheval, L. Wu, E. Gray || christophe.boscher@alcatel.fr, pierrick.cheval@space.alcatel.fr, liwwu@cisco.com, eric.gray@sandburst.com +# RFC3216 || C. Elliott, D. Harrington, J. Jason, J. Schoenwaelder, F. Strauss, W. Weiss || chelliot@cisco.com, dbh@enterasys.com, jamie.jason@intel.com, schoenw@ibr.cs.tu-bs.de, strauss@ibr.cs.tu-bs.de, wweiss@ellacoya.com +# RFC3217 || R. Housley || rhousley@rsasecurity.com +# RFC3218 || E. Rescorla || ekr@rtfm.com +# RFC3219 || J. Rosenberg, H. Salama, M. Squire || jdrosen@dynamicsoft.com, hsalama@cisco.com, mattsquire@acm.org +# RFC3220 || C. Perkins, Ed. || charliep@iprg.nokia.com +# RFC3221 || G. Huston || +# RFC3222 || G. Trotter || Guy_Trotter@agilent.com +# RFC3223 || || +# RFC3224 || E. Guttman || erik.guttman@sun.com +# RFC3225 || D. Conrad || david.conrad@nominum.com +# RFC3226 || O. Gudmundsson || ogud@ogud.com +# RFC3227 || D. Brezinski, T. Killalea || dbrezinski@In-Q-Tel.org, tomk@neart.org +# RFC3228 || B. Fenner || fenner@research.att.com +# RFC3229 || J. Mogul, B. Krishnamurthy, F. Douglis, A. Feldmann, Y. Goland, A. van Hoff, D. Hellerstein || +# RFC3230 || J. Mogul, A. Van Hoff || JeffMogul@acm.org, avh@marimba.com +# RFC3231 || D. Levi, J. Schoenwaelder || +# RFC3232 || J. Reynolds, Ed. || rfc-editor@rfc-editor.org +# RFC3233 || P. Hoffman, S. Bradner || +# RFC3234 || B. Carpenter, S. Brim || brian@hursley.ibm.com, sbrim@cisco.com +# RFC3235 || D. Senie || dts@senie.com +# RFC3236 || M. Baker, P. Stark || mbaker@planetfred.com, distobj@acm.org, Peter.Stark@ecs.ericsson.com +# RFC3237 || M. Tuexen, Q. Xie, R. Stewart, M. Shore, L. Ong, J. Loughney, M. Stillman || Michael.Tuexen@icn.siemens.de, qxie1@email.mot.com, randall@lakerest.net, mshore@cisco.com, lyong@ciena.com, john.loughney@nokia.com, maureen.stillman@nokia.com +# RFC3238 || S. Floyd, L. Daigle || iab@iab.org +# RFC3239 || C. Kugler, H. Lewis, T. Hastings || kugler@us.ibm.com, tom.hastings@alum.mit.edu, harryl@us.ibm.com +# RFC3240 || D. Clunie, E. Cordonnier || dclunie@dclunie.com, emmanuel.cordonnier@etiam.com +# RFC3241 || C. Bormann || cabo@tzi.org +# RFC3242 || L-E. Jonsson, G. Pelletier || lars-erik.jonsson@ericsson.com, ghyslain.pelletier@epl.ericsson.se +# RFC3243 || L-E. Jonsson || lars-erik.jonsson@ericsson.com +# RFC3244 || M. Swift, J. Trostle, J. Brezak || mikesw@cs.washington.edu, john3725@world.std.com, jbrezak@microsoft.com +# RFC3245 || J. Klensin, Ed., IAB || iab@iab.org, sob@harvard.edu, paf@cisco.com +# RFC3246 || B. Davie, A. Charny, J.C.R. Bennet, K. Benson, J.Y. Le Boudec, W. Courtney, S. Davari, V. Firoiu, D. Stiliadis || bsd@cisco.com, acharny@cisco.com, jcrb@motorola.com, Kent.Benson@tellabs.com, jean-yves.leboudec@epfl.ch, bill.courtney@trw.com, shahram_davari@pmc-sierra.com, vfiroiu@nortelnetworks.com, stiliadi@bell-labs.com +# RFC3247 || A. Charny, J. Bennet, K. Benson, J. Boudec, A. Chiu, W. Courtney, S. Davari, V. Firoiu, C. Kalmanek, K. Ramakrishnan || acharny@cisco.com, jcrb@motorola.com, Kent.Benson@tellabs.com, jean-yves.leboudec@epfl.ch, angela.chiu@celion.com, bill.courtney@trw.com, shahram_davari@pmc-sierra.com, vfiroiu@nortelnetworks.com, crk@research.att.com, kk@teraoptic.com +# RFC3248 || G. Armitage, B. Carpenter, A. Casati, J. Crowcroft, J. Halpern, B. Kumar, J. Schnizlein || +# RFC3249 || V. Cancio, M. Moldovan, H. Tamura, D. Wing || vcancio@pacbell.net, mmoldovan@g3nova.com, tamura@toda.ricoh.co.jp, dwing-ietf@fuggles.com +# RFC3250 || L. McIntyre, G. Parsons, J. Rafferty || lmcintyre@pahv.xerox.com, gparsons@nortelnetworks.com, jraff@brooktrout.com +# RFC3251 || B. Rajagopalan || braja@tellium.com +# RFC3252 || H. Kennedy || kennedyh@engin.umich.edu +# RFC3253 || G. Clemm, J. Amsden, T. Ellison, C. Kaler, J. Whitehead || geoffrey.clemm@rational.com, jamsden@us.ibm.com, tim_ellison@uk.ibm.com, ckaler@microsoft.com, ejw@cse.ucsc.edu +# RFC3254 || H. Alvestrand || Harald@alvestrand.no +# RFC3255 || N. Jones, C. Murton || nrjones@agere.com, murton@nortelnetworks.com +# RFC3256 || D. Jones, R. Woundy || doug@yas.com, rwoundy@broadband.att.com +# RFC3257 || L. Coene || +# RFC3258 || T. Hardie || Ted.Hardie@nominum.com +# RFC3259 || J. Ott, C. Perkins, D. Kutscher || jo@tzi.uni-bremen.de, csp@isi.edu, dku@tzi.uni-bremen.de +# RFC3260 || D. Grossman || dan@dma.isg.mot.com +# RFC3261 || J. Rosenberg, H. Schulzrinne, G. Camarillo, A. Johnston, J. Peterson, R. Sparks, M. Handley, E. Schooler || jdrosen@dynamicsoft.com, schulzrinne@cs.columbia.edu, Gonzalo.Camarillo@ericsson.com, alan.johnston@wcom.com, jon.peterson@neustar.com, rsparks@dynamicsoft.com, mjh@icir.org, schooler@research.att.com +# RFC3262 || J. Rosenberg, H. Schulzrinne || jdrosen@dynamicsoft.com, schulzrinne@cs.columbia.edu +# RFC3263 || J. Rosenberg, H. Schulzrinne || jdrosen@dynamicsoft.com, schulzrinne@cs.columbia.edu +# RFC3264 || J. Rosenberg, H. Schulzrinne || jdrosen@dynamicsoft.com, schulzrinne@cs.columbia.edu +# RFC3265 || A. B. Roach || adam@dynamicsoft.com +# RFC3266 || S. Olson, G. Camarillo, A. B. Roach || seanol@microsoft.com, Gonzalo.Camarillo@ericsson.com, adam@dynamicsoft.com +# RFC3267 || J. Sjoberg, M. Westerlund, A. Lakaniemi, Q. Xie || Johan.Sjoberg@ericsson.com, Magnus.Westerlund@ericsson.com, ari.lakaniemi@nokia.com, qxie1@email.mot.com +# RFC3268 || P. Chown || pc@skygate.co.uk +# RFC3269 || R. Kermode, L. Vicisano || Roger.Kermode@motorola.com, lorenzo@cisco.com +# RFC3270 || F. Le Faucheur, L. Wu, B. Davie, S. Davari, P. Vaananen, R. Krishnan, P. Cheval, J. Heinanen || flefauch@cisco.com, liwwu@cisco.com, bsd@cisco.com, davari@ieee.org, pasi.vaananen@nokia.com, ram@axiowave.com, pierrick.cheval@space.alcatel.fr, jh@song.fi +# RFC3271 || V. Cerf || vinton.g.cerf@wcom.com +# RFC3272 || D. Awduche, A. Chiu, A. Elwalid, I. Widjaja, X. Xiao || awduche@movaz.com, angela.chiu@celion.com, anwar@lucent.com, iwidjaja@research.bell-labs.com, xipeng@redback.com +# RFC3273 || S. Waldbusser || waldbusser@nextbeacon.com +# RFC3274 || P. Gutmann || pgut001@cs.auckland.ac.nz +# RFC3275 || D. Eastlake 3rd, J. Reagle, D. Solo || Donald.Eastlake@motorola.com, reagle@w3.org, dsolo@alum.mit.edu +# RFC3276 || B. Ray, R. Abbi || rray@pesa.com, Rajesh.Abbi@alcatel.com +# RFC3277 || D. McPherson || danny@tcb.net +# RFC3278 || S. Blake-Wilson, D. Brown, P. Lambert || sblakewi@certicom.com, dbrown@certicom.com, plambert@sprintmail.com +# RFC3279 || L. Bassham, W. Polk, R. Housley || tim.polk@nist.gov, rhousley@rsasecurity.com, lbassham@nist.gov +# RFC3280 || R. Housley, W. Polk, W. Ford, D. Solo || rhousley@rsasecurity.com, wford@verisign.com, wpolk@nist.gov, dsolo@alum.mit.edu +# RFC3281 || S. Farrell, R. Housley || stephen.farrell@baltimore.ie, rhousley@rsasecurity.com +# RFC3282 || H. Alvestrand || Harald@Alvestrand.no +# RFC3283 || B. Mahoney, G. Babics, A. Taler || bobmah@mit.edu, georgeb@steltor.com, alex@0--0.org +# RFC3284 || D. Korn, J. MacDonald, J. Mogul, K. Vo || kpv@research.att.com, dgk@research.att.com, JeffMogul@acm.org, jmacd@cs.berkeley.edu +# RFC3285 || M. Gahrns, T. Hain || mikega@microsoft.com, ahain@cisco.com +# RFC3286 || L. Ong, J. Yoakum || lyong@ciena.com, yoakum@nortelnetworks.com +# RFC3287 || A. Bierman || andy@yumaworks.com +# RFC3288 || E. O'Tuathail, M. Rose || eamon.otuathail@clipcode.com, mrose17@gmail.com +# RFC3289 || F. Baker, K. Chan, A. Smith || fred@cisco.com, khchan@nortelnetworks.com, ah_smith@acm.org +# RFC3290 || Y. Bernet, S. Blake, D. Grossman, A. Smith || ybernet@msn.com, steven.blake@ericsson.com, dan@dma.isg.mot.com, ah_smith@acm.org +# RFC3291 || M. Daniele, B. Haberman, S. Routhier, J. Schoenwaelder || md@world.std.com, bkhabs@nc.rr.com, sar@epilogue.com, schoenw@ibr.cs.tu-bs.de +# RFC3292 || A. Doria, F. Hellstrand, K. Sundell, T. Worster || avri@acm.org, fiffi@nortelnetworks.com, ksundell@nortelnetworks.com, fsb@thefsb.org +# RFC3293 || T. Worster, A. Doria, J. Buerkle || fsb@thefsb.org, avri@acm.com, Joachim.Buerkle@nortelnetworks.com +# RFC3294 || A. Doria, K. Sundell || avri@acm.org, sundell@nortelnetworks.com +# RFC3295 || H. Sjostrand, J. Buerkle, B. Srinivasan || hans@ipunplugged.com, joachim.buerkle@nortelnetworks.com, balaji@cplane.com +# RFC3296 || K. Zeilenga || Kurt@OpenLDAP.org +# RFC3297 || G. Klyne, R. Iwazaki, D. Crocker || GK@ACM.ORG, iwa@rdl.toshibatec.co.jp, dcrocker@brandenburg.com +# RFC3298 || I. Faynberg, J. Gato, H. Lu, L. Slutsman || lslutsman@att.com, faynberg@lucent.com, jgato@airtel.es, huilanlu@lucent.com +# RFC3299 || S. Ginoza || ginoza@isi.edu +# RFC3300 || J. Reynolds, R. Braden, S. Ginoza, A. De La Cruz || +# RFC3301 || Y. T'Joens, P. Crivellari, B. Sales || paolo.crivellari@belgacom.be +# RFC3302 || G. Parsons, J. Rafferty || gparsons@nortelnetworks.com, jraff@brooktrout.com +# RFC3303 || P. Srisuresh, J. Kuthan, J. Rosenberg, A. Molitor, A. Rayhan || srisuresh@yahoo.com, kuthan@fokus.fhg.de, jdrosen@dynamicsoft.com, amolitor@visi.com, rayhan@ee.ryerson.ca +# RFC3304 || R. P. Swale, P. A. Mart, P. Sijben, S. Brim, M. Shore || richard.swale@bt.com, paul.sijben@picopoint.com, philip.mart@marconi.com, sbrim@cisco.com, mshore@cisco.com +# RFC3305 || M. Mealling, Ed., R. Denenberg, Ed. || michael@verisignlabs.com, rden@loc.gov +# RFC3306 || B. Haberman, D. Thaler || bkhabs@nc.rr.com, dthaler@microsoft.com +# RFC3307 || B. Haberman || bkhabs@nc.rr.com +# RFC3308 || P. Calhoun, W. Luo, D. McPherson, K. Peirce || pcalhoun@bstormnetworks.com, luo@cisco.com, danny@tcb.net, Ken@malibunetworks.com +# RFC3309 || J. Stone, R. Stewart, D. Otis || jonathan@dsg.stanford.edu, randall@lakerest.net, dotis@sanlight.net +# RFC3310 || A. Niemi, J. Arkko, V. Torvinen || aki.niemi@nokia.com, jari.arkko@ericsson.com, vesa.torvinen@ericsson.fi +# RFC3311 || J. Rosenberg || jdrosen@dynamicsoft.com +# RFC3312 || G. Camarillo, Ed., W. Marshall, Ed., J. Rosenberg || Gonzalo.Camarillo@ericsson.com, wtm@research.att.com, jdrosen@dynamicsoft.com +# RFC3313 || W. Marshall, Ed. || +# RFC3314 || M. Wasserman, Ed. || +# RFC3315 || R. Droms, Ed., J. Bound, B. Volz, T. Lemon, C. Perkins, M. Carney || Jim.Bound@hp.com, volz@metrocast.net, Ted.Lemon@nominum.com, charles.perkins@nokia.com, michael.carney@sun.com +# RFC3316 || J. Arkko, G. Kuijpers, H. Soliman, J. Loughney, J. Wiljakka || jari.arkko@ericsson.com, gerben.a.kuijpers@ted.ericsson.se, john.loughney@nokia.com, hesham.soliman@era.ericsson.se, juha.wiljakka@nokia.com +# RFC3317 || K. Chan, R. Sahita, S. Hahn, K. McCloghrie || khchan@nortelnetworks.com, ravi.sahita@intel.com, scott.hahn@intel.com, kzm@cisco.com +# RFC3318 || R. Sahita, Ed., S. Hahn, K. Chan, K. McCloghrie || ravi.sahita@intel.com, scott.hahn@intel.com, khchan@nortelnetworks.com, kzm@cisco.com +# RFC3319 || H. Schulzrinne, B. Volz || schulzrinne@cs.columbia.edu, volz@metrocast.net +# RFC3320 || R. Price, C. Bormann, J. Christoffersson, H. Hannu, Z. Liu, J. Rosenberg || richard.price@roke.co.uk, cabo@tzi.org, jan.christoffersson@epl.ericsson.se, hans.hannu@epl.ericsson.se, zhigang.c.liu@nokia.com, jdrosen@dynamicsoft.com +# RFC3321 || H. Hannu, J. Christoffersson, S. Forsgren, K.-C. Leung, Z. Liu, R. Price || hans.hannu@epl.ericsson.se, jan.christoffersson@epl.ericsson.se, StefanForsgren@alvishagglunds.se, kcleung@cs.ttu.edu, zhigang.c.liu@nokia.com, richard.price@roke.co.uk +# RFC3322 || H. Hannu || hans.hannu@epl.ericsson.se +# RFC3323 || J. Peterson || jon.peterson@neustar.biz +# RFC3324 || M. Watson || mwatson@nortelnetworks.com +# RFC3325 || C. Jennings, J. Peterson, M. Watson || fluffy@cisco.com, Jon.Peterson@NeuStar.biz, mwatson@nortelnetworks.com +# RFC3326 || H. Schulzrinne, D. Oran, G. Camarillo || schulzrinne@cs.columbia.edu, oran@cisco.com, Gonzalo.Camarillo@ericsson.com +# RFC3327 || D. Willis, B. Hoeneisen || dean.willis@softarmor.com, hoeneisen@switch.ch +# RFC3328 || || +# RFC3329 || J. Arkko, V. Torvinen, G. Camarillo, A. Niemi, T. Haukka || jari.arkko@ericsson.com, vesa.torvinen@ericsson.fi, Gonzalo.Camarillo@ericsson.com, aki.niemi@nokia.com, tao.haukka@nokia.com +# RFC3330 || IANA || iana@iana.org +# RFC3331 || K. Morneault, R. Dantu, G. Sidebottom, B. Bidulock, J. Heitz || kmorneau@cisco.com, rdantu@netrake.com, greg@signatustechnologies.com, bidulock@openss7.org, jheitz@lucent.com +# RFC3332 || G. Sidebottom, Ed., K. Morneault, Ed., J. Pastor-Balbas, Ed. || +# RFC3334 || T. Zseby, S. Zander, C. Carle || zseby@fokus.fhg.de, zander@fokus.fhg.de, carle@fokus.fhg.de +# RFC3335 || T. Harding, R. Drummond, C. Shih || tharding@cyclonecommerce.com, chuck.shih@gartner.com, rik@drummondgroup.com +# RFC3336 || B. Thompson, T. Koren, B. Buffam || brucet@cisco.com, tmima@cisco.com, bruce@seawaynetworks.com +# RFC3337 || B. Thompson, T. Koren, B. Buffam || brucet@cisco.com, bruce@seawaynetworks.com, tmima@cisco.com +# RFC3338 || S. Lee, M-K. Shin, Y-J. Kim, E. Nordmark, A. Durand || syl@pec.etri.re.kr, mkshin@pec.etri.re.kr, yjkim@pec.etri.re.kr, Alain.Durand@sun.com, erik.nordmark@sun.com +# RFC3339 || G. Klyne, C. Newman || chris.newman@sun.com, GK@ACM.ORG +# RFC3340 || M. Rose, G. Klyne, D. Crocker || mrose17@gmail.com, Graham.Klyne@MIMEsweeper.com, dcrocker@brandenburg.com +# RFC3341 || M. Rose, G. Klyne, D. Crocker || mrose17@gmail.com, Graham.Klyne@MIMEsweeper.com, dcrocker@brandenburg.com +# RFC3342 || E. Dixon, H. Franklin, J. Kint, G. Klyne, D. New, S. Pead, M. Rose, M. Schwartz || Graham.Klyne@MIMEsweeper.com, mrose17@gmail.com, schwartz@CodeOnTheRoad.com, edixon@myrealbox.com, huston@franklin.ro, d20@icosahedron.org, dnew@san.rr.com, spead@fiber.net +# RFC3343 || M. Rose, G. Klyne, D. Crocker || mrose17@gmail.com, gk@ninebynine.org, dcrocker@brandenburg.com +# RFC3344 || C. Perkins, Ed. || Basavaraj.Patil@nokia.com, PRoberts@MEGISTO.com, charliep@iprg.nokia.com +# RFC3345 || D. McPherson, V. Gill, D. Walton, A. Retana || danny@tcb.net, vijay@umbc.edu, dwalton@cisco.com, aretana@cisco.com +# RFC3346 || J. Boyle, V. Gill, A. Hannan, D. Cooper, D. Awduche, B. Christian, W.S. Lai || jboyle@pdnets.com, vijay@umbc.edu, alan@routingloop.com, dcooper@gblx.net, awduche@movaz.com, blaine@uu.net, wlai@att.com +# RFC3347 || M. Krueger, R. Haagens || marjorie_krueger@hp.com, Randy_Haagens@hp.com, csapuntz@stanford.edu, mbakke@cisco.com +# RFC3348 || M. Gahrns, R. Cheng || mikega@microsoft.com, raych@microsoft.com +# RFC3349 || M. Rose || mrose17@gmail.com +# RFC3351 || N. Charlton, M. Gasson, G. Gybels, M. Spanner, A. van Wijk || nathan@millpark.com, michael.gasson@korusolutions.com, Guido.Gybels@rnid.org.uk, mike.spanner@rnid.org.uk, Arnoud.van.Wijk@eln.ericsson.se +# RFC3352 || K. Zeilenga || Kurt@OpenLDAP.org +# RFC3353 || D. Ooms, B. Sales, W. Livens, A. Acharya, F. Griffoul, F. Ansari || Dirk.Ooms@alcatel.be, Bernard.Sales@alcatel.be, WLivens@colt-telecom.be, arup@us.ibm.com, griffoul@ulticom.com, furquan@dnrc.bell-labs.com +# RFC3354 || D. Eastlake 3rd || Donald.Eastlake@motorola.com +# RFC3355 || A. Singh, R. Turner, R. Tio, S. Nanji || rturner@eng.paradyne.com, tor@redback.com, asingh1@motorola.com, suhail@redback.com +# RFC3356 || G. Fishman, S. Bradner || +# RFC3357 || R. Koodli, R. Ravikanth || rajeev.koodli@nokia.com, rravikanth@axiowave.com +# RFC3358 || T. Przygienda || prz@xebeo.com +# RFC3359 || T. Przygienda || +# RFC3360 || S. Floyd || floyd@icir.org +# RFC3361 || H. Schulzrinne || schulzrinne@cs.columbia.edu +# RFC3362 || G. Parsons || gparsons@nortelnetworks.com +# RFC3363 || R. Bush, A. Durand, B. Fink, O. Gudmundsson, T. Hain || +# RFC3364 || R. Austein || sra@hactrn.net +# RFC3365 || J. Schiller || jis@mit.edu +# RFC3366 || G. Fairhurst, L. Wood || gorry@erg.abdn.ac.uk, lwood@cisco.com +# RFC3367 || N. Popp, M. Mealling, M. Moseley || npopp@verisign.com, michael@verisignlabs.com, marshall@netword.com +# RFC3368 || M. Mealling || michael@verisignlabs.com +# RFC3369 || R. Housley || rhousley@rsasecurity.com +# RFC3370 || R. Housley || rhousley@rsasecurity.com +# RFC3371 || E. Caves, P. Calhoun, R. Wheeler || evan@occamnetworks.com, pcalhoun@bstormnetworks.com +# RFC3372 || A. Vemuri, J. Peterson || Aparna.Vemuri@Qwest.com, jon.peterson@neustar.biz +# RFC3373 || D. Katz, R. Saluja || dkatz@juniper.net, rajesh.saluja@tenetindia.com +# RFC3374 || J. Kempf, Ed. || henrik@levkowetz.com, pcalhoun@bstormnetworks.com, kempf@docomolabs-usa.com, gkenward@nortelnetworks.com, hmsyed@nortelnetworks.com, jmanner@cs.helsinki.fi, madjid.nakhjiri@motorola.com, govind.krishnamurthi@nokia.com, rajeev.koodli@nokia.com, kulwinder.atwal@zucotto.com, mat@cisco.com, mat.horan@comdev.cc, phil_neumiller@3com.com +# RFC3375 || S. Hollenbeck || +# RFC3376 || B. Cain, S. Deering, I. Kouvelas, B. Fenner, A. Thyagarajan || deering@cisco.com, fenner@research.att.com, kouvelas@cisco.com +# RFC3377 || J. Hodges, R. Morgan || Jeff.Hodges@sun.com, rlmorgan@washington.edu +# RFC3378 || R. Housley, S. Hollenbeck || rhousley@rsasecurity.com, shollenbeck@verisign.com +# RFC3379 || D. Pinkas, R. Housley || Denis.Pinkas@bull.net, rhousley@rsasecurity.com +# RFC3380 || T. Hastings, R. Herriot, C. Kugler, H. Lewis || kugler@us.ibm.com, tom.hastings@alum.mit.edu, bob@Herriot.com, harryl@us.ibm.com +# RFC3381 || T. Hastings, H. Lewis, R. Bergman || tom.hastings@alum.mit.edu, harryl@us.ibm.com, rbergma@hitachi-hkis.com +# RFC3382 || R. deBry, T. Hastings, R. Herriot, K. Ocke, P. Zehler || debryro@uvsc.edu, tom.hastings@alum.mit.edu, bob@herriot.com, KOcke@crt.xerox.com, Peter.Zehler@xerox.com +# RFC3383 || K. Zeilenga || Kurt@OpenLDAP.org +# RFC3384 || E. Stokes, R. Weiser, R. Moats, R. Huber || rweiser@trustdst.com, stokese@us.ibm.com, rmoats@lemurnetworks.net, rvh@att.com +# RFC3385 || D. Sheinwald, J. Satran, P. Thaler, V. Cavanna || julian_satran@il.ibm.com, Dafna_Sheinwald@il.ibm.com, pat_thaler@agilent.com, vince_cavanna@agilent.com +# RFC3386 || W. Lai, Ed., D. McDysan, Ed. || +# RFC3387 || M. Eder, H. Chaskar, S. Nag || Michael.eder@nokia.com, thinker@monmouth.com, hemant.chaskar@nokia.com +# RFC3388 || G. Camarillo, G. Eriksson, J. Holler, H. Schulzrinne || Gonzalo.Camarillo@ericsson.com, Jan.Holler@era.ericsson.se, Goran.AP.Eriksson@era.ericsson.se, schulzrinne@cs.columbia.edu +# RFC3389 || R. Zopf || zopf@lucent.com +# RFC3390 || M. Allman, S. Floyd, C. Partridge || mallman@bbn.com, floyd@icir.org, craig@bbn.com +# RFC3391 || R. Herriot || bob@herriot.com +# RFC3392 || R. Chandra, J. Scudder || rchandra@redback.com, jgs@cisco.com +# RFC3393 || C. Demichelis, P. Chimento || carlo.demichelis@tilab.com, chimento@torrentnet.com +# RFC3394 || J. Schaad, R. Housley || jimsch@exmsft.com, rhousley@rsasecurity.com +# RFC3395 || A. Bierman, C. Bucci, R. Dietz, A. Warth || andy@yumaworks.com, cbucci@cisco.com, rdietz@hifn.com, dahoss@earthlink.net +# RFC3396 || T. Lemon, S. Cheshire || mellon@nominum.com, rfc@stuartcheshire.org +# RFC3397 || B. Aboba, S. Cheshire || bernarda@microsoft.com, rfc@stuartcheshire.org +# RFC3398 || G. Camarillo, A. B. Roach, J. Peterson, L. Ong || Gonzalo.Camarillo@Ericsson.com, adam@dynamicsoft.com, jon.peterson@neustar.biz, lyOng@ciena.com +# RFC3400 || || +# RFC3401 || M. Mealling || michael@neonym.net +# RFC3402 || M. Mealling || michael@neonym.net +# RFC3403 || M. Mealling || michael@neonym.net +# RFC3404 || M. Mealling || michael@neonym.net +# RFC3405 || M. Mealling || michael@neonym.net +# RFC3406 || L. Daigle, D. van Gulik, R. Iannella, P. Faltstrom || leslie@thinkingcat.com, renato@iprsystems.com, paf@cisco.com +# RFC3407 || F. Andreasen || fandreas@cisco.com +# RFC3408 || Z. Liu, K. Le || khiem.le@nokia.com +# RFC3409 || K. Svanbro || krister.svanbro@ericsson.com +# RFC3410 || J. Case, R. Mundy, D. Partain, B. Stewart || +# RFC3411 || D. Harrington, R. Presuhn, B. Wijnen || +# RFC3412 || J. Case, D. Harrington, R. Presuhn, B. Wijnen || +# RFC3413 || D. Levi, P. Meyer, B. Stewart || +# RFC3414 || U. Blumenthal, B. Wijnen || +# RFC3415 || B. Wijnen, R. Presuhn, K. McCloghrie || +# RFC3416 || R. Presuhn, Ed. || +# RFC3417 || R. Presuhn, Ed. || +# RFC3418 || R. Presuhn, Ed. || +# RFC3419 || M. Daniele, J. Schoenwaelder || md@world.std.com, schoenw@ibr.cs.tu-bs.de +# RFC3420 || R. Sparks || rsparks@dynamicsoft.com +# RFC3421 || W. Zhao, H. Schulzrinne, E. Guttman, C. Bisdikian, W. Jerome || zwb@cs.columbia.edu, hgs@cs.columbia.edu, Erik.Guttman@sun.com, bisdik@us.ibm.com, wfj@us.ibm.com +# RFC3422 || O. Okamoto, M. Maruyama, T. Sajima || okamoto.osamu@lab.ntt.co.jp, mitsuru@core.ecl.net, tjs@sun.com +# RFC3423 || K. Zhang, E. Elkin || kevinzhang@ieee.org, eitan@xacct.com +# RFC3424 || L. Daigle, Ed., IAB || iab@iab.org +# RFC3425 || D. Lawrence || tale@nominum.com +# RFC3426 || S. Floyd || iab@iab.org +# RFC3427 || A. Mankin, S. Bradner, R. Mahy, D. Willis, J. Ott, B. Rosen || mankin@psg.com, sob@harvard.edu, rohan@cisco.com, dean.willis@softarmor.com, brian.rosen@marconi.com, jo@ipdialog.com +# RFC3428 || B. Campbell, Ed., J. Rosenberg, H. Schulzrinne, C. Huitema, D. Gurle || bcampbell@dynamicsoft.com, jdrosen@dynamicsoft.com, schulzrinne@cs.columbia.edu, huitema@microsoft.com, dgurle@microsoft.com +# RFC3429 || H. Ohta || ohta.hiroshi@lab.ntt.co.jp +# RFC3430 || J. Schoenwaelder || schoenw@ibr.cs.tu-bs.de +# RFC3431 || W. Segmuller || whs@watson.ibm.com +# RFC3432 || V. Raisanen, G. Grotefeld, A. Morton || Vilho.Raisanen@nokia.com, g.grotefeld@motorola.com, acmorton@att.com +# RFC3433 || A. Bierman, D. Romascanu, K.C. Norseth || andy@yumaworks.com, dromasca@gmail.com , kenyon.c.norseth@L-3com.com +# RFC3434 || A. Bierman, K. McCloghrie || andy@yumaworks.com, kzm@cisco.com +# RFC3435 || F. Andreasen, B. Foster || fandreas@cisco.com, bfoster@cisco.com +# RFC3436 || A. Jungmaier, E. Rescorla, M. Tuexen || ajung@exp-math.uni-essen.de, ekr@rtfm.com, Michael.Tuexen@siemens.com +# RFC3437 || W. Palter, W. Townsley || mark@townsley.net, palter.ietf@zev.net +# RFC3438 || W. Townsley || mark@townsley.net +# RFC3439 || R. Bush, D. Meyer || randy@psg.com, dmm@maoz.com +# RFC3440 || F. Ly, G. Bathrick || faye@pedestalnetworks.com, greg.bathrick@nokia.com +# RFC3441 || R. Kumar || rkumar@cisco.com +# RFC3442 || T. Lemon, S. Cheshire, B. Volz || Ted.Lemon@nominum.com, rfc@stuartcheshire.org, bernie.volz@ericsson.com +# RFC3443 || P. Agarwal, B. Akyol || puneet@acm.org, bora@cisco.com +# RFC3444 || A. Pras, J. Schoenwaelder || pras@ctit.utwente.nl, schoenw@informatik.uni-osnabrueck.de +# RFC3445 || D. Massey, S. Rose || masseyd@isi.edu, scott.rose@nist.gov +# RFC3446 || D. Kim, D. Meyer, H. Kilmer, D. Farinacci || dorian@blackrose.org, hank@rem.com, dino@procket.com, dmm@maoz.com +# RFC3447 || J. Jonsson, B. Kaliski || jonsson@mathematik.uni-marburg.de, bkaliski@rsasecurity.com +# RFC3448 || M. Handley, S. Floyd, J. Padhye, J. Widmer || mjh@icir.org, floyd@icir.org, padhye@microsoft.com, widmer@informatik.uni-mannheim.de +# RFC3449 || H. Balakrishnan, V. Padmanabhan, G. Fairhurst, M. Sooriyabandara || hari@lcs.mit.edu, padmanab@microsoft.com, gorry@erg.abdn.ac.uk, mahesh@erg.abdn.ac.uk +# RFC3450 || M. Luby, J. Gemmell, L. Vicisano, L. Rizzo, J. Crowcroft || luby@digitalfountain.com, jgemmell@microsoft.com, lorenzo@cisco.com, luigi@iet.unipi.it, Jon.Crowcroft@cl.cam.ac.uk +# RFC3451 || M. Luby, J. Gemmell, L. Vicisano, L. Rizzo, M. Handley, J. Crowcroft || luby@digitalfountain.com, jgemmell@microsoft.com, lorenzo@cisco.com, luigi@iet.unipi.it, mjh@icir.org, Jon.Crowcroft@cl.cam.ac.uk +# RFC3452 || M. Luby, L. Vicisano, J. Gemmell, L. Rizzo, M. Handley, J. Crowcroft || luby@digitalfountain.com, lorenzo@cisco.com, jgemmell@microsoft.com, luigi@iet.unipi.it, mjh@icir.org, Jon.Crowcroft@cl.cam.ac.uk +# RFC3453 || M. Luby, L. Vicisano, J. Gemmell, L. Rizzo, M. Handley, J. Crowcroft || luby@digitalfountain.com, lorenzo@cisco.com, jgemmell@microsoft.com, luigi@iet.unipi.it, mjh@icir.org, Jon.Crowcroft@cl.cam.ac.uk +# RFC3454 || P. Hoffman, M. Blanchet || paul.hoffman@imc.org, Marc.Blanchet@viagenie.qc.ca +# RFC3455 || M. Garcia-Martin, E. Henrikson, D. Mills || miguel.a.garcia@ericsson.com, ehenrikson@lucent.com, duncan.mills@vf.vodafone.co.uk +# RFC3456 || B. Patel, B. Aboba, S. Kelly, V. Gupta || baiju.v.patel@intel.com, bernarda@microsoft.com, scott@hyperthought.com, vipul.gupta@sun.com +# RFC3457 || S. Kelly, S. Ramamoorthi || +# RFC3458 || E. Burger, E. Candell, C. Eliot, G. Klyne || e.burger@ieee.org, emily.candell@comverse.com, GK-IETF@ninebynine.org, charle@Microsoft.com +# RFC3459 || E. Burger || e.burger@ieee.org +# RFC3460 || B. Moore, Ed. || remoore@us.ibm.com +# RFC3461 || K. Moore || moore@cs.utk.edu +# RFC3462 || G. Vaudreuil || GregV@ieee.org +# RFC3463 || G. Vaudreuil || GregV@ieee.org +# RFC3464 || K. Moore, G. Vaudreuil || moore@cs.utk.edu, GregV@ieee.org +# RFC3465 || M. Allman || mallman@bbn.com +# RFC3466 || M. Day, B. Cain, G. Tomlinson, P. Rzewski || mday@alum.mit.edu, bcain@storigen.com, gary@tomlinsongroup.net, philrz@yahoo.com +# RFC3467 || J. Klensin || +# RFC3468 || L. Andersson, G. Swallow || loa@pi.se, swallow@cisco.com +# RFC3469 || V. Sharma, Ed., F. Hellstrand, Ed. || +# RFC3470 || S. Hollenbeck, M. Rose, L. Masinter || shollenbeck@verisign.com, mrose17@gmail.com, LMM@acm.org +# RFC3471 || L. Berger, Ed. || lberger@movaz.com +# RFC3472 || P. Ashwood-Smith, Ed., L. Berger, Ed. || petera@nortelnetworks.com, lberger@movaz.com +# RFC3473 || L. Berger, Ed. || lberger@movaz.com +# RFC3474 || Z. Lin, D. Pendarakis || zhiwlin@nyct.com, dpendarakis@tellium.com +# RFC3475 || O. Aboul-Magd || osama@nortelnetworks.com +# RFC3476 || B. Rajagopalan || braja@tellium.com +# RFC3477 || K. Kompella, Y. Rekhter || kireeti@juniper.net, yakov@juniper.net +# RFC3478 || M. Leelanivas, Y. Rekhter, R. Aggarwal || manoj@juniper.net, yakov@juniper.net, rahul@redback.com +# RFC3479 || A. Farrel, Ed. || afarrel@movaz.com, pjb@dataconnection.com, pmatthews@hyperchip.com, ewgray@GraIyMage.com, jack.shaio@vivacenetworks.com, tob@laurelnetworks.com, andy.malis@vivacenetworks.com +# RFC3480 || K. Kompella, Y. Rekhter, A. Kullberg || kireeti@juniper.net, yakov@juniper.net, akullber@netplane.com +# RFC3481 || H. Inamura, Ed., G. Montenegro, Ed., R. Ludwig, A. Gurtov, F. Khafizov || inamura@mml.yrp.nttdocomo.co.jp, gab@sun.com, Reiner.Ludwig@Ericsson.com, andrei.gurtov@sonera.com, faridk@nortelnetworks.com +# RFC3482 || M. Foster, T. McGarry, J. Yu || mark.foster@neustar.biz, tom.mcgarry@neustar.biz, james.yu@neustar.biz +# RFC3483 || D. Rawlins, A. Kulkarni, M. Bokaemper, K. Chan || Diana.Rawlins@wcom.com, amol.kulkarni@intel.com, khchan@nortelnetworks.com, mbokaemper@juniper.net +# RFC3484 || R. Draves || richdr@microsoft.com +# RFC3485 || M. Garcia-Martin, C. Bormann, J. Ott, R. Price, A. B. Roach || miguel.a.garcia@ericsson.com, cabo@tzi.org, jo@tzi.org, richard.price@roke.co.uk, adam@dynamicsoft.com +# RFC3486 || G. Camarillo || Gonzalo.Camarillo@ericsson.com +# RFC3487 || H. Schulzrinne || schulzrinne@cs.columbia.edu +# RFC3488 || I. Wu, T. Eckert || iwu@cisco.com +# RFC3489 || J. Rosenberg, J. Weinberger, C. Huitema, R. Mahy || jdrosen@dynamicsoft.com, jweinberger@dynamicsoft.com, huitema@microsoft.com, rohan@cisco.com +# RFC3490 || P. Faltstrom, P. Hoffman, A. Costello || paf@cisco.com, phoffman@imc.org +# RFC3491 || P. Hoffman, M. Blanchet || paul.hoffman@imc.org, Marc.Blanchet@viagenie.qc.ca +# RFC3492 || A. Costello || +# RFC3493 || R. Gilligan, S. Thomson, J. Bound, J. McCann, W. Stevens || gilligan@intransa.com, sethomso@cisco.com, Jim.Bound@hp.com, Jack.McCann@hp.com +# RFC3494 || K. Zeilenga || Kurt@OpenLDAP.org +# RFC3495 || B. Beser, P. Duffy, Ed. || burcak@juniper.net, paduffy@cisco.com +# RFC3496 || A. G. Malis, T. Hsiao || Andy.Malis@vivacenetworks.com, Tony.Hsiao@VivaceNetworks.com +# RFC3497 || L. Gharai, C. Perkins, G. Goncher, A. Mankin || ladan@isi.edu, csp@csperkins.org, mankin@psg.com, Gary.Goncher@tek.com +# RFC3498 || J. Kuhfeld, J. Johnson, M. Thatcher || +# RFC3499 || S. Ginoza || ginoza@isi.edu +# RFC3500 || || +# RFC3501 || M. Crispin || MRC@CAC.Washington.EDU +# RFC3502 || M. Crispin || MRC@CAC.Washington.EDU +# RFC3503 || A. Melnikov || mel@messagingdirect.com +# RFC3504 || D. Eastlake || Donald.Eastlake@motorola.com +# RFC3505 || D. Eastlake || Donald.Eastlake@motorola.com +# RFC3506 || K. Fujimura, D. Eastlake || fujimura@isl.ntt.co.jp, Donald.Eastlake@motorola.com +# RFC3507 || J. Elson, A. Cerpa || jelson@cs.ucla.edu, cerpa@cs.ucla.edu +# RFC3508 || O. Levin || orit@radvision.com +# RFC3509 || A. Zinin, A. Lindem, D. Yeung || zinin@psg.com, myeung@procket.com, acee@redback.com +# RFC3510 || R. Herriot, I. McDonald || bob@herriot.com, imcdonald@sharplabs.com +# RFC3511 || B. Hickman, D. Newman, S. Tadjudin, T. Martin || brooks.hickman@spirentcom.com, dnewman@networktest.com, Saldju.Tadjudin@spirentcom.com, tmartin@gvnw.com +# RFC3512 || M. MacFaden, D. Partain, J. Saperia, W. Tackabury || +# RFC3513 || R. Hinden, S. Deering || bob.hinden@gmail.com, deering@cisco.com +# RFC3514 || S. Bellovin || bellovin@acm.org +# RFC3515 || R. Sparks || rsparks@dynamicsoft.com +# RFC3516 || L. Nerenberg || lyndon@orthanc.ab.ca +# RFC3517 || E. Blanton, M. Allman, K. Fall, L. Wang || eblanton@cs.purdue.edu, mallman@bbn.com, kfall@intel-research.net, lwang0@uky.edu +# RFC3518 || M. Higashiyama, F. Baker, T. Liao || Mitsuru.Higashiyama@yy.anritsu.co.jp, fred@cisco.com, tawei@cisco.com +# RFC3519 || H. Levkowetz, S. Vaarala || henrik@levkowetz.com, sami.vaarala@iki.fi +# RFC3520 || L-N. Hamer, B. Gage, B. Kosinski, H. Shieh || nhamer@nortelnetworks.com, brettk@invidi.com, gageb@nortelnetworks.com, hugh.shieh@attws.com +# RFC3521 || L-N. Hamer, B. Gage, H. Shieh || nhamer@nortelnetworks.com, gageb@nortelnetworks.com, hugh.shieh@attws.com +# RFC3522 || R. Ludwig, M. Meyer || Reiner.Ludwig@eed.ericsson.se, Michael.Meyer@eed.ericsson.se +# RFC3523 || J. Polk || jmpolk@cisco.com +# RFC3524 || G. Camarillo, A. Monrad || Gonzalo.Camarillo@ericsson.com, atle.monrad@ericsson.com +# RFC3525 || C. Groves, Ed., M. Pantaleo, Ed., T. Anderson, Ed., T. Taylor, Ed. || tlatla@verizon.net, Christian.Groves@ericsson.com.au, Marcello.Pantaleo@eed.ericsson.se, tom.taylor.stds@gmail.com +# RFC3526 || T. Kivinen, M. Kojo || kivinen@ssh.fi, mika.kojo@helsinki.fi +# RFC3527 || K. Kinnear, M. Stapp, R. Johnson, J. Kumarasamy || kkinnear@cisco.com, mjs@cisco.com, jayk@cisco.com, raj@cisco.com +# RFC3528 || W. Zhao, H. Schulzrinne, E. Guttman || zwb@cs.columbia.edu, hgs@cs.columbia.edu, Erik.Guttman@sun.com +# RFC3529 || W. Harold || wharold@us.ibm.com +# RFC3530 || S. Shepler, B. Callaghan, D. Robinson, R. Thurlow, C. Beame, M. Eisler, D. Noveck || beame@bws.com, brent.callaghan@sun.com, mike@eisler.com, dnoveck@netapp.com, david.robinson@sun.com, robert.thurlow@sun.com +# RFC3531 || M. Blanchet || Marc.Blanchet@viagenie.qc.ca +# RFC3532 || T. Anderson, J. Buerkle || todd.a.anderson@intel.com, joachim.buerkle@nortelnetworks.com +# RFC3533 || S. Pfeiffer || Silvia.Pfeiffer@csiro.au +# RFC3534 || L. Walleij || triad@df.lth.se +# RFC3535 || J. Schoenwaelder || j.schoenwaelder@iu-bremen.de +# RFC3536 || P. Hoffman || paul.hoffman@imc.org +# RFC3537 || J. Schaad, R. Housley || jimsch@exmsft.com, housley@vigilsec.com +# RFC3538 || Y. Kawatsura || kawatura@bisd.hitachi.co.jp +# RFC3539 || B. Aboba, J. Wood || bernarda@microsoft.com, jonwood@speakeasy.net +# RFC3540 || N. Spring, D. Wetherall, D. Ely || nspring@cs.washington.edu, djw@cs.washington.edu, ely@cs.washington.edu +# RFC3541 || A. Walsh || aaron@mantiscorp.com +# RFC3542 || W. Stevens, M. Thomas, E. Nordmark, T. Jinmei || matt@3am-software.com, Erik.Nordmark@sun.com, jinmei@isl.rdc.toshiba.co.jp +# RFC3543 || S. Glass, M. Chandra || steven.glass@sun.com, mchandra@cisco.com +# RFC3544 || T. Koren, S. Casner, C. Bormann || tmima@cisco.com, casner@packetdesign.com, cabo@tzi.org +# RFC3545 || T. Koren, S. Casner, J. Geevarghese, B. Thompson, P. Ruddy || tmima@cisco.com, casner@acm.org, geevjohn@hotmail.com, brucet@cisco.com, pruddy@cisco.com +# RFC3546 || S. Blake-Wilson, M. Nystrom, D. Hopwood, J. Mikkelsen, T. Wright || sblakewilson@bcisse.com, magnus@rsasecurity.com, david.hopwood@zetnet.co.uk, janm@transactionware.com, timothy.wright@vodafone.com +# RFC3547 || M. Baugher, B. Weis, T. Hardjono, H. Harney || mbaugher@cisco.com, thardjono@verisign.com, hh@sparta.com, bew@cisco.com +# RFC3548 || S. Josefsson, Ed. || +# RFC3549 || J. Salim, H. Khosravi, A. Kleen, A. Kuznetsov || hadi@znyx.com, hormuzd.m.khosravi@intel.com, ak@suse.de, kuznet@ms2.inr.ac.ru +# RFC3550 || H. Schulzrinne, S. Casner, R. Frederick, V. Jacobson || schulzrinne@cs.columbia.edu, casner@acm.org, ronf@bluecoat.com, van@packetdesign.com +# RFC3551 || H. Schulzrinne, S. Casner || schulzrinne@cs.columbia.edu, casner@acm.org +# RFC3552 || E. Rescorla, B. Korver || ekr@rtfm.com, briank@xythos.com, iab@iab.org +# RFC3553 || M. Mealling, L. Masinter, T. Hardie, G. Klyne || michael@verisignlabs.com, LMM@acm.org, hardie@qualcomm.com, GK-IETF@ninebynine.org +# RFC3554 || S. Bellovin, J. Ioannidis, A. Keromytis, R. Stewart || smb@research.att.com, ji@research.att.com, angelos@cs.columbia.edu, randall@lakerest.net +# RFC3555 || S. Casner, P. Hoschka || casner@acm.org, ph@w3.org +# RFC3556 || S. Casner || casner@acm.org +# RFC3557 || Q. Xie, Ed. || bdp003@motorola.com, Senaka.Balasuriya@motorola.com, yoonie@verbaltek.com, stephane.maes@oracle.com, hgarudad@qualcomm.com, Qiaobing.Xie@motorola.com +# RFC3558 || A. Li || adamli@icsl.ucla.edu +# RFC3559 || D. Thaler || dthaler@microsoft.com +# RFC3560 || R. Housley || housley@vigilsec.com +# RFC3561 || C. Perkins, E. Belding-Royer, S. Das || Charles.Perkins@nokia.com, ebelding@cs.ucsb.edu, sdas@ececs.uc.edu +# RFC3562 || M. Leech || mleech@nortelnetworks.com +# RFC3563 || A. Zinin || zinin@psg.com +# RFC3564 || F. Le Faucheur, W. Lai || +# RFC3565 || J. Schaad || jimsch@exmsft.com +# RFC3566 || S. Frankel, H. Herbert || sheila.frankel@nist.gov, howard.c.herbert@intel.com +# RFC3567 || T. Li, R. Atkinson || tli@procket.net, rja@extremenetworks.com +# RFC3568 || A. Barbir, B. Cain, R. Nair, O. Spatscheck || abbieb@nortelnetworks.com, bcain@storigen.com, nair_raj@yahoo.com, spatsch@research.att.com +# RFC3569 || S. Bhattacharyya, Ed. || +# RFC3570 || P. Rzewski, M. Day, D. Gilletti || mday@alum.mit.edu, dgilletti@yahoo.com, philrz@yahoo.com +# RFC3571 || D. Rawlins, A. Kulkarni, K. Ho Chan, M. Bokaemper, D. Dutt || Diana.Rawlins@mci.com, amol.kulkarni@intel.com, khchan@nortelnetworks.com, mbokaemper@juniper.net, ddutt@cisco.com +# RFC3572 || T. Ogura, M. Maruyama, T. Yoshida || ogura@core.ecl.net, mitsuru@core.ecl.net, yoshida@peta.arch.ecl.net +# RFC3573 || I. Goyret || igoyret@lucent.com +# RFC3574 || J. Soininen, Ed. || +# RFC3575 || B. Aboba || bernarda@microsoft.com +# RFC3576 || M. Chiba, G. Dommety, M. Eklund, D. Mitton, B. Aboba || mchiba@cisco.com, gdommety@cisco.com, meklund@cisco.com, david@mitton.com, bernarda@microsoft.com +# RFC3577 || S. Waldbusser, R. Cole, C. Kalbfleisch, D. Romascanu || waldbusser@nextbeacon.com, cwk@verio.net, rgcole@att.com, dromasca@gmail.com +# RFC3578 || G. Camarillo, A. B. Roach, J. Peterson, L. Ong || Gonzalo.Camarillo@ericsson.com, adam@dynamicsoft.com, jon.peterson@neustar.biz, lyong@ciena.com +# RFC3579 || B. Aboba, P. Calhoun || bernarda@microsoft.com, pcalhoun@airespace.com +# RFC3580 || P. Congdon, B. Aboba, A. Smith, G. Zorn, J. Roese || paul_congdon@hp.com, bernarda@microsoft.com, ah_smith@acm.org, jjr@enterasys.com, gwz@cisco.com +# RFC3581 || J. Rosenberg, H. Schulzrinne || jdrosen@dynamicsoft.com, schulzrinne@cs.columbia.edu +# RFC3582 || J. Abley, B. Black, V. Gill || jabley@isc.org, ben@layer8.net, vijaygill9@aol.com +# RFC3583 || H. Chaskar, Ed. || john.loughney@nokia.com, hemant.chaskar@nokia.com +# RFC3584 || R. Frye, D. Levi, S. Routhier, B. Wijnen || +# RFC3585 || J. Jason, L. Rafalow, E. Vyncke || jamie.jason@intel.com, rafalow@watson.ibm.com, evyncke@cisco.com +# RFC3586 || M. Blaze, A. Keromytis, M. Richardson, L. Sanchez || mab@crypto.com, angelos@cs.columbia.edu, mcr@sandelman.ottawa.on.ca, lsanchez@xapiens.com +# RFC3587 || R. Hinden, S. Deering, E. Nordmark || bob.hinden@gmail.com, erik.nordmark@sun.com +# RFC3588 || P. Calhoun, J. Loughney, E. Guttman, G. Zorn, J. Arkko || pcalhoun@airespace.com, john.Loughney@nokia.com, Jari.Arkko@ericsson.com, erik.guttman@sun.com +# RFC3589 || J. Loughney || john.Loughney@Nokia.com +# RFC3590 || B. Haberman || brian@innovationslab.net +# RFC3591 || H-K. Lam, M. Stewart, A. Huynh || mstewart1@nc.rr.com, a_n_huynh@yahoo.com, hklam@lucent.com +# RFC3592 || K. Tesink || kaj@research.telcordia.com +# RFC3593 || K. Tesink, Ed. || +# RFC3594 || P. Duffy || paduffy@cisco.com +# RFC3595 || B. Wijnen || bwijnen@lucent.com +# RFC3596 || S. Thomson, C. Huitema, V. Ksinant, M. Souissi || sethomso@cisco.com, huitema@microsoft.com, vladimir.ksinant@6wind.com, Mohsen.Souissi@nic.fr +# RFC3597 || A. Gustafsson || gson@nominum.com +# RFC3598 || K. Murchison || ken@oceana.com +# RFC3599 || S. Ginoza || ginoza@isi.edu +# RFC3600 || J. Reynolds, Ed., S. Ginoza, Ed. || +# RFC3601 || C. Allocchio || Claudio.Allocchio@garr.it +# RFC3602 || S. Frankel, R. Glenn, S. Kelly || sheila.frankel@nist.gov, scott@hyperthought.com, rob.glenn@nist.gov +# RFC3603 || W. Marshall, Ed., F. Andreasen, Ed. || +# RFC3604 || H. Khosravi, G. Kullgren, S. Shew, J. Sadler, A. Watanabe || hormuzd.m.khosravi@intel.com, geku@nortelnetworks.com, Jonathan.Sadler@tellabs.com, sdshew@nortelnetworks.com, Shiomoto.Kohei@lab.ntt.co.jp, atsushi@exa.onlab.ntt.co.jp, okamoto@exa.onlab.ntt.co.jp +# RFC3605 || C. Huitema || huitema@microsoft.com +# RFC3606 || F. Ly, M. Noto, A. Smith, E. Spiegel, K. Tesink || faye@pedestalnetworks.com, mnoto@cisco.com, ah_smith@acm.org, mspiegel@cisco.com, kaj@research.telcordia.com +# RFC3607 || M. Leech || mleech@nortelnetworks.com +# RFC3608 || D. Willis, B. Hoeneisen || dean.willis@softarmor.com, hoeneisen@switch.ch +# RFC3609 || R. Bonica, K. Kompella, D. Meyer || ronald.p.bonica@mci.com, kireeti@juniper.net, dmm@maoz.com +# RFC3610 || D. Whiting, R. Housley, N. Ferguson || dwhiting@hifn.com, housley@vigilsec.com, niels@macfergus.com +# RFC3611 || T. Friedman, Ed., R. Caceres, Ed., A. Clark, Ed. || almeroth@cs.ucsb.edu, caceres@watson.ibm.com, alan@telchemy.com, robert.cole@jhuapl.edu, duffield@research.att.com, timur.friedman@lip6.fr, khedayat@brixnet.com, ksarac@utdallas.edu, magnus.westerlund@ericsson.com +# RFC3612 || A. Farrel || adrian@olddog.co.uk +# RFC3613 || R. Morgan, K. Hazelton || rlmorgan@washington.edu, hazelton@doit.wisc.edu +# RFC3614 || J. Smith || jrsmith@watson.ibm.com +# RFC3615 || J. Gustin, A. Goyens || jean-marc.gustin@swift.com, andre.goyens@swift.com +# RFC3616 || F. Bellifemine, I. Constantinescu, S. Willmott || Fabio.Bellifemine@TILAB.COM, ion.constantinescu@epfl.ch, steve@lsi.upc.es +# RFC3617 || E. Lear || lear@cisco.com +# RFC3618 || B. Fenner, Ed., D. Meyer, Ed. || +# RFC3619 || S. Shah, M. Yip || sshah@extremenetworks.com, my@extremenetworks.com +# RFC3620 || D. New || dnew@san.rr.com +# RFC3621 || A. Berger, D. Romascanu || avib@PowerDsine.com, dromasca@gmail.com +# RFC3622 || M. Mealling || michael@neonym.net +# RFC3623 || J. Moy, P. Pillay-Esnault, A. Lindem || jmoy@sycamorenet.com, padma@juniper.net, acee@redback.com +# RFC3624 || B. Foster, D. Auerbach, F. Andreasen || fandreas@cisco.com, dea@cisco.com, bfoster@cisco.com +# RFC3625 || R. Gellens, H. Garudadri || +# RFC3626 || T. Clausen, Ed., P. Jacquet, Ed. || T.Clausen@computer.org, Philippe.Jacquet@inria.fr +# RFC3627 || P. Savola || psavola@funet.fi +# RFC3628 || D. Pinkas, N. Pope, J. Ross || Denis.Pinkas@bull.net, pope@secstan.com, ross@secstan.com, claire.desclercs@etsi.org +# RFC3629 || F. Yergeau || fyergeau@alis.com +# RFC3630 || D. Katz, K. Kompella, D. Yeung || dkatz@juniper.net, myeung@procket.com, kireeti@juniper.net +# RFC3631 || S. Bellovin, Ed., J. Schiller, Ed., C. Kaufman, Ed. || +# RFC3632 || S. Hollenbeck, S. Veeramachaneni, S. Yalamanchilli || shollenbeck@verisign.com, sveerama@verisign.com, syalamanchilli@verisign.com +# RFC3633 || O. Troan, R. Droms || ot@cisco.com, rdroms@cisco.com +# RFC3634 || K. Luehrs, R. Woundy, J. Bevilacqua, N. Davoust || k.luehrs@cablelabs.com, richard_woundy@cable.comcast.com, john@yas.com, nancy@yas.com +# RFC3635 || J. Flick || johnf@rose.hp.com +# RFC3636 || J. Flick || johnf@rose.hp.com +# RFC3637 || C.M. Heard, Ed. || +# RFC3638 || J. Flick, C. M. Heard || johnf@rose.hp.com, heard@pobox.com +# RFC3639 || M. St. Johns, Ed., G. Huston, Ed., IAB || +# RFC3640 || J. van der Meer, D. Mackie, V. Swaminathan, D. Singer, P. Gentric || jan.vandermeer@philips.com, dmackie@apple.com, viswanathan.swaminathan@sun.com, singer@apple.com, philippe.gentric@philips.com +# RFC3641 || S. Legg || steven.legg@adacel.com.au +# RFC3642 || S. Legg || steven.legg@adacel.com.au +# RFC3643 || R. Weber, M. Rajagopal, F. Travostino, M. O'Donnell, C. Monia, M. Merhar || roweber@ieee.org, muralir@broadcom.com, travos@nortelnetworks.com, cmonia@pacbell.net, milan.merhar@sun.com +# RFC3644 || Y. Snir, Y. Ramberg, J. Strassner, R. Cohen, B. Moore || yramberg@cisco.com, ysnir@cisco.com, john.strassner@intelliden.com, ronc@lyciumnetworks.com, remoore@us.ibm.com +# RFC3645 || S. Kwan, P. Garg, J. Gilroy, L. Esibov, J. Westhead, R. Hall || skwan@microsoft.com, praeritg@microsoft.com, jamesg@microsoft.com, levone@microsoft.com, randyhall@lucent.com, jwesth@microsoft.com +# RFC3646 || R. Droms, Ed. || rdroms@cisco.com +# RFC3647 || S. Chokhani, W. Ford, R. Sabett, C. Merrill, S. Wu || chokhani@orionsec.com, wford@verisign.com, rsabett@cooley.com, cmerrill@mccarter.com, swu@infoliance.com +# RFC3648 || J. Whitehead, J. Reschke, Ed. || ejw@cse.ucsc.edu, julian.reschke@greenbytes.de +# RFC3649 || S. Floyd || floyd@acm.org +# RFC3650 || S. Sun, L. Lannom, B. Boesch || ssun@cnri.reston.va.us, llannom@cnri.reston.va.us, bboesch@cnri.reston.va.us +# RFC3651 || S. Sun, S. Reilly, L. Lannom || ssun@cnri.reston.va.us, sreilly@cnri.reston.va.us, llannom@cnri.reston.va.us +# RFC3652 || S. Sun, S. Reilly, L. Lannom, J. Petrone || ssun@cnri.reston.va.us, sreilly@cnri.reston.va.us, llannom@cnri.reston.va.us, jpetrone@cnri.reston.va.us +# RFC3653 || J. Boyer, M. Hughes, J. Reagle || jboyer@PureEdge.com, Merlin.Hughes@betrusted.com, reagle@mit.edu +# RFC3654 || H. Khosravi, Ed., T. Anderson, Ed. || edbowen@us.ibm.com, rdantu@unt.edu, avri@acm.org, ram.gopal@nokia.com, hadi@znyx.com, muneyb@avaya.com, margaret.wasserman@nokia.com, hormuzd.m.khosravi@intel.com, todd.a.anderson@intel.com +# RFC3655 || B. Wellington, O. Gudmundsson || Brian.Wellington@nominum.com, ogud@ogud.com +# RFC3656 || R. Siemborski || +# RFC3657 || S. Moriai, A. Kato || camellia@isl.ntt.co.jp, akato@po.ntts.co.jp +# RFC3658 || O. Gudmundsson || ds-rfc@ogud.com +# RFC3659 || P. Hethmon || phethmon@hethmon.com +# RFC3660 || B. Foster, F. Andreasen || bfoster@cisco.com, fandreas@cisco.com +# RFC3661 || B. Foster, C. Sivachelvan || chelliah@cisco.com, bfoster@cisco.com +# RFC3662 || R. Bless, K. Nichols, K. Wehrle || bless@tm.uka.de, knichols@ieee.org, Klaus.Wehrle@uni-tuebingen.de +# RFC3663 || A. Newton || anewton@verisignlabs.com +# RFC3664 || P. Hoffman || paul.hoffman@vpnc.org +# RFC3665 || A. Johnston, S. Donovan, R. Sparks, C. Cunningham, K. Summers || alan.johnston@mci.com, sdonovan@dynamicsoft.com, rsparks@dynamicsoft.com, ccunningham@dynamicsoft.com, kevin.summers@sonusnet.com +# RFC3666 || A. Johnston, S. Donovan, R. Sparks, C. Cunningham, K. Summers || alan.johnston@mci.com, sdonovan@dynamicsoft.com, rsparks@dynamicsoft.com, ccunningham@dynamicsoft.com, kevin.summers@sonusnet.com +# RFC3667 || S. Bradner || +# RFC3668 || S. Bradner || +# RFC3669 || S. Brim || sbrim@cisco.com +# RFC3670 || B. Moore, D. Durham, J. Strassner, A. Westerinen, W. Weiss || remoore@us.ibm.com, david.durham@intel.com, john.strassner@intelliden.com, andreaw@cisco.com, walterweiss@attbi.com +# RFC3671 || K. Zeilenga || Kurt@OpenLDAP.org +# RFC3672 || K. Zeilenga || Kurt@OpenLDAP.org, steven.legg@adacel.com.au +# RFC3673 || K. Zeilenga || Kurt@OpenLDAP.org +# RFC3674 || K. Zeilenga || Kurt@OpenLDAP.org +# RFC3675 || D. Eastlake 3rd || dee3@torque.pothole.com +# RFC3676 || R. Gellens || randy@qualcomm.com +# RFC3677 || L. Daigle, Ed., Internet Architecture Board || iab@iab.org +# RFC3678 || D. Thaler, B. Fenner, B. Quinn || dthaler@microsoft.com, fenner@research.att.com, rcq@ipmulticast.com +# RFC3679 || R. Droms || rdroms@cisco.com +# RFC3680 || J. Rosenberg || jdrosen@dynamicsoft.com +# RFC3681 || R. Bush, R. Fink || randy@psg.com, bob@thefinks.com +# RFC3682 || V. Gill, J. Heasley, D. Meyer || vijay@umbc.edu, heas@shrubbery.net, dmm@1-4-5.net +# RFC3683 || M. Rose || mrose17@gmail.com +# RFC3684 || R. Ogier, F. Templin, M. Lewis || ogier@erg.sri.com, ftemplin@iprg.nokia.com, lewis@erg.sri.com +# RFC3685 || C. Daboo || daboo@cyrusoft.com +# RFC3686 || R. Housley || housley@vigilsec.com +# RFC3687 || S. Legg || steven.legg@adacel.com.au +# RFC3688 || M. Mealling || michael@verisignlabs.com +# RFC3689 || K. Carlberg, R. Atkinson || k.carlberg@cs.ucl.ac.uk, rja@extremenetworks.com +# RFC3690 || K. Carlberg, R. Atkinson || k.carlberg@cs.ucl.ac.uk, rja@extremenetworks.com +# RFC3691 || A. Melnikov || Alexey.Melnikov@isode.com +# RFC3692 || T. Narten || narten@us.ibm.com +# RFC3693 || J. Cuellar, J. Morris, D. Mulligan, J. Peterson, J. Polk || Jorge.Cuellar@siemens.com, jmorris@cdt.org, dmulligan@law.berkeley.edu, jon.peterson@neustar.biz, jmpolk@cisco.com +# RFC3694 || M. Danley, D. Mulligan, J. Morris, J. Peterson || mre213@nyu.edu, dmulligan@law.berkeley.edu, jmorris@cdt.org, jon.peterson@neustar.biz +# RFC3695 || M. Luby, L. Vicisano || luby@digitalfountain.com, lorenzo@cisco.com +# RFC3696 || J. Klensin || john-ietf@jck.com +# RFC3697 || J. Rajahalme, A. Conta, B. Carpenter, S. Deering || jarno.rajahalme@nokia.com, aconta@txc.com, brc@zurich.ibm.com +# RFC3698 || K. Zeilenga, Ed. || Kurt@OpenLDAP.org +# RFC3700 || J. Reynolds, Ed., S. Ginoza, Ed. || +# RFC3701 || R. Fink, R. Hinden || bob@thefinks.com, bob.hinden@gmail.com +# RFC3702 || J. Loughney, G. Camarillo || John.Loughney@nokia.com, Gonzalo.Camarillo@ericsson.com +# RFC3703 || J. Strassner, B. Moore, R. Moats, E. Ellesson || john.strassner@intelliden.com, remoore@us.ibm.com, rmoats@lemurnetworks.net, ellesson@mindspring.com +# RFC3704 || F. Baker, P. Savola || fred@cisco.com, psavola@funet.fi +# RFC3705 || B. Ray, R. Abbi || rray@pesa.com, Rajesh.Abbi@alcatel.com +# RFC3706 || G. Huang, S. Beaulieu, D. Rochefort || +# RFC3707 || A. Newton || anewton@verisignlabs.com +# RFC3708 || E. Blanton, M. Allman || eblanton@cs.purdue.edu, mallman@icir.org +# RFC3709 || S. Santesson, R. Housley, T. Freeman || stefans@microsoft.com, housley@vigilsec.com, trevorf@microsoft.com +# RFC3710 || H. Alvestrand || harald@alvestrand.no +# RFC3711 || M. Baugher, D. McGrew, M. Naslund, E. Carrara, K. Norrman || mbaugher@cisco.com, elisabetta.carrara@ericsson.com, mcgrew@cisco.com, mats.naslund@ericsson.com, karl.norrman@ericsson.com +# RFC3712 || P. Fleming, I. McDonald || flemingp@us.ibm.com, flemingp@us.ibm.com, flemingp@us.ibm.com +# RFC3713 || M. Matsui, J. Nakajima, S. Moriai || matsui@iss.isl.melco.co.jp, june15@iss.isl.melco.co.jp, shiho@rd.scei.sony.co.jp +# RFC3714 || S. Floyd, Ed., J. Kempf, Ed. || iab@iab.org +# RFC3715 || B. Aboba, W. Dixon || bernarda@microsoft.com, ietf-wd@v6security.com +# RFC3716 || IAB Advisory Committee || iab@iab.org +# RFC3717 || B. Rajagopalan, J. Luciani, D. Awduche || braja@tellium.com, james_luciani@mindspring.com, awduche@awduche.com +# RFC3718 || R. McGowan || +# RFC3719 || J. Parker, Ed. || jparker@axiowave.com +# RFC3720 || J. Satran, K. Meth, C. Sapuntzakis, M. Chadalapaka, E. Zeidner || Julian_Satran@il.ibm.com, meth@il.ibm.com, csapuntz@alum.mit.edu, efri@xiv.co.il, cbm@rose.hp.com +# RFC3721 || M. Bakke, J. Hafner, J. Hufferd, K. Voruganti, M. Krueger || kaladhar@us.ibm.com, mbakke@cisco.com, hafner@almaden.ibm.com, hufferd@us.ibm.com, marjorie_krueger@hp.com +# RFC3722 || M. Bakke || mbakke@cisco.com +# RFC3723 || B. Aboba, J. Tseng, J. Walker, V. Rangan, F. Travostino || bernarda@microsoft.com, joshtseng@yahoo.com, jesse.walker@intel.com, vrangan@brocade.com, travos@nortelnetworks.com +# RFC3724 || J. Kempf, Ed., R. Austein, Ed., IAB || +# RFC3725 || J. Rosenberg, J. Peterson, H. Schulzrinne, G. Camarillo || jdrosen@dynamicsoft.com, jon.peterson@neustar.biz, schulzrinne@cs.columbia.edu, Gonzalo.Camarillo@ericsson.com +# RFC3726 || M. Brunner, Ed. || brunner@netlab.nec.de, robert.hancock@roke.co.uk, eleanor.hepworth@roke.co.uk, cornelia.kappler@siemens.com, Hannes.Tschofenig@mchp.siemens.de +# RFC3727 || S. Legg || steven.legg@adacel.com.au +# RFC3728 || B. Ray, R. Abbi || rray@pesa.com, Rajesh.Abbi@alcatel.com +# RFC3729 || S. Waldbusser || waldbusser@nextbeacon.com +# RFC3730 || S. Hollenbeck || shollenbeck@verisign.com +# RFC3731 || S. Hollenbeck || shollenbeck@verisign.com +# RFC3732 || S. Hollenbeck || shollenbeck@verisign.com +# RFC3733 || S. Hollenbeck || shollenbeck@verisign.com +# RFC3734 || S. Hollenbeck || shollenbeck@verisign.com +# RFC3735 || S. Hollenbeck || shollenbeck@verisign.com +# RFC3736 || R. Droms || rdroms@cisco.com +# RFC3737 || B. Wijnen, A. Bierman || bwijnen@lucent.com, andy@yumaworks.com +# RFC3738 || M. Luby, V. Goyal || luby@digitalfountain.com, v.goyal@ieee.org +# RFC3739 || S. Santesson, M. Nystrom, T. Polk || stefans@microsoft.com, wpolk@nist.gov, magnus@rsasecurity.com +# RFC3740 || T. Hardjono, B. Weis || thardjono@verisign.com, bew@cisco.com +# RFC3741 || J. Boyer, D. Eastlake 3rd, J. Reagle || jboyer@PureEdge.com, Donald.Eastlake@motorola.com, reagle@mit.edu +# RFC3742 || S. Floyd || floyd@icir.org +# RFC3743 || K. Konishi, K. Huang, H. Qian, Y. Ko || konishi@jp.apan.net, huangk@alum.sinica.edu, Hlqian@cnnic.net.cn, yw@mrko.pe.kr, jseng@pobox.org.sg, rickard@rickardgroup.com +# RFC3744 || G. Clemm, J. Reschke, E. Sedlar, J. Whitehead || geoffrey.clemm@us.ibm.com, julian.reschke@greenbytes.de, eric.sedlar@oracle.com, ejw@cse.ucsc.edu +# RFC3745 || D. Singer, R. Clark, D. Lee || singer@apple.com, richard@elysium.ltd.uk, dlee@yahoo-inc.com +# RFC3746 || L. Yang, R. Dantu, T. Anderson, R. Gopal || lily.l.yang@intel.com, rdantu@unt.edu, todd.a.anderson@intel.com, ram.gopal@nokia.com +# RFC3747 || H. Hazewinkel, Ed., D. Partain, Ed. || +# RFC3748 || B. Aboba, L. Blunk, J. Vollbrecht, J. Carlson, H. Levkowetz, Ed. || bernarda@microsoft.com, ljb@merit.edu, jrv@umich.edu, james.d.carlson@sun.com, henrik@levkowetz.com +# RFC3749 || S. Hollenbeck || shollenbeck@verisign.com +# RFC3750 || C. Huitema, R. Austein, S. Satapati, R. van der Pol || huitema@microsoft.com, sra@isc.org, satapati@cisco.com, Ronald.vanderPol@nlnetlabs.nl +# RFC3751 || S. Bradner || sob@harvard.edu +# RFC3752 || A. Barbir, E. Burger, R. Chen, S. McHenry, H. Orman, R. Penno || abbieb@nortelnetworks.com, e.burger@ieee.org, chen@research.att.com, stephen@mchenry.net, ho@alum.mit.edu, rpenno@nortelnetworks.com +# RFC3753 || J. Manner, Ed., M. Kojo, Ed. || jmanner@cs.helsinki.fi, kojo@cs.helsinki.fi +# RFC3754 || R. Bless, K. Wehrle || bless@tm.uka.de, Klaus.Wehrle@uni-tuebingen.de +# RFC3755 || S. Weiler || weiler@tislabs.com +# RFC3756 || P. Nikander, Ed., J. Kempf, E. Nordmark || pekka.nikander@nomadiclab.com, kempf@docomolabs-usa.com, erik.nordmark@sun.com +# RFC3757 || O. Kolkman, J. Schlyter, E. Lewis || olaf@ripe.net, jakob@nic.se, edlewis@arin.net +# RFC3758 || R. Stewart, M. Ramalho, Q. Xie, M. Tuexen, P. Conrad || randall@lakerest.net, mramalho@cisco.com, qxie1@email.mot.com, tuexen@fh-muenster.de, conrad@acm.org +# RFC3759 || L-E. Jonsson || lars-erik.jonsson@ericsson.com +# RFC3760 || D. Gustafson, M. Just, M. Nystrom || degustafson@comcast.net, Just.Mike@tbs-sct.gc.ca, magnus@rsasecurity.com +# RFC3761 || P. Faltstrom, M. Mealling || paf@cisco.com +# RFC3762 || O. Levin || oritl@microsoft.com +# RFC3763 || S. Shalunov, B. Teitelbaum || shalunov@internet2.edu, ben@internet2.edu +# RFC3764 || J. Peterson || jon.peterson@neustar.biz +# RFC3765 || G. Huston || gih@telstra.net +# RFC3766 || H. Orman, P. Hoffman || hilarie@purplestreak.com, paul.hoffman@vpnc.org +# RFC3767 || S. Farrell, Ed. || +# RFC3768 || R. Hinden, Ed. || bob.hinden@gmail.com +# RFC3769 || S. Miyakawa, R. Droms || miyakawa@nttv6.jp, rdroms@cisco.com +# RFC3770 || R. Housley, T. Moore || housley@vigilsec.com, timmoore@microsoft.com +# RFC3771 || R. Harrison, K. Zeilenga || roger_harrison@novell.com, Kurt@OpenLDAP.org +# RFC3772 || J. Carlson, R. Winslow || +# RFC3773 || E. Candell || emily.candell@comverse.com +# RFC3774 || E. Davies, Ed. || +# RFC3775 || D. Johnson, C. Perkins, J. Arkko || dbj@cs.rice.edu, charliep@iprg.nokia.com, jari.arkko@ericsson.com +# RFC3776 || J. Arkko, V. Devarapalli, F. Dupont || jari.arkko@ericsson.com, vijayd@iprg.nokia.com, Francis.Dupont@enst-bretagne.fr +# RFC3777 || J. Galvin, Ed. || galvin+ietf@elistx.com +# RFC3778 || E. Taft, J. Pravetz, S. Zilles, L. Masinter || taft@adobe.com, jpravetz@adobe.com, szilles@adobe.com, LMM@acm.org +# RFC3779 || C. Lynn, S. Kent, K. Seo || CLynn@BBN.Com, Kent@BBN.Com, KSeo@BBN.Com +# RFC3780 || F. Strauss, J. Schoenwaelder || strauss@ibr.cs.tu-bs.de, j.schoenwaelder@iu-bremen.de +# RFC3781 || F. Strauss, J. Schoenwaelder || strauss@ibr.cs.tu-bs.de, j.schoenwaelder@iu-bremen.de +# RFC3782 || S. Floyd, T. Henderson, A. Gurtov || floyd@acm.org, thomas.r.henderson@boeing.com, andrei.gurtov@teliasonera.com +# RFC3783 || M. Chadalapaka, R. Elliott || cbm@rose.hp.com, elliott@hp.com +# RFC3784 || H. Smit, T. Li || hhwsmit@xs4all.nl, tony.li@tony.li +# RFC3785 || F. Le Faucheur, R. Uppili, A. Vedrenne, P. Merckx, T. Telkamp || flefauch@cisco.com, alain.vedrenne@equant.com, pierre.merckx@equant.com, telkamp@gblx.net +# RFC3786 || A. Hermelin, S. Previdi, M. Shand || amir@montilio.com, sprevidi@cisco.com, mshand@cisco.com +# RFC3787 || J. Parker, Ed. || jparker@axiowave.com +# RFC3788 || J. Loughney, M. Tuexen, Ed., J. Pastor-Balbas || john.loughney@nokia.com, tuexen@fh-muenster.de, j.javier.pastor@ericsson.com +# RFC3789 || P. Nesser, II, A. Bergstrom, Ed. || phil@nesser.com, andreas.bergstrom@hiof.no +# RFC3790 || C. Mickles, Ed., P. Nesser, II || cmickles.ee88@gtalumni.org, phil@nesser.com +# RFC3791 || C. Olvera, P. Nesser, II || cesar.olvera@consulintel.es, phil@nesser.com +# RFC3792 || P. Nesser, II, A. Bergstrom, Ed. || phil@nesser.com, andreas.bergstrom@hiof.no +# RFC3793 || P. Nesser, II, A. Bergstrom, Ed. || phil@nesser.com, andreas.bergstrom@hiof.no +# RFC3794 || P. Nesser, II, A. Bergstrom, Ed. || phil@nesser.com, andreas.bergstrom@hiof.no +# RFC3795 || R. Sofia, P. Nesser, II || rsofia@zmail.pt, phil@nesser.com +# RFC3796 || P. Nesser, II, A. Bergstrom, Ed. || phil@nesser.com, andreas.bergstrom@hiof.no +# RFC3797 || D. Eastlake 3rd || Donald.Eastlake@motorola.com +# RFC3798 || T. Hansen, Ed., G. Vaudreuil, Ed. || GregV@ieee.org +# RFC3801 || G. Vaudreuil, G. Parsons || gregv@ieee.org, GParsons@NortelNetworks.com +# RFC3802 || G. Vaudreuil, G. Parsons || gregv@ieee.org, gparsons@nortelnetworks.com +# RFC3803 || G. Vaudreuil, G. Parsons || gregv@ieee.org, gparsons@nortelnetworks.com +# RFC3804 || G. Parsons || gparsons@nortelnetworks.com +# RFC3805 || R. Bergman, H. Lewis, I. McDonald || Ron.Bergman@hitachi-ps.us, harryl@us.ibm.com, imcdonald@sharplabs.com +# RFC3806 || R. Bergman, H. Lewis, I. McDonald || Ron.Bergman@hitachi-ps.us, harryl@us.ibm.com, imcdonald@sharplabs.com +# RFC3807 || E. Weilandt, N. Khanchandani, S. Rao || eva.weilandt@temic.com, rsanjay@nortelnetworks.com, neerajk@nortelnetworks.com +# RFC3808 || I. McDonald || imcdonald@sharplabs.com, iana@iana.org +# RFC3809 || A. Nagarajan, Ed. || +# RFC3810 || R. Vida, Ed., L. Costa, Ed. || Rolland.Vida@lip6.fr, Luis.Costa@lip6.fr, Serge.Fdida@lip6.fr, deering@cisco.com, fenner@research.att.com, kouvelas@cisco.com, brian@innovationslab.net +# RFC3811 || T. Nadeau, Ed., J. Cucchiara, Ed. || tnadeau@cisco.com, jcucchiara@mindspring.com +# RFC3812 || C. Srinivasan, A. Viswanathan, T. Nadeau || cheenu@bloomberg.net, arunv@force10networks.com, tnadeau@cisco.com +# RFC3813 || C. Srinivasan, A. Viswanathan, T. Nadeau || cheenu@bloomberg.net, arunv@force10networks.com, tnadeau@cisco.com +# RFC3814 || T. Nadeau, C. Srinivasan, A. Viswanathan || tnadeau@cisco.com, cheenu@bloomberg.net, arunv@force10networks.com +# RFC3815 || J. Cucchiara, H. Sjostrand, J. Luciani || james_luciani@mindspring.com, hans@ipunplugged.com, jcucchiara@mindspring.com +# RFC3816 || J. Quittek, M. Stiemerling, H. Hartenstein || quittek@netlab.nec.de, stiemerling@netlab.nec.de, hartenstein@rz.uni-karlsruhe.de +# RFC3817 || W. Townsley, R. da Silva || mark@townsley.net, rdasilva@va.rr.com +# RFC3818 || V. Schryver || vjs@rhyolite.com +# RFC3819 || P. Karn, Ed., C. Bormann, G. Fairhurst, D. Grossman, R. Ludwig, J. Mahdavi, G. Montenegro, J. Touch, L. Wood || karn@qualcomm.com, cabo@tzi.org, gorry@erg.abdn.ac.uk, Dan.Grossman@motorola.com, Reiner.Ludwig@ericsson.com, jmahdavi@earthlink.net, gab@sun.com, touch@isi.edu, lwood@cisco.com +# RFC3820 || S. Tuecke, V. Welch, D. Engert, L. Pearlman, M. Thompson || tuecke@mcs.anl.gov, vwelch@ncsa.uiuc.edu, deengert@anl.gov, laura@isi.edu, mrthompson@lbl.gov +# RFC3821 || M. Rajagopal, E. Rodriguez, R. Weber || +# RFC3822 || D. Peterson || dap@cnt.com +# RFC3823 || B. Kovitz || bkovitz@caltech.edu +# RFC3824 || J. Peterson, H. Liu, J. Yu, B. Campbell || jon.peterson@neustar.biz, hong.liu@neustar.biz, james.yu@neustar.biz, bcampbell@dynamicsoft.com +# RFC3825 || J. Polk, J. Schnizlein, M. Linsner || jmpolk@cisco.com, john.schnizlein@cisco.com, marc.linsner@cisco.com +# RFC3826 || U. Blumenthal, F. Maino, K. McCloghrie || uri@bell-labs.com, fmaino@andiamo.com, kzm@cisco.com +# RFC3827 || K. Sarcar || kanoj.sarcar@sun.com +# RFC3828 || L-A. Larzon, M. Degermark, S. Pink, L-E. Jonsson, Ed., G. Fairhurst, Ed. || lln@csee.ltu.se, micke@cs.arizona.edu, steve@cs.arizona.edu, lars-erik.jonsson@ericsson.com, gorry@erg.abdn.ac.uk +# RFC3829 || R. Weltman, M. Smith, M. Wahl || robw@worldspot.com, mcs@pearlcrescent.com +# RFC3830 || J. Arkko, E. Carrara, F. Lindholm, M. Naslund, K. Norrman || jari.arkko@ericsson.com, elisabetta.carrara@ericsson.com, fredrik.lindholm@ericsson.com, mats.naslund@ericsson.com, karl.norrman@ericsson.com +# RFC3831 || C. DeSanti || cds@cisco.com +# RFC3832 || W. Zhao, H. Schulzrinne, E. Guttman, C. Bisdikian, W. Jerome || zwb@cs.columbia.edu, hgs@cs.columbia.edu, Erik.Guttman@sun.com, bisdik@us.ibm.com, wfj@us.ibm.com +# RFC3833 || D. Atkins, R. Austein || derek@ihtfp.com, sra@isc.org +# RFC3834 || K. Moore || moore@cs.utk.edu +# RFC3835 || A. Barbir, R. Penno, R. Chen, M. Hofmann, H. Orman || abbieb@nortelnetworks.com, chen@research.att.com, hofmann@bell-labs.com, ho@alum.mit.edu, rpenno@nortelnetworks.com +# RFC3836 || A. Beck, M. Hofmann, H. Orman, R. Penno, A. Terzis || abeck@bell-labs.com, hofmann@bell-labs.com, ho@alum.mit.edu, rpenno@nortelnetworks.com, terzis@cs.jhu.edu +# RFC3837 || A. Barbir, O. Batuner, B. Srinivas, M. Hofmann, H. Orman || abbieb@nortelnetworks.com, batuner@attbi.com, bindignavile.srinivas@nokia.com, hofmann@bell-labs.com, ho@alum.mit.edu +# RFC3838 || A. Barbir, O. Batuner, A. Beck, T. Chan, H. Orman || abbieb@nortelnetworks.com, batuner@attbi.com, abeck@bell-labs.com, Tat.Chan@nokia.com, ho@alum.mit.edu +# RFC3839 || R. Castagno, D. Singer || +# RFC3840 || J. Rosenberg, H. Schulzrinne, P. Kyzivat || jdrosen@dynamicsoft.com, schulzrinne@cs.columbia.edu, pkyzivat@cisco.com +# RFC3841 || J. Rosenberg, H. Schulzrinne, P. Kyzivat || jdrosen@dynamicsoft.com, schulzrinne@cs.columbia.edu, pkyzivat@cisco.com +# RFC3842 || R. Mahy || rohan@cisco.com +# RFC3843 || L-E. Jonsson, G. Pelletier || lars-erik.jonsson@ericsson.com, ghyslain.pelletier@ericsson.com +# RFC3844 || E. Davies, Ed., J. Hofmann, Ed. || elwynd@nortelnetworks.com, jeanette@wz-berlin.de +# RFC3845 || J. Schlyter, Ed. || jakob@nic.se +# RFC3846 || F. Johansson, T. Johansson || fredrik@ipunplugged.com, tony.johansson@bytemobile.com +# RFC3847 || M. Shand, L. Ginsberg || mshand@cisco.com, ginsberg@cisco.com +# RFC3848 || C. Newman || chris.newman@sun.com +# RFC3849 || G. Huston, A. Lord, P. Smith || gih@apnic.net, anne@apnic.net, pfs@cisco.com +# RFC3850 || B. Ramsdell, Ed. || +# RFC3851 || B. Ramsdell, Ed. || +# RFC3852 || R. Housley || housley@vigilsec.com +# RFC3853 || J. Peterson || jon.peterson@neustar.biz +# RFC3854 || P. Hoffman, C. Bonatti, A. Eggen || +# RFC3855 || P. Hoffman, C. Bonatti || phoffman@imc.org, bonattic@ieca.com +# RFC3856 || J. Rosenberg || jdrosen@dynamicsoft.com +# RFC3857 || J. Rosenberg || jdrosen@dynamicsoft.com +# RFC3858 || J. Rosenberg || jdrosen@dynamicsoft.com +# RFC3859 || J. Peterson || jon.peterson@neustar.biz +# RFC3860 || J. Peterson || jon.peterson@neustar.biz +# RFC3861 || J. Peterson || jon.peterson@neustar.biz +# RFC3862 || G. Klyne, D. Atkins || GK-IETF@ninebynine.org, derek@ihtfp.com +# RFC3863 || H. Sugano, S. Fujimoto, G. Klyne, A. Bateman, W. Carr, J. Peterson || sugano.h@jp.fujitsu.com, shingo_fujimoto@jp.fujitsu.com, GK@ninebynine.org, bateman@acm.org, wayne.carr@intel.com, jon.peterson@neustar.biz +# RFC3864 || G. Klyne, M. Nottingham, J. Mogul || GK-IETF@ninebynine.org, mnot@pobox.com, JeffMogul@acm.org +# RFC3865 || C. Malamud || carl@media.org +# RFC3866 || K. Zeilenga, Ed. || +# RFC3867 || Y. Kawatsura, M. Hiroya, H. Beykirch || ykawatsu@itg.hitachi.co.jp, hiroya@st.rim.or.jp, hbbeykirch@web.de +# RFC3868 || J. Loughney, Ed., G. Sidebottom, L. Coene, G. Verwimp, J. Keller, B. Bidulock || john.Loughney@nokia.com, greg@signatustechnologies.com, lode.coene@siemens.com, gery.verwimp@siemens.com, joe.keller@tekelec.com, bidulock@openss7.org +# RFC3869 || R. Atkinson, Ed., S. Floyd, Ed., Internet Architecture Board || iab@iab.org, iab@iab.org, iab@iab.org +# RFC3870 || A. Swartz || me@aaronsw.com +# RFC3871 || G. Jones, Ed. || gmj3871@pobox.com +# RFC3872 || D. Zinman, D. Walker, J. Jiang || dzinman@rogers.com, david.walker@sedna-wireless.com, jjiang@syndesis.com +# RFC3873 || J. Pastor, M. Belinchon || J.Javier.Pastor@ericsson.com, maria.carmen.belinchon@ericsson.com +# RFC3874 || R. Housley || housley@vigilsec.com +# RFC3875 || D. Robinson, K. Coar || drtr@apache.org, coar@apache.org +# RFC3876 || D. Chadwick, S. Mullan || d.w.chadwick@salford.ac.uk, sean.mullan@sun.com +# RFC3877 || S. Chisholm, D. Romascanu || schishol@nortelnetworks.com, dromasca@gmail.com +# RFC3878 || H. Lam, A. Huynh, D. Perkins || hklam@lucent.com, a_n_huynh@yahoo.com, dperkins@snmpinfo.com +# RFC3879 || C. Huitema, B. Carpenter || huitema@microsoft.com, brc@zurich.ibm.com +# RFC3880 || J. Lennox, X. Wu, H. Schulzrinne || lennox@cs.columbia.edu, xiaotaow@cs.columbia.edu, schulzrinne@cs.columbia.edu +# RFC3881 || G. Marshall || glen.f.marshall@siemens.com +# RFC3882 || D. Turk || doughan.turk@bell.ca +# RFC3883 || S. Rao, A. Zinin, A. Roy || siraprao@hotmail.com, zinin@psg.com, akr@cisco.com +# RFC3884 || J. Touch, L. Eggert, Y. Wang || touch@isi.edu, lars.eggert@netlab.nec.de, yushunwa@isi.edu +# RFC3885 || E. Allman, T. Hansen || eric@Sendmail.COM, tony+msgtrk@maillennium.att.com +# RFC3886 || E. Allman || eric@Sendmail.COM +# RFC3887 || T. Hansen || tony+msgtrk@maillennium.att.com +# RFC3888 || T. Hansen || tony+msgtrk@maillennium.att.com +# RFC3889 || || +# RFC3890 || M. Westerlund || Magnus.Westerlund@ericsson.com +# RFC3891 || R. Mahy, B. Biggs, R. Dean || rohan@cisco.com, bbiggs@dumbterm.net, rfc@fdd.com +# RFC3892 || R. Sparks || RjS@xten.com +# RFC3893 || J. Peterson || jon.peterson@neustar.biz +# RFC3894 || J. Degener || jutta@sendmail.com +# RFC3895 || O. Nicklass, Ed. || orly_n@rad.com +# RFC3896 || O. Nicklass, Ed. || orly_n@rad.com +# RFC3897 || A. Barbir || abbieb@nortelnetworks.com +# RFC3898 || V. Kalusivalingam || vibhaska@cisco.com +# RFC3901 || A. Durand, J. Ihren || Alain.Durand@sun.com, johani@autonomica.se +# RFC3902 || M. Baker, M. Nottingham || distobj@acm.org, mnot@pobox.com +# RFC3903 || A. Niemi, Ed. || aki.niemi@nokia.com +# RFC3904 || C. Huitema, R. Austein, S. Satapati, R. van der Pol || huitema@microsoft.com, sra@isc.org, satapati@cisco.com, Ronald.vanderPol@nlnetlabs.nl +# RFC3905 || V. See, Ed. || vsee@microsoft.com +# RFC3906 || N. Shen, H. Smit || naiming@redback.com, hhwsmit@xs4all.nl +# RFC3909 || K. Zeilenga || Kurt@OpenLDAP.org +# RFC3910 || V. Gurbani, Ed., A. Brusilovsky, I. Faynberg, J. Gato, H. Lu, M. Unmehopa || vkg@lucent.com, abrusilovsky@lucent.com, faynberg@lucent.com, jorge.gato@vodafone.com, huilanlu@lucent.com, unmehopa@lucent.com +# RFC3911 || R. Mahy, D. Petrie || rohan@airespace.com, dpetrie@pingtel.com +# RFC3912 || L. Daigle || leslie@verisignlabs.com +# RFC3913 || D. Thaler || dthaler@microsoft.com +# RFC3914 || A. Barbir, A. Rousskov || abbieb@nortelnetworks.com, rousskov@measurement-factory.com +# RFC3915 || S. Hollenbeck || shollenbeck@verisign.com +# RFC3916 || X. Xiao, Ed., D. McPherson, Ed., P. Pate, Ed. || xxiao@riverstonenet.com, danny@arbor.net, prayson.pate@overturenetworks.com +# RFC3917 || J. Quittek, T. Zseby, B. Claise, S. Zander || quittek@netlab.nec.de, zseby@fokus.fhg.de, bclaise@cisco.com, szander@swin.edu.au +# RFC3918 || D. Stopp, B. Hickman || debby@ixiacom.com, brooks.hickman@spirentcom.com +# RFC3919 || E. Stephan, J. Palet || emile.stephan@francetelecom.com, jordi.palet@consulintel.es +# RFC3920 || P. Saint-Andre, Ed. || ietf@stpeter.im +# RFC3921 || P. Saint-Andre, Ed. || ietf@stpeter.im +# RFC3922 || P. Saint-Andre || ietf@stpeter.im +# RFC3923 || P. Saint-Andre || ietf@stpeter.im +# RFC3924 || F. Baker, B. Foster, C. Sharp || fred@cisco.com, bfoster@cisco.com, chsharp@cisco.com +# RFC3925 || J. Littlefield || joshl@cisco.com +# RFC3926 || T. Paila, M. Luby, R. Lehtonen, V. Roca, R. Walsh || toni.paila@nokia.com, luby@digitalfountain.com, rami.lehtonen@teliasonera.com, vincent.roca@inrialpes.fr, rod.walsh@nokia.com +# RFC3927 || S. Cheshire, B. Aboba, E. Guttman || rfc@stuartcheshire.org, bernarda@microsoft.com, erik@spybeam.org +# RFC3928 || R. Megginson, Ed., M. Smith, O. Natkovich, J. Parham || rmegginson0224@aol.com, olgan@yahoo-inc.com, mcs@pearlcrescent.com, jeffparh@microsoft.com +# RFC3929 || T. Hardie || hardie@qualcomm.com +# RFC3930 || D. Eastlake 3rd || Donald.Eastlake@motorola.com +# RFC3931 || J. Lau, Ed., M. Townsley, Ed., I. Goyret, Ed. || jedlau@cisco.com, mark@townsley.net, igoyret@lucent.com +# RFC3932 || H. Alvestrand || harald@alvestrand.no +# RFC3933 || J. Klensin, S. Dawkins || john-ietf@jck.com, spencer@mcsr-labs.org +# RFC3934 || M. Wasserman || margaret@thingmagic.com +# RFC3935 || H. Alvestrand || harald@alvestrand.no +# RFC3936 || K. Kompella, J. Lang || kireeti@juniper.net, jplang@ieee.org +# RFC3937 || M. Steidl || mdirector@iptc.org +# RFC3938 || T. Hansen || tony+msgctxt@maillennium.att.com +# RFC3939 || G. Parsons, J. Maruszak || gparsons@nortelnetworks.com, jjmaruszak@sympatico.ca +# RFC3940 || B. Adamson, C. Bormann, M. Handley, J. Macker || adamson@itd.nrl.navy.mil, cabo@tzi.org, M.Handley@cs.ucl.ac.uk, macker@itd.nrl.navy.mil +# RFC3941 || B. Adamson, C. Bormann, M. Handley, J. Macker || adamson@itd.nrl.navy.mil, cabo@tzi.org, M.Handley@cs.ucl.ac.uk, macker@itd.nrl.navy.mil +# RFC3942 || B. Volz || volz@cisco.com +# RFC3943 || R. Friend || rfriend@hifn.com +# RFC3944 || T. Johnson, S. Okubo, S. Campos || Tyler_Johnson@unc.edu, sokubo@waseda.jp, simao.campos@itu.int +# RFC3945 || E. Mannie, Ed. || eric_mannie@hotmail.com +# RFC3946 || E. Mannie, D. Papadimitriou || eric_mannie@hotmail.com, dimitri.papadimitriou@alcatel.be +# RFC3947 || T. Kivinen, B. Swander, A. Huttunen, V. Volpe || kivinen@safenet-inc.com, Ari.Huttunen@F-Secure.com, briansw@microsoft.com, vvolpe@cisco.com +# RFC3948 || A. Huttunen, B. Swander, V. Volpe, L. DiBurro, M. Stenberg || Ari.Huttunen@F-Secure.com, briansw@microsoft.com, vvolpe@cisco.com, ldiburro@nortelnetworks.com, markus.stenberg@iki.fi +# RFC3949 || R. Buckley, D. Venable, L. McIntyre, G. Parsons, J. Rafferty || rbuckley@crt.xerox.com, dvenable@crt.xerox.com, lloyd10328@pacbell.net, gparsons@nortel.com, jraff@brooktrout.com +# RFC3950 || L. McIntyre, G. Parsons, J. Rafferty || lloyd10328@pacbell.net, gparsons@nortel.com, jraff@brooktrout.com +# RFC3951 || S. Andersen, A. Duric, H. Astrom, R. Hagen, W. Kleijn, J. Linden || sva@kom.auc.dk, alan.duric@telio.no, henrik.astrom@globalipsound.com, roar.hagen@globalipsound.com, bastiaan.kleijn@globalipsound.com, jan.linden@globalipsound.com +# RFC3952 || A. Duric, S. Andersen || alan.duric@telio.no, sva@kom.auc.dk +# RFC3953 || J. Peterson || jon.peterson@neustar.biz +# RFC3954 || B. Claise, Ed. || bclaise@cisco.com +# RFC3955 || S. Leinen || simon@switch.ch +# RFC3956 || P. Savola, B. Haberman || psavola@funet.fi, brian@innovationslab.net +# RFC3957 || C. Perkins, P. Calhoun || charles.perkins@nokia.com, pcalhoun@airespace.com +# RFC3958 || L. Daigle, A. Newton || leslie@thinkingcat.com, anewton@verisignlabs.com +# RFC3959 || G. Camarillo || Gonzalo.Camarillo@ericsson.com +# RFC3960 || G. Camarillo, H. Schulzrinne || Gonzalo.Camarillo@ericsson.com, schulzrinne@cs.columbia.edu +# RFC3961 || K. Raeburn || raeburn@mit.edu +# RFC3962 || K. Raeburn || raeburn@mit.edu +# RFC3963 || V. Devarapalli, R. Wakikawa, A. Petrescu, P. Thubert || vijay.devarapalli@nokia.com, ryuji@sfc.wide.ad.jp, Alexandru.Petrescu@motorola.com, pthubert@cisco.com +# RFC3964 || P. Savola, C. Patel || psavola@funet.fi, chirayu@chirayu.org +# RFC3965 || K. Toyoda, H. Ohno, J. Murai, D. Wing || toyoda.kiyoshi@jp.panasonic.com, hohno@ohnolab.org, jun@wide.ad.jp, dwing-ietf@fuggles.com +# RFC3966 || H. Schulzrinne || hgs@cs.columbia.edu +# RFC3967 || R. Bush, T. Narten || randy@psg.com, narten@us.ibm.com +# RFC3968 || G. Camarillo || Gonzalo.Camarillo@ericsson.com +# RFC3969 || G. Camarillo || Gonzalo.Camarillo@ericsson.com +# RFC3970 || K. Kompella || kireeti@juniper.net +# RFC3971 || J. Arkko, Ed., J. Kempf, B. Zill, P. Nikander || jari.arkko@ericsson.com, kempf@docomolabs-usa.com, bzill@microsoft.com, Pekka.Nikander@nomadiclab.com +# RFC3972 || T. Aura || tuomaura@microsoft.com +# RFC3973 || A. Adams, J. Nicholas, W. Siadak || ala@nexthop.com, jonathan.nicholas@itt.com, wfs@nexthop.com +# RFC3974 || M. Nakamura, J. Hagino || motonori@media.kyoto-u.ac.jp, itojun@iijlab.net +# RFC3975 || G. Huston, Ed., I. Leuca, Ed. || execd@iab.org, ileana.leuca@Cingular.com +# RFC3976 || V. K. Gurbani, F. Haerens, V. Rastogi || vkg@lucent.com, frans.haerens@alcatel.be, vidhi.rastogi@wipro.com +# RFC3977 || C. Feather || clive@davros.org +# RFC3978 || S. Bradner, Ed. || sob@harvard.edu +# RFC3979 || S. Bradner, Ed. || sob@harvard.edu +# RFC3980 || M. Krueger, M. Chadalapaka, R. Elliott || marjorie_krueger@hp.com, cbm@rose.hp.com, elliott@hp.com +# RFC3981 || A. Newton, M. Sanz || anewton@verisignlabs.com, sanz@denic.de +# RFC3982 || A. Newton, M. Sanz || anewton@verisignlabs.com, sanz@denic.de +# RFC3983 || A. Newton, M. Sanz || anewton@verisignlabs.com, sanz@denic.de +# RFC3984 || S. Wenger, M.M. Hannuksela, T. Stockhammer, M. Westerlund, D. Singer || stewe@stewe.org, miska.hannuksela@nokia.com, stockhammer@nomor.de, magnus.westerlund@ericsson.com, singer@apple.com +# RFC3985 || S. Bryant, Ed., P. Pate, Ed. || stbryant@cisco.com, prayson.pate@overturenetworks.com +# RFC3986 || T. Berners-Lee, R. Fielding, L. Masinter || timbl@w3.org, fielding@gbiv.com, LMM@acm.org +# RFC3987 || M. Duerst, M. Suignard || duerst@w3.org, michelsu@microsoft.com +# RFC3988 || B. Black, K. Kompella || ben@layer8.net, kireeti@juniper.net +# RFC3989 || M. Stiemerling, J. Quittek, T. Taylor || stiemerling@netlab.nec.de, quittek@netlab.nec.de, tom.taylor.stds@gmail.com +# RFC3990 || B. O'Hara, P. Calhoun, J. Kempf || bob@airespace.com, pcalhoun@airespace.com, kempf@docomolabs-usa.com +# RFC3991 || B. Foster, F. Andreasen || bfoster@cisco.com, fandreas@cisco.com +# RFC3992 || B. Foster, F. Andreasen || bfoster@cisco.com, fandreas@cisco.com +# RFC3993 || R. Johnson, T. Palaniappan, M. Stapp || raj@cisco.com, athenmoz@cisco.com, mjs@cisco.com +# RFC3994 || H. Schulzrinne || hgs@cs.columbia.edu +# RFC3995 || R. Herriot, T. Hastings || bob@herriot.com, tom.hastings@alum.mit.edu +# RFC3996 || R. Herriot, T. Hastings, H. Lewis || bob@herriot.com, tom.hastings@alum.mit.edu, harryl@us.ibm.com +# RFC3997 || T. Hastings, Ed., R. K. deBry, H. Lewis || tom.hastings@alum.mit.edu, debryro@uvsc.edu, harryl@us.ibm.com +# RFC3998 || C. Kugler, H. Lewis, T. Hastings, Ed. || kugler@us.ibm.com, harryl@us.ibm.com, tom.hastings@alum.mit.edu +# RFC4001 || M. Daniele, B. Haberman, S. Routhier, J. Schoenwaelder || michael.daniele@syamsoftware.com, brian@innovationslab.net, shawn.routhier@windriver.com, j.schoenwaelder@iu-bremen.de +# RFC4002 || R. Brandner, L. Conroy, R. Stastny || rudolf.brandner@siemens.com, lwc@roke.co.uk, richard.stastny@oefeg.at +# RFC4003 || L. Berger || lberger@movaz.com +# RFC4004 || P. Calhoun, T. Johansson, C. Perkins, T. Hiller, Ed., P. McCann || pcalhoun@cisco.com, tony.johansson@bytemobile.com, Charles.Perkins@nokia.com, tomhiller@lucent.com, mccap@lucent.com +# RFC4005 || P. Calhoun, G. Zorn, D. Spence, D. Mitton || pcalhoun@cisco.com, gwz@cisco.com, dspence@computer.org, dmitton@circularnetworks.com +# RFC4006 || H. Hakala, L. Mattila, J-P. Koskinen, M. Stura, J. Loughney || Harri.Hakala@ericsson.com, Leena.Mattila@ericsson.com, juha-pekka.koskinen@nokia.com, marco.stura@nokia.com, John.Loughney@nokia.com +# RFC4007 || S. Deering, B. Haberman, T. Jinmei, E. Nordmark, B. Zill || none, brian@innovationslab.net, jinmei@isl.rdc.toshiba.co.jp, Erik.Nordmark@sun.com, bzill@microsoft.com +# RFC4008 || R. Rohit, P. Srisuresh, R. Raghunarayan, N. Pai, C. Wang || rrohit74@hotmail.com, srisuresh@yahoo.com, raraghun@cisco.com, npai@cisco.com, cliffwang2000@yahoo.com +# RFC4009 || J. Park, S. Lee, J. Kim, J. Lee || khopri@kisa.or.kr, sjlee@kisa.or.kr, jykim@kisa.or.kr, jilee@kisa.or.kr +# RFC4010 || J. Park, S. Lee, J. Kim, J. Lee || khopri@kisa.or.kr, sjlee@kisa.or.kr, jykim@kisa.or.kr, jilee@kisa.or.kr +# RFC4011 || S. Waldbusser, J. Saperia, T. Hongal || waldbusser@nextbeacon.com, saperia@jdscons.com, hongal@riverstonenet.com +# RFC4012 || L. Blunk, J. Damas, F. Parent, A. Robachevsky || ljb@merit.edu, Joao_Damas@isc.org, Florent.Parent@hexago.com, andrei@ripe.net +# RFC4013 || K. Zeilenga || Kurt@OpenLDAP.org +# RFC4014 || R. Droms, J. Schnizlein || rdroms@cisco.com, jschnizl@cisco.com +# RFC4015 || R. Ludwig, A. Gurtov || Reiner.Ludwig@ericsson.com, andrei.gurtov@cs.helsinki.fi +# RFC4016 || M. Parthasarathy || mohanp@sbcglobal.net +# RFC4017 || D. Stanley, J. Walker, B. Aboba || dstanley@agere.com, jesse.walker@intel.com, bernarda@microsoft.com +# RFC4018 || M. Bakke, J. Hufferd, K. Voruganti, M. Krueger, T. Sperry || mbakke@cisco.com, jlhufferd@comcast.net, kaladhar@us.ibm.com, marjorie_krueger@hp.com, todd_sperry@adaptec.com +# RFC4019 || G. Pelletier || ghyslain.pelletier@ericsson.com +# RFC4020 || K. Kompella, A. Zinin || kireeti@juniper.net, zinin@psg.com +# RFC4021 || G. Klyne, J. Palme || GK-IETF@ninebynine.org, jpalme@dsv.su.se +# RFC4022 || R. Raghunarayan, Ed. || raraghun@cisco.com +# RFC4023 || T. Worster, Y. Rekhter, E. Rosen, Ed. || tom.worster@motorola.com, yakov@juniper.net, erosen@cisco.com +# RFC4024 || G. Parsons, J. Maruszak || gparsons@nortel.com, jjmaruszak@sympatico.ca +# RFC4025 || M. Richardson || mcr@sandelman.ottawa.on.ca +# RFC4026 || L. Andersson, T. Madsen || loa@pi.se, tove.madsen@acreo.se +# RFC4027 || S. Josefsson || simon@josefsson.org +# RFC4028 || S. Donovan, J. Rosenberg || srd@cisco.com, jdrosen@cisco.com +# RFC4029 || M. Lind, V. Ksinant, S. Park, A. Baudot, P. Savola || mikael.lind@teliasonera.com, vladimir.ksinant@fr.thalesgroup.com, soohong.park@samsung.com, alain.baudot@francetelecom.com, psavola@funet.fi +# RFC4030 || M. Stapp, T. Lemon || mjs@cisco.com, Ted.Lemon@nominum.com +# RFC4031 || M. Carugi, Ed., D. McDysan, Ed. || marco.carugi@nortel.com, dave.mcdysan@mci.com +# RFC4032 || G. Camarillo, P. Kyzivat || Gonzalo.Camarillo@ericsson.com, pkyzivat@cisco.com +# RFC4033 || R. Arends, R. Austein, M. Larson, D. Massey, S. Rose || roy.arends@telin.nl, sra@isc.org, mlarson@verisign.com, massey@cs.colostate.edu, scott.rose@nist.gov +# RFC4034 || R. Arends, R. Austein, M. Larson, D. Massey, S. Rose || roy.arends@telin.nl, sra@isc.org, mlarson@verisign.com, massey@cs.colostate.edu, scott.rose@nist.gov +# RFC4035 || R. Arends, R. Austein, M. Larson, D. Massey, S. Rose || roy.arends@telin.nl, sra@isc.org, mlarson@verisign.com, massey@cs.colostate.edu, scott.rose@nist.gov +# RFC4036 || W. Sawyer || wsawyer@ieee.org +# RFC4037 || A. Rousskov || rousskov@measurement-factory.com +# RFC4038 || M-K. Shin, Ed., Y-G. Hong, J. Hagino, P. Savola, E. M. Castro || mshin@nist.gov, yghong@pec.etri.re.kr, itojun@iijlab.net, psavola@funet.fi, eva@gsyc.escet.urjc.es +# RFC4039 || S. Park, P. Kim, B. Volz || soohong.park@samsung.com, kimps@samsung.com, volz@cisco.com +# RFC4040 || R. Kreuter || ruediger.kreuter@siemens.com +# RFC4041 || A. Farrel || adrian@olddog.co.uk +# RFC4042 || M. Crispin || UTF9@Lingling.Panda.COM +# RFC4043 || D. Pinkas, T. Gindin || Denis.Pinkas@bull.net, tgindin@us.ibm.com +# RFC4044 || K. McCloghrie || kzm@cisco.com +# RFC4045 || G. Bourdon || gilles.bourdon@francetelecom.com +# RFC4046 || M. Baugher, R. Canetti, L. Dondeti, F. Lindholm || mbaugher@cisco.com, canetti@watson.ibm.com, ldondeti@qualcomm.com, fredrik.lindholm@ericsson.com +# RFC4047 || S. Allen, D. Wells || sla@ucolick.org, dwells@nrao.edu +# RFC4048 || B. Carpenter || brc@zurich.ibm.com +# RFC4049 || R. Housley || housley@vigilsec.com +# RFC4050 || S. Blake-Wilson, G. Karlinger, T. Kobayashi, Y. Wang || sblakewilson@bcisse.com, gregor.karlinger@cio.gv.at, kotetsu@isl.ntt.co.jp, yonwang@uncc.edu +# RFC4051 || D. Eastlake 3rd || Donald.Eastlake@motorola.com +# RFC4052 || L. Daigle, Ed., Internet Architecture Board || iab@iab.org, iab@iab.org +# RFC4053 || S. Trowbridge, S. Bradner, F. Baker || sjtrowbridge@lucent.com, sob@harvard.edu, fred@cisco.com +# RFC4054 || J. Strand, Ed., A. Chiu, Ed. || jls@research.att.com, chiu@research.att.com +# RFC4055 || J. Schaad, B. Kaliski, R. Housley || jimsch@exmsft.com, bkaliski@rsasecurity.com, housley@vigilsec.com +# RFC4056 || J. Schaad || jimsch@exmsft.com +# RFC4057 || J. Bound, Ed. || jim.bound@hp.com +# RFC4058 || A. Yegin, Ed., Y. Ohba, R. Penno, G. Tsirtsis, C. Wang || alper.yegin@samsung.com, yohba@tari.toshiba.com, rpenno@juniper.net, G.Tsirtsis@Flarion.com, cliffwangmail@yahoo.com +# RFC4059 || D. Linsenbardt, S. Pontius, A. Sturgeon || dlinsenbardt@spyrus.com, spontius@spyrus.com, asturgeon@spyrus.com +# RFC4060 || Q. Xie, D. Pearce || qxie1@email.mot.com, bdp003@motorola.com +# RFC4061 || V. Manral, R. White, A. Shaikh || vishwas@sinett.com, riw@cisco.com, ashaikh@research.att.com +# RFC4062 || V. Manral, R. White, A. Shaikh || vishwas@sinett.com, riw@cisco.com, ashaikh@research.att.com +# RFC4063 || V. Manral, R. White, A. Shaikh || vishwas@sinett.com, riw@cisco.com, ashaikh@research.att.com +# RFC4064 || A. Patel, K. Leung || alpesh@cisco.com, kleung@cisco.com +# RFC4065 || J. Kempf || kempf@docomolabs-usa.com +# RFC4066 || M. Liebsch, Ed., A. Singh, Ed., H. Chaskar, D. Funato, E. Shim || marco.liebsch@netlab.nec.de, asingh1@email.mot.com, hemant.chaskar@airtightnetworks.net, funato@mlab.yrp.nttdocomo.co.jp, eunsoo@research.panasonic.com +# RFC4067 || J. Loughney, Ed., M. Nakhjiri, C. Perkins, R. Koodli || john.loughney@nokia.com, madjid.nakhjiri@motorola.com, charles.perkins@.nokia.com, rajeev.koodli@nokia.com +# RFC4068 || R. Koodli, Ed. || Rajeev.Koodli@nokia.com +# RFC4069 || M. Dodge, B. Ray || mbdodge@ieee.org, rray@pesa.com +# RFC4070 || M. Dodge, B. Ray || mbdodge@ieee.org, rray@pesa.com +# RFC4071 || R. Austein, Ed., B. Wijnen, Ed. || sra@isc.org, bwijnen@lucent.com +# RFC4072 || P. Eronen, Ed., T. Hiller, G. Zorn || pe@iki.fi, tomhiller@lucent.com, gwz@cisco.com +# RFC4073 || R. Housley || housley@vigilsec.com +# RFC4074 || Y. Morishita, T. Jinmei || yasuhiro@jprs.co.jp, jinmei@isl.rdc.toshiba.co.jp +# RFC4075 || V. Kalusivalingam || vibhaska@cisco.com +# RFC4076 || T. Chown, S. Venaas, A. Vijayabhaskar || tjc@ecs.soton.ac.uk, venaas@uninett.no, vibhaska@cisco.com +# RFC4077 || A.B. Roach || adam@estacado.net +# RFC4078 || N. Earnshaw, S. Aoki, A. Ashley, W. Kameyama || nigel.earnshaw@rd.bbc.co.uk, shig@center.jfn.co.jp, aashley@ndsuk.com, wataru@waseda.jp +# RFC4079 || J. Peterson || jon.peterson@neustar.biz +# RFC4080 || R. Hancock, G. Karagiannis, J. Loughney, S. Van den Bosch || robert.hancock@roke.co.uk, g.karagiannis@ewi.utwente.nl, john.loughney@nokia.com, sven.van_den_bosch@alcatel.be +# RFC4081 || H. Tschofenig, D. Kroeselberg || Hannes.Tschofenig@siemens.com, Dirk.Kroeselberg@siemens.com +# RFC4082 || A. Perrig, D. Song, R. Canetti, J. D. Tygar, B. Briscoe || perrig@cmu.edu, dawnsong@cmu.edu, canetti@watson.ibm.com, doug.tygar@gmail.com, bob.briscoe@bt.com +# RFC4083 || M. Garcia-Martin || miguel.an.garcia@nokia.com +# RFC4084 || J. Klensin || john-ietf@jck.com +# RFC4085 || D. Plonka || plonka@doit.wisc.edu +# RFC4086 || D. Eastlake 3rd, J. Schiller, S. Crocker || Donald.Eastlake@motorola.com, jis@mit.edu, steve@stevecrocker.com +# RFC4087 || D. Thaler || dthaler@microsoft.com +# RFC4088 || D. Black, K. McCloghrie, J. Schoenwaelder || black_david@emc.com, kzm@cisco.com, j.schoenwaelder@iu-bremen.de +# RFC4089 || S. Hollenbeck, Ed., IAB and IESG || sah@428cobrajet.net, none, none +# RFC4090 || P. Pan, Ed., G. Swallow, Ed., A. Atlas, Ed. || ppan@hammerheadsystems.com, swallow@cisco.com, aatlas@avici.com +# RFC4091 || G. Camarillo, J. Rosenberg || Gonzalo.Camarillo@ericsson.com, jdrosen@cisco.com +# RFC4092 || G. Camarillo, J. Rosenberg || Gonzalo.Camarillo@ericsson.com, jdrosen@cisco.com +# RFC4093 || F. Adrangi, Ed., H. Levkowetz, Ed. || farid.adrangi@intel.com, henrik@levkowetz.com +# RFC4094 || J. Manner, X. Fu || jmanner@cs.helsinki.fi, fu@cs.uni-goettingen.de +# RFC4095 || C. Malamud || carl@media.org +# RFC4096 || C. Malamud || carl@media.org +# RFC4097 || M. Barnes, Ed. || mary.barnes@nortel.com +# RFC4098 || H. Berkowitz, E. Davies, Ed., S. Hares, P. Krishnaswamy, M. Lepp || hcb@gettcomm.com, elwynd@dial.pipex.com, skh@nexthop.com, padma.krishnaswamy@saic.com, mlepp@lepp.com +# RFC4101 || E. Rescorla, IAB || ekr@rtfm.com, iab@iab.org +# RFC4102 || P. Jones || paulej@packetizer.com +# RFC4103 || G. Hellstrom, P. Jones || gunnar.hellstrom@omnitor.se, paulej@packetizer.com +# RFC4104 || M. Pana, Ed., A. Reyes, A. Barba, D. Moron, M. Brunner || mpana@metasolv.com, mreyes@ac.upc.edu, telabm@mat.upc.es, dmor4477@hotmail.com, brunner@netlab.nec.de +# RFC4105 || J.-L. Le Roux, Ed., J.-P. Vasseur, Ed., J. Boyle, Ed. || jeanlouis.leroux@francetelecom.com, jpv@cisco.com, jboyle@pdnets.com +# RFC4106 || J. Viega, D. McGrew || viega@securesoftware.com, mcgrew@cisco.com +# RFC4107 || S. Bellovin, R. Housley || bellovin@acm.org, housley@vigilsec.com +# RFC4108 || R. Housley || housley@vigilsec.com +# RFC4109 || P. Hoffman || paul.hoffman@vpnc.org +# RFC4110 || R. Callon, M. Suzuki || rcallon@juniper.net, suzuki.muneyoshi@lab.ntt.co.jp +# RFC4111 || L. Fang, Ed. || luyuanfang@att.com +# RFC4112 || D. Eastlake 3rd || Donald.Eastlake@motorola.com +# RFC4113 || B. Fenner, J. Flick || fenner@research.att.com, john.flick@hp.com +# RFC4114 || S. Hollenbeck || shollenbeck@verisign.com +# RFC4115 || O. Aboul-Magd, S. Rabie || osama@nortel.com, rabie@nortel.com +# RFC4116 || J. Abley, K. Lindqvist, E. Davies, B. Black, V. Gill || jabley@isc.org, kurtis@kurtis.pp.se, elwynd@dial.pipex.com, ben@layer8.net, vgill@vijaygill.com +# RFC4117 || G. Camarillo, E. Burger, H. Schulzrinne, A. van Wijk || Gonzalo.Camarillo@ericsson.com, eburger@brooktrout.com, schulzrinne@cs.columbia.edu, a.vwijk@viataal.nl +# RFC4118 || L. Yang, P. Zerfos, E. Sadot || lily.l.yang@intel.com, pzerfos@cs.ucla.edu, esadot@avaya.com +# RFC4119 || J. Peterson || jon.peterson@neustar.biz +# RFC4120 || C. Neuman, T. Yu, S. Hartman, K. Raeburn || bcn@isi.edu, tlyu@mit.edu, hartmans-ietf@mit.edu, raeburn@mit.edu +# RFC4121 || L. Zhu, K. Jaganathan, S. Hartman || LZhu@microsoft.com, karthikj@microsoft.com, hartmans-ietf@mit.edu +# RFC4122 || P. Leach, M. Mealling, R. Salz || paulle@microsoft.com, michael@refactored-networks.com, rsalz@datapower.com +# RFC4123 || H. Schulzrinne, C. Agboh || hgs@cs.columbia.edu, charles.agboh@packetizer.com +# RFC4124 || F. Le Faucheur, Ed. || flefauch@cisco.com +# RFC4125 || F. Le Faucheur, W. Lai || flefauch@cisco.com, wlai@att.com +# RFC4126 || J. Ash || gash@att.com +# RFC4127 || F. Le Faucheur, Ed. || flefauch@cisco.com +# RFC4128 || W. Lai || wlai@att.com +# RFC4129 || R. Mukundan, K. Morneault, N. Mangalpally || ranjith.mukundan@wipro.com, kmorneau@cisco.com, narsim@nortelnetworks.com +# RFC4130 || D. Moberg, R. Drummond || dmoberg@cyclonecommerce.com, rvd2@drummondgroup.com +# RFC4131 || S. Green, K. Ozawa, E. Cardona, Ed., A. Katsnelson || rubbersoul3@yahoo.com, Kazuyoshi.Ozawa@toshiba.co.jp, katsnelson6@peoplepc.com, e.cardona@cablelabs.com +# RFC4132 || S. Moriai, A. Kato, M. Kanda || shiho@rd.scei.sony.co.jp, akato@po.ntts.co.jp, kanda.masayuki@lab.ntt.co.jp +# RFC4133 || A. Bierman, K. McCloghrie || andy@yumaworks.com, kzm@cisco.com +# RFC4134 || P. Hoffman, Ed. || phoffman@imc.org +# RFC4135 || JH. Choi, G. Daley || jinchoe@samsung.com, greg.daley@eng.monash.edu.au +# RFC4136 || P. Pillay-Esnault || ppe@cisco.com +# RFC4137 || J. Vollbrecht, P. Eronen, N. Petroni, Y. Ohba || jrv@mtghouse.com, pe@iki.fi, npetroni@cs.umd.edu, yohba@tari.toshiba.com +# RFC4138 || P. Sarolahti, M. Kojo || pasi.sarolahti@nokia.com, kojo@cs.helsinki.fi +# RFC4139 || D. Papadimitriou, J. Drake, J. Ash, A. Farrel, L. Ong || dimitri.papadimitriou@alcatel.be, John.E.Drake2@boeing.com, gash@att.com, adrian@olddog.co.uk, lyong@ciena.com +# RFC4140 || H. Soliman, C. Castelluccia, K. El Malki, L. Bellier || h.soliman@flarion.com, claude.castelluccia@inria.fr, karim@elmalki.homeip.net, ludovic.bellier@inria.fr +# RFC4141 || K. Toyoda, D. Crocker || toyoda.kiyoshi@jp.panasonic.com, dcrocker@bbiw.net +# RFC4142 || D. Crocker, G. Klyne || dcrocker@bbiw.net, GK-IETF@ninebynine.org +# RFC4143 || K. Toyoda, D. Crocker || toyoda.kiyoshi@jp.panasonic.com, dcrocker@bbiw.net +# RFC4144 || D. Eastlake 3rd || Donald.Eastlake@motorola.com +# RFC4145 || D. Yon, G. Camarillo || yon-comedia@rfdsoftware.com, Gonzalo.Camarillo@ericsson.com +# RFC4146 || R. Gellens || randy@qualcomm.com +# RFC4147 || G. Huston || gih@apnic.net +# RFC4148 || E. Stephan || emile.stephan@francetelecom.com +# RFC4149 || C. Kalbfleisch, R. Cole, D. Romascanu || ietf@kalbfleisch.us, robert.cole@jhuapl.edu, dromasca@gmail.com +# RFC4150 || R. Dietz, R. Cole || rdietz@hifn.com, robert.cole@jhuapl.edu +# RFC4151 || T. Kindberg, S. Hawke || timothy@hpl.hp.com, sandro@w3.org +# RFC4152 || K. Tesink, R. Fox || kaj@research.telcordia.com, rfox@telcordia.com +# RFC4153 || K. Fujimura, M. Terada, D. Eastlake 3rd || fujimura.ko@lab.ntt.co.jp, te@rex.yrp.nttdocomo.co.jp, Donald.Eastlake@motorola.com +# RFC4154 || M. Terada, K. Fujimura || te@rex.yrp.nttdocomo.co.jp, fujimura.ko@lab.ntt.co.jp +# RFC4155 || E. Hall || ehall@ntrg.com +# RFC4156 || P. Hoffman || paul.hoffman@vpnc.org +# RFC4157 || P. Hoffman || paul.hoffman@vpnc.org +# RFC4158 || M. Cooper, Y. Dzambasow, P. Hesse, S. Joseph, R. Nicholas || mcooper@orionsec.com, yuriy@anassoc.com, pmhesse@geminisecurity.com, susan.joseph@vdtg.com, richard.nicholas@it.baesystems.com +# RFC4159 || G. Huston || gih@apnic.net +# RFC4160 || K. Mimura, K. Yokoyama, T. Satoh, C. Kanaide, C. Allocchio || mimu@miyabi-labo.net, keiyoko@msn.com, zsatou@t-ns.co.jp, icemilk77@yahoo.co.jp, Claudio.Allocchio@garr.it +# RFC4161 || K. Mimura, K. Yokoyama, T. Satoh, K. Watanabe, C. Kanaide || mimu@miyabi-labo.net, keiyoko@msn.com, zsatou@t-ns.co.jp, knabe@ad.cyberhome.ne.jp, icemilk77@yahoo.co.jp +# RFC4162 || H.J. Lee, J.H. Yoon, J.I. Lee || jiinii@kisa.or.kr, jhyoon@kisa.or.kr, jilee@kisa.or.kr +# RFC4163 || L-E. Jonsson || lars-erik.jonsson@ericsson.com +# RFC4164 || G. Pelletier || ghyslain.pelletier@ericsson.com +# RFC4165 || T. George, B. Bidulock, R. Dantu, H. Schwarzbauer, K. Morneault || tgeorge_tx@verizon.net, bidulock@openss7.org, rdantu@unt.edu, HannsJuergen.Schwarzbauer@Siemens.com, kmorneau@cisco.com +# RFC4166 || L. Coene, J. Pastor-Balbas || lode.coene@siemens.com, J.Javier.Pastor@ericsson.com +# RFC4167 || A. Lindem || acee@cisco.com +# RFC4168 || J. Rosenberg, H. Schulzrinne, G. Camarillo || jdrosen@cisco.com, schulzrinne@cs.columbia.edu, Gonzalo.Camarillo@ericsson.com +# RFC4169 || V. Torvinen, J. Arkko, M. Naslund || vesa.torvinen@turkuamk.fi, jari.arkko@ericsson.com, mats.naslund@ericsson.com +# RFC4170 || B. Thompson, T. Koren, D. Wing || brucet@cisco.com, tmima@cisco.com, dwing-ietf@fuggles.com +# RFC4171 || J. Tseng, K. Gibbons, F. Travostino, C. Du Laney, J. Souza || joshtseng@yahoo.com, kevin.gibbons@mcdata.com, travos@nortel.com, cdl@rincon.com, joes@exmsft.com +# RFC4172 || C. Monia, R. Mullendore, F. Travostino, W. Jeong, M. Edwards || charles_monia@yahoo.com, Rod.Mullendore@MCDATA.com, travos@nortel.com, wayland@TroikaNetworks.com, mark_edwards@adaptec.com +# RFC4173 || P. Sarkar, D. Missimer, C. Sapuntzakis || psarkar@almaden.ibm.com, duncan.missimer@ieee.org, csapuntz@alum.mit.edu +# RFC4174 || C. Monia, J. Tseng, K. Gibbons || charles_monia@yahoo.com, joshtseng@yahoo.com, kevin.gibbons@mcdata.com +# RFC4175 || L. Gharai, C. Perkins || ladan@isi.edu, csp@csperkins.org +# RFC4176 || Y. El Mghazli, Ed., T. Nadeau, M. Boucadair, K. Chan, A. Gonguet || yacine.el_mghazli@alcatel.fr, tnadeau@cisco.com, mohamed.boucadair@francetelecom.com, khchan@nortel.com, arnaud.gonguet@alcatel.fr +# RFC4177 || G. Huston || gih@apnic.net +# RFC4178 || L. Zhu, P. Leach, K. Jaganathan, W. Ingersoll || lzhu@microsoft.com, paulle@microsoft.com, karthikj@microsoft.com, wyllys.ingersoll@sun.com +# RFC4179 || S. Kang || sukang@nca.or.kr +# RFC4180 || Y. Shafranovich || ietf@shaftek.org +# RFC4181 || C. Heard, Ed. || heard@pobox.com +# RFC4182 || E. Rosen || erosen@cisco.com +# RFC4183 || E. Warnicke || eaw@cisco.com +# RFC4184 || B. Link, T. Hager, J. Flaks || bdl@dolby.com, thh@dolby.com, jasonfl@microsoft.com +# RFC4185 || J. Klensin || john-ietf@jck.com +# RFC4186 || H. Haverinen, Ed., J. Salowey, Ed. || henry.haverinen@nokia.com, jsalowey@cisco.com +# RFC4187 || J. Arkko, H. Haverinen || jari.Arkko@ericsson.com, henry.haverinen@nokia.com +# RFC4188 || K. Norseth, Ed., E. Bell, Ed. || kenyon.c.norseth@L-3com.com, elbell@ntlworld.com +# RFC4189 || K. Ono, S. Tachimoto || ono.kumiko@lab.ntt.co.jp, kumiko@cs.columbia.edu, tachimoto.shinya@lab.ntt.co.jp +# RFC4190 || K. Carlberg, I. Brown, C. Beard || k.carlberg@cs.ucl.ac.uk, I.Brown@cs.ucl.ac.uk, BeardC@umkc.edu +# RFC4191 || R. Draves, D. Thaler || richdr@microsoft.com, dthaler@microsoft.com +# RFC4192 || F. Baker, E. Lear, R. Droms || fred@cisco.com, lear@cisco.com, rdroms@cisco.com +# RFC4193 || R. Hinden, B. Haberman || bob.hinden@gmail.com, brian@innovationslab.net +# RFC4194 || J. Strombergson, L. Walleij, P. Faltstrom || Joachim.Strombergson@InformAsic.com, triad@df.lth.se, paf@cisco.com +# RFC4195 || W. Kameyama || wataru@waseda.jp +# RFC4196 || H.J. Lee, J.H. Yoon, S.L. Lee, J.I. Lee || jiinii@kisa.or.kr, jhyoon@kisa.or.kr, sllee@kisa.or.kr, jilee@kisa.or.kr +# RFC4197 || M. Riegel, Ed. || maximilian.riegel@siemens.com +# RFC4198 || D. Tessman || dtessman@zelestra.com +# RFC4201 || K. Kompella, Y. Rekhter, L. Berger || kireeti@juniper.net, yakov@juniper.net, lberger@movaz.com +# RFC4202 || K. Kompella, Ed., Y. Rekhter, Ed. || kireeti@juniper.net, yakov@juniper.net +# RFC4203 || K. Kompella, Ed., Y. Rekhter, Ed. || kireeti@juniper.net, yakov@juniper.net +# RFC4204 || J. Lang, Ed. || jplang@ieee.org +# RFC4205 || K. Kompella, Ed., Y. Rekhter, Ed. || kireeti@juniper.net, yakov@juniper.net +# RFC4206 || K. Kompella, Y. Rekhter || kireeti@juniper.net, yakov@juniper.net +# RFC4207 || J. Lang, D. Papadimitriou || jplang@ieee.org, dimitri.papadimitriou@alcatel.be +# RFC4208 || G. Swallow, J. Drake, H. Ishimatsu, Y. Rekhter || swallow@cisco.com, John.E.Drake2@boeing.com, hirokazu.ishimatsu@g1m.jp, yakov@juniper.net +# RFC4209 || A. Fredette, Ed., J. Lang, Ed. || Afredette@HatterasNetworks.com, jplang@ieee.org +# RFC4210 || C. Adams, S. Farrell, T. Kause, T. Mononen || cadams@site.uottawa.ca, stephen.farrell@cs.tcd.ie, toka@ssh.com, tmononen@safenet-inc.com +# RFC4211 || J. Schaad || jimsch@exmsft.com +# RFC4212 || M. Blinov, C. Adams || mikblinov@online.ie, cadams@site.uottawa.ca +# RFC4213 || E. Nordmark, R. Gilligan || erik.nordmark@sun.com, bob.gilligan@acm.org +# RFC4214 || F. Templin, T. Gleeson, M. Talwar, D. Thaler || fltemplin@acm.org, tgleeson@cisco.com, mohitt@microsoft.com, dthaler@microsoft.com +# RFC4215 || J. Wiljakka, Ed. || juha.wiljakka@nokia.com +# RFC4216 || R. Zhang, Ed., J.-P. Vasseur, Ed. || raymond_zhang@infonet.com, jpv@cisco.com +# RFC4217 || P. Ford-Hutchinson || rfc4217@ford-hutchinson.com +# RFC4218 || E. Nordmark, T. Li || erik.nordmark@sun.com, Tony.Li@tony.li +# RFC4219 || E. Lear || lear@cisco.com +# RFC4220 || M. Dubuc, T. Nadeau, J. Lang || mdubuc@ncf.ca, tnadeau@cisco.com, jplang@ieee.org +# RFC4221 || T. Nadeau, C. Srinivasan, A. Farrel || tnadeau@cisco.com, cheenu@bloomberg.net, adrian@olddog.co.uk +# RFC4222 || G. Choudhury, Ed. || gchoudhury@att.com +# RFC4223 || P. Savola || psavola@funet.fi +# RFC4224 || G. Pelletier, L-E. Jonsson, K. Sandlund || ghyslain.pelletier@ericsson.com, lars-erik.jonsson@ericsson.com, kristofer.sandlund@ericsson.com +# RFC4225 || P. Nikander, J. Arkko, T. Aura, G. Montenegro, E. Nordmark || pekka.nikander@nomadiclab.com, jari.arkko@ericsson.com, Tuomaura@microsoft.com, gabriel_montenegro_2000@yahoo.com, erik.nordmark@sun.com +# RFC4226 || D. M'Raihi, M. Bellare, F. Hoornaert, D. Naccache, O. Ranen || davidietf@gmail.com, mihir@cs.ucsd.edu, frh@vasco.com, david.naccache@gemplus.com, Ohad.Ranen@ealaddin.com +# RFC4227 || E. O'Tuathail, M. Rose || eamon.otuathail@clipcode.com, mrose17@gmail.com +# RFC4228 || A. Rousskov || rousskov@measurement-factory.com +# RFC4229 || M. Nottingham, J. Mogul || mnot@pobox.com, JeffMogul@acm.org +# RFC4230 || H. Tschofenig, R. Graveman || Hannes.Tschofenig@siemens.com, rfg@acm.org +# RFC4231 || M. Nystrom || magnus@rsasecurity.com +# RFC4233 || K. Morneault, S. Rengasami, M. Kalla, G. Sidebottom || kmorneau@cisco.com, mkalla@telcordia.com, selvam@trideaworks.com, greg@signatustechnologies.com +# RFC4234 || D. Crocker, Ed., P. Overell || dcrocker@bbiw.net, paul@bayleaf.org.uk +# RFC4235 || J. Rosenberg, H. Schulzrinne, R. Mahy, Ed. || jdrosen@cisco.com, schulzrinne@cs.columbia.edu, rohan@ekabal.com +# RFC4236 || A. Rousskov, M. Stecher || rousskov@measurement-factory.com, martin.stecher@webwasher.com +# RFC4237 || G. Vaudreuil || GregV@ieee.org +# RFC4238 || G. Vaudreuil || GregV@ieee.org +# RFC4239 || S. McRae, G. Parsons || stuart.mcrae@uk.ibm.com, gparsons@nortel.com +# RFC4240 || E. Burger, Ed., J. Van Dyke, A. Spitzer || eburger@brooktrout.com, jvandyke@brooktrout.com, woof@brooktrout.com +# RFC4241 || Y. Shirasaki, S. Miyakawa, T. Yamasaki, A. Takenouchi || yasuhiro@nttv6.jp, miyakawa@nttv6.jp, t.yamasaki@ntt.com, takenouchi.ayako@lab.ntt.co.jp +# RFC4242 || S. Venaas, T. Chown, B. Volz || venaas@uninett.no, tjc@ecs.soton.ac.uk, volz@cisco.com +# RFC4243 || M. Stapp, R. Johnson, T. Palaniappan || mjs@cisco.com, raj@cisco.com, athenmoz@cisco.com +# RFC4244 || M. Barnes, Ed. || mary.barnes@nortel.com +# RFC4245 || O. Levin, R. Even || oritl@microsoft.com, roni.even@polycom.co.il +# RFC4246 || M. Dolan || md.1@newtbt.com +# RFC4247 || J. Ash, B. Goode, J. Hand, R. Zhang || gash@att.com, bgoode@att.com, jameshand@att.com, raymond.zhang@bt.infonet.com +# RFC4248 || P. Hoffman || paul.hoffman@vpnc.org +# RFC4249 || B. Lilly || blilly@erols.com +# RFC4250 || S. Lehtinen, C. Lonvick, Ed. || sjl@ssh.com, clonvick@cisco.com +# RFC4251 || T. Ylonen, C. Lonvick, Ed. || ylo@ssh.com, clonvick@cisco.com +# RFC4252 || T. Ylonen, C. Lonvick, Ed. || ylo@ssh.com, clonvick@cisco.com +# RFC4253 || T. Ylonen, C. Lonvick, Ed. || ylo@ssh.com, clonvick@cisco.com +# RFC4254 || T. Ylonen, C. Lonvick, Ed. || ylo@ssh.com, clonvick@cisco.com +# RFC4255 || J. Schlyter, W. Griffin || jakob@openssh.com, wgriffin@sparta.com +# RFC4256 || F. Cusack, M. Forssen || frank@savecore.net, maf@appgate.com +# RFC4257 || G. Bernstein, E. Mannie, V. Sharma, E. Gray || gregb@grotto-networking.com, eric.mannie@perceval.net, v.sharma@ieee.org, Eric.Gray@Marconi.com +# RFC4258 || D. Brungard, Ed. || dbrungard@att.com +# RFC4259 || M.-J. Montpetit, G. Fairhurst, H. Clausen, B. Collini-Nocker, H. Linder || mmontpetit@motorola.com, gorry@erg.abdn.ac.uk, h.d.clausen@ieee.org, bnocker@cosy.sbg.ac.at, hlinder@cosy.sbg.ac.at +# RFC4260 || P. McCann || mccap@lucent.com +# RFC4261 || J. Walker, A. Kulkarni, Ed. || jesse.walker@intel.com, amol.kulkarni@intel.com +# RFC4262 || S. Santesson || stefans@microsoft.com +# RFC4263 || B. Lilly || blilly@erols.com +# RFC4264 || T. Griffin, G. Huston || Timothy.Griffin@cl.cam.ac.uk, gih@apnic.net +# RFC4265 || B. Schliesser, T. Nadeau || bensons@savvis.net, tnadeau@cisco.com +# RFC4266 || P. Hoffman || paul.hoffman@vpnc.org +# RFC4267 || M. Froumentin || mf@w3.org +# RFC4268 || S. Chisholm, D. Perkins || schishol@nortel.com, dperkins@snmpinfo.com +# RFC4269 || H.J. Lee, S.J. Lee, J.H. Yoon, D.H. Cheon, J.I. Lee || jiinii@kisa.or.kr, sjlee@kisa.or.kr, jhyoon@kisa.or.kr, dhcheon@mmaa.or.kr, jilee@kisa.or.kr +# RFC4270 || P. Hoffman, B. Schneier || paul.hoffman@vpnc.org, schneier@counterpane.com +# RFC4271 || Y. Rekhter, Ed., T. Li, Ed., S. Hares, Ed. || yakov@juniper.net, tony.li@tony.li, skh@nexthop.com +# RFC4272 || S. Murphy || Sandy@tislabs.com +# RFC4273 || J. Haas, Ed., S. Hares, Ed. || jhaas@nexthop.com, skh@nexthop.com +# RFC4274 || D. Meyer, K. Patel || dmm@1-4-5.net, keyupate@cisco.com +# RFC4275 || S. Hares, D. Hares || skh@nexthop.com, dhares@hickoryhill-consulting.com +# RFC4276 || S. Hares, A. Retana || skh@nexthop.com, aretana@cisco.com +# RFC4277 || D. McPherson, K. Patel || danny@arbor.net, keyupate@cisco.com +# RFC4278 || S. Bellovin, A. Zinin || bellovin@acm.org, zinin@psg.com +# RFC4279 || P. Eronen, Ed., H. Tschofenig, Ed. || pe@iki.fi, Hannes.Tschofenig@siemens.com +# RFC4280 || K. Chowdhury, P. Yegani, L. Madour || kchowdhury@starentnetworks.com, pyegani@cisco.com, Lila.Madour@ericsson.com +# RFC4281 || R. Gellens, D. Singer, P. Frojdh || randy@qualcomm.com, singer@apple.com, Per.Frojdh@ericsson.com +# RFC4282 || B. Aboba, M. Beadles, J. Arkko, P. Eronen || bernarda@microsoft.com, mbeadles@endforce.com, jari.arkko@ericsson.com, pe@iki.fi +# RFC4283 || A. Patel, K. Leung, M. Khalil, H. Akhtar, K. Chowdhury || alpesh@cisco.com, kleung@cisco.com, mkhalil@nortel.com, haseebak@nortel.com, kchowdhury@starentnetworks.com +# RFC4284 || F. Adrangi, V. Lortz, F. Bari, P. Eronen || farid.adrangi@intel.com, victor.lortz@intel.com, farooq.bari@cingular.com, pe@iki.fi +# RFC4285 || A. Patel, K. Leung, M. Khalil, H. Akhtar, K. Chowdhury || alpesh@cisco.com, kleung@cisco.com, mkhalil@nortel.com, haseebak@nortel.com, kchowdhury@starentnetworks.com +# RFC4286 || B. Haberman, J. Martin || brian@innovationslab.net, jim@netzwert.ag +# RFC4287 || M. Nottingham, Ed., R. Sayre, Ed. || mnot@pobox.com, rfsayre@boswijck.com +# RFC4288 || N. Freed, J. Klensin || ned.freed@mrochek.com, klensin+ietf@jck.com +# RFC4289 || N. Freed, J. Klensin || ned.freed@mrochek.com, klensin+ietf@jck.com +# RFC4290 || J. Klensin || john-ietf@jck.com +# RFC4291 || R. Hinden, S. Deering || bob.hinden@gmail.com +# RFC4292 || B. Haberman || brian@innovationslab.net +# RFC4293 || S. Routhier, Ed. || sar@iwl.com +# RFC4294 || J. Loughney, Ed. || john.loughney@nokia.com +# RFC4295 || G. Keeni, K. Koide, K. Nagami, S. Gundavelli || glenn@cysols.com, koide@shiratori.riec.tohoku.ac.jp, nagami@inetcore.com, sgundave@cisco.com +# RFC4296 || S. Bailey, T. Talpey || steph@sandburst.com, thomas.talpey@netapp.com +# RFC4297 || A. Romanow, J. Mogul, T. Talpey, S. Bailey || allyn@cisco.com, JeffMogul@acm.org, thomas.talpey@netapp.com, steph@sandburst.com +# RFC4298 || J.-H. Chen, W. Lee, J. Thyssen || rchen@broadcom.com, wlee@broadcom.com, jthyssen@broadcom.com +# RFC4301 || S. Kent, K. Seo || kent@bbn.com, kseo@bbn.com +# RFC4302 || S. Kent || kent@bbn.com +# RFC4303 || S. Kent || kent@bbn.com +# RFC4304 || S. Kent || kent@bbn.com +# RFC4305 || D. Eastlake 3rd || Donald.Eastlake@Motorola.com +# RFC4306 || C. Kaufman, Ed. || charliek@microsoft.com +# RFC4307 || J. Schiller || jis@mit.edu +# RFC4308 || P. Hoffman || paul.hoffman@vpnc.org +# RFC4309 || R. Housley || housley@vigilsec.com +# RFC4310 || S. Hollenbeck || shollenbeck@verisign.com +# RFC4311 || R. Hinden, D. Thaler || bob.hinden@gmail.com, dthaler@microsoft.com +# RFC4312 || A. Kato, S. Moriai, M. Kanda || akato@po.ntts.co.jp, shiho@rd.scei.sony.co.jp, kanda@isl.ntt.co.jp +# RFC4313 || D. Oran || oran@cisco.com +# RFC4314 || A. Melnikov || alexey.melnikov@isode.com +# RFC4315 || M. Crispin || MRC@CAC.Washington.EDU +# RFC4316 || J. Reschke || julian.reschke@greenbytes.de +# RFC4317 || A. Johnston, R. Sparks || ajohnston@tello.com, rjsparks@estacado.net +# RFC4318 || D. Levi, D. Harrington || dlevi@nortel.com, ietfdbh@comcast.net +# RFC4319 || C. Sikes, B. Ray, R. Abbi || csikes@zhone.com, rray@pesa.com, Rajesh.Abbi@alcatel.com +# RFC4320 || R. Sparks || rjsparks@estacado.net +# RFC4321 || R. Sparks || rjsparks@estacado.net +# RFC4322 || M. Richardson, D.H. Redelmeier || mcr@sandelman.ottawa.on.ca, hugh@mimosa.com +# RFC4323 || M. Patrick, W. Murwin || michael.patrick@motorola.com, w.murwin@motorola.com +# RFC4324 || D. Royer, G. Babics, S. Mansour || Doug@IntelliCal.com, george.babics@oracle.com, smansour@ebay.com +# RFC4325 || S. Santesson, R. Housley || stefans@microsoft.com, housley@vigilsec.com +# RFC4326 || G. Fairhurst, B. Collini-Nocker || gorry@erg.abdn.ac.uk, bnocker@cosy.sbg.ac.at +# RFC4327 || M. Dubuc, T. Nadeau, J. Lang, E. McGinnis || dubuc.consulting@sympatico.ca, tnadeau@cisco.com, jplang@ieee.org, emcginnis@hammerheadsystems.com +# RFC4328 || D. Papadimitriou, Ed. || dimitri.papadimitriou@alcatel.be +# RFC4329 || B. Hoehrmann || bjoern@hoehrmann.de +# RFC4330 || D. Mills || mills@udel.edu +# RFC4331 || B. Korver, L. Dusseault || briank@networkresonance.com, lisa.dusseault@gmail.com +# RFC4332 || K. Leung, A. Patel, G. Tsirtsis, E. Klovning || kleung@cisco.com, alpesh@cisco.com, g.tsirtsis@flarion.com, espen@birdstep.com +# RFC4333 || G. Huston, Ed., B. Wijnen, Ed. || gih@apnic.net, bwijnen@lucent.com +# RFC4334 || R. Housley, T. Moore || housley@vigilsec.com, timmoore@microsoft.com +# RFC4335 || J. Galbraith, P. Remaker || galb-list@vandyke.com, remaker@cisco.com +# RFC4336 || S. Floyd, M. Handley, E. Kohler || floyd@icir.org, M.Handley@cs.ucl.ac.uk, kohler@cs.ucla.edu +# RFC4337 || Y Lim, D. Singer || young@netntv.co.kr, singer@apple.com +# RFC4338 || C. DeSanti, C. Carlson, R. Nixon || cds@cisco.com, craig.carlson@qlogic.com, bob.nixon@emulex.com +# RFC4339 || J. Jeong, Ed. || jjeong@cs.umn.edu +# RFC4340 || E. Kohler, M. Handley, S. Floyd || kohler@cs.ucla.edu, M.Handley@cs.ucl.ac.uk, floyd@icir.org +# RFC4341 || S. Floyd, E. Kohler || floyd@icir.org, kohler@cs.ucla.edu +# RFC4342 || S. Floyd, E. Kohler, J. Padhye || floyd@icir.org, kohler@cs.ucla.edu, padhye@microsoft.com +# RFC4343 || D. Eastlake 3rd || Donald.Eastlake@motorola.com +# RFC4344 || M. Bellare, T. Kohno, C. Namprempre || mihir@cs.ucsd.edu, tkohno@cs.ucsd.edu, meaw@alum.mit.edu +# RFC4345 || B. Harris || bjh21@bjh21.me.uk +# RFC4346 || T. Dierks, E. Rescorla || tim@dierks.org, ekr@rtfm.com +# RFC4347 || E. Rescorla, N. Modadugu || ekr@rtfm.com, nagendra@cs.stanford.edu +# RFC4348 || S. Ahmadi || sassan.ahmadi@ieee.org +# RFC4349 || C. Pignataro, M. Townsley || cpignata@cisco.com, mark@townsley.net +# RFC4350 || F. Hendrikx, C. Wallis || ferry.hendrikx@ssc.govt.nz, colin.wallis@ssc.govt.nz +# RFC4351 || G. Hellstrom, P. Jones || gunnar.hellstrom@omnitor.se, paulej@packetizer.com +# RFC4352 || J. Sjoberg, M. Westerlund, A. Lakaniemi, S. Wenger || Johan.Sjoberg@ericsson.com, Magnus.Westerlund@ericsson.com, ari.lakaniemi@nokia.com, Stephan.Wenger@nokia.com +# RFC4353 || J. Rosenberg || jdrosen@cisco.com +# RFC4354 || M. Garcia-Martin || miguel.an.garcia@nokia.com +# RFC4355 || R. Brandner, L. Conroy, R. Stastny || rudolf.brandner@siemens.com, lwc@roke.co.uk, Richard.stastny@oefeg.at +# RFC4356 || R. Gellens || randy@qualcomm.com +# RFC4357 || V. Popov, I. Kurepkin, S. Leontiev || vpopov@cryptopro.ru, kure@cryptopro.ru, lse@cryptopro.ru +# RFC4358 || D. Smith || dwight.smith@motorola.com +# RFC4359 || B. Weis || bew@cisco.com +# RFC4360 || S. Sangli, D. Tappan, Y. Rekhter || rsrihari@cisco.com, tappan@cisco.com, yakov@juniper.net +# RFC4361 || T. Lemon, B. Sommerfeld || mellon@nominum.com, sommerfeld@sun.com +# RFC4362 || L-E. Jonsson, G. Pelletier, K. Sandlund || lars-erik.jonsson@ericsson.com, ghyslain.pelletier@ericsson.com, kristofer.sandlund@ericsson.com +# RFC4363 || D. Levi, D. Harrington || dlevi@nortel.com, ietfdbh@comcast.net +# RFC4364 || E. Rosen, Y. Rekhter || erosen@cisco.com, yakov@juniper.net +# RFC4365 || E. Rosen || erosen@cisco.com +# RFC4366 || S. Blake-Wilson, M. Nystrom, D. Hopwood, J. Mikkelsen, T. Wright || sblakewilson@bcisse.com, magnus@rsasecurity.com, david.hopwood@blueyonder.co.uk, janm@transactionware.com, timothy.wright@vodafone.com +# RFC4367 || J. Rosenberg, Ed., IAB || jdrosen@cisco.com +# RFC4368 || T. Nadeau, S. Hegde || tnadeau@cisco.com, subrah@cisco.com +# RFC4369 || K. Gibbons, C. Monia, J. Tseng, F. Travostino || kevin.gibbons@mcdata.com, charles_monia@yahoo.com, joshtseng@yahoo.com, travos@nortel.com +# RFC4370 || R. Weltman || robw@worldspot.com +# RFC4371 || B. Carpenter, Ed., L. Lynch, Ed. || brc@zurich.ibm.com, llynch@darkwing.uoregon.edu +# RFC4372 || F. Adrangi, A. Lior, J. Korhonen, J. Loughney || farid.adrangi@intel.com, avi@bridgewatersystems.com, jouni.korhonen@teliasonera.com, john.loughney@nokia.com +# RFC4373 || R. Harrison, J. Sermersheim, Y. Dong || rharrison@novell.com, jimse@novell.com, yulindong@gmail.com +# RFC4374 || G. McCobb || mccobb@us.ibm.com +# RFC4375 || K. Carlberg || carlberg@g11.org.uk +# RFC4376 || P. Koskelainen, J. Ott, H. Schulzrinne, X. Wu || petri.koskelainen@nokia.com, jo@netlab.hut.fi, hgs@cs.columbia.edu, xiaotaow@cs.columbia.edu +# RFC4377 || T. Nadeau, M. Morrow, G. Swallow, D. Allan, S. Matsushima || tnadeau@cisco.com, mmorrow@cisco.com, swallow@cisco.com, dallan@nortel.com, satoru@ft.solteria.net +# RFC4378 || D. Allan, Ed., T. Nadeau, Ed. || dallan@nortel.com, tnadeau@cisco.com +# RFC4379 || K. Kompella, G. Swallow || kireeti@juniper.net, swallow@cisco.com +# RFC4380 || C. Huitema || huitema@microsoft.com +# RFC4381 || M. Behringer || mbehring@cisco.com +# RFC4382 || T. Nadeau, Ed., H. van der Linde, Ed. || tnadeau@cisco.com, havander@cisco.com +# RFC4383 || M. Baugher, E. Carrara || mbaugher@cisco.com, carrara@kth.se +# RFC4384 || D. Meyer || dmm@1-4-5.net +# RFC4385 || S. Bryant, G. Swallow, L. Martini, D. McPherson || stbryant@cisco.com, swallow@cisco.com, lmartini@cisco.com, danny@arbor.net +# RFC4386 || S. Boeyen, P. Hallam-Baker || sharon.boeyen@entrust.com, pbaker@VeriSign.com +# RFC4387 || P. Gutmann, Ed. || pgut001@cs.auckland.ac.nz +# RFC4388 || R. Woundy, K. Kinnear || richard_woundy@cable.comcast.com, kkinnear@cisco.com +# RFC4389 || D. Thaler, M. Talwar, C. Patel || dthaler@microsoft.com, mohitt@microsoft.com, chirayu@chirayu.org +# RFC4390 || V. Kashyap || vivk@us.ibm.com +# RFC4391 || J. Chu, V. Kashyap || jerry.chu@sun.com, vivk@us.ibm.com +# RFC4392 || V. Kashyap || vivk@us.ibm.com +# RFC4393 || H. Garudadri || hgarudadri@qualcomm.com +# RFC4394 || D. Fedyk, O. Aboul-Magd, D. Brungard, J. Lang, D. Papadimitriou || dwfedyk@nortel.com, osama@nortel.com, dbrungard@att.com, jplang@ieee.org, dimitri.papadimitriou@alcatel.be +# RFC4395 || T. Hansen, T. Hardie, L. Masinter || tony+urireg@maillennium.att.com, hardie@qualcomm.com, LMM@acm.org +# RFC4396 || J. Rey, Y. Matsui || jose.rey@eu.panasonic.com, matsui.yoshinori@jp.panasonic.com +# RFC4397 || I. Bryskin, A. Farrel || i_bryskin@yahoo.com, adrian@olddog.co.uk +# RFC4398 || S. Josefsson || simon@josefsson.org +# RFC4401 || N. Williams || Nicolas.Williams@sun.com +# RFC4402 || N. Williams || Nicolas.Williams@sun.com +# RFC4403 || B. Bergeson, K. Boogert, V. Nanjundaswamy || bruce.bergeson@novell.com, kent.boogert@novell.com, vijay.nanjundaswamy@oracle.com +# RFC4404 || R. Natarajan, A. Rijhsinghani || anil@charter.net, r.natarajan@f5.com +# RFC4405 || E. Allman, H. Katz || eric@sendmail.com, hkatz@microsoft.com +# RFC4406 || J. Lyon, M. Wong || jimlyon@microsoft.com, mengwong@dumbo.pobox.com +# RFC4407 || J. Lyon || jimlyon@microsoft.com +# RFC4408 || M. Wong, W. Schlitt || mengwong+spf@pobox.com, wayne@schlitt.net +# RFC4409 || R. Gellens, J. Klensin || g+ietf@qualcomm.com, john+ietf@jck.com +# RFC4410 || M. Pullen, F. Zhao, D. Cohen || mpullen@gmu.edu, fzhao@netlab.gmu.edu, danny.cohen@sun.com +# RFC4411 || J. Polk || jmpolk@cisco.com +# RFC4412 || H. Schulzrinne, J. Polk || hgs@cs.columbia.edu, jmpolk@cisco.com +# RFC4413 || M. West, S. McCann || mark.a.west@roke.co.uk, stephen.mccann@roke.co.uk +# RFC4414 || A. Newton || andy@hxr.us +# RFC4415 || R. Brandner, L. Conroy, R. Stastny || rudolf.brandner@siemens.com, lwc@roke.co.uk, Richard.stastny@oefeg.at +# RFC4416 || J. Wong, Ed. || j.k.wong@sympatico.ca +# RFC4417 || P. Resnick, Ed., P. Saint-Andre, Ed. || presnick@qti.qualcomm.com, ietf@stpeter.im +# RFC4418 || T. Krovetz, Ed. || tdk@acm.org +# RFC4419 || M. Friedl, N. Provos, W. Simpson || markus@openbsd.org, provos@citi.umich.edu, wsimpson@greendragon.com +# RFC4420 || A. Farrel, Ed., D. Papadimitriou, J.-P. Vasseur, A. Ayyangar || adrian@olddog.co.uk, dimitri.papadimitriou@alcatel.be, jpv@cisco.com, arthi@juniper.net +# RFC4421 || C. Perkins || csp@csperkins.org +# RFC4422 || A. Melnikov, Ed., K. Zeilenga, Ed. || Alexey.Melnikov@isode.com, Kurt@OpenLDAP.org +# RFC4423 || R. Moskowitz, P. Nikander || rgm@icsalabs.com, pekka.nikander@nomadiclab.com +# RFC4424 || S. Ahmadi || sassan.ahmadi@ieee.org +# RFC4425 || A. Klemets || Anders.Klemets@microsoft.com +# RFC4426 || J. Lang, Ed., B. Rajagopalan, Ed., D. Papadimitriou, Ed. || jplang@ieee.org, balar@microsoft.com, dimitri.papadimitriou@alcatel.be +# RFC4427 || E. Mannie, Ed., D. Papadimitriou, Ed. || eric.mannie@perceval.net, dimitri.papadimitriou@alcatel.be +# RFC4428 || D. Papadimitriou, Ed., E. Mannie, Ed. || dimitri.papadimitriou@alcatel.be, eric.mannie@perceval.net +# RFC4429 || N. Moore || sharkey@zoic.org +# RFC4430 || S. Sakane, K. Kamada, M. Thomas, J. Vilhuber || Shouichi.Sakane@jp.yokogawa.com, Ken-ichi.Kamada@jp.yokogawa.com, mat@cisco.com, vilhuber@cisco.com +# RFC4431 || M. Andrews, S. Weiler || Mark_Andrews@isc.org, weiler@tislabs.com +# RFC4432 || B. Harris || bjh21@bjh21.me.uk +# RFC4433 || M. Kulkarni, A. Patel, K. Leung || mkulkarn@cisco.com, alpesh@cisco.com, kleung@cisco.com +# RFC4434 || P. Hoffman || paul.hoffman@vpnc.org +# RFC4435 || Y. Nomura, R. Walsh, J-P. Luoma, H. Asaeda, H. Schulzrinne || nom@flab.fujitsu.co.jp, rod.walsh@nokia.com, juha-pekka.luoma@nokia.com, asaeda@wide.ad.jp, schulzrinne@cs.columbia.edu +# RFC4436 || B. Aboba, J. Carlson, S. Cheshire || bernarda@microsoft.com, james.d.carlson@sun.com, rfc@stuartcheshire.org +# RFC4437 || J. Whitehead, G. Clemm, J. Reschke, Ed. || ejw@cse.ucsc.edu, julian.reschke@greenbytes.degeoffrey.clemm@us.ibm.com, +# RFC4438 || C. DeSanti, V. Gaonkar, H.K. Vivek, K. McCloghrie, S. Gai || cds@cisco.com, vgaonkar@cisco.com, hvivek@cisco.com, kzm@cisco.com, none +# RFC4439 || C. DeSanti, V. Gaonkar, K. McCloghrie, S. Gai || cds@cisco.com, vgaonkar@cisco.com, kzm@cisco.com, none +# RFC4440 || S. Floyd, Ed., V. Paxson, Ed., A. Falk, Ed., IAB || floyd@acm.org, vern@icir.org, falk@isi.edu +# RFC4441 || B. Aboba, Ed. || bernarda@microsoft.com +# RFC4442 || S. Fries, H. Tschofenig || steffen.fries@siemens.com, Hannes.Tschofenig@siemens.com +# RFC4443 || A. Conta, S. Deering, M. Gupta, Ed. || aconta@txc.com, none, mukesh.gupta@tropos.com +# RFC4444 || J. Parker, Ed. || jeffp@middlebury.edu +# RFC4445 || J. Welch, J. Clark || Jim.Welch@ineoquest.com, jiclark@cisco.com +# RFC4446 || L. Martini || lmartini@cisco.com +# RFC4447 || L. Martini, Ed., E. Rosen, N. El-Aawar, T. Smith, G. Heron || lmartini@cisco.com, nna@level3.net, giles.heron@tellabs.com, erosen@cisco.com, tob@netapp.com +# RFC4448 || L. Martini, Ed., E. Rosen, N. El-Aawar, G. Heron || lmartini@cisco.com, nna@level3.net, giles.heron@tellabs.com, erosen@cisco.com +# RFC4449 || C. Perkins || charles.perkins@nokia.com +# RFC4450 || E. Lear, H. Alvestrand || lear@cisco.com, harald@alvestrand.no +# RFC4451 || D. McPherson, V. Gill || danny@arbor.net, VijayGill9@aol.com +# RFC4452 || H. Van de Sompel, T. Hammond, E. Neylon, S. Weibel || herbertv@lanl.gov, t.hammond@nature.com, eneylon@manifestsolutions.com, weibel@oclc.org +# RFC4453 || J. Rosenberg, G. Camarillo, Ed., D. Willis || jdrosen@cisco.com, Gonzalo.Camarillo@ericsson.com, dean.willis@softarmor.com +# RFC4454 || S. Singh, M. Townsley, C. Pignataro || sanjeevs@cisco.com, mark@townsley.net, cpignata@cisco.com +# RFC4455 || M. Hallak-Stamler, M. Bakke, Y. Lederman, M. Krueger, K. McCloghrie || michele@sanrad.com, mbakke@cisco.com, yaronled@bezeqint.net, marjorie_krueger@hp.com, kzm@cisco.com +# RFC4456 || T. Bates, E. Chen, R. Chandra || tbates@cisco.com, enkechen@cisco.com, rchandra@sonoasystems.com +# RFC4457 || G. Camarillo, G. Blanco || Gonzalo.Camarillo@ericsson.com, german.blanco@ericsson.com +# RFC4458 || C. Jennings, F. Audet, J. Elwell || fluffy@cisco.com, audet@nortel.com, john.elwell@siemens.com +# RFC4459 || P. Savola || psavola@funet.fi +# RFC4460 || R. Stewart, I. Arias-Rodriguez, K. Poon, A. Caro, M. Tuexen || randall@lakerest.net, ivan.arias-rodriguez@nokia.com, kacheong.poon@sun.com, acaro@bbn.com, tuexen@fh-muenster.de +# RFC4461 || S. Yasukawa, Ed. || yasukawa.seisho@lab.ntt.co.jp +# RFC4462 || J. Hutzelman, J. Salowey, J. Galbraith, V. Welch || jhutz+@cmu.edu, jsalowey@cisco.com, galb@vandyke.com, welch@mcs.anl.gov +# RFC4463 || S. Shanmugham, P. Monaco, B. Eberman || sarvi@cisco.com, peter.monaco@nuasis.com, brian.eberman@speechworks.com +# RFC4464 || A. Surtees, M. West || abigail.surtees@roke.co.uk, mark.a.west@roke.co.uk +# RFC4465 || A. Surtees, M. West || abigail.surtees@roke.co.uk, mark.a.west@roke.co.uk +# RFC4466 || A. Melnikov, C. Daboo || Alexey.Melnikov@isode.com, cyrus@daboo.name +# RFC4467 || M. Crispin || MRC@CAC.Washington.EDU +# RFC4468 || C. Newman || chris.newman@sun.com +# RFC4469 || P. Resnick || presnick@qti.qualcomm.com +# RFC4470 || S. Weiler, J. Ihren || weiler@tislabs.com, johani@autonomica.se +# RFC4471 || G. Sisson, B. Laurie || geoff@nominet.org.uk, ben@algroup.co.uk +# RFC4472 || A. Durand, J. Ihren, P. Savola || Alain_Durand@cable.comcast.com, johani@autonomica.se, psavola@funet.fi +# RFC4473 || Y. Nomura, R. Walsh, J-P. Luoma, J. Ott, H. Schulzrinne || nom@flab.fujitsu.co.jp, rod.walsh@nokia.com, juha-pekka.luoma@nokia.com, jo@netlab.tkk.fi, schulzrinne@cs.columbia.edu +# RFC4474 || J. Peterson, C. Jennings || jon.peterson@neustar.biz, fluffy@cisco.com +# RFC4475 || R. Sparks, Ed., A. Hawrylyshen, A. Johnston, J. Rosenberg, H. Schulzrinne || RjS@estacado.net, ahawrylyshen@ditechnetworks.com, alan@sipstation.com, jdrosen@cisco.com, hgs@cs.columbia.edu +# RFC4476 || C. Francis, D. Pinkas || Chris_S_Francis@Raytheon.com, Denis.Pinkas@bull.net +# RFC4477 || T. Chown, S. Venaas, C. Strauf || tjc@ecs.soton.ac.uk, venaas@uninett.no, strauf@rz.tu-clausthal.de +# RFC4478 || Y. Nir || ynir@checkpoint.com +# RFC4479 || J. Rosenberg || jdrosen@cisco.com +# RFC4480 || H. Schulzrinne, V. Gurbani, P. Kyzivat, J. Rosenberg || hgs+simple@cs.columbia.edu, vkg@lucent.com, pkyzivat@cisco.com, jdrosen@cisco.com +# RFC4481 || H. Schulzrinne || hgs+simple@cs.columbia.edu +# RFC4482 || H. Schulzrinne || hgs+simple@cs.columbia.edu +# RFC4483 || E. Burger, Ed. || eburger@cantata.com +# RFC4484 || J. Peterson, J. Polk, D. Sicker, H. Tschofenig || jon.peterson@neustar.biz, jmpolk@cisco.com, douglas.sicker@colorado.edu, Hannes.Tschofenig@siemens.com +# RFC4485 || J. Rosenberg, H. Schulzrinne || jdrosen@cisco.com, schulzrinne@cs.columbia.edu +# RFC4486 || E. Chen, V. Gillet || enkechen@cisco.com, vgi@opentransit.net +# RFC4487 || F. Le, S. Faccin, B. Patil, H. Tschofenig || franckle@cmu.edu, sfaccinstd@gmail.com, Basavaraj.Patil@nokia.com, Hannes.Tschofenig@siemens.com +# RFC4488 || O. Levin || oritl@microsoft.com +# RFC4489 || J-S. Park, M-K. Shin, H-J. Kim || pjs@etri.re.kr, myungki.shin@gmail.com, khj@etri.re.kr +# RFC4490 || S. Leontiev, Ed., G. Chudov, Ed. || lse@cryptopro.ru, chudov@cryptopro.ru +# RFC4491 || S. Leontiev, Ed., D. Shefanovski, Ed. || lse@cryptopro.ru, dbs@mts.ru +# RFC4492 || S. Blake-Wilson, N. Bolyard, V. Gupta, C. Hawk, B. Moeller || sblakewilson@safenet-inc.com, nelson@bolyard.com, vipul.gupta@sun.com, chris@corriente.net, bodo@openssl.org +# RFC4493 || JH. Song, R. Poovendran, J. Lee, T. Iwata || songlee@ee.washington.edu, radha@ee.washington.edu, icheol.lee@samsung.com, iwata@cse.nagoya-u.ac.jp +# RFC4494 || JH. Song, R. Poovendran, J. Lee || songlee@ee.washington.edu, radha@ee.washington.edu, jicheol.lee@samsung.com +# RFC4495 || J. Polk, S. Dhesikan || jmpolk@cisco.com, sdhesika@cisco.com +# RFC4496 || M. Stecher, A. Barbir || martin.stecher@webwasher.com, abbieb@nortel.com +# RFC4497 || J. Elwell, F. Derks, P. Mourot, O. Rousseau || john.elwell@siemens.com, frank.derks@nec-philips.com, Patrick.Mourot@alcatel.fr, Olivier.Rousseau@alcatel.fr +# RFC4498 || G. Keeni || glenn@cysols.com +# RFC4501 || S. Josefsson || simon@josefsson.org +# RFC4502 || S. Waldbusser || waldbusser@nextbeacon.com +# RFC4503 || M. Boesgaard, M. Vesterager, E. Zenner || mab@cryptico.com, mvp@cryptico.com, ez@cryptico.com +# RFC4504 || H. Sinnreich, Ed., S. Lass, C. Stredicke || henry@pulver.com, steven.lass@verizonbusiness.com, cs@snom.de +# RFC4505 || K. Zeilenga || Kurt@OpenLDAP.org +# RFC4506 || M. Eisler, Ed. || email2mre-rfc4506@yahoo.com +# RFC4507 || J. Salowey, H. Zhou, P. Eronen, H. Tschofenig || jsalowey@cisco.com, hzhou@cisco.com, pe@iki.fi, Hannes.Tschofenig@siemens.com +# RFC4508 || O. Levin, A. Johnston || oritl@microsoft.com, ajohnston@ipstation.com +# RFC4509 || W. Hardaker || hardaker@tislabs.com +# RFC4510 || K. Zeilenga, Ed. || Kurt@OpenLDAP.org +# RFC4511 || J. Sermersheim, Ed. || jimse@novell.com +# RFC4512 || K. Zeilenga, Ed. || Kurt@OpenLDAP.org +# RFC4513 || R. Harrison, Ed. || roger_harrison@novell.com +# RFC4514 || K. Zeilenga, Ed. || Kurt@OpenLDAP.org +# RFC4515 || M. Smith, Ed., T. Howes || mcs@pearlcrescent.com, howes@opsware.com +# RFC4516 || M. Smith, Ed., T. Howes || mcs@pearlcrescent.com, howes@opsware.com +# RFC4517 || S. Legg, Ed. || steven.legg@eb2bcom.com +# RFC4518 || K. Zeilenga || Kurt@OpenLDAP.org +# RFC4519 || A. Sciberras, Ed. || andrew.sciberras@eb2bcom.com +# RFC4520 || K. Zeilenga || Kurt@OpenLDAP.org +# RFC4521 || K. Zeilenga || Kurt@OpenLDAP.org +# RFC4522 || S. Legg || steven.legg@eb2bcom.com +# RFC4523 || K. Zeilenga || Kurt@OpenLDAP.org +# RFC4524 || K. Zeilenga, Ed. || Kurt@OpenLDAP.org +# RFC4525 || K. Zeilenga || Kurt@OpenLDAP.org +# RFC4526 || K. Zeilenga || Kurt@OpenLDAP.org +# RFC4527 || K. Zeilenga || Kurt@OpenLDAP.org +# RFC4528 || K. Zeilenga || Kurt@OpenLDAP.org +# RFC4529 || K. Zeilenga || Kurt@OpenLDAP.org +# RFC4530 || K. Zeilenga || Kurt@OpenLDAP.org +# RFC4531 || K. Zeilenga || Kurt@OpenLDAP.org +# RFC4532 || K. Zeilenga || Kurt@OpenLDAP.org +# RFC4533 || K. Zeilenga, J.H. Choi || Kurt@OpenLDAP.org, jongchoi@us.ibm.com +# RFC4534 || A Colegrove, H Harney || acc@sparta.com, hh@sparta.com +# RFC4535 || H. Harney, U. Meth, A. Colegrove, G. Gross || hh@sparta.com, umeth@sparta.com, acc@sparta.com, gmgross@identaware.com +# RFC4536 || P. Hoschka || ph@w3.org +# RFC4537 || L. Zhu, P. Leach, K. Jaganathan || lzhu@microsoft.com, paulle@microsoft.com, karthikj@microsoft.com +# RFC4538 || J. Rosenberg || jdrosen@cisco.com +# RFC4539 || T. Edwards || tedwards@pbs.org +# RFC4540 || M. Stiemerling, J. Quittek, C. Cadar || stiemerling@netlab.nec.de, quittek@netlab.nec.de, ccadar2@yahoo.com +# RFC4541 || M. Christensen, K. Kimball, F. Solensky || mjc@tt.dk, karen.kimball@hp.com, frank.solensky@calix.com +# RFC4542 || F. Baker, J. Polk || fred@cisco.com, jmpolk@cisco.com +# RFC4543 || D. McGrew, J. Viega || mcgrew@cisco.com, viega@list.org +# RFC4544 || M. Bakke, M. Krueger, T. McSweeney, J. Muchow || mbakke@cisco.com, marjorie_krueger@hp.com, tommcs@us.ibm.com, james.muchow@qlogic.com +# RFC4545 || M. Bakke, J. Muchow || mbakke@cisco.com, james.muchow@qlogic.com +# RFC4546 || D. Raftus, E. Cardona || david.raftus@ati.com, e.cardona@cablelabs.com +# RFC4547 || A. Ahmad, G. Nakanishi || azlina@cisco.com, gnakanishi@motorola.com +# RFC4548 || E. Gray, J. Rutemiller, G. Swallow || Eric.Gray@Marconi.com, John.Rutemiller@Marconi.com, swallow@cisco.com +# RFC4549 || A. Melnikov, Ed. || alexey.melnikov@isode.com +# RFC4550 || S. Maes, A. Melnikov || stephane.maes@oracle.com, Alexey.melnikov@isode.com +# RFC4551 || A. Melnikov, S. Hole || Alexey.Melnikov@isode.com, Steve.Hole@messagingdirect.com +# RFC4552 || M. Gupta, N. Melam || mukesh.gupta@tropos.com, nmelam@juniper.net +# RFC4553 || A. Vainshtein, Ed., YJ. Stein, Ed. || sasha@axerra.com, yaakov_s@rad.com +# RFC4554 || T. Chown || tjc@ecs.soton.ac.uk +# RFC4555 || P. Eronen || pe@iki.fi +# RFC4556 || L. Zhu, B. Tung || lzhu@microsoft.com, brian@aero.org +# RFC4557 || L. Zhu, K. Jaganathan, N. Williams || lzhu@microsoft.com, karthikj@microsoft.com, Nicolas.Williams@sun.com +# RFC4558 || Z. Ali, R. Rahman, D. Prairie, D. Papadimitriou || zali@cisco.com, rrahman@cisco.com, dprairie@cisco.com, dimitri.papadimitriou@alcatel.be +# RFC4559 || K. Jaganathan, L. Zhu, J. Brezak || karthikj@microsoft.com, lzhu@microsoft.com, jbrezak@microsoft.com +# RFC4560 || J. Quittek, Ed., K. White, Ed. || quittek@netlab.nec.de, wkenneth@us.ibm.com +# RFC4561 || J.-P. Vasseur, Ed., Z. Ali, S. Sivabalan || jpv@cisco.com, zali@cisco.com, msiva@cisco.com +# RFC4562 || T. Melsen, S. Blake || Torben.Melsen@ericsson.com, steven.blake@ericsson.com +# RFC4563 || E. Carrara, V. Lehtovirta, K. Norrman || carrara@kth.se, vesa.lehtovirta@ericsson.com, karl.norrman@ericsson.com +# RFC4564 || S. Govindan, Ed., H. Cheng, ZH. Yao, WH. Zhou, L. Yang || saravanan.govindan@sg.panasonic.com, hong.cheng@sg.panasonic.com, yaoth@huawei.com, zhouwenhui@chinamobile.com, lily.l.yang@intel.com +# RFC4565 || D. Loher, D. Nelson, O. Volinsky, B. Sarikaya || dplore@gmail.com, dnelson@enterasys.com, ovolinsky@colubris.com, sarikaya@ieee.org +# RFC4566 || M. Handley, V. Jacobson, C. Perkins || M.Handley@cs.ucl.ac.uk, van@packetdesign.com, csp@csperkins.org +# RFC4567 || J. Arkko, F. Lindholm, M. Naslund, K. Norrman, E. Carrara || jari.arkko@ericsson.com, fredrik.lindholm@ericsson.com, mats.naslund@ericsson.com, karl.norrman@ericsson.com, carrara@kth.se +# RFC4568 || F. Andreasen, M. Baugher, D. Wing || fandreas@cisco.com, mbaugher@cisco.com, dwing-ietf@fuggles.com +# RFC4569 || G. Camarillo || Gonzalo.Camarillo@ericsson.com +# RFC4570 || B. Quinn, R. Finlayson || rcq@boxnarrow.com, finlayson@live555.com +# RFC4571 || J. Lazzaro || lazzaro@cs.berkeley.edu +# RFC4572 || J. Lennox || lennox@cs.columbia.edu +# RFC4573 || R. Even, A. Lochbaum || roni.even@polycom.co.il, alochbaum@polycom.com +# RFC4574 || O. Levin, G. Camarillo || oritl@microsoft.com, Gonzalo.Camarillo@ericsson.com +# RFC4575 || J. Rosenberg, H. Schulzrinne, O. Levin, Ed. || jdrosen@cisco.com, schulzrinne@cs.columbia.edu, oritl@microsoft.com +# RFC4576 || E. Rosen, P. Psenak, P. Pillay-Esnault || erosen@cisco.com, ppsenak@cisco.com, ppe@cisco.com +# RFC4577 || E. Rosen, P. Psenak, P. Pillay-Esnault || erosen@cisco.com, ppsenak@cisco.com, ppe@cisco.com +# RFC4578 || M. Johnston, S. Venaas, Ed. || michael.johnston@intel.com, venaas@uninett.no +# RFC4579 || A. Johnston, O. Levin || alan@sipstation.com, oritl@microsoft.com +# RFC4580 || B. Volz || volz@cisco.com +# RFC4581 || M. Bagnulo, J. Arkko || marcelo@it.uc3m.es, jari.arkko@ericsson.com +# RFC4582 || G. Camarillo, J. Ott, K. Drage || Gonzalo.Camarillo@ericsson.com, jo@netlab.hut.fi, drage@lucent.com +# RFC4583 || G. Camarillo || Gonzalo.Camarillo@ericsson.com +# RFC4584 || S. Chakrabarti, E. Nordmark || samitac2@gmail.com, erik.nordmark@sun.com +# RFC4585 || J. Ott, S. Wenger, N. Sato, C. Burmeister, J. Rey || jo@acm.org, stewe@stewe.org, sato652@oki.com, carsten.burmeister@eu.panasonic.com, jose.rey@eu.panasonic.com +# RFC4586 || C. Burmeister, R. Hakenberg, A. Miyazaki, J. Ott, N. Sato, S. Fukunaga || carsten.burmeister@eu.panasonic.com, rolf.hakenberg@eu.panasonic.com, miyazaki.akihiro@jp.panasonic.com, jo@acm.org, sato652@oki.com, fukunaga444@oki.com +# RFC4587 || R. Even || roni.even@polycom.co.il +# RFC4588 || J. Rey, D. Leon, A. Miyazaki, V. Varsa, R. Hakenberg || jose.rey@eu.panasonic.com, davidleon123@yahoo.com, miyazaki.akihiro@jp.panasonic.com, viktor.varsa@nokia.com, rolf.hakenberg@eu.panasonic.com +# RFC4589 || H. Schulzrinne, H. Tschofenig || schulzrinne@cs.columbia.edu, Hannes.Tschofenig@siemens.com +# RFC4590 || B. Sterman, D. Sadolevsky, D. Schwartz, D. Williams, W. Beck || baruch@kayote.com, dscreat@dscreat.com, david@kayote.com, dwilli@cisco.com, beckw@t-systems.com +# RFC4591 || M. Townsley, G. Wilkie, S. Booth, S. Bryant, J. Lau || mark@townsley.net, gwilkie@cisco.com, jebooth@cisco.com, stbryant@cisco.com, jedlau@gmail.com +# RFC4592 || E. Lewis || ed.lewis@neustar.biz +# RFC4593 || A. Barbir, S. Murphy, Y. Yang || abbieb@nortel.com, sandy@sparta.com, yiya@cisco.com +# RFC4594 || J. Babiarz, K. Chan, F. Baker || babiarz@nortel.com, khchan@nortel.com, fred@cisco.com +# RFC4595 || F. Maino, D. Black || fmaino@cisco.com, black_david@emc.com +# RFC4596 || J. Rosenberg, P. Kyzivat || jdrosen@cisco.com, pkyzivat@cisco.com +# RFC4597 || R. Even, N. Ismail || roni.even@polycom.co.il, nismail@cisco.com +# RFC4598 || B. Link || bdl@dolby.com +# RFC4601 || B. Fenner, M. Handley, H. Holbrook, I. Kouvelas || fenner@research.att.com, M.Handley@cs.ucl.ac.uk, holbrook@arastra.com, kouvelas@cisco.com +# RFC4602 || T. Pusateri || pusateri@juniper.net +# RFC4603 || G. Zorn, G. Weber, R. Foltak || gwz@cisco.com, gdweber@cisco.com, rfoltak@cisco.com +# RFC4604 || H. Holbrook, B. Cain, B. Haberman || holbrook@cisco.com, bcain99@gmail.com, brian@innovationslab.net +# RFC4605 || B. Fenner, H. He, B. Haberman, H. Sandick || fenner@research.att.com, haixiang@nortelnetworks.com, brian@innovationslab.net, sandick@nc.rr.com +# RFC4606 || E. Mannie, D. Papadimitriou || eric.mannie@perceval.net, dimitri.papadimitriou@alcatel.be +# RFC4607 || H. Holbrook, B. Cain || holbrook@arastra.com, bcain99@gmail.com +# RFC4608 || D. Meyer, R. Rockell, G. Shepherd || dmm@1-4-5.net, rrockell@sprint.net, gjshep@gmail.com +# RFC4609 || P. Savola, R. Lehtonen, D. Meyer || psavola@funet.fi, rami.lehtonen@teliasonera.com, dmm@1-4-5.net +# RFC4610 || D. Farinacci, Y. Cai || dino@cisco.com, ycai@cisco.com +# RFC4611 || M. McBride, J. Meylor, D. Meyer || mcbride@cisco.com, jmeylor@cisco.com, dmm@1-4-5.net +# RFC4612 || P. Jones, H. Tamura || paulej@packetizer.com, tamura@cs.ricoh.co.jp +# RFC4613 || P. Frojdh, U. Lindgren, M. Westerlund || per.frojdh@ericsson.com, ulf.a.lindgren@ericsson.com, magnus.westerlund@ericsson.com +# RFC4614 || M. Duke, R. Braden, W. Eddy, E. Blanton || martin.duke@boeing.com, braden@isi.edu, weddy@grc.nasa.gov, eblanton@cs.purdue.edu +# RFC4615 || J. Song, R. Poovendran, J. Lee, T. Iwata || junhyuk.song@gmail.com, radha@ee.washington.edu, jicheol.lee@samsung.com, iwata@cse.nagoya-u.ac.jp +# RFC4616 || K. Zeilenga, Ed. || Kurt@OpenLDAP.org +# RFC4617 || J. Kornijenko || j.kornienko@abcsoftware.lv +# RFC4618 || L. Martini, E. Rosen, G. Heron, A. Malis || lmartini@cisco.com, erosen@cisco.com, giles.heron@tellabs.com, Andy.Malis@tellabs.com +# RFC4619 || L. Martini, Ed., C. Kawa, Ed., A. Malis, Ed. || lmartini@cisco.com, claude.kawa@oz.com, Andy.Malis@tellabs.com +# RFC4620 || M. Crawford, B. Haberman, Ed. || crawdad@fnal.gov, brian@innovationslab.net +# RFC4621 || T. Kivinen, H. Tschofenig || kivinen@safenet-inc.com, Hannes.Tschofenig@siemens.com +# RFC4622 || P. Saint-Andre || ietf@stpeter.im +# RFC4623 || A. Malis, M. Townsley || Andy.Malis@tellabs.com, mark@townsley.net +# RFC4624 || B. Fenner, D. Thaler || fenner@research.att.com, dthaler@microsoft.com +# RFC4625 || C. DeSanti, K. McCloghrie, S. Kode, S. Gai || cds@cisco.com, srinikode@yahoo.com, kzm@cisco.com, none +# RFC4626 || C. DeSanti, V. Gaonkar, K. McCloghrie, S. Gai || cds@cisco.com, vgaonkar@cisco.com, kzm@cisco.com, none +# RFC4627 || D. Crockford || douglas@crockford.com +# RFC4628 || R. Even || roni.even@polycom.co.il +# RFC4629 || J. Ott, C. Bormann, G. Sullivan, S. Wenger, R. Even, Ed. || jo@netlab.tkk.fi, cabo@tzi.org, garysull@microsoft.com, stewe@stewe.org, roni.even@polycom.co.il +# RFC4630 || R. Housley, S. Santesson || housley@vigilsec.com, stefans@microsoft.com +# RFC4631 || M. Dubuc, T. Nadeau, J. Lang, E. McGinnis, A. Farrel || dubuc.consulting@sympatico.ca, tnadeau@cisco.com, jplang@ieee.org, emcginnis@hammerheadsystems.com, adrian@olddog.co.uk +# RFC4632 || V. Fuller, T. Li || vaf@cisco.com, tli@tropos.com +# RFC4633 || S. Hartman || hartmans-ietf@mit.edu +# RFC4634 || D. Eastlake 3rd, T. Hansen || donald.eastlake@motorola.com, tony+shs@maillennium.att.com +# RFC4635 || D. Eastlake 3rd || Donald.Eastlake@motorola.com +# RFC4636 || C. Perkins || charles.perkins@nokia.com +# RFC4637 || || +# RFC4638 || P. Arberg, D. Kourkouzelis, M. Duckett, T. Anschutz, J. Moisand || parberg@redback.com, diamondk@redback.com, mike.duckett@bellsouth.com, tom.anschutz@bellsouth.com, jmoisand@juniper.net +# RFC4639 || R. Woundy, K. Marez || richard_woundy@cable.comcast.com, kevin.marez@motorola.com +# RFC4640 || A. Patel, Ed., G. Giaretta, Ed. || alpesh@cisco.com, gerardo.giaretta@telecomitalia.it +# RFC4641 || O. Kolkman, R. Gieben || olaf@nlnetlabs.nl, miek@miek.nl +# RFC4642 || K. Murchison, J. Vinocur, C. Newman || murch@andrew.cmu.edu, vinocur@cs.cornell.edu, Chris.Newman@sun.com +# RFC4643 || J. Vinocur, K. Murchison || vinocur@cs.cornell.edu, murch@andrew.cmu.edu +# RFC4644 || J. Vinocur, K. Murchison || vinocur@cs.cornell.edu, murch@andrew.cmu.edu +# RFC4645 || D. Ewell || dewell@adelphia.net +# RFC4646 || A. Phillips, M. Davis || addison@inter-locale.com, mark.davis@macchiato.com +# RFC4647 || A. Phillips, M. Davis || addison@inter-locale.com, mark.davis@macchiato.com +# RFC4648 || S. Josefsson || simon@josefsson.org +# RFC4649 || B. Volz || volz@cisco.com +# RFC4650 || M. Euchner || martin_euchner@hotmail.com +# RFC4651 || C. Vogt, J. Arkko || chvogt@tm.uka.de, jari.arkko@ericsson.com +# RFC4652 || D. Papadimitriou, Ed., L.Ong, J. Sadler, S. Shew, D. Ward || dimitri.papadimitriou@alcatel.be, lyong@ciena.com, jonathan.sadler@tellabs.com, sdshew@nortel.com, dward@cisco.com +# RFC4653 || S. Bhandarkar, A. L. N. Reddy, M. Allman, E. Blanton || sumitha@tamu.edu, reddy@ee.tamu.edu, mallman@icir.org, eblanton@cs.purdue.edu +# RFC4654 || J. Widmer, M. Handley || widmer@acm.org, m.handley@cs.ucl.ac.uk +# RFC4655 || A. Farrel, J.-P. Vasseur, J. Ash || adrian@olddog.co.uk, jpv@cisco.com, gash@att.com +# RFC4656 || S. Shalunov, B. Teitelbaum, A. Karp, J. Boote, M. Zekauskas || shalunov@internet2.edu, ben@internet2.edu, akarp@cs.wisc.edu, boote@internet2.edu, matt@internet2.edu +# RFC4657 || J. Ash, Ed., J.L. Le Roux, Ed. || gash@att.com, jeanlouis.leroux@orange-ft.com +# RFC4659 || J. De Clercq, D. Ooms, M. Carugi, F. Le Faucheur || jeremy.de_clercq@alcatel.be, dirk@onesparrow.com, marco.carugi@nortel.com, flefauch@cisco.com +# RFC4660 || H. Khartabil, E. Leppanen, M. Lonnfors, J. Costa-Requena || hisham.khartabil@telio.no, eva-maria.leppanen@nokia.com, mikko.lonnfors@nokia.com, jose.costa-requena@nokia.com +# RFC4661 || H. Khartabil, E. Leppanen, M. Lonnfors, J. Costa-Requena || hisham.khartabil@telio.no, eva-maria.leppanen@nokia.com, mikko.lonnfors@nokia.com, jose.costa-requena@nokia.com +# RFC4662 || A. B. Roach, B. Campbell, J. Rosenberg || adam@estacado.net, ben@estacado.net, jdrosen@cisco.com +# RFC4663 || D. Harrington || dbharrington@comcast.net +# RFC4664 || L. Andersson, Ed., E. Rosen, Ed. || loa@pi.se, erosen@cisco.com +# RFC4665 || W. Augustyn, Ed., Y. Serbest, Ed. || waldemar@wdmsys.com, yetik_serbest@labs.att.com +# RFC4666 || K. Morneault, Ed., J. Pastor-Balbas, Ed. || kmorneau@cisco.com, j.javier.pastor@ericsson.com +# RFC4667 || W. Luo || luo@cisco.com +# RFC4668 || D. Nelson || dnelson@enterasys.com +# RFC4669 || D. Nelson || dnelson@enterasys.com +# RFC4670 || D. Nelson || dnelson@enterasys.com +# RFC4671 || D. Nelson || dnelson@enterasys.com +# RFC4672 || S. De Cnodder, N. Jonnala, M. Chiba || stefaan.de_cnodder@alcatel.be, njonnala@cisco.com, mchiba@cisco.com +# RFC4673 || S. De Cnodder, N. Jonnala, M. Chiba || stefaan.de_cnodder@alcatel.be, njonnala@cisco.com, mchiba@cisco.com +# RFC4674 || J.L. Le Roux, Ed. || jeanlouis.leroux@francetelecom.com +# RFC4675 || P. Congdon, M. Sanchez, B. Aboba || paul.congdon@hp.com, mauricio.sanchez@hp.com, bernarda@microsoft.com +# RFC4676 || H. Schulzrinne || hgs+geopriv@cs.columbia.edu +# RFC4677 || P. Hoffman, S. Harris || paul.hoffman@vpnc.org, srh@umich.edu +# RFC4678 || A. Bivens || jbivens@us.ibm.com +# RFC4679 || V. Mammoliti, G. Zorn, P. Arberg, R. Rennison || vince@cisco.com, gwz@cisco.com, parberg@redback.com, robert.rennison@ecitele.com +# RFC4680 || S. Santesson || stefans@microsoft.com +# RFC4681 || S. Santesson, A. Medvinsky, J. Ball || stefans@microsoft.com, arimed@microsoft.com, joshball@microsoft.com +# RFC4682 || E. Nechamkin, J-F. Mule || enechamkin@broadcom.com, jf.mule@cablelabs.com +# RFC4683 || J. Park, J. Lee, H.. Lee, S. Park, T. Polk || khopri@kisa.or.kr, jilee@kisa.or.kr, hslee@kisa.or.kr, sjpark@bcqre.com, tim.polk@nist.gov +# RFC4684 || P. Marques, R. Bonica, L. Fang, L. Martini, R. Raszuk, K. Patel, J. Guichard || roque@juniper.net, rbonica@juniper.net, luyuanfang@att.com, lmartini@cisco.com, rraszuk@cisco.com, keyupate@cisco.com, jguichar@cisco.com +# RFC4685 || J. Snell || jasnell@gmail.com +# RFC4686 || J. Fenton || fenton@bluepopcorn.net +# RFC4687 || S. Yasukawa, A. Farrel, D. King, T. Nadeau || s.yasukawa@hco.ntt.co.jp, adrian@olddog.co.uk, daniel.king@aria-networks.com, tnadeau@cisco.com +# RFC4688 || S. Rushing || srushing@inmedius.com +# RFC4689 || S. Poretsky, J. Perser, S. Erramilli, S. Khurana || sporetsky@reefpoint.com, jerry@perser.org, shobha@research.telcordia.com, skhurana@motorola.com +# RFC4690 || J. Klensin, P. Faltstrom, C. Karp, IAB || john-ietf@jck.com, paf@cisco.com, ck@nic.museum, iab@iab.org +# RFC4691 || L. Andersson, Ed. || loa@pi.se +# RFC4692 || G. Huston || gih@apnic.net +# RFC4693 || H. Alvestrand || harald@alvestrand.no +# RFC4694 || J. Yu || james.yu@neustar.biz +# RFC4695 || J. Lazzaro, J. Wawrzynek || lazzaro@cs.berkeley.edu, johnw@cs.berkeley.edu +# RFC4696 || J. Lazzaro, J. Wawrzynek || lazzaro@cs.berkeley.edu, johnw@cs.berkeley.edu +# RFC4697 || M. Larson, P. Barber || mlarson@verisign.com, pbarber@verisign.com +# RFC4698 || E. Gunduz, A. Newton, S. Kerr || e.gunduz@computer.org, andy@hxr.us, shane@time-travellers.org +# RFC4701 || M. Stapp, T. Lemon, A. Gustafsson || mjs@cisco.com, mellon@nominum.com, gson@araneus.fi +# RFC4702 || M. Stapp, B. Volz, Y. Rekhter || mjs@cisco.com, volz@cisco.com, yakov@juniper.net +# RFC4703 || M. Stapp, B. Volz || mjs@cisco.com, volz@cisco.com +# RFC4704 || B. Volz || volz@cisco.com +# RFC4705 || R. Housley, A. Corry || housley@vigilsec.com, publications@gigabeam.com +# RFC4706 || M. Morgenstern, M. Dodge, S. Baillie, U. Bonollo || moti.Morgenstern@ecitele.com, mbdodge@ieee.org, scott.baillie@nec.com.au, umberto.bonollo@nec.com.au +# RFC4707 || P. Grau, V. Heinau, H. Schlichting, R. Schuettler || nas@fu-berlin.de, nas@fu-berlin.de, nas@fu-berlin.de, nas@fu-berlin.de +# RFC4708 || A. Miller || ak.miller@auckland.ac.nz +# RFC4709 || J. Reschke || julian.reschke@greenbytes.de +# RFC4710 || A. Siddiqui, D. Romascanu, E. Golovinsky || anwars@avaya.com, dromasca@gmail.com , gene@alertlogic.net +# RFC4711 || A. Siddiqui, D. Romascanu, E. Golovinsky || anwars@avaya.com, dromasca@gmail.com , gene@alertlogic.net +# RFC4712 || A. Siddiqui, D. Romascanu, E. Golovinsky, M. Rahman,Y. Kim || anwars@avaya.com, dromasca@gmail.com , gene@alertlogic.net, none, ybkim@broadcom.com +# RFC4713 || X. Lee, W. Mao, E. Chen, N. Hsu, J. Klensin || lee@cnnic.cn, mao@cnnic.cn, erin@twnic.net.tw, snw@twnic.net.tw, john+ietf@jck.com +# RFC4714 || A. Mankin, S. Hayes || mankin@psg.com, stephen.hayes@ericsson.com +# RFC4715 || M. Munakata, S. Schubert, T. Ohba || munakata.mayumi@lab.ntt.co.jp, shida@ntt-at.com, ohba.takumi@lab.ntt.co.jp +# RFC4716 || J. Galbraith, R. Thayer || galb@vandyke.com, rodney@canola-jones.com +# RFC4717 || L. Martini, J. Jayakumar, M. Bocci, N. El-Aawar, J. Brayley, G. Koleyni || lmartini@cisco.com, jjayakum@cisco.com, matthew.bocci@alcatel.co.uk, nna@level3.net, jeremy.brayley@ecitele.com, ghassem@nortelnetworks.com +# RFC4718 || P. Eronen, P. Hoffman || pe@iki.fi, paul.hoffman@vpnc.org +# RFC4719 || R. Aggarwal, Ed., M. Townsley, Ed., M. Dos Santos, Ed. || rahul@juniper.net, mark@townsley.net, mariados@cisco.com +# RFC4720 || A. Malis, D. Allan, N. Del Regno || Andy.Malis@tellabs.com, dallan@nortelnetworks.com, nick.delregno@mci.com +# RFC4721 || C. Perkins, P. Calhoun, J. Bharatia || charles.perkins@nokia.com, pcalhoun@cisco.com, jayshree@nortel.com +# RFC4722 || J. Van Dyke, E. Burger, Ed., A. Spitzer || jvandyke@cantata.com, eburger@cantata.com, woof@pingtel.com +# RFC4723 || T. Kosonen, T. White || timo.kosonen@nokia.com, twhite@midi.org +# RFC4724 || S. Sangli, E. Chen, R. Fernando, J. Scudder, Y. Rekhter || rsrihari@cisco.com, enkechen@cisco.com, rex@juniper.net, jgs@juniper.net, yakov@juniper.net +# RFC4725 || A. Mayrhofer, B. Hoeneisen || alexander.mayrhofer@enum.at, b.hoeneisen@ieee.org +# RFC4726 || A. Farrel, J.-P. Vasseur, A. Ayyangar || adrian@olddog.co.uk, jpv@cisco.com, arthi@nuovasystems.com +# RFC4727 || B. Fenner || fenner@research.att.com +# RFC4728 || D. Johnson, Y. Hu, D. Maltz || dbj@cs.rice.edu, yihchun@uiuc.edu, dmaltz@cs.cmu.edu +# RFC4729 || M. Abel || TPM@nfc-forum.org +# RFC4730 || E. Burger, M. Dolly || eburger@cantata.com, mdolly@att.com +# RFC4731 || A. Melnikov, D. Cridland || Alexey.Melnikov@isode.com, dave.cridland@inventuresystems.co.uk +# RFC4732 || M. Handley, Ed., E. Rescorla, Ed., IAB || M.Handley@cs.ucl.ac.uk, ekr@networkresonance.com, iab@ietf.org +# RFC4733 || H. Schulzrinne, T. Taylor || schulzrinne@cs.columbia.edu, tom.taylor.stds@gmail.com +# RFC4734 || H. Schulzrinne, T. Taylor || schulzrinne@cs.columbia.edu, tom.taylor.stds@gmail.com +# RFC4735 || T. Taylor || tom.taylor.stds@gmail.com +# RFC4736 || JP. Vasseur, Ed., Y. Ikejiri, R. Zhang || jpv@cisco.com, y.ikejiri@ntt.com, raymond_zhang@bt.infonet.com +# RFC4737 || A. Morton, L. Ciavattone, G. Ramachandran, S. Shalunov, J. Perser || acmorton@att.com, lencia@att.com, gomathi@att.com, shalunov@internet2.edu, jperser@veriwave.com +# RFC4738 || D. Ignjatic, L. Dondeti, F. Audet, P. Lin || dignjatic@polycom.com, dondeti@qualcomm.com, audet@nortel.com, linping@nortel.com +# RFC4739 || P. Eronen, J. Korhonen || pe@iki.fi, jouni.korhonen@teliasonera.com +# RFC4740 || M. Garcia-Martin, Ed., M. Belinchon, M. Pallares-Lopez, C. Canales-Valenzuela, K. Tammi || miguel.an.garcia@nokia.com, maria.carmen.belinchon@ericsson.com, miguel-angel.pallares@ericsson.com, carolina.canales@ericsson.com, kalle.tammi@nokia.com +# RFC4741 || R. Enns, Ed. || rpe@juniper.net +# RFC4742 || M. Wasserman, T. Goddard || margaret@thingmagic.com, ted.goddard@icesoft.com +# RFC4743 || T. Goddard || ted.goddard@icesoft.com +# RFC4744 || E. Lear, K. Crozier || lear@cisco.com, ken.crozier@gmail.com +# RFC4745 || H. Schulzrinne, H. Tschofenig, J. Morris, J. Cuellar, J. Polk, J. Rosenberg || schulzrinne@cs.columbia.edu, Hannes.Tschofenig@siemens.com, jmorris@cdt.org, Jorge.Cuellar@siemens.com, jmpolk@cisco.com, jdrosen@cisco.com +# RFC4746 || T. Clancy, W. Arbaugh || clancy@ltsnet.net, waa@cs.umd.edu +# RFC4747 || S. Kipp, G. Ramkumar, K. McCloghrie || scott.kipp@mcdata.com, gramkumar@stanfordalumni.org, kzm@cisco.com +# RFC4748 || S. Bradner, Ed. || sob@harvard.edu +# RFC4749 || A. Sollaud || aurelien.sollaud@orange-ft.com +# RFC4750 || D. Joyal, Ed., P. Galecki, Ed., S. Giacalone, Ed., R. Coltun, F. Baker || djoyal@nortel.com, pgalecki@airvana.com, spencer.giacalone@gmail.com, fred@cisco.com +# RFC4752 || A. Melnikov, Ed. || Alexey.Melnikov@isode.com +# RFC4753 || D. Fu, J. Solinas || defu@orion.ncsc.mil, jasolin@orion.ncsc.mil +# RFC4754 || D. Fu, J. Solinas || defu@orion.ncsc.mil, jasolin@orion.ncsc.mil +# RFC4755 || V. Kashyap || vivk@us.ibm.com +# RFC4756 || A. Li || adamli@hyervision.com +# RFC4757 || K. Jaganathan, L. Zhu, J. Brezak || karthikj@microsoft.com, lzhu@microsoft.com, jbrezak@microsoft.com +# RFC4758 || M. Nystroem || magnus@rsasecurity.com +# RFC4759 || R. Stastny, R. Shockey, L. Conroy || Richard.stastny@oefeg.at, richard.shockey@neustar.biz, lconroy@insensate.co.uk +# RFC4760 || T. Bates, R. Chandra, D. Katz, Y. Rekhter || tbates@cisco.com, rchandra@sonoasystems.com, dkatz@juniper.com, yakov@juniper.com +# RFC4761 || K. Kompella, Ed., Y. Rekhter, Ed. || kireeti@juniper.net, yakov@juniper.net +# RFC4762 || M. Lasserre, Ed., V. Kompella, Ed. || mlasserre@alcatel-lucent.com, vach.kompella@alcatel-lucent.com +# RFC4763 || M. Vanderveen, H. Soliman || mvandervn@yahoo.com, solimanhs@gmail.com +# RFC4764 || F. Bersani, H. Tschofenig || bersani_florent@yahoo.fr, Hannes.Tschofenig@siemens.com +# RFC4765 || H. Debar, D. Curry, B. Feinstein || herve.debar@orange-ftgroup.com, david_a_curry@glic.com, feinstein@acm.org +# RFC4766 || M. Wood, M. Erlinger || mark1@iss.net, mike@cs.hmc.edu +# RFC4767 || B. Feinstein, G. Matthews || bfeinstein@acm.org, gmatthew@nas.nasa.gov +# RFC4768 || S. Hartman || hartmans-ietf@mit.edu +# RFC4769 || J. Livingood, R. Shockey || jason_livingood@cable.comcast.com, richard.shockey@neustar.biz +# RFC4770 || C. Jennings, J. Reschke, Ed. || fluffy@cisco.com, julian.reschke@greenbytes.de +# RFC4771 || V. Lehtovirta, M. Naslund, K. Norrman || vesa.lehtovirta@ericsson.com, mats.naslund@ericsson.com, karl.norrman@ericsson.com +# RFC4772 || S. Kelly || scott@hyperthought.com +# RFC4773 || G. Huston || gih@apnic.net +# RFC4774 || S. Floyd || floyd@icir.org +# RFC4775 || S. Bradner, B. Carpenter, Ed., T. Narten || sob@harvard.edu, brc@zurich.ibm.com, narten@us.ibm.com +# RFC4776 || H. Schulzrinne || hgs+geopriv@cs.columbia.edu +# RFC4777 || T. Murphy Jr., P. Rieth, J. Stevens || murphyte@us.ibm.com, rieth@us.ibm.com, jssteven@us.ibm.com +# RFC4778 || M. Kaeo || merike@doubleshotsecurity.com +# RFC4779 || S. Asadullah, A. Ahmed, C. Popoviciu, P. Savola, J. Palet || sasad@cisco.com, adahmed@cisco.com, cpopovic@cisco.com, psavola@funet.fi, jordi.palet@consulintel.es +# RFC4780 || K. Lingle, J-F. Mule, J. Maeng, D. Walker || klingle@cisco.com, jf.mule@cablelabs.com, jmaeng@austin.rr.com, drwalker@rogers.com +# RFC4781 || Y. Rekhter, R. Aggarwal || yakov@juniper.net, rahul@juniper.net +# RFC4782 || S. Floyd, M. Allman, A. Jain, P. Sarolahti || floyd@icir.org, mallman@icir.org, a.jain@f5.com, pasi.sarolahti@iki.fi +# RFC4783 || L. Berger, Ed. || lberger@labn.net +# RFC4784 || C. Carroll, F. Quick || Christopher.Carroll@ropesgray.com, fquick@qualcomm.com +# RFC4785 || U. Blumenthal, P. Goel || urimobile@optonline.net, Purushottam.Goel@intel.com +# RFC4786 || J. Abley, K. Lindqvist || jabley@ca.afilias.info, kurtis@kurtis.pp.se +# RFC4787 || F. Audet, Ed., C. Jennings || audet@nortel.com, fluffy@cisco.com +# RFC4788 || Q. Xie, R. Kapoor || Qiaobing.Xie@Motorola.com, rkapoor@qualcomm.com +# RFC4789 || J. Schoenwaelder, T. Jeffree || j.schoenwaelder@iu-bremen.de, tony@jeffree.co.uk +# RFC4790 || C. Newman, M. Duerst, A. Gulbrandsen || chris.newman@sun.com, duerst@it.aoyama.ac.jp, arnt@oryx.com +# RFC4791 || C. Daboo, B. Desruisseaux, L. Dusseault || cyrus@daboo.name, bernard.desruisseaux@oracle.com, lisa.dusseault@gmail.com +# RFC4792 || S. Legg || steven.legg@eb2bcom.com +# RFC4793 || M. Nystroem || magnus@rsasecurity.com +# RFC4794 || B. Fenner || fenner@research.att.com +# RFC4795 || B. Aboba, D. Thaler, L. Esibov || bernarda@microsoft.com, dthaler@microsoft.com, levone@microsoft.com +# RFC4796 || J. Hautakorpi, G. Camarillo || Jani.Hautakorpi@ericsson.com, Gonzalo.Camarillo@ericsson.com +# RFC4797 || Y. Rekhter, R. Bonica, E. Rosen || yakov@juniper.net, rbonica@juniper.net, erosen@cisco.com +# RFC4798 || J. De Clercq, D. Ooms, S. Prevost, F. Le Faucheur || jeremy.de_clercq@alcatel-lucent.be, dirk@onesparrow.com, stuart.prevost@bt.com, flefauch@cisco.com +# RFC4801 || T. Nadeau, Ed., A. Farrel, Ed. || tnadeau@cisco.com, adrian@olddog.co.uk +# RFC4802 || T. Nadeau, Ed., A. Farrel, Ed. || tnadeau@cisco.com, adrian@olddog.co.uk +# RFC4803 || T. Nadeau, Ed., A. Farrel, Ed. || tnadeau@cisco.com, adrian@olddog.co.uk +# RFC4804 || F. Le Faucheur, Ed. || flefauch@cisco.com +# RFC4805 || O. Nicklass, Ed. || orly_n@rad.com +# RFC4806 || M. Myers, H. Tschofenig || mmyers@fastq.com, Hannes.Tschofenig@siemens.com +# RFC4807 || M. Baer, R. Charlet, W. Hardaker, R. Story, C. Wang || baerm@tislabs.com, rcharlet@alumni.calpoly.edu, hardaker@tislabs.com, rstory@ipsp.revelstone.com, cliffwangmail@yahoo.com +# RFC4808 || S. Bellovin || bellovin@acm.org +# RFC4809 || C. Bonatti, Ed., S. Turner, Ed., G. Lebovitz, Ed. || Bonattic@ieca.com, Turners@ieca.com, gregory.ietf@gmail.com +# RFC4810 || C. Wallace, U. Pordesch, R. Brandner || cwallace@cygnacom.com, ulrich.pordesch@zv.fraunhofer.de, ralf.brandner@intercomponentware.com +# RFC4811 || L. Nguyen, A. Roy, A. Zinin || lhnguyen@cisco.com, akr@cisco.com, alex.zinin@alcatel-lucent.com +# RFC4812 || L. Nguyen, A. Roy, A. Zinin || lhnguyen@cisco.com, akr@cisco.com, alex.zinin@alcatel-lucent.com +# RFC4813 || B. Friedman, L. Nguyen, A. Roy, D. Yeung, A. Zinin || friedman@cisco.com, lhnguyen@cisco.com, akr@cisco.com, myeung@cisco.com, alex.zinin@alcatel-lucent.com +# RFC4814 || D. Newman, T. Player || dnewman@networktest.com, timmons.player@spirent.com +# RFC4815 || L-E. Jonsson, K. Sandlund, G. Pelletier, P. Kremer || lars-erik.jonsson@ericsson.com, kristofer.sandlund@ericsson.com, ghyslain.pelletier@ericsson.com, peter.kremer@ericsson.com +# RFC4816 || A. Malis, L. Martini, J. Brayley, T. Walsh || andrew.g.malis@verizon.com, lmartini@cisco.com, jeremy.brayley@ecitele.com, twalsh@juniper.net +# RFC4817 || M. Townsley, C. Pignataro, S. Wainner, T. Seely, J. Young || mark@townsley.net, cpignata@cisco.com, swainner@cisco.com, tseely@sprint.net, young@jsyoung.net +# RFC4818 || J. Salowey, R. Droms || jsalowey@cisco.com, rdroms@cisco.com +# RFC4819 || J. Galbraith, J. Van Dyke, J. Bright || galb@vandyke.com, jpv@vandyke.com, jon@siliconcircus.com +# RFC4820 || M. Tuexen, R. Stewart, P. Lei || tuexen@fh-muenster.de, randall@lakerest.net, peterlei@cisco.com +# RFC4821 || M. Mathis, J. Heffner || mathis@psc.edu, jheffner@psc.edu +# RFC4822 || R. Atkinson, M. Fanto || rja@extremenetworks.com, mattjf@umd.edu +# RFC4823 || T. Harding, R. Scott || tharding@us.axway.com, rscott@us.axway.com +# RFC4824 || J. Hofmueller, Ed., A. Bachmann, Ed., IO. zmoelnig, Ed. || ip-sfs@mur.at, ip-sfs@mur.at, ip-sfs@mur.at +# RFC4825 || J. Rosenberg || jdrosen@cisco.com +# RFC4826 || J. Rosenberg || jdrosen@cisco.com +# RFC4827 || M. Isomaki, E. Leppanen || markus.isomaki@nokia.com, eva-maria.leppanen@nokia.com +# RFC4828 || S. Floyd, E. Kohler || floyd@icir.org, kohler@cs.ucla.edu +# RFC4829 || J. de Oliveira, Ed., JP. Vasseur, Ed., L. Chen, C. Scoglio || jau@ece.drexel.edu, jpv@cisco.com, leonardo.c.chen@verizon.com, caterina@eece.ksu.edu +# RFC4830 || J. Kempf, Ed. || kempf@docomolabs-usa.com +# RFC4831 || J. Kempf, Ed. || kempf@docomolabs-usa.com +# RFC4832 || C. Vogt, J. Kempf || chvogt@tm.uka.de, kempf@docomolabs-usa.com +# RFC4833 || E. Lear, P. Eggert || lear@cisco.com, eggert@cs.ucla.edu +# RFC4834 || T. Morin, Ed. || thomas.morin@orange-ftgroup.com +# RFC4835 || V. Manral || vishwas@ipinfusion.com +# RFC4836 || E. Beili || edward.beili@actelis.com +# RFC4837 || L. Khermosh || lior_khermosh@pmc-sierra.com +# RFC4838 || V. Cerf, S. Burleigh, A. Hooke, L. Torgerson, R. Durst, K. Scott, K. Fall, H. Weiss || vint@google.com, Scott.Burleigh@jpl.nasa.gov, Adrian.Hooke@jpl.nasa.gov, ltorgerson@jpl.nasa.gov, durst@mitre.org, kscott@mitre.org, kfall@intel.com, howard.weiss@sparta.com +# RFC4839 || G. Conboy, J. Rivlin, J. Ferraiolo || gc@ebooktechnologies.com, john@ebooktechnologies.com, jferrai@us.ibm.com +# RFC4840 || B. Aboba, Ed., E. Davies, D. Thaler || bernarda@microsoft.com, elwynd@dial.pipex.com, dthaler@microsoft.com +# RFC4841 || C. Heard, Ed. || heard@pobox.com +# RFC4842 || A. Malis, P. Pate, R. Cohen, Ed., D. Zelig || andrew.g.malis@verizon.com, prayson.pate@overturenetworks.com, ronc@resolutenetworks.com, davidz@corrigent.com +# RFC4843 || P. Nikander, J. Laganier, F. Dupont || pekka.nikander@nomadiclab.com, julien.ietf@laposte.net, Francis.Dupont@fdupont.fr +# RFC4844 || L. Daigle, Ed., Internet Architecture Board || leslie@thinkingcat.com, iab@iab.org +# RFC4845 || L. Daigle, Ed., Internet Architecture Board || leslie@thinkingcat.com, iab@iab.org +# RFC4846 || J. Klensin, Ed., D. Thaler, Ed. || john-ietf@jck.com, dthaler@microsoft.com +# RFC4847 || T. Takeda, Ed. || takeda.tomonori@lab.ntt.co.jp +# RFC4848 || L. Daigle || leslie@thinkingcat.com +# RFC4849 || P. Congdon, M. Sanchez, B. Aboba || paul.congdon@hp.com, mauricio.sanchez@hp.com, bernarda@microsoft.com +# RFC4850 || D. Wysochanski || wysochanski@pobox.com +# RFC4851 || N. Cam-Winget, D. McGrew, J. Salowey, H. Zhou || ncamwing@cisco.com, mcgrew@cisco.com, jsalowey@cisco.com, hzhou@cisco.com +# RFC4852 || J. Bound, Y. Pouffary, S. Klynsma, T. Chown, D. Green || jim.bound@hp.com, Yanick.pouffary@hp.com, tjc@ecs.soton.ac.uk, green@commandinformation.com, sklynsma@mitre.org +# RFC4853 || R. Housley || housley@vigilsec.com +# RFC4854 || P. Saint-Andre || ietf@stpeter.im +# RFC4855 || S. Casner || casner@acm.org +# RFC4856 || S. Casner || casner@acm.org +# RFC4857 || E. Fogelstroem, A. Jonsson, C. Perkins || eva.fogelstrom@ericsson.com, annika.jonsson@ericsson.com, charles.perkins@nsn.com +# RFC4858 || H. Levkowetz, D. Meyer, L. Eggert, A. Mankin || henrik@levkowetz.com, dmm@1-4-5.net, lars.eggert@nokia.com, mankin@psg.com +# RFC4859 || A. Farrel || adrian@olddog.co.uk +# RFC4860 || F. Le Faucheur, B. Davie, P. Bose, C. Christou, M. Davenport || flefauch@cisco.com, bds@cisco.com, pratik.bose@lmco.com, christou_chris@bah.com, davenport_michael@bah.com +# RFC4861 || T. Narten, E. Nordmark, W. Simpson, H. Soliman || narten@us.ibm.com, erik.nordmark@sun.com, william.allen.simpson@gmail.com, hesham@elevatemobile.com +# RFC4862 || S. Thomson, T. Narten, T. Jinmei || sethomso@cisco.com, narten@us.ibm.com, jinmei@isl.rdc.toshiba.co.jp +# RFC4863 || L. Martini, G. Swallow || lmartini@cisco.com, swallow@cisco.com +# RFC4864 || G. Van de Velde, T. Hain, R. Droms, B. Carpenter, E. Klein || gunter@cisco.com, alh-ietf@tndh.net, rdroms@cisco.com, brc@zurich.ibm.com, ericlklein.ipv6@gmail.com +# RFC4865 || G. White, G. Vaudreuil || g.a.white@comcast.net, GregV@ieee.org +# RFC4866 || J. Arkko, C. Vogt, W. Haddad || jari.arkko@ericsson.com, chvogt@tm.uka.de, wassim.haddad@ericsson.com +# RFC4867 || J. Sjoberg, M. Westerlund, A. Lakaniemi, Q. Xie || Johan.Sjoberg@ericsson.com, Magnus.Westerlund@ericsson.com, ari.lakaniemi@nokia.com, Qiaobing.Xie@motorola.com +# RFC4868 || S. Kelly, S. Frankel || scott@hyperthought.com, sheila.frankel@nist.gov +# RFC4869 || L. Law, J. Solinas || lelaw@orion.ncsc.mil, jasolin@orion.ncsc.mil +# RFC4870 || M. Delany || markd+domainkeys@yahoo-inc.com +# RFC4871 || E. Allman, J. Callas, M. Delany, M. Libbey, J. Fenton, M. Thomas || eric+dkim@sendmail.org, jon@pgp.com, markd+dkim@yahoo-inc.com, mlibbeymail-mailsig@yahoo.com, fenton@bluepopcorn.net, mat@cisco.com +# RFC4872 || J.P. Lang, Ed., Y. Rekhter, Ed., D. Papadimitriou, Ed. || jplang@ieee.org, yakov@juniper.net, dimitri.papadimitriou@alcatel-lucent.be +# RFC4873 || L. Berger, I. Bryskin, D. Papadimitriou, A. Farrel || lberger@labn.net, IBryskin@advaoptical.com, dimitri.papadimitriou@alcatel-lucent.be, adrian@olddog.co.uk +# RFC4874 || CY. Lee, A. Farrel, S. De Cnodder || c.yin.lee@gmail.com, adrian@olddog.co.uk, stefaan.de_cnodder@alcatel-lucent.be +# RFC4875 || R. Aggarwal, Ed., D. Papadimitriou, Ed., S. Yasukawa, Ed. || rahul@juniper.net, yasukawa.seisho@lab.ntt.co.jp, Dimitri.Papadimitriou@alcatel-lucent.be +# RFC4876 || B. Neal-Joslin, Ed., L. Howard, M. Ansari || bob_joslin@hp.com, lukeh@padl.com, morteza@infoblox.com +# RFC4877 || V. Devarapalli, F. Dupont || vijay.devarapalli@azairenet.com, Francis.Dupont@fdupont.fr +# RFC4878 || M. Squire || msquire@hatterasnetworks.com +# RFC4879 || T. Narten || narten@us.ibm.com +# RFC4880 || J. Callas, L. Donnerhacke, H. Finney, D. Shaw, R. Thayer || jon@callas.org, lutz@iks-jena.de, hal@finney.org, dshaw@jabberwocky.com, rodney@canola-jones.com +# RFC4881 || K. El Malki, Ed. || karim@athonet.com +# RFC4882 || R. Koodli || rajeev.koodli@nokia.com +# RFC4883 || G. Feher, K. Nemeth, A. Korn, I. Cselenyi || Gabor.Feher@tmit.bme.hu, Krisztian.Nemeth@tmit.bme.hu, Andras.Korn@tmit.bme.hu, Istvan.Cselenyi@teliasonera.com +# RFC4884 || R. Bonica, D. Gan, D. Tappan, C. Pignataro || rbonica@juniper.net, derhwagan@yahoo.com, Dan.Tappan@gmail.com, cpignata@cisco.com +# RFC4885 || T. Ernst, H-Y. Lach || thierry.ernst@inria.fr, hong-yon.lach@motorola.com +# RFC4886 || T. Ernst || thierry.ernst@inria.fr +# RFC4887 || P. Thubert, R. Wakikawa, V. Devarapalli || pthubert@cisco.com, ryuji@sfc.wide.ad.jp, vijay.devarapalli@azairenet.com +# RFC4888 || C. Ng, P. Thubert, M. Watari, F. Zhao || chanwah.ng@sg.panasonic.com, pthubert@cisco.com, watari@kddilabs.jp, fanzhao@ucdavis.edu +# RFC4889 || C. Ng, F. Zhao, M. Watari, P. Thubert || chanwah.ng@sg.panasonic.com, fanzhao@ucdavis.edu, watari@kddilabs.jp, pthubert@cisco.com +# RFC4890 || E. Davies, J. Mohacsi || elwynd@dial.pipex.com, mohacsi@niif.hu +# RFC4891 || R. Graveman, M. Parthasarathy, P. Savola, H. Tschofenig || rfg@acm.org, mohanp@sbcglobal.net, psavola@funet.fi, Hannes.Tschofenig@nsn.com +# RFC4892 || S. Woolf, D. Conrad || woolf@isc.org, david.conrad@icann.org +# RFC4893 || Q. Vohra, E. Chen || quaizar.vohra@gmail.com, enkechen@cisco.com +# RFC4894 || P. Hoffman || paul.hoffman@vpnc.org +# RFC4895 || M. Tuexen, R. Stewart, P. Lei, E. Rescorla || tuexen@fh-muenster.de, randall@lakerest.net, peterlei@cisco.com, ekr@rtfm.com +# RFC4896 || A. Surtees, M. West, A.B. Roach || abigail.surtees@roke.co.uk, mark.a.west@roke.co.uk, adam@estacado.net +# RFC4897 || J. Klensin, S. Hartman || john-ietf@jck.com, hartmans-ietf@mit.edu +# RFC4898 || M. Mathis, J. Heffner, R. Raghunarayan || mathis@psc.edu, jheffner@psc.edu, raraghun@cisco.com +# RFC4901 || J. Ash, Ed., J. Hand, Ed., A. Malis, Ed. || gash5107@yahoo.com, jameshand@att.com, andrew.g.malis@verizon.com +# RFC4902 || M. Stecher || martin.stecher@webwasher.com +# RFC4903 || D. Thaler || dthaler@microsoft.com +# RFC4904 || V. Gurbani, C. Jennings || vkg@alcatel-lucent.com, fluffy@cisco.com +# RFC4905 || L. Martini, Ed., E. Rosen, Ed., N. El-Aawar, Ed. || lmartini@cisco.com, erosen@cisco.com, nna@level3.net +# RFC4906 || L. Martini, Ed., E. Rosen, Ed., N. El-Aawar, Ed. || lmartini@cisco.com, erosen@cisco.com, nna@level3.net +# RFC4907 || B. Aboba, Ed. || bernarda@microsoft.com +# RFC4908 || K. Nagami, S. Uda, N. Ogashiwa, H. Esaki, R. Wakikawa, H. Ohnishi || nagami@inetcore.com, zin@jaist.ac.jp, ogashiwa@wide.ad.jp, hiroshi@wide.ad.jp, ryuji@sfc.wide.ad.jp, ohnishi.hiroyuki@lab.ntt.co.jp +# RFC4909 || L. Dondeti, Ed., D. Castleford, F. Hartung || ldondeti@qualcomm.com, david.castleford@orange-ftgroup.com, frank.hartung@ericsson.com +# RFC4910 || S. Legg, D. Prager || steven.legg@eb2bcom.com, dap@austhink.com +# RFC4911 || S. Legg || steven.legg@eb2bcom.com +# RFC4912 || S. Legg || steven.legg@eb2bcom.com +# RFC4913 || S. Legg || steven.legg@eb2bcom.com +# RFC4914 || S. Legg || steven.legg@eb2bcom.com +# RFC4915 || P. Psenak, S. Mirtorabi, A. Roy, L. Nguyen, P. Pillay-Esnault || ppsenak@cisco.com, sina@force10networks.com, akr@cisco.com, lhnguyen@cisco.com, ppe@cisco.com +# RFC4916 || J. Elwell || john.elwell@siemens.com +# RFC4917 || V. Sastry, K. Leung, A. Patel || venkat.s@samsung.com, kleung@cisco.com, alpesh@cisco.com +# RFC4918 || L. Dusseault, Ed. || lisa.dusseault@gmail.com +# RFC4919 || N. Kushalnagar, G. Montenegro, C. Schumacher || nandakishore.kushalnagar@intel.com, gabriel.montenegro@microsoft.com, schumacher@danfoss.com +# RFC4920 || A. Farrel, Ed., A. Satyanarayana, A. Iwata, N. Fujita, G. Ash || adrian@olddog.co.uk, asatyana@cisco.com, a-iwata@ah.jp.nec.com, n-fujita@bk.jp.nec.com, gash5107@yahoo.com +# RFC4923 || F. Baker, P. Bose || fred@cisco.com, pratik.bose@lmco.com +# RFC4924 || B. Aboba, Ed., E. Davies || bernarda@microsoft.com, elwynd@dial.pipex.com +# RFC4925 || X. Li, Ed., S. Dawkins, Ed., D. Ward, Ed., A. Durand, Ed. || xing@cernet.edu.cn, spencer@mcsr-labs.org, dward@cisco.com, alain_durand@cable.comcast.com +# RFC4926 || T.Kalin, M.Molina || tomaz.kalin@dante.org.uk, maurizio.molina@dante.org.uk +# RFC4927 || J.-L. Le Roux, Ed. || jeanlouis.leroux@orange-ftgroup.com +# RFC4928 || G. Swallow, S. Bryant, L. Andersson || stbryant@cisco.com, swallow@cisco.com, loa@pi.se +# RFC4929 || L. Andersson, Ed., A. Farrel, Ed. || loa@pi.se, adrian@olddog.co.uk +# RFC4930 || S. Hollenbeck || shollenbeck@verisign.com +# RFC4931 || S. Hollenbeck || shollenbeck@verisign.com +# RFC4932 || S. Hollenbeck || shollenbeck@verisign.com +# RFC4933 || S. Hollenbeck || shollenbeck@verisign.com +# RFC4934 || S. Hollenbeck || shollenbeck@verisign.com +# RFC4935 || C. DeSanti, H.K. Vivek, K. McCloghrie, S. Gai || cds@cisco.com, hvivek@cisco.com, kzm@cisco.com, sgai@nuovasystems.com +# RFC4936 || C. DeSanti, H.K. Vivek, K. McCloghrie, S. Gai || cds@cisco.com, hvivek@cisco.com, kzm@cisco.com, sgai@nuovasystems.com +# RFC4937 || P. Arberg, V. Mammoliti || parberg@redback.com, vince@cisco.com +# RFC4938 || B. Berry, H. Holgate || bberry@cisco.com, hholgate@cisco.com +# RFC4939 || K. Gibbons, G. Ramkumar, S. Kipp || kgibbons@yahoo.com, gramkumar@stanfordalumni.org, skipp@brocade.com +# RFC4940 || K. Kompella, B. Fenner || kireeti@juniper.net, fenner@research.att.com +# RFC4941 || T. Narten, R. Draves, S. Krishnan || narten@us.ibm.com, richdr@microsoft.com, suresh.krishnan@ericsson.com +# RFC4942 || E. Davies, S. Krishnan, P. Savola || elwynd@dial.pipex.com, suresh.krishnan@ericsson.com, psavola@funet.fi +# RFC4943 || S. Roy, A. Durand, J. Paugh || sebastien.roy@sun.com, alain_durand@cable.comcast.com, jim.paugh@nominum.com +# RFC4944 || G. Montenegro, N. Kushalnagar, J. Hui, D. Culler || gabriel.montenegro@microsoft.com, nandakishore.kushalnagar@intel.com, jhui@archrock.com, dculler@archrock.com +# RFC4945 || B. Korver || briank@networkresonance.com +# RFC4946 || J. Snell || jasnell@gmail.com +# RFC4947 || G. Fairhurst, M. Montpetit || gorry@erg.abdn.ac.uk, mmontpetit@motorola.com +# RFC4948 || L. Andersson, E. Davies, L. Zhang || loa@pi.se, elwynd@dial.pipex.com, lixia@cs.ucla.edu +# RFC4949 || R. Shirey || rwshirey4949@verizon.net +# RFC4950 || R. Bonica, D. Gan, D. Tappan, C. Pignataro || rbonica@juniper.net, derhwagan@yahoo.com, dan.tappan@gmail.com, cpignata@cisco.com +# RFC4951 || V. Jain, Ed. || vipinietf@yahoo.com +# RFC4952 || J. Klensin, Y. Ko || john-ietf@jck.com, yw@mrko.pe.kr +# RFC4953 || J. Touch || touch@isi.edu +# RFC4954 || R. Siemborski, Ed., A. Melnikov, Ed. || robsiemb@google.com, Alexey.Melnikov@isode.com +# RFC4955 || D. Blacka || davidb@verisign.com +# RFC4956 || R. Arends, M. Kosters, D. Blacka || roy@nominet.org.uk, markk@verisign.com, davidb@verisign.com +# RFC4957 || S. Krishnan, Ed., N. Montavont, E. Njedjou, S. Veerepalli, A. Yegin, Ed. || suresh.krishnan@ericsson.com, nicolas.montavont@enst-bretagne.fr, eric.njedjou@orange-ftgroup.com, sivav@qualcomm.com, a.yegin@partner.samsung.com +# RFC4958 || K. Carlberg || carlberg@g11.org.uk +# RFC4959 || R. Siemborski, A. Gulbrandsen || robsiemb@google.com, arnt@oryx.com +# RFC4960 || R. Stewart, Ed. || randall@lakerest.net +# RFC4961 || D. Wing || dwing-ietf@fuggles.com +# RFC4962 || R. Housley, B. Aboba || housley@vigilsec.com, bernarda@microsoft.com +# RFC4963 || J. Heffner, M. Mathis, B. Chandler || jheffner@psc.edu, mathis@psc.edu, bchandle@gmail.com +# RFC4964 || A. Allen, Ed., J. Holm, T. Hallin || aallen@rim.com, Jan.Holm@ericsson.com, thallin@motorola.com +# RFC4965 || J-F. Mule, W. Townsley || jf.mule@cablelabs.com, mark@townsley.net +# RFC4966 || C. Aoun, E. Davies || ietf@energizeurnet.com, elwynd@dial.pipex.com +# RFC4967 || B. Rosen || br@brianrosen.net +# RFC4968 || S. Madanapalli, Ed. || smadanapalli@gmail.com +# RFC4969 || A. Mayrhofer || alexander.mayrhofer@enum.at +# RFC4970 || A. Lindem, Ed., N. Shen, JP. Vasseur, R. Aggarwal, S. Shaffer || acee@redback.com, naiming@cisco.com, jpv@cisco.com, rahul@juniper.net, sshaffer@bridgeport-networks.com +# RFC4971 || JP. Vasseur, Ed., N. Shen, Ed., R. Aggarwal, Ed. || jpv@cisco.com, naiming@cisco.com, rahul@juniper.net +# RFC4972 || JP. Vasseur, Ed., JL. Leroux, Ed., S. Yasukawa, S. Previdi, P. Psenak, P. Mabbey || jpv@cisco.com, jeanlouis.leroux@orange-ftgroup.com, s.yasukawa@hco.ntt.co.jp, sprevidi@cisco.com, ppsenak@cisco.com, Paul_Mabey@cable.comcast.com +# RFC4973 || P. Srisuresh, P. Joseph || srisuresh@yahoo.com, paul_95014@yahoo.com +# RFC4974 || D. Papadimitriou, A. Farrel || dimitri.papadimitriou@alcatel-lucent.be, adrian@olddog.co.uk +# RFC4975 || B. Campbell, Ed., R. Mahy, Ed., C. Jennings, Ed. || ben@estacado.net, rohan@ekabal.com, fluffy@cisco.com +# RFC4976 || C. Jennings, R. Mahy, A. B. Roach || fluffy@cisco.com, rohan@ekabal.com, adam@estacado.net +# RFC4977 || G. Tsirtsis, H. Soliman || tsirtsis@qualcomm.com, hesham@elevatemobile.com +# RFC4978 || A. Gulbrandsen || arnt@oryx.com +# RFC4979 || A. Mayrhofer || alexander.mayrhofer@enum.at +# RFC4980 || C. Ng, T. Ernst, E. Paik, M. Bagnulo || chanwah.ng@sg.panasonic.com, thierry.ernst@inria.fr, euna@kt.co.kr, marcelo@it.uc3m.es +# RFC4981 || J. Risson, T. Moors || jr@tuffit.com, t.moors@unsw.edu.au +# RFC4982 || M. Bagnulo, J. Arkko || marcelo@it.uc3m.es, jari.arkko@ericsson.com +# RFC4983 || C. DeSanti, H.K. Vivek, K. McCloghrie, S. Gai || cds@cisco.com, hvivek@cisco.com, kzm@cisco.com, sgai@nuovasystems.com +# RFC4984 || D. Meyer, Ed., L. Zhang, Ed., K. Fall, Ed. || dmm@1-4-5.net, lixia@cs.ucla.edu, kfall@intel.com +# RFC4985 || S. Santesson || stefans@microsoft.com +# RFC4986 || H. Eland, R. Mundy, S. Crocker, S. Krishnaswamy || heland@afilias.info, mundy@sparta.com, steve@shinkuro.com, suresh@sparta.com +# RFC4987 || W. Eddy || weddy@grc.nasa.gov +# RFC4988 || R. Koodli, C. Perkins || rajeev.koodli@nokia.com, charles.perkins@nokia.com +# RFC4990 || K. Shiomoto, R. Papneja, R. Rabbat || shiomoto.kohei@lab.ntt.co.jp, rabbat@alum.mit.edu, rpapneja@isocore.com +# RFC4991 || A. Newton || andy@hxr.us +# RFC4992 || A. Newton || andy@hxr.us +# RFC4993 || A. Newton || andy@hxr.us +# RFC4994 || S. Zeng, B. Volz, K. Kinnear, J. Brzozowski || szeng@cisco.com, volz@cisco.com, kkinnear@cisco.com, john_brzozowski@cable.comcast.com +# RFC4995 || L-E. Jonsson, G. Pelletier, K. Sandlund || lars-erik@lejonsson.com, ghyslain.pelletier@ericsson.com, kristofer.sandlund@ericsson.com +# RFC4996 || G. Pelletier, K. Sandlund, L-E. Jonsson, M. West || ghyslain.pelletier@ericsson.com, kristofer.sandlund@ericsson.com, lars-erik@lejonsson.com, mark.a.west@roke.co.uk +# RFC4997 || R. Finking, G. Pelletier || robert.finking@roke.co.uk, ghyslain.pelletier@ericsson.com +# RFC4998 || T. Gondrom, R. Brandner, U. Pordesch || tobias.gondrom@opentext.com, ralf.brandner@intercomponentware.com, ulrich.pordesch@zv.fraunhofer.de +# RFC5000 || RFC Editor || rfc-editor@rfc-editor.org +# RFC5001 || R. Austein || sra@isc.org +# RFC5002 || G. Camarillo, G. Blanco || Gonzalo.Camarillo@ericsson.com, German.Blanco@ericsson.com +# RFC5003 || C. Metz, L. Martini, F. Balus, J. Sugimoto || chmetz@cisco.com, lmartini@cisco.com, florin.balus@alcatel-lucent.com, sugimoto@nortel.com +# RFC5004 || E. Chen, S. Sangli || enkechen@cisco.com, rsrihari@cisco.com +# RFC5005 || M. Nottingham || mnot@pobox.com +# RFC5006 || J. Jeong, Ed., S. Park, L. Beloeil, S. Madanapalli || jjeong@cs.umn.edu, soohong.park@samsung.com, luc.beloeil@orange-ftgroup.com, smadanapalli@gmail.com +# RFC5007 || J. Brzozowski, K. Kinnear, B. Volz, S. Zeng || john_brzozowski@cable.comcast.com, kkinnear@cisco.com, volz@cisco.com, szeng@cisco.com +# RFC5008 || R. Housley, J. Solinas || housley@vigilsec.com, jasolin@orion.ncsc.mil +# RFC5009 || R. Ejza || ejzak@alcatel-lucent.com +# RFC5010 || K. Kinnear, M. Normoyle, M. Stapp || kkinnear@cisco.com, mnormoyle@cisco.com, mjs@cisco.com +# RFC5011 || M. StJohns || mstjohns@comcast.net +# RFC5012 || H. Schulzrinne, R. Marshall, Ed. || hgs+ecrit@cs.columbia.edu, rmarshall@telecomsys.com +# RFC5013 || J. Kunze, T. Baker || jak@ucop.edu, tbaker@tbaker.de +# RFC5014 || E. Nordmark, S. Chakrabarti, J. Laganier || Erik.Nordmark@Sun.com, samitac2@gmail.com, julien.IETF@laposte.net +# RFC5015 || M. Handley, I. Kouvelas, T. Speakman, L. Vicisano || M.Handley@cs.ucl.ac.uk, kouvelas@cisco.com, speakman@cisco.com, lorenzo@digitalfountain.com +# RFC5016 || M. Thomas || mat@cisco.com +# RFC5017 || D. McWalter, Ed. || dmcw@dataconnection.com +# RFC5018 || G. Camarillo || Gonzalo.Camarillo@ericsson.com +# RFC5019 || A. Deacon, R. Hurst || alex@verisign.com, rmh@microsoft.com +# RFC5020 || K. Zeilenga || Kurt.Zeilenga@Isode.COM +# RFC5021 || S. Josefsson || simon@josefsson.org +# RFC5022 || J. Van Dyke, E. Burger, Ed., A. Spitzer || jvandyke@cantata.com, eburger@standardstrack.com, woof@pingtel.com +# RFC5023 || J. Gregorio, Ed., B. de hOra, Ed. || joe@bitworking.org, bill@dehora.net +# RFC5024 || I. Friend || ieuan.friend@dip.co.uk +# RFC5025 || J. Rosenberg || jdrosen@cisco.com +# RFC5026 || G. Giaretta, Ed., J. Kempf, V. Devarapalli, Ed. || gerardog@qualcomm.com, kempf@docomolabs-usa.com, vijay.devarapalli@azairenet.com +# RFC5027 || F. Andreasen, D. Wing || fandreas@cisco.com, dwing-ietf@fuggles.com +# RFC5028 || R. Mahy || rohan@ekabal.com +# RFC5029 || JP. Vasseur, S. Previdi || jpv@cisco.com, sprevidi@cisco.com +# RFC5030 || M. Nakhjiri, Ed., K. Chowdhury, A. Lior, K. Leung || madjid.nakhjiri@motorola.com, kchowdhury@starentnetworks.com, avi@bridgewatersystems.com, kleung@cisco.com +# RFC5031 || H. Schulzrinne || hgs+ecrit@cs.columbia.edu +# RFC5032 || E. Burger, Ed. || eric.burger@bea.com +# RFC5033 || S. Floyd, M. Allman || floyd@icir.org, mallman@icir.org +# RFC5034 || R. Siemborski, A. Menon-Sen || robsiemb@google.com, ams@oryx.com +# RFC5035 || J. Schaad || jimsch@exmsft.com +# RFC5036 || L. Andersson, Ed., I. Minei, Ed., B. Thomas, Ed. || loa@pi.se, ina@juniper.net, rhthomas@cisco.com +# RFC5037 || L. Andersson, Ed., I. Minei, Ed., B. Thomas, Ed. || loa@pi.se, ina@juniper.net, rhthomas@cisco.com +# RFC5038 || B. Thomas, L. Andersson || loa@pi.se, rhthomas@cisco.com +# RFC5039 || J. Rosenberg, C. Jennings || jdrosen@cisco.com, fluffy@cisco.com +# RFC5040 || R. Recio, B. Metzler, P. Culley, J. Hilland, D. Garcia || recio@us.ibm.com, bmt@zurich.ibm.com, paul.culley@hp.com, jeff.hilland@hp.com, Dave.Garcia@StanfordAlumni.org +# RFC5041 || H. Shah, J. Pinkerton, R. Recio, P. Culley || hemal@broadcom.com, jpink@microsoft.com, recio@us.ibm.com, paul.culley@hp.com +# RFC5042 || J. Pinkerton, E. Deleganes || jpink@windows.microsoft.com, deleganes@yahoo.com +# RFC5043 || C. Bestler, Ed., R. Stewart, Ed. || caitlin.bestler@neterion.com, randall@lakerest.net +# RFC5044 || P. Culley, U. Elzur, R. Recio, S. Bailey, J. Carrier || paul.culley@hp.com, uri@broadcom.com, recio@us.ibm.com, steph@sandburst.com, carrier@cray.com +# RFC5045 || C. Bestler, Ed., L. Coene || caitlin.bestler@neterion.com, lode.coene@nsn.com +# RFC5046 || M. Ko, M. Chadalapaka, J. Hufferd, U. Elzur, H. Shah, P. Thaler || mako@us.ibm.com, cbm@rose.hp.com, jhufferd@brocade.com, Uri@Broadcom.com, hemal@broadcom.com, pthaler@broadcom.com +# RFC5047 || M. Chadalapaka, J. Hufferd, J. Satran, H. Shah || cbm@rose.hp.com, jhufferd@brocade.com, Julian_Satran@il.ibm.com, hemal@broadcom.com +# RFC5048 || M. Chadalapaka, Ed. || cbm@rose.hp.com +# RFC5049 || C. Bormann, Z. Liu, R. Price, G. Camarillo, Ed. || cabo@tzi.org, zhigang.c.liu@nokia.com, richard.price@eads.com, Gonzalo.Camarillo@ericsson.com +# RFC5050 || K. Scott, S. Burleigh || kscott@mitre.org, Scott.Burleigh@jpl.nasa.gov +# RFC5051 || M. Crispin || MRC@CAC.Washington.EDU +# RFC5052 || M. Watson, M. Luby, L. Vicisano || mark@digitalfountain.com, luby@digitalfountain.com, lorenzo@digitalfountain.com +# RFC5053 || M. Luby, A. Shokrollahi, M. Watson, T. Stockhammer || luby@digitalfountain.com, amin.shokrollahi@epfl.ch, mark@digitalfountain.com, stockhammer@nomor.de +# RFC5054 || D. Taylor, T. Wu, N. Mavrogiannopoulos, T. Perrin || dtaylor@gnutls.org, thomwu@cisco.com, nmav@gnutls.org, trevp@trevp.net +# RFC5055 || T. Freeman, R. Housley, A. Malpani, D. Cooper, W. Polk || trevorf@microsoft.com, housley@vigilsec.com, ambarish@yahoo.com, david.cooper@nist.gov, wpolk@nist.gov +# RFC5056 || N. Williams || Nicolas.Williams@sun.com +# RFC5057 || R. Sparks || RjS@estacado.net +# RFC5058 || R. Boivie, N. Feldman, Y. Imai, W. Livens, D. Ooms || rhboivie@us.ibm.com, nkfeldman@yahoo.com, ug@xcast.jp, wim@livens.net, dirk@onesparrow.com +# RFC5059 || N. Bhaskar, A. Gall, J. Lingard, S. Venaas || nidhi@arastra.com, alexander.gall@switch.ch, jchl@arastra.com, venaas@uninett.no +# RFC5060 || R. Sivaramu, J. Lingard, D. McWalter, B. Joshi, A. Kessler || raghava@cisco.com, jchl@arastra.com, dmcw@dataconnection.com, bharat_joshi@infosys.com, kessler@cisco.com +# RFC5061 || R. Stewart, Q. Xie, M. Tuexen, S. Maruyama, M. Kozuka || randall@lakerest.net, Qiaobing.Xie@motorola.com, tuexen@fh-muenster.de, mail@marushin.gr.jp, ma-kun@kozuka.jp +# RFC5062 || R. Stewart, M. Tuexen, G. Camarillo || randall@lakerest.net, tuexen@fh-muenster.de, Gonzalo.Camarillo@ericsson.com +# RFC5063 || A. Satyanarayana, Ed., R. Rahman, Ed. || asatyana@cisco.com, rrahman@cisco.com +# RFC5064 || M. Duerst || duerst@it.aoyama.ac.jp +# RFC5065 || P. Traina, D. McPherson, J. Scudder || bgp-confederations@st04.pst.org, danny@arbor.net, jgs@juniper.net +# RFC5066 || E. Beili || edward.beili@actelis.com +# RFC5067 || S. Lind, P. Pfautz || sdlind@att.com, ppfautz@att.com +# RFC5068 || C. Hutzler, D. Crocker, P. Resnick, E. Allman, T. Finch || cdhutzler@aol.com, dcrocker@bbiw.net, presnick@qti.qualcomm.com, eric+ietf-smtp@sendmail.org, dot@dotat.at +# RFC5069 || T. Taylor, Ed., H. Tschofenig, H. Schulzrinne, M. Shanmugam || tom.taylor.stds@gmail.com, Hannes.Tschofenig@nsn.com, hgs+ecrit@cs.columbia.edu, murugaraj.shanmugam@detecon.com +# RFC5070 || R. Danyliw, J. Meijer, Y. Demchenko || rdd@cert.org, jan@flyingcloggies.nl, demch@chello.nl +# RFC5071 || D. Hankins || David_Hankins@isc.org +# RFC5072 || S. Varada, Ed., D. Haskins, E. Allen || varada@txc.com +# RFC5073 || J.P. Vasseur, Ed., J.L. Le Roux, Ed. || jpv@cisco.com, jeanlouis.leroux@orange-ftgroup.com +# RFC5074 || S. Weiler || weiler@tislabs.com +# RFC5075 || B. Haberman, Ed., R. Hinden || brian@innovationslab.net, bob.hinden@gmail.com +# RFC5076 || B. Hoeneisen || hoeneisen@switch.ch +# RFC5077 || J. Salowey, H. Zhou, P. Eronen, H. Tschofenig || jsalowey@cisco.com, hzhou@cisco.com, pe@iki.fi, Hannes.Tschofenig@nsn.com +# RFC5078 || S. Dawkins || spencer@mcsr-labs.org +# RFC5079 || J. Rosenberg || jdrosen@cisco.com +# RFC5080 || D. Nelson, A. DeKok || dnelson@elbrysnetworks.com, aland@freeradius.org +# RFC5081 || N. Mavrogiannopoulos || nmav@gnutls.org +# RFC5082 || V. Gill, J. Heasley, D. Meyer, P. Savola, Ed., C. Pignataro || vijay@umbc.edu, heas@shrubbery.net, dmm@1-4-5.net, psavola@funet.fi, cpignata@cisco.com +# RFC5083 || R. Housley || housley@vigilsec.com +# RFC5084 || R. Housley || housley@vigilsec.com +# RFC5085 || T. Nadeau, Ed., C. Pignataro, Ed. || tnadeau@lucidvision.com, cpignata@cisco.com +# RFC5086 || A. Vainshtein, Ed., I. Sasson, E. Metz, T. Frost, P. Pate || sasha@axerra.com, israel@axerra.com, e.t.metz@telecom.tno.nl, tfrost@symmetricom.com, prayson.pate@overturenetworks.com +# RFC5087 || Y(J). Stein, R. Shashoua, R. Insler, M. Anavi || yaakov_s@rad.com, ronen_s@rad.com, ron_i@rad.com, motty@radusa.com +# RFC5088 || JL. Le Roux, Ed., JP. Vasseur, Ed., Y. Ikejiri, R. Zhang || jeanlouis.leroux@orange-ftgroup.com, jpv@cisco.com, y.ikejiri@ntt.com, raymond.zhang@bt.com +# RFC5089 || JL. Le Roux, Ed., JP. Vasseur, Ed., Y. Ikejiri, R. Zhang || jeanlouis.leroux@orange-ftgroup.com, jpv@cisco.com, y.ikejiri@ntt.com, raymond.zhang@bt.com +# RFC5090 || B. Sterman, D. Sadolevsky, D. Schwartz, D. Williams, W. Beck || baruch@kayote.com, dscreat@dscreat.com, david@kayote.com, dwilli@cisco.com, beckw@t-systems.com +# RFC5091 || X. Boyen, L. Martin || xavier@voltage.com, martin@voltage.com +# RFC5092 || A. Melnikov, Ed., C. Newman || Alexey.Melnikov@isode.com, chris.newman@sun.com +# RFC5093 || G. Hunt || geoff.hunt@bt.com +# RFC5094 || V. Devarapalli, A. Patel, K. Leung || vijay.devarapalli@azairenet.com, alpesh@cisco.com, kleung@cisco.com +# RFC5095 || J. Abley, P. Savola, G. Neville-Neil || jabley@ca.afilias.info, psavola@funet.fi, gnn@neville-neil.com +# RFC5096 || V. Devarapalli || vijay.devarapalli@azairenet.com +# RFC5097 || G. Renker, G. Fairhurst || gerrit@erg.abdn.ac.uk, gorry@erg.abdn.ac.uk +# RFC5098 || G. Beacham, S. Kumar, S. Channabasappa || gordon.beacham@motorola.com, satish.kumar@ti.com, Sumanth@cablelabs.com +# RFC5101 || B. Claise, Ed. || bclaise@cisco.com +# RFC5102 || J. Quittek, S. Bryant, B. Claise, P. Aitken, J. Meyer || quittek@netlab.nec.de, stbryant@cisco.com, bclaise@cisco.com, paitken@cisco.com, jemeyer@paypal.com +# RFC5103 || B. Trammell, E. Boschi || bht@cert.org, elisa.boschi@hitachi-eu.com +# RFC5104 || S. Wenger, U. Chandra, M. Westerlund, B. Burman || stewe@stewe.org, Umesh.1.Chandra@nokia.com, magnus.westerlund@ericsson.com, bo.burman@ericsson.com +# RFC5105 || O. Lendl || otmar.lendl@enum.at +# RFC5106 || H. Tschofenig, D. Kroeselberg, A. Pashalidis, Y. Ohba, F. Bersani || Hannes.Tschofenig@nsn.com, Dirk.Kroeselberg@nsn.com, pashalidis@nw.neclab.eu, yohba@tari.toshiba.com, florent.ftrd@gmail.com +# RFC5107 || R. Johnson, J. Kumarasamy, K. Kinnear, M. Stapp || raj@cisco.com, jayk@cisco.com, kkinnear@cisco.com, mjs@cisco.com +# RFC5109 || A. Li, Ed. || adamli@hyervision.com +# RFC5110 || P. Savola || psavola@funet.fi +# RFC5111 || B. Aboba, L. Dondeti || bernarda@microsoft.com, ldondeti@qualcomm.com +# RFC5112 || M. Garcia-Martin || miguel.garcia@nsn.com +# RFC5113 || J. Arkko, B. Aboba, J. Korhonen, Ed., F. Bari || jari.arkko@ericsson.com, bernarda@microsoft.com, jouni.korhonen@teliasonera.com, farooq.bari@att.com +# RFC5114 || M. Lepinski, S. Kent || mlepinski@bbn.com, kent@bbn.com +# RFC5115 || K. Carlberg, P. O'Hanlon || carlberg@g11.org.uk, p.ohanlon@cs.ucl.ac.uk +# RFC5116 || D. McGrew || mcgrew@cisco.com +# RFC5117 || M. Westerlund, S. Wenger || magnus.westerlund@ericsson.com, stewe@stewe.org +# RFC5118 || V. Gurbani, C. Boulton, R. Sparks || vkg@alcatel-lucent.com, cboulton@ubiquitysoftware.com, RjS@estacado.net +# RFC5119 || T. Edwards || thomas.edwards@fox.com +# RFC5120 || T. Przygienda, N. Shen, N. Sheth || prz@net4u.ch, naiming@cisco.com, nsheth@juniper.net +# RFC5121 || B. Patil, F. Xia, B. Sarikaya, JH. Choi, S. Madanapalli || basavaraj.patil@nsn.com, xiayangsong@huawei.com, sarikaya@ieee.org, jinchoe@samsung.com, smadanapalli@gmail.com +# RFC5122 || P. Saint-Andre || ietf@stpeter.im +# RFC5123 || R. White, B. Akyol || riw@cisco.com, bora@cisco.com +# RFC5124 || J. Ott, E. Carrara || jo@comnet.tkk.fi, carrara@kth.se +# RFC5125 || T. Taylor || tom.taylor.stds@gmail.com +# RFC5126 || D. Pinkas, N. Pope, J. Ross || Denis.Pinkas@bull.net, nick.pope@thales-esecurity.com, ross@secstan.com +# RFC5127 || K. Chan, J. Babiarz, F. Baker || khchan@nortel.com, babiarz@nortel.com, fred@cisco.com +# RFC5128 || P. Srisuresh, B. Ford, D. Kegel || srisuresh@yahoo.com, baford@mit.edu, dank06@kegel.com +# RFC5129 || B. Davie, B. Briscoe, J. Tay || bsd@cisco.com, bob.briscoe@bt.com, june.tay@bt.com +# RFC5130 || S. Previdi, M. Shand, Ed., C. Martin || sprevidi@cisco.com, mshand@cisco.com, chris@ipath.net +# RFC5131 || D. McWalter, Ed. || dmcw@dataconnection.com +# RFC5132 || D. McWalter, D. Thaler, A. Kessler || dmcw@dataconnection.com, dthaler@windows.microsoft.com, kessler@cisco.com +# RFC5133 || M. Tuexen, K. Morneault || tuexen@fh-muenster.de, kmorneau@cisco.com +# RFC5134 || M. Mealling || michael@refactored-networks.com +# RFC5135 || D. Wing, T. Eckert || dwing-ietf@fuggles.com, eckert@cisco.com +# RFC5136 || P. Chimento, J. Ishac || Philip.Chimento@jhuapl.edu, jishac@nasa.gov +# RFC5137 || J. Klensin || john-ietf@jck.com +# RFC5138 || S. Cox || Simon.Cox@csiro.au +# RFC5139 || M. Thomson, J. Winterbottom || martin.thomson@andrew.com, james.winterbottom@andrew.com +# RFC5140 || M. Bangalore, R. Kumar, J. Rosenberg, H. Salama, D.N. Shah || manjax@cisco.com, rajneesh@cisco.com, jdrosen@cisco.com, hsalama@citexsoftware.com, dhaval@moowee.tv +# RFC5141 || J. Goodwin, H. Apel || goodwin@iso.org, apel@iso.org +# RFC5142 || B. Haley, V. Devarapalli, H. Deng, J. Kempf || brian.haley@hp.com, vijay.devarapalli@azairenet.com, kempf@docomolabs-usa.com, denghui@chinamobile.com +# RFC5143 || A. Malis, J. Brayley, J. Shirron, L. Martini, S. Vogelsang || andrew.g.malis@verizon.com, jeremy.brayley@ecitele.com, john.shirron@ecitele.com, lmartini@cisco.com, steve.vogelsang@alcatel-lucent.com +# RFC5144 || A. Newton, M. Sanz || andy@arin.net, sanz@denic.de +# RFC5145 || K. Shiomoto, Ed. || shiomoto.kohei@lab.ntt.co.jp +# RFC5146 || K. Kumaki, Ed. || ke-kumaki@kddi.com +# RFC5147 || E. Wilde, M. Duerst || dret@berkeley.edu, duerst@it.aoyama.ac.jp +# RFC5148 || T. Clausen, C. Dearlove, B. Adamson || T.Clausen@computer.org, chris.dearlove@baesystems.com, adamson@itd.nrl.navy.mil +# RFC5149 || J. Korhonen, U. Nilsson, V. Devarapalli || jouni.korhonen@teliasonera.com, ulf.s.nilsson@teliasonera.com, vijay.devarapalli@azairenet.com +# RFC5150 || A. Ayyangar, K. Kompella, JP. Vasseur, A. Farrel || arthi@juniper.net, kireeti@juniper.net, jpv@cisco.com, adrian@olddog.co.uk +# RFC5151 || A. Farrel, Ed., A. Ayyangar, JP. Vasseur || adrian@olddog.co.uk, arthi@juniper.net, jpv@cisco.com +# RFC5152 || JP. Vasseur, Ed., A. Ayyangar, Ed., R. Zhang || jpv@cisco.com, arthi@juniper.net, raymond.zhang@bt.com +# RFC5153 || E. Boschi, L. Mark, J. Quittek, M. Stiemerling, P. Aitken || elisa.boschi@hitachi-eu.com, lutz.mark@fokus.fraunhofer.de, quittek@nw.neclab.eu, stiemerling@nw.neclab.eu, paitken@cisco.com +# RFC5154 || J. Jee, Ed., S. Madanapalli, J. Mandin || jhjee@etri.re.kr, smadanapalli@gmail.com, j_mandin@yahoo.com +# RFC5155 || B. Laurie, G. Sisson, R. Arends, D. Blacka || ben@links.org, geoff-s@panix.com, roy@nominet.org.uk, davidb@verisign.com +# RFC5156 || M. Blanchet || Marc.Blanchet@viagenie.ca +# RFC5157 || T. Chown || tjc@ecs.soton.ac.uk +# RFC5158 || G. Huston || gih@apnic.net +# RFC5159 || L. Dondeti, Ed., A. Jerichow || ldondeti@qualcomm.com, anja.jerichow@nsn.com +# RFC5160 || P. Levis, M. Boucadair || pierre.levis@orange-ftgroup.com, mohamed.boucadair@orange-ftgroup.com +# RFC5161 || A. Gulbrandsen, Ed., A. Melnikov, Ed. || arnt@oryx.com, Alexey.Melnikov@isode.com +# RFC5162 || A. Melnikov, D. Cridland, C. Wilson || Alexey.Melnikov@isode.com, dave.cridland@isode.com, corby@computer.org +# RFC5163 || G. Fairhurst, B. Collini-Nocker || gorry@erg.abdn.ac.uk, bnocker@cosy.sbg.ac.at +# RFC5164 || T. Melia, Ed. || tmelia@cisco.com +# RFC5165 || C. Reed || creed@opengeospatial.org +# RFC5166 || S. Floyd, Ed. || floyd@icir.org +# RFC5167 || M. Dolly, R. Even || mdolly@att.com, roni.even@polycom.co.il +# RFC5168 || O. Levin, R. Even, P. Hagendorf || oritl@microsoft.com, roni.even@polycom.co.il, pierre@radvision.com +# RFC5169 || T. Clancy, M. Nakhjiri, V. Narayanan, L. Dondeti || clancy@LTSnet.net, madjid.nakhjiri@motorola.com, vidyan@qualcomm.com, ldondeti@qualcomm.com +# RFC5170 || V. Roca, C. Neumann, D. Furodet || vincent.roca@inria.fr, christoph.neumann@thomson.net, david.furodet@st.com +# RFC5171 || M. Foschiano || foschia@cisco.com +# RFC5172 || S. Varada, Ed. || varada@ieee.org +# RFC5173 || J. Degener, P. Guenther || jutta@pobox.com, guenther@sendmail.com +# RFC5174 || J-P. Evain || evain@ebu.ch +# RFC5175 || B. Haberman, Ed., R. Hinden || brian@innovationslab.net, bob.hinden@gmail.com +# RFC5176 || M. Chiba, G. Dommety, M. Eklund, D. Mitton, B. Aboba || mchiba@cisco.com, gdommety@cisco.com, meklund@cisco.com, david@mitton.com, bernarda@microsoft.com +# RFC5177 || K. Leung, G. Dommety, V. Narayanan, A. Petrescu || kleung@cisco.com, gdommety@cisco.com, vidyan@qualcomm.com, alexandru.petrescu@motorola.com +# RFC5178 || N. Williams, A. Melnikov || Nicolas.Williams@sun.com, Alexey.Melnikov@isode.com +# RFC5179 || N. Williams || Nicolas.Williams@sun.com +# RFC5180 || C. Popoviciu, A. Hamza, G. Van de Velde, D. Dugatkin || cpopovic@cisco.com, ahamza@cisco.com, gunter@cisco.com, diego@fastsoft.com +# RFC5181 || M-K. Shin, Ed., Y-H. Han, S-E. Kim, D. Premec || myungki.shin@gmail.com, yhhan@kut.ac.kr, sekim@kt.co.kr, domagoj.premec@siemens.com +# RFC5182 || A. Melnikov || Alexey.Melnikov@isode.com +# RFC5183 || N. Freed || ned.freed@mrochek.com +# RFC5184 || F. Teraoka, K. Gogo, K. Mitsuya, R. Shibui, K. Mitani || tera@ics.keio.ac.jp, gogo@tera.ics.keio.ac.jp, mitsuya@sfc.wide.ad.jp, shibrie@tera.ics.keio.ac.jp, koki@tera.ics.keio.ac.jp, rajeev_koodli@yahoo.com +# RFC5185 || S. Mirtorabi, P. Psenak, A. Lindem, Ed., A. Oswal || sina@nuovasystems.com, ppsenak@cisco.com, acee@redback.com, aoswal@redback.com +# RFC5186 || B. Haberman, J. Martin || brian@innovationslab.net, jim@wovensystems.com +# RFC5187 || P. Pillay-Esnault, A. Lindem || ppe@cisco.com, acee@redback.com +# RFC5188 || H. Desineni, Q. Xie || hd@qualcomm.com, Qiaobing.Xie@Gmail.com +# RFC5189 || M. Stiemerling, J. Quittek, T. Taylor || stiemerling@nw.neclab.eu, quittek@nw.neclab.eu, tom.taylor.stds@gmail.com +# RFC5190 || J. Quittek, M. Stiemerling, P. Srisuresh || quittek@nw.neclab.eu, stiemerling@nw.neclab.eu, srisuresh@yahoo.com +# RFC5191 || D. Forsberg, Y. Ohba, Ed., B. Patil, H. Tschofenig, A. Yegin || dan.forsberg@nokia.com, yohba@tari.toshiba.com, basavaraj.patil@nsn.com, hannes.tschofenig@nsn.com, a.yegin@partner.samsung.com +# RFC5192 || L. Morand, A. Yegin, S. Kumar, S. Madanapalli || lionel.morand@orange-ftgroup.com, a.yegin@partner.samsung.com, surajk@techmahindra.com, syam@samsung.com +# RFC5193 || P. Jayaraman, R. Lopez, Y. Ohba, Ed., M. Parthasarathy, A. Yegin || prakash_jayaraman@net.com, rafa@um.es, yohba@tari.toshiba.com, mohanp@sbcglobal.net, a.yegin@partner.samsung.com +# RFC5194 || A. van Wijk, Ed., G. Gybels, Ed. || guido.gybels@rnid.org.uk, arnoud@realtimetext.org +# RFC5195 || H. Ould-Brahim, D. Fedyk, Y. Rekhter || hbrahim@nortel.com, yakov@juniper.net, dwfedyk@nortel.com +# RFC5196 || M. Lonnfors, K. Kiss || mikko.lonnfors@nokia.com, krisztian.kiss@nokia.com +# RFC5197 || S. Fries, D. Ignjatic || steffen.fries@siemens.com, dignjatic@polycom.com +# RFC5198 || J. Klensin, M. Padlipsky || john-ietf@jck.com, the.map@alum.mit.edu +# RFC5201 || R. Moskowitz, P. Nikander, P. Jokela, Ed., T. Henderson || rgm@icsalabs.com, pekka.nikander@nomadiclab.com, petri.jokela@nomadiclab.com, thomas.r.henderson@boeing.com +# RFC5202 || P. Jokela, R. Moskowitz, P. Nikander || petri.jokela@nomadiclab.com, rgm@icsalabs.com, pekka.nikander@nomadiclab.com +# RFC5203 || J. Laganier, T. Koponen, L. Eggert || julien.ietf@laposte.net, teemu.koponen@iki.fi, lars.eggert@nokia.com +# RFC5204 || J. Laganier, L. Eggert || julien.ietf@laposte.net, lars.eggert@nokia.com +# RFC5205 || P. Nikander, J. Laganier || pekka.nikander@nomadiclab.com, julien.ietf@laposte.net +# RFC5206 || P. Nikander, T. Henderson, Ed., C. Vogt, J. Arkko || pekka.nikander@nomadiclab.com, thomas.r.henderson@boeing.com, christian.vogt@ericsson.com, jari.arkko@ericsson.com +# RFC5207 || M. Stiemerling, J. Quittek, L. Eggert || stiemerling@netlab.nec.de, quittek@nw.neclab.eu, lars.eggert@nokia.com +# RFC5208 || B. Kaliski || kaliski_burt@emc.com +# RFC5209 || P. Sangster, H. Khosravi, M. Mani, K. Narayan, J. Tardo || Paul_Sangster@symantec.com, hormuzd.m.khosravi@intel.com, mmani@avaya.com, kaushik@cisco.com, joseph.tardo@nevisnetworks.com +# RFC5210 || J. Wu, J. Bi, X. Li, G. Ren, K. Xu, M. Williams || jianping@cernet.edu.cn, junbi@cernet.edu.cn, xing@cernet.edu.cn, rg03@mails.tsinghua.edu.cn, xuke@csnet1.cs.tsinghua.edu.cn, miw@juniper.net +# RFC5211 || J. Curran || jcurran@istaff.org +# RFC5212 || K. Shiomoto, D. Papadimitriou, JL. Le Roux, M. Vigoureux, D. Brungard || shiomoto.kohei@lab.ntt.co.jp, dimitri.papadimitriou@alcatel-lucent.be, jeanlouis.leroux@orange-ftgroup.com, martin.vigoureux@alcatel-lucent.fr, dbrungard@att.com +# RFC5213 || S. Gundavelli, Ed., K. Leung, V. Devarapalli, K. Chowdhury, B. Patil || sgundave@cisco.com, kleung@cisco.com, vijay@wichorus.com, kchowdhury@starentnetworks.com, basavaraj.patil@nokia.com +# RFC5214 || F. Templin, T. Gleeson, D. Thaler || fred.l.templin@boeing.com, tgleeson@cisco.com, dthaler@microsoft.com +# RFC5215 || L. Barbato || lu_zero@gentoo.org +# RFC5216 || D. Simon, B. Aboba, R. Hurst || dansimon@microsoft.com, bernarda@microsoft.com, rmh@microsoft.com +# RFC5217 || M. Shimaoka, Ed., N. Hastings, R. Nielsen || m-shimaoka@secom.co.jp, nelson.hastings@nist.gov, nielsen_rebecca@bah.com +# RFC5218 || D. Thaler, B. Aboba || dthaler@microsoft.com, bernarda@microsoft.com +# RFC5219 || R. Finlayson || finlayson@live555.com +# RFC5220 || A. Matsumoto, T. Fujisaki, R. Hiromi, K. Kanayama || arifumi@nttv6.net, fujisaki@nttv6.net, hiromi@inetcore.com, kanayama_kenichi@intec-si.co.jp +# RFC5221 || A. Matsumoto, T. Fujisaki, R. Hiromi, K. Kanayama || arifumi@nttv6.net, fujisaki@nttv6.net, hiromi@inetcore.com, kanayama_kenichi@intec-si.co.jp +# RFC5222 || T. Hardie, A. Newton, H. Schulzrinne, H. Tschofenig || hardie@qualcomm.com, andy@hxr.us, hgs+ecrit@cs.columbia.edu, Hannes.Tschofenig@nsn.com +# RFC5223 || H. Schulzrinne, J. Polk, H. Tschofenig || hgs+ecrit@cs.columbia.edu, jmpolk@cisco.com, Hannes.Tschofenig@nsn.com +# RFC5224 || M. Brenner || mrbrenner@alcatel-lucent.com +# RFC5225 || G. Pelletier, K. Sandlund || ghyslain.pelletier@ericsson.com, kristofer.sandlund@ericsson.com +# RFC5226 || T. Narten, H. Alvestrand || narten@us.ibm.com, Harald@Alvestrand.no +# RFC5227 || S. Cheshire || rfc@stuartcheshire.org +# RFC5228 || P. Guenther, Ed., T. Showalter, Ed. || guenther@sendmail.com, tjs@psaux.com +# RFC5229 || K. Homme || kjetilho@ifi.uio.no +# RFC5230 || T. Showalter, N. Freed, Ed. || tjs@psaux.com, ned.freed@mrochek.com +# RFC5231 || W. Segmuller, B. Leiba || werewolf@us.ibm.com, leiba@watson.ibm.com +# RFC5232 || A. Melnikov || alexey.melnikov@isode.com +# RFC5233 || K. Murchison || murch@andrew.cmu.edu +# RFC5234 || D. Crocker, Ed., P. Overell || dcrocker@bbiw.net, paul@bayleaf.org.uk +# RFC5235 || C. Daboo || cyrus@daboo.name +# RFC5236 || A. Jayasumana, N. Piratla, T. Banka, A. Bare, R. Whitner || Anura.Jayasumana@colostate.edu, Nischal.Piratla@telekom.de, Tarun.Banka@colostate.edu, abhijit_bare@agilent.com, rick_whitner@agilent.com +# RFC5237 || J. Arkko, S. Bradner || jari.arkko@piuha.net, sob@harvard.edu +# RFC5238 || T. Phelan || tphelan@sonusnet.com +# RFC5239 || M. Barnes, C. Boulton, O. Levin || mary.barnes@nortel.com, cboulton@avaya.com, oritl@microsoft.com +# RFC5240 || B. Joshi, R. Bijlani || bharat_joshi@infosys.com, rainab@gmail.com +# RFC5241 || A. Falk, S. Bradner || falk@bbn.com, sob@harvard.edu +# RFC5242 || J. Klensin, H. Alvestrand || john+ietf@jck.com, harald@alvestrand.no +# RFC5243 || R. Ogier || rich.ogier@earthlink.net +# RFC5244 || H. Schulzrinne, T. Taylor || schulzrinne@cs.columbia.edu, tom.taylor.stds@gmail.com +# RFC5245 || J. Rosenberg || jdrosen@jdrosen.net +# RFC5246 || T. Dierks, E. Rescorla || tim@dierks.org, ekr@rtfm.com +# RFC5247 || B. Aboba, D. Simon, P. Eronen || bernarda@microsoft.com, dansimon@microsoft.com, pe@iki.fi +# RFC5248 || T. Hansen, J. Klensin || tony+mailesc@maillennium.att.com, john+ietf@jck.com +# RFC5249 || D. Harrington, Ed. || dharrington@huawei.com +# RFC5250 || L. Berger, I. Bryskin, A. Zinin, R. Coltun || lberger@labn.net, ibryskin@advaoptical.com, alex.zinin@alcatel-lucent.com, none +# RFC5251 || D. Fedyk, Ed., Y. Rekhter, Ed., D. Papadimitriou, R. Rabbat, L. Berger || dwfedyk@nortel.com, yakov@juniper.net, Dimitri.Papadimitriou@alcatel-lucent.be, rabbat@alum.mit.edu, lberger@labn.net +# RFC5252 || I. Bryskin, L. Berger || ibryskin@advaoptical.com, lberger@labn.net +# RFC5253 || T. Takeda, Ed. || takeda.tomonori@lab.ntt.co.jp +# RFC5254 || N. Bitar, Ed., M. Bocci, Ed., L. Martini, Ed. || nabil.bitar@verizon.com, matthew.bocci@alcatel-lucent.co.uk, lmartini@cisco.com +# RFC5255 || C. Newman, A. Gulbrandsen, A. Melnikov || chris.newman@sun.com, arnt@oryx.com, Alexey.Melnikov@isode.com +# RFC5256 || M. Crispin, K. Murchison || IMAP+SORT+THREAD@Lingling.Panda.COM, murch@andrew.cmu.edu +# RFC5257 || C. Daboo, R. Gellens || cyrus@daboo.name, randy@qualcomm.com +# RFC5258 || B. Leiba, A. Melnikov || leiba@watson.ibm.com, Alexey.Melnikov@isode.com +# RFC5259 || A. Melnikov, Ed., P. Coates, Ed. || Alexey.Melnikov@isode.com, peter.coates@Sun.COM +# RFC5260 || N. Freed || ned.freed@mrochek.com +# RFC5261 || J. Urpalainen || jari.urpalainen@nokia.com +# RFC5262 || M. Lonnfors, E. Leppanen, H. Khartabil, J. Urpalainen || mikko.lonnfors@nokia.com, eva.leppanen@saunalahti.fi, hisham.khartabil@gmail.com, jari.urpalainen@nokia.com +# RFC5263 || M. Lonnfors, J. Costa-Requena, E. Leppanen, H. Khartabil || mikko.lonnfors@nokia.com, jose.costa-requena@nokia.com, eva.leppanen@saunalahti.fi, hisham.khartabil@gmail.com +# RFC5264 || A. Niemi, M. Lonnfors, E. Leppanen || aki.niemi@nokia.com, mikko.lonnfors@nokia.com, eva.leppanen@saunalaht.fi +# RFC5265 || S. Vaarala, E. Klovning || sami.vaarala@iki.fi, espen@birdstep.com +# RFC5266 || V. Devarapalli, P. Eronen || vijay@wichorus.com, pe@iki.fi +# RFC5267 || D. Cridland, C. King || dave.cridland@isode.com, cking@mumbo.ca +# RFC5268 || R. Koodli, Ed. || rkoodli@starentnetworks.com[ +# RFC5269 || J. Kempf, R. Koodli || kempf@docomolabs-usa.com, rkoodli@starentnetworks.com +# RFC5270 || H. Jang, J. Jee, Y. Han, S. Park, J. Cha || heejin.jang@gmail.com, jhjee@etri.re.kr, yhhan@kut.ac.kr, soohong.park@samsung.com, jscha@etri.re.kr +# RFC5271 || H. Yokota, G. Dommety || yokota@kddilabs.jp, gdommety@cisco.com +# RFC5272 || J. Schaad, M. Myers || jimsch@nwlink.com, mmyers@fastq.com +# RFC5273 || J. Schaad, M. Myers || jimsch@nwlink.com, mmyers@fastq.com +# RFC5274 || J. Schaad, M. Myers || jimsch@nwlink.com, mmyers@fastq.com +# RFC5275 || S. Turner || turners@ieca.com +# RFC5276 || C. Wallace || cwallace@cygnacom.com +# RFC5277 || S. Chisholm, H. Trevino || schishol@nortel.com, htrevino@cisco.com +# RFC5278 || J. Livingood, D. Troshynski || jason_livingood@cable.comcast.com, dtroshynski@acmepacket.com +# RFC5279 || A. Monrad, S. Loreto || atle.monrad@ericsson.com, Salvatore.Loreto@ericsson.com +# RFC5280 || D. Cooper, S. Santesson, S. Farrell, S. Boeyen, R. Housley, W. Polk || david.cooper@nist.gov, stefans@microsoft.com, stephen.farrell@cs.tcd.ie, sharon.boeyen@entrust.com, housley@vigilsec.com, wpolk@nist.gov +# RFC5281 || P. Funk, S. Blake-Wilson || PaulFunk@alum.mit.edu, sblakewilson@nl.safenet-inc.com +# RFC5282 || D. Black, D. McGrew || black_david@emc.com, mcgrew@cisco.com +# RFC5283 || B. Decraene, JL. Le Roux, I. Minei || bruno.decraene@orange-ftgroup.com, jeanlouis.leroux@orange-ftgroup.com, ina@juniper.net +# RFC5284 || G. Swallow, A. Farrel || swallow@cisco.com, adrian@olddog.co.uk +# RFC5285 || D. Singer, H. Desineni || singer@apple.com, hd@qualcomm.com +# RFC5286 || A. Atlas, Ed., A. Zinin, Ed. || alia.atlas@bt.com, alex.zinin@alcatel-lucent.com +# RFC5287 || A. Vainshtein, Y(J). Stein || Alexander.Vainshtein@ecitele.com, yaakov_s@rad.com +# RFC5288 || J. Salowey, A. Choudhury, D. McGrew || jsalowey@cisco.com, abhijitc@cisco.com, mcgrew@cisco.com +# RFC5289 || E. Rescorla || ekr@rtfm.com +# RFC5290 || S. Floyd, M. Allman || floyd@icir.org, mallman@icir.org +# RFC5291 || E. Chen, Y. Rekhter || enkechen@cisco.com, yakov@juniper.net +# RFC5292 || E. Chen, S. Sangli || enkechen@cisco.com, rsrihari@cisco.com +# RFC5293 || J. Degener, P. Guenther || jutta@pobox.com, guenther@sendmail.com +# RFC5294 || P. Savola, J. Lingard || psavola@funet.fi, jchl@arastra.com +# RFC5295 || J. Salowey, L. Dondeti, V. Narayanan, M. Nakhjiri || jsalowey@cisco.com, ldondeti@qualcomm.com, vidyan@qualcomm.com, madjid.nakhjiri@motorola.com +# RFC5296 || V. Narayanan, L. Dondeti || vidyan@qualcomm.com, ldondeti@qualcomm.com +# RFC5297 || D. Harkins || dharkins@arubanetworks.com +# RFC5298 || T. Takeda, Ed., A. Farrel, Ed., Y. Ikejiri, JP. Vasseur || takeda.tomonori@lab.ntt.co.jp, y.ikejiri@ntt.com, adrian@olddog.co.uk, jpv@cisco.com +# RFC5301 || D. McPherson, N. Shen || danny@arbor.net, naiming@cisco.com +# RFC5302 || T. Li, H. Smit, T. Przygienda || tony.li@tony.li, hhw.smit@xs4all.nl, prz@net4u.ch +# RFC5303 || D. Katz, R. Saluja, D. Eastlake 3rd || dkatz@juniper.net, rajesh.saluja@tenetindia.com, d3e3e3@gmail.com +# RFC5304 || T. Li, R. Atkinson || tony.li@tony.li, rja@extremenetworks.com +# RFC5305 || T. Li, H. Smit || tony.li@tony.li, hhwsmit@xs4all.nl +# RFC5306 || M. Shand, L. Ginsberg || mshand@cisco.com, ginsberg@cisco.com +# RFC5307 || K. Kompella, Ed., Y. Rekhter, Ed. || kireeti@juniper.net, yakov@juniper.net +# RFC5308 || C. Hopps || chopps@cisco.com +# RFC5309 || N. Shen, Ed., A. Zinin, Ed. || naiming@cisco.com, alex.zinin@alcatel-lucent.com +# RFC5310 || M. Bhatia, V. Manral, T. Li, R. Atkinson, R. White, M. Fanto || manav@alcatel-lucent.com, vishwas@ipinfusion.com, tony.li@tony.li, rja@extremenetworks.com, riw@cisco.com, mfanto@aegisdatasecurity.com +# RFC5311 || D. McPherson, Ed., L. Ginsberg, S. Previdi, M. Shand || danny@arbor.net, ginsberg@cisco.com, sprevidi@cisco.com, mshand@cisco.com +# RFC5316 || M. Chen, R. Zhang, X. Duan || mach@huawei.com, zhangrenhai@huawei.com, duanxiaodong@chinamobile.com +# RFC5317 || S. Bryant, Ed., L. Andersson, Ed. || stbryant@cisco.com, loa@pi.nu +# RFC5318 || J. Hautakorpi, G. Camarillo || Jani.Hautakorpi@ericsson.com, Gonzalo.Camarillo@ericsson.com +# RFC5320 || F. Templin, Ed. || fltemplin@acm.org +# RFC5321 || J. Klensin || john+smtp@jck.com +# RFC5322 || P. Resnick, Ed. || presnick@qti.qualcomm.com +# RFC5323 || J. Reschke, Ed., S. Reddy, J. Davis, A. Babich || julian.reschke@greenbytes.de, Surendra.Reddy@mitrix.com, jrd3@alum.mit.edu, ababich@us.ibm.com +# RFC5324 || C. DeSanti, F. Maino, K. McCloghrie || cds@cisco.com, fmaino@cisco.com, kzm@cisco.com +# RFC5325 || S. Burleigh, M. Ramadas, S. Farrell || Scott.Burleigh@jpl.nasa.gov, mramadas@gmail.com, stephen.farrell@cs.tcd.ie +# RFC5326 || M. Ramadas, S. Burleigh, S. Farrell || mramadas@gmail.com, Scott.Burleigh@jpl.nasa.gov, stephen.farrell@cs.tcd.ie +# RFC5327 || S. Farrell, M. Ramadas, S. Burleigh || stephen.farrell@cs.tcd.ie, mramadas@gmail.com, Scott.Burleigh@jpl.nasa.gov +# RFC5328 || A. Adolf, P. MacAvock || alexander.adolf@micronas.com, macavock@dvb.org +# RFC5329 || K. Ishiguro, V. Manral, A. Davey, A. Lindem, Ed. || kunihiro@ipinfusion.com, vishwas@ipinfusion.com, Alan.Davey@dataconnection.com, acee@redback.com +# RFC5330 || JP. Vasseur, Ed., M. Meyer, K. Kumaki, A. Bonda || jpv@cisco.com, matthew.meyer@bt.com, ke-kumaki@kddi.com, alberto.tempiabonda@telecomitalia.it +# RFC5331 || R. Aggarwal, Y. Rekhter, E. Rosen || rahul@juniper.net, yakov@juniper.net, erosen@cisco.com +# RFC5332 || T. Eckert, E. Rosen, Ed., R. Aggarwal, Y. Rekhter || eckert@cisco.com, erosen@cisco.com, rahul@juniper.net, yakov@juniper.net +# RFC5333 || R. Mahy, B. Hoeneisen || rohan@ekabal.com, bernie@ietf.hoeneisen.ch +# RFC5334 || I. Goncalves, S. Pfeiffer, C. Montgomery || justivo@gmail.com, silvia@annodex.net, monty@xiph.org +# RFC5335 || A. Yang, Ed. || abelyang@twnic.net.tw +# RFC5336 || J. Yao, Ed., W. Mao, Ed. || yaojk@cnnic.cn, maowei_ietf@cnnic.cn +# RFC5337 || C. Newman, A. Melnikov, Ed. || chris.newman@sun.com, Alexey.Melnikov@isode.com +# RFC5338 || T. Henderson, P. Nikander, M. Komu || thomas.r.henderson@boeing.com, pekka.nikander@nomadiclab.com, miika@iki.fi +# RFC5339 || JL. Le Roux, Ed., D. Papadimitriou, Ed. || jeanlouis.leroux@orange-ftgroup.com, dimitri.papadimitriou@alcatel-lucent.be +# RFC5340 || R. Coltun, D. Ferguson, J. Moy, A. Lindem || none, dennis@juniper.net, jmoy@sycamorenet.com, acee@redback.com +# RFC5341 || C. Jennings, V. Gurbani || fluffy@cisco.com, vkg@alcatel-lucent.com +# RFC5342 || D. Eastlake 3rd || d3e3e3@gmail.com +# RFC5343 || J. Schoenwaelder || j.schoenwaelder@jacobs-university.de +# RFC5344 || A. Houri, E. Aoki, S. Parameswar || avshalom@il.ibm.com, aoki@aol.net, Sriram.Parameswar@microsoft.com +# RFC5345 || J. Schoenwaelder || j.schoenwaelder@jacobs-university.de +# RFC5346 || J. Lim, W. Kim, C. Park, L. Conroy || jhlim@nida.or.kr, wkim@nida.or.kr, ckp@nida.or.kr, lconroy@insensate.co.uk +# RFC5347 || F. Andreasen, D. Hancock || fandreas@cisco.com, d.hancock@cablelabs.com +# RFC5348 || S. Floyd, M. Handley, J. Padhye, J. Widmer || floyd@icir.org, M.Handley@cs.ucl.ac.uk, padhye@microsoft.com, widmer@acm.org +# RFC5349 || L. Zhu, K. Jaganathan, K. Lauter || lzhu@microsoft.com, karthikj@microsoft.com, klauter@microsoft.com +# RFC5350 || J. Manner, A. McDonald || jukka.manner@tkk.fi, andrew.mcdonald@roke.co.uk +# RFC5351 || P. Lei, L. Ong, M. Tuexen, T. Dreibholz || peterlei@cisco.com, Lyong@Ciena.com, tuexen@fh-muenster.de, dreibh@iem.uni-due.de +# RFC5352 || R. Stewart, Q. Xie, M. Stillman, M. Tuexen || randall@lakerest.net, Qiaobing.Xie@gmail.org, maureen.stillman@nokia.com, tuexen@fh-muenster.de +# RFC5353 || Q. Xie, R. Stewart, M. Stillman, M. Tuexen, A. Silverton || Qiaobing.Xie@gmail.org, randall@lakerest.net, maureen.stillman@nokia.com, tuexen@fh-muenster.de, ajs.ietf@gmail.com +# RFC5354 || R. Stewart, Q. Xie, M. Stillman, M. Tuexen || randall@lakerest.net, Qiaobing.Xie@gmail.org, maureen.stillman@nokia.com, tuexen@fh-muenster.de +# RFC5355 || M. Stillman, Ed., R. Gopal, E. Guttman, S. Sengodan, M. Holdrege || maureen.stillman@nokia.com, ram.gopal@nsn.com, Erik.Guttman@sun.com, Senthil.sengodan@nsn.com, Holdrege@gmail.com +# RFC5356 || T. Dreibholz, M. Tuexen || dreibh@iem.uni-due.de, tuexen@fh-muenster.de +# RFC5357 || K. Hedayat, R. Krzanowski, A. Morton, K. Yum, J. Babiarz || khedayat@brixnet.com, roman.krzanowski@verizon.com, acmorton@att.com, kyum@juniper.net, babiarz@nortel.com +# RFC5358 || J. Damas, F. Neves || Joao_Damas@isc.org, fneves@registro.br +# RFC5359 || A. Johnston, Ed., R. Sparks, C. Cunningham, S. Donovan, K. Summers || alan@sipstation.com, RjS@nostrum.com, chrcunni@cisco.com, srd@cisco.com, ksummers@sonusnet.com +# RFC5360 || J. Rosenberg, G. Camarillo, Ed., D. Willis || jdrosen@cisco.com, Gonzalo.Camarillo@ericsson.com, dean.willis@softarmor.com +# RFC5361 || G. Camarillo || Gonzalo.Camarillo@ericsson.com +# RFC5362 || G. Camarillo || Gonzalo.Camarillo@ericsson.com +# RFC5363 || G. Camarillo, A.B. Roach || Gonzalo.Camarillo@ericsson.com, Adam.Roach@tekelec.com +# RFC5364 || M. Garcia-Martin, G. Camarillo || miguel.a.garcia@ericsson.com, Gonzalo.Camarillo@ericsson.com +# RFC5365 || M. Garcia-Martin, G. Camarillo || miguel.a.garcia@ericsson.com, Gonzalo.Camarillo@ericsson.com +# RFC5366 || G. Camarillo, A. Johnston || Gonzalo.Camarillo@ericsson.com, alan@sipstation.com +# RFC5367 || G. Camarillo, A.B. Roach, O. Levin || Gonzalo.Camarillo@ericsson.com, Adam.Roach@tekelec.com, oritl@microsoft.com +# RFC5368 || G. Camarillo, A. Niemi, M. Isomaki, M. Garcia-Martin, H. Khartabil || Gonzalo.Camarillo@ericsson.com, Aki.Niemi@nokia.com, markus.isomaki@nokia.com, miguel.a.garcia@ericsson.com, hisham.khartabil@gmail.com +# RFC5369 || G. Camarillo || Gonzalo.Camarillo@ericsson.com +# RFC5370 || G. Camarillo || Gonzalo.Camarillo@ericsson.com +# RFC5371 || S. Futemma, E. Itakura, A. Leung || satosi-f@sm.sony.co.jp, itakura@sm.sony.co.jp, andrew@ualberta.net +# RFC5372 || A. Leung, S. Futemma, E. Itakura || andrew@ualberta.net, satosi-f@sm.sony.co.jp, itakura@sm.sony.co.jp +# RFC5373 || D. Willis, Ed., A. Allen || dean.willis@softarmor.com, aallen@rim.com +# RFC5374 || B. Weis, G. Gross, D. Ignjatic || bew@cisco.com, gmgross@securemulticast.net, dignjatic@polycom.com +# RFC5375 || G. Van de Velde, C. Popoviciu, T. Chown, O. Bonness, C. Hahn || gunter@cisco.com, cpopovic@cisco.com, tjc@ecs.soton.ac.uk, Olaf.Bonness@t-systems.com, HahnC@t-systems.com +# RFC5376 || N. Bitar, R. Zhang, K. Kumaki || nabil.n.bitar@verizon.com, ke-kumaki@kddi.com, Raymond.zhang@bt.com +# RFC5377 || J. Halpern, Ed. || jmh@joelhalpern.com +# RFC5378 || S. Bradner, Ed., J. Contreras, Ed. || sob@harvard.edu, jorge.contreras@wilmerhale.com +# RFC5379 || M. Munakata, S. Schubert, T. Ohba || munakata.mayumi@lab.ntt.co.jp, shida@ntt-at.com, ohba.takumi@lab.ntt.co.jp +# RFC5380 || H. Soliman, C. Castelluccia, K. ElMalki, L. Bellier || hesham@elevatemobile.com, claude.castelluccia@inria.fr, karim@athonet.com, ludovic.bellier@inria.fr +# RFC5381 || T. Iijima, Y. Atarashi, H. Kimura, M. Kitani, H. Okita || tomoyuki.iijima@alaxala.com, atarashi@alaxala.net, h-kimura@alaxala.net, makoto.kitani@alaxala.com, hideki.okita.pf@hitachi.com +# RFC5382 || S. Guha, Ed., K. Biswas, B. Ford, S. Sivakumar, P. Srisuresh || saikat@cs.cornell.edu, kbiswas@cisco.com, baford@mpi-sws.org, ssenthil@cisco.com, srisuresh@yahoo.com +# RFC5383 || R. Gellens || randy@qualcomm.com +# RFC5384 || A. Boers, I. Wijnands, E. Rosen || aboers@cisco.com, ice@cisco.com, erosen@cisco.com +# RFC5385 || J. Touch || touch@isi.edu +# RFC5386 || N. Williams, M. Richardson || Nicolas.Williams@sun.com, mcr@sandelman.ottawa.on.ca +# RFC5387 || J. Touch, D. Black, Y. Wang || touch@isi.edu, black_david@emc.com, yu-shun.wang@microsoft.com +# RFC5388 || S. Niccolini, S. Tartarelli, J. Quittek, T. Dietz, M. Swany || saverio.niccolini@nw.neclab.eu, sandra.tartarelli@nw.neclab.eu, quittek@nw.neclab.eu, thomas.dietz@nw.neclab.eu, swany@UDel.Edu +# RFC5389 || J. Rosenberg, R. Mahy, P. Matthews, D. Wing || jdrosen@cisco.com, rohan@ekabal.com, philip_matthews@magma.ca, dwing-ietf@fuggles.com +# RFC5390 || J. Rosenberg || jdrosen@cisco.com +# RFC5391 || A. Sollaud || aurelien.sollaud@orange-ftgroup.com +# RFC5392 || M. Chen, R. Zhang, X. Duan || mach@huawei.com, zhangrenhai@huawei.com, duanxiaodong@chinamobile.com +# RFC5393 || R. Sparks, Ed., S. Lawrence, A. Hawrylyshen, B. Campen || RjS@nostrum.com, scott.lawrence@nortel.com, alan.ietf@polyphase.ca, bcampen@estacado.net +# RFC5394 || I. Bryskin, D. Papadimitriou, L. Berger, J. Ash || ibryskin@advaoptical.com, dimitri.papadimitriou@alcatel.be, lberger@labn.net, gash5107@yahoo.com +# RFC5395 || D. Eastlake 3rd || d3e3e3@gmail.com +# RFC5396 || G. Huston, G. Michaelson || gih@apnic.net, ggm@apnic.net +# RFC5397 || W. Sanchez, C. Daboo || wsanchez@wsanchez.net, cyrus@daboo.name +# RFC5398 || G. Huston || gih@apnic.net +# RFC5401 || B. Adamson, C. Bormann, M. Handley, J. Macker || adamson@itd.nrl.navy.mil, cabo@tzi.org, M.Handley@cs.ucl.ac.uk, macker@itd.nrl.navy.mil +# RFC5402 || T. Harding, Ed. || tharding@us.axway.com +# RFC5403 || M. Eisler || mike@eisler.com +# RFC5404 || M. Westerlund, I. Johansson || magnus.westerlund@ericsson.com, ingemar.s.johansson@ericsson.com +# RFC5405 || L. Eggert, G. Fairhurst || lars.eggert@nokia.com, gorry@erg.abdn.ac.uk +# RFC5406 || S. Bellovin || bellovin@acm.org +# RFC5407 || M. Hasebe, J. Koshiko, Y. Suzuki, T. Yoshikawa, P. Kyzivat || hasebe.miki@east.ntt.co.jp, j.koshiko@east.ntt.co.jp, suzuki.yasushi@lab.ntt.co.jp, tomoyuki.yoshikawa@east.ntt.co.jp, pkyzivat@cisco.com +# RFC5408 || G. Appenzeller, L. Martin, M. Schertler || appenz@cs.stanford.edu, martin@voltage.com, mschertler@us.axway.com +# RFC5409 || L. Martin, M. Schertler || martin@voltage.com, mschertler@us.axway.com +# RFC5410 || A. Jerichow, Ed., L. Piron || anja.jerichow@nsn.com, laurent.piron@nagravision.com +# RFC5411 || J. Rosenberg || jdrosen@cisco.com +# RFC5412 || P. Calhoun, R. Suri, N. Cam-Winget, M. Williams, S. Hares, B. O'Hara, S. Kelly || pcalhoun@cisco.com, rsuri@cisco.com, ncamwing@cisco.com, gwhiz@gwhiz.com, shares@ndzh.com, bob.ohara@computer.org, scott@hyperthought.com +# RFC5413 || P. Narasimhan, D. Harkins, S. Ponnuswamy || partha@arubanetworks.com, dharkins@arubanetworks.com, subbu@arubanetworks.com +# RFC5414 || S. Iino, S. Govindan, M. Sugiura, H. Cheng || iino.satoshi@jp.panasonic.com, saravanan.govindan@sg.panasonic.com, sugiura.mikihito@jp.panasonic.com, hong.cheng@sg.panasonic.com +# RFC5415 || P. Calhoun, Ed., M. Montemurro, Ed., D. Stanley, Ed. || pcalhoun@cisco.com, mmontemurro@rim.com, dstanley@arubanetworks.com +# RFC5416 || P. Calhoun, Ed., M. Montemurro, Ed., D. Stanley, Ed. || pcalhoun@cisco.com, mmontemurro@rim.com, dstanley@arubanetworks.com +# RFC5417 || P. Calhoun || pcalhoun@cisco.com +# RFC5418 || S. Kelly, T. Clancy || scott@hyperthought.com, clancy@LTSnet.net +# RFC5419 || B. Patil, G. Dommety || basavaraj.patil@nokia.com, gdommety@cisco.com +# RFC5420 || A. Farrel, Ed., D. Papadimitriou, JP. Vasseur, A. Ayyangarps || adrian@olddog.co.uk, dimitri.papadimitriou@alcatel.be, jpv@cisco.com, arthi@juniper.net +# RFC5421 || N. Cam-Winget, H. Zhou || ncamwing@cisco.com, hzhou@cisco.com +# RFC5422 || N. Cam-Winget, D. McGrew, J. Salowey, H. Zhou || ncamwing@cisco.com, mcgrew@cisco.com, jsalowey@cisco.com, hzhou@cisco.com +# RFC5423 || R. Gellens, C. Newman || rg+ietf@qualcomm.com, chris.newman@sun.com +# RFC5424 || R. Gerhards || rgerhards@adiscon.com +# RFC5425 || F. Miao, Ed., Y. Ma, Ed., J. Salowey, Ed. || miaofy@huawei.com, myz@huawei.com, jsalowey@cisco.com +# RFC5426 || A. Okmianski || aokmians@cisco.com +# RFC5427 || G. Keeni || glenn@cysols.com +# RFC5428 || S. Channabasappa, W. De Ketelaere, E. Nechamkin || Sumanth@cablelabs.com, deketelaere@tComLabs.com, enechamkin@broadcom.com +# RFC5429 || A. Stone, Ed. || aaron@serendipity.palo-alto.ca.us +# RFC5430 || M. Salter, E. Rescorla, R. Housley || msalter@restarea.ncsc.mil, ekr@rtfm.com, housley@vigilsec.com +# RFC5431 || D. Sun || dongsun@alcatel-lucent.com +# RFC5432 || J. Polk, S. Dhesikan, G. Camarillo || jmpolk@cisco.com, sdhesika@cisco.com, Gonzalo.Camarillo@ericsson.com +# RFC5433 || T. Clancy, H. Tschofenig || clancy@ltsnet.net, Hannes.Tschofenig@gmx.net +# RFC5434 || T. Narten || narten@us.ibm.com +# RFC5435 || A. Melnikov, Ed., B. Leiba, Ed., W. Segmuller, T. Martin || Alexey.Melnikov@isode.com, leiba@watson.ibm.com, werewolf@us.ibm.com, timmartin@alumni.cmu.edu +# RFC5436 || B. Leiba, M. Haardt || leiba@watson.ibm.com, michael.haardt@freenet.ag +# RFC5437 || P. Saint-Andre, A. Melnikov || ietf@stpeter.im, Alexey.Melnikov@isode.com +# RFC5438 || E. Burger, H. Khartabil || eburger@standardstrack.com, hisham.khartabil@gmail.com +# RFC5439 || S. Yasukawa, A. Farrel, O. Komolafe || s.yasukawa@hco.ntt.co.jp, adrian@olddog.co.uk, femi@cisco.com +# RFC5440 || JP. Vasseur, Ed., JL. Le Roux, Ed. || jpv@cisco.com, jeanlouis.leroux@orange-ftgroup.com +# RFC5441 || JP. Vasseur, Ed., R. Zhang, N. Bitar, JL. Le Roux || jpv@cisco.com, raymond.zhang@bt.com, nabil.n.bitar@verizon.com, jeanlouis.leroux@orange-ftgroup.com +# RFC5442 || E. Burger, G. Parsons || eburger@standardstrack.com, gparsons@nortel.com +# RFC5443 || M. Jork, A. Atlas, L. Fang || Markus.Jork@genband.com, alia.atlas@bt.com, lufang@cisco.com +# RFC5444 || T. Clausen, C. Dearlove, J. Dean, C. Adjih || T.Clausen@computer.org, chris.dearlove@baesystems.com, jdean@itd.nrl.navy.mil, Cedric.Adjih@inria.fr +# RFC5445 || M. Watson || mark@digitalfountain.com +# RFC5446 || J. Korhonen, U. Nilsson || jouni.nospam@gmail.com, ulf.s.nilsson@teliasonera.com +# RFC5447 || J. Korhonen, Ed., J. Bournelle, H. Tschofenig, C. Perkins, K. Chowdhury || jouni.nospam@gmail.com, julien.bournelle@orange-ftgroup.com, Hannes.Tschofenig@nsn.com, charliep@wichorus.com, kchowdhury@starentnetworks.com +# RFC5448 || J. Arkko, V. Lehtovirta, P. Eronen || jari.arkko@piuha.net, vesa.lehtovirta@ericsson.com, pe@iki.fi +# RFC5449 || E. Baccelli, P. Jacquet, D. Nguyen, T. Clausen || Emmanuel.Baccelli@inria.fr, Philippe.Jacquet@inria.fr, dang.nguyen@crc.ca, T.Clausen@computer.org +# RFC5450 || D. Singer, H. Desineni || singer@apple.com, hd@qualcomm.com +# RFC5451 || M. Kucherawy || msk+ietf@sendmail.com +# RFC5452 || A. Hubert, R. van Mook || bert.hubert@netherlabs.nl, remco@eu.equinix.com +# RFC5453 || S. Krishnan || suresh.krishnan@ericsson.com +# RFC5454 || G. Tsirtsis, V. Park, H. Soliman || tsirtsis@googlemail.com, vpark@qualcomm.com, hesham@elevatemobile.com +# RFC5455 || S. Sivabalan, Ed., J. Parker, S. Boutros, K. Kumaki || msiva@cisco.com, jdparker@cisco.com, sboutros@cisco.com, ke-kumaki@kddi.com +# RFC5456 || M. Spencer, B. Capouch, E. Guy, Ed., F. Miller, K. Shumard || markster@digium.com, brianc@saintjoe.edu, edguy@emcsw.com, mail@frankwmiller.net, kshumard@gmail.com +# RFC5457 || E. Guy, Ed. || edguy@emcsw.com +# RFC5458 || H. Cruickshank, P. Pillai, M. Noisternig, S. Iyengar || h.cruickshank@surrey.ac.uk, p.pillai@bradford.ac.uk, mnoist@cosy.sbg.ac.at, sunil.iyengar@logica.com +# RFC5459 || A. Sollaud || aurelien.sollaud@orange-ftgroup.com +# RFC5460 || M. Stapp || mjs@cisco.com +# RFC5461 || F. Gont || fernando@gont.com.ar +# RFC5462 || L. Andersson, R. Asati || loa@pi.nu, rajiva@cisco.com +# RFC5463 || N. Freed || ned.freed@mrochek.com +# RFC5464 || C. Daboo || cyrus@daboo.name +# RFC5465 || A. Gulbrandsen, C. King, A. Melnikov || arnt@oryx.com, Curtis.King@isode.com, Alexey.Melnikov@isode.com +# RFC5466 || A. Melnikov, C. King || Alexey.Melnikov@isode.com, Curtis.King@isode.com +# RFC5467 || L. Berger, A. Takacs, D. Caviglia, D. Fedyk, J. Meuric || lberger@labn.net, attila.takacs@ericsson.com, diego.caviglia@ericsson.com, dwfedyk@nortel.com, julien.meuric@orange-ftgroup.com +# RFC5468 || S. Dasgupta, J. de Oliveira, JP. Vasseur || sukrit@ece.drexel.edu, jau@ece.drexel.edu, jpv@cisco.com +# RFC5469 || P. Eronen, Ed. || pe@iki.fi +# RFC5470 || G. Sadasivan, N. Brownlee, B. Claise, J. Quittek || gsadasiv@rohati.com, n.brownlee@auckland.ac.nz, bclaise@cisco.com, quittek@nw.neclab.eu +# RFC5471 || C. Schmoll, P. Aitken, B. Claise || carsten.schmoll@fokus.fraunhofer.de, paitken@cisco.com, bclaise@cisco.com +# RFC5472 || T. Zseby, E. Boschi, N. Brownlee, B. Claise || tanja.zseby@fokus.fraunhofer.de, elisa.boschi@hitachi-eu.com, nevil@caida.org, bclaise@cisco.com +# RFC5473 || E. Boschi, L. Mark, B. Claise || elisa.boschi@hitachi-eu.com, lutz.mark@ifam.fraunhofer.de, bclaise@cisco.com +# RFC5474 || N. Duffield, Ed., D. Chiou, B. Claise, A. Greenberg, M. Grossglauser, J. Rexford || duffield@research.att.com, Derek@ece.utexas.edu, bclaise@cisco.com, albert@microsoft.com, matthias.grossglauser@epfl.ch, jrex@cs.princeton.edu +# RFC5475 || T. Zseby, M. Molina, N. Duffield, S. Niccolini, F. Raspall || tanja.zseby@fokus.fraunhofer.de, maurizio.molina@dante.org.uk, duffield@research.att.com, saverio.niccolini@netlab.nec.de, fredi@entel.upc.es +# RFC5476 || B. Claise, Ed., A. Johnson, J. Quittek || bclaise@cisco.com, andrjohn@cisco.com, quittek@nw.neclab.eu +# RFC5477 || T. Dietz, B. Claise, P. Aitken, F. Dressler, G. Carle || Thomas.Dietz@nw.neclab.eu, bclaise@cisco.com, paitken@cisco.com, dressler@informatik.uni-erlangen.de, carle@informatik.uni-tuebingen.de +# RFC5478 || J. Polk || jmpolk@cisco.com +# RFC5479 || D. Wing, Ed., S. Fries, H. Tschofenig, F. Audet || dwing-ietf@fuggles.com, steffen.fries@siemens.com, Hannes.Tschofenig@nsn.com, audet@nortel.com +# RFC5480 || S. Turner, D. Brown, K. Yiu, R. Housley, T. Polk || turners@ieca.com, kelviny@microsoft.com, dbrown@certicom.com, housley@vigilsec.com, wpolk@nist.gov +# RFC5481 || A. Morton, B. Claise || acmorton@att.com, bclaise@cisco.com +# RFC5482 || L. Eggert, F. Gont || lars.eggert@nokia.com, fernando@gont.com.ar +# RFC5483 || L. Conroy, K. Fujiwara || lconroy@insensate.co.uk, fujiwara@jprs.co.jp +# RFC5484 || D. Singer || singer@apple.com +# RFC5485 || R. Housley || housley@vigilsec.com +# RFC5486 || D. Malas, Ed., D. Meyer, Ed. || d.malas@cablelabs.com, dmm@1-4-5.net +# RFC5487 || M. Badra || badra@isima.fr +# RFC5488 || S. Gundavelli, G. Keeni, K. Koide, K. Nagami || sgundave@cisco.com, glenn@cysols.com, ka-koide@kddi.com, nagami@inetcore.com +# RFC5489 || M. Badra, I. Hajjeh || badra@isima.fr, ibrahim.hajjeh@ineovation.fr +# RFC5490 || A. Melnikov || Alexey.Melnikov@isode.com +# RFC5491 || J. Winterbottom, M. Thomson, H. Tschofenig || james.winterbottom@andrew.com, martin.thomson@andrew.com, Hannes.Tschofenig@gmx.net +# RFC5492 || J. Scudder, R. Chandra || jgs@juniper.net, rchandra@sonoasystems.com +# RFC5493 || D. Caviglia, D. Bramanti, D. Li, D. McDysan || diego.caviglia@ericsson.com, dino.bramanti@ericsson.com, danli@huawei.com, dave.mcdysan@verizon.com +# RFC5494 || J. Arkko, C. Pignataro || jari.arkko@piuha.net, cpignata@cisco.com +# RFC5495 || D. Li, J. Gao, A. Satyanarayana, S. Bardalai || danli@huawei.com, gjhhit@huawei.com, asatyana@cisco.com, snigdho.bardalai@us.fujitsu.com +# RFC5496 || IJ. Wijnands, A. Boers, E. Rosen || ice@cisco.com, aboers@cisco.com, erosen@cisco.com +# RFC5497 || T. Clausen, C. Dearlove || T.Clausen@computer.org, chris.dearlove@baesystems.com +# RFC5498 || I. Chakeres || ian.chakeres@gmail.com +# RFC5501 || Y. Kamite, Ed., Y. Wada, Y. Serbest, T. Morin, L. Fang || y.kamite@ntt.com, wada.yuichiro@lab.ntt.co.jp, yetik_serbest@labs.att.com, thomas.morin@francetelecom.com, lufang@cisco.com +# RFC5502 || J. van Elburg || HansErik.van.Elburg@ericsson.com +# RFC5503 || F. Andreasen, B. McKibben, B. Marshall || fandreas@cisco.com, B.McKibben@cablelabs.com, wtm@research.att.com +# RFC5504 || K. Fujiwara, Ed., Y. Yoneya, Ed. || fujiwara@jprs.co.jp, yone@jprs.co.jp +# RFC5505 || B. Aboba, D. Thaler, L. Andersson, S. Cheshire || bernarda@microsoft.com, dthaler@microsoft.com, loa.andersson@ericsson.com, cheshire@apple.com +# RFC5506 || I. Johansson, M. Westerlund || ingemar.s.johansson@ericsson.com, magnus.westerlund@ericsson.com +# RFC5507 || IAB, P. Faltstrom, Ed., R. Austein, Ed., P. Koch, Ed. || iab@iab.org, paf@cisco.com, sra@isc.org, pk@denic.de +# RFC5508 || P. Srisuresh, B. Ford, S. Sivakumar, S. Guha || srisuresh@yahoo.com, baford@mpi-sws.org, ssenthil@cisco.com, saikat@cs.cornell.edu +# RFC5509 || S. Loreto || Salvatore.Loreto@ericsson.com +# RFC5510 || J. Lacan, V. Roca, J. Peltotalo, S. Peltotalo || jerome.lacan@isae.fr, vincent.roca@inria.fr, jani.peltotalo@tut.fi, sami.peltotalo@tut.fi +# RFC5511 || A. Farrel || adrian@olddog.co.uk +# RFC5512 || P. Mohapatra, E. Rosen || pmohapat@cisco.com, erosen@cisco.com +# RFC5513 || A. Farrel || adrian@olddog.co.uk +# RFC5514 || E. Vyncke || evyncke@cisco.com +# RFC5515 || V. Mammoliti, C. Pignataro, P. Arberg, J. Gibbons, P. Howard || vince@cisco.com, cpignata@cisco.com, parberg@redback.com, jgibbons@juniper.net, howsoft@mindspring.com +# RFC5516 || M. Jones, L. Morand || mark.jones@bridgewatersystems.com, lionel.morand@orange-ftgroup.com +# RFC5517 || S. HomChaudhuri, M. Foschiano || sanjibhc@gmail.com, foschia@cisco.com +# RFC5518 || P. Hoffman, J. Levine, A. Hathcock || paul.hoffman@domain-assurance.org, john.levine@domain-assurance.org, arvel.hathcock@altn.com +# RFC5519 || J. Chesterfield, B. Haberman, Ed. || julian.chesterfield@cl.cam.ac.uk, brian@innovationslab.net +# RFC5520 || R. Bradford, Ed., JP. Vasseur, A. Farrel || rbradfor@cisco.com, jpv@cisco.com, adrian@olddog.co.uk +# RFC5521 || E. Oki, T. Takeda, A. Farrel || oki@ice.uec.ac.jp, takeda.tomonori@lab.ntt.co.jp, adrian@olddog.co.uk +# RFC5522 || W. Eddy, W. Ivancic, T. Davis || weddy@grc.nasa.gov, William.D.Ivancic@grc.nasa.gov, Terry.L.Davis@boeing.com +# RFC5523 || L. Berger || lberger@labn.net +# RFC5524 || D. Cridland || dave.cridland@isode.com +# RFC5525 || T. Dreibholz, J. Mulik || dreibh@iem.uni-due.de, jaiwant@mulik.com +# RFC5526 || J. Livingood, P. Pfautz, R. Stastny || jason_livingood@cable.comcast.com, ppfautz@att.com, richard.stastny@gmail.com +# RFC5527 || M. Haberler, O. Lendl, R. Stastny || ietf@mah.priv.at, otmar.lendl@enum.at, richardstastny@gmail.com +# RFC5528 || A. Kato, M. Kanda, S. Kanno || akato@po.ntts.co.jp, kanda.masayuki@lab.ntt.co.jp, kanno-s@po.ntts.co.jp +# RFC5529 || A. Kato, M. Kanda, S. Kanno || akato@po.ntts.co.jp, kanda.masayuki@lab.ntt.co.jp, kanno-s@po.ntts.co.jp +# RFC5530 || A. Gulbrandsen || arnt@oryx.com +# RFC5531 || R. Thurlow || robert.thurlow@sun.com +# RFC5532 || T. Talpey, C. Juszczak || tmtalpey@gmail.com, chetnh@earthlink.net +# RFC5533 || E. Nordmark, M. Bagnulo || erik.nordmark@sun.com, marcelo@it.uc3m.es +# RFC5534 || J. Arkko, I. van Beijnum || jari.arkko@ericsson.com, iljitsch@muada.com +# RFC5535 || M. Bagnulo || marcelo@it.uc3m.es +# RFC5536 || K. Murchison, Ed., C. Lindsey, D. Kohn || murch@andrew.cmu.edu, chl@clerew.man.ac.uk, dan@dankohn.com +# RFC5537 || R. Allbery, Ed., C. Lindsey || rra@stanford.edu, chl@clerew.man.ac.uk +# RFC5538 || F. Ellermann || hmdmhdfmhdjmzdtjmzdtzktdkztdjz@gmail.com +# RFC5539 || M. Badra || badra@isima.fr +# RFC5540 || RFC Editor || rfc-editor@rfc-editor.org +# RFC5541 || JL. Le Roux, JP. Vasseur, Y. Lee || jeanlouis.leroux@orange-ftgroup.com, jpv@cisco.com, ylee@huawei.com +# RFC5542 || T. Nadeau, Ed., D. Zelig, Ed., O. Nicklass, Ed. || tom.nadeau@bt.com, davidz@oversi.com, orlyn@radvision.com +# RFC5543 || H. Ould-Brahim, D. Fedyk, Y. Rekhter || hbrahim@nortel.com, donald.fedyk@alcatel-lucent.com, yakov@juniper.com +# RFC5544 || A. Santoni || adriano.santoni@actalis.it +# RFC5545 || B. Desruisseaux, Ed. || bernard.desruisseaux@oracle.com +# RFC5546 || C. Daboo, Ed. || cyrus@daboo.name +# RFC5547 || M. Garcia-Martin, M. Isomaki, G. Camarillo, S. Loreto, P. Kyzivat || miguel.a.garcia@ericsson.com, markus.isomaki@nokia.com, Gonzalo.Camarillo@ericsson.com, Salvatore.Loreto@ericsson.com, pkyzivat@cisco.com +# RFC5548 || M. Dohler, Ed., T. Watteyne, Ed., T. Winter, Ed., D. Barthel, Ed. || mischa.dohler@cttc.es, watteyne@eecs.berkeley.edu, wintert@acm.org, Dominique.Barthel@orange-ftgroup.com +# RFC5549 || F. Le Faucheur, E. Rosen || flefauch@cisco.com, erosen@cisco.com +# RFC5550 || D. Cridland, Ed., A. Melnikov, Ed., S. Maes, Ed. || dave.cridland@isode.com, Alexey.Melnikov@isode.com, stephane.maes@oracle.com +# RFC5551 || R. Gellens, Ed. || rg+ietf@qualcomm.com +# RFC5552 || D. Burke, M. Scott || daveburke@google.com, Mark.Scott@genesyslab.com +# RFC5553 || A. Farrel, Ed., R. Bradford, JP. Vasseur || adrian@olddog.co.uk, rbradfor@cisco.com, jpv@cisco.com +# RFC5554 || N. Williams || Nicolas.Williams@sun.com +# RFC5555 || H. Soliman, Ed. || hesham@elevatemobile.com +# RFC5556 || J. Touch, R. Perlman || touch@isi.edu, Radia.Perlman@sun.com +# RFC5557 || Y. Lee, JL. Le Roux, D. King, E. Oki || ylee@huawei.com, jeanlouis.leroux@orange-ftgroup.com, daniel@olddog.co.uk, oki@ice.uec.ac.jp +# RFC5558 || F. Templin, Ed. || fltemplin@acm.org +# RFC5559 || P. Eardley, Ed. || philip.eardley@bt.com +# RFC5560 || H. Uijterwaal || henk@ripe.net +# RFC5561 || B. Thomas, K. Raza, S. Aggarwal, R. Aggarwal, JL. Le Roux || bobthomas@alum.mit.edu, skraza@cisco.com, shivani@juniper.net, rahul@juniper.net, jeanlouis.leroux@orange-ftgroup.com +# RFC5562 || A. Kuzmanovic, A. Mondal, S. Floyd, K. Ramakrishnan || akuzma@northwestern.edu, a-mondal@northwestern.edu, floyd@icir.org, kkrama@research.att.com +# RFC5563 || K. Leung, G. Dommety, P. Yegani, K. Chowdhury || kleung@cisco.com, gdommety@cisco.com, pyegani@cisco.com, kchowdhury@starentnetworks.com +# RFC5564 || A. El-Sherbiny, M. Farah, I. Oueichek, A. Al-Zoman || El-sherbiny@un.org, farah14@un.org, oueichek@scs-net.org, azoman@citc.gov.sa +# RFC5565 || J. Wu, Y. Cui, C. Metz, E. Rosen || jianping@cernet.edu.cn, yong@csnet1.cs.tsinghua.edu.cn, chmetz@cisco.com, erosen@cisco.com +# RFC5566 || L. Berger, R. White, E. Rosen || lberger@labn.net, riw@cisco.com, erosen@cisco.com +# RFC5567 || T. Melanchuk, Ed. || tim.melanchuk@gmail.com +# RFC5568 || R. Koodli, Ed. || rkoodli@starentnetworks.com +# RFC5569 || R. Despres || remi.despres@free.fr +# RFC5570 || M. StJohns, R. Atkinson, G. Thomas || mstjohns@comcast.net, rja@extremenetworks.com, none +# RFC5571 || B. Storer, C. Pignataro, Ed., M. Dos Santos, B. Stevant, Ed., L. Toutain, J. Tremblay || bstorer@cisco.com, cpignata@cisco.com, mariados@cisco.com, bruno.stevant@telecom-bretagne.eu, laurent.toutain@telecom-bretagne.eu, jf@jftremblay.com +# RFC5572 || M. Blanchet, F. Parent || Marc.Blanchet@viagenie.ca, Florent.Parent@beon.ca +# RFC5573 || M. Thomson || martin.thomson@andrew.com +# RFC5574 || G. Herlein, J. Valin, A. Heggestad, A. Moizard || gherlein@herlein.com, jean-marc.valin@usherbrooke.ca, aeh@db.org, jack@atosc.org +# RFC5575 || P. Marques, N. Sheth, R. Raszuk, B. Greene, J. Mauch, D. McPherson || roque@cisco.com, nsheth@juniper.net, raszuk@cisco.com, bgreene@juniper.net, jmauch@us.ntt.net, danny@arbor.net +# RFC5576 || J. Lennox, J. Ott, T. Schierl || jonathan@vidyo.com, jo@acm.org, ts@thomas-schierl.de +# RFC5577 || P. Luthi, R. Even || patrick.luthi@tandberg.no, ron.even.tlv@gmail.com +# RFC5578 || B. Berry, Ed., S. Ratliff, E. Paradise, T. Kaiser, M. Adams || bberry@cisco.com, sratliff@cisco.com, pdice@cisco.com, timothy.kaiser@harris.com, Michael.D.Adams@L-3com.com +# RFC5579 || F. Templin, Ed. || fltemplin@acm.org +# RFC5580 || H. Tschofenig, Ed., F. Adrangi, M. Jones, A. Lior, B. Aboba || Hannes.Tschofenig@gmx.net, farid.adrangi@intel.com, mark.jones@bridgewatersystems.com, avi@bridgewatersystems.com, bernarda@microsoft.com +# RFC5581 || D. Shaw || dshaw@jabberwocky.com +# RFC5582 || H. Schulzrinne || hgs+ecrit@cs.columbia.edu +# RFC5583 || T. Schierl, S. Wenger || ts@thomas-schierl.de, stewe@stewe.org +# RFC5584 || M. Hatanaka, J. Matsumoto || actech@jp.sony.com, actech@jp.sony.com +# RFC5585 || T. Hansen, D. Crocker, P. Hallam-Baker || tony+dkimov@maillennium.att.com, dcrocker@bbiw.net, phillip@hallambaker.com +# RFC5586 || M. Bocci, Ed., M. Vigoureux, Ed., S. Bryant, Ed. || matthew.bocci@alcatel-lucent.com, martin.vigoureux@alcatel-lucent.com, stbryant@cisco.com +# RFC5587 || N. Williams || Nicolas.Williams@sun.com +# RFC5588 || N. Williams || Nicolas.Williams@sun.com +# RFC5589 || R. Sparks, A. Johnston, Ed., D. Petrie || RjS@nostrum.com, alan@sipstation.com, dan.ietf@SIPez.com +# RFC5590 || D. Harrington, J. Schoenwaelder || ietfdbh@comcast.net, j.schoenwaelder@jacobs-university.de +# RFC5591 || D. Harrington, W. Hardaker || ietfdbh@comcast.net, ietf@hardakers.net +# RFC5592 || D. Harrington, J. Salowey, W. Hardaker || ietfdbh@comcast.net, jsalowey@cisco.com, ietf@hardakers.net +# RFC5593 || N. Cook || neil.cook@noware.co.uk +# RFC5594 || J. Peterson, A. Cooper || jon.peterson@neustar.biz, acooper@cdt.org +# RFC5595 || G. Fairhurst || gorry@erg.abdn.ac.uk +# RFC5596 || G. Fairhurst || gorry@erg.abdn.ac.uk +# RFC5597 || R. Denis-Courmont || rem@videolan.org +# RFC5598 || D. Crocker || dcrocker@bbiw.net +# RFC5601 || T. Nadeau, Ed., D. Zelig, Ed. || thomas.nadeau@bt.com, davidz@oversi.com +# RFC5602 || D. Zelig, Ed., T. Nadeau, Ed. || davidz@oversi.com, tom.nadeau@bt.com +# RFC5603 || D. Zelig, Ed., T. Nadeau, Ed. || davidz@oversi.com, tom.nadeau@bt.com +# RFC5604 || O. Nicklass || orlyn@radvision.com +# RFC5605 || O. Nicklass, T. Nadeau || orlyn@radvision.com, tom.nadeau@bt.com +# RFC5606 || J. Peterson, T. Hardie, J. Morris || jon.peterson@neustar.biz, hardie@qualcomm.com, jmorris@cdt.org +# RFC5607 || D. Nelson, G. Weber || dnelson@elbrysnetworks.com, gdweber@gmail.com +# RFC5608 || K. Narayan, D. Nelson || kaushik_narayan@yahoo.com, dnelson@elbrysnetworks.com +# RFC5609 || V. Fajardo, Ed., Y. Ohba, R. Marin-Lopez || vfajardo@research.telcordia.com, yoshihiro.ohba@toshiba.co.jp, rafa@um.es +# RFC5610 || E. Boschi, B. Trammell, L. Mark, T. Zseby || elisa.boschi@hitachi-eu.com, brian.trammell@hitachi-eu.com, lutz.mark@ifam.fraunhofer.de, tanja.zseby@fokus.fraunhofer.de +# RFC5611 || A. Vainshtein, S. Galtzur || Alexander.Vainshtein@ecitele.com, sharon.galtzur@rebellion.co.uk +# RFC5612 || P. Eronen, D. Harrington || pe@iki.fi, dharrington@huawei.com +# RFC5613 || A. Zinin, A. Roy, L. Nguyen, B. Friedman, D. Yeung || alex.zinin@alcatel-lucent.com, akr@cisco.com, lhnguyen@cisco.com, barryf@google.com, myeung@cisco.com +# RFC5614 || R. Ogier, P. Spagnolo || rich.ogier@earthlink.net, phillipspagnolo@gmail.com +# RFC5615 || C. Groves, Y. Lin || Christian.Groves@nteczone.com, linyangbo@huawei.com +# RFC5616 || N. Cook || neil.cook@noware.co.uk +# RFC5617 || E. Allman, J. Fenton, M. Delany, J. Levine || eric+dkim@sendmail.org, fenton@bluepopcorn.net, markd+dkim@yahoo-inc.com, standards@taugh.com +# RFC5618 || A. Morton, K. Hedayat || acmorton@att.com, kaynam.hedayat@exfo.com +# RFC5619 || S. Yamamoto, C. Williams, H. Yokota, F. Parent || shu@nict.go.jp, carlw@mcsr-labs.org, yokota@kddilabs.jp, Florent.Parent@beon.ca +# RFC5620 || O. Kolkman, Ed., IAB || olaf@nlnetlabs.nl, iab@iab.org +# RFC5621 || G. Camarillo || Gonzalo.Camarillo@ericsson.com +# RFC5622 || S. Floyd, E. Kohler || floyd@icir.org, kohler@cs.ucla.edu +# RFC5623 || E. Oki, T. Takeda, JL. Le Roux, A. Farrel || oki@ice.uec.ac.jp, takeda.tomonori@lab.ntt.co.jp, jeanlouis.leroux@orange-ftgroup.com, adrian@olddog.co.uk +# RFC5624 || J. Korhonen, Ed., H. Tschofenig, E. Davies || jouni.korhonen@nsn.com, Hannes.Tschofenig@gmx.net, elwynd@dial.pipex.com +# RFC5625 || R. Bellis || ray.bellis@nominet.org.uk +# RFC5626 || C. Jennings, Ed., R. Mahy, Ed., F. Audet, Ed. || fluffy@cisco.com, rohan@ekabal.com, francois.audet@skypelabs.com +# RFC5627 || J. Rosenberg || jdrosen@cisco.com +# RFC5628 || P. Kyzivat || pkyzivat@cisco.com +# RFC5629 || J. Rosenberg || jdrosen@cisco.com +# RFC5630 || F. Audet || francois.audet@skypelabs.com +# RFC5631 || R. Shacham, H. Schulzrinne, S. Thakolsri, W. Kellerer || shacham@cs.columbia.edu, hgs@cs.columbia.edu, thakolsri@docomolab-euro.com, kellerer@docomolab-euro.com +# RFC5632 || C. Griffiths, J. Livingood, L. Popkin, R. Woundy, Y. Yang || chris_griffiths@cable.comcast.com, jason_livingood@cable.comcast.com, laird@pando.com, richard_woundy@cable.comcast.com, yry@cs.yale.edu +# RFC5633 || S. Dawkins, Ed. || spencer@wonderhamster.org +# RFC5634 || G. Fairhurst, A. Sathiaseelan || gorry@erg.abdn.ac.uk, arjuna@erg.abdn.ac.uk +# RFC5635 || W. Kumari, D. McPherson || warren@kumari.net, danny@arbor.net +# RFC5636 || S. Park, H. Park, Y. Won, J. Lee, S. Kent || shpark@kisa.or.kr, hrpark@kisa.or.kr, yjwon@kisa.or.kr, jilee@kisa.or.kr, kent@bbn.com +# RFC5637 || G. Giaretta, I. Guardini, E. Demaria, J. Bournelle, R. Lopez || gerardo@qualcomm.com, ivano.guardini@telecomitalia.it, elena.demaria@telecomitalia.it, julien.bournelle@gmail.com, rafa@dif.um.es +# RFC5638 || H. Sinnreich, Ed., A. Johnston, E. Shim, K. Singh || henrys@adobe.com, alan@sipstation.com, eunsooshim@gmail.com, kns10@cs.columbia.edu +# RFC5639 || M. Lochter, J. Merkle || manfred.lochter@bsi.bund.de, johannes.merkle@secunet.com +# RFC5640 || C. Filsfils, P. Mohapatra, C. Pignataro || cfilsfil@cisco.com, pmohapat@cisco.com, cpignata@cisco.com +# RFC5641 || N. McGill, C. Pignataro || nmcgill@cisco.com, cpignata@cisco.com +# RFC5642 || S. Venkata, S. Harwani, C. Pignataro, D. McPherson || svenkata@google.com, sharwani@cisco.com, cpignata@cisco.com, danny@arbor.net +# RFC5643 || D. Joyal, Ed., V. Manral, Ed. || djoyal@nortel.com, vishwas@ipinfusion.com +# RFC5644 || E. Stephan, L. Liang, A. Morton || emile.stephan@orange-ftgroup.com, L.Liang@surrey.ac.uk, acmorton@att.com +# RFC5645 || D. Ewell, Ed. || doug@ewellic.org +# RFC5646 || A. Phillips, Ed., M. Davis, Ed. || addison@inter-locale.com, markdavis@google.com +# RFC5647 || K. Igoe, J. Solinas || kmigoe@nsa.gov, jasolin@orion.ncsc.mil +# RFC5648 || R. Wakikawa, Ed., V. Devarapalli, G. Tsirtsis, T. Ernst, K. Nagami || ryuji.wakikawa@gmail.com, vijay@wichorus.com, Tsirtsis@gmail.com, thierry.ernst@inria.fr, nagami@inetcore.com +# RFC5649 || R. Housley, M. Dworkin || housley@vigilsec.com, dworkin@nist.gov +# RFC5650 || M. Morgenstern, S. Baillie, U. Bonollo || moti.Morgenstern@ecitele.com, scott.baillie@nec.com.au, umberto.bonollo@nec.com.au +# RFC5651 || M. Luby, M. Watson, L. Vicisano || luby@qti.qualcomm.com, watson@qualcomm.com, vicisano@qualcomm.com +# RFC5652 || R. Housley || housley@vigilsec.com +# RFC5653 || M. Upadhyay, S. Malkani || m.d.upadhyay+ietf@gmail.com, Seema.Malkani@gmail.com +# RFC5654 || B. Niven-Jenkins, Ed., D. Brungard, Ed., M. Betts, Ed., N. Sprecher, S. Ueno || benjamin.niven-jenkins@bt.com, dbrungard@att.com, malcolm.betts@huawei.com, nurit.sprecher@nsn.com, satoshi.ueno@ntt.com +# RFC5655 || B. Trammell, E. Boschi, L. Mark, T. Zseby, A. Wagner || brian.trammell@hitachi-eu.com, elisa.boschi@hitachi-eu.com, lutz.mark@ifam.fraunhofer.de, tanja.zseby@fokus.fraunhofer.de, arno@wagner.name +# RFC5656 || D. Stebila, J. Green || douglas@stebila.ca, jonathan.green@queensu.ca +# RFC5657 || L. Dusseault, R. Sparks || lisa.dusseault@gmail.com, RjS@nostrum.com +# RFC5658 || T. Froment, C. Lebel, B. Bonnaerens || thomas.froment@tech-invite.com, Christophe.Lebel@alcatel-lucent.fr, ben.bonnaerens@alcatel-lucent.be +# RFC5659 || M. Bocci, S. Bryant || matthew.bocci@alcatel-lucent.com, stbryant@cisco.com +# RFC5660 || N. Williams || Nicolas.Williams@sun.com +# RFC5661 || S. Shepler, Ed., M. Eisler, Ed., D. Noveck, Ed. || shepler@storspeed.com, mike@eisler.com, dnoveck@netapp.com +# RFC5662 || S. Shepler, Ed., M. Eisler, Ed., D. Noveck, Ed. || shepler@storspeed.com, mike@eisler.com, dnoveck@netapp.com +# RFC5663 || D. Black, S. Fridella, J. Glasgow || black_david@emc.com, stevef@nasuni.com, jglasgow@aya.yale.edu +# RFC5664 || B. Halevy, B. Welch, J. Zelenka || bhalevy@panasas.com, welch@panasas.com, jimz@panasas.com +# RFC5665 || M. Eisler || mike@eisler.com +# RFC5666 || T. Talpey, B. Callaghan || tmtalpey@gmail.com, brentc@apple.com +# RFC5667 || T. Talpey, B. Callaghan || tmtalpey@gmail.com, brentc@apple.com +# RFC5668 || Y. Rekhter, S. Sangli, D. Tappan || yakov@juniper.net, rsrihari@cisco.com, Dan.Tappan@Gmail.com +# RFC5669 || S. Yoon, J. Kim, H. Park, H. Jeong, Y. Won || seokung@kisa.or.kr, seopo@kisa.or.kr, hrpark@kisa.or.kr, hcjung@kisa.or.kr, yjwon@kisa.or.kr +# RFC5670 || P. Eardley, Ed. || philip.eardley@bt.com +# RFC5671 || S. Yasukawa, A. Farrel, Ed. || yasukawa.seisho@lab.ntt.co.jp, adrian@olddog.co.uk +# RFC5672 || D. Crocker, Ed. || dcrocker@bbiw.net +# RFC5673 || K. Pister, Ed., P. Thubert, Ed., S. Dwars, T. Phinney || kpister@dustnetworks.com, pthubert@cisco.com, sicco.dwars@shell.com, tom.phinney@cox.net +# RFC5674 || S. Chisholm, R. Gerhards || schishol@nortel.com, rgerhards@adiscon.com +# RFC5675 || V. Marinov, J. Schoenwaelder || v.marinov@jacobs-university.de, j.schoenwaelder@jacobs-university.de +# RFC5676 || J. Schoenwaelder, A. Clemm, A. Karmakar || j.schoenwaelder@jacobs-university.de, alex@cisco.com, akarmaka@cisco.com +# RFC5677 || T. Melia, Ed., G. Bajko, S. Das, N. Golmie, JC. Zuniga || telemaco.melia@alcatel-lucent.com, Gabor.Bajko@nokia.com, subir@research.telcordia.com, nada.golmie@nist.gov, j.c.zuniga@ieee.org +# RFC5678 || G. Bajko, S. Das || gabor.bajko@nokia.com, subir@research.telcordia.com +# RFC5679 || G. Bajko || gabor.bajko@nokia.com +# RFC5680 || S. Dawkins, Ed. || spencer@wonderhamster.org +# RFC5681 || M. Allman, V. Paxson, E. Blanton || mallman@icir.org, vern@icir.org, eblanton@cs.purdue.edu +# RFC5682 || P. Sarolahti, M. Kojo, K. Yamamoto, M. Hata || pasi.sarolahti@iki.fi, kojo@cs.helsinki.fi, yamamotokaz@nttdocomo.co.jp, hatama@s1.nttdocomo.co.jp +# RFC5683 || A. Brusilovsky, I. Faynberg, Z. Zeltsan, S. Patel || Alec.Brusilovsky@alcatel-lucent.com, igor.faynberg@alcatel-lucent.com, zeltsan@alcatel-lucent.com, sarvar@google.com +# RFC5684 || P. Srisuresh, B. Ford || srisuresh@yahoo.com, bryan.ford@yale.edu +# RFC5685 || V. Devarapalli, K. Weniger || vijay@wichorus.com, kilian.weniger@googlemail.com +# RFC5686 || Y. Hiwasaki, H. Ohmuro || hiwasaki.yusuke@lab.ntt.co.jp, ohmuro.hitoshi@lab.ntt.co.jp +# RFC5687 || H. Tschofenig, H. Schulzrinne || Hannes.Tschofenig@gmx.net, hgs+ecrit@cs.columbia.edu +# RFC5688 || J. Rosenberg || jdrosen@jdrosen.net +# RFC5689 || C. Daboo || cyrus@daboo.name +# RFC5690 || S. Floyd, A. Arcia, D. Ros, J. Iyengar || floyd@icir.org, ae.arcia@telecom-bretagne.eu, David.Ros@telecom-bretagne.eu, jiyengar@fandm.edu +# RFC5691 || F. de Bont, S. Doehla, M. Schmidt, R. Sperschneider || frans.de.bont@philips.com, stefan.doehla@iis.fraunhofer.de, malte.schmidt@dolby.com, ralph.sperschneider@iis.fraunhofer.de +# RFC5692 || H. Jeon, S. Jeong, M. Riegel || hongseok.jeon@gmail.com, sjjeong@etri.re.kr, maximilian.riegel@nsn.com +# RFC5693 || J. Seedorf, E. Burger || jan.seedorf@nw.neclab.eu, eburger@standardstrack.com +# RFC5694 || G. Camarillo, Ed., IAB || Gonzalo.Camarillo@ericsson.com, iab@iab.org +# RFC5695 || A. Akhter, R. Asati, C. Pignataro || aakhter@cisco.com, rajiva@cisco.com, cpignata@cisco.com +# RFC5696 || T. Moncaster, B. Briscoe, M. Menth || toby.moncaster@bt.com, bob.briscoe@bt.com, menth@informatik.uni-wuerzburg.de +# RFC5697 || S. Farrell || stephen.farrell@cs.tcd.ie +# RFC5698 || T. Kunz, S. Okunick, U. Pordesch || thomas.kunz@sit.fraunhofer.de, susanne.okunick@pawisda.de, ulrich.pordesch@zv.fraunhofer.de +# RFC5701 || Y. Rekhter || yakov@juniper.net +# RFC5702 || J. Jansen || jelte@NLnetLabs.nl +# RFC5703 || T. Hansen, C. Daboo || tony+sieveloop@maillennium.att.com, cyrus@daboo.name +# RFC5704 || S. Bryant, Ed., M. Morrow, Ed., IAB || stbryant@cisco.com, mmorrow@cisco.com, iab@iab.org +# RFC5705 || E. Rescorla || ekr@rtfm.com +# RFC5706 || D. Harrington || ietfdbh@comcast.net +# RFC5707 || A. Saleem, Y. Xin, G. Sharratt || adnan.saleem@RadiSys.com, yong.xin@RadiSys.com, garland.sharratt@gmail.com +# RFC5708 || A. Keromytis || angelos@cs.columbia.edu +# RFC5709 || M. Bhatia, V. Manral, M. Fanto, R. White, M. Barnes, T. Li, R. Atkinson || manav@alcatel-lucent.com, vishwas@ipinfusion.com, mfanto@aegisdatasecurity.com, riw@cisco.com, mjbarnes@cisco.com, tony.li@tony.li, rja@extremenetworks.com +# RFC5710 || L. Berger, D. Papadimitriou, JP. Vasseur || lberger@labn.net, Dimitri.Papadimitriou@alcatel-lucent.be, jpv@cisco.com +# RFC5711 || JP. Vasseur, Ed., G. Swallow, I. Minei || jpv@cisco.com, swallow@cisco.com, ina@juniper.net +# RFC5712 || M. Meyer, Ed., JP. Vasseur, Ed. || matthew.meyer@bt.com, jpv@cisco.com +# RFC5713 || H. Moustafa, H. Tschofenig, S. De Cnodder || hassnaa.moustafa@orange-ftgroup.com, Hannes.Tschofenig@gmx.net, stefaan.de_cnodder@alcatel-lucent.com +# RFC5714 || M. Shand, S. Bryant || mshand@cisco.com, stbryant@cisco.com +# RFC5715 || M. Shand, S. Bryant || mshand@cisco.com, stbryant@cisco.com +# RFC5716 || J. Lentini, C. Everhart, D. Ellard, R. Tewari, M. Naik || jlentini@netapp.com, everhart@netapp.com, dellard@bbn.com, tewarir@us.ibm.com, manoj@almaden.ibm.com +# RFC5717 || B. Lengyel, M. Bjorklund || balazs.lengyel@ericsson.com, mbj@tail-f.com +# RFC5718 || D. Beller, A. Farrel || dieter.beller@alcatel-lucent.com, adrian@olddog.co.uk +# RFC5719 || D. Romascanu, H. Tschofenig || dromasca@gmail.com , Hannes.Tschofenig@gmx.net +# RFC5720 || F. Templin || fltemplin@acm.org +# RFC5721 || R. Gellens, C. Newman || rg+ietf@qualcomm.com, chris.newman@sun.com +# RFC5722 || S. Krishnan || suresh.krishnan@ericsson.com +# RFC5723 || Y. Sheffer, H. Tschofenig || yaronf@checkpoint.com, Hannes.Tschofenig@gmx.net +# RFC5724 || E. Wilde, A. Vaha-Sipila || dret@berkeley.edu, antti.vaha-sipila@nokia.com +# RFC5725 || A. Begen, D. Hsu, M. Lague || abegen@cisco.com, dohsu@cisco.com, mlague@cisco.com +# RFC5726 || Y. Qiu, F. Zhao, Ed., R. Koodli || qiuying@i2r.a-star.edu.sg, fanzhao@google.com, rkoodli@cisco.com +# RFC5727 || J. Peterson, C. Jennings, R. Sparks || jon.peterson@neustar.biz, fluffy@cisco.com, rjsparks@nostrum.com +# RFC5728 || S. Combes, P. Amundsen, M. Lambert, H-P. Lexow || stephane.combes@esa.int, pca@verisat.no, micheline.lambert@advantechamt.com, hlexow@stmi.com +# RFC5729 || J. Korhonen, Ed., M. Jones, L. Morand, T. Tsou || jouni.nospam@gmail.com, Mark.Jones@bridgewatersystems.com, Lionel.morand@orange-ftgroup.com, tena@huawei.com +# RFC5730 || S. Hollenbeck || shollenbeck@verisign.com +# RFC5731 || S. Hollenbeck || shollenbeck@verisign.com +# RFC5732 || S. Hollenbeck || shollenbeck@verisign.com +# RFC5733 || S. Hollenbeck || shollenbeck@verisign.com +# RFC5734 || S. Hollenbeck || shollenbeck@verisign.com +# RFC5735 || M. Cotton, L. Vegoda || michelle.cotton@icann.org, leo.vegoda@icann.org +# RFC5736 || G. Huston, M. Cotton, L. Vegoda || gih@apnic.net, michelle.cotton@icann.org, leo.vegoda@icann.org +# RFC5737 || J. Arkko, M. Cotton, L. Vegoda || jari.arkko@piuha.net, michelle.cotton@icann.org, leo.vegoda@icann.org +# RFC5738 || P. Resnick, C. Newman || presnick@qti.qualcomm.com, chris.newman@sun.com +# RFC5739 || P. Eronen, J. Laganier, C. Madson || pe@iki.fi, julienl@qualcomm.com, cmadson@cisco.com +# RFC5740 || B. Adamson, C. Bormann, M. Handley, J. Macker || adamson@itd.nrl.navy.mil, cabo@tzi.org, M.Handley@cs.ucl.ac.uk, macker@itd.nrl.navy.mil +# RFC5741 || L. Daigle, Ed., O. Kolkman, Ed., IAB || leslie@thinkingcat.com, olaf@nlnetlabs.nl, iab@iab.org +# RFC5742 || H. Alvestrand, R. Housley || harald@alvestrand.no, housley@vigilsec.com +# RFC5743 || A. Falk || falk@bbn.com +# RFC5744 || R. Braden, J. Halpern || braden@isi.edu, jhalpern@redback.com +# RFC5745 || A. Malis, Ed., IAB || andrew.g.malis@verizon.com, iab@iab.org +# RFC5746 || E. Rescorla, M. Ray, S. Dispensa, N. Oskov || ekr@rtfm.com, marsh@extendedsubset.com, dispensa@phonefactor.com, nasko.oskov@microsoft.com +# RFC5747 || J. Wu, Y. Cui, X. Li, M. Xu, C. Metz || jianping@cernet.edu.cn, cy@csnet1.cs.tsinghua.edu.cn, xing@cernet.edu.cn, xmw@csnet1.cs.tsinghua.edu.cn, chmetz@cisco.com +# RFC5748 || S. Yoon, J. Jeong, H. Kim, H. Jeong, Y. Won || seokung@kisa.or.kr, jijeong@kisa.or.kr, rinyfeel@kisa.or.kr, hcjung@kisa.or.kr, yjwon@kisa.or.kr +# RFC5749 || K. Hoeper, Ed., M. Nakhjiri, Y. Ohba, Ed. || khoeper@motorola.com, madjid.nakhjiri@motorola.com, yoshihiro.ohba@toshiba.co.jp +# RFC5750 || B. Ramsdell, S. Turner || blaker@gmail.com, turners@ieca.com +# RFC5751 || B. Ramsdell, S. Turner || blaker@gmail.com, turners@ieca.com +# RFC5752 || S. Turner, J. Schaad || turners@ieca.com, jimsch@exmsft.com +# RFC5753 || S. Turner, D. Brown || turners@ieca.com, dbrown@certicom.com +# RFC5754 || S. Turner || turners@ieca.com +# RFC5755 || S. Farrell, R. Housley, S. Turner || stephen.farrell@cs.tcd.ie, housley@vigilsec.com, turners@ieca.com +# RFC5756 || S. Turner, D. Brown, K. Yiu, R. Housley, T. Polk || turners@ieca.com, dbrown@certicom.com, kelviny@microsoft.com, housley@vigilsec.com, wpolk@nist.gov +# RFC5757 || T. Schmidt, M. Waehlisch, G. Fairhurst || schmidt@informatik.haw-hamburg.de, mw@link-lab.net, gorry@erg.abdn.ac.uk +# RFC5758 || Q. Dang, S. Santesson, K. Moriarty, D. Brown, T. Polk || quynh.dang@nist.gov, sts@aaa-sec.com, Moriarty_Kathleen@emc.com, dbrown@certicom.com, tim.polk@nist.gov +# RFC5759 || J. Solinas, L. Zieglar || jasolin@orion.ncsc.mil, llziegl@tycho.ncsc.mil +# RFC5760 || J. Ott, J. Chesterfield, E. Schooler || jo@acm.org, julianchesterfield@cantab.net, eve_schooler@acm.org +# RFC5761 || C. Perkins, M. Westerlund || csp@csperkins.org, magnus.westerlund@ericsson.com +# RFC5762 || C. Perkins || csp@csperkins.org +# RFC5763 || J. Fischl, H. Tschofenig, E. Rescorla || jason.fischl@skype.net, Hannes.Tschofenig@gmx.net, ekr@rtfm.com +# RFC5764 || D. McGrew, E. Rescorla || mcgrew@cisco.com, ekr@rtfm.com +# RFC5765 || H. Schulzrinne, E. Marocco, E. Ivov || hgs@cs.columbia.edu, enrico.marocco@telecomitalia.it, emcho@sip-communicator.org +# RFC5766 || R. Mahy, P. Matthews, J. Rosenberg || rohan@ekabal.com, philip_matthews@magma.ca, jdrosen@jdrosen.net +# RFC5767 || M. Munakata, S. Schubert, T. Ohba || munakata.mayumi@lab.ntt.co.jp, shida@ntt-at.com, ohba.takumi@lab.ntt.co.jp +# RFC5768 || J. Rosenberg || jdrosen@jdrosen.net +# RFC5769 || R. Denis-Courmont || remi.denis-courmont@nokia.com +# RFC5770 || M. Komu, T. Henderson, H. Tschofenig, J. Melen, A. Keranen, Ed. || miika@iki.fi, thomas.r.henderson@boeing.com, Hannes.Tschofenig@gmx.net, jan.melen@ericsson.com, ari.keranen@ericsson.com +# RFC5771 || M. Cotton, L. Vegoda, D. Meyer || michelle.cotton@icann.org, leo.vegoda@icann.org, dmm@1-4-5.net +# RFC5772 || A. Doria, E. Davies, F. Kastenholz || avri@ltu.se, elwynd@dial.pipex.com, frank@bbn.com +# RFC5773 || E. Davies, A. Doria || elwynd@dial.pipex.com, avri@acm.org +# RFC5774 || K. Wolf, A. Mayrhofer || karlheinz.wolf@nic.at, alexander.mayrhofer@nic.at +# RFC5775 || M. Luby, M. Watson, L. Vicisano || luby@qti.qualcomm.com, watson@qualcomm.com, vicisano@qualcomm.com +# RFC5776 || V. Roca, A. Francillon, S. Faurite || vincent.roca@inria.fr, aurelien.francillon@inria.fr, faurite@lcpc.fr +# RFC5777 || J. Korhonen, H. Tschofenig, M. Arumaithurai, M. Jones, Ed., A. Lior || jouni.korhonen@nsn.com, Hannes.Tschofenig@gmx.net, mayutan.arumaithurai@gmail.com, mark.jones@bridgewatersystems.com, avi@bridgewatersystems.com +# RFC5778 || J. Korhonen, Ed., H. Tschofenig, J. Bournelle, G. Giaretta, M. Nakhjiri || jouni.nospam@gmail.com, Hannes.Tschofenig@gmx.net, julien.bournelle@orange-ftgroup.com, gerardo.giaretta@gmail.com, madjid.nakhjiri@motorola.com +# RFC5779 || J. Korhonen, Ed., J. Bournelle, K. Chowdhury, A. Muhanna, U. Meyer || jouni.nospam@gmail.com, julien.bournelle@orange-ftgroup.com, kchowdhury@cisco.com, Ahmad.muhanna@ericsson.com, meyer@umic.rwth-aachen.de +# RFC5780 || D. MacDonald, B. Lowekamp || derek.macdonald@gmail.com, bbl@lowekamp.net +# RFC5781 || S. Weiler, D. Ward, R. Housley || weiler@tislabs.com, dward@juniper.net, housley@vigilsec.com +# RFC5782 || J. Levine || standards@taugh.com +# RFC5783 || M. Welzl, W. Eddy || michawe@ifi.uio.no, wes@mti-systems.com +# RFC5784 || N. Freed, S. Vedam || ned.freed@mrochek.com, Srinivas.Sv@Sun.COM +# RFC5785 || M. Nottingham, E. Hammer-Lahav || mnot@mnot.net, eran@hueniverse.com +# RFC5786 || R. Aggarwal, K. Kompella || rahul@juniper.net, kireeti@juniper.net +# RFC5787 || D. Papadimitriou || dimitri.papadimitriou@alcatel-lucent.be +# RFC5788 || A. Melnikov, D. Cridland || Alexey.Melnikov@isode.com, dave.cridland@isode.com +# RFC5789 || L. Dusseault, J. Snell || lisa.dusseault@gmail.com, jasnell@gmail.com +# RFC5790 || H. Liu, W. Cao, H. Asaeda || Liuhui47967@huawei.com, caowayne@huawei.com, asaeda@wide.ad.jp +# RFC5791 || J. Reschke, J. Kunze || julian.reschke@greenbytes.de, jak@ucop.edu +# RFC5792 || P. Sangster, K. Narayan || Paul_Sangster@symantec.com, kaushik@cisco.com +# RFC5793 || R. Sahita, S. Hanna, R. Hurst, K. Narayan || Ravi.Sahita@intel.com, shanna@juniper.net, Ryan.Hurst@microsoft.com, kaushik@cisco.com +# RFC5794 || J. Lee, J. Lee, J. Kim, D. Kwon, C. Kim || jklee@ensec.re.kr, jlee05@ensec.re.kr, jaeheon@ensec.re.kr, ds_kwon@ensec.re.kr, jbr@ensec.re.kr +# RFC5795 || K. Sandlund, G. Pelletier, L-E. Jonsson || kristofer.sandlund@ericsson.com, ghyslain.pelletier@ericsson.com, lars-erik@lejonsson.com +# RFC5796 || W. Atwood, S. Islam, M. Siami || bill@cse.concordia.ca, Salekul.Islam@emt.inrs.ca, mzrsm@yahoo.ca +# RFC5797 || J. Klensin, A. Hoenes || john+ietf@jck.com, ah@TR-Sys.de +# RFC5798 || S. Nadas, Ed. || stephen.nadas@ericsson.com +# RFC5801 || S. Josefsson, N. Williams || simon@josefsson.org, Nicolas.Williams@oracle.com +# RFC5802 || C. Newman, A. Menon-Sen, A. Melnikov, N. Williams || chris.newman@oracle.com, ams@toroid.org, Alexey.Melnikov@isode.com, Nicolas.Williams@oracle.com +# RFC5803 || A. Melnikov || alexey.melnikov@isode.com +# RFC5804 || A. Melnikov, Ed., T. Martin || Alexey.Melnikov@isode.com, timmartin@alumni.cmu.edu +# RFC5805 || K. Zeilenga || Kurt.Zeilenga@Isode.COM +# RFC5806 || S. Levy, M. Mohali, Ed. || stlevy@cisco.com, marianne.mohali@orange-ftgroup.com +# RFC5807 || Y. Ohba, A. Yegin || yoshihiro.ohba@toshiba.co.jp, alper.yegin@yegin.org +# RFC5808 || R. Marshall, Ed. || rmarshall@telecomsys.com +# RFC5810 || A. Doria, Ed., J. Hadi Salim, Ed., R. Haas, Ed., H. Khosravi, Ed., W. Wang, Ed., L. Dong, R. Gopal, J. Halpern || avri@ltu.se, hadi@mojatatu.com, rha@zurich.ibm.com, hormuzd.m.khosravi@intel.com, wmwang@mail.zjgsu.edu.cn, donglg@zjgsu.edu.cn, ram.gopal@nsn.com, jmh@joelhalpern.com +# RFC5811 || J. Hadi Salim, K. Ogawa || hadi@mojatatu.com, ogawa.kentaro@lab.ntt.co.jp +# RFC5812 || J. Halpern, J. Hadi Salim || jmh@joelhalpern.com, hadi@mojatatu.com +# RFC5813 || R. Haas || rha@zurich.ibm.com +# RFC5814 || W. Sun, Ed., G. Zhang, Ed. || sunwq@mit.edu, zhangguoying@mail.ritt.com.cn +# RFC5815 || T. Dietz, Ed., A. Kobayashi, B. Claise, G. Muenz || Thomas.Dietz@nw.neclab.eu, akoba@nttv6.net, bclaise@cisco.com, muenz@net.in.tum.de +# RFC5816 || S. Santesson, N. Pope || sts@aaa-sec.com, nick.pope@thales-esecurity.com +# RFC5817 || Z. Ali, JP. Vasseur, A. Zamfir, J. Newton || zali@cisco.com, jpv@cisco.com, ancaz@cisco.com, jonathan.newton@cw.com +# RFC5818 || D. Li, H. Xu, S. Bardalai, J. Meuric, D. Caviglia || danli@huawei.com, xuhuiying@huawei.com, snigdho.bardalai@us.fujitsu.com, julien.meuric@orange-ftgroup.com, diego.caviglia@ericsson.com +# RFC5819 || A. Melnikov, T. Sirainen || Alexey.Melnikov@isode.com, tss@iki.fi +# RFC5820 || A. Roy, Ed., M. Chandra, Ed. || akr@cisco.com, mw.chandra@gmail.com +# RFC5824 || K. Kumaki, Ed., R. Zhang, Y. Kamite || ke-kumaki@kddi.com, raymond.zhang@bt.com, y.kamite@ntt.com +# RFC5825 || K. Fujiwara, B. Leiba || fujiwara@jprs.co.jp, barryleiba@computer.org +# RFC5826 || A. Brandt, J. Buron, G. Porcu || abr@sdesigns.dk, jbu@sdesigns.dk, gporcu@gmail.com +# RFC5827 || M. Allman, K. Avrachenkov, U. Ayesta, J. Blanton, P. Hurtig || mallman@icir.org, k.avrachenkov@sophia.inria.fr, urtzi@laas.fr, jblanton@irg.cs.ohiou.edu, per.hurtig@kau.se +# RFC5828 || D. Fedyk, L. Berger, L. Andersson || donald.fedyk@alcatel-lucent.com, lberger@labn.net, loa.andersson@ericsson.com +# RFC5829 || A. Brown, G. Clemm, J. Reschke, Ed. || albertcbrown@us.ibm.com, geoffrey.clemm@us.ibm.com, julian.reschke@greenbytes.de +# RFC5830 || V. Dolmatov, Ed. || dol@cryptocom.ru +# RFC5831 || V. Dolmatov, Ed. || dol@cryptocom.ru +# RFC5832 || V. Dolmatov, Ed. || dol@cryptocom.ru +# RFC5833 || Y. Shi, Ed., D. Perkins, Ed., C. Elliott, Ed., Y. Zhang, Ed. || rishyang@gmail.com, dperkins@dsperkins.com, chelliot@pobox.com, yzhang@fortinet.com +# RFC5834 || Y. Shi, Ed., D. Perkins, Ed., C. Elliott, Ed., Y. Zhang, Ed. || rishyang@gmail.com, dperkins@dsperkins.com, chelliot@pobox.com, yzhang@fortinet.com +# RFC5835 || A. Morton, Ed., S. Van den Berghe, Ed. || acmorton@att.com, steven.van_den_berghe@alcatel-lucent.com +# RFC5836 || Y. Ohba, Ed., Q. Wu, Ed., G. Zorn, Ed. || oshihiro.ohba@toshiba.co.jp, sunseawq@huawei.com, gwz@net-zen.net +# RFC5837 || A. Atlas, Ed., R. Bonica, Ed., C. Pignataro, Ed., N. Shen, JR. Rivers || alia.atlas@bt.com, rbonica@juniper.net, cpignata@cisco.com, naiming@cisco.com, jrrivers@yahoo.com +# RFC5838 || A. Lindem, Ed., S. Mirtorabi, A. Roy, M. Barnes, R. Aggarwal || acee.lindem@ericsson.com, smirtora@cisco.com, akr@cisco.com, mjbarnes@cisco.com, rahul@juniper.net +# RFC5839 || A. Niemi, D. Willis, Ed. || aki.niemi@nokia.com, dean.willis@softarmor.com +# RFC5840 || K. Grewal, G. Montenegro, M. Bhatia || ken.grewal@intel.com, gabriel.montenegro@microsoft.com, manav.bhatia@alcatel-lucent.com +# RFC5841 || R. Hay, W. Turkal || rhay@google.com, turkal@google.com +# RFC5842 || G. Clemm, J. Crawford, J. Reschke, Ed., J. Whitehead || geoffrey.clemm@us.ibm.com, ccjason@us.ibm.com, julian.reschke@greenbytes.de, ejw@cse.ucsc.edu +# RFC5843 || A. Bryan || anthonybryan@gmail.com +# RFC5844 || R. Wakikawa, S. Gundavelli || ryuji@us.toyota-itc.com, sgundave@cisco.com +# RFC5845 || A. Muhanna, M. Khalil, S. Gundavelli, K. Leung || ahmad.muhanna@ericsson.com, Mohamed.khalil@ericsson.com, sgundave@cisco.com, kleung@cisco.com +# RFC5846 || A. Muhanna, M. Khalil, S. Gundavelli, K. Chowdhury, P. Yegani || ahmad.muhanna@ericsson.com, mohamed.khalil@ericsson.com, sgundave@cisco.com, kchowdhu@cisco.com, pyegani@juniper.net +# RFC5847 || V. Devarapalli, Ed., R. Koodli, Ed., H. Lim, N. Kant, S. Krishnan, J. Laganier || vijay@wichorus.com, rkoodli@cisco.com, hlim@stoke.com, nishi@stoke.com, suresh.krishnan@ericsson.com, julienl@qualcomm.com +# RFC5848 || J. Kelsey, J. Callas, A. Clemm || john.kelsey@nist.gov, jon@callas.org, alex@cisco.com +# RFC5849 || E. Hammer-Lahav, Ed. || eran@hueniverse.com +# RFC5850 || R. Mahy, R. Sparks, J. Rosenberg, D. Petrie, A. Johnston, Ed. || rohan@ekabal.com, rjsparks@nostrum.com, jdrosen@jdrosen.net, dpetrie@sipez.com, alan@sipstation.com +# RFC5851 || S. Ooghe, N. Voigt, M. Platnic, T. Haag, S. Wadhwa || sven.ooghe@alcatel-lucent.com, norbert.voigt@nsn.com, mplatnic@gmail.com, haagt@telekom.de, swadhwa@juniper.net +# RFC5852 || D. Caviglia, D. Ceccarelli, D. Bramanti, D. Li, S. Bardalai || diego.caviglia@ericsson.com, daniele.ceccarelli@ericsson.com, none, danli@huawei.com, sbardalai@gmail.com +# RFC5853 || J. Hautakorpi, Ed., G. Camarillo, R. Penfield, A. Hawrylyshen, M. Bhatia || Jani.Hautakorpi@ericsson.com, Gonzalo.Camarillo@ericsson.com, bpenfield@acmepacket.com, alan.ietf@polyphase.ca, mbhatia@3clogic.com +# RFC5854 || A. Bryan, T. Tsujikawa, N. McNab, P. Poeml || anthonybryan@gmail.com, tatsuhiro.t@gmail.com, neil@nabber.org, peter@poeml.de +# RFC5855 || J. Abley, T. Manderson || joe.abley@icann.org, terry.manderson@icann.org +# RFC5856 || E. Ertekin, R. Jasani, C. Christou, C. Bormann || ertekin_emre@bah.com, ro@breakcheck.com, christou_chris@bah.com, cabo@tzi.org +# RFC5857 || E. Ertekin, C. Christou, R. Jasani, T. Kivinen, C. Bormann || ertekin_emre@bah.com, christou_chris@bah.com, ro@breakcheck.com, kivinen@iki.fi, cabo@tzi.org +# RFC5858 || E. Ertekin, C. Christou, C. Bormann || ertekin_emre@bah.com, christou_chris@bah.com, cabo@tzi.org +# RFC5859 || R. Johnson || raj@cisco.com +# RFC5860 || M. Vigoureux, Ed., D. Ward, Ed., M. Betts, Ed. || martin.vigoureux@alcatel-lucent.com, dward@juniper.net, malcolm.betts@rogers.com +# RFC5861 || M. Nottingham || mnot@yahoo-inc.com +# RFC5862 || S. Yasukawa, A. Farrel || yasukawa.seisho@lab.ntt.co.jp, adrian@olddog.co.uk +# RFC5863 || T. Hansen, E. Siegel, P. Hallam-Baker, D. Crocker || tony+dkimov@maillennium.att.com, dkim@esiegel.net, phillip@hallambaker.com, dcrocker@bbiw.net +# RFC5864 || R. Allbery || rra@stanford.edu +# RFC5865 || F. Baker, J. Polk, M. Dolly || fred@cisco.com, jmpolk@cisco.com, mdolly@att.com +# RFC5866 || D. Sun, Ed., P. McCann, H. Tschofenig, T. Tsou, A. Doria, G. Zorn, Ed. || d.sun@alcatel-lucent.com, pete.mccann@motorola.com, Hannes.Tschofenig@gmx.net, tena@huawei.com, avri@ltu.se, gwz@net-zen.net +# RFC5867 || J. Martocci, Ed., P. De Mil, N. Riou, W. Vermeylen || jerald.p.martocci@jci.com, pieter.demil@intec.ugent.be, nicolas.riou@fr.schneider-electric.com, wouter@vooruit.be +# RFC5868 || S. Sakane, K. Kamada, S. Zrelli, M. Ishiyama || Shouichi.Sakane@jp.yokogawa.com, Ken-ichi.Kamada@jp.yokogawa.com, Saber.Zrelli@jp.yokogawa.com, masahiro@isl.rdc.toshiba.co.jp +# RFC5869 || H. Krawczyk, P. Eronen || hugokraw@us.ibm.com, pe@iki.fi +# RFC5870 || A. Mayrhofer, C. Spanring || alexander.mayrhofer@ipcom.at, christian@spanring.eu +# RFC5871 || J. Arkko, S. Bradner || jari.arkko@piuha.net, sob@harvard.edu +# RFC5872 || J. Arkko, A. Yegin || jari.arkko@piuha.net, alper.yegin@yegin.org +# RFC5873 || Y. Ohba, A. Yegin || yoshihiro.ohba@toshiba.co.jp, alper.yegin@yegin.org +# RFC5874 || J. Rosenberg, J. Urpalainen || jdrosen.net, jari.urpalainen@nokia.com +# RFC5875 || J. Urpalainen, D. Willis, Ed. || jari.urpalainen@nokia.com, dean.willis@softarmor.com +# RFC5876 || J. Elwell || john.elwell@siemens-enterprise.com +# RFC5877 || R. Housley || housley@vigilsec.com +# RFC5878 || M. Brown, R. Housley || mark@redphonesecurity.com, housley@vigilsec.com +# RFC5879 || T. Kivinen, D. McDonald || kivinen@iki.fi, danmcd@opensolaris.org +# RFC5880 || D. Katz, D. Ward || dkatz@juniper.net, dward@juniper.net +# RFC5881 || D. Katz, D. Ward || dkatz@juniper.net, dward@juniper.net +# RFC5882 || D. Katz, D. Ward || dkatz@juniper.net, dward@juniper.net +# RFC5883 || D. Katz, D. Ward || dkatz@juniper.net, dward@juniper.net +# RFC5884 || R. Aggarwal, K. Kompella, T. Nadeau, G. Swallow || rahul@juniper.net, kireeti@juniper.net, tom.nadeau@bt.com, swallow@cisco.com +# RFC5885 || T. Nadeau, Ed., C. Pignataro, Ed. || tom.nadeau@bt.com, cpignata@cisco.com +# RFC5886 || JP. Vasseur, Ed., JL. Le Roux, Y. Ikejiri || jpv@cisco.com, jeanlouis.leroux@orange-ftgroup.com, y.ikejiri@ntt.com +# RFC5887 || B. Carpenter, R. Atkinson, H. Flinck || brian.e.carpenter@gmail.com, rja@extremenetworks.com, hannu.flinck@nsn.com +# RFC5888 || G. Camarillo, H. Schulzrinne || Gonzalo.Camarillo@ericsson.com, schulzrinne@cs.columbia.edu +# RFC5889 || E. Baccelli, Ed., M. Townsley, Ed. || Emmanuel.Baccelli@inria.fr, mark@townsley.net +# RFC5890 || J. Klensin || john+ietf@jck.com +# RFC5891 || J. Klensin || john+ietf@jck.com +# RFC5892 || P. Faltstrom, Ed. || paf@cisco.com +# RFC5893 || H. Alvestrand, Ed., C. Karp || harald@alvestrand.no, ck@nic.museum +# RFC5894 || J. Klensin || john+ietf@jck.com +# RFC5895 || P. Resnick, P. Hoffman || presnick@qti.qualcomm.com, paul.hoffman@vpnc.org +# RFC5896 || L. Hornquist Astrand, S. Hartman || lha@apple.com, hartmans-ietf@mit.edu +# RFC5897 || J. Rosenberg || jdrosen@jdrosen.net +# RFC5898 || F. Andreasen, G. Camarillo, D. Oran, D. Wing || fandreas@cisco.com, Gonzalo.Camarillo@ericsson.com, oran@cisco.com, dwing-ietf@fuggles.com +# RFC5901 || P. Cain, D. Jevans || pcain@coopercain.com, dave.jevans@antiphishing.org +# RFC5902 || D. Thaler, L. Zhang, G. Lebovitz || dthaler@microsoft.com, lixia@cs.ucla.edu, gregory.ietf@gmail.com, iab@iab.org +# RFC5903 || D. Fu, J. Solinas || defu@orion.ncsc.mil, jasolin@orion.ncsc.mil +# RFC5904 || G. Zorn || gwz@net-zen.net +# RFC5905 || D. Mills, J. Martin, Ed., J. Burbank, W. Kasch || mills@udel.edu, jrmii@isc.org, jack.burbank@jhuapl.edu, william.kasch@jhuapl.edu +# RFC5906 || B. Haberman, Ed., D. Mills || brian@innovationslab.net, mills@udel.edu +# RFC5907 || H. Gerstung, C. Elliott, B. Haberman, Ed. || heiko.gerstung@meinberg.de, chelliot@pobox.com, brian@innovationslab.net +# RFC5908 || R. Gayraud, B. Lourdelet || richard.gayraud@free.fr, blourdel@cisco.com +# RFC5909 || J-M. Combes, S. Krishnan, G. Daley || jeanmichel.combes@orange-ftgroup.com, Suresh.Krishnan@ericsson.com, hoskuld@hotmail.com +# RFC5910 || J. Gould, S. Hollenbeck || jgould@verisign.com, shollenbeck@verisign.com +# RFC5911 || P. Hoffman, J. Schaad || paul.hoffman@vpnc.org, jimsch@exmsft.com +# RFC5912 || P. Hoffman, J. Schaad || paul.hoffman@vpnc.org, jimsch@exmsft.com +# RFC5913 || S. Turner, S. Chokhani || turners@ieca.com, SChokhani@cygnacom.com +# RFC5914 || R. Housley, S. Ashmore, C. Wallace || housley@vigilsec.com, srashmo@radium.ncsc.mil, cwallace@cygnacom.com +# RFC5915 || S. Turner, D. Brown || turners@ieca.com, dbrown@certicom.com +# RFC5916 || S. Turner || turners@ieca.com +# RFC5917 || S. Turner || turners@ieca.com +# RFC5918 || R. Asati, I. Minei, B. Thomas || rajiva@cisco.com, ina@juniper.net, bobthomas@alum.mit.edu +# RFC5919 || R. Asati, P. Mohapatra, E. Chen, B. Thomas || rajiva@cisco.com, pmohapat@cisco.com, chenying220@huawei.com, bobthomas@alum.mit.edu +# RFC5920 || L. Fang, Ed. || lufang@cisco.com +# RFC5921 || M. Bocci, Ed., S. Bryant, Ed., D. Frost, Ed., L. Levrau, L. Berger || matthew.bocci@alcatel-lucent.com, stbryant@cisco.com, danfrost@cisco.com, lieven.levrau@alcatel-lucent.com, lberger@labn.net +# RFC5922 || V. Gurbani, S. Lawrence, A. Jeffrey || vkg@alcatel-lucent.com, scott-ietf@skrb.org, ajeffrey@alcatel-lucent.com +# RFC5923 || V. Gurbani, Ed., R. Mahy, B. Tate || vkg@alcatel-lucent.com, rohan@ekabal.com, brett@broadsoft.com +# RFC5924 || S. Lawrence, V. Gurbani || scott-ietf@skrb.org, vkg@bell-labs.com +# RFC5925 || J. Touch, A. Mankin, R. Bonica || touch@isi.edu, mankin@psg.com, rbonica@juniper.net +# RFC5926 || G. Lebovitz, E. Rescorla || gregory.ietf@gmail.com, ekr@rtfm.com +# RFC5927 || F. Gont || fernando@gont.com.ar +# RFC5928 || M. Petit-Huguenin || petithug@acm.org +# RFC5929 || J. Altman, N. Williams, L. Zhu || jaltman@secure-endpoints.com, Nicolas.Williams@oracle.com, larry.zhu@microsoft.com +# RFC5930 || S. Shen, Y. Mao, NSS. Murthy || shenshuo@cnnic.cn, yumao9@gmail.com, ssmurthy.nittala@freescale.com +# RFC5931 || D. Harkins, G. Zorn || dharkins@arubanetworks.com, gwz@net-zen.net +# RFC5932 || A. Kato, M. Kanda, S. Kanno || kato.akihiro@po.ntts.co.jp, kanda.masayuki@lab.ntt.co.jp, kanno.satoru@po.ntts.co.jp +# RFC5933 || V. Dolmatov, Ed., A. Chuprina, I. Ustinov || dol@cryptocom.ru, ran@cryptocom.ru, igus@cryptocom.ru +# RFC5934 || R. Housley, S. Ashmore, C. Wallace || housley@vigilsec.com, srashmo@radium.ncsc.mil, cwallace@cygnacom.com +# RFC5935 || M. Ellison, B. Natale || ietf@ellisonsoftware.com, rnatale@mitre.org +# RFC5936 || E. Lewis, A. Hoenes, Ed. || ed.lewis@neustar.biz, ah@TR-Sys.de +# RFC5937 || S. Ashmore, C. Wallace || srashmo@radium.ncsc.mil, cwallace@cygnacom.com +# RFC5938 || A. Morton, M. Chiba || acmorton@att.com, mchiba@cisco.com +# RFC5939 || F. Andreasen || fandreas@cisco.com +# RFC5940 || S. Turner, R. Housley || turners@ieca.com, housley@vigilsec.com +# RFC5941 || D. M'Raihi, S. Boeyen, M. Grandcolas, S. Bajaj || davidietf@gmail.com, sharon.boeyen@entrust.com, michael.grandcolas@hotmail.com, sbajaj@verisign.com +# RFC5942 || H. Singh, W. Beebee, E. Nordmark || shemant@cisco.com, wbeebee@cisco.com, erik.nordmark@oracle.com +# RFC5943 || B. Haberman, Ed. || brian@innovationslab.net +# RFC5944 || C. Perkins, Ed. || charliep@computer.org +# RFC5945 || F. Le Faucheur, J. Manner, D. Wing, A. Guillou || flefauch@cisco.com, jukka.manner@tkk.fi, dwing-ietf@fuggles.com, allan.guillou@sfr.com +# RFC5946 || F. Le Faucheur, J. Manner, A. Narayanan, A. Guillou, H. Malik || flefauch@cisco.com, jukka.manner@tkk.fi, ashokn@cisco.com, allan.guillou@sfr.com, Hemant.Malik@airtel.in +# RFC5947 || J. Elwell, H. Kaplan || john.elwell@siemens-enterprise.com, hkaplan@acmepacket.com +# RFC5948 || S. Madanapalli, S. Park, S. Chakrabarti, G. Montenegro || smadanapalli@gmail.com, soohong.park@samsung.com, samitac@ipinfusion.com, gabriel.montenegro@microsoft.com +# RFC5949 || H. Yokota, K. Chowdhury, R. Koodli, B. Patil, F. Xia || yokota@kddilabs.jp, kchowdhu@cisco.com, rkoodli@cisco.com, basavaraj.patil@nokia.com, xiayangsong@huawei.com +# RFC5950 || S. Mansfield, Ed., E. Gray, Ed., K. Lam, Ed. || scott.mansfield@ericsson.com, eric.gray@ericsson.com, Kam.Lam@alcatel-lucent.com +# RFC5951 || K. Lam, S. Mansfield, E. Gray || Kam.Lam@Alcatel-Lucent.com, Scott.Mansfield@Ericsson.com, Kam.Lam@Alcatel-Lucent.com +# RFC5952 || S. Kawamura, M. Kawashima || kawamucho@mesh.ad.jp, kawashimam@vx.jp.nec.com +# RFC5953 || W. Hardaker || ietf@hardakers.net +# RFC5954 || V. Gurbani, Ed., B. Carpenter, Ed., B. Tate, Ed. || vkg@bell-labs.com, brian.e.carpenter@gmail.com, brett@broadsoft.com +# RFC5955 || A. Santoni || adriano.santoni@actalis.it +# RFC5956 || A. Begen || abegen@cisco.com +# RFC5957 || D. Karp || dkarp@zimbra.com +# RFC5958 || S. Turner || turners@ieca.com +# RFC5959 || S. Turner || turners@ieca.com +# RFC5960 || D. Frost, Ed., S. Bryant, Ed., M. Bocci, Ed. || danfrost@cisco.com, stbryant@cisco.com, matthew.bocci@alcatel-lucent.com +# RFC5961 || A. Ramaiah, R. Stewart, M. Dalal || ananth@cisco.com, randall@lakerest.net, mdalal@cisco.com +# RFC5962 || H. Schulzrinne, V. Singh, H. Tschofenig, M. Thomson || hgs@cs.columbia.edu, vs2140@cs.columbia.edu, Hannes.Tschofenig@gmx.net, martin.thomson@andrew.com +# RFC5963 || R. Gagliano || rogaglia@cisco.com +# RFC5964 || J. Winterbottom, M. Thomson || james.winterbottom@andrew.com, martin.thomson@andrew.com +# RFC5965 || Y. Shafranovich, J. Levine, M. Kucherawy || ietf@shaftek.org, standards@taugh.com, msk@cloudmark.com +# RFC5966 || R. Bellis || ray.bellis@nominet.org.uk +# RFC5967 || S. Turner || turners@ieca.com +# RFC5968 || J. Ott, C. Perkins || jo@netlab.tkk.fi, csp@csperkins.org +# RFC5969 || W. Townsley, O. Troan || mark@townsley.net, ot@cisco.com +# RFC5970 || T. Huth, J. Freimann, V. Zimmer, D. Thaler || thuth@de.ibm.com, jfrei@de.ibm.com, vincent.zimmer@intel.com, dthaler@microsoft.com +# RFC5971 || H. Schulzrinne, R. Hancock || hgs+nsis@cs.columbia.edu, robert.hancock@roke.co.uk +# RFC5972 || T. Tsenov, H. Tschofenig, X. Fu, Ed., C. Aoun, E. Davies || tseno.tsenov@mytum.de, Hannes.Tschofenig@nsn.com, fu@cs.uni-goettingen.de, cedaoun@yahoo.fr, elwynd@dial.pipex.com +# RFC5973 || M. Stiemerling, H. Tschofenig, C. Aoun, E. Davies || Martin.Stiemerling@neclab.eu, Hannes.Tschofenig@nsn.com, cedaoun@yahoo.fr, elwynd@dial.pipex.com +# RFC5974 || J. Manner, G. Karagiannis, A. McDonald || jukka.manner@tkk.fi, karagian@cs.utwente.nl, andrew.mcdonald@roke.co.uk +# RFC5975 || G. Ash, Ed., A. Bader, Ed., C. Kappler, Ed., D. Oran, Ed. || gash5107@yahoo.com, Attila.Bader@ericsson.com, cornelia.kappler@cktecc.de, oran@cisco.com +# RFC5976 || G. Ash, A. Morton, M. Dolly, P. Tarapore, C. Dvorak, Y. El Mghazli || gash5107@yahoo.com, acmorton@att.com, mdolly@att.com, tarapore@att.com, cdvorak@att.com, yacine.el_mghazli@alcatel.fr +# RFC5977 || A. Bader, L. Westberg, G. Karagiannis, C. Kappler, T. Phelan || Attila.Bader@ericsson.com, Lars.Westberg@ericsson.com, g.karagiannis@ewi.utwente.nl, cornelia.kappler@cktecc.de, tphelan@sonusnet.com +# RFC5978 || J. Manner, R. Bless, J. Loughney, E. Davies, Ed. || jukka.manner@tkk.fi, bless@kit.edu, john.loughney@nokia.com, elwynd@folly.org.uk +# RFC5979 || C. Shen, H. Schulzrinne, S. Lee, J. Bang || charles@cs.columbia.edu, hgs@cs.columbia.edu, sung1.lee@samsung.com, jh0278.bang@samsung.com +# RFC5980 || T. Sanda, Ed., X. Fu, S. Jeong, J. Manner, H. Tschofenig || sanda.takako@jp.panasonic.com, fu@cs.uni-goettingen.de, shjeong@hufs.ac.kr, jukka.manner@tkk.fi, Hannes.Tschofenig@nsn.com +# RFC5981 || J. Manner, M. Stiemerling, H. Tschofenig, R. Bless, Ed. || jukka.manner@tkk.fi, martin.stiemerling@neclab.eu, Hannes.Tschofenig@gmx.net, roland.bless@kit.edu +# RFC5982 || A. Kobayashi, Ed., B. Claise, Ed. || akoba@nttv6.net, bclaise@cisco.com +# RFC5983 || R. Gellens || rg+ietf@qualcomm.com +# RFC5984 || K-M. Moller || kalle@tankesaft.se +# RFC5985 || M. Barnes, Ed. || mary.ietf.barnes@gmail.com +# RFC5986 || M. Thomson, J. Winterbottom || martin.thomson@andrew.com, james.winterbottom@andrew.com +# RFC5987 || J. Reschke || julian.reschke@greenbytes.de +# RFC5988 || M. Nottingham || mnot@mnot.net +# RFC5989 || A.B. Roach || adam@nostrum.com +# RFC5990 || J. Randall, B. Kaliski, J. Brainard, S. Turner || jdrandall@comcast.net, kaliski_burt@emc.com, jbrainard@rsa.com, turners@ieca.com +# RFC5991 || D. Thaler, S. Krishnan, J. Hoagland || dthaler@microsoft.com, suresh.krishnan@ericsson.com, Jim_Hoagland@symantec.com +# RFC5992 || S. Sharikov, D. Miloshevic, J. Klensin || s.shar@regtime.net, dmiloshevic@afilias.info, john-ietf@jck.com +# RFC5993 || X. Duan, S. Wang, M. Westerlund, K. Hellwig, I. Johansson || duanxiaodong@chinamobile.com, wangshuaiyu@chinamobile.com, magnus.westerlund@ericsson.com, karl.hellwig@ericsson.com, ingemar.s.johansson@ericsson.com +# RFC5994 || S. Bryant, Ed., M. Morrow, G. Swallow, R. Cherukuri, T. Nadeau, N. Harrison, B. Niven-Jenkins || stbryant@cisco.com, mmorrow@cisco.com, swallow@cisco.com, cherukuri@juniper.net, thomas.nadeau@huawei.com, neil.2.harrison@bt.com, ben@niven-jenkins.co.uk +# RFC5995 || J. Reschke || julian.reschke@greenbytes.de +# RFC5996 || C. Kaufman, P. Hoffman, Y. Nir, P. Eronen || charliek@microsoft.com, paul.hoffman@vpnc.org, ynir@checkpoint.com, pe@iki.fi +# RFC5997 || A. DeKok || aland@freeradius.org +# RFC5998 || P. Eronen, H. Tschofenig, Y. Sheffer || pe@iki.fi, Hannes.Tschofenig@gmx.net, yaronf.ietf@gmail.com +# RFC6001 || D. Papadimitriou, M. Vigoureux, K. Shiomoto, D. Brungard, JL. Le Roux || dimitri.papadimitriou@alcatel-lucent.com, martin.vigoureux@alcatel-lucent.fr, shiomoto.kohei@lab.ntt.co.jp, dbrungard@att.com, jean-louis.leroux@rd.francetelecom.com +# RFC6002 || L. Berger, D. Fedyk || lberger@labn.net, donald.fedyk@alcatel-lucent.com +# RFC6003 || D. Papadimitriou || dimitri.papadimitriou@alcatel-lucent.be +# RFC6004 || L. Berger, D. Fedyk || lberger@labn.net, donald.fedyk@alcatel-lucent.com +# RFC6005 || L. Berger, D. Fedyk || lberger@labn.net, donald.fedyk@alcatel-lucent.com +# RFC6006 || Q. Zhao, Ed., D. King, Ed., F. Verhaeghe, T. Takeda, Z. Ali, J. Meuric || qzhao@huawei.com, daniel@olddog.co.uk, fabien.verhaeghe@gmail.com, takeda.tomonori@lab.ntt.co.jp, zali@cisco.com, julien.meuric@orange-ftgroup.com +# RFC6007 || I. Nishioka, D. King || i-nishioka@cb.jp.nec.com, daniel@olddog.co.uk +# RFC6008 || M. Kucherawy || msk@cloudmark.com +# RFC6009 || N. Freed || ned.freed@mrochek.com +# RFC6010 || R. Housley, S. Ashmore, C. Wallace || housley@vigilsec.com, srashmo@radium.ncsc.mil, cwallace@cygnacom.com +# RFC6011 || S. Lawrence, Ed., J. Elwell || scott-ietf@skrb.org, john.elwell@siemens-enterprise.com +# RFC6012 || J. Salowey, T. Petch, R. Gerhards, H. Feng || jsalowey@cisco.com, tomSecurity@network-engineer.co.uk, rgerhards@adiscon.com, fhyfeng@gmail.com +# RFC6013 || W. Simpson || William.Allen.Simpson@Gmail.com +# RFC6014 || P. Hoffman || paul.hoffman@vpnc.org +# RFC6015 || A. Begen || abegen@cisco.com +# RFC6016 || B. Davie, F. Le Faucheur, A. Narayanan || bsd@cisco.com, flefauch@cisco.com, ashokn@cisco.com +# RFC6017 || K. Meadors, Ed. || kyle@drummondgroup.com +# RFC6018 || F. Baker, W. Harrop, G. Armitage || fred@cisco.com, wazz@bud.cc.swin.edu.au, garmitage@swin.edu.au +# RFC6019 || R. Housley || housley@vigilsec.com +# RFC6020 || M. Bjorklund, Ed. || mbj@tail-f.com +# RFC6021 || J. Schoenwaelder, Ed. || j.schoenwaelder@jacobs-university.de +# RFC6022 || M. Scott, M. Bjorklund || mark.scott@ericsson.com, mbj@tail-f.com +# RFC6023 || Y. Nir, H. Tschofenig, H. Deng, R. Singh || ynir@checkpoint.com, Hannes.Tschofenig@gmx.net, denghui02@gmail.com, rsj@cisco.com +# RFC6024 || R. Reddy, C. Wallace || r.reddy@radium.ncsc.mil, cwallace@cygnacom.com +# RFC6025 || C. Wallace, C. Gardiner || cwallace@cygnacom.com, gardiner@bbn.com +# RFC6026 || R. Sparks, T. Zourzouvillys || RjS@nostrum.com, theo@crazygreek.co.uk +# RFC6027 || Y. Nir || ynir@checkpoint.com +# RFC6028 || G. Camarillo, A. Keranen || Gonzalo.Camarillo@ericsson.com, Ari.Keranen@ericsson.com +# RFC6029 || I. Rimac, V. Hilt, M. Tomsu, V. Gurbani, E. Marocco || rimac@bell-labs.com, volkerh@bell-labs.com, marco.tomsu@alcatel-lucent.com, vkg@bell-labs.com, enrico.marocco@telecomitalia.it +# RFC6030 || P. Hoyer, M. Pei, S. Machani || phoyer@actividentity.com, mpei@verisign.com, smachani@diversinet.com +# RFC6031 || S. Turner, R. Housley || turners@ieca.com, housley@vigilsec.com +# RFC6032 || S. Turner, R. Housley || turners@ieca.com, housley@vigilsec.com +# RFC6033 || S. Turner || turners@ieca.com +# RFC6034 || D. Thaler || dthaler@microsoft.com +# RFC6035 || A. Pendleton, A. Clark, A. Johnston, H. Sinnreich || aspen@telchemy.com, alan.d.clark@telchemy.com, alan.b.johnston@gmail.com, henry.sinnreich@gmail.com +# RFC6036 || B. Carpenter, S. Jiang || brian.e.carpenter@gmail.com, shengjiang@huawei.com +# RFC6037 || E. Rosen, Ed., Y. Cai, Ed., IJ. Wijnands || erosen@cisco.com, ycai@cisco.com, ice@cisco.com +# RFC6038 || A. Morton, L. Ciavattone || acmorton@att.com, lencia@att.com +# RFC6039 || V. Manral, M. Bhatia, J. Jaeggli, R. White || vishwas@ipinfusion.com, manav.bhatia@alcatel-lucent.com, joel.jaeggli@nokia.com, riw@cisco.com +# RFC6040 || B. Briscoe || bob.briscoe@bt.com +# RFC6041 || A. Crouch, H. Khosravi, A. Doria, Ed., X. Wang, K. Ogawa || alan.crouch@intel.com, hormuzd.m.khosravi@intel.com, avri@acm.org, carly.wang@huawei.com, ogawa.kentaro@lab.ntt.co.jp +# RFC6042 || A. Keromytis || angelos@cs.columbia.edu +# RFC6043 || J. Mattsson, T. Tian || john.mattsson@ericsson.com, tian.tian1@zte.com.cn +# RFC6044 || M. Mohali || marianne.mohali@orange-ftgroup.com +# RFC6045 || K. Moriarty || Moriarty_Kathleen@EMC.com +# RFC6046 || K. Moriarty, B. Trammell || Moriarty_Kathleen@EMC.com, trammell@tik.ee.ethz.ch +# RFC6047 || A. Melnikov, Ed. || Alexey.Melnikov@isode.com +# RFC6048 || J. Elie || julien@trigofacile.com +# RFC6049 || A. Morton, E. Stephan || acmorton@att.com, emile.stephan@orange-ftgroup.com +# RFC6050 || K. Drage || drage@alcatel-lucent.com +# RFC6051 || C. Perkins, T. Schierl || csp@csperkins.org, ts@thomas-schierl.de +# RFC6052 || C. Bao, C. Huitema, M. Bagnulo, M. Boucadair, X. Li || congxiao@cernet.edu.cn, huitema@microsoft.com, marcelo@it.uc3m.es, mohamed.boucadair@orange-ftgroup.com, xing@cernet.edu.cn +# RFC6053 || E. Haleplidis, K. Ogawa, W. Wang, J. Hadi Salim || ehalep@ece.upatras.gr, ogawa.kentaro@lab.ntt.co.jp, wmwang@mail.zjgsu.edu.cn, hadi@mojatatu.com +# RFC6054 || D. McGrew, B. Weis || mcgrew@cisco.com, bew@cisco.com +# RFC6055 || D. Thaler, J. Klensin, S. Cheshire || dthaler@microsoft.com, john+ietf@jck.com, cheshire@apple.com +# RFC6056 || M. Larsen, F. Gont || michael.larsen@tieto.com, fernando@gont.com.ar +# RFC6057 || C. Bastian, T. Klieber, J. Livingood, J. Mills, R. Woundy || chris_bastian@cable.comcast.com, tom_klieber@cable.comcast.com, jason_livingood@cable.comcast.com, jim_mills@cable.comcast.com, richard_woundy@cable.comcast.com +# RFC6058 || M. Liebsch, Ed., A. Muhanna, O. Blume || marco.liebsch@neclab.eu, ahmad.muhanna@ericsson.com, oliver.blume@alcatel-lucent.de +# RFC6059 || S. Krishnan, G. Daley || suresh.krishnan@ericsson.com, hoskuld@hotmail.com +# RFC6060 || D. Fedyk, H. Shah, N. Bitar, A. Takacs || donald.fedyk@alcatel-lucent.com, hshah@ciena.com, nabil.n.bitar@verizon.com, attila.takacs@ericsson.com +# RFC6061 || B. Rosen || br@brianrosen.net +# RFC6062 || S. Perreault, Ed., J. Rosenberg || simon.perreault@viagenie.ca, jdrosen@jdrosen.net +# RFC6063 || A. Doherty, M. Pei, S. Machani, M. Nystrom || andrea.doherty@rsa.com, mpei@verisign.com, smachani@diversinet.com, mnystrom@microsoft.com +# RFC6064 || M. Westerlund, P. Frojdh || magnus.westerlund@ericsson.com, per.frojdh@ericsson.com +# RFC6065 || K. Narayan, D. Nelson, R. Presuhn, Ed. || kaushik_narayan@yahoo.com, d.b.nelson@comcast.net, randy_presuhn@mindspring.com +# RFC6066 || D. Eastlake 3rd || d3e3e3@gmail.com +# RFC6067 || M. Davis, A. Phillips, Y. Umaoka || mark@macchiato.com, addison@lab126.com, yoshito_umaoka@us.ibm.com +# RFC6068 || M. Duerst, L. Masinter, J. Zawinski || duerst@it.aoyama.ac.jp, LMM@acm.org, jwz@jwz.org +# RFC6069 || A. Zimmermann, A. Hannemann || zimmermann@cs.rwth-aachen.de, hannemann@nets.rwth-aachen.de +# RFC6070 || S. Josefsson || simon@josefsson.org +# RFC6071 || S. Frankel, S. Krishnan || sheila.frankel@nist.gov, suresh.krishnan@ericsson.com +# RFC6072 || C. Jennings, J. Fischl, Ed. || fluffy@cisco.com, jason.fischl@skype.net +# RFC6073 || L. Martini, C. Metz, T. Nadeau, M. Bocci, M. Aissaoui || lmartini@cisco.com, chmetz@cisco.com, tnadeau@lucidvision.com, matthew.bocci@alcatel-lucent.co.uk, mustapha.aissaoui@alcatel-lucent.com +# RFC6074 || E. Rosen, B. Davie, V. Radoaca, W. Luo || erosen@cisco.com, bsd@cisco.com, vasile.radoaca@alcatel-lucent.com, luo@weiluo.net +# RFC6075 || D. Cridland || dave.cridland@isode.com +# RFC6076 || D. Malas, A. Morton || d.malas@cablelabs.com, acmorton@att.com +# RFC6077 || D. Papadimitriou, Ed., M. Welzl, M. Scharf, B. Briscoe || dimitri.papadimitriou@alcatel-lucent.be, michawe@ifi.uio.no, michael.scharf@googlemail.com, bob.briscoe@bt.com +# RFC6078 || G. Camarillo, J. Melen || Gonzalo.Camarillo@ericsson.com, Jan.Melen@ericsson.com +# RFC6079 || G. Camarillo, P. Nikander, J. Hautakorpi, A. Keranen, A. Johnston || Gonzalo.Camarillo@ericsson.com, Pekka.Nikander@ericsson.com, Jani.Hautakorpi@ericsson.com, Ari.Keranen@ericsson.com, alan.b.johnston@gmail.com +# RFC6080 || D. Petrie, S. Channabasappa, Ed. || dan.ietf@SIPez.com, sumanth@cablelabs.com +# RFC6081 || D. Thaler || dthaler@microsoft.com +# RFC6082 || K. Whistler, G. Adams, M. Duerst, R. Presuhn, Ed., J. Klensin || kenw@sybase.com, glenn@skynav.com, duerst@it.aoyama.ac.jp, randy_presuhn@mindspring.com, john+ietf@jck.com +# RFC6083 || M. Tuexen, R. Seggelmann, E. Rescorla || tuexen@fh-muenster.de, seggelmann@fh-muenster.de, ekr@networkresonance.com +# RFC6084 || X. Fu, C. Dickmann, J. Crowcroft || fu@cs.uni-goettingen.de, mail@christian-dickmann.de, jon.crowcroft@cl.cam.ac.uk +# RFC6085 || S. Gundavelli, M. Townsley, O. Troan, W. Dec || sgundave@cisco.com, townsley@cisco.com, ot@cisco.com, wdec@cisco.com +# RFC6086 || C. Holmberg, E. Burger, H. Kaplan || christer.holmberg@ericsson.com, eburger@standardstrack.com, hkaplan@acmepacket.com +# RFC6087 || A. Bierman || andy@yumaworks.com +# RFC6088 || G. Tsirtsis, G. Giarreta, H. Soliman, N. Montavont || tsirtsis@qualcomm.com, gerardog@qualcomm.com, hesham@elevatemobile.com, nicolas.montavont@telecom-bretagne.eu +# RFC6089 || G. Tsirtsis, H. Soliman, N. Montavont, G. Giaretta, K. Kuladinithi || tsirtsis@qualcomm.com, hesham@elevatemobile.com, nicolas.montavont@telecom-bretagne.eu, gerardog@qualcomm.com, koo@comnets.uni-bremen.de +# RFC6090 || D. McGrew, K. Igoe, M. Salter || mcgrew@cisco.com, kmigoe@nsa.gov, msalter@restarea.ncsc.mil +# RFC6091 || N. Mavrogiannopoulos, D. Gillmor || nikos.mavrogiannopoulos@esat.kuleuven.be, dkg@fifthhorseman.net +# RFC6092 || J. Woodyatt, Ed. || jhw@apple.com +# RFC6093 || F. Gont, A. Yourtchenko || fernando@gont.com.ar, ayourtch@cisco.com +# RFC6094 || M. Bhatia, V. Manral || manav.bhatia@alcatel-lucent.com, vishwas@ipinfusion.com +# RFC6095 || B. Linowski, M. Ersue, S. Kuryla || bernd.linowski.ext@nsn.com, mehmet.ersue@nsn.com, s.kuryla@gmail.com +# RFC6096 || M. Tuexen, R. Stewart || tuexen@fh-muenster.de, randall@lakerest.net +# RFC6097 || J. Korhonen, V. Devarapalli || jouni.nospam@gmail.com, dvijay@gmail.com +# RFC6098 || H. Deng, H. Levkowetz, V. Devarapalli, S. Gundavelli, B. Haley || denghui02@gmail.com, henrik@levkowetz.com, dvijay@gmail.com, sgundave@cisco.com, brian.haley@hp.com +# RFC6101 || A. Freier, P. Karlton, P. Kocher || nikos.mavrogiannopoulos@esat.kuleuven.be +# RFC6104 || T. Chown, S. Venaas || tjc@ecs.soton.ac.uk, stig@cisco.com +# RFC6105 || E. Levy-Abegnoli, G. Van de Velde, C. Popoviciu, J. Mohacsi || elevyabe@cisco.com, gunter@cisco.com, chip@technodyne.com, mohacsi@niif.hu +# RFC6106 || J. Jeong, S. Park, L. Beloeil, S. Madanapalli || pjeong@brocade.com, soohong.park@samsung.com, luc.beloeil@orange-ftgroup.com, smadanapalli@gmail.com +# RFC6107 || K. Shiomoto, Ed., A. Farrel, Ed. || shiomoto.kohei@lab.ntt.co.jp, adrian@olddog.co.uk +# RFC6108 || C. Chung, A. Kasyanov, J. Livingood, N. Mody, B. Van Lieu || chae_chung@cable.comcast.com, alexander_kasyanov@cable.comcast.com, jason_livingood@cable.comcast.com, nirmal_mody@cable.comcast.com, brian@vanlieu.net +# RFC6109 || C. Petrucci, F. Gennai, A. Shahin, A. Vinciarelli || petrucci@digitpa.gov.it, francesco.gennai@isti.cnr.it, alba.shahin@isti.cnr.it, alessandro.vinciarelli@gmail.com +# RFC6110 || L. Lhotka, Ed. || ladislav@lhotka.name +# RFC6111 || L. Zhu || lzhu@microsoft.com +# RFC6112 || L. Zhu, P. Leach, S. Hartman || larry.zhu@microsoft.com, paulle@microsoft.com, hartmans-ietf@mit.edu +# RFC6113 || S. Hartman, L. Zhu || hartmans-ietf@mit.edu, larry.zhu@microsoft.com +# RFC6114 || M. Katagi, S. Moriai || Masanobu.Katagi@jp.sony.com, clefia-q@jp.sony.com +# RFC6115 || T. Li, Ed. || tony.li@tony.li +# RFC6116 || S. Bradner, L. Conroy, K. Fujiwara || sob@harvard.edu, lconroy@insensate.co.uk, fujiwara@jprs.co.jp +# RFC6117 || B. Hoeneisen, A. Mayrhofer, J. Livingood || bernie@ietf.hoeneisen.ch, alexander.mayrhofer@enum.at, jason_livingood@cable.comcast.com +# RFC6118 || B. Hoeneisen, A. Mayrhofer || bernie@ietf.hoeneisen.ch, alexander.mayrhofer@enum.at +# RFC6119 || J. Harrison, J. Berger, M. Bartlett || jon.harrison@metaswitch.com, jon.berger@metaswitch.com, mike.bartlett@metaswitch.com +# RFC6120 || P. Saint-Andre || ietf@stpeter.im +# RFC6121 || P. Saint-Andre || ietf@stpeter.im +# RFC6122 || P. Saint-Andre || ietf@stpeter.im +# RFC6123 || A. Farrel || adrian@olddog.co.uk +# RFC6124 || Y. Sheffer, G. Zorn, H. Tschofenig, S. Fluhrer || yaronf.ietf@gmail.com, gwz@net-zen.net, Hannes.Tschofenig@gmx.net, sfluhrer@cisco.com +# RFC6125 || P. Saint-Andre, J. Hodges || ietf@stpeter.im, Jeff.Hodges@PayPal.com +# RFC6126 || J. Chroboczek || jch@pps.jussieu.fr +# RFC6127 || J. Arkko, M. Townsley || jari.arkko@piuha.net, townsley@cisco.com +# RFC6128 || A. Begen || abegen@cisco.com +# RFC6129 || L. Romary, S. Lundberg || laurent.romary@inria.fr, slu@kb.dk +# RFC6130 || T. Clausen, C. Dearlove, J. Dean || T.Clausen@computer.org, chris.dearlove@baesystems.com, jdean@itd.nrl.navy.mil +# RFC6131 || R. George, B. Leiba || robinsgv@gmail.com, barryleiba@computer.org +# RFC6132 || R. George, B. Leiba || robinsgv@gmail.com, barryleiba@computer.org +# RFC6133 || R. George, B. Leiba, A. Melnikov || robinsgv@gmail.com, barryleiba@computer.org, Alexey.Melnikov@isode.com +# RFC6134 || A. Melnikov, B. Leiba || Alexey.Melnikov@isode.com, barryleiba@computer.org +# RFC6135 || C. Holmberg, S. Blau || christer.holmberg@ericsson.com, staffan.blau@ericsson.com +# RFC6136 || A. Sajassi, Ed., D. Mohan, Ed. || sajassi@cisco.com, mohand@nortel.com +# RFC6137 || D. Zisiadis, Ed., S. Kopsidas, Ed., M. Tsavli, Ed., G. Cessieux, Ed. || dzisiadis@iti.gr, spyros@uth.gr, sttsavli@uth.gr, Guillaume.Cessieux@cc.in2p3.fr +# RFC6138 || S. Kini, Ed., W. Lu, Ed. || sriganesh.kini@ericsson.com, wenhu.lu@ericsson.com +# RFC6139 || S. Russert, Ed., E. Fleischman, Ed., F. Templin, Ed. || russerts@hotmail.com, eric.fleischman@boeing.com, fltemplin@acm.org +# RFC6140 || A.B. Roach || adam@nostrum.com +# RFC6141 || G. Camarillo, Ed., C. Holmberg, Y. Gao || Gonzalo.Camarillo@ericsson.com, Christer.Holmberg@ericsson.com, gao.yang2@zte.com.cn +# RFC6142 || A. Moise, J. Brodkin || avy@fdos.ca, jonathan.brodkin@fdos.ca +# RFC6143 || T. Richardson, J. Levine || standards@realvnc.com, standards@taugh.com +# RFC6144 || F. Baker, X. Li, C. Bao, K. Yin || fred@cisco.com, xing@cernet.edu.cn, congxiao@cernet.edu.cn, kyin@cisco.com +# RFC6145 || X. Li, C. Bao, F. Baker || xing@cernet.edu.cn, congxiao@cernet.edu.cn, fred@cisco.com +# RFC6146 || M. Bagnulo, P. Matthews, I. van Beijnum || marcelo@it.uc3m.es, philip_matthews@magma.ca, iljitsch@muada.com +# RFC6147 || M. Bagnulo, A. Sullivan, P. Matthews, I. van Beijnum || marcelo@it.uc3m.es, ajs@shinkuro.com, philip_matthews@magma.ca, iljitsch@muada.com +# RFC6148 || P. Kurapati, R. Desetti, B. Joshi || kurapati@juniper.net, ramakrishnadtv@infosys.com, bharat_joshi@infosys.com +# RFC6149 || S. Turner, L. Chen || turners@ieca.com, lily.chen@nist.gov +# RFC6150 || S. Turner, L. Chen || turners@ieca.com, lily.chen@nist.gov +# RFC6151 || S. Turner, L. Chen || turners@ieca.com, lily.chen@nist.gov +# RFC6152 || J. Klensin, N. Freed, M. Rose, D. Crocker, Ed. || john+ietf@jck.com, ned.freed@mrochek.com, mrose17@gmail.com, dcrocker@bbiw.net +# RFC6153 || S. Das, G. Bajko || subir@research.Telcordia.com, gabor.bajko@nokia.com +# RFC6154 || B. Leiba, J. Nicolson || barryleiba@computer.org, nicolson@google.com +# RFC6155 || J. Winterbottom, M. Thomson, H. Tschofenig, R. Barnes || james.winterbottom@andrew.com, martin.thomson@andrew.com, Hannes.Tschofenig@gmx.net, rbarnes@bbn.com +# RFC6156 || G. Camarillo, O. Novo, S. Perreault, Ed. || Gonzalo.Camarillo@ericsson.com, Oscar.Novo@ericsson.com, simon.perreault@viagenie.ca +# RFC6157 || G. Camarillo, K. El Malki, V. Gurbani || Gonzalo.Camarillo@ericsson.com, karim@athonet.com, vkg@bell-labs.com +# RFC6158 || A. DeKok, Ed., G. Weber || aland@freeradius.org, gdweber@gmail.com +# RFC6159 || T. Tsou, G. Zorn, T. Taylor, Ed. || tena@huawei.com, gwz@net-zen.net, tom.taylor.stds@gmail.com +# RFC6160 || S. Turner || turners@ieca.com +# RFC6161 || S. Turner || turners@ieca.com +# RFC6162 || S. Turner || turners@ieca.com +# RFC6163 || Y. Lee, Ed., G. Bernstein, Ed., W. Imajuku || ylee@huawei.com, gregb@grotto-networking.com, imajuku.wataru@lab.ntt.co.jp +# RFC6164 || M. Kohno, B. Nitzan, R. Bush, Y. Matsuzaki, L. Colitti, T. Narten || mkohno@juniper.net, nitzan@juniper.net, randy@psg.com, maz@iij.ad.jp, lorenzo@google.com, narten@us.ibm.com +# RFC6165 || A. Banerjee, D. Ward || ayabaner@cisco.com, dward@juniper.net +# RFC6166 || S. Venaas || stig@cisco.com +# RFC6167 || M. Phillips, P. Adams, D. Rokicki, E. Johnson || m8philli@uk.ibm.com, phil_adams@us.ibm.com, derek.rokicki@softwareag.com, eric@tibco.com +# RFC6168 || W. Hardaker || ietf@hardakers.net +# RFC6169 || S. Krishnan, D. Thaler, J. Hoagland || suresh.krishnan@ericsson.com, dthaler@microsoft.com, Jim_Hoagland@symantec.com +# RFC6170 || S. Santesson, R. Housley, S. Bajaj, L. Rosenthol || sts@aaa-sec.com, housley@vigilsec.com, siddharthietf@gmail.com, leonardr@adobe.com +# RFC6171 || K. Zeilenga || Kurt.Zeilenga@Isode.COM +# RFC6172 || D. Black, D. Peterson || david.black@emc.com, david.peterson@brocade.com +# RFC6173 || P. Venkatesen, Ed. || prakashvn@hcl.com +# RFC6174 || E. Juskevicius || edj.etc@gmail.com +# RFC6175 || E. Juskevicius || edj.etc@gmail.com +# RFC6176 || S. Turner, T. Polk || turners@ieca.com, tim.polk@nist.gov +# RFC6177 || T. Narten, G. Huston, L. Roberts || narten@us.ibm.com, gih@apnic.net, lea.roberts@stanford.edu +# RFC6178 || D. Smith, J. Mullooly, W. Jaeger, T. Scholl || djsmith@cisco.com, jmullool@cisco.com, wjaeger@att.com, tscholl@nlayer.net +# RFC6179 || F. Templin, Ed. || fltemplin@acm.org +# RFC6180 || J. Arkko, F. Baker || jari.arkko@piuha.net, fred@cisco.com +# RFC6181 || M. Bagnulo || marcelo@it.uc3m.es +# RFC6182 || A. Ford, C. Raiciu, M. Handley, S. Barre, J. Iyengar || alan.ford@roke.co.uk, c.raiciu@cs.ucl.ac.uk, m.handley@cs.ucl.ac.uk, sebastien.barre@uclouvain.be, jiyengar@fandm.edu +# RFC6183 || A. Kobayashi, B. Claise, G. Muenz, K. Ishibashi || akoba@orange.plala.or.jp, bclaise@cisco.com, muenz@net.in.tum.de, ishibashi.keisuke@lab.ntt.co.jp +# RFC6184 || Y.-K. Wang, R. Even, T. Kristensen, R. Jesup || yekuiwang@huawei.com, even.roni@huawei.com, tom.kristensen@tandberg.com, rjesup@wgate.com +# RFC6185 || T. Kristensen, P. Luthi || tom.kristensen@tandberg.com, patrick.luthi@tandberg.com +# RFC6186 || C. Daboo || cyrus@daboo.name +# RFC6187 || K. Igoe, D. Stebila || kmigoe@nsa.gov, douglas@stebila.ca +# RFC6188 || D. McGrew || mcgrew@cisco.com +# RFC6189 || P. Zimmermann, A. Johnston, Ed., J. Callas || prz@mit.edu, alan.b.johnston@gmail.com, jon@callas.org +# RFC6190 || S. Wenger, Y.-K. Wang, T. Schierl, A. Eleftheriadis || stewe@stewe.org, yekui.wang@huawei.com, ts@thomas-schierl.de, alex@vidyo.com +# RFC6191 || F. Gont || fernando@gont.com.ar +# RFC6192 || D. Dugal, C. Pignataro, R. Dunn || dave@juniper.net, cpignata@cisco.com, rodunn@cisco.com +# RFC6193 || M. Saito, D. Wing, M. Toyama || ma.saito@nttv6.jp, dwing-ietf@fuggles.com, toyama.masashi@lab.ntt.co.jp +# RFC6194 || T. Polk, L. Chen, S. Turner, P. Hoffman || tim.polk@nist.gov, lily.chen@nist.gov, turners@ieca.com, paul.hoffman@vpnc.org +# RFC6195 || D. Eastlake 3rd || d3e3e3@gmail.com +# RFC6196 || A. Melnikov || Alexey.Melnikov@isode.com +# RFC6197 || K. Wolf || karlheinz.wolf@nic.at +# RFC6198 || B. Decraene, P. Francois, C. Pelsser, Z. Ahmad, A.J. Elizondo Armengol, T. Takeda || bruno.decraene@orange-ftgroup.com, francois@info.ucl.ac.be, cristel@iij.ad.jp, zubair.ahmad@orange-ftgroup.com, ajea@tid.es, takeda.tomonori@lab.ntt.co.jp +# RFC6201 || R. Asati, C. Pignataro, F. Calabria, C. Olvera || rajiva@cisco.com, cpignata@cisco.com, fcalabri@cisco.com, cesar.olvera@consulintel.es +# RFC6202 || S. Loreto, P. Saint-Andre, S. Salsano, G. Wilkins || salvatore.loreto@ericsson.com, ietf@stpeter.im, stefano.salsano@uniroma2.it, gregw@webtide.com +# RFC6203 || T. Sirainen || tss@iki.fi +# RFC6204 || H. Singh, W. Beebee, C. Donley, B. Stark, O. Troan, Ed. || shemant@cisco.com, wbeebee@cisco.com, c.donley@cablelabs.com, barbara.stark@att.com, ot@cisco.com +# RFC6205 || T. Otani, Ed., D. Li, Ed. || tm-otani@kddi.com, danli@huawei.com +# RFC6206 || P. Levis, T. Clausen, J. Hui, O. Gnawali, J. Ko || pal@cs.stanford.edu, T.Clausen@computer.org, jhui@archrock.com, gnawali@cs.stanford.edu, jgko@cs.jhu.edu +# RFC6207 || R. Denenberg, Ed. || rden@loc.gov +# RFC6208 || K. Sankar, Ed., A. Jones || ksankar@cisco.com, arnold.jones@snia.org +# RFC6209 || W. Kim, J. Lee, J. Park, D. Kwon || whkim5@ensec.re.kr, jklee@ensec.re.kr, jhpark@ensec.re.kr, ds_kwon@ensec.re.kr +# RFC6210 || J. Schaad || ietf@augustcellars.com +# RFC6211 || J. Schaad || ietf@augustcellars.com +# RFC6212 || M. Kucherawy || msk@cloudmark.com +# RFC6213 || C. Hopps, L. Ginsberg || chopps@cisco.com, ginsberg@cisco.com +# RFC6214 || B. Carpenter, R. Hinden || brian.e.carpenter@gmail.com, bob.hinden@gmail.com +# RFC6215 || M. Bocci, L. Levrau, D. Frost || matthew.bocci@alcatel-lucent.com, lieven.levrau@alcatel-lucent.com, danfrost@cisco.com +# RFC6216 || C. Jennings, K. Ono, R. Sparks, B. Hibbard, Ed. || fluffy@cisco.com, kumiko@cs.columbia.edu, Robert.Sparks@tekelec.com, Brian.Hibbard@tekelec.com +# RFC6217 || T. Ritter || tom@ritter.vg +# RFC6218 || G. Zorn, T. Zhang, J. Walker, J. Salowey || gwz@net-zen.net, tzhang@advistatech.com, jesse.walker@intel.com, jsalowey@cisco.com +# RFC6219 || X. Li, C. Bao, M. Chen, H. Zhang, J. Wu || xing@cernet.edu.cn, congxiao@cernet.edu.cn, fibrib@gmail.com, neilzh@gmail.com, jianping@cernet.edu.cn +# RFC6220 || D. McPherson, Ed., O. Kolkman, Ed., J. Klensin, Ed., G. Huston, Ed., Internet Architecture Board || dmcpherson@verisign.com, olaf@NLnetLabs.nl, john+ietf@jck.com, gih@apnic.net +# RFC6221 || D. Miles, Ed., S. Ooghe, W. Dec, S. Krishnan, A. Kavanagh || david.miles@alcatel-lucent.com, sven.ooghe@alcatel-lucent.com, wdec@cisco.com, suresh.krishnan@ericsson.com, alan.kavanagh@ericsson.com +# RFC6222 || A. Begen, C. Perkins, D. Wing || abegen@cisco.com, csp@csperkins.org, dwing-ietf@fuggles.com +# RFC6223 || C. Holmberg || christer.holmberg@ericsson.com +# RFC6224 || T. Schmidt, M. Waehlisch, S. Krishnan || schmidt@informatik.haw-hamburg.de, mw@link-lab.net, suresh.krishnan@ericsson.com +# RFC6225 || J. Polk, M. Linsner, M. Thomson, B. Aboba, Ed. || jmpolk@cisco.com, marc.linsner@cisco.com, martin.thomson@andrew.com, bernard_aboba@hotmail.com +# RFC6226 || B. Joshi, A. Kessler, D. McWalter || bharat_joshi@infosys.com, kessler@cisco.com, david@mcwalter.eu +# RFC6227 || T. Li, Ed. || tli@cisco.com +# RFC6228 || C. Holmberg || christer.holmberg@ericsson.com +# RFC6229 || J. Strombergson, S. Josefsson || joachim@secworks.se, simon@josefsson.org +# RFC6230 || C. Boulton, T. Melanchuk, S. McGlashan || chris@ns-technologies.com, timm@rainwillow.com, smcg.stds01@mcglashan.org +# RFC6231 || S. McGlashan, T. Melanchuk, C. Boulton || smcg.stds01@mcglashan.org, timm@rainwillow.com, chris@ns-technologies.com +# RFC6232 || F. Wei, Y. Qin, Z. Li, T. Li, J. Dong || weifang@chinamobile.com, qinyue@chinamobile.com, lizhenqiang@chinamobile.com, tony.li@tony.li, dongjie_dj@huawei.com +# RFC6233 || T. Li, L. Ginsberg || tony.li@tony.li, ginsberg@cisco.com +# RFC6234 || D. Eastlake 3rd, T. Hansen || d3e3e3@gmail.com, tony+shs@maillennium.att.com +# RFC6235 || E. Boschi, B. Trammell || boschie@tik.ee.ethz.ch, trammell@tik.ee.ethz.ch +# RFC6236 || I. Johansson, K. Jung || ingemar.s.johansson@ericsson.com, kyunghun.jung@samsung.com +# RFC6237 || B. Leiba, A. Melnikov || barryleiba@computer.org, Alexey.Melnikov@isode.com +# RFC6238 || D. M'Raihi, S. Machani, M. Pei, J. Rydell || davidietf@gmail.com, smachani@diversinet.com, Mingliang_Pei@symantec.com, johanietf@gmail.com +# RFC6239 || K. Igoe || kmigoe@nsa.gov +# RFC6240 || D. Zelig, Ed., R. Cohen, Ed., T. Nadeau, Ed. || david_zelig@pmc-sierra.com, ronc@resolutenetworks.com, Thomas.Nadeau@ca.com +# RFC6241 || R. Enns, Ed., M. Bjorklund, Ed., J. Schoenwaelder, Ed., A. Bierman, Ed. || rob.enns@gmail.com, mbj@tail-f.com, j.schoenwaelder@jacobs-university.de, andy@yumaworks.com +# RFC6242 || M. Wasserman || mrw@painless-security.com +# RFC6243 || A. Bierman, B. Lengyel || andy@yumaworks.com, balazs.lengyel@ericsson.com +# RFC6244 || P. Shafer || phil@juniper.net +# RFC6245 || P. Yegani, K. Leung, A. Lior, K. Chowdhury, J. Navali || pyegani@juniper.net, kleung@cisco.com, avi@bridgewatersystems.com, kchowdhu@cisco.com, jnavali@cisco.com +# RFC6246 || A. Sajassi, Ed., F. Brockners, D. Mohan, Ed., Y. Serbest || sajassi@cisco.com, fbrockne@cisco.com, dinmohan@hotmail.com, yetik_serbest@labs.att.com +# RFC6247 || L. Eggert || lars.eggert@nokia.com +# RFC6248 || A. Morton || acmorton@att.com +# RFC6249 || A. Bryan, N. McNab, T. Tsujikawa, P. Poeml, H. Nordstrom || anthonybryan@gmail.com, neil@nabber.org, tatsuhiro.t@gmail.com, peter@poeml.de, henrik@henriknordstrom.net +# RFC6250 || D. Thaler || dthaler@microsoft.com +# RFC6251 || S. Josefsson || simon@josefsson.org +# RFC6252 || A. Dutta, Ed., V. Fajardo, Y. Ohba, K. Taniuchi, H. Schulzrinne || ashutosh.dutta@ieee.org, vf0213@gmail.com, yoshihiro.ohba@toshiba.co.jp, kenichi.taniuchi@toshiba.co.jp, hgs@cs.columbia.edu +# RFC6253 || T. Heer, S. Varjonen || heer@cs.rwth-aachen.de, samu.varjonen@hiit.fi +# RFC6254 || M. McFadden || mark.mcfadden@icann.org +# RFC6255 || M. Blanchet || Marc.Blanchet@viagenie.ca +# RFC6256 || W. Eddy, E. Davies || wes@mti-systems.com, elwynd@folly.org.uk +# RFC6257 || S. Symington, S. Farrell, H. Weiss, P. Lovell || susan@mitre.org, stephen.farrell@cs.tcd.ie, howard.weiss@sparta.com, dtnbsp@gmail.com +# RFC6258 || S. Symington || susan@mitre.org +# RFC6259 || S. Symington || susan@mitre.org +# RFC6260 || S. Burleigh || Scott.C.Burleigh@jpl.nasa.gov +# RFC6261 || A. Keranen || ari.keranen@ericsson.com +# RFC6262 || S. Ikonin || ikonin@spiritdsp.com +# RFC6263 || X. Marjou, A. Sollaud || xavier.marjou@orange-ftgroup.com, aurelien.sollaud@orange-ftgroup.com +# RFC6264 || S. Jiang, D. Guo, B. Carpenter || jiangsheng@huawei.com, guoseu@huawei.com, brian.e.carpenter@gmail.com +# RFC6265 || A. Barth || abarth@eecs.berkeley.edu +# RFC6266 || J. Reschke || julian.reschke@greenbytes.de +# RFC6267 || V. Cakulev, G. Sundaram || violeta.cakulev@alcatel-lucent.com, ganesh.sundaram@alcatel-lucent.com +# RFC6268 || J. Schaad, S. Turner || ietf@augustcellars.com, turners@ieca.com +# RFC6269 || M. Ford, Ed., M. Boucadair, A. Durand, P. Levis, P. Roberts || ford@isoc.org, mohamed.boucadair@orange-ftgroup.com, adurand@juniper.net, pierre.levis@orange-ftgroup.com, roberts@isoc.org +# RFC6270 || M. Yevstifeyev || evnikita2@gmail.com +# RFC6271 || J-F. Mule || jf.mule@cablelabs.com +# RFC6272 || F. Baker, D. Meyer || fred@cisco.com, dmm@cisco.com +# RFC6273 || A. Kukec, S. Krishnan, S. Jiang || ana.kukec@fer.hr, suresh.krishnan@ericsson.com, jiangsheng@huawei.com +# RFC6274 || F. Gont || fernando@gont.com.ar +# RFC6275 || C. Perkins, Ed., D. Johnson, J. Arkko || charliep@computer.org, dbj@cs.rice.edu, jari.arkko@ericsson.com +# RFC6276 || R. Droms, P. Thubert, F. Dupont, W. Haddad, C. Bernardos || rdroms@cisco.com, pthubert@cisco.com, fdupont@isc.org, Wassim.Haddad@ericsson.com, cjbc@it.uc3m.es +# RFC6277 || S. Santesson, P. Hallam-Baker || sts@aaa-sec.com, hallam@gmail.com +# RFC6278 || J. Herzog, R. Khazan || jherzog@ll.mit.edu, rkh@ll.mit.edu +# RFC6279 || M. Liebsch, Ed., S. Jeong, Q. Wu || liebsch@neclab.eu, sjjeong@etri.re.kr, sunseawq@huawei.com +# RFC6280 || R. Barnes, M. Lepinski, A. Cooper, J. Morris, H. Tschofenig, H. Schulzrinne || rbarnes@bbn.com, mlepinski@bbn.com, acooper@cdt.org, jmorris@cdt.org, Hannes.Tschofenig@gmx.net, hgs@cs.columbia.edu +# RFC6281 || S. Cheshire, Z. Zhu, R. Wakikawa, L. Zhang || cheshire@apple.com, zhenkai@ucla.edu, ryuji@jp.toyota-itc.com, lixia@cs.ucla.edu +# RFC6282 || J. Hui, Ed., P. Thubert || jhui@archrock.com, pthubert@cisco.com +# RFC6283 || A. Jerman Blazic, S. Saljic, T. Gondrom || aljosa@setcce.si, svetlana.saljic@setcce.si, tobias.gondrom@gondrom.org +# RFC6284 || A. Begen, D. Wing, T. Van Caenegem || abegen@cisco.com, dwing-ietf@fuggles.com, Tom.Van_Caenegem@alcatel-lucent.com +# RFC6285 || B. Ver Steeg, A. Begen, T. Van Caenegem, Z. Vax || billvs@cisco.com, abegen@cisco.com, Tom.Van_Caenegem@alcatel-lucent.be, zeevvax@microsoft.com +# RFC6286 || E. Chen, J. Yuan || enkechen@cisco.com, jenny@cisco.com +# RFC6287 || D. M'Raihi, J. Rydell, S. Bajaj, S. Machani, D. Naccache || davidietf@gmail.com, johanietf@gmail.com, siddharthietf@gmail.com, smachani@diversinet.com, david.naccache@ens.fr +# RFC6288 || C. Reed || creed@opengeospatial.org +# RFC6289 || E. Cardona, S. Channabasappa, J-F. Mule || e.cardona@cablelabs.com, sumanth@cablelabs.com, jf.mule@cablelabs.com +# RFC6290 || Y. Nir, Ed., D. Wierbowski, F. Detienne, P. Sethi || ynir@checkpoint.com, wierbows@us.ibm.com, fd@cisco.com, psethi@cisco.com +# RFC6291 || L. Andersson, H. van Helvoort, R. Bonica, D. Romascanu, S. Mansfield || loa.andersson@ericsson.com, huub.van.helvoort@huawei.com, rbonica@juniper.net, dromasca@gmail.com , scott.mansfield@ericsson.com +# RFC6292 || P. Hoffman || paul.hoffman@vpnc.org +# RFC6293 || P. Hoffman || paul.hoffman@vpnc.org +# RFC6294 || Q. Hu, B. Carpenter || qhu009@aucklanduni.ac.nz, brian.e.carpenter@gmail.com +# RFC6295 || J. Lazzaro, J. Wawrzynek || lazzaro@cs.berkeley.edu, johnw@cs.berkeley.edu +# RFC6296 || M. Wasserman, F. Baker || mrw@painless-security.com, fred@cisco.com +# RFC6297 || M. Welzl, D. Ros || michawe@ifi.uio.no, david.ros@telecom-bretagne.eu +# RFC6298 || V. Paxson, M. Allman, J. Chu, M. Sargent || vern@icir.org, mallman@icir.org, hkchu@google.com, mts71@case.edu +# RFC6301 || Z. Zhu, R. Wakikawa, L. Zhang || zhenkai@cs.ucla.edu, ryuji.wakikawa@gmail.com, lixia@cs.ucla.edu +# RFC6302 || A. Durand, I. Gashinsky, D. Lee, S. Sheppard || adurand@juniper.net, igor@yahoo-inc.com, donn@fb.com, Scott.Sheppard@att.com +# RFC6303 || M. Andrews || marka@isc.org +# RFC6304 || J. Abley, W. Maton || joe.abley@icann.org, wmaton@ryouko.imsb.nrc.ca +# RFC6305 || J. Abley, W. Maton || joe.abley@icann.org, wmaton@ryouko.imsb.nrc.ca +# RFC6306 || P. Frejborg || pfrejborg@gmail.com +# RFC6307 || D. Black, Ed., L. Dunbar, Ed., M. Roth, R. Solomon || david.black@emc.com, ldunbar@huawei.com, MRoth@infinera.com, ronens@corrigent.com +# RFC6308 || P. Savola || psavola@funet.fi +# RFC6309 || J. Arkko, A. Keranen, J. Mattsson || jari.arkko@piuha.net, ari.keranen@ericsson.com, john.mattsson@ericsson.com +# RFC6310 || M. Aissaoui, P. Busschbach, L. Martini, M. Morrow, T. Nadeau, Y(J). Stein || mustapha.aissaoui@alcatel-lucent.com, busschbach@alcatel-lucent.com, lmartini@cisco.com, mmorrow@cisco.com, Thomas.Nadeau@ca.com, yaakov_s@rad.com +# RFC6311 || R. Singh, Ed., G. Kalyani, Y. Nir, Y. Sheffer, D. Zhang || rsj@cisco.com, kagarigi@cisco.com, ynir@checkpoint.com, yaronf.ietf@gmail.com, zhangdacheng@huawei.com +# RFC6312 || R. Koodli || rkoodli@cisco.com +# RFC6313 || B. Claise, G. Dhandapani, P. Aitken, S. Yates || bclaise@cisco.com, gowri@cisco.com, paitken@cisco.com, syates@cisco.com +# RFC6314 || C. Boulton, J. Rosenberg, G. Camarillo, F. Audet || chris@ns-technologies.com, jdrosen@jdrosen.net, Gonzalo.Camarillo@ericsson.com, francois.audet@skype.net +# RFC6315 || E. Guy, K. Darilion || edguy@CleverSpoke.com, klaus.darilion@nic.at +# RFC6316 || M. Komu, M. Bagnulo, K. Slavov, S. Sugimoto, Ed. || miika@iki.fi, marcelo@it.uc3m.es, kristian.slavov@ericsson.com, shinta@sfc.wide.ad.jp +# RFC6317 || M. Komu, T. Henderson || miika@iki.fi, thomas.r.henderson@boeing.com +# RFC6318 || R. Housley, J. Solinas || housley@vigilsec.com, jasolin@orion.ncsc.mil +# RFC6319 || M. Azinger, L. Vegoda || marla.azinger@ftr.com, leo.vegoda@icann.org +# RFC6320 || S. Wadhwa, J. Moisand, T. Haag, N. Voigt, T. Taylor, Ed. || sanjay.wadhwa@alcatel-lucent.com, jmoisand@juniper.net, haagt@telekom.de, norbert.voigt@nsn.com, tom.taylor.stds@gmail.com +# RFC6321 || C. Daboo, M. Douglass, S. Lees || cyrus@daboo.name, douglm@rpi.edu, steven.lees@microsoft.com +# RFC6322 || P. Hoffman || paul.hoffman@vpnc.org +# RFC6323 || G. Renker, G. Fairhurst || gerrit@erg.abdn.ac.uk, gorry@erg.abdn.ac.uk +# RFC6324 || G. Nakibly, F. Templin || gnakibly@yahoo.com, fltemplin@acm.org +# RFC6325 || R. Perlman, D. Eastlake 3rd, D. Dutt, S. Gai, A. Ghanwani || Radia@alum.mit.edu, d3e3e3@gmail.com, ddutt@cisco.com, silvano@ip6.com, anoop@alumni.duke.edu +# RFC6326 || D. Eastlake, A. Banerjee, D. Dutt, R. Perlman, A. Ghanwani || d3e3e3@gmail.com, ayabaner@cisco.com, ddutt@cisco.com, Radia@alum.mit.edu, anoop@alumni.duke.edu +# RFC6327 || D. Eastlake 3rd, R. Perlman, A. Ghanwani, D. Dutt, V. Manral || d3e3e3@gmail.com, Radia@alum.mit.edu, anoop@alumni.duke.edu, ddutt@cisco.com, vishwas.manral@hp.com +# RFC6328 || D. Eastlake 3rd || d3e3e3@gmail.com +# RFC6329 || D. Fedyk, Ed., P. Ashwood-Smith, Ed., D. Allan, A. Bragg, P. Unbehagen || Donald.Fedyk@alcatel-lucent.com, Peter.AshwoodSmith@huawei.com, david.i.allan@ericsson.com, nbragg@ciena.com, unbehagen@avaya.com +# RFC6330 || M. Luby, A. Shokrollahi, M. Watson, T. Stockhammer, L. Minder || luby@qti.qualcomm.com, amin.shokrollahi@epfl.ch, watsonm@netflix.com, stockhammer@nomor.de, lminder@qualcomm.com +# RFC6331 || A. Melnikov || Alexey.Melnikov@isode.com +# RFC6332 || A. Begen, E. Friedrich || abegen@cisco.com, efriedri@cisco.com +# RFC6333 || A. Durand, R. Droms, J. Woodyatt, Y. Lee || adurand@juniper.net, rdroms@cisco.com, jhw@apple.com, yiu_lee@cable.comcast.com +# RFC6334 || D. Hankins, T. Mrugalski || dhankins@google.com, tomasz.mrugalski@eti.pg.gda.pl +# RFC6335 || M. Cotton, L. Eggert, J. Touch, M. Westerlund, S. Cheshire || michelle.cotton@icann.org, lars.eggert@nokia.com, touch@isi.edu, magnus.westerlund@ericsson.com, cheshire@apple.com +# RFC6336 || M. Westerlund, C. Perkins || magnus.westerlund@ericsson.com, csp@csperkins.org +# RFC6337 || S. Okumura, T. Sawada, P. Kyzivat || shinji.okumura@softfront.jp, tu-sawada@kddi.com, pkyzivat@alum.mit.edu +# RFC6338 || V. Giralt, R. McDuff || victoriano@uma.es, r.mcduff@uq.edu.au +# RFC6339 || S. Josefsson, L. Hornquist Astrand || simon@josefsson.org, lha@apple.com +# RFC6340 || R. Presuhn || randy_presuhn@mindspring.com +# RFC6341 || K. Rehor, Ed., L. Portman, Ed., A. Hutton, R. Jain || krehor@cisco.com, leon.portman@nice.com, andrew.hutton@siemens-enterprise.com, rajnish.jain@ipc.com +# RFC6342 || R. Koodli || rkoodli@cisco.com +# RFC6343 || B. Carpenter || brian.e.carpenter@gmail.com +# RFC6344 || G. Bernstein, Ed., D. Caviglia, R. Rabbat, H. van Helvoort || gregb@grotto-networking.com, diego.caviglia@ericsson.com, rabbat@alum.mit.edu, hhelvoort@huawei.com +# RFC6345 || P. Duffy, S. Chakrabarti, R. Cragie, Y. Ohba, Ed., A. Yegin || paduffy@cisco.com, samita.chakrabarti@ericsson.com, robert.cragie@gridmerge.com, yoshihiro.ohba@toshiba.co.jp, a.yegin@partner.samsung.com +# RFC6346 || R. Bush, Ed. || randy@psg.com +# RFC6347 || E. Rescorla, N. Modadugu || ekr@rtfm.com, nagendra@cs.stanford.edu +# RFC6348 || JL. Le Roux, Ed., T. Morin, Ed. || jeanlouis.leroux@orange-ftgroup.com, thomas.morin@orange-ftgroup.com +# RFC6349 || B. Constantine, G. Forget, R. Geib, R. Schrage || barry.constantine@jdsu.com, gilles.forget@sympatico.ca, Ruediger.Geib@telekom.de, reinhard@schrageconsult.com +# RFC6350 || S. Perreault || simon.perreault@viagenie.ca +# RFC6351 || S. Perreault || simon.perreault@viagenie.ca +# RFC6352 || C. Daboo || cyrus@daboo.name +# RFC6353 || W. Hardaker || ietf@hardakers.net +# RFC6354 || Q. Xie || Qiaobing.Xie@gmail.com +# RFC6355 || T. Narten, J. Johnson || narten@us.ibm.com, jarrod.b.johnson@gmail.com +# RFC6356 || C. Raiciu, M. Handley, D. Wischik || costin.raiciu@cs.pub.ro, m.handley@cs.ucl.ac.uk, d.wischik@cs.ucl.ac.uk +# RFC6357 || V. Hilt, E. Noel, C. Shen, A. Abdelal || volker.hilt@alcatel-lucent.com, eric.noel@att.com, charles@cs.columbia.edu, aabdelal@sonusnet.com +# RFC6358 || P. Hoffman || paul.hoffman@vpnc.org +# RFC6359 || S. Ginoza, M. Cotton, A. Morris || sginoza@amsl.com, michelle.cotton@icann.org, amorris@amsl.com +# RFC6360 || R. Housley || housley@vigilsec.com +# RFC6361 || J. Carlson, D. Eastlake 3rd || carlsonj@workingcode.com, d3e3e3@gmail.com +# RFC6362 || K. Meadors, Ed. || kyle@drummondgroup.com +# RFC6363 || M. Watson, A. Begen, V. Roca || watsonm@netflix.com, abegen@cisco.com, vincent.roca@inria.fr +# RFC6364 || A. Begen || abegen@cisco.com +# RFC6365 || P. Hoffman, J. Klensin || paul.hoffman@vpnc.org, john+ietf@jck.com +# RFC6366 || J. Valin, K. Vos || jmvalin@jmvalin.ca, koen.vos@skype.net +# RFC6367 || S. Kanno, M. Kanda || kanno.satoru@po.ntts.co.jp, kanda.masayuki@lab.ntt.co.jp +# RFC6368 || P. Marques, R. Raszuk, K. Patel, K. Kumaki, T. Yamagata || pedro.r.marques@gmail.com, robert@raszuk.net, keyupate@cisco.com, ke-kumaki@kddi.com, to-yamagata@kddi.com +# RFC6369 || E. Haleplidis, O. Koufopavlou, S. Denazis || ehalep@ece.upatras.gr, odysseas@ece.upatras.gr, sdena@upatras.gr +# RFC6370 || M. Bocci, G. Swallow, E. Gray || matthew.bocci@alcatel-lucent.com, swallow@cisco.com, eric.gray@ericsson.com +# RFC6371 || I. Busi, Ed., D. Allan, Ed. || Italo.Busi@alcatel-lucent.com, david.i.allan@ericsson.com +# RFC6372 || N. Sprecher, Ed., A. Farrel, Ed. || nurit.sprecher@nsn.com, adrian@olddog.co.uk +# RFC6373 || L. Andersson, Ed., L. Berger, Ed., L. Fang, Ed., N. Bitar, Ed., E. Gray, Ed. || loa.andersson@ericsson.com, lberger@labn.net, lufang@cisco.com, nabil.n.bitar@verizon.com, Eric.Gray@Ericsson.com +# RFC6374 || D. Frost, S. Bryant || danfrost@cisco.com, stbryant@cisco.com +# RFC6375 || D. Frost, Ed., S. Bryant, Ed. || danfrost@cisco.com, stbryant@cisco.com +# RFC6376 || D. Crocker, Ed., T. Hansen, Ed., M. Kucherawy, Ed. || dcrocker@bbiw.net, tony+dkimov@maillennium.att.com, msk@cloudmark.com +# RFC6377 || M. Kucherawy || msk@cloudmark.com +# RFC6378 || Y. Weingarten, Ed., S. Bryant, E. Osborne, N. Sprecher, A. Fulignoli, Ed. || yaacov.weingarten@nsn.com, stbryant@cisco.com, eosborne@cisco.com, nurit.sprecher@nsn.com, annamaria.fulignoli@ericsson.com +# RFC6379 || L. Law, J. Solinas || lelaw@orion.ncsc.mil, jasolin@orion.ncsc.mil +# RFC6380 || K. Burgin, M. Peck || kwburgi@tycho.ncsc.mil, mpeck@mitre.org +# RFC6381 || R. Gellens, D. Singer, P. Frojdh || rg+ietf@qualcomm.com, singer@apple.com, Per.Frojdh@ericsson.com +# RFC6382 || D. McPherson, R. Donnelly, F. Scalzo || dmcpherson@verisign.com, rdonnelly@verisign.com, fscalzo@verisign.com +# RFC6383 || K. Shiomoto, A. Farrel || shiomoto.kohei@lab.ntt.co.jp, adrian@olddog.co.uk +# RFC6384 || I. van Beijnum || iljitsch@muada.com +# RFC6385 || M. Barnes, A. Doria, H. Alvestrand, B. Carpenter || mary.ietf.barnes@gmail.com, avri@acm.org, harald@alvestrand.no, brian.e.carpenter@gmail.com +# RFC6386 || J. Bankoski, J. Koleszar, L. Quillio, J. Salonen, P. Wilkins, Y. Xu || jimbankoski@google.com, jkoleszar@google.com, louquillio@google.com, jsalonen@google.com, paulwilkins@google.com, yaowu@google.com +# RFC6387 || A. Takacs, L. Berger, D. Caviglia, D. Fedyk, J. Meuric || attila.takacs@ericsson.com, lberger@labn.net, diego.caviglia@ericsson.com, donald.fedyk@alcatel-lucent.com, julien.meuric@orange.com +# RFC6388 || IJ. Wijnands, Ed., I. Minei, Ed., K. Kompella, B. Thomas || ice@cisco.com, ina@juniper.net, kireeti@juniper.net, bobthomas@alum.mit.edu +# RFC6389 || R. Aggarwal, JL. Le Roux || raggarwa_1@yahoo.com, jeanlouis.leroux@orange-ftgroup.com +# RFC6390 || A. Clark, B. Claise || alan.d.clark@telchemy.com, bclaise@cisco.com +# RFC6391 || S. Bryant, Ed., C. Filsfils, U. Drafz, V. Kompella, J. Regan, S. Amante || stbryant@cisco.com, cfilsfil@cisco.com, Ulrich.Drafz@telekom.de, vach.kompella@alcatel-lucent.com, joe.regan@alcatel-lucent.com, shane@level3.net +# RFC6392 || R. Alimi, Ed., A. Rahman, Ed., Y. Yang, Ed. || ralimi@google.com, Akbar.Rahman@InterDigital.com, yry@cs.yale.edu +# RFC6393 || M. Yevstifeyev || evnikita2@gmail.com +# RFC6394 || R. Barnes || rbarnes@bbn.com +# RFC6395 || S. Gulrajani, S. Venaas || sameerg@cisco.com, stig@cisco.com +# RFC6396 || L. Blunk, M. Karir, C. Labovitz || ljb@merit.edu, mkarir@merit.edu, labovit@deepfield.net +# RFC6397 || T. Manderson || terry.manderson@icann.org +# RFC6398 || F. Le Faucheur, Ed. || flefauch@cisco.com +# RFC6401 || F. Le Faucheur, J. Polk, K. Carlberg || flefauch@cisco.com, jmpolk@cisco.com, carlberg@g11.org.uk +# RFC6402 || J. Schaad || jimsch@augustcellars.com +# RFC6403 || L. Zieglar, S. Turner, M. Peck || llziegl@tycho.ncsc.mil, turners@ieca.com, mpeck@alumni.virginia.edu +# RFC6404 || J. Seedorf, S. Niccolini, E. Chen, H. Scholz || jan.seedorf@nw.neclab.eu, saverio.niccolini@.neclab.eu, eric.chen@lab.ntt.co.jp, hendrik.scholz@voipfuture.com +# RFC6405 || A. Uzelac, Ed., Y. Lee, Ed. || adam.uzelac@globalcrossing.com, yiu_lee@cable.comcast.com +# RFC6406 || D. Malas, Ed., J. Livingood, Ed. || d.malas@cablelabs.com, Jason_Livingood@cable.comcast.com +# RFC6407 || B. Weis, S. Rowles, T. Hardjono || bew@cisco.com, sheela@cisco.com, hardjono@mit.edu +# RFC6408 || M. Jones, J. Korhonen, L. Morand || mark@azu.ca, jouni.nospam@gmail.com, lionel.morand@orange-ftgroup.com +# RFC6409 || R. Gellens, J. Klensin || rg+ietf@qualcomm.com, john-ietf@jck.com +# RFC6410 || R. Housley, D. Crocker, E. Burger || housley@vigilsec.com, dcrocker@bbiw.net, eburger@standardstrack.com +# RFC6411 || M. Behringer, F. Le Faucheur, B. Weis || mbehring@cisco.com, flefauch@cisco.com, bew@cisco.com +# RFC6412 || S. Poretsky, B. Imhoff, K. Michielsen || sporetsky@allot.com, bimhoff@planetspork.com, kmichiel@cisco.com +# RFC6413 || S. Poretsky, B. Imhoff, K. Michielsen || sporetsky@allot.com, bimhoff@planetspork.com, kmichiel@cisco.com +# RFC6414 || S. Poretsky, R. Papneja, J. Karthik, S. Vapiwala || sporetsky@allot.com, rajiv.papneja@huawei.com, jkarthik@cisco.com, svapiwal@cisco.com +# RFC6415 || E. Hammer-Lahav, Ed., B. Cook || eran@hueniverse.com, romeda@gmail.com +# RFC6416 || M. Schmidt, F. de Bont, S. Doehla, J. Kim || malte.schmidt@dolby.com, frans.de.bont@philips.com, stefan.doehla@iis.fraunhofer.de, kjh1905m@naver.com +# RFC6417 || P. Eardley, L. Eggert, M. Bagnulo, R. Winter || philip.eardley@bt.com, lars.eggert@nokia.com, marcelo@it.uc3m.es, rolf.winter@neclab.eu +# RFC6418 || M. Blanchet, P. Seite || Marc.Blanchet@viagenie.ca, pierrick.seite@orange.com +# RFC6419 || M. Wasserman, P. Seite || mrw@painless-security.com, pierrick.seite@orange-ftgroup.com +# RFC6420 || Y. Cai, H. Ou || ycai@cisco.com, hou@cisco.com +# RFC6421 || D. Nelson, Ed. || d.b.nelson@comcast.net +# RFC6422 || T. Lemon, Q. Wu || mellon@nominum.com, sunseawq@huawei.com +# RFC6423 || H. Li, L. Martini, J. He, F. Huang || lihan@chinamobile.com, lmartini@cisco.com, hejia@huawei.com, feng.f.huang@alcatel-sbell.com.cn +# RFC6424 || N. Bahadur, K. Kompella, G. Swallow || nitinb@juniper.net, kireeti@juniper.net, swallow@cisco.com +# RFC6425 || S. Saxena, Ed., G. Swallow, Z. Ali, A. Farrel, S. Yasukawa, T. Nadeau || ssaxena@cisco.com, swallow@cisco.com, zali@cisco.com, adrian@olddog.co.uk, yasukawa.seisho@lab.ntt.co.jp, thomas.nadeau@ca.com +# RFC6426 || E. Gray, N. Bahadur, S. Boutros, R. Aggarwal || eric.gray@ericsson.com, nitinb@juniper.net, sboutros@cisco.com, raggarwa_1@yahoo.com +# RFC6427 || G. Swallow, Ed., A. Fulignoli, Ed., M. Vigoureux, Ed., S. Boutros, D. Ward || swallow@cisco.com, annamaria.fulignoli@ericsson.com, martin.vigoureux@alcatel-lucent.com, sboutros@cisco.com, dward@juniper.net +# RFC6428 || D. Allan, Ed., G. Swallow, Ed., J. Drake, Ed. || david.i.allan@ericsson.com, swallow@cisco.com, jdrake@juniper.net +# RFC6429 || M. Bashyam, M. Jethanandani, A. Ramaiah || mbashyam@ocarinanetworks.com, mjethanandani@gmail.com, ananth@cisco.com +# RFC6430 || K. Li, B. Leiba || likepeng@huawei.com, barryleiba@computer.org +# RFC6431 || M. Boucadair, P. Levis, G. Bajko, T. Savolainen, T. Tsou || mohamed.boucadair@orange.com, pierre.levis@orange.com, gabor.bajko@nokia.com, teemu.savolainen@nokia.com, tina.tsou.zouting@huawei.com +# RFC6432 || R. Jesske, L. Liess || r.jesske@telekom.de, L.Liess@telekom.de +# RFC6433 || P. Hoffman || paul.hoffman@vpnc.org +# RFC6434 || E. Jankiewicz, J. Loughney, T. Narten || edward.jankiewicz@sri.com, john.loughney@nokia.com, narten@us.ibm.com +# RFC6435 || S. Boutros, Ed., S. Sivabalan, Ed., R. Aggarwal, Ed., M. Vigoureux, Ed., X. Dai, Ed. || sboutros@cisco.com, msiva@cisco.com, raggarwa_1@yahoo.com, martin.vigoureux@alcatel-lucent.com, dai.xuehui@zte.com.cn +# RFC6436 || S. Amante, B. Carpenter, S. Jiang || shane@level3.net, brian.e.carpenter@gmail.com, shengjiang@huawei.com +# RFC6437 || S. Amante, B. Carpenter, S. Jiang, J. Rajahalme || shane@level3.net, brian.e.carpenter@gmail.com, jiangsheng@huawei.com, jarno.rajahalme@nsn.com +# RFC6438 || B. Carpenter, S. Amante || brian.e.carpenter@gmail.com, shane@level3.net +# RFC6439 || R. Perlman, D. Eastlake, Y. Li, A. Banerjee, F. Hu || Radia@alum.mit.edu, d3e3e3@gmail.com, liyizhou@huawei.com, ayabaner@cisco.com, hu.fangwei@zte.com.cn +# RFC6440 || G. Zorn, Q. Wu, Y. Wang || gwz@net-zen.net, sunseawq@huawei.com, w52006@huawei.com +# RFC6441 || L. Vegoda || leo.vegoda@icann.org +# RFC6442 || J. Polk, B. Rosen, J. Peterson || jmpolk@cisco.com, br@brianrosen.net, jon.peterson@neustar.biz +# RFC6443 || B. Rosen, H. Schulzrinne, J. Polk, A. Newton || br@brianrosen.net, hgs@cs.columbia.edu, jmpolk@cisco.com, andy@hxr.us +# RFC6444 || H. Schulzrinne, L. Liess, H. Tschofenig, B. Stark, A. Kuett || hgs+ecrit@cs.columbia.edu, L.Liess@telekom.de, Hannes.Tschofenig@gmx.net, barbara.stark@att.com, andres.kytt@skype.net +# RFC6445 || T. Nadeau, Ed., A. Koushik, Ed., R. Cetin, Ed. || thomas.nadeau@ca.com, kkoushik@cisco.com, riza.cetin@alcatel.be +# RFC6446 || A. Niemi, K. Kiss, S. Loreto || aki.niemi@nokia.com, krisztian.kiss@nokia.com, salvatore.loreto@ericsson.com +# RFC6447 || R. Mahy, B. Rosen, H. Tschofenig || rohan@ekabal.com, br@brianrosen.net, Hannes.Tschofenig@gmx.net +# RFC6448 || R. Yount || rjy@cmu.edu +# RFC6449 || J. Falk, Ed. || ietf@cybernothing.org +# RFC6450 || S. Venaas || stig@cisco.com +# RFC6451 || A. Forte, H. Schulzrinne || forte@att.com, hgs@cs.columbia.edu +# RFC6452 || P. Faltstrom, Ed., P. Hoffman, Ed. || paf@cisco.com, paul.hoffman@vpnc.org +# RFC6453 || F. Dijkstra, R. Hughes-Jones || Freek.Dijkstra@sara.nl, Richard.Hughes-Jones@dante.net +# RFC6454 || A. Barth || ietf@adambarth.com +# RFC6455 || I. Fette, A. Melnikov || ifette+ietf@google.com, Alexey.Melnikov@isode.com +# RFC6456 || H. Li, R. Zheng, A. Farrel || hongyu.lihongyu@huawei.com, robin@huawei.com, adrian@olddog.co.uk +# RFC6457 || T. Takeda, Ed., A. Farrel || takeda.tomonori@lab.ntt.co.jp, adrian@olddog.co.uk +# RFC6458 || R. Stewart, M. Tuexen, K. Poon, P. Lei, V. Yasevich || randall@lakerest.net, tuexen@fh-muenster.de, ka-cheong.poon@oracle.com, peterlei@cisco.com, vladislav.yasevich@hp.com +# RFC6459 || J. Korhonen, Ed., J. Soininen, B. Patil, T. Savolainen, G. Bajko, K. Iisakkila || jouni.nospam@gmail.com, jonne.soininen@renesasmobile.com, basavaraj.patil@nokia.com, teemu.savolainen@nokia.com, gabor.bajko@nokia.com, kaisu.iisakkila@renesasmobile.com +# RFC6460 || M. Salter, R. Housley || misalte@nsa.gov, housley@vigilsec.com +# RFC6461 || S. Channabasappa, Ed. || sumanth@cablelabs.com +# RFC6462 || A. Cooper || acooper@cdt.org +# RFC6463 || J. Korhonen, Ed., S. Gundavelli, H. Yokota, X. Cui || jouni.nospam@gmail.com, sri.gundavelli@cisco.com, yokota@kddilabs.jp, Xiangsong.Cui@huawei.com +# RFC6464 || J. Lennox, Ed., E. Ivov, E. Marocco || jonathan@vidyo.com, emcho@jitsi.org, enrico.marocco@telecomitalia.it +# RFC6465 || E. Ivov, Ed., E. Marocco, Ed., J. Lennox || emcho@jitsi.org, enrico.marocco@telecomitalia.it, jonathan@vidyo.com +# RFC6466 || G. Salgueiro || gsalguei@cisco.com +# RFC6467 || T. Kivinen || kivinen@iki.fi +# RFC6468 || A. Melnikov, B. Leiba, K. Li || Alexey.Melnikov@isode.com, barryleiba@computer.org, likepeng@huawei.com +# RFC6469 || K. Kobayashi, K. Mishima, S. Casner, C. Bormann || ikob@riken.jp, three@sfc.wide.ad.jp, casner@acm.org, cabo@tzi.org +# RFC6470 || A. Bierman || andy@yumaworks.com +# RFC6471 || C. Lewis, M. Sergeant || clewisbcp@cauce.org, matt@sergeant.org +# RFC6472 || W. Kumari, K. Sriram || warren@kumari.net, ksriram@nist.gov +# RFC6473 || P. Saint-Andre || ietf@stpeter.im +# RFC6474 || K. Li, B. Leiba || likepeng@huawei.com, barryleiba@computer.org +# RFC6475 || G. Keeni, K. Koide, S. Gundavelli, R. Wakikawa || glenn@cysols.com, ka-koide@kddi.com, sgundave@cisco.com, ryuji@us.toyota-itc.com +# RFC6476 || P. Gutmann || pgut001@cs.auckland.ac.nz +# RFC6477 || A. Melnikov, G. Lunt || Alexey.Melnikov@isode.com, graeme.lunt@smhs.co.uk +# RFC6478 || L. Martini, G. Swallow, G. Heron, M. Bocci || lmartini@cisco.com, swallow@cisco.com, giheron@cisco.com, matthew.bocci@alcatel-lucent.com +# RFC6479 || X. Zhang, T. Tsou || xiangyang.zhang@huawei.com, tena@huawei.com +# RFC6480 || M. Lepinski, S. Kent || mlepinski@bbn.com, kent@bbn.com +# RFC6481 || G. Huston, R. Loomans, G. Michaelson || gih@apnic.net, robertl@apnic.net, ggm@apnic.net +# RFC6482 || M. Lepinski, S. Kent, D. Kong || mlepinski@bbn.com, skent@bbn.com, dkong@bbn.com +# RFC6483 || G. Huston, G. Michaelson || gih@apnic.net, ggm@apnic.net +# RFC6484 || S. Kent, D. Kong, K. Seo, R. Watro || skent@bbn.com, dkong@bbn.com, kseo@bbn.com, rwatro@bbn.com +# RFC6485 || G. Huston || gih@apnic.net +# RFC6486 || R. Austein, G. Huston, S. Kent, M. Lepinski || sra@isc.org, gih@apnic.net, kent@bbn.com, mlepinski@bbn.com +# RFC6487 || G. Huston, G. Michaelson, R. Loomans || gih@apnic.net, ggm@apnic.net, robertl@apnic.net +# RFC6488 || M. Lepinski, A. Chi, S. Kent || mlepinski@bbn.com, achi@bbn.com, kent@bbn.com +# RFC6489 || G. Huston, G. Michaelson, S. Kent || gih@apnic.net, ggm@apnic.net, kent@bbn.com +# RFC6490 || G. Huston, S. Weiler, G. Michaelson, S. Kent || gih@apnic.net, weiler@sparta.com, ggm@apnic.net, kent@bbn.com +# RFC6491 || T. Manderson, L. Vegoda, S. Kent || terry.manderson@icann.org, leo.vegoda@icann.org, kent@bbn.com +# RFC6492 || G. Huston, R. Loomans, B. Ellacott, R. Austein || gih@apnic.net, robertl@apnic.net, bje@apnic.net, sra@hactrn.net +# RFC6493 || R. Bush || randy@psg.com +# RFC6494 || R. Gagliano, S. Krishnan, A. Kukec || rogaglia@cisco.com, suresh.krishnan@ericsson.com, ana.kukec@enterprisearchitects.com +# RFC6495 || R. Gagliano, S. Krishnan, A. Kukec || rogaglia@cisco.com, suresh.krishnan@ericsson.com, ana.kukec@enterprisearchitects.com +# RFC6496 || S. Krishnan, J. Laganier, M. Bonola, A. Garcia-Martinez || suresh.krishnan@ericsson.com, julien.ietf@gmail.com, marco.bonola@gmail.com, alberto@it.uc3m.es +# RFC6497 || M. Davis, A. Phillips, Y. Umaoka, C. Falk || mark@macchiato.com, addison@lab126.com, yoshito_umaoka@us.ibm.com, court@infiauto.com +# RFC6498 || J. Stone, R. Kumar, F. Andreasen || joestone@cisco.com, rkumar@cisco.com, fandreas@cisco.com +# RFC6501 || O. Novo, G. Camarillo, D. Morgan, J. Urpalainen || Oscar.Novo@ericsson.com, Gonzalo.Camarillo@ericsson.com, Dave.Morgan@fmr.com, jari.urpalainen@nokia.com +# RFC6502 || G. Camarillo, S. Srinivasan, R. Even, J. Urpalainen || Gonzalo.Camarillo@ericsson.com, srivatsa.srinivasan@gmail.com, ron.even.tlv@gmail.com, jari.urpalainen@nokia.com +# RFC6503 || M. Barnes, C. Boulton, S. Romano, H. Schulzrinne || mary.ietf.barnes@gmail.com, chris@ns-technologies.com, spromano@unina.it, hgs+xcon@cs.columbia.edu +# RFC6504 || M. Barnes, L. Miniero, R. Presta, S P. Romano || mary.ietf.barnes@gmail.com, lorenzo@meetecho.com, roberta.presta@unina.it, spromano@unina.it +# RFC6505 || S. McGlashan, T. Melanchuk, C. Boulton || smcg.stds01@mcglashan.org, timm@rainwillow.com, chris@ns-technologies.com +# RFC6506 || M. Bhatia, V. Manral, A. Lindem || manav.bhatia@alcatel-lucent.com, vishwas.manral@hp.com, acee.lindem@ericsson.com +# RFC6507 || M. Groves || Michael.Groves@cesg.gsi.gov.uk +# RFC6508 || M. Groves || Michael.Groves@cesg.gsi.gov.uk +# RFC6509 || M. Groves || Michael.Groves@cesg.gsi.gov.uk +# RFC6510 || L. Berger, G. Swallow || lberger@labn.net, swallow@cisco.com +# RFC6511 || Z. Ali, G. Swallow, R. Aggarwal || zali@cisco.com, swallow@cisco.com, raggarwa_1@yahoo.com +# RFC6512 || IJ. Wijnands, E. Rosen, M. Napierala, N. Leymann || ice@cisco.com, erosen@cisco.com, mnapierala@att.com, n.leymann@telekom.de +# RFC6513 || E. Rosen, Ed., R. Aggarwal, Ed. || erosen@cisco.com, raggarwa_1@yahoo.com +# RFC6514 || R. Aggarwal, E. Rosen, T. Morin, Y. Rekhter || raggarwa_1@yahoo.com, erosen@cisco.com, thomas.morin@orange-ftgroup.com, yakov@juniper.net +# RFC6515 || R. Aggarwal, E. Rosen || raggarwa_1@yahoo.com, erosen@cisco.com +# RFC6516 || Y. Cai, E. Rosen, Ed., I. Wijnands || ycai@cisco.com, erosen@cisco.com, ice@cisco.com +# RFC6517 || T. Morin, Ed., B. Niven-Jenkins, Ed., Y. Kamite, R. Zhang, N. Leymann, N. Bitar || thomas.morin@orange.com, ben@niven-jenkins.co.uk, y.kamite@ntt.com, raymond.zhang@alcatel-lucent.com, n.leymann@telekom.de, nabil.n.bitar@verizon.com +# RFC6518 || G. Lebovitz, M. Bhatia || gregory.ietf@gmail.com, manav.bhatia@alcatel-lucent.com +# RFC6519 || R. Maglione, A. Durand || roberta.maglione@telecomitalia.it, adurand@juniper.net +# RFC6520 || R. Seggelmann, M. Tuexen, M. Williams || seggelmann@fh-muenster.de, tuexen@fh-muenster.de, michael.glenn.williams@gmail.com +# RFC6521 || A. Makela, J. Korhonen || antti.t.makela@iki.fi, jouni.nospam@gmail.com +# RFC6522 || M. Kucherawy, Ed. || msk@cloudmark.com +# RFC6525 || R. Stewart, M. Tuexen, P. Lei || randall@lakerest.net, tuexen@fh-muenster.de, peterlei@cisco.com +# RFC6526 || B. Claise, P. Aitken, A. Johnson, G. Muenz || bclaise@cisco.com, paitken@cisco.com, andrjohn@cisco.com, muenz@net.in.tum.de +# RFC6527 || K. Tata || tata_kalyan@yahoo.com +# RFC6528 || F. Gont, S. Bellovin || fgont@si6networks.com, bellovin@acm.org +# RFC6529 || A. McKenzie, S. Crocker || amckenzie3@yahoo.com, steve@stevecrocker.com +# RFC6530 || J. Klensin, Y. Ko || john-ietf@jck.com, yangwooko@gmail.com +# RFC6531 || J. Yao, W. Mao || yaojk@cnnic.cn, maowei_ietf@cnnic.cn +# RFC6532 || A. Yang, S. Steele, N. Freed || abelyang@twnic.net.tw, Shawn.Steele@microsoft.com, ned+ietf@mrochek.com +# RFC6533 || T. Hansen, Ed., C. Newman, A. Melnikov || tony+eaidsn@maillennium.att.com, chris.newman@oracle.com, Alexey.Melnikov@isode.com +# RFC6534 || N. Duffield, A. Morton, J. Sommers || duffield@research.att.com, acmorton@att.com, jsommers@colgate.edu +# RFC6535 || B. Huang, H. Deng, T. Savolainen || bill.huang@chinamobile.com, denghui@chinamobile.com, teemu.savolainen@nokia.com +# RFC6536 || A. Bierman, M. Bjorklund || andy@yumaworks.com, mbj@tail-f.com +# RFC6537 || J. Ahrenholz || jeffrey.m.ahrenholz@boeing.com +# RFC6538 || T. Henderson, A. Gurtov || thomas.r.henderson@boeing.com, gurtov@ee.oulu.fi +# RFC6539 || V. Cakulev, G. Sundaram, I. Broustis || violeta.cakulev@alcatel-lucent.com, ganesh.sundaram@alcatel-lucent.com, ioannis.broustis@alcatel-lucent.com +# RFC6540 || W. George, C. Donley, C. Liljenstolpe, L. Howard || wesley.george@twcable.com, C.Donley@cablelabs.com, cdl@asgaard.org, lee.howard@twcable.com +# RFC6541 || M. Kucherawy || msk@cloudmark.com +# RFC6542 || S. Emery || shawn.emery@oracle.com +# RFC6543 || S. Gundavelli || sgundave@cisco.com +# RFC6544 || J. Rosenberg, A. Keranen, B. B. Lowekamp, A. B. Roach || jdrosen@jdrosen.net, ari.keranen@ericsson.com, bbl@lowekamp.net, adam@nostrum.com +# RFC6545 || K. Moriarty || Kathleen.Moriarty@emc.com +# RFC6546 || B. Trammell || trammell@tik.ee.ethz.ch +# RFC6547 || W. George || wesley.george@twcable.com +# RFC6548 || N. Brownlee, Ed., IAB || n.brownlee@auckland.ac.nz, iab@iab.org +# RFC6549 || A. Lindem, A. Roy, S. Mirtorabi || acee.lindem@ericsson.com, akr@cisco.com, sina@cisco.com +# RFC6550 || T. Winter, Ed., P. Thubert, Ed., A. Brandt, J. Hui, R. Kelsey, P. Levis, K. Pister, R. Struik, JP. Vasseur, R. Alexander || wintert@acm.org, pthubert@cisco.com, abr@sdesigns.dk, jhui@archrock.com, kelsey@ember.com, pal@cs.stanford.edu, kpister@dustnetworks.com, rstruik.ext@gmail.com, jpv@cisco.com, roger.alexander@cooperindustries.com +# RFC6551 || JP. Vasseur, Ed., M. Kim, Ed., K. Pister, N. Dejean, D. Barthel || jpv@cisco.com, mjkim@kt.com, kpister@dustnetworks.com, nicolas.dejean@coronis.com, dominique.barthel@orange-ftgroup.com +# RFC6552 || P. Thubert, Ed. || pthubert@cisco.com +# RFC6553 || J. Hui, JP. Vasseur || jonhui@cisco.com, jpv@cisco.com +# RFC6554 || J. Hui, JP. Vasseur, D. Culler, V. Manral || jonhui@cisco.com, jpv@cisco.com, culler@cs.berkeley.edu, vishwas.manral@hp.com +# RFC6555 || D. Wing, A. Yourtchenko || dwing-ietf@fuggles.com, ayourtch@cisco.com +# RFC6556 || F. Baker || fred@cisco.com +# RFC6557 || E. Lear, P. Eggert || lear@cisco.com, eggert@cs.ucla.edu +# RFC6558 || A. Melnikov, B. Leiba, K. Li || Alexey.Melnikov@isode.com, barryleiba@computer.org, likepeng@huawei.com +# RFC6559 || D. Farinacci, IJ. Wijnands, S. Venaas, M. Napierala || dino@cisco.com, ice@cisco.com, stig@cisco.com, mnapierala@att.com +# RFC6560 || G. Richards || gareth.richards@rsa.com +# RFC6561 || J. Livingood, N. Mody, M. O'Reirdan || jason_livingood@cable.comcast.com, nirmal_mody@cable.comcast.com, michael_oreirdan@cable.comcast.com +# RFC6562 || C. Perkins, JM. Valin || csp@csperkins.org, jmvalin@jmvalin.ca +# RFC6563 || S. Jiang, D. Conrad, B. Carpenter || jiangsheng@huawei.com, drc@cloudflare.com, brian.e.carpenter@gmail.com +# RFC6564 || S. Krishnan, J. Woodyatt, E. Kline, J. Hoagland, M. Bhatia || suresh.krishnan@ericsson.com, jhw@apple.com, ek@google.com, Jim_Hoagland@symantec.com, manav.bhatia@alcatel-lucent.com +# RFC6565 || P. Pillay-Esnault, P. Moyer, J. Doyle, E. Ertekin, M. Lundberg || ppe@cisco.com, pete@pollere.net, jdoyle@doyleassociates.net, ertekin_emre@bah.com, lundberg_michael@bah.com +# RFC6566 || Y. Lee, Ed., G. Bernstein, Ed., D. Li, G. Martinelli || leeyoung@huawei.com, gregb@grotto-networking.com, danli@huawei.com, giomarti@cisco.com +# RFC6567 || A. Johnston, L. Liess || alan.b.johnston@gmail.com, laura.liess.dt@gmail.com +# RFC6568 || E. Kim, D. Kaspar, JP. Vasseur || eunah.ietf@gmail.com, dokaspar.ietf@gmail.com, jpv@cisco.com +# RFC6569 || JM. Valin, S. Borilin, K. Vos, C. Montgomery, R. Chen || jmvalin@jmvalin.ca, borilin@spiritdsp.net, koen.vos@skype.net, xiphmont@xiph.org, rchen@broadcom.com +# RFC6570 || J. Gregorio, R. Fielding, M. Hadley, M. Nottingham, D. Orchard || joe@bitworking.org, fielding@gbiv.com, mhadley@mitre.org, mnot@mnot.net, orchard@pacificspirit.com +# RFC6571 || C. Filsfils, Ed., P. Francois, Ed., M. Shand, B. Decraene, J. Uttaro, N. Leymann, M. Horneffer || cf@cisco.com, pierre.francois@imdea.org, imc.shand@googlemail.com, bruno.decraene@orange.com, uttaro@att.com, N.Leymann@telekom.de, Martin.Horneffer@telekom.de +# RFC6572 || F. Xia, B. Sarikaya, J. Korhonen, Ed., S. Gundavelli, D. Damic || xiayangsong@huawei.com, sarikaya@ieee.org, jouni.nospam@gmail.com, sgundave@cisco.com, damjan.damic@siemens.com +# RFC6573 || M. Amundsen || mca@amundsen.com +# RFC6574 || H. Tschofenig, J. Arkko || Hannes.Tschofenig@gmx.net, jari.arkko@piuha.net +# RFC6575 || H. Shah, Ed., E. Rosen, Ed., G. Heron, Ed., V. Kompella, Ed. || hshah@ciena.com, erosen@cisco.com, giheron@cisco.com, vach.kompella@alcatel-lucent.com +# RFC6576 || R. Geib, Ed., A. Morton, R. Fardid, A. Steinmitz || Ruediger.Geib@telekom.de, acmorton@att.com, rfardid@cariden.com, Alexander.Steinmitz@telekom.de +# RFC6577 || M. Kucherawy || msk@cloudmark.com +# RFC6578 || C. Daboo, A. Quillaud || cyrus@daboo.name, arnaud.quillaud@oracle.com +# RFC6579 || M. Yevstifeyev || evnikita2@gmail.com +# RFC6580 || M. Ko, D. Black || mkosjc@gmail.com, david.black@emc.com +# RFC6581 || A. Kanevsky, Ed., C. Bestler, Ed., R. Sharp, S. Wise || arkady.kanevsky@gmail.com, Caitlin.Bestler@nexenta.com, robert.o.sharp@intel.com, swise@opengridcomputing.com +# RFC6582 || T. Henderson, S. Floyd, A. Gurtov, Y. Nishida || thomas.r.henderson@boeing.com, floyd@acm.org, gurtov@ee.oulu.fi, nishida@wide.ad.jp +# RFC6583 || I. Gashinsky, J. Jaeggli, W. Kumari || igor@yahoo-inc.com, jjaeggli@zynga.com, warren@kumari.net +# RFC6584 || V. Roca || vincent.roca@inria.fr +# RFC6585 || M. Nottingham, R. Fielding || mnot@mnot.net, fielding@gbiv.com +# RFC6586 || J. Arkko, A. Keranen || jari.arkko@piuha.net, ari.keranen@ericsson.com +# RFC6587 || R. Gerhards, C. Lonvick || rgerhards@adiscon.com, clonvick@cisco.com +# RFC6588 || C. Ishikawa || chiaki.ishikawa@ubin.jp +# RFC6589 || J. Livingood || jason_livingood@cable.comcast.com +# RFC6590 || J. Falk, Ed., M. Kucherawy, Ed. || ietf@cybernothing.org, msk@cloudmark.com +# RFC6591 || H. Fontana || hilda@hfontana.com +# RFC6592 || C. Pignataro || cpignata@cisco.com +# RFC6593 || C. Pignataro, J. Clarke, G. Salgueiro || cpignata@cisco.com, jclarke@cisco.com, gsalguei@cisco.com +# RFC6594 || O. Sury || ondrej.sury@nic.cz +# RFC6595 || K. Wierenga, E. Lear, S. Josefsson || klaas@cisco.com, lear@cisco.com, simon@josefsson.org +# RFC6596 || M. Ohye, J. Kupke || maileohye@gmail.com, joachim@kupke.za.net +# RFC6597 || J. Downs, Ed., J. Arbeiter, Ed. || jeff_downs@partech.com, jimsgti@gmail.com +# RFC6598 || J. Weil, V. Kuarsingh, C. Donley, C. Liljenstolpe, M. Azinger || jason.weil@twcable.com, victor.kuarsingh@gmail.com, c.donley@cablelabs.com, cdl@asgaard.org, marla.azinger@frontiercorp.com +# RFC6601 || G. Ash, Ed., D. McDysan || gash5107@yahoo.com, dave.mcdysan@verizon.com +# RFC6602 || F. Abinader, Ed., S. Gundavelli, Ed., K. Leung, S. Krishnan, D. Premec || fabinader@gmail.com, sgundave@cisco.com, kleung@cisco.com, suresh.krishnan@ericsson.com, domagoj.premec@gmail.com +# RFC6603 || J. Korhonen, Ed., T. Savolainen, S. Krishnan, O. Troan || jouni.nospam@gmail.com, teemu.savolainen@nokia.com, suresh.krishnan@ericsson.com, ot@cisco.com +# RFC6604 || D. Eastlake 3rd || d3e3e3@gmail.com +# RFC6605 || P. Hoffman, W.C.A. Wijngaards || paul.hoffman@vpnc.org, wouter@nlnetlabs.nl +# RFC6606 || E. Kim, D. Kaspar, C. Gomez, C. Bormann || eunah.ietf@gmail.com, dokaspar.ietf@gmail.com, carlesgo@entel.upc.edu, cabo@tzi.org +# RFC6607 || K. Kinnear, R. Johnson, M. Stapp || kkinnear@cisco.com, raj@cisco.com, mjs@cisco.com +# RFC6608 || J. Dong, M. Chen, A. Suryanarayana || jie.dong@huawei.com, mach.chen@huawei.com, asuryana@cisco.com +# RFC6609 || C. Daboo, A. Stone || cyrus@daboo.name, aaron@serendipity.cx +# RFC6610 || H. Jang, A. Yegin, K. Chowdhury, J. Choi, T. Lemon || heejin.jang@gmail.com, alper.yegin@yegin.org, kc@radiomobiles.com, jinchoe@gmail.com, Ted.Lemon@nominum.com +# RFC6611 || K. Chowdhury, Ed., A. Yegin || kc@radiomobiles.com, alper.yegin@yegin.org +# RFC6612 || G. Giaretta, Ed. || gerardog@qualcomm.com +# RFC6613 || A. DeKok || aland@freeradius.org +# RFC6614 || S. Winter, M. McCauley, S. Venaas, K. Wierenga || stefan.winter@restena.lu, mikem@open.com.au, stig@cisco.com, klaas@cisco.com +# RFC6615 || T. Dietz, Ed., A. Kobayashi, B. Claise, G. Muenz || Thomas.Dietz@neclab.eu, akoba@nttv6.net, bclaise@cisco.com, muenz@net.in.tum.de +# RFC6616 || E. Lear, H. Tschofenig, H. Mauldin, S. Josefsson || lear@cisco.com, Hannes.Tschofenig@gmx.net, hmauldin@cisco.com, simon@josefsson.org +# RFC6617 || D. Harkins || dharkins@arubanetworks.com +# RFC6618 || J. Korhonen, Ed., B. Patil, H. Tschofenig, D. Kroeselberg || jouni.nospam@gmail.com, basavaraj.patil@nokia.com, Hannes.Tschofenig@gmx.net, dirk.kroeselberg@siemens.com +# RFC6619 || J. Arkko, L. Eggert, M. Townsley || jari.arkko@piuha.net, lars@netapp.com, townsley@cisco.com +# RFC6620 || E. Nordmark, M. Bagnulo, E. Levy-Abegnoli || nordmark@acm.org, marcelo@it.uc3m.es, elevyabe@cisco.com +# RFC6621 || J. Macker, Ed. || macker@itd.nrl.navy.mil +# RFC6622 || U. Herberg, T. Clausen || ulrich@herberg.name, T.Clausen@computer.org +# RFC6623 || E. Burger || eburger@standardstrack.com +# RFC6624 || K. Kompella, B. Kothari, R. Cherukuri || kireeti@juniper.net, bhupesh@cisco.com, cherukuri@juniper.net +# RFC6625 || E. Rosen, Ed., Y. Rekhter, Ed., W. Hendrickx, R. Qiu || erosen@cisco.com, yakov@juniper.net, wim.henderickx@alcatel-lucent.be, rayq@huawei.com +# RFC6626 || G. Tsirtsis, V. Park, V. Narayanan, K. Leung || tsirtsis@googlemail.com, vpark@qualcomm.com, vidyan@qualcomm.com, kleung@cisco.com +# RFC6627 || G. Karagiannis, K. Chan, T. Moncaster, M. Menth, P. Eardley, B. Briscoe || g.karagiannis@utwente.nl, khchan.work@gmail.com, Toby.Moncaster@cl.cam.ac.uk, menth@informatik.uni-tuebingen.de, philip.eardley@bt.com, bob.briscoe@bt.com +# RFC6628 || S. Shin, K. Kobara || seonghan.shin@aist.go.jp, kobara_conf@m.aist.go.jp +# RFC6629 || J. Abley, M. Bagnulo, A. Garcia-Martinez || joe.abley@icann.org, marcelo@it.uc3m.es, alberto@it.uc3m.es +# RFC6630 || Z. Cao, H. Deng, Q. Wu, G. Zorn, Ed. || zehn.cao@gmail.com, denghui02@gmail.com, sunseawq@huawei.com, glenzorn@gmail.com +# RFC6631 || D. Kuegler, Y. Sheffer || dennis.kuegler@bsi.bund.de, yaronf.ietf@gmail.com +# RFC6632 || M. Ersue, Ed., B. Claise || mehmet.ersue@nsn.com, bclaise@cisco.com +# RFC6633 || F. Gont || fgont@si6networks.com +# RFC6635 || O. Kolkman, Ed., J. Halpern, Ed., IAB || olaf@nlnetlabs.nl, joel.halpern@ericsson.com, iab@iab.org +# RFC6636 || H. Asaeda, H. Liu, Q. Wu || asaeda@wide.ad.jp, helen.liu@huawei.com, bill.wu@huawei.com +# RFC6637 || A. Jivsov || Andrey_Jivsov@symantec.com +# RFC6638 || C. Daboo, B. Desruisseaux || cyrus@daboo.name, bernard.desruisseaux@oracle.com +# RFC6639 || D. King, Ed., M. Venkatesan, Ed. || daniel@olddog.co.uk, venkat.mahalingams@gmail.com +# RFC6640 || W. George || wesley.george@twcable.com +# RFC6641 || C. Everhart, W. Adamson, J. Zhang || everhart@netapp.com, andros@netapp.com, jiayingz@google.com +# RFC6642 || Q. Wu, Ed., F. Xia, R. Even || sunseawq@huawei.com, xiayangsong@huawei.com, even.roni@huawei.com +# RFC6643 || J. Schoenwaelder || j.schoenwaelder@jacobs-university.de +# RFC6644 || D. Evans, R. Droms, S. Jiang || N7DR@ipfonix.com, rdroms@cisco.com, jiangsheng@huawei.com +# RFC6645 || J. Novak || janovak@cisco.com +# RFC6646 || H. Song, N. Zong, Y. Yang, R. Alimi || haibin.song@huawei.com, zongning@huawei.com, yry@cs.yale.edu, ralimi@google.com +# RFC6647 || M. Kucherawy, D. Crocker || superuser@gmail.com, dcrocker@bbiw.net +# RFC6648 || P. Saint-Andre, D. Crocker, M. Nottingham || ietf@stpeter.im, dcrocker@bbiw.net, mnot@mnot.net +# RFC6649 || L. Hornquist Astrand, T. Yu || lha@apple.com, tlyu@mit.edu +# RFC6650 || J. Falk, M. Kucherawy, Ed. || none, superuser@gmail.com +# RFC6651 || M. Kucherawy || superuser@gmail.com +# RFC6652 || S. Kitterman || scott@kitterman.com +# RFC6653 || B. Sarikaya, F. Xia, T. Lemon || sarikaya@ieee.org, xiayangsong@huawei.com, mellon@nominum.com +# RFC6654 || T. Tsou, C. Zhou, T. Taylor, Q. Chen || Tina.Tsou.Zouting@huawei.com, cathy.zhou@huawei.com, tom.taylor.stds@gmail.com, chenqi.0819@gmail.com +# RFC6655 || D. McGrew, D. Bailey || mcgrew@cisco.com, dbailey@rsa.com +# RFC6656 || R. Johnson, K. Kinnear, M. Stapp || raj@cisco.com, kkinnear@cisco.com, mjs@cisco.com +# RFC6657 || A. Melnikov, J. Reschke || Alexey.Melnikov@isode.com, julian.reschke@greenbytes.de +# RFC6658 || S. Bryant, Ed., L. Martini, G. Swallow, A. Malis || stbryant@cisco.com, lmartini@cisco.com, swallow@cisco.com, andrew.g.malis@verizon.com +# RFC6659 || A. Begen || abegen@cisco.com +# RFC6660 || B. Briscoe, T. Moncaster, M. Menth || bob.briscoe@bt.com, toby.moncaster@cl.cam.ac.uk, menth@uni-tuebingen.de +# RFC6661 || A. Charny, F. Huang, G. Karagiannis, M. Menth, T. Taylor, Ed. || anna@mwsm.com, huangfuqing@huawei.com, g.karagiannis@utwente.nl, menth@uni-tuebingen.de, tom.taylor.stds@gmail.com +# RFC6662 || A. Charny, J. Zhang, G. Karagiannis, M. Menth, T. Taylor, Ed. || anna@mwsm.com, joyzhang@cisco.com, g.karagiannis@utwente.nl, menth@uni-tuebingen.de, tom.taylor.stds@gmail.com +# RFC6663 || G. Karagiannis, T. Taylor, K. Chan, M. Menth, P. Eardley || g.karagiannis@utwente.nl, tom.taylor.stds@gmail.com, khchan.work@gmail.com, menth@uni-tuebingen.de, philip.eardley@bt.com +# RFC6664 || J. Schaad || ietf@augustcellars.com +# RFC6665 || A.B. Roach || adam@nostrum.com +# RFC6666 || N. Hilliard, D. Freedman || nick@inex.ie, david.freedman@uk.clara.net +# RFC6667 || K. Raza, S. Boutros, C. Pignataro || skraza@cisco.com, sboutros@cisco.com, cpignata@cisco.com +# RFC6668 || D. Bider, M. Baushke || ietf-ssh2@denisbider.com, mdb@juniper.net +# RFC6669 || N. Sprecher, L. Fang || nurit.sprecher@nsn.com, lufang@cisco.com +# RFC6670 || N. Sprecher, KY. Hong || nurit.sprecher@nsn.com, hongk@cisco.com +# RFC6671 || M. Betts || malcolm.betts@zte.com.cn +# RFC6672 || S. Rose, W. Wijngaards || scott.rose@nist.gov, wouter@nlnetlabs.nl +# RFC6673 || A. Morton || acmorton@att.com +# RFC6674 || F. Brockners, S. Gundavelli, S. Speicher, D. Ward || fbrockne@cisco.com, sgundave@cisco.com, sebastian.speicher@telekom.de, wardd@cisco.com +# RFC6675 || E. Blanton, M. Allman, L. Wang, I. Jarvinen, M. Kojo, Y. Nishida || elb@psg.com, mallman@icir.org, liliw@juniper.net, ilpo.jarvinen@helsinki.fi, kojo@cs.helsinki.fi, nishida@wide.ad.jp +# RFC6676 || S. Venaas, R. Parekh, G. Van de Velde, T. Chown, M. Eubanks || stig@cisco.com, riparekh@cisco.com, gvandeve@cisco.com, tjc@ecs.soton.ac.uk, marshall.eubanks@iformata.com +# RFC6677 || S. Hartman, Ed., T. Clancy, K. Hoeper || hartmans-ietf@mit.edu, tcc@vt.edu, khoeper@motorolasolutions.com +# RFC6678 || K. Hoeper, S. Hanna, H. Zhou, J. Salowey, Ed. || khoeper@motorolasolutions.com, shanna@juniper.net, hzhou@cisco.com, jsalowey@cisco.com +# RFC6679 || M. Westerlund, I. Johansson, C. Perkins, P. O'Hanlon, K. Carlberg || magnus.westerlund@ericsson.com, ingemar.s.johansson@ericsson.com, csp@csperkins.org, piers.ohanlon@oii.ox.ac.uk, carlberg@g11.org.uk +# RFC6680 || N. Williams, L. Johansson, S. Hartman, S. Josefsson || nico@cryptonector.com, leifj@sunet.se, hartmans-ietf@mit.edu, simon@josefsson.org +# RFC6681 || M. Watson, T. Stockhammer, M. Luby || watsonm@netflix.com, stockhammer@nomor.de, luby@qti.qualcomm.com +# RFC6682 || M. Watson, T. Stockhammer, M. Luby || watsonm@netflix.com, stockhammer@nomor.de, luby@qti.qualcomm.com +# RFC6683 || A. Begen, T. Stockhammer || abegen@cisco.com, stockhammer@nomor.de +# RFC6684 || B. Trammell || trammell@tik.ee.ethz.ch +# RFC6685 || B. Trammell || trammell@tik.ee.ethz.ch +# RFC6686 || M. Kucherawy || superuser@gmail.com +# RFC6687 || J. Tripathi, Ed., J. de Oliveira, Ed., JP. Vasseur, Ed. || jt369@drexel.edu, jau@coe.drexel.edu, jpv@cisco.com +# RFC6688 || D. Black, Ed., J. Glasgow, S. Faibish || david.black@emc.com, jglasgow@google.com, sfaibish@emc.com +# RFC6689 || L. Berger || lberger@labn.net +# RFC6690 || Z. Shelby || zach@sensinode.com +# RFC6691 || D. Borman || david.borman@quantum.com +# RFC6692 || R. Clayton, M. Kucherawy || richard.clayton@cl.cam.ac.uk, superuser@gmail.com +# RFC6693 || A. Lindgren, A. Doria, E. Davies, S. Grasic || andersl@sics.se, avri@acm.org, elwynd@folly.org.uk, samo.grasic@ltu.se +# RFC6694 || S. Moonesamy, Ed. || sm+ietf@elandsys.com +# RFC6695 || R. Asati || rajiva@cisco.com +# RFC6696 || Z. Cao, B. He, Y. Shi, Q. Wu, Ed., G. Zorn, Ed. || caozhen@chinamobile.com, hebaohong@catr.cn, shiyang1@huawei.com, bill.wu@huawei.com, glenzorn@gmail.com +# RFC6697 || G. Zorn, Ed., Q. Wu, T. Taylor, Y. Nir, K. Hoeper, S. Decugis || glenzorn@gmail.com, bill.wu@huawei.com, tom.taylor.stds@gmail.com, ynir@checkpoint.com, khoeper@motorolasolutions.com, sdecugis@freediameter.net +# RFC6698 || P. Hoffman, J. Schlyter || paul.hoffman@vpnc.org, jakob@kirei.se +# RFC6701 || A. Farrel, P. Resnick || adrian@olddog.co.uk, presnick@qti.qualcomm.com +# RFC6702 || T. Polk, P. Saint-Andre || tim.polk@nist.gov, ietf@stpeter.im +# RFC6703 || A. Morton, G. Ramachandran, G. Maguluri || acmorton@att.com, gomathi@att.com, gmaguluri@att.com +# RFC6704 || D. Miles, W. Dec, J. Bristow, R. Maglione || davidmiles@google.com, wdec@cisco.com, James.Bristow@swisscom.com, roberta.maglione@telecomitalia.it +# RFC6705 || S. Krishnan, R. Koodli, P. Loureiro, Q. Wu, A. Dutta || suresh.krishnan@ericsson.com, rkoodli@cisco.com, loureiro@neclab.eu, Sunseawq@huawei.com, adutta@niksun.com +# RFC6706 || F. Templin, Ed. || fltemplin@acm.org +# RFC6707 || B. Niven-Jenkins, F. Le Faucheur, N. Bitar || ben@velocix.com, flefauch@cisco.com, nabil.n.bitar@verizon.com +# RFC6708 || S. Kiesel, Ed., S. Previdi, M. Stiemerling, R. Woundy, Y. Yang || ietf-alto@skiesel.de, sprevidi@cisco.com, martin.stiemerling@neclab.eu, Richard_Woundy@cable.comcast.com, yry@cs.yale.edu +# RFC6709 || B. Carpenter, B. Aboba, Ed., S. Cheshire || brian.e.carpenter@gmail.com, bernard_aboba@hotmail.com, cheshire@apple.com +# RFC6710 || A. Melnikov, K. Carlberg || Alexey.Melnikov@isode.com, carlberg@g11.org.uk +# RFC6711 || L. Johansson || leifj@nordu.net +# RFC6712 || T. Kause, M. Peylo || toka@ssh.com, martin.peylo@nsn.com +# RFC6713 || J. Levine || standards@taugh.com +# RFC6714 || C. Holmberg, S. Blau, E. Burger || christer.holmberg@ericsson.com, staffan.blau@ericsson.com, eburger@standardstrack.com +# RFC6715 || D. Cauchie, B. Leiba, K. Li || dany.cauchie@orange.com, barryleiba@computer.org, likepeng@huawei.com +# RFC6716 || JM. Valin, K. Vos, T. Terriberry || jmvalin@jmvalin.ca, koenvos74@gmail.com, tterriberry@mozilla.com +# RFC6717 || H. Hotz, R. Allbery || hotz@jpl.nasa.gov, rra@stanford.edu +# RFC6718 || P. Muley, M. Aissaoui, M. Bocci || praveen.muley@alcatel-lucent.com, mustapha.aissaoui@alcatel-lucent.com, matthew.bocci@alcatel-lucent.com +# RFC6719 || O. Gnawali, P. Levis || gnawali@cs.uh.edu, pal@cs.stanford.edu +# RFC6720 || C. Pignataro, R. Asati || cpignata@cisco.com, rajiva@cisco.com +# RFC6721 || J. Snell || jasnell@us.ibm.com +# RFC6722 || P. Hoffman, Ed. || paul.hoffman@vpnc.org +# RFC6723 || L. Jin, Ed., R. Key, Ed., S. Delord, T. Nadeau, S. Boutros || lizhong.jin@zte.com.cn, raymond.key@ieee.org, simon.delord@gmail.com, tnadeau@juniper.net, sboutros@cisco.com +# RFC6724 || D. Thaler, Ed., R. Draves, A. Matsumoto, T. Chown || dthaler@microsoft.com, richdr@microsoft.com, arifumi@nttv6.net, tjc@ecs.soton.ac.uk +# RFC6725 || S. Rose || scottr.nist@gmail.com +# RFC6726 || T. Paila, R. Walsh, M. Luby, V. Roca, R. Lehtonen || toni.paila@gmail.com, roderick.walsh@tut.fi, luby@qti.qualcomm.com, vincent.roca@inria.fr, rami.lehtonen@teliasonera.com +# RFC6727 || T. Dietz, Ed., B. Claise, J. Quittek || dietz@neclab.eu, bclaise@cisco.com, quittek@neclab.eu +# RFC6728 || G. Muenz, B. Claise, P. Aitken || muenz@net.in.tum.de, bclaise@cisco.com, paitken@cisco.com +# RFC6729 || D. Crocker, M. Kucherawy || dcrocker@bbiw.net, superuser@gmail.com +# RFC6730 || S. Krishnan, J. Halpern || suresh.krishnan@ericsson.com, joel.halpern@ericsson.com +# RFC6731 || T. Savolainen, J. Kato, T. Lemon || teemu.savolainen@nokia.com, kato@syce.net, Ted.Lemon@nominum.com +# RFC6732 || V. Kuarsingh, Ed., Y. Lee, O. Vautrin || victor.kuarsingh@gmail.com, yiu_lee@cable.comcast.com, olivier@juniper.net +# RFC6733 || V. Fajardo, Ed., J. Arkko, J. Loughney, G. Zorn, Ed. || vf0213@gmail.com, jari.arkko@ericsson.com, john.loughney@nokia.com, glenzorn@gmail.com +# RFC6734 || G. Zorn, Q. Wu, V. Cakulev || glenzorn@gmail.com, sunseawq@huawei.com, violeta.cakulev@alcatel-lucent.com +# RFC6735 || K. Carlberg, Ed., T. Taylor || carlberg@g11.org.uk, tom.taylor.stds@gmail.com +# RFC6736 || F. Brockners, S. Bhandari, V. Singh, V. Fajardo || fbrockne@cisco.com, shwethab@cisco.com, vaneeta.singh@gmail.com, vf0213@gmail.com +# RFC6737 || K. Jiao, G. Zorn || kangjiao@huawei.com, gwz@net-zen.net +# RFC6738 || V. Cakulev, A. Lior, S. Mizikovsky || violeta.cakulev@alcatel-lucent.com, avi.ietf@lior.org, Simon.Mizikovsky@alcatel-lucent.com +# RFC6739 || H. Schulzrinne, H. Tschofenig || hgs+ecrit@cs.columbia.edu, Hannes.Tschofenig@gmx.net +# RFC6740 || RJ Atkinson, SN Bhatti || rja.lists@gmail.com, saleem@cs.st-andrews.ac.uk +# RFC6741 || RJ Atkinson, SN Bhatti || rja.lists@gmail.com, saleem@cs.st-andrews.ac.uk +# RFC6742 || RJ Atkinson, SN Bhatti, S. Rose || rja.lists@gmail.com, saleem@cs.st-andrews.ac.uk, scottr.nist@gmail.com +# RFC6743 || RJ Atkinson, SN Bhatti || rja.lists@gmail.com, saleem@cs.st-andrews.ac.uk +# RFC6744 || RJ Atkinson, SN Bhatti || rja.lists@gmail.com, saleem@cs.st-andrews.ac.uk +# RFC6745 || RJ Atkinson, SN Bhatti || rja.lists@gmail.com, saleem@cs.st-andrews.ac.uk +# RFC6746 || RJ Atkinson, SN Bhatti || rja.lists@gmail.com, saleem@cs.st-andrews.ac.uk +# RFC6747 || RJ Atkinson, SN Bhatti || rja.lists@gmail.com, saleem@cs.st-andrews.ac.uk +# RFC6748 || RJ Atkinson, SN Bhatti || rja.lists@gmail.com, saleem@cs.st-andrews.ac.uk +# RFC6749 || D. Hardt, Ed. || dick.hardt@gmail.com +# RFC6750 || M. Jones, D. Hardt || mbj@microsoft.com, dick.hardt@gmail.com +# RFC6751 || R. Despres, Ed., B. Carpenter, D. Wing, S. Jiang || despres.remi@laposte.net, brian.e.carpenter@gmail.com, dwing-ietf@fuggles.com, shengjiang@huawei.com +# RFC6752 || A. Kirkham || tkirkham@paloaltonetworks.com +# RFC6753 || J. Winterbottom, H. Tschofenig, H. Schulzrinne, M. Thomson || james.winterbottom@commscope.com, Hannes.Tschofenig@gmx.net, hgs@cs.columbia.edu, martin.thomson@skype.net +# RFC6754 || Y. Cai, L. Wei, H. Ou, V. Arya, S. Jethwani || yiqunc@microsoft.com, lwei@cisco.com, hou@cisco.com, varya@directv.com, sjethwani@directv.com +# RFC6755 || B. Campbell, H. Tschofenig || brian.d.campbell@gmail.com, hannes.tschofenig@gmx.net +# RFC6756 || S. Trowbridge, Ed., E. Lear, Ed., G. Fishman, Ed., S. Bradner, Ed. || steve.trowbridge@alcatel-lucent.com, lear@cisco.com, gryfishman@aol.com, sob@harvard.edu +# RFC6757 || S. Gundavelli, Ed., J. Korhonen, Ed., M. Grayson, K. Leung, R. Pazhyannur || sgundave@cisco.com, jouni.nospam@gmail.com, mgrayson@cisco.com, kleung@cisco.com, rpazhyan@cisco.com +# RFC6758 || A. Melnikov, K. Carlberg || Alexey.Melnikov@isode.com, carlberg@g11.org.uk +# RFC6759 || B. Claise, P. Aitken, N. Ben-Dvora || bclaise@cisco.com, paitken@cisco.com, nirbd@cisco.com +# RFC6760 || S. Cheshire, M. Krochmal || cheshire@apple.com, marc@apple.com +# RFC6761 || S. Cheshire, M. Krochmal || cheshire@apple.com, marc@apple.com +# RFC6762 || S. Cheshire, M. Krochmal || cheshire@apple.com, marc@apple.com +# RFC6763 || S. Cheshire, M. Krochmal || cheshire@apple.com, marc@apple.com +# RFC6764 || C. Daboo || cyrus@daboo.name +# RFC6765 || E. Beili, M. Morgenstern || edward.beili@actelis.com, moti.morgenstern@ecitele.com +# RFC6766 || E. Beili || edward.beili@actelis.com +# RFC6767 || E. Beili, M. Morgenstern || edward.beili@actelis.com, moti.morgenstern@ecitele.com +# RFC6768 || E. Beili || edward.beili@actelis.com +# RFC6769 || R. Raszuk, J. Heitz, A. Lo, L. Zhang, X. Xu || robert@raszuk.net, jakob.heitz@ericsson.com, altonlo@aristanetworks.com, lixia@cs.ucla.edu, xuxh@huawei.com +# RFC6770 || G. Bertrand, Ed., E. Stephan, T. Burbridge, P. Eardley, K. Ma, G. Watson || gilles.bertrand@orange.com, emile.stephan@orange.com, trevor.burbridge@bt.com, philip.eardley@bt.com, kevin.ma@azukisystems.com, gwatson@velocix.com +# RFC6771 || L. Eggert, G. Camarillo || lars@netapp.com, Gonzalo.Camarillo@ericsson.com +# RFC6772 || H. Schulzrinne, Ed., H. Tschofenig, Ed., J. Cuellar, J. Polk, J. Morris, M. Thomson || schulzrinne@cs.columbia.edu, Hannes.Tschofenig@gmx.net, Jorge.Cuellar@siemens.com, jmpolk@cisco.com, ietf@jmorris.org, martin.thomson@gmail.com +# RFC6773 || T. Phelan, G. Fairhurst, C. Perkins || tphelan@sonusnet.com, gorry@erg.abdn.ac.uk, csp@csperkins.org +# RFC6774 || R. Raszuk, Ed., R. Fernando, K. Patel, D. McPherson, K. Kumaki || robert@raszuk.net, rex@cisco.com, keyupate@cisco.com, dmcpherson@verisign.com, ke-kumaki@kddi.com +# RFC6775 || Z. Shelby, Ed., S. Chakrabarti, E. Nordmark, C. Bormann || zach@sensinode.com, samita.chakrabarti@ericsson.com, nordmark@cisco.com, cabo@tzi.org +# RFC6776 || A. Clark, Q. Wu || alan.d.clark@telchemy.com, sunseawq@huawei.com +# RFC6777 || W. Sun, Ed., G. Zhang, Ed., J. Gao, G. Xie, R. Papneja || sun.weiqiang@gmail.com, zhangguoying@catr.cn, gjhhit@huawei.com, xieg@cs.ucr.edu, rajiv.papneja@huawei.com +# RFC6778 || R. Sparks || RjS@nostrum.com +# RFC6779 || U. Herberg, R. Cole, I. Chakeres || ulrich@herberg.name, robert.g.cole@us.army.mil, ian.chakeres@gmail.com +# RFC6780 || L. Berger, F. Le Faucheur, A. Narayanan || lberger@labn.net, flefauch@cisco.com, ashokn@cisco.com +# RFC6781 || O. Kolkman, W. Mekking, R. Gieben || olaf@nlnetlabs.nl, matthijs@nlnetlabs.nl, miek.gieben@sidn.nl +# RFC6782 || V. Kuarsingh, Ed., L. Howard || victor.kuarsingh@gmail.com, lee.howard@twcable.com +# RFC6783 || J. Levine, R. Gellens || standards@taugh.com, rg+ietf@qti.qualcomm.com +# RFC6784 || S. Sakane, M. Ishiyama || ssakane@cisco.com, masahiro.ishiyama@toshiba.co.jp +# RFC6785 || B. Leiba || barryleiba@computer.org +# RFC6786 || A. Yegin, R. Cragie || alper.yegin@yegin.org, robert.cragie@gridmerge.com +# RFC6787 || D. Burnett, S. Shanmugham || dburnett@voxeo.com, sarvi@cisco.com +# RFC6788 || S. Krishnan, A. Kavanagh, B. Varga, S. Ooghe, E. Nordmark || suresh.krishnan@ericsson.com, alan.kavanagh@ericsson.com, balazs.a.varga@ericsson.com, sven.ooghe@alcatel-lucent.com, nordmark@cisco.com +# RFC6789 || B. Briscoe, Ed., R. Woundy, Ed., A. Cooper, Ed. || bob.briscoe@bt.com, richard_woundy@cable.comcast.com, acooper@cdt.org +# RFC6790 || K. Kompella, J. Drake, S. Amante, W. Henderickx, L. Yong || kireeti.kompella@gmail.com, jdrake@juniper.net, shane@level3.net, wim.henderickx@alcatel-lucent.com, lucy.yong@huawei.com +# RFC6791 || X. Li, C. Bao, D. Wing, R. Vaithianathan, G. Huston || xing@cernet.edu.cn, congxiao@cernet.edu.cn, dwing-ietf@fuggles.com, rvaithia@cisco.com, gih@apnic.net +# RFC6792 || Q. Wu, Ed., G. Hunt, P. Arden || sunseawq@huawei.com, r.geoff.hunt@gmail.com, philip.arden@bt.com +# RFC6793 || Q. Vohra, E. Chen || quaizar.vohra@gmail.com, enkechen@cisco.com +# RFC6794 || V. Hilt, G. Camarillo, J. Rosenberg || volker.hilt@bell-labs.com, Gonzalo.Camarillo@ericsson.com, jdrosen@jdrosen.net +# RFC6795 || V. Hilt, G. Camarillo || volker.hilt@bell-labs.com, Gonzalo.Camarillo@ericsson.com +# RFC6796 || V. Hilt, G. Camarillo, J. Rosenberg, D. Worley || volker.hilt@bell-labs.com, Gonzalo.Camarillo@ericsson.com, jdrosen@jdrosen.net, worley@ariadne.com +# RFC6797 || J. Hodges, C. Jackson, A. Barth || Jeff.Hodges@PayPal.com, collin.jackson@sv.cmu.edu, ietf@adambarth.com +# RFC6798 || A. Clark, Q. Wu || alan.d.clark@telchemy.com, sunseawq@huawei.com +# RFC6801 || U. Kozat, A. Begen || kozat@docomolabs-usa.com, abegen@cisco.com +# RFC6802 || S. Baillargeon, C. Flinta, A. Johnsson || steve.baillargeon@ericsson.com, christofer.flinta@ericsson.com, andreas.a.johnsson@ericsson.com +# RFC6803 || G. Hudson || ghudson@mit.edu +# RFC6804 || B. Manning || bmanning@sfc.keio.ac.jp +# RFC6805 || D. King, Ed., A. Farrel, Ed. || daniel@olddog.co.uk, adrian@olddog.co.uk +# RFC6806 || S. Hartman, Ed., K. Raeburn, L. Zhu || hartmans-ietf@mit.edu, raeburn@mit.edu, lzhu@microsoft.com +# RFC6807 || D. Farinacci, G. Shepherd, S. Venaas, Y. Cai || dino@cisco.com, gjshep@gmail.com, stig@cisco.com, yiqunc@microsoft.com +# RFC6808 || L. Ciavattone, R. Geib, A. Morton, M. Wieser || lencia@att.com, Ruediger.Geib@telekom.de, acmorton@att.com, matthias_michael.wieser@stud.tu-darmstadt.de +# RFC6809 || C. Holmberg, I. Sedlacek, H. Kaplan || christer.holmberg@ericsson.com, ivo.sedlacek@ericsson.com, hkaplan@acmepacket.com +# RFC6810 || R. Bush, R. Austein || randy@psg.com, sra@hactrn.net +# RFC6811 || P. Mohapatra, J. Scudder, D. Ward, R. Bush, R. Austein || pmohapat@cisco.com, jgs@juniper.net, dward@cisco.com, randy@psg.com, sra@hactrn.net +# RFC6812 || M. Chiba, A. Clemm, S. Medley, J. Salowey, S. Thombare, E. Yedavalli || mchiba@cisco.com, alex@cisco.com, stmedley@cisco.com, jsalowey@cisco.com, thombare@cisco.com, eshwar@cisco.com +# RFC6813 || J. Salowey, S. Hanna || jsalowey@cisco.com, shanna@juniper.net +# RFC6814 || C. Pignataro, F. Gont || cpignata@cisco.com, fgont@si6networks.com +# RFC6815 || S. Bradner, K. Dubray, J. McQuaid, A. Morton || sob@harvard.edu, kdubray@juniper.net, jim@turnipvideo.com, acmorton@att.com +# RFC6816 || V. Roca, M. Cunche, J. Lacan || vincent.roca@inria.fr, mathieu.cunche@inria.fr, jerome.lacan@isae.fr +# RFC6817 || S. Shalunov, G. Hazel, J. Iyengar, M. Kuehlewind || shalunov@shlang.com, greg@bittorrent.com, jiyengar@fandm.edu, mirja.kuehlewind@ikr.uni-stuttgart.de +# RFC6818 || P. Yee || peter@akayla.com +# RFC6819 || T. Lodderstedt, Ed., M. McGloin, P. Hunt || torsten@lodderstedt.net, mark.mcgloin@ie.ibm.com, phil.hunt@yahoo.com +# RFC6820 || T. Narten, M. Karir, I. Foo || narten@us.ibm.com, mkarir@merit.edu, Ian.Foo@huawei.com +# RFC6821 || E. Marocco, A. Fusco, I. Rimac, V. Gurbani || enrico.marocco@telecomitalia.it, antonio2.fusco@telecomitalia.it, rimac@bell-labs.com, vkg@bell-labs.com +# RFC6822 || S. Previdi, Ed., L. Ginsberg, M. Shand, A. Roy, D. Ward || sprevidi@cisco.com, ginsberg@cisco.com, imc.shand@gmail.com, akr@cisco.com, wardd@cisco.com +# RFC6823 || L. Ginsberg, S. Previdi, M. Shand || ginsberg@cisco.com, sprevidi@cisco.com, imc.shand@gmail.com +# RFC6824 || A. Ford, C. Raiciu, M. Handley, O. Bonaventure || alanford@cisco.com, costin.raiciu@cs.pub.ro, m.handley@cs.ucl.ac.uk, olivier.bonaventure@uclouvain.be +# RFC6825 || M. Miyazawa, T. Otani, K. Kumaki, T. Nadeau || ma-miyazawa@kddilabs.jp, Tm-otani@kddi.com, ke-kumaki@kddi.com, tnadeau@juniper.net +# RFC6826 || IJ. Wijnands, Ed., T. Eckert, N. Leymann, M. Napierala || ice@cisco.com, eckert@cisco.com, n.leymann@telekom.de, mnapierala@att.com +# RFC6827 || A. Malis, Ed., A. Lindem, Ed., D. Papadimitriou, Ed. || andrew.g.malis@verizon.com, acee.lindem@ericsson.com, dimitri.papadimitriou@alcatel-lucent.com +# RFC6828 || J. Xia || xiajinwei@huawei.com +# RFC6829 || M. Chen, P. Pan, C. Pignataro, R. Asati || mach@huawei.com, ppan@infinera.com, cpignata@cisco.com, rajiva@cisco.com +# RFC6830 || D. Farinacci, V. Fuller, D. Meyer, D. Lewis || farinacci@gmail.com, vaf@vaf.net, dmm@1-4-5.net, darlewis@cisco.com +# RFC6831 || D. Farinacci, D. Meyer, J. Zwiebel, S. Venaas || farinacci@gmail.com, dmm@cisco.com, jzwiebel@cruzio.com, stig@cisco.com +# RFC6832 || D. Lewis, D. Meyer, D. Farinacci, V. Fuller || darlewis@cisco.com, dmm@1-4-5.net, farinacci@gmail.com, vaf@vaf.net +# RFC6833 || V. Fuller, D. Farinacci || vaf@vaf.net, farinacci@gmail.com +# RFC6834 || L. Iannone, D. Saucez, O. Bonaventure || luigi.iannone@telecom-paristech.fr, damien.saucez@inria.fr, olivier.bonaventure@uclouvain.be +# RFC6835 || D. Farinacci, D. Meyer || farinacci@gmail.com, dmm@cisco.com +# RFC6836 || V. Fuller, D. Farinacci, D. Meyer, D. Lewis || vaf@vaf.net, farinacci@gmail.com, dmm@1-4-5.net, darlewis@cisco.com +# RFC6837 || E. Lear || lear@cisco.com +# RFC6838 || N. Freed, J. Klensin, T. Hansen || ned+ietf@mrochek.com, john+ietf@jck.com, tony+mtsuffix@maillennium.att.com +# RFC6839 || T. Hansen, A. Melnikov || tony+sss@maillennium.att.com, Alexey.Melnikov@isode.com +# RFC6840 || S. Weiler, Ed., D. Blacka, Ed. || weiler@tislabs.com, davidb@verisign.com +# RFC6841 || F. Ljunggren, AM. Eklund Lowinder, T. Okubo || fredrik@kirei.se, amel@iis.se, tomofumi.okubo@icann.org +# RFC6842 || N. Swamy, G. Halwasia, P. Jhingran || nn.swamy@samsung.com, ghalwasi@cisco.com, pjhingra@cisco.com +# RFC6843 || A. Clark, K. Gross, Q. Wu || alan.d.clark@telchemy.com, kevin.gross@avanw.com, sunseawq@huawei.com +# RFC6844 || P. Hallam-Baker, R. Stradling || philliph@comodo.com, rob.stradling@comodo.com +# RFC6845 || N. Sheth, L. Wang, J. Zhang || nsheth@contrailsystems.com, liliw@juniper.net, zzhang@juniper.net +# RFC6846 || G. Pelletier, K. Sandlund, L-E. Jonsson, M. West || ghyslain.pelletier@interdigital.com, kristofer.sandlund@ericsson.com, lars-erik@lejonsson.com, mark.a.west@roke.co.uk +# RFC6847 || D. Melman, T. Mizrahi, D. Eastlake 3rd || davidme@marvell.com, talmi@marvell.com, d3e3e3@gmail.com +# RFC6848 || J. Winterbottom, M. Thomson, R. Barnes, B. Rosen, R. George || james.winterbottom@commscope.com, martin.thomson@gmail.com, rbarnes@bbn.com, br@brianrosen.net, robinsgv@gmail.com +# RFC6849 || H. Kaplan, Ed., K. Hedayat, N. Venna, P. Jones, N. Stratton || hkaplan@acmepacket.com, kh274@cornell.edu, vnagarjuna@saperix.com, paulej@packetizer.com, nathan@robotics.net +# RFC6850 || A. Rijhsinghani, K. Zebrose || anil@charter.net, zebrose@alum.mit.edu +# RFC6851 || A. Gulbrandsen, N. Freed, Ed. || arnt@gulbrandsen.priv.no, ned+ietf@mrochek.com +# RFC6852 || R. Housley, S. Mills, J. Jaffe, B. Aboba, L. St.Amour || housley@vigilsec.com, s.mills@ieee.org, jeff@w3.org, bernard_aboba@hotmail.com, st.amour@isoc.org +# RFC6853 || J. Brzozowski, J. Tremblay, J. Chen, T. Mrugalski || john_brzozowski@cable.comcast.com, jf@jftremblay.com, jack.chen@twcable.com, tomasz.mrugalski@gmail.com +# RFC6854 || B. Leiba || barryleiba@computer.org +# RFC6855 || P. Resnick, Ed., C. Newman, Ed., S. Shen, Ed. || presnick@qti.qualcomm.com, chris.newman@oracle.com, shenshuo@cnnic.cn +# RFC6856 || R. Gellens, C. Newman, J. Yao, K. Fujiwara || rg+ietf@qualcomm.com, chris.newman@oracle.com, yaojk@cnnic.cn, fujiwara@jprs.co.jp +# RFC6857 || K. Fujiwara || fujiwara@jprs.co.jp +# RFC6858 || A. Gulbrandsen || arnt@gulbrandsen.priv.no +# RFC6859 || B. Leiba || barryleiba@computer.org +# RFC6860 || Y. Yang, A. Retana, A. Roy || yiya@cisco.com, aretana@cisco.com, akr@cisco.com +# RFC6861 || I. Dzmanashvili || ioseb.dzmanashvili@gmail.com +# RFC6862 || G. Lebovitz, M. Bhatia, B. Weis || gregory.ietf@gmail.com, manav.bhatia@alcatel-lucent.com, bew@cisco.com +# RFC6863 || S. Hartman, D. Zhang || hartmans-ietf@mit.edu, zhangdacheng@huawei.com +# RFC6864 || J. Touch || touch@isi.edu +# RFC6865 || V. Roca, M. Cunche, J. Lacan, A. Bouabdallah, K. Matsuzono || vincent.roca@inria.fr, mathieu.cunche@inria.fr, jerome.lacan@isae.fr, abouabdallah@cdta.dz, kazuhisa@sfc.wide.ad.jp +# RFC6866 || B. Carpenter, S. Jiang || brian.e.carpenter@gmail.com, jiangsheng@huawei.com +# RFC6867 || Y. Nir, Q. Wu || ynir@checkpoint.com, sunseawq@huawei.com +# RFC6868 || C. Daboo || cyrus@daboo.name +# RFC6869 || G. Salgueiro, J. Clarke, P. Saint-Andre || gsalguei@cisco.com, jclarke@cisco.com, ietf@stpeter.im +# RFC6870 || P. Muley, Ed., M. Aissaoui, Ed. || praveen.muley@alcatel-lucent.com, mustapha.aissaoui@alcatel-lucent.com +# RFC6871 || R. Gilman, R. Even, F. Andreasen || bob_gilman@comcast.net, roni.even@mail01.huawei.com, fandreas@cisco.com +# RFC6872 || V. Gurbani, Ed., E. Burger, Ed., T. Anjali, H. Abdelnur, O. Festor || vkg@bell-labs.com, eburger@standardstrack.com, tricha@ece.iit.edu, humbol@gmail.com, Olivier.Festor@loria.fr +# RFC6873 || G. Salgueiro, V. Gurbani, A. B. Roach || gsalguei@cisco.com, vkg@bell-labs.com, adam@nostrum.com +# RFC6874 || B. Carpenter, S. Cheshire, R. Hinden || brian.e.carpenter@gmail.com, cheshire@apple.com, bob.hinden@gmail.com +# RFC6875 || S. Kamei, T. Momose, T. Inoue, T. Nishitani || skame@nttv6.jp, tmomose@cisco.com, inoue@jp.ntt.net, tomohiro.nishitani@ntt.com +# RFC6876 || P. Sangster, N. Cam-Winget, J. Salowey || paul_sangster@symantec.com, ncamwing@cisco.com, jsalowey@cisco.com +# RFC6877 || M. Mawatari, M. Kawashima, C. Byrne || mawatari@jpix.ad.jp, kawashimam@vx.jp.nec.com, cameron.byrne@t-mobile.com +# RFC6878 || A.B. Roach || adam@nostrum.com +# RFC6879 || S. Jiang, B. Liu, B. Carpenter || jiangsheng@huawei.com, leo.liubing@huawei.com, brian.e.carpenter@gmail.com +# RFC6880 || L. Johansson || leifj@sunet.se +# RFC6881 || B. Rosen, J. Polk || br@brianrosen.net, jmpolk@cisco.com +# RFC6882 || K. Kumaki, Ed., T. Murai, D. Cheng, S. Matsushima, P. Jiang || ke-kumaki@kddi.com, murai@fnsc.co.jp, dean.cheng@huawei.com, satoru.matsushima@g.softbank.co.jp, pe-jiang@kddi.com +# RFC6883 || B. Carpenter, S. Jiang || brian.e.carpenter@gmail.com, jiangsheng@huawei.com +# RFC6884 || Z. Fang || zfang@qualcomm.com +# RFC6885 || M. Blanchet, A. Sullivan || Marc.Blanchet@viagenie.ca, asullivan@dyn.com +# RFC6886 || S. Cheshire, M. Krochmal || cheshire@apple.com, marc@apple.com +# RFC6887 || D. Wing, Ed., S. Cheshire, M. Boucadair, R. Penno, P. Selkirk || dwing-ietf@fuggles.com, cheshire@apple.com, mohamed.boucadair@orange.com, repenno@cisco.com, pselkirk@isc.org +# RFC6888 || S. Perreault, Ed., I. Yamagata, S. Miyakawa, A. Nakagawa, H. Ashida || simon.perreault@viagenie.ca, ikuhei@nttv6.jp, miyakawa@nttv6.jp, a-nakagawa@jpix.ad.jp, hiashida@cisco.com +# RFC6889 || R. Penno, T. Saxena, M. Boucadair, S. Sivakumar || rpenno@juniper.net, tasaxena@cisco.com, mohamed.boucadair@orange.com, ssenthil@cisco.com +# RFC6890 || M. Cotton, L. Vegoda, R. Bonica, Ed., B. Haberman || michelle.cotton@icann.org, leo.vegoda@icann.org, rbonica@juniper.net, brian@innovationslab.net +# RFC6891 || J. Damas, M. Graff, P. Vixie || joao@bondis.org, explorer@flame.org, vixie@isc.org +# RFC6892 || E. Wilde || erik.wilde@emc.com +# RFC6893 || P. Higgs, P. Szucs || paul.higgs@ericsson.com, paul.szucs@eu.sony.com +# RFC6894 || R. Papneja, S. Vapiwala, J. Karthik, S. Poretsky, S. Rao, JL. Le Roux || rajiv.papneja@huawei.com, svapiwal@cisco.com, jkarthik@cisco.com, sporetsky@allot.com, shankar.rao@du.edu, jeanlouis.leroux@orange.com +# RFC6895 || D. Eastlake 3rd || d3e3e3@gmail.com +# RFC6896 || S. Barbato, S. Dorigotti, T. Fossati, Ed. || tat@koanlogic.com, stewy@koanlogic.com, tho@koanlogic.com +# RFC6897 || M. Scharf, A. Ford || michael.scharf@alcatel-lucent.com, alanford@cisco.com +# RFC6898 || D. Li, D. Ceccarelli, L. Berger || huawei.danli@huawei.com, daniele.ceccarelli@ericsson.com, lberger@labn.net +# RFC6901 || P. Bryan, Ed., K. Zyp, M. Nottingham, Ed. || pbryan@anode.ca, kris@sitepen.com, mnot@mnot.net +# RFC6902 || P. Bryan, Ed., M. Nottingham, Ed. || pbryan@anode.ca, mnot@mnot.net +# RFC6903 || J. Snell || jasnell@gmail.com +# RFC6904 || J. Lennox || jonathan@vidyo.com +# RFC6905 || T. Senevirathne, D. Bond, S. Aldrin, Y. Li, R. Watve || tsenevir@cisco.com, mokon@mokon.net, aldrin.ietf@gmail.com, liyizhou@huawei.com, rwatve@cisco.com +# RFC6906 || E. Wilde || erik.wilde@emc.com +# RFC6907 || T. Manderson, K. Sriram, R. White || terry.manderson@icann.org, ksriram@nist.gov, russ@riw.us +# RFC6908 || Y. Lee, R. Maglione, C. Williams, C. Jacquenet, M. Boucadair || yiu_lee@cable.comcast.com, robmgl@cisco.com, carlw@mcsr-labs.org, christian.jacquenet@orange.com, mohamed.boucadair@orange.com +# RFC6909 || S. Gundavelli, Ed., X. Zhou, J. Korhonen, G. Feige, R. Koodli || sgundave@cisco.com, zhou.xingyue@zte.com.cn, jouni.nospam@gmail.com, gfeige@cisco.com, rkoodli@cisco.com +# RFC6910 || D. Worley, M. Huelsemann, R. Jesske, D. Alexeitsev || worley@ariadne.com, martin.huelsemann@telekom.de, r.jesske@telekom.de, alexeitsev@teleflash.com +# RFC6911 || W. Dec, Ed., B. Sarikaya, G. Zorn, Ed., D. Miles, B. Lourdelet || wdec@cisco.com, sarikaya@ieee.org, glenzorn@gmail.com, davidmiles@google.com, blourdel@juniper.net +# RFC6912 || A. Sullivan, D. Thaler, J. Klensin, O. Kolkman || asullivan@dyn.com, dthaler@microsoft.com, john-ietf@jck.com, olaf@NLnetLabs.nl +# RFC6913 || D. Hanes, G. Salgueiro, K. Fleming || dhanes@cisco.com, gsalguei@cisco.com, kevin@kpfleming.us +# RFC6914 || J. Rosenberg || jdrosen@jdrosen.net +# RFC6915 || R. Bellis || ray.bellis@nominet.org.uk +# RFC6916 || R. Gagliano, S. Kent, S. Turner || rogaglia@cisco.com, kent@bbn.com, turners@ieca.com +# RFC6917 || C. Boulton, L. Miniero, G. Munson || chris@ns-technologies.com, lorenzo@meetecho.com, gamunson@gmail.com +# RFC6918 || F. Gont, C. Pignataro || fgont@si6networks.com, cpignata@cisco.com +# RFC6919 || R. Barnes, S. Kent, E. Rescorla || rlb@ipv.sx, kent@bbn.com, ekr@rtfm.com +# RFC6920 || S. Farrell, D. Kutscher, C. Dannewitz, B. Ohlman, A. Keranen, P. Hallam-Baker || stephen.farrell@cs.tcd.ie, kutscher@neclab.eu, cdannewitz@googlemail.com, Borje.Ohlman@ericsson.com, ari.keranen@ericsson.com, philliph@comodo.com +# RFC6921 || R. Hinden || bob.hinden@gmail.com +# RFC6922 || Y. Shafranovich || ietf@shaftek.org +# RFC6923 || R. Winter, E. Gray, H. van Helvoort, M. Betts || rolf.winter@neclab.eu, eric.gray@ericsson.com, huub.van.helvoort@huawei.com, malcolm.betts@zte.com.cn +# RFC6924 || B. Leiba || barryleiba@computer.org +# RFC6925 || B. Joshi, R. Desetti, M. Stapp || bharat_joshi@infosys.com, ramakrishnadtv@infosys.com, mjs@cisco.com +# RFC6926 || K. Kinnear, M. Stapp, R. Desetti, B. Joshi, N. Russell, P. Kurapati, B. Volz || kkinnear@cisco.com, mjs@cisco.com, ramakrishnadtv@infosys.com, bharat_joshi@infosys.com, neil.e.russell@gmail.com, kurapati@juniper.net, volz@cisco.com +# RFC6927 || J. Levine, P. Hoffman || standards@taugh.com, paul.hoffman@vpnc.org +# RFC6928 || J. Chu, N. Dukkipati, Y. Cheng, M. Mathis || hkchu@google.com, nanditad@google.com, ycheng@google.com, mattmathis@google.com +# RFC6929 || A. DeKok, A. Lior || aland@networkradius.com, avi.ietf@lior.org +# RFC6930 || D. Guo, S. Jiang, Ed., R. Despres, R. Maglione || guoseu@huawei.com, jiangsheng@huawei.com, despres.remi@laposte.net, robmgl@cisco.com +# RFC6931 || D. Eastlake 3rd || d3e3e3@gmail.com +# RFC6932 || D. Harkins, Ed. || dharkins@arubanetworks.com +# RFC6933 || A. Bierman, D. Romascanu, J. Quittek, M. Chandramouli || andy@yumaworks.com, dromasca@gmail.com , quittek@neclab.eu, moulchan@cisco.com +# RFC6934 || N. Bitar, Ed., S. Wadhwa, Ed., T. Haag, H. Li || nabil.n.bitar@verizon.com, sanjay.wadhwa@alcatel-lucent.com, HaagT@telekom.de, hongyu.lihongyu@huawei.com +# RFC6935 || M. Eubanks, P. Chimento, M. Westerlund || marshall.eubanks@gmail.com, Philip.Chimento@jhuapl.edu, magnus.westerlund@ericsson.com +# RFC6936 || G. Fairhurst, M. Westerlund || gorry@erg.abdn.ac.uk, magnus.westerlund@ericsson.com +# RFC6937 || M. Mathis, N. Dukkipati, Y. Cheng || mattmathis@google.com, nanditad@google.com, ycheng@google.com +# RFC6938 || J. Scudder || jgs@juniper.net +# RFC6939 || G. Halwasia, S. Bhandari, W. Dec || ghalwasi@cisco.com, shwethab@cisco.com, wdec@cisco.com +# RFC6940 || C. Jennings, B. Lowekamp, Ed., E. Rescorla, S. Baset, H. Schulzrinne || fluffy@cisco.com, bbl@lowekamp.net, ekr@rtfm.com, salman@cs.columbia.edu, hgs@cs.columbia.edu +# RFC6941 || L. Fang, Ed., B. Niven-Jenkins, Ed., S. Mansfield, Ed., R. Graveman, Ed. || lufang@cisco.com, ben@niven-jenkins.co.uk, scott.mansfield@ericsson.com, rfg@acm.org +# RFC6942 || J. Bournelle, L. Morand, S. Decugis, Q. Wu, G. Zorn || julien.bournelle@orange.com, lionel.morand@orange.com, sdecugis@freediameter.net, sunseawq@huawei.com, glenzorn@gmail.com +# RFC6943 || D. Thaler, Ed. || dthaler@microsoft.com +# RFC6944 || S. Rose || scottr.nist@gmail.com +# RFC6945 || R. Bush, B. Wijnen, K. Patel, M. Baer || randy@psg.com, bertietf@bwijnen.net, keyupate@cisco.com, baerm@tislabs.com +# RFC6946 || F. Gont || fgont@si6networks.com +# RFC6947 || M. Boucadair, H. Kaplan, R. Gilman, S. Veikkolainen || mohamed.boucadair@orange.com, hkaplan@acmepacket.com, bob_gilman@comcast.net, Simo.Veikkolainen@nokia.com +# RFC6948 || A. Keranen, J. Arkko || ari.keranen@ericsson.com, jari.arkko@piuha.net +# RFC6949 || H. Flanagan, N. Brownlee || rse@rfc-editor.org, rfc-ise@rfc-editor.org +# RFC6950 || J. Peterson, O. Kolkman, H. Tschofenig, B. Aboba || jon.peterson@neustar.biz, olaf@nlnetlabs.nl, Hannes.Tschofenig@gmx.net, Bernard_aboba@hotmail.com +# RFC6951 || M. Tuexen, R. Stewart || tuexen@fh-muenster.de, randall@lakerest.net +# RFC6952 || M. Jethanandani, K. Patel, L. Zheng || mjethanandani@gmail.com, keyupate@cisco.com, vero.zheng@huawei.com +# RFC6953 || A. Mancuso, Ed., S. Probasco, B. Patil || amancuso@google.com, scott@probasco.me, basavpat@cisco.com +# RFC6954 || J. Merkle, M. Lochter || johannes.merkle@secunet.com, manfred.lochter@bsi.bund.de +# RFC6955 || J. Schaad, H. Prafullchandra || ietf@augustcellars.com, HPrafullchandra@hytrust.com +# RFC6956 || W. Wang, E. Haleplidis, K. Ogawa, C. Li, J. Halpern || wmwang@zjsu.edu.cn, ehalep@ece.upatras.gr, ogawa.kentaro@lab.ntt.co.jp, chuanhuang_li@zjsu.edu.cn, joel.halpern@ericsson.com +# RFC6957 || F. Costa, J-M. Combes, Ed., X. Pougnard, H. Li || fabio.costa@orange.com, jeanmichel.combes@orange.com, xavier.pougnard@orange.com, lihy@huawei.com +# RFC6958 || A. Clark, S. Zhang, J. Zhao, Q. Wu, Ed. || alan.d.clark@telchemy.com, zhangyx@sttri.com.cn, zhaojing@sttri.com.cn, sunseawq@huawei.com +# RFC6959 || D. McPherson, F. Baker, J. Halpern || dmcpherson@verisign.com, fred@cisco.com, joel.halpern@ericsson.com +# RFC6960 || S. Santesson, M. Myers, R. Ankney, A. Malpani, S. Galperin, C. Adams || sts@aaa-sec.com, mmyers@fastq.com, none, ambarish@gmail.com, slava.galperin@gmail.com, cadams@eecs.uottawa.ca +# RFC6961 || Y. Pettersen || yngve@spec-work.net +# RFC6962 || B. Laurie, A. Langley, E. Kasper || benl@google.com, agl@google.com, ekasper@google.com +# RFC6963 || P. Saint-Andre || ietf@stpeter.im +# RFC6964 || F. Templin || fltemplin@acm.org +# RFC6965 || L. Fang, Ed., N. Bitar, R. Zhang, M. Daikoku, P. Pan || lufang@cisco.com, nabil.bitar@verizon.com, raymond.zhang@alcatel-lucent.com, ms-daikoku@kddi.com, ppan@infinera.com +# RFC6967 || M. Boucadair, J. Touch, P. Levis, R. Penno || mohamed.boucadair@orange.com, touch@isi.edu, pierre.levis@orange.com, repenno@cisco.com +# RFC6968 || V. Roca, B. Adamson || vincent.roca@inria.fr, adamson@itd.nrl.navy.mil +# RFC6969 || A. Retana, D. Cheng || aretana@cisco.com, dean.cheng@huawei.com +# RFC6970 || M. Boucadair, R. Penno, D. Wing || mohamed.boucadair@orange.com, repenno@cisco.com, dwing-ietf@fuggles.com +# RFC6971 || U. Herberg, Ed., A. Cardenas, T. Iwao, M. Dow, S. Cespedes || ulrich.herberg@us.fujitsu.com, alvaro.cardenas@me.com, smartnetpro-iwao_std@ml.css.fujitsu.com, m.dow@freescale.com, scespedes@icesi.edu.co +# RFC6972 || Y. Zhang, N. Zong || hishigh@gmail.com, zongning@huawei.com +# RFC6973 || A. Cooper, H. Tschofenig, B. Aboba, J. Peterson, J. Morris, M. Hansen, R. Smith || acooper@cdt.org, Hannes.Tschofenig@gmx.net, bernard_aboba@hotmail.com, jon.peterson@neustar.biz, ietf@jmorris.org, marit.hansen@datenschutzzentrum.de, rhys.smith@ja.net +# RFC6974 || Y. Weingarten, S. Bryant, D. Ceccarelli, D. Caviglia, F. Fondelli, M. Corsi, B. Wu, X. Dai || wyaacov@gmail.com, stbryant@cisco.com, daniele.ceccarelli@ericsson.com, diego.caviglia@ericsson.com, francesco.fondelli@ericsson.com, corsi.marco@gmail.com, wu.bo@zte.com.cn, dai.xuehui@zte.com.cn +# RFC6975 || S. Crocker, S. Rose || steve@shinkuro.com, scottr.nist@gmail.com +# RFC6976 || M. Shand, S. Bryant, S. Previdi, C. Filsfils, P. Francois, O. Bonaventure || imc.shand@googlemail.com, stbryant@cisco.com, sprevidi@cisco.com, cfilsfil@cisco.com, pierre.francois@imdea.org, Olivier.Bonaventure@uclouvain.be +# RFC6977 || M. Boucadair, X. Pougnard || mohamed.boucadair@orange.com, xavier.pougnard@orange.com +# RFC6978 || J. Touch || touch@isi.edu +# RFC6979 || T. Pornin || pornin@bolet.org +# RFC6980 || F. Gont || fgont@si6networks.com +# RFC6981 || S. Bryant, S. Previdi, M. Shand || stbryant@cisco.com, sprevidi@cisco.com, imc.shand@googlemail.com +# RFC6982 || Y. Sheffer, A. Farrel || yaronf.ietf@gmail.com, adrian@olddog.co.uk +# RFC6983 || R. van Brandenburg, O. van Deventer, F. Le Faucheur, K. Leung || ray.vanbrandenburg@tno.nl, oskar.vandeventer@tno.nl, flefauch@cisco.com, kleung@cisco.com +# RFC6984 || W. Wang, K. Ogawa, E. Haleplidis, M. Gao, J. Hadi Salim || wmwang@zjsu.edu.cn, ogawa.kentaro@lab.ntt.co.jp, ehalep@ece.upatras.gr, gaoming@mail.zjgsu.edu.cn, hadi@mojatatu.com +# RFC6985 || A. Morton || acmorton@att.com +# RFC6986 || V. Dolmatov, Ed., A. Degtyarev || dol@cryptocom.ru, alexey@renatasystems.org +# RFC6987 || A. Retana, L. Nguyen, A. Zinin, R. White, D. McPherson || aretana@cisco.com, lhnguyen@cisco.com, alex.zinin@gmail.com, Russ.White@vce.com, dmcpherson@verisign.com +# RFC6988 || J. Quittek, Ed., M. Chandramouli, R. Winter, T. Dietz, B. Claise || quittek@neclab.eu, moulchan@cisco.com, Rolf.Winter@neclab.eu, Thomas.Dietz@neclab.eu, bclaise@cisco.com +# RFC6989 || Y. Sheffer, S. Fluhrer || yaronf.ietf@gmail.com, sfluhrer@cisco.com +# RFC6990 || R. Huang, Q. Wu, H. Asaeda, G. Zorn || rachel.huang@huawei.com, bill.wu@huawei.com, asaeda@nict.go.jp, glenzorn@gmail.com +# RFC6991 || J. Schoenwaelder, Ed. || j.schoenwaelder@jacobs-university.de +# RFC6992 || D. Cheng, M. Boucadair, A. Retana || dean.cheng@huawei.com, mohamed.boucadair@orange.com, aretana@cisco.com +# RFC6993 || P. Saint-Andre || ietf@stpeter.im +# RFC6994 || J. Touch || touch@isi.edu +# RFC6996 || J. Mitchell || Jon.Mitchell@microsoft.com +# RFC6997 || M. Goyal, Ed., E. Baccelli, M. Philipp, A. Brandt, J. Martocci || mukul@uwm.edu, Emmanuel.Baccelli@inria.fr, matthias-philipp@gmx.de, abr@sdesigns.dk, jerald.p.martocci@jci.com +# RFC6998 || M. Goyal, Ed., E. Baccelli, A. Brandt, J. Martocci || mukul@uwm.edu, Emmanuel.Baccelli@inria.fr, abr@sdesigns.dk, jerald.p.martocci@jci.com +# RFC7001 || M. Kucherawy || superuser@gmail.com +# RFC7002 || A. Clark, G. Zorn, Q. Wu || alan.d.clark@telchemy.com, glenzorn@gmail.com, sunseawq@huawei.com +# RFC7003 || A. Clark, R. Huang, Q. Wu, Ed. || alan.d.clark@telchemy.com, Rachel@huawei.com, sunseawq@huawei.com +# RFC7004 || G. Zorn, R. Schott, Q. Wu, Ed., R. Huang || glenzorn@gmail.com, Roland.Schott@telekom.de, sunseawq@huawei.com, Rachel@huawei.com +# RFC7005 || A. Clark, V. Singh, Q. Wu || alan.d.clark@telchemy.com, varun@comnet.tkk.fi, sunseawq@huawei.com +# RFC7006 || M. Garcia-Martin, S. Veikkolainen, R. Gilman || miguel.a.garcia@ericsson.com, simo.veikkolainen@nokia.com, bob_gilman@comcast.net +# RFC7007 || T. Terriberry || tterribe@xiph.org +# RFC7008 || S. Kiyomoto, W. Shin || kiyomoto@kddilabs.jp, ohpato@hanmail.net +# RFC7009 || T. Lodderstedt, Ed., S. Dronia, M. Scurtescu || torsten@lodderstedt.net, sdronia@gmx.de, mscurtescu@google.com +# RFC7010 || B. Liu, S. Jiang, B. Carpenter, S. Venaas, W. George || leo.liubing@huawei.com, jiangsheng@huawei.com, brian.e.carpenter@gmail.com, stig@cisco.com, wesley.george@twcable.com +# RFC7011 || B. Claise, Ed., B. Trammell, Ed., P. Aitken || bclaise@cisco.com, trammell@tik.ee.ethz.ch, paitken@cisco.com +# RFC7012 || B. Claise, Ed., B. Trammell, Ed. || bclaise@cisco.com, trammell@tik.ee.ethz.ch +# RFC7013 || B. Trammell, B. Claise || trammell@tik.ee.ethz.ch, bclaise@cisco.com +# RFC7014 || S. D'Antonio, T. Zseby, C. Henke, L. Peluso || salvatore.dantonio@uniparthenope.it, tanja@caida.org, christian.henke@tektronix.com, lorenzo.peluso@unina.it +# RFC7015 || B. Trammell, A. Wagner, B. Claise || trammell@tik.ee.ethz.ch, arno@wagner.name, bclaise@cisco.com +# RFC7016 || M. Thornburgh || mthornbu@adobe.com +# RFC7017 || R. Sparks || rjsparks@nostrum.com +# RFC7018 || V. Manral, S. Hanna || vishwas.manral@hp.com, shanna@juniper.net +# RFC7019 || J. Buford, M. Kolberg, Ed. || buford@avaya.com, mkolberg@ieee.org +# RFC7020 || R. Housley, J. Curran, G. Huston, D. Conrad || housley@vigilsec.com, jcurran@arin.net, gih@apnic.net, drc@virtualized.org +# RFC7021 || C. Donley, Ed., L. Howard, V. Kuarsingh, J. Berg, J. Doshi || c.donley@cablelabs.com, william.howard@twcable.com, victor@jvknet.com, j.berg@cablelabs.com, jineshd@juniper.net +# RFC7022 || A. Begen, C. Perkins, D. Wing, E. Rescorla || abegen@cisco.com, csp@csperkins.org, dwing-ietf@fuggles.com, ekr@rtfm.com +# RFC7023 || D. Mohan, Ed., N. Bitar, Ed., A. Sajassi, Ed., S. DeLord, P. Niger, R. Qiu || dinmohan@hotmail.com, nabil.n.bitar@verizon.com, sajassi@cisco.com, simon.delord@gmail.com, philippe.niger@orange.com, rqiu@juniper.net +# RFC7024 || H. Jeng, J. Uttaro, L. Jalil, B. Decraene, Y. Rekhter, R. Aggarwal || hj2387@att.com, ju1738@att.com, luay.jalil@verizon.com, bruno.decraene@orange.com, yakov@juniper.net, raggarwa_1@yahoo.com +# RFC7025 || T. Otani, K. Ogaki, D. Caviglia, F. Zhang, C. Margaria || tm-otani@kddi.com, ke-oogaki@kddi.com, diego.caviglia@ericsson.com, zhangfatai@huawei.com, cyril.margaria@coriant.com +# RFC7026 || A. Farrel, S. Bryant || adrian@olddog.co.uk, stbryant@cisco.com +# RFC7027 || J. Merkle, M. Lochter || johannes.merkle@secunet.com, manfred.lochter@bsi.bund.de +# RFC7028 || JC. Zuniga, LM. Contreras, CJ. Bernardos, S. Jeon, Y. Kim || JuanCarlos.Zuniga@InterDigital.com, lmcm@tid.es, cjbc@it.uc3m.es, seiljeon@av.it.pt, yhkim@dcn.ssu.ac.kr +# RFC7029 || S. Hartman, M. Wasserman, D. Zhang || hartmans-ietf@mit.edu, mrw@painless-security.com, zhangdacheng@huawei.com +# RFC7030 || M. Pritikin, Ed., P. Yee, Ed., D. Harkins, Ed. || pritikin@cisco.com, peter@akayla.com, dharkins@arubanetworks.com +# RFC7031 || T. Mrugalski, K. Kinnear || tomasz.mrugalski@gmail.com, kkinnear@cisco.com +# RFC7032 || T. Beckhaus, Ed., B. Decraene, K. Tiruveedhula, M. Konstantynowicz, Ed., L. Martini || thomas.beckhaus@telekom.de, bruno.decraene@orange.com, kishoret@juniper.net, maciek@cisco.com, lmartini@cisco.com +# RFC7033 || P. Jones, G. Salgueiro, M. Jones, J. Smarr || paulej@packetizer.com, gsalguei@cisco.com, mbj@microsoft.com, jsmarr@google.com +# RFC7034 || D. Ross, T. Gondrom || dross@microsoft.com, tobias.gondrom@gondrom.org +# RFC7035 || M. Thomson, B. Rosen, D. Stanley, G. Bajko, A. Thomson || martin.thomson@skype.net, br@brianrosen.net, dstanley@arubanetworks.com, Gabor.Bajko@nokia.com, athomson@lgscout.com +# RFC7036 || R. Housley || housley@vigilsec.com +# RFC7037 || L. Yeh, M. Boucadair || leaf.yeh.sdo@gmail.com, mohamed.boucadair@orange.com +# RFC7038 || R. Ogier || ogier@earthlink.net +# RFC7039 || J. Wu, J. Bi, M. Bagnulo, F. Baker, C. Vogt, Ed. || jianping@cernet.edu.cn, junbi@tsinghua.edu.cn, marcelo@it.uc3m.es, fred@cisco.com, mail@christianvogt.net +# RFC7040 || Y. Cui, J. Wu, P. Wu, O. Vautrin, Y. Lee || yong@csnet1.cs.tsinghua.edu.cn, jianping@cernet.edu.cn, pengwu.thu@gmail.com, Olivier@juniper.net, yiu_lee@cable.comcast.com +# RFC7041 || F. Balus, Ed., A. Sajassi, Ed., N. Bitar, Ed. || florin.balus@alcatel-lucent.com, sajassi@cisco.com, nabil.n.bitar@verizon.com +# RFC7042 || D. Eastlake 3rd, J. Abley || d3e3e3@gmail.com, jabley@dyn.com +# RFC7043 || J. Abley || jabley@dyn.com +# RFC7044 || M. Barnes, F. Audet, S. Schubert, J. van Elburg, C. Holmberg || mary.ietf.barnes@gmail.com, francois.audet@skype.net, shida@ntt-at.com, ietf.hanserik@gmail.com, christer.holmberg@ericsson.com +# RFC7045 || B. Carpenter, S. Jiang || brian.e.carpenter@gmail.com, jiangsheng@huawei.com +# RFC7046 || M. Waehlisch, T. Schmidt, S. Venaas || mw@link-lab.net, Schmidt@informatik.haw-hamburg.de, stig@cisco.com +# RFC7047 || B. Pfaff, B. Davie, Ed. || blp@nicira.com, bsd@nicira.com +# RFC7048 || E. Nordmark, I. Gashinsky || nordmark@acm.org, igor@yahoo-inc.com +# RFC7049 || C. Bormann, P. Hoffman || cabo@tzi.org, paul.hoffman@vpnc.org +# RFC7050 || T. Savolainen, J. Korhonen, D. Wing || teemu.savolainen@nokia.com, jouni.nospam@gmail.com, dwing-ietf@fuggles.com +# RFC7051 || J. Korhonen, Ed., T. Savolainen, Ed. || jouni.nospam@gmail.com, teemu.savolainen@nokia.com +# RFC7052 || G. Schudel, A. Jain, V. Moreno || gschudel@cisco.com, atjain@juniper.net, vimoreno@cisco.com +# RFC7053 || M. Tuexen, I. Ruengeler, R. Stewart || tuexen@fh-muenster.de, i.ruengeler@fh-muenster.de, randall@lakerest.net +# RFC7054 || A. Farrel, H. Endo, R. Winter, Y. Koike, M. Paul || adrian@olddog.co.uk, hideki.endo.es@hitachi.com, rolf.winter@neclab.eu, koike.yoshinori@lab.ntt.co.jp, Manuel.Paul@telekom.de +# RFC7055 || S. Hartman, Ed., J. Howlett || hartmans-ietf@mit.edu, josh.howlett@ja.net +# RFC7056 || S. Hartman, J. Howlett || hartmans-ietf@mit.edu, josh.howlett@ja.net +# RFC7057 || S. Winter, J. Salowey || stefan.winter@restena.lu, jsalowey@cisco.com +# RFC7058 || A. Amirante, T. Castaldi, L. Miniero, S P. Romano || alessandro.amirante@unina.it, tcastaldi@meetecho.com, lorenzo@meetecho.com, spromano@unina.it +# RFC7059 || S. Steffann, I. van Beijnum, R. van Rein || sander@steffann.nl, iljitsch@muada.com, rick@openfortress.nl +# RFC7060 || M. Napierala, E. Rosen, IJ. Wijnands || mnapierala@att.com, erosen@cisco.com, ice@cisco.com +# RFC7061 || R. Sinnema, E. Wilde || remon.sinnema@emc.com, erik.wilde@emc.com +# RFC7062 || F. Zhang, Ed., D. Li, H. Li, S. Belotti, D. Ceccarelli || zhangfatai@huawei.com, huawei.danli@huawei.com, lihan@chinamobile.com, sergio.belotti@alcatel-lucent.it, daniele.ceccarelli@ericsson.com +# RFC7063 || L. Zheng, J. Zhang, R. Parekh || vero.zheng@huawei.com, zzhang@juniper.net, riparekh@cisco.com +# RFC7064 || S. Nandakumar, G. Salgueiro, P. Jones, M. Petit-Huguenin || snandaku@cisco.com, gsalguei@cisco.com, paulej@packetizer.com, petithug@acm.org +# RFC7065 || M. Petit-Huguenin, S. Nandakumar, G. Salgueiro, P. Jones || petithug@acm.org, snandaku@cisco.com, gsalguei@cisco.com, paulej@packetizer.com +# RFC7066 || J. Korhonen, Ed., J. Arkko, Ed., T. Savolainen, S. Krishnan || jouni.nospam@gmail.com, jari.arkko@piuha.net, teemu.savolainen@nokia.com, suresh.krishnan@ericsson.com +# RFC7067 || L. Dunbar, D. Eastlake 3rd, R. Perlman, I. Gashinsky || ldunbar@huawei.com, d3e3e3@gmail.com, Radia@alum.mit.edu, igor@yahoo-inc.com +# RFC7068 || E. McMurry, B. Campbell || emcmurry@computer.org, ben@nostrum.com +# RFC7069 || R. Alimi, A. Rahman, D. Kutscher, Y. Yang, H. Song, K. Pentikousis || ralimi@google.com, Akbar.Rahman@InterDigital.com, dirk.kutscher@neclab.eu, yry@cs.yale.edu, haibin.song@huawei.com, k.pentikousis@eict.de +# RFC7070 || N. Borenstein, M. Kucherawy || nsb@guppylake.com, superuser@gmail.com +# RFC7071 || N. Borenstein, M. Kucherawy || nsb@guppylake.com, superuser@gmail.com +# RFC7072 || N. Borenstein, M. Kucherawy || nsb@guppylake.com, superuser@gmail.com +# RFC7073 || N. Borenstein, M. Kucherawy || nsb@guppylake.com, superuser@gmail.com +# RFC7074 || L. Berger, J. Meuric || lberger@labn.net, julien.meuric@orange.com +# RFC7075 || T. Tsou, R. Hao, T. Taylor, Ed. || tina.tsou.zouting@huawei.com, ruibing_hao@cable.comcast.com, tom.taylor.stds@gmail.com +# RFC7076 || M. Joseph, J. Susoy || mark@p6r.com, jim@p6r.com +# RFC7077 || S. Krishnan, S. Gundavelli, M. Liebsch, H. Yokota, J. Korhonen || suresh.krishnan@ericsson.com, sgundave@cisco.com, marco.liebsch@neclab.eu, yokota@kddilabs.jp, jouni.nospam@gmail.com +# RFC7078 || A. Matsumoto, T. Fujisaki, T. Chown || arifumi@nttv6.net, fujisaki@nttv6.net, tjc@ecs.soton.ac.uk +# RFC7079 || N. Del Regno, Ed., A. Malis, Ed. || nick.delregno@verizon.com, amalis@gmail.com +# RFC7080 || A. Sajassi, S. Salam, N. Bitar, F. Balus || sajassi@cisco.com, ssalam@cisco.com, nabil.n.bitar@verizon.com, florin.balus@nuagenetworks.net +# RFC7081 || E. Ivov, P. Saint-Andre, E. Marocco || emcho@jitsi.org, ietf@stpeter.im, enrico.marocco@telecomitalia.it +# RFC7082 || R. Shekh-Yusef, M. Barnes || rifaat.ietf@gmail.com, mary.ietf.barnes@gmail.com +# RFC7083 || R. Droms || rdroms@cisco.com +# RFC7084 || H. Singh, W. Beebee, C. Donley, B. Stark || shemant@cisco.com, wbeebee@cisco.com, c.donley@cablelabs.com, barbara.stark@att.com +# RFC7085 || J. Levine, P. Hoffman || standards@taugh.com, paul.hoffman@cybersecurity.org +# RFC7086 || A. Keranen, G. Camarillo, J. Maenpaa || Ari.Keranen@ericsson.com, Gonzalo.Camarillo@ericsson.com, Jouni.Maenpaa@ericsson.com +# RFC7087 || H. van Helvoort, Ed., L. Andersson, Ed., N. Sprecher, Ed. || Huub.van.Helvoort@huawei.com, loa@mail01.huawei.com, nurit.sprecher@nsn.com +# RFC7088 || D. Worley || worley@ariadne.com +# RFC7089 || H. Van de Sompel, M. Nelson, R. Sanderson || hvdsomp@gmail.com, mln@cs.odu.edu, azaroth42@gmail.com +# RFC7090 || H. Schulzrinne, H. Tschofenig, C. Holmberg, M. Patel || hgs+ecrit@cs.columbia.edu, Hannes.Tschofenig@gmx.net, christer.holmberg@ericsson.com, Milan.Patel@huawei.com +# RFC7091 || V. Dolmatov, Ed., A. Degtyarev || dol@cryptocom.ru, alexey@renatasystems.org +# RFC7092 || H. Kaplan, V. Pascual || hadriel.kaplan@oracle.com, victor.pascual@quobis.com +# RFC7093 || S. Turner, S. Kent, J. Manger || turners@ieca.com, kent@bbn.com, james.h.manger@team.telstra.com +# RFC7094 || D. McPherson, D. Oran, D. Thaler, E. Osterweil || dmcpherson@verisign.com, oran@cisco.com, dthaler@microsoft.com, eosterweil@verisign.com +# RFC7095 || P. Kewisch || mozilla@kewis.ch +# RFC7096 || S. Belotti, Ed., P. Grandi, D. Ceccarelli, Ed., D. Caviglia, F. Zhang, D. Li || sergio.belotti@alcatel-lucent.com, pietro_vittorio.grandi@alcatel-lucent.com, daniele.ceccarelli@ericsson.com, diego.caviglia@ericsson.com, zhangfatai@huawei.com, danli@huawei.com +# RFC7097 || J. Ott, V. Singh, Ed., I. Curcio || jo@comnet.tkk.fi, varun@comnet.tkk.fi, igor.curcio@nokia.com +# RFC7098 || B. Carpenter, S. Jiang, W. Tarreau || brian.e.carpenter@gmail.com, jiangsheng@huawei.com, willy@haproxy.com +# RFC7100 || P. Resnick || presnick@qti.qualcomm.com +# RFC7101 || S. Ginoza || sginoza@amsl.com +# RFC7102 || JP. Vasseur || jpv@cisco.com +# RFC7103 || M. Kucherawy, G. Shapiro, N. Freed || superuser@gmail.com, gshapiro@proofpoint.com, ned.freed@mrochek.com +# RFC7104 || A. Begen, Y. Cai, H. Ou || abegen@cisco.com, yiqunc@microsoft.com, hou@cisco.com +# RFC7105 || M. Thomson, J. Winterbottom || martin.thomson@gmail.com, a.james.winterbottom@gmail.com +# RFC7106 || E. Ivov || emcho@jitsi.org +# RFC7107 || R. Housley || housley@vigilsec.com +# RFC7108 || J. Abley, T. Manderson || jabley@dyn.com, terry.manderson@icann.org +# RFC7109 || H. Yokota, D. Kim, B. Sarikaya, F. Xia || yokota@kddilabs.jp, dskim@jejutp.or.kr, sarikaya@ieee.org, xiayangsong@huawei.com +# RFC7110 || M. Chen, W. Cao, S. Ning, F. Jounay, S. Delord || mach.chen@huawei.com, wayne.caowei@huawei.com, ning.so@tatacommunications.com, frederic.jounay@orange.ch, simon.delord@alcatel-lucent.com +# RFC7111 || M. Hausenblas, E. Wilde, J. Tennison || mhausenblas@maprtech.com, dret@berkeley.edu, jeni@jenitennison.com +# RFC7112 || F. Gont, V. Manral, R. Bonica || fgont@si6networks.com, vishwas@ionosnetworks.com, rbonica@juniper.net +# RFC7113 || F. Gont || fgont@si6networks.com +# RFC7114 || B. Leiba || barryleiba@computer.org +# RFC7115 || R. Bush || randy@psg.com +# RFC7116 || K. Scott, M. Blanchet || kscott@mitre.org, marc.blanchet@viagenie.ca +# RFC7117 || R. Aggarwal, Ed., Y. Kamite, L. Fang, Y. Rekhter, C. Kodeboniya || raggarwa_1@yahoo.com, y.kamite@ntt.com, lufang@microsoft.com, yakov@juniper.net, chaitk@yahoo.com +# RFC7118 || I. Baz Castillo, J. Millan Villegas, V. Pascual || ibc@aliax.net, jmillan@aliax.net, victor.pascual@quobis.com +# RFC7119 || B. Claise, A. Kobayashi, B. Trammell || bclaise@cisco.com, akoba@nttv6.net, trammell@tik.ee.ethz.ch +# RFC7120 || M. Cotton || michelle.cotton@icann.org +# RFC7121 || K. Ogawa, W. Wang, E. Haleplidis, J. Hadi Salim || k.ogawa@ntt.com, wmwang@mail.zjgsu.edu.cn, ehalep@ece.upatras.gr, hadi@mojatatu.com +# RFC7122 || H. Kruse, S. Jero, S. Ostermann || kruse@ohio.edu, sjero@purdue.edu, ostermann@eecs.ohiou.edu +# RFC7123 || F. Gont, W. Liu || fgont@si6networks.com, liushucheng@huawei.com +# RFC7124 || E. Beili || edward.beili@actelis.com +# RFC7125 || B. Trammell, P. Aitken || trammell@tik.ee.ethz.ch, paitken@cisco.com +# RFC7126 || F. Gont, R. Atkinson, C. Pignataro || fgont@si6networks.com, rja.lists@gmail.com, cpignata@cisco.com +# RFC7127 || O. Kolkman, S. Bradner, S. Turner || olaf@nlnetlabs.nl, sob@harvard.edu, turners@ieca.com +# RFC7128 || R. Bush, R. Austein, K. Patel, H. Gredler, M. Waehlisch || randy@psg.com, sra@hactrn.net, keyupate@cisco.com, hannes@juniper.net, waehlisch@ieee.org +# RFC7129 || R. Gieben, W. Mekking || miek@google.com, matthijs@nlnetlabs.nl +# RFC7130 || M. Bhatia, Ed., M. Chen, Ed., S. Boutros, Ed., M. Binderberger, Ed., J. Haas, Ed. || manav.bhatia@alcatel-lucent.com, mach@huawei.com, sboutros@cisco.com, mbinderb@cisco.com, jhaas@juniper.net +# RFC7131 || M. Barnes, F. Audet, S. Schubert, H. van Elburg, C. Holmberg || mary.ietf.barnes@gmail.com, francois.audet@skype.net, shida@ntt-at.com, ietf.hanserik@gmail.com, christer.holmberg@ericsson.com +# RFC7132 || S. Kent, A. Chi || kent@bbn.com, achi@cs.unc.edu +# RFC7133 || S. Kashima, A. Kobayashi, Ed., P. Aitken || kashima@nttv6.net, akoba@nttv6.net, paitken@cisco.com +# RFC7134 || B. Rosen || br@brianrosen.net +# RFC7135 || J. Polk || jmpolk@cisco.com +# RFC7136 || B. Carpenter, S. Jiang || brian.e.carpenter@gmail.com, jiangsheng@huawei.com +# RFC7137 || A. Retana, S. Ratliff || aretana@cisco.com, sratliff@cisco.com +# RFC7138 || D. Ceccarelli, Ed., F. Zhang, S. Belotti, R. Rao, J. Drake || daniele.ceccarelli@ericsson.com, zhangfatai@huawei.com, sergio.belotti@alcatel-lucent.com, rrao@infinera.com, jdrake@juniper.net +# RFC7139 || F. Zhang, Ed., G. Zhang, S. Belotti, D. Ceccarelli, K. Pithewan || zhangfatai@huawei.com, zhangguoying@mail.ritt.com.cn, sergio.belotti@alcatel-lucent.it, daniele.ceccarelli@ericsson.com, kpithewan@infinera.com +# RFC7140 || L. Jin, F. Jounay, IJ. Wijnands, N. Leymann || lizho.jin@gmail.com, frederic.jounay@orange.ch, ice@cisco.com, n.leymann@telekom.de +# RFC7141 || B. Briscoe, J. Manner || bob.briscoe@bt.com, jukka.manner@aalto.fi +# RFC7142 || M. Shand, L. Ginsberg || imc.shand@googlemail.com, ginsberg@cisco.com +# RFC7143 || M. Chadalapaka, J. Satran, K. Meth, D. Black || cbm@chadalapaka.com, julians@infinidat.com, meth@il.ibm.com, david.black@emc.com +# RFC7144 || F. Knight, M. Chadalapaka || knight@netapp.com, cbm@chadalapaka.com +# RFC7145 || M. Ko, A. Nezhinsky || mkosjc@gmail.com, alexandern@mellanox.com +# RFC7146 || D. Black, P. Koning || david.black@emc.com, paul_koning@Dell.com +# RFC7147 || M. Bakke, P. Venkatesen || mark_bakke@dell.com, prakashvn@hcl.com +# RFC7148 || X. Zhou, J. Korhonen, C. Williams, S. Gundavelli, CJ. Bernardos || zhou.xingyue@zte.com.cn, jouni.nospam@gmail.com, carlw@mcsr-labs.org, sgundave@cisco.com, cjbc@it.uc3m.es +# RFC7149 || M. Boucadair, C. Jacquenet || mohamed.boucadair@orange.com, christian.jacquenet@orange.com +# RFC7150 || F. Zhang, A. Farrel || zhangfatai@huawei.com, adrian@olddog.co.uk +# RFC7151 || P. Hethmon, R. McMurray || phethmon@hethmon.com, robmcm@microsoft.com +# RFC7152 || R. Key, Ed., S. DeLord, F. Jounay, L. Huang, Z. Liu, M. Paul || raymond.key@ieee.org, simon.delord@gmail.com, frederic.jounay@orange.ch, huanglu@chinamobile.com, zhliu@gsta.com, manuel.paul@telekom.de +# RFC7153 || E. Rosen, Y. Rekhter || erosen@cisco.com, yakov@juniper.net +# RFC7154 || S. Moonesamy, Ed. || sm+ietf@elandsys.com +# RFC7155 || G. Zorn, Ed. || glenzorn@gmail.com +# RFC7156 || G. Zorn, Q. Wu, J. Korhonen || glenzorn@gmail.com, bill.wu@huawei.com, jouni.nospam@gmail.com +# RFC7157 || O. Troan, Ed., D. Miles, S. Matsushima, T. Okimoto, D. Wing || ot@cisco.com, davidmiles@google.com, satoru.matsushima@g.softbank.co.jp, t.okimoto@west.ntt.co.jp, dwing-ietf@fuggles.com +# RFC7158 || T. Bray, Ed. || tbray@textuality.com +# RFC7159 || T. Bray, Ed. || tbray@textuality.com +# RFC7160 || M. Petit-Huguenin, G. Zorn, Ed. || petithug@acm.org, glenzorn@gmail.com +# RFC7161 || LM. Contreras, CJ. Bernardos, I. Soto || lmcm@tid.es, cjbc@it.uc3m.es, isoto@it.uc3m.es +# RFC7162 || A. Melnikov, D. Cridland || Alexey.Melnikov@isode.com, dave.cridland@surevine.com +# RFC7163 || C. Holmberg, I. Sedlacek || christer.holmberg@ericsson.com, ivo.sedlacek@ericsson.com +# RFC7164 || K. Gross, R. Brandenburg || kevin.gross@avanw.com, ray.vanbrandenburg@tno.nl +# RFC7165 || R. Barnes || rlb@ipv.sx +# RFC7166 || M. Bhatia, V. Manral, A. Lindem || manav.bhatia@alcatel-lucent.com, vishwas@ionosnetworks.com, acee.lindem@ericsson.com +# RFC7167 || D. Frost, S. Bryant, M. Bocci, L. Berger || frost@mm.st, stbryant@cisco.com, matthew.bocci@alcatel-lucent.com, lberger@labn.net +# RFC7168 || I. Nazar || inazar@deviantart.com +# RFC7169 || S. Turner || turners@ieca.com +# RFC7170 || H. Zhou, N. Cam-Winget, J. Salowey, S. Hanna || hzhou@cisco.com, ncamwing@cisco.com, jsalowey@cisco.com, steve.hanna@infineon.com +# RFC7171 || N. Cam-Winget, P. Sangster || ncamwing@cisco.com, paul_sangster@symantec.com +# RFC7172 || D. Eastlake 3rd, M. Zhang, P. Agarwal, R. Perlman, D. Dutt || d3e3e3@gmail.com, zhangmingui@huawei.com, pagarwal@broadcom.com, Radia@alum.mit.edu, ddutt.ietf@hobbesdutt.com +# RFC7173 || L. Yong, D. Eastlake 3rd, S. Aldrin, J. Hudson || lucy.yong@huawei.com, d3e3e3@gmail.com, sam.aldrin@huawei.com, jon.hudson@gmail.com +# RFC7174 || S. Salam, T. Senevirathne, S. Aldrin, D. Eastlake 3rd || ssalam@cisco.com, tsenevir@cisco.com, sam.aldrin@gmail.com, d3e3e3@gmail.com +# RFC7175 || V. Manral, D. Eastlake 3rd, D. Ward, A. Banerjee || vishwas@ionosnetworks.com, d3e3e3@gmail.com, dward@cisco.com, ayabaner@gmail.com +# RFC7176 || D. Eastlake 3rd, T. Senevirathne, A. Ghanwani, D. Dutt, A. Banerjee || d3e3e3@gmail.com, tsenevir@cisco.com, anoop@alumni.duke.edu, ddutt.ietf@hobbesdutt.com, ayabaner@gmail.com +# RFC7177 || D. Eastlake 3rd, R. Perlman, A. Ghanwani, H. Yang, V. Manral || d3e3e3@gmail.com, radia@alum.mit.edu, anoop@alumni.duke.edu, howardy@cisco.com, vishwas@ionosnetworks.com +# RFC7178 || D. Eastlake 3rd, V. Manral, Y. Li, S. Aldrin, D. Ward || d3e3e3@gmail.com, vishwas@ionosnetworks.com, liyizhou@huawei.com, sam.aldrin@huawei.com, dward@cisco.com +# RFC7179 || D. Eastlake 3rd, A. Ghanwani, V. Manral, Y. Li, C. Bestler || d3e3e3@gmail.com, anoop@alumni.duke.edu, vishwas@ionosnetworks.com, liyizhou@huawei.com, caitlin.bestler@nexenta.com +# RFC7180 || D. Eastlake 3rd, M. Zhang, A. Ghanwani, V. Manral, A. Banerjee || d3e3e3@gmail.com, zhangmingui@huawei.com, anoop@alumni.duke.edu, vishwas@ionosnetworks.com, ayabaner@gmail.com +# RFC7181 || T. Clausen, C. Dearlove, P. Jacquet, U. Herberg || T.Clausen@computer.org, chris.dearlove@baesystems.com, philippe.jacquet@alcatel-lucent.com, ulrich@herberg.name +# RFC7182 || U. Herberg, T. Clausen, C. Dearlove || ulrich@herberg.name, T.Clausen@computer.org, chris.dearlove@baesystems.com +# RFC7183 || U. Herberg, C. Dearlove, T. Clausen || ulrich@herberg.name, chris.dearlove@baesystems.com, T.Clausen@computer.org +# RFC7184 || U. Herberg, R. Cole, T. Clausen || ulrich@herberg.name, robert.g.cole@us.army.mil, T.Clausen@computer.org +# RFC7185 || C. Dearlove, T. Clausen, P. Jacquet || chris.dearlove@baesystems.com, T.Clausen@computer.org, philippe.jacquet@alcatel-lucent.com +# RFC7186 || J. Yi, U. Herberg, T. Clausen || jiazi@jiaziyi.com, ulrich@herberg.name, T.Clausen@computer.org +# RFC7187 || C. Dearlove, T. Clausen || chris.dearlove@baesystems.com, T.Clausen@computer.org +# RFC7188 || C. Dearlove, T. Clausen || chris.dearlove@baesystems.com, T.Clausen@computer.org +# RFC7189 || G. Mirsky || gregory.mirsky@ericsson.com +# RFC7190 || C. Villamizar || curtis@occnc.com +# RFC7191 || R. Housley || housley@vigilsec.com +# RFC7192 || S. Turner || turners@ieca.com +# RFC7193 || S. Turner, R. Housley, J. Schaad || turners@ieca.com, housley@vigilsec.com, ietf@augustcellars.com +# RFC7194 || R. Hartmann || richih.mailinglist@gmail.com +# RFC7195 || M. Garcia-Martin, S. Veikkolainen || miguel.a.garcia@ericsson.com, simo.veikkolainen@nokia.com +# RFC7196 || C. Pelsser, R. Bush, K. Patel, P. Mohapatra, O. Maennel || cristel@iij.ad.jp, randy@psg.com, keyupate@cisco.com, mpradosh@yahoo.com, o@maennel.net +# RFC7197 || A. Begen, Y. Cai, H. Ou || abegen@cisco.com, yiqunc@microsoft.com, hou@cisco.com +# RFC7198 || A. Begen, C. Perkins || abegen@cisco.com, csp@csperkins.org +# RFC7199 || R. Barnes, M. Thomson, J. Winterbottom, H. Tschofenig || rlb@ipv.sx, martin.thomson@gmail.com, a.james.winterbottom@gmail.com, Hannes.Tschofenig@gmx.net +# RFC7200 || C. Shen, H. Schulzrinne, A. Koike || charles@cs.columbia.edu, schulzrinne@cs.columbia.edu, koike.arata@lab.ntt.co.jp +# RFC7201 || M. Westerlund, C. Perkins || magnus.westerlund@ericsson.com, csp@csperkins.org +# RFC7202 || C. Perkins, M. Westerlund || csp@csperkins.org, magnus.westerlund@ericsson.com +# RFC7203 || T. Takahashi, K. Landfield, Y. Kadobayashi || takeshi_takahashi@nict.go.jp, kent_landfield@mcafee.com, youki-k@is.aist-nara.ac.jp +# RFC7204 || T. Haynes || tdh@excfb.com +# RFC7205 || A. Romanow, S. Botzko, M. Duckworth, R. Even, Ed. || allyn@cisco.com, stephen.botzko@polycom.com, mark.duckworth@polycom.com, roni.even@mail01.huawei.com +# RFC7206 || P. Jones, G. Salgueiro, J. Polk, L. Liess, H. Kaplan || paulej@packetizer.com, gsalguei@cisco.com, jmpolk@cisco.com, laura.liess.dt@gmail.com, hadriel.kaplan@oracle.com +# RFC7207 || M. Ortseifen, G. Dickfeld || iso20022@bundesbank.de, iso20022@bundesbank.de +# RFC7208 || S. Kitterman || scott@kitterman.com +# RFC7209 || A. Sajassi, R. Aggarwal, J. Uttaro, N. Bitar, W. Henderickx, A. Isaac || sajassi@cisco.com, raggarwa_1@yahoo.com, uttaro@att.com, nabil.n.bitar@verizon.com, wim.henderickx@alcatel-lucent.com, aisaac71@bloomberg.net +# RFC7210 || R. Housley, T. Polk, S. Hartman, D. Zhang || housley@vigilsec.com, tim.polk@nist.gov, hartmans-ietf@mit.edu, zhangdacheng@huawei.com +# RFC7211 || S. Hartman, D. Zhang || hartmans-ietf@mit.edu, zhangdacheng@huawei.com +# RFC7212 || D. Frost, S. Bryant, M. Bocci || frost@mm.st, stbryant@cisco.com, matthew.bocci@alcatel-lucent.com +# RFC7213 || D. Frost, S. Bryant, M. Bocci || frost@mm.st, stbryant@cisco.com, matthew.bocci@alcatel-lucent.com +# RFC7214 || L. Andersson, C. Pignataro || loa@mail01.huawei.com, cpignata@cisco.com +# RFC7215 || L. Jakab, A. Cabellos-Aparicio, F. Coras, J. Domingo-Pascual, D. Lewis || lojakab@cisco.com, acabello@ac.upc.edu, fcoras@ac.upc.edu, jordi.domingo@ac.upc.edu, darlewis@cisco.com +# RFC7216 || M. Thomson, R. Bellis || martin.thomson@gmail.com, ray.bellis@nominet.org.uk +# RFC7217 || F. Gont || fgont@si6networks.com +# RFC7218 || O. Gudmundsson || ogud@ogud.com +# RFC7219 || M. Bagnulo, A. Garcia-Martinez || marcelo@it.uc3m.es, alberto@it.uc3m.es +# RFC7220 || M. Boucadair, R. Penno, D. Wing || mohamed.boucadair@orange.com, repenno@cisco.com, dwing-ietf@fuggles.com +# RFC7221 || A. Farrel, D. Crocker, Ed. || adrian@olddog.co.uk, dcrocker@bbiw.net +# RFC7222 || M. Liebsch, P. Seite, H. Yokota, J. Korhonen, S. Gundavelli || liebsch@neclab.eu, pierrick.seite@orange.com, yokota@kddilabs.jp, jouni.nospam@gmail.com, sgundave@cisco.com +# RFC7223 || M. Bjorklund || mbj@tail-f.com +# RFC7224 || M. Bjorklund || mbj@tail-f.com +# RFC7225 || M. Boucadair || mohamed.boucadair@orange.com +# RFC7226 || C. Villamizar, Ed., D. McDysan, Ed., S. Ning, A. Malis, L. Yong || curtis@occnc.com, dave.mcdysan@verizon.com, ning.so@tatacommunications.com, agmalis@gmail.com, lucy.yong@huawei.com +# RFC7227 || D. Hankins, T. Mrugalski, M. Siodelski, S. Jiang, S. Krishnan || dhankins@google.com, tomasz.mrugalski@gmail.com, msiodelski@gmail.com, jiangsheng@huawei.com, suresh.krishnan@ericsson.com +# RFC7228 || C. Bormann, M. Ersue, A. Keranen || cabo@tzi.org, mehmet.ersue@nsn.com, ari.keranen@ericsson.com +# RFC7229 || R. Housley || housley@vigilsec.com +# RFC7230 || R. Fielding, Ed., J. Reschke, Ed. || fielding@gbiv.com, julian.reschke@greenbytes.de +# RFC7231 || R. Fielding, Ed., J. Reschke, Ed. || fielding@gbiv.com, julian.reschke@greenbytes.de +# RFC7232 || R. Fielding, Ed., J. Reschke, Ed. || fielding@gbiv.com, julian.reschke@greenbytes.de +# RFC7233 || R. Fielding, Ed., Y. Lafon, Ed., J. Reschke, Ed. || fielding@gbiv.com, ylafon@w3.org, julian.reschke@greenbytes.de +# RFC7234 || R. Fielding, Ed., M. Nottingham, Ed., J. Reschke, Ed. || fielding@gbiv.com, mnot@mnot.net, julian.reschke@greenbytes.de +# RFC7235 || R. Fielding, Ed., J. Reschke, Ed. || fielding@gbiv.com, julian.reschke@greenbytes.de +# RFC7236 || J. Reschke || julian.reschke@greenbytes.de +# RFC7237 || J. Reschke || julian.reschke@greenbytes.de +# RFC7238 || J. Reschke || julian.reschke@greenbytes.de +# RFC7239 || A. Petersson, M. Nilsson || andreas@sbin.se, nilsson@opera.com +# RFC7240 || J. Snell || jasnell@gmail.com +# RFC7241 || S. Dawkins, P. Thaler, D. Romascanu, B. Aboba, Ed. || spencerdawkins.ietf@gmail.com, pthaler@broadcom.com, dromasca@gmail.com , bernard_aboba@hotmail.com +# RFC7242 || M. Demmer, J. Ott, S. Perreault || demmer@cs.berkeley.edu, jo@netlab.tkk.fi, simon@per.reau.lt +# RFC7243 || V. Singh, Ed., J. Ott, I. Curcio || varun@comnet.tkk.fi, jo@comnet.tkk.fi, igor.curcio@nokia.com +# RFC7244 || H. Asaeda, Q. Wu, R. Huang || asaeda@nict.go.jp, bill.wu@huawei.com, Rachel@huawei.com +# RFC7245 || A. Hutton, Ed., L. Portman, Ed., R. Jain, K. Rehor || andrew.hutton@unify.com, leon.portman@gmail.com, rajnish.jain@outlook.com, krehor@cisco.com +# RFC7246 || IJ. Wijnands, Ed., P. Hitchen, N. Leymann, W. Henderickx, A. Gulko, J. Tantsura || ice@cisco.com, paul.hitchen@bt.com, n.leymann@telekom.de, wim.henderickx@alcatel-lucent.com, arkadiy.gulko@thomsonreuters.com, jeff.tantsura@ericsson.com +# RFC7247 || P. Saint-Andre, A. Houri, J. Hildebrand || ietf@stpeter.im, avshalom@il.ibm.com, jhildebr@cisco.com +# RFC7248 || P. Saint-Andre, A. Houri, J. Hildebrand || ietf@stpeter.im, avshalom@il.ibm.com, jhildebr@cisco.com +# RFC7249 || R. Housley || housley@vigilsec.com +# RFC7250 || P. Wouters, Ed., H. Tschofenig, Ed., J. Gilmore, S. Weiler, T. Kivinen || pwouters@redhat.com, Hannes.Tschofenig@gmx.net, gnu@toad.com, weiler@tislabs.com, kivinen@iki.fi +# RFC7251 || D. McGrew, D. Bailey, M. Campagna, R. Dugal || mcgrew@cisco.com, danbailey@sth.rub.de, mcampagna@gmail.com, rdugal@certicom.com +# RFC7252 || Z. Shelby, K. Hartke, C. Bormann || zach.shelby@arm.com, hartke@tzi.org, cabo@tzi.org +# RFC7253 || T. Krovetz, P. Rogaway || ted@krovetz.net, rogaway@cs.ucdavis.edu +# RFC7254 || M. Montemurro, Ed., A. Allen, D. McDonald, P. Gosden || mmontemurro@blackberry.com, aallen@blackberry.com, david.mcdonald@meteor.ie, pgosden@gsma.com +# RFC7255 || A. Allen, Ed. || aallen@blackberry.com +# RFC7256 || F. Le Faucheur, R. Maglione, T. Taylor || flefauch@cisco.com, robmgl@cisco.com, tom.taylor.stds@gmail.com +# RFC7257 || T. Nadeau, Ed., A. Kiran Koushik, Ed., R. Mediratta, Ed. || tnadeau@lucidvision.com, kkoushik@brocade.com, romedira@cisco.com +# RFC7258 || S. Farrell, H. Tschofenig || stephen.farrell@cs.tcd.ie, Hannes.Tschofenig@gmx.net +# RFC7259 || P. Saint-Andre || ietf@stpeter.im +# RFC7260 || A. Takacs, D. Fedyk, J. He || attila.takacs@ericsson.com, don.fedyk@hp.com, hejia@huawei.com +# RFC7261 || M. Perumal, P. Ravindran || mperumal@cisco.com, partha@parthasarathi.co.in +# RFC7262 || A. Romanow, S. Botzko, M. Barnes || allyn@cisco.com, stephen.botzko@polycom.com, mary.ietf.barnes@gmail.com +# RFC7263 || N. Zong, X. Jiang, R. Even, Y. Zhang || zongning@huawei.com, jiang.x.f@huawei.com, roni.even@mail01.huawei.com, hishigh@gmail.com +# RFC7264 || N. Zong, X. Jiang, R. Even, Y. Zhang || zongning@huawei.com, jiang.x.f@huawei.com, roni.even@mail01.huawei.com, hishigh@gmail.com +# RFC7265 || P. Kewisch, C. Daboo, M. Douglass || mozilla@kewis.ch, cyrus@daboo.name, douglm@rpi.edu +# RFC7266 || A. Clark, Q. Wu, R. Schott, G. Zorn || alan.d.clark@telchemy.com, sunseawq@huawei.com, Roland.Schott@telekom.de, gwz@net-zen.net +# RFC7267 || L. Martini, Ed., M. Bocci, Ed., F. Balus, Ed. || lmartini@cisco.com, matthew.bocci@alcatel-lucent.com, florin@nuagenetworks.net +# RFC7268 || B. Aboba, J. Malinen, P. Congdon, J. Salowey, M. Jones || Bernard_Aboba@hotmail.com, j@w1.fi, paul.congdon@tallac.com, jsalowey@cisco.com, mark@azu.ca +# RFC7269 || G. Chen, Z. Cao, C. Xie, D. Binet || chengang@chinamobile.com, caozhen@chinamobile.com, xiechf@ctbri.com.cn, david.binet@orange.com +# RFC7270 || A. Yourtchenko, P. Aitken, B. Claise || ayourtch@cisco.com, paitken@cisco.com, bclaise@cisco.com +# RFC7271 || J. Ryoo, Ed., E. Gray, Ed., H. van Helvoort, A. D'Alessandro, T. Cheung, E. Osborne || ryoo@etri.re.kr, eric.gray@ericsson.com, huub.van.helvoort@huawei.com, alessandro.dalessandro@telecomitalia.it, cts@etri.re.kr, eric.osborne@notcom.com +# RFC7272 || R. van Brandenburg, H. Stokking, O. van Deventer, F. Boronat, M. Montagud, K. Gross || ray.vanbrandenburg@tno.nl, hans.stokking@tno.nl, oskar.vandeventer@tno.nl, fboronat@dcom.upv.es, mamontor@posgrado.upv.es, kevin.gross@avanw.com +# RFC7273 || A. Williams, K. Gross, R. van Brandenburg, H. Stokking || aidan.williams@audinate.com, kevin.gross@avanw.com, ray.vanbrandenburg@tno.nl, hans.stokking@tno.nl +# RFC7274 || K. Kompella, L. Andersson, A. Farrel || kireeti.kompella@gmail.com, loa@mail01.huawei.com, adrian@olddog.co.uk +# RFC7275 || L. Martini, S. Salam, A. Sajassi, M. Bocci, S. Matsushima, T. Nadeau || lmartini@cisco.com, ssalam@cisco.com, sajassi@cisco.com, matthew.bocci@alcatel-lucent.com, satoru.matsushima@gmail.com, tnadeau@brocade.com +# RFC7276 || T. Mizrahi, N. Sprecher, E. Bellagamba, Y. Weingarten || talmi@marvell.com, nurit.sprecher@nsn.com, elisa.bellagamba@ericsson.com, wyaacov@gmail.com +# RFC7277 || M. Bjorklund || mbj@tail-f.com +# RFC7278 || C. Byrne, D. Drown, A. Vizdal || cameron.byrne@t-mobile.com, dan@drown.org, ales.vizdal@t-mobile.cz +# RFC7279 || M. Shore, C. Pignataro || melinda.shore@nomountain.net, cpignata@cisco.com +# RFC7280 || G. Fairhurst || gorry@erg.abdn.ac.uk +# RFC7281 || A. Melnikov || Alexey.Melnikov@isode.com +# RFC7282 || P. Resnick || presnick@qti.qualcomm.com +# RFC7283 || Y. Cui, Q. Sun, T. Lemon || yong@csnet1.cs.tsinghua.edu.cn, sunqi@csnet1.cs.tsinghua.edu.cn, Ted.Lemon@nominum.com +# RFC7284 || M. Lanthaler || mail@markus-lanthaler.com +# RFC7285 || R. Alimi, Ed., R. Penno, Ed., Y. Yang, Ed., S. Kiesel, S. Previdi, W. Roome, S. Shalunov, R. Woundy || ralimi@google.com, repenno@cisco.com, yry@cs.yale.edu, ietf-alto@skiesel.de, sprevidi@cisco.com, w.roome@alcatel-lucent.com, shalunov@shlang.com, Richard_Woundy@cable.comcast.com +# RFC7286 || S. Kiesel, M. Stiemerling, N. Schwan, M. Scharf, H. Song || ietf-alto@skiesel.de, mls.ietf@gmail.com, ietf@nico-schwan.de, michael.scharf@alcatel-lucent.com, haibin.song@huawei.com +# RFC7287 || T. Schmidt, Ed., S. Gao, H. Zhang, M. Waehlisch || Schmidt@informatik.haw-hamburg.de, shgao@bjtu.edu.cn, hkzhang@bjtu.edu.cn, mw@link-lab.net +# RFC7288 || D. Thaler || dthaler@microsoft.com +# RFC7289 || V. Kuarsingh, Ed., J. Cianfarani || victor@jvknet.com, john.cianfarani@rci.rogers.com +# RFC7290 || L. Ciavattone, R. Geib, A. Morton, M. Wieser || lencia@att.com, Ruediger.Geib@telekom.de, acmorton@att.com, matthias_michael.wieser@stud.tu-darmstadt.de +# RFC7291 || M. Boucadair, R. Penno, D. Wing || mohamed.boucadair@orange.com, repenno@cisco.com, dwing-ietf@fuggles.com +# RFC7292 || K. Moriarty, Ed., M. Nystrom, S. Parkinson, A. Rusch, M. Scott || Kathleen.Moriarty@emc.com, mnystrom@microsoft.com, sean.parkinson@rsa.com, andreas.rusch@rsa.com, michael2.scott@rsa.com +# RFC7293 || W. Mills, M. Kucherawy || wmills_92105@yahoo.com, msk@fb.com +# RFC7294 || A. Clark, G. Zorn, C. Bi, Q. Wu || alan.d.clark@telchemy.com, gwz@net-zen.net, bijy@sttri.com.cn, sunseawq@huawei.com +# RFC7295 || H. Tschofenig, L. Eggert, Z. Sarker || Hannes.Tschofenig@gmx.net, lars@netapp.com, Zaheduzzaman.Sarker@ericsson.com +# RFC7296 || C. Kaufman, P. Hoffman, Y. Nir, P. Eronen, T. Kivinen || charliekaufman@outlook.com, paul.hoffman@vpnc.org, nir.ietf@gmail.com, pe@iki.fi, kivinen@iki.fi +# RFC7297 || M. Boucadair, C. Jacquenet, N. Wang || mohamed.boucadair@orange.com, christian.jacquenet@orange.com, n.wang@surrey.ac.uk +# RFC7298 || D. Ovsienko || infrastation@yandex.ru +# RFC7299 || R. Housley || housley@vigilsec.com +# RFC7300 || J. Haas, J. Mitchell || jhaas@juniper.net, jon.mitchell@microsoft.com +# RFC7301 || S. Friedl, A. Popov, A. Langley, E. Stephan || sfriedl@cisco.com, andreipo@microsoft.com, agl@google.com, emile.stephan@orange.com +# RFC7302 || P. Lemieux || pal@sandflow.com +# RFC7303 || H. Thompson, C. Lilley || ht@inf.ed.ac.uk, chris@w3.org +# RFC7304 || W. Kumari || warren@kumari.net +# RFC7305 || E. Lear, Ed. || lear@cisco.com +# RFC7306 || H. Shah, F. Marti, W. Noureddine, A. Eiriksson, R. Sharp || hemal@broadcom.com, felix@chelsio.com, asgeir@chelsio.com, wael@chelsio.com, robert.o.sharp@intel.com +# RFC7307 || Q. Zhao, K. Raza, C. Zhou, L. Fang, L. Li, D. King || quintin.zhao@huawei.com, skraza@cisco.com, czhou@cisco.com, lufang@microsoft.com, lilianyuan@chinamobile.com, daniel@olddog.co.uk +# RFC7308 || E. Osborne || none +# RFC7309 || Z. Liu, L. Jin, R. Chen, D. Cai, S. Salam || zhliu@gsta.com, lizho.jin@gmail.com, chen.ran@zte.com.cn, dcai@cisco.com, ssalam@cisco.com +# RFC7310 || J. Lindsay, H. Foerster || lindsay@worldcastsystems.com, foerster@worldcastsystems.com +# RFC7311 || P. Mohapatra, R. Fernando, E. Rosen, J. Uttaro || mpradosh@yahoo.com, rex@cisco.com, erosen@cisco.com, uttaro@att.com +# RFC7312 || J. Fabini, A. Morton || joachim.fabini@tuwien.ac.at, acmorton@att.com +# RFC7313 || K. Patel, E. Chen, B. Venkatachalapathy || keyupate@cisco.com, enkechen@cisco.com, balaji_pv@hotmail.com +# RFC7314 || M. Andrews || marka@isc.org +# RFC7315 || R. Jesske, K. Drage, C. Holmberg || r.jesske@telekom.de, drage@alcatel-lucent.com, christer.holmberg@ericsson.com +# RFC7316 || J. van Elburg, K. Drage, M. Ohsugi, S. Schubert, K. Arai || ietf.hanserik@gmail.com, drage@alcatel-lucent.com, mayumi.ohsugi@ntt-at.co.jp, shida@ntt-at.com, arai.kenjiro@lab.ntt.co.jp +# RFC7317 || A. Bierman, M. Bjorklund || andy@yumaworks.com, mbj@tail-f.com +# RFC7318 || A. Newton, G. Huston || andy@arin.net, gih@apnic.net +# RFC7319 || D. Eastlake 3rd || d3e3e3@gmail.com +# RFC7320 || M. Nottingham || mnot@mnot.net +# RFC7321 || D. McGrew, P. Hoffman || mcgrew@cisco.com, paul.hoffman@vpnc.org +# RFC7322 || H. Flanagan, S. Ginoza || rse@rfc-editor.org, rfc-editor@rfc-editor.org +# RFC7323 || D. Borman, B. Braden, V. Jacobson, R. Scheffenegger, Ed. || david.borman@quantum.com, braden@isi.edu, vanj@google.com, rs@netapp.com +# RFC7324 || E. Osborne || eric.osborne@notcom.com +# RFC7325 || C. Villamizar, Ed., K. Kompella, S. Amante, A. Malis, C. Pignataro || curtis@occnc.com, kireeti@juniper.net, amante@apple.com, agmalis@gmail.com, cpignata@cisco.com +# RFC7326 || J. Parello, B. Claise, B. Schoening, J. Quittek || jparello@cisco.com, bclaise@cisco.com, brad.schoening@verizon.net, quittek@netlab.nec.de +# RFC7328 || R. Gieben || miek@google.com +# RFC7329 || H. Kaplan || hadrielk@yahoo.com +# RFC7330 || T. Nadeau, Z. Ali, N. Akiya || tnadeau@lucidvision.com, zali@cisco.com, nobo@cisco.com +# RFC7331 || T. Nadeau, Z. Ali, N. Akiya || tnadeau@lucidvision.com, zali@cisco.com, nobo@cisco.com +# RFC7332 || H. Kaplan, V. Pascual || hadrielk@yahoo.com, victor.pascual@quobis.com +# RFC7333 || H. Chan, Ed., D. Liu, P. Seite, H. Yokota, J. Korhonen || h.a.chan@ieee.org, liudapeng@chinamobile.com, pierrick.seite@orange.com, hidetoshi.yokota@landisgyr.com, jouni.nospam@gmail.com +# RFC7334 || Q. Zhao, D. Dhody, D. King, Z. Ali, R. Casellas || quintin.zhao@huawei.com, dhruv.dhody@huawei.com, daniel@olddog.co.uk, zali@cisco.com, ramon.casellas@cttc.es +# RFC7335 || C. Byrne || cameron.byrne@t-mobile.com +# RFC7336 || L. Peterson, B. Davie, R. van Brandenburg, Ed. || lapeters@akamai.com, bdavie@vmware.com, ray.vanbrandenburg@tno.nl +# RFC7337 || K. Leung, Ed., Y. Lee, Ed. || kleung@cisco.com, yiu_lee@cable.comcast.com +# RFC7338 || F. Jounay, Ed., Y. Kamite, Ed., G. Heron, M. Bocci || frederic.jounay@orange.ch, y.kamite@ntt.com, giheron@cisco.com, Matthew.Bocci@alcatel-lucent.com +# RFC7339 || V. Gurbani, Ed., V. Hilt, H. Schulzrinne || vkg@bell-labs.com, volker.hilt@bell-labs.com, hgs@cs.columbia.edu +# RFC7340 || J. Peterson, H. Schulzrinne, H. Tschofenig || jon.peterson@neustar.biz, hgs@cs.columbia.edu, Hannes.Tschofenig@gmx.net +# RFC7341 || Q. Sun, Y. Cui, M. Siodelski, S. Krishnan, I. Farrer || sunqi@csnet1.cs.tsinghua.edu.cn, yong@csnet1.cs.tsinghua.edu.cn, msiodelski@gmail.com, suresh.krishnan@ericsson.com, ian.farrer@telekom.de +# RFC7342 || L. Dunbar, W. Kumari, I. Gashinsky || ldunbar@huawei.com, warren@kumari.net, igor@yahoo-inc.com +# RFC7343 || J. Laganier, F. Dupont || julien.ietf@gmail.com, fdupont@isc.org +# RFC7344 || W. Kumari, O. Gudmundsson, G. Barwood || warren@kumari.net, ogud@ogud.com, george.barwood@blueyonder.co.uk +# RFC7345 || C. Holmberg, I. Sedlacek, G. Salgueiro || christer.holmberg@ericsson.com, ivo.sedlacek@ericsson.com, gsalguei@cisco.com +# RFC7346 || R. Droms || rdroms.ietf@gmail.com +# RFC7347 || H. van Helvoort, Ed., J. Ryoo, Ed., H. Zhang, F. Huang, H. Li, A. D'Alessandro || huub@van-helvoort.eu, ryoo@etri.re.kr, zhanghaiyan@huawei.com, feng.huang@philips.com, lihan@chinamobile.com, alessandro.dalessandro@telecomitalia.it +# RFC7348 || M. Mahalingam, D. Dutt, K. Duda, P. Agarwal, L. Kreeger, T. Sridhar, M. Bursell, C. Wright || mallik_mahalingam@yahoo.com, ddutt.ietf@hobbesdutt.com, kduda@arista.com, pagarwal@broadcom.com, kreeger@cisco.com, tsridhar@vmware.com, mike.bursell@intel.com, chrisw@redhat.com +# RFC7349 || L. Zheng, M. Chen, M. Bhatia || vero.zheng@huawei.com, mach.chen@huawei.com, manav@ionosnetworks.com +# RFC7350 || M. Petit-Huguenin, G. Salgueiro || marcph@getjive.com, gsalguei@cisco.com +# RFC7351 || E. Wilde || dret@berkeley.edu +# RFC7352 || S. Bosch || stephan@rename-it.nl +# RFC7353 || S. Bellovin, R. Bush, D. Ward || bellovin@acm.org, randy@psg.com, dward@cisco.com +# RFC7354 || A. Adolf, P. Siebert || alexander.adolf@condition-alpha.com, dvb@dvb.org +# RFC7355 || G. Salgueiro, V. Pascual, A. Roman, S. Garcia || gsalguei@cisco.com, victor.pascual@quobis.com, anton.roman@quobis.com, sergio.garcia@quobis.com +# RFC7356 || L. Ginsberg, S. Previdi, Y. Yang || ginsberg@cisco.com, sprevidi@cisco.com, yiya@cisco.com +# RFC7357 || H. Zhai, F. Hu, R. Perlman, D. Eastlake 3rd, O. Stokes || zhai.hongjun@zte.com.cn, hu.fangwei@zte.com.cn, Radia@alum.mit.edu, d3e3e3@gmail.com, ostokes@extremenetworks.com +# RFC7358 || K. Raza, S. Boutros, L. Martini, N. Leymann || skraza@cisco.com, sboutros@cisco.com, lmartini@cisco.com, n.leymann@telekom.de +# RFC7359 || F. Gont || fgont@si6networks.com +# RFC7360 || A. DeKok || aland@freeradius.org +# RFC7361 || P. Dutta, F. Balus, O. Stokes, G. Calvignac, D. Fedyk || pranjal.dutta@alcatel-lucent.com, florin.balus@alcatel-lucent.com, ostokes@extremenetworks.com, geraldine.calvignac@orange.com, don.fedyk@hp.com +# RFC7362 || E. Ivov, H. Kaplan, D. Wing || emcho@jitsi.org, hadrielk@yahoo.com, dwing-ietf@fuggles.com +# RFC7363 || J. Maenpaa, G. Camarillo || Jouni.Maenpaa@ericsson.com, Gonzalo.Camarillo@ericsson.com +# RFC7364 || T. Narten, Ed., E. Gray, Ed., D. Black, L. Fang, L. Kreeger, M. Napierala || narten@us.ibm.com, Eric.Gray@Ericsson.com, david.black@emc.com, lufang@microsoft.com, kreeger@cisco.com, mnapierala@att.com +# RFC7365 || M. Lasserre, F. Balus, T. Morin, N. Bitar, Y. Rekhter || marc.lasserre@alcatel-lucent.com, florin.balus@alcatel-lucent.com, thomas.morin@orange.com, nabil.n.bitar@verizon.com, yakov@juniper.net +# RFC7366 || P. Gutmann || pgut001@cs.auckland.ac.nz +# RFC7367 || R. Cole, J. Macker, B. Adamson || robert.g.cole@us.army.mil, macker@itd.nrl.navy.mil, adamson@itd.nrl.navy.mil +# RFC7368 || T. Chown, Ed., J. Arkko, A. Brandt, O. Troan, J. Weil || tjc@ecs.soton.ac.uk, jari.arkko@piuha.net, Anders_Brandt@sigmadesigns.com, ot@cisco.com, jason.weil@twcable.com +# RFC7369 || A. Takacs, B. Gero, H. Long || attila.takacs@ericsson.com, balazs.peter.gero@ericsson.com, lonho@huawei.com +# RFC7370 || L. Ginsberg || ginsberg@cisco.com +# RFC7371 || M. Boucadair, S. Venaas || mohamed.boucadair@orange.com, stig@cisco.com +# RFC7372 || M. Kucherawy || superuser@gmail.com +# RFC7373 || B. Trammell || ietf@trammell.ch +# RFC7374 || J. Maenpaa, G. Camarillo || Jouni.Maenpaa@ericsson.com, gonzalo.camarillo@ericsson.com +# RFC7375 || J. Peterson || jon.peterson@neustar.biz +# RFC7376 || T. Reddy, R. Ravindranath, M. Perumal, A. Yegin || tireddy@cisco.com, rmohanr@cisco.com, muthu.arul@gmail.com, alper.yegin@yegin.org +# RFC7377 || B. Leiba, A. Melnikov || barryleiba@computer.org, alexey.melnikov@isode.com +# RFC7378 || H. Tschofenig, H. Schulzrinne, B. Aboba, Ed. || Hannes.Tschofenig@gmx.net, hgs@cs.columbia.edu, Bernard_Aboba@hotmail.com +# RFC7379 || Y. Li, W. Hao, R. Perlman, J. Hudson, H. Zhai || liyizhou@huawei.com, haoweiguo@huawei.com, radia@alum.mit.edu, jon.hudson@gmail.com, honjun.zhai@tom.com +# RFC7380 || J. Tong, C. Bi, Ed., R. Even, Q. Wu, Ed., R. Huang || tongjg@sttri.com.cn, bijy@sttri.com.cn, roni.even@mail01.huawei.com, bill.wu@huawei.com, rachel.huang@huawei.com +# RFC7381 || K. Chittimaneni, T. Chown, L. Howard, V. Kuarsingh, Y. Pouffary, E. Vyncke || kk@dropbox.com, tjc@ecs.soton.ac.uk, lee.howard@twcable.com, victor@jvknet.com, yanick.pouffary@hp.com, evyncke@cisco.com +# RFC7382 || S. Kent, D. Kong, K. Seo || skent@bbn.com, dkong@bbn.com, kseo@bbn.com +# RFC7383 || V. Smyslov || svan@elvis.ru +# RFC7384 || T. Mizrahi || talmi@marvell.com +# RFC7385 || L. Andersson, G. Swallow || loa@mail01.huawei.com, swallow@cisco.com +# RFC7386 || P. Hoffman, J. Snell || paul.hoffman@vpnc.org, jasnell@gmail.com +# RFC7387 || R. Key, Ed., L. Yong, Ed., S. Delord, F. Jounay, L. Jin || raymond.key@ieee.org, lucy.yong@huawei.com, simon.delord@gmail.com, frederic.jounay@orange.ch, lizho.jin@gmail.com +# RFC7388 || J. Schoenwaelder, A. Sehgal, T. Tsou, C. Zhou || j.schoenwaelder@jacobs-university.de, s.anuj@jacobs-university.de, tina.tsou.zouting@huawei.com, cathyzhou@huawei.com +# RFC7389 || R. Wakikawa, R. Pazhyannur, S. Gundavelli, C. Perkins || ryuji.wakikawa@gmail.com, rpazhyan@cisco.com, sgundave@cisco.com, charliep@computer.org +# RFC7390 || A. Rahman, Ed., E. Dijk, Ed. || Akbar.Rahman@InterDigital.com, esko.dijk@philips.com +# RFC7391 || J. Hadi Salim || hadi@mojatatu.com +# RFC7392 || P. Dutta, M. Bocci, L. Martini || pranjal.dutta@alcatel-lucent.com, matthew.bocci@alcatel-lucent.com, lmartini@cisco.com +# RFC7393 || X. Deng, M. Boucadair, Q. Zhao, J. Huang, C. Zhou || dxhbupt@gmail.com, mohamed.boucadair@orange.com, zhaoqin.bupt@gmail.com, james.huang@huawei.com, cathy.zhou@huawei.com +# RFC7394 || S. Boutros, S. Sivabalan, G. Swallow, S. Saxena, V. Manral, S. Aldrin || sboutros@cisco.com, msiva@cisco.com, swallow@cisco.com, ssaxena@cisco.com, vishwas@ionosnetworks.com, aldrin.ietf@gmail.com +# RFC7395 || L. Stout, Ed., J. Moffitt, E. Cestari || lance@andyet.net, jack@metajack.im, eric@cstar.io +# RFC7396 || P. Hoffman, J. Snell || paul.hoffman@vpnc.org, jasnell@gmail.com +# RFC7397 || J. Gilger, H. Tschofenig || Gilger@ITSec.RWTH-Aachen.de, Hannes.tschofenig@gmx.net +# RFC7398 || M. Bagnulo, T. Burbridge, S. Crawford, P. Eardley, A. Morton || marcelo@it.uc3m.es, trevor.burbridge@bt.com, sam@samknows.com, philip.eardley@bt.com, acmorton@att.com +# RFC7399 || A. Farrel, D. King || adrian@olddog.co.uk, daniel@olddog.co.uk +# RFC7400 || C. Bormann || cabo@tzi.org +# RFC7401 || R. Moskowitz, Ed., T. Heer, P. Jokela, T. Henderson || rgm@labs.htt-consult.com, tobias.heer@belden.com, petri.jokela@nomadiclab.com, tomhend@u.washington.edu +# RFC7402 || P. Jokela, R. Moskowitz, J. Melen || petri.jokela@nomadiclab.com, rgm@labs.htt-consult.com, jan.melen@nomadiclab.com +# RFC7403 || H. Kaplan || hadrielk@yahoo.com +# RFC7404 || M. Behringer, E. Vyncke || mbehring@cisco.com, evyncke@cisco.com +# RFC7405 || P. Kyzivat || pkyzivat@alum.mit.edu +# RFC7406 || H. Schulzrinne, S. McCann, G. Bajko, H. Tschofenig, D. Kroeselberg || hgs+ecrit@cs.columbia.edu, smccann@blackberry.com, gabor.bajko@mediatek.com, Hannes.Tschofenig@gmx.net, dirk.kroeselberg@siemens.com +# RFC7407 || M. Bjorklund, J. Schoenwaelder || mbj@tail-f.com, j.schoenwaelder@jacobs-university.de +# RFC7408 || E. Haleplidis || ehalep@ece.upatras.gr +# RFC7409 || E. Haleplidis, J. Halpern || ehalep@ece.upatras.gr, joel.halpern@ericsson.com +# RFC7410 || M. Kucherawy || superuser@gmail.com +# RFC7411 || T. Schmidt, Ed., M. Waehlisch, R. Koodli, G. Fairhurst, D. Liu || t.schmidt@haw-hamburg.de, mw@link-lab.net, rajeev.koodli@intel.com, gorry@erg.abdn.ac.uk, liudapeng@chinamobile.com +# RFC7412 || Y. Weingarten, S. Aldrin, P. Pan, J. Ryoo, G. Mirsky || wyaacov@gmail.com, aldrin.ietf@gmail.com, ppan@infinera.com, ryoo@etri.re.kr, gregory.mirsky@ericsson.com +# RFC7413 || Y. Cheng, J. Chu, S. Radhakrishnan, A. Jain || ycheng@google.com, hkchu@google.com, sivasankar@cs.ucsd.edu, arvind@google.com +# RFC7414 || M. Duke, R. Braden, W. Eddy, E. Blanton, A. Zimmermann || m.duke@f5.com, braden@isi.edu, wes@mti-systems.com, elb@interruptsciences.com, alexander.zimmermann@netapp.com +# RFC7415 || E. Noel, P. Williams || ecnoel@att.com, phil.m.williams@bt.com +# RFC7416 || T. Tsao, R. Alexander, M. Dohler, V. Daza, A. Lozano, M. Richardson, Ed. || tzetatsao@eaton.com, rogeralexander@eaton.com, mischa.dohler@kcl.ac.uk, vanesa.daza@upf.edu, angel.lozano@upf.edu, mcr+ietf@sandelman.ca +# RFC7417 || G. Karagiannis, A. Bhargava || georgios.karagiannis@huawei.com, anuragb@cisco.com +# RFC7418 || S. Dawkins, Ed. || spencerdawkins.ietf@gmail.com +# RFC7419 || N. Akiya, M. Binderberger, G. Mirsky || nobo@cisco.com, mbinderb@cisco.com, gregory.mirsky@ericsson.com +# RFC7420 || A. Koushik, E. Stephan, Q. Zhao, D. King, J. Hardwick || kkoushik@brocade.com, emile.stephan@orange.com, qzhao@huawei.com, daniel@olddog.co.uk, jonathan.hardwick@metaswitch.com +# RFC7421 || B. Carpenter, Ed., T. Chown, F. Gont, S. Jiang, A. Petrescu, A. Yourtchenko || brian.e.carpenter@gmail.com, tjc@ecs.soton.ac.uk, fgont@si6networks.com, jiangsheng@huawei.com, alexandru.petrescu@cea.fr, ayourtch@cisco.com +# RFC7422 || C. Donley, C. Grundemann, V. Sarawat, K. Sundaresan, O. Vautrin || c.donley@cablelabs.com, cgrundemann@gmail.com, v.sarawat@cablelabs.com, k.sundaresan@cablelabs.com, Olivier@juniper.net +# RFC7423 || L. Morand, Ed., V. Fajardo, H. Tschofenig || lionel.morand@orange.com, vf0213@gmail.com, Hannes.Tschofenig@gmx.net +# RFC7424 || R. Krishnan, L. Yong, A. Ghanwani, N. So, B. Khasnabish || ramkri123@gmail.com, lucy.yong@huawei.com, anoop@alumni.duke.edu, ningso@yahoo.com, vumip1@gmail.com +# RFC7425 || M. Thornburgh || mthornbu@adobe.com +# RFC7426 || E. Haleplidis, Ed., K. Pentikousis, Ed., S. Denazis, J. Hadi Salim, D. Meyer, O. Koufopavlou || ehalep@ece.upatras.gr, k.pentikousis@eict.de, sdena@upatras.gr, hadi@mojatatu.com, dmm@1-4-5.net, odysseas@ece.upatras.gr +# RFC7427 || T. Kivinen, J. Snyder || kivinen@iki.fi, jms@opus1.com +# RFC7428 || A. Brandt, J. Buron || anders_brandt@sigmadesigns.com, jakob_buron@sigmadesigns.com +# RFC7429 || D. Liu, Ed., JC. Zuniga, Ed., P. Seite, H. Chan, CJ. Bernardos || liudapeng@chinamobile.com, JuanCarlos.Zuniga@InterDigital.com, pierrick.seite@orange.com, h.a.chan@ieee.org, cjbc@it.uc3m.es +# RFC7430 || M. Bagnulo, C. Paasch, F. Gont, O. Bonaventure, C. Raiciu || marcelo@it.uc3m.es, christoph.paasch@gmail.com, fgont@si6networks.com, Olivier.Bonaventure@uclouvain.be, costin.raiciu@cs.pub.ro +# RFC7431 || A. Karan, C. Filsfils, IJ. Wijnands, Ed., B. Decraene || apoorva@cisco.com, cfilsfil@cisco.com, ice@cisco.com, bruno.decraene@orange.com +# RFC7432 || A. Sajassi, Ed., R. Aggarwal, N. Bitar, A. Isaac, J. Uttaro, J. Drake, W. Henderickx || sajassi@cisco.com, raggarwa_1@yahoo.com, nabil.n.bitar@verizon.com, aisaac71@bloomberg.net, uttaro@att.com, jdrake@juniper.net, wim.henderickx@alcatel-lucent.com +# RFC7433 || A. Johnston, J. Rafferty || alan.b.johnston@gmail.com, jay@humancomm.com +# RFC7434 || K. Drage, Ed., A. Johnston || keith.drage@alcatel-lucent.com, alan.b.johnston@gmail.com +# RFC7435 || V. Dukhovni || ietf-dane@dukhovni.org +# RFC7436 || H. Shah, E. Rosen, F. Le Faucheur, G. Heron || hshah@ciena.com, erosen@juniper.net, flefauch@cisco.com, giheron@cisco.com +# RFC7437 || M. Kucherawy, Ed. || superuser@gmail.com +# RFC7438 || IJ. Wijnands, Ed., E. Rosen, A. Gulko, U. Joorde, J. Tantsura || ice@cisco.com, erosen@juniper.net, arkadiy.gulko@thomsonreuters.com, uwe.joorde@telekom.de, jeff.tantsura@ericsson.com +# RFC7439 || W. George, Ed., C. Pignataro, Ed. || wesley.george@twcable.com, cpignata@cisco.com +# RFC7440 || P. Masotta || patrick.masotta.ietf@vercot.com +# RFC7441 || IJ. Wijnands, E. Rosen, U. Joorde || ice@cisco.com, erosen@juniper.net, uwe.joorde@telekom.de +# RFC7442 || Y. Rekhter, R. Aggarwal, N. Leymann, W. Henderickx, Q. Zhao, R. Li || yakov@juniper.net, raggarwa_1@yahoo.com, N.Leymann@telekom.de, wim.henderickx@alcatel-lucent.com, quintin.zhao@huawei.com, renwei.li@huawei.com +# RFC7443 || P. Patil, T. Reddy, G. Salgueiro, M. Petit-Huguenin || praspati@cisco.com, tireddy@cisco.com, gsalguei@cisco.com, marc@petit-huguenin.org +# RFC7444 || K. Zeilenga, A. Melnikov || kurt.zeilenga@isode.com, alexey.melnikov@isode.com +# RFC7445 || G. Chen, H. Deng, D. Michaud, J. Korhonen, M. Boucadair || phdgang@gmail.com, denghui@chinamobile.com, dave.michaud@rci.rogers.com, jouni.nospam@gmail.com, mohamed.boucadair@orange.com +# RFC7446 || Y. Lee, Ed., G. Bernstein, Ed., D. Li, W. Imajuku || leeyoung@huawei.com, gregb@grotto-networking.com, danli@huawei.com, imajuku.wataru@lab.ntt.co.jp +# RFC7447 || J. Scudder, K. Kompella || jgs@juniper.net, kireeti@juniper.net +# RFC7448 || T. Taylor, Ed., D. Romascanu || tom.taylor.stds@gmail.com, dromasca@gmail.com +# RFC7449 || Y. Lee, Ed., G. Bernstein, Ed., J. Martensson, T. Takeda, T. Tsuritani, O. Gonzalez de Dios || leeyoung@huawei.com, gregb@grotto-networking.com, jonas.martensson@acreo.se, tomonori.takeda@ntt.com, tsuri@kddilabs.jp, oscar.gonzalezdedios@telefonica.com +# RFC7450 || G. Bumgardner || gbumgard@gmail.com +# RFC7451 || S. Hollenbeck || shollenbeck@verisign.com +# RFC7452 || H. Tschofenig, J. Arkko, D. Thaler, D. McPherson || Hannes.Tschofenig@gmx.net, jari.arkko@piuha.net, dthaler@microsoft.com, dmcpherson@verisign.com +# RFC7453 || V. Mahalingam, K. Sampath, S. Aldrin, T. Nadeau || venkat.mahalingams@gmail.com, kannankvs@gmail.com, aldrin.ietf@gmail.com, tnadeau@lucidvision.com +# RFC7454 || J. Durand, I. Pepelnjak, G. Doering || jerduran@cisco.com, ip@ipspace.net, gert@space.net +# RFC7455 || T. Senevirathne, N. Finn, S. Salam, D. Kumar, D. Eastlake 3rd, S. Aldrin, Y. Li || tsenevir@cisco.com, nfinn@cisco.com, ssalam@cisco.com, dekumar@cisco.com, d3e3e3@gmail.com, aldrin.ietf@gmail.com, liyizhou@huawei.com +# RFC7456 || T. Mizrahi, T. Senevirathne, S. Salam, D. Kumar, D. Eastlake 3rd || talmi@marvell.com, tsenevir@cisco.com, ssalam@cisco.com, dekumar@cisco.com, d3e3e3@gmail.com +# RFC7457 || Y. Sheffer, R. Holz, P. Saint-Andre || yaronf.ietf@gmail.com, holz@net.in.tum.de, peter@andyet.com +# RFC7458 || R. Valmikam, R. Koodli || valmikam@gmail.com, rajeev.koodli@intel.com +# RFC7459 || M. Thomson, J. Winterbottom || martin.thomson@gmail.com, a.james.winterbottom@gmail.com +# RFC7460 || M. Chandramouli, B. Claise, B. Schoening, J. Quittek, T. Dietz || moulchan@cisco.com, bclaise@cisco.com, brad.schoening@verizon.net, quittek@neclab.eu, Thomas.Dietz@neclab.eu +# RFC7461 || J. Parello, B. Claise, M. Chandramouli || jparello@cisco.com, bclaise@cisco.com, moulchan@cisco.com +# RFC7462 || L. Liess, Ed., R. Jesske, A. Johnston, D. Worley, P. Kyzivat || laura.liess.dt@gmail.com, r.jesske@telekom.de, alan.b.johnston@gmail.com, worley@ariadne.com, pkyzivat@alum.mit.edu +# RFC7463 || A. Johnston, Ed., M. Soroushnejad, Ed., V. Venkataramanan || alan.b.johnston@gmail.com, msoroush@gmail.com, vvenkatar@gmail.com +# RFC7464 || N. Williams || nico@cryptonector.com +# RFC7465 || A. Popov || andreipo@microsoft.com +# RFC7466 || C. Dearlove, T. Clausen || chris.dearlove@baesystems.com, T.Clausen@computer.org +# RFC7467 || A. Murdock || Aidan.murdock@ncia.nato.int +# RFC7468 || S. Josefsson, S. Leonard || simon@josefsson.org, dev+ietf@seantek.com +# RFC7469 || C. Evans, C. Palmer, R. Sleevi || cevans@google.com, palmer@google.com, sleevi@google.com +# RFC7470 || F. Zhang, A. Farrel || zhangfatai@huawei.com, adrian@olddog.co.uk +# RFC7471 || S. Giacalone, D. Ward, J. Drake, A. Atlas, S. Previdi || spencer.giacalone@gmail.com, dward@cisco.com, jdrake@juniper.net, akatlas@juniper.net, sprevidi@cisco.com +# RFC7472 || I. McDonald, M. Sweet || blueroofmusic@gmail.com, msweet@apple.com +# RFC7473 || K. Raza, S. Boutros || skraza@cisco.com, sboutros@cisco.com +# RFC7474 || M. Bhatia, S. Hartman, D. Zhang, A. Lindem, Ed. || manav@ionosnetworks.com, hartmans-ietf@mit.edu, dacheng.zhang@gmail.com, acee@cisco.com +# RFC7475 || S. Dawkins || spencerdawkins.ietf@gmail.com +# RFC7476 || K. Pentikousis, Ed., B. Ohlman, D. Corujo, G. Boggia, G. Tyson, E. Davies, A. Molinaro, S. Eum || k.pentikousis@eict.de, Borje.Ohlman@ericsson.com, dcorujo@av.it.pt, g.boggia@poliba.it, gareth.tyson@eecs.qmul.ac.uk, davieseb@scss.tcd.ie, antonella.molinaro@unirc.it, suyong@nict.go.jp +# RFC7477 || W. Hardaker || ietf@hardakers.net +# RFC7478 || C. Holmberg, S. Hakansson, G. Eriksson || christer.holmberg@ericsson.com, stefan.lk.hakansson@ericsson.com, goran.ap.eriksson@ericsson.com +# RFC7479 || S. Moonesamy || sm+ietf@elandsys.com +# RFC7480 || A. Newton, B. Ellacott, N. Kong || andy@arin.net, bje@apnic.net, nkong@cnnic.cn +# RFC7481 || S. Hollenbeck, N. Kong || shollenbeck@verisign.com, nkong@cnnic.cn +# RFC7482 || A. Newton, S. Hollenbeck || andy@arin.net, shollenbeck@verisign.com +# RFC7483 || A. Newton, S. Hollenbeck || andy@arin.net, shollenbeck@verisign.com +# RFC7484 || M. Blanchet || Marc.Blanchet@viagenie.ca +# RFC7485 || L. Zhou, N. Kong, S. Shen, S. Sheng, A. Servin || zhoulinlin@cnnic.cn, nkong@cnnic.cn, shenshuo@cnnic.cn, steve.sheng@icann.org, arturo.servin@gmail.com +# RFC7486 || S. Farrell, P. Hoffman, M. Thomas || stephen.farrell@cs.tcd.ie, paul.hoffman@vpnc.org, mike@phresheez.com +# RFC7487 || E. Bellagamba, A. Takacs, G. Mirsky, L. Andersson, P. Skoldstrom, D. Ward || elisa.bellagamba@ericsson.com, attila.takacs@ericsson.com, gregory.mirsky@ericsson.com, loa@mail01.huawei.com, pontus.skoldstrom@acreo.se, dward@cisco.com +# RFC7488 || M. Boucadair, R. Penno, D. Wing, P. Patil, T. Reddy || mohamed.boucadair@orange.com, repenno@cisco.com, dwing-ietf@fuggles.com, praspati@cisco.com, tireddy@cisco.com +# RFC7489 || M. Kucherawy, Ed., E. Zwicky, Ed. || superuser@gmail.com, zwicky@yahoo-inc.com +# RFC7490 || S. Bryant, C. Filsfils, S. Previdi, M. Shand, N. So || stbryant@cisco.com, cfilsfil@cisco.com, sprevidi@cisco.com, imc.shand@gmail.com, ningso@vinci-systems.com +# RFC7491 || D. King, A. Farrel || daniel@olddog.co.uk, adrian@olddog.co.uk +# RFC7492 || M. Bhatia, D. Zhang, M. Jethanandani || manav@ionosnetworks.com, dacheng.zhang@gmail.com, mjethanandani@gmail.com +# RFC7493 || T. Bray, Ed. || tbray@textuality.com +# RFC7494 || C. Shao, H. Deng, R. Pazhyannur, F. Bari, R. Zhang, S. Matsushima || shaochunju@chinamobile.com, denghui@chinamobile.com, rpazhyan@cisco.com, farooq.bari@att.com, zhangr@gsta.com, satoru.matsushima@g.softbank.co.jp +# RFC7495 || A. Montville, D. Black || adam.w.montville@gmail.com, david.black@emc.com +# RFC7496 || M. Tuexen, R. Seggelmann, R. Stewart, S. Loreto || tuexen@fh-muenster.de, rfc@robin-seggelmann.com, randall@lakerest.net, Salvatore.Loreto@ericsson.com +# RFC7497 || A. Morton || acmorton@att.com +# RFC7498 || P. Quinn, Ed., T. Nadeau, Ed. || paulq@cisco.com, tnadeau@lucidvision.com +# RFC7499 || A. Perez-Mendez, Ed., R. Marin-Lopez, F. Pereniguez-Garcia, G. Lopez-Millan, D. Lopez, A. DeKok || alex@um.es, rafa@um.es, pereniguez@um.es, gabilm@um.es, diego@tid.es, aland@networkradius.com +# RFC7500 || R. Housley, Ed., O. Kolkman, Ed. || housley@vigilsec.com, kolkman@isoc.org +# RFC7501 || C. Davids, V. Gurbani, S. Poretsky || davids@iit.edu, vkg@bell-labs.com, sporetsky@allot.com +# RFC7502 || C. Davids, V. Gurbani, S. Poretsky || davids@iit.edu, vkg@bell-labs.com, sporetsky@allot.com +# RFC7503 || A. Lindem, J. Arkko || acee@cisco.com, jari.arkko@piuha.net +# RFC7504 || J. Klensin || john-ietf@jck.com +# RFC7505 || J. Levine, M. Delany || standards@taugh.com, mx0dot@yahoo.com +# RFC7506 || K. Raza, N. Akiya, C. Pignataro || skraza@cisco.com, nobo.akiya.dev@gmail.com, cpignata@cisco.com +# RFC7507 || B. Moeller, A. Langley || bmoeller@acm.org, agl@google.com +# RFC7508 || L. Cailleux, C. Bonatti || laurent.cailleux@intradef.gouv.fr, bonatti252@ieca.com +# RFC7509 || R. Huang, V. Singh || rachel.huang@huawei.com, varun@comnet.tkk.fi +# RFC7510 || X. Xu, N. Sheth, L. Yong, R. Callon, D. Black || xuxiaohu@huawei.com, nsheth@juniper.net, lucy.yong@huawei.com, rcallon@juniper.net, david.black@emc.com +# RFC7511 || M. Wilhelm || max@rfc2324.org +# RFC7512 || J. Pechanec, D. Moffat || Jan.Pechanec@Oracle.COM, Darren.Moffat@Oracle.COM +# RFC7513 || J. Bi, J. Wu, G. Yao, F. Baker || junbi@tsinghua.edu.cn, jianping@cernet.edu.cn, yaoguang@cernet.edu.cn, fred@cisco.com +# RFC7514 || M. Luckie || mjl@caida.org +# RFC7515 || M. Jones, J. Bradley, N. Sakimura || mbj@microsoft.com, ve7jtb@ve7jtb.com, n-sakimura@nri.co.jp +# RFC7516 || M. Jones, J. Hildebrand || mbj@microsoft.com, jhildebr@cisco.com +# RFC7517 || M. Jones || mbj@microsoft.com +# RFC7518 || M. Jones || mbj@microsoft.com +# RFC7519 || M. Jones, J. Bradley, N. Sakimura || mbj@microsoft.com, ve7jtb@ve7jtb.com, n-sakimura@nri.co.jp +# RFC7520 || M. Miller || mamille2@cisco.com +# RFC7521 || B. Campbell, C. Mortimore, M. Jones, Y. Goland || brian.d.campbell@gmail.com, cmortimore@salesforce.com, mbj@microsoft.com, yarong@microsoft.com +# RFC7522 || B. Campbell, C. Mortimore, M. Jones || brian.d.campbell@gmail.com, cmortimore@salesforce.com, mbj@microsoft.com +# RFC7523 || M. Jones, B. Campbell, C. Mortimore || mbj@microsoft.com, brian.d.campbell@gmail.com, cmortimore@salesforce.com +# RFC7524 || Y. Rekhter, E. Rosen, R. Aggarwal, T. Morin, I. Grosclaude, N. Leymann, S. Saad || yakov@juniper.net, erosen@juniper.net, raggarwa_1@yahoo.com, thomas.morin@orange.com, irene.grosclaude@orange.com, n.leymann@telekom.de, samirsaad1@outlook.com +# RFC7525 || Y. Sheffer, R. Holz, P. Saint-Andre || yaronf.ietf@gmail.com, ralph.ietf@gmail.com, peter@andyet.com +# RFC7526 || O. Troan, B. Carpenter, Ed. || ot@cisco.com, brian.e.carpenter@gmail.com +# RFC7527 || R. Asati, H. Singh, W. Beebee, C. Pignataro, E. Dart, W. George || rajiva@cisco.com, shemant@cisco.com, wbeebee@cisco.com, cpignata@cisco.com, dart@es.net, wesley.george@twcable.com +# RFC7528 || P. Higgs, J. Piesing || paul.higgs@ericsson.com, jon.piesing@tpvision.com +# RFC7529 || C. Daboo, G. Yakushev || cyrus@daboo.name, gyakushev@yahoo.com +# RFC7530 || T. Haynes, Ed., D. Noveck, Ed. || thomas.haynes@primarydata.com, dave_noveck@dell.com +# RFC7531 || T. Haynes, Ed., D. Noveck, Ed. || thomas.haynes@primarydata.com, dave_noveck@dell.com +# RFC7532 || J. Lentini, R. Tewari, C. Lever, Ed. || jlentini@netapp.com, tewarir@us.ibm.com, chuck.lever@oracle.com +# RFC7533 || J. Lentini, R. Tewari, C. Lever, Ed. || jlentini@netapp.com, tewarir@us.ibm.com, chuck.lever@oracle.com +# RFC7534 || J. Abley, W. Sotomayor || jabley@dyn.com, wfms@ottix.net +# RFC7535 || J. Abley, B. Dickson, W. Kumari, G. Michaelson || jabley@dyn.com, bdickson@twitter.com, warren@kumari.net, ggm@apnic.net +# RFC7536 || M. Linsner, P. Eardley, T. Burbridge, F. Sorensen || mlinsner@cisco.com, philip.eardley@bt.com, trevor.burbridge@bt.com, frode.sorensen@nkom.no +# RFC7537 || B. Decraene, N. Akiya, C. Pignataro, L. Andersson, S. Aldrin || bruno.decraene@orange.com, nobo.akiya.dev@gmail.com, cpignata@cisco.com, loa@mail01.huawei.com, aldrin.ietf@gmail.com +# RFC7538 || J. Reschke || julian.reschke@greenbytes.de +# RFC7539 || Y. Nir, A. Langley || ynir.ietf@gmail.com, agl@google.com +# RFC7540 || M. Belshe, R. Peon, M. Thomson, Ed. || mike@belshe.com, fenix@google.com, martin.thomson@gmail.com +# RFC7541 || R. Peon, H. Ruellan || fenix@google.com, herve.ruellan@crf.canon.fr +# RFC7542 || A. DeKok || aland@freeradius.org +# RFC7543 || H. Jeng, L. Jalil, R. Bonica, K. Patel, L. Yong || hj2387@att.com, luay.jalil@verizon.com, rbonica@juniper.net, keyupate@cisco.com, lucy.yong@huawei.com +# RFC7544 || M. Mohali || marianne.mohali@orange.com +# RFC7545 || V. Chen, Ed., S. Das, L. Zhu, J. Malyar, P. McCann || vchen@google.com, sdas@appcomsci.com, lei.zhu@huawei.com, jmalyar@iconectiv.com, peter.mccann@huawei.com +# RFC7546 || B. Kaduk || kaduk@mit.edu +# RFC7547 || M. Ersue, Ed., D. Romascanu, J. Schoenwaelder, U. Herberg || mehmet.ersue@nsn.com, dromasca@gmail.com , j.schoenwaelder@jacobs-university.de, ulrich@herberg.name +# RFC7548 || M. Ersue, Ed., D. Romascanu, J. Schoenwaelder, A. Sehgal || mehmet.ersue@nsn.com, dromasca@gmail.com , j.schoenwaelder@jacobs-university.de, s.anuj@jacobs-university.de +# RFC7549 || C. Holmberg, J. Holm, R. Jesske, M. Dolly || christer.holmberg@ericsson.com, jan.holm@ericsson.com, r.jesske@telekom.de, md3135@att.com +# RFC7550 || O. Troan, B. Volz, M. Siodelski || ot@cisco.com, volz@cisco.com, msiodelski@gmail.com +# RFC7551 || F. Zhang, Ed., R. Jing, R. Gandhi, Ed. || zhangfei7@huawei.com, jingrq@ctbri.com.cn, rgandhi@cisco.com +# RFC7552 || R. Asati, C. Pignataro, K. Raza, V. Manral, R. Papneja || rajiva@cisco.com, cpignata@cisco.com, skraza@cisco.com, vishwas@ionosnetworks.com, rajiv.papneja@huawei.com +# RFC7553 || P. Faltstrom, O. Kolkman || paf@netnod.se, kolkman@isoc.org +# RFC7554 || T. Watteyne, Ed., M. Palattella, L. Grieco || twatteyne@linear.com, maria-rita.palattella@uni.lu, a.grieco@poliba.it +# RFC7555 || G. Swallow, V. Lim, S. Aldrin || swallow@cisco.com, vlim@cisco.com, aldrin.ietf@gmail.com +# RFC7556 || D. Anipko, Ed. || dmitry.anipko@gmail.com +# RFC7557 || J. Chroboczek || jch@pps.univ-paris-diderot.fr +# RFC7558 || K. Lynn, S. Cheshire, M. Blanchet, D. Migault || kerry.lynn@verizon.com, cheshire@apple.com, Marc.Blanchet@viagenie.ca, daniel.migault@ericsson.com +# RFC7559 || S. Krishnan, D. Anipko, D. Thaler || suresh.krishnan@ericsson.com, dmitry.anipko@gmail.com, dthaler@microsoft.com +# RFC7560 || M. Kuehlewind, Ed., R. Scheffenegger, B. Briscoe || mirja.kuehlewind@tik.ee.ethz.ch, rs@netapp.com, ietf@bobbriscoe.net +# RFC7561 || J. Kaippallimalil, R. Pazhyannur, P. Yegani || john.kaippallimalil@huawei.com, rpazhyan@cisco.com, pyegani@juniper.net +# RFC7562 || D. Thakore || d.thakore@cablelabs.com +# RFC7563 || R. Pazhyannur, S. Speicher, S. Gundavelli, J. Korhonen, J. Kaippallimalil || rpazhyan@cisco.com, sespeich@cisco.com, sgundave@cisco.com, jouni.nospam@gmail.com, john.kaippallimalil@huawei.com +# RFC7564 || P. Saint-Andre, M. Blanchet || peter@andyet.com, Marc.Blanchet@viagenie.ca +# RFC7565 || P. Saint-Andre || peter@andyet.com +# RFC7566 || L. Goix, K. Li || laurent.goix@econocom-osiatis.com, kepeng.likp@gmail.com +# RFC7567 || F. Baker, Ed., G. Fairhurst, Ed. || fred@cisco.com, gorry@erg.abdn.ac.uk +# RFC7568 || R. Barnes, M. Thomson, A. Pironti, A. Langley || rlb@ipv.sx, martin.thomson@gmail.com, alfredo@pironti.eu, agl@google.com +# RFC7569 || D. Quigley, J. Lu, T. Haynes || dpquigl@davequigley.com, Jarrett.Lu@oracle.com, thomas.haynes@primarydata.com +# RFC7570 || C. Margaria, Ed., G. Martinelli, S. Balls, B. Wright || cmargaria@juniper.net, giomarti@cisco.com, steve.balls@metaswitch.com, ben.wright@metaswitch.com +# RFC7571 || J. Dong, M. Chen, Z. Li, D. Ceccarelli || jie.dong@huawei.com, mach.chen@huawei.com, lizhenqiang@chinamobile.com, daniele.ceccarelli@ericsson.com +# RFC7572 || P. Saint-Andre, A. Houri, J. Hildebrand || peter@andyet.com, avshalom@il.ibm.com, jhildebr@cisco.com +# RFC7573 || P. Saint-Andre, S. Loreto || peter@andyet.com, Salvatore.Loreto@ericsson.com +# RFC7574 || A. Bakker, R. Petrocco, V. Grishchenko || arno@cs.vu.nl, r.petrocco@gmail.com, victor.grishchenko@gmail.com +# RFC7575 || M. Behringer, M. Pritikin, S. Bjarnason, A. Clemm, B. Carpenter, S. Jiang, L. Ciavaglia || mbehring@cisco.com, pritikin@cisco.com, sbjarnas@cisco.com, alex@cisco.com, brian.e.carpenter@gmail.com, jiangsheng@huawei.com, Laurent.Ciavaglia@alcatel-lucent.com +# RFC7576 || S. Jiang, B. Carpenter, M. Behringer || jiangsheng@huawei.com, brian.e.carpenter@gmail.com, mbehring@cisco.com +# RFC7577 || J. Quittek, R. Winter, T. Dietz || quittek@neclab.eu, rolf.winter@neclab.eu, Thomas.Dietz@neclab.eu +# RFC7578 || L. Masinter || masinter@adobe.com +# RFC7579 || G. Bernstein, Ed., Y. Lee, Ed., D. Li, W. Imajuku, J. Han || gregb@grotto-networking.com, ylee@huawei.com, danli@huawei.com, imajuku.wataru@lab.ntt.co.jp, hanjianrui@huawei.com +# RFC7580 || F. Zhang, Y. Lee, J. Han, G. Bernstein, Y. Xu || zhangfatai@huawei.com, leeyoung@huawei.com, hanjianrui@huawei.com, gregb@grotto-networking.com, xuyunbin@mail.ritt.com.cn +# RFC7581 || G. Bernstein, Ed., Y. Lee, Ed., D. Li, W. Imajuku, J. Han || gregb@grotto-networking.com, leeyoung@huawei.com, danli@huawei.com, imajuku.wataru@lab.ntt.co.jp, hanjianrui@huawei.com +# RFC7582 || E. Rosen, IJ. Wijnands, Y. Cai, A. Boers || erosen@juniper.net, ice@cisco.com, yiqunc@microsoft.com, arjen@boers.com +# RFC7583 || S. Morris, J. Ihren, J. Dickinson, W. Mekking || stephen@isc.org, johani@netnod.se, jad@sinodun.com, mmekking@dyn.com +# RFC7584 || R. Ravindranath, T. Reddy, G. Salgueiro || rmohanr@cisco.com, tireddy@cisco.com, gsalguei@cisco.com +# RFC7585 || S. Winter, M. McCauley || stefan.winter@restena.lu, mikem@airspayce.com +# RFC7586 || Y. Nachum, L. Dunbar, I. Yerushalmi, T. Mizrahi || youval.nachum@gmail.com, ldunbar@huawei.com, yilan@marvell.com, talmi@marvell.com +# RFC7587 || J. Spittka, K. Vos, JM. Valin || jspittka@gmail.com, koenvos74@gmail.com, jmvalin@jmvalin.ca +# RFC7588 || R. Bonica, C. Pignataro, J. Touch || rbonica@juniper.net, cpignata@cisco.com, touch@isi.edu +# RFC7589 || M. Badra, A. Luchuk, J. Schoenwaelder || mohamad.badra@zu.ac.ae, luchuk@snmp.com, j.schoenwaelder@jacobs-university.de +# RFC7590 || P. Saint-Andre, T. Alkemade || peter@andyet.com, me@thijsalkema.de +# RFC7591 || J. Richer, Ed., M. Jones, J. Bradley, M. Machulak, P. Hunt || ietf@justin.richer.org, mbj@microsoft.com, ve7jtb@ve7jtb.com, maciej.machulak@gmail.com, phil.hunt@yahoo.com +# RFC7592 || J. Richer, Ed., M. Jones, J. Bradley, M. Machulak || ietf@justin.richer.org, mbj@microsoft.com, ve7jtb@ve7jtb.com, maciej.machulak@gmail.com +# RFC7593 || K. Wierenga, S. Winter, T. Wolniewicz || klaas@cisco.com, stefan.winter@restena.lu, twoln@umk.pl +# RFC7594 || P. Eardley, A. Morton, M. Bagnulo, T. Burbridge, P. Aitken, A. Akhter || philip.eardley@bt.com, acmorton@att.com, marcelo@it.uc3m.es, trevor.burbridge@bt.com, paitken@brocade.com, aakhter@gmail.com +# RFC7595 || D. Thaler, Ed., T. Hansen, T. Hardie || dthaler@microsoft.com, tony+urireg@maillennium.att.com, ted.ietf@gmail.com +# RFC7596 || Y. Cui, Q. Sun, M. Boucadair, T. Tsou, Y. Lee, I. Farrer || yong@csnet1.cs.tsinghua.edu.cn, sunqiong@ctbri.com.cn, mohamed.boucadair@orange.com, tena@huawei.com, yiu_lee@cable.comcast.com, ian.farrer@telekom.de +# RFC7597 || O. Troan, Ed., W. Dec, X. Li, C. Bao, S. Matsushima, T. Murakami, T. Taylor, Ed. || ot@cisco.com, wdec@cisco.com, xing@cernet.edu.cn, congxiao@cernet.edu.cn, satoru.matsushima@g.softbank.co.jp, tetsuya@ipinfusion.com, tom.taylor.stds@gmail.com +# RFC7598 || T. Mrugalski, O. Troan, I. Farrer, S. Perreault, W. Dec, C. Bao, L. Yeh, X. Deng || tomasz.mrugalski@gmail.com, ot@cisco.com, ian.farrer@telekom.de, sperreault@jive.com, wdec@cisco.com, congxiao@cernet.edu.cn, leaf.y.yeh@hotmail.com, dxhbupt@gmail.com +# RFC7599 || X. Li, C. Bao, W. Dec, Ed., O. Troan, S. Matsushima, T. Murakami || xing@cernet.edu.cn, congxiao@cernet.edu.cn, wdec@cisco.com, ot@cisco.com, satoru.matsushima@g.softbank.co.jp, tetsuya@ipinfusion.com +# RFC7600 || R. Despres, S. Jiang, Ed., R. Penno, Y. Lee, G. Chen, M. Chen || despres.remi@laposte.net, jiangsheng@huawei.com, repenno@cisco.com, yiu_lee@cable.comcast.com, phdgang@gmail.com, maoke@bbix.net +# RFC7601 || M. Kucherawy || superuser@gmail.com +# RFC7602 || U. Chunduri, W. Lu, A. Tian, N. Shen || uma.chunduri@ericsson.com, wenhu.lu@ericsson.com, albert.tian@ericsson.com, naiming@cisco.com +# RFC7603 || B. Schoening, M. Chandramouli, B. Nordman || brad.schoening@verizon.net, moulchan@cisco.com, bnordman@lbl.gov +# RFC7604 || M. Westerlund, T. Zeng || magnus.westerlund@ericsson.com, thomas.zeng@gmail.com +# RFC7605 || J. Touch || touch@isi.edu +# RFC7606 || E. Chen, Ed., J. Scudder, Ed., P. Mohapatra, K. Patel || enkechen@cisco.com, jgs@juniper.net, mpradosh@yahoo.com, keyupate@cisco.com +# RFC7607 || W. Kumari, R. Bush, H. Schiller, K. Patel || warren@kumari.net, randy@psg.com, has@google.com, keyupate@cisco.com +# RFC7608 || M. Boucadair, A. Petrescu, F. Baker || mohamed.boucadair@orange.com, alexandre.petrescu@cea.fr, fred@cisco.com +# RFC7609 || M. Fox, C. Kassimis, J. Stevens || mjfox@us.ibm.com, kassimis@us.ibm.com, sjerry@us.ibm.com +# RFC7610 || F. Gont, W. Liu, G. Van de Velde || fgont@si6networks.com, liushucheng@huawei.com, gunter.van_de_velde@alcatel-lucent.com +# RFC7611 || J. Uttaro, P. Mohapatra, D. Smith, R. Raszuk, J. Scudder || uttaro@att.com, mpradosh@yahoo.com, djsmith@cisco.com, robert@raszuk.net, jgs@juniper.net +# RFC7612 || P. Fleming, I. McDonald || patfleminghtc@gmail.com, blueroofmusic@gmail.com +# RFC7613 || P. Saint-Andre, A. Melnikov || peter@andyet.com, alexey.melnikov@isode.com +# RFC7614 || R. Sparks || rjsparks@nostrum.com +# RFC7615 || J. Reschke || julian.reschke@greenbytes.de +# RFC7616 || R. Shekh-Yusef, Ed., D. Ahrens, S. Bremer || rifaat.ietf@gmail.com, ahrensdc@gmail.com, sophie.bremer@netzkonform.de +# RFC7617 || J. Reschke || julian.reschke@greenbytes.de +# RFC7618 || Y. Cui, Q. Sun, I. Farrer, Y. Lee, Q. Sun, M. Boucadair || yong@csnet1.cs.tsinghua.edu.cn, sunqi.ietf@gmail.com, ian.farrer@telekom.de, yiu_lee@cable.comcast.com, sunqiong@ctbri.com.cn, mohamed.boucadair@orange.com +# RFC7619 || V. Smyslov, P. Wouters || svan@elvis.ru, pwouters@redhat.com +# RFC7620 || M. Boucadair, Ed., B. Chatras, T. Reddy, B. Williams, B. Sarikaya || mohamed.boucadair@orange.com, bruno.chatras@orange.com, tireddy@cisco.com, brandon.williams@akamai.com, sarikaya@ieee.org +# RFC7621 || A.B. Roach || adam@nostrum.com +# RFC7622 || P. Saint-Andre || peter@andyet.com +# RFC7623 || A. Sajassi, Ed., S. Salam, N. Bitar, A. Isaac, W. Henderickx || sajassi@cisco.com, ssalam@cisco.com, nabil.n.bitar@verizon.com, aisaac@juniper.net, wim.henderickx@alcatel-lucent.com +# RFC7624 || R. Barnes, B. Schneier, C. Jennings, T. Hardie, B. Trammell, C. Huitema, D. Borkmann || rlb@ipv.sx, schneier@schneier.com, fluffy@cisco.com, ted.ietf@gmail.com, ietf@trammell.ch, huitema@huitema.net, daniel@iogearbox.net +# RFC7625 || J. T. Hao, P. Maheshwari, R. Huang, L. Andersson, M. Chen || haojiangtao@huawei.com, praveen.maheshwari@in.airtel.com, river.huang@huawei.com, loa@mail01.huawei.com, mach.chen@huawei.com +# RFC7626 || S. Bortzmeyer || bortzmeyer+ietf@nic.fr +# RFC7627 || K. Bhargavan, Ed., A. Delignat-Lavaud, A. Pironti, A. Langley, M. Ray || karthikeyan.bhargavan@inria.fr, antoine.delignat-lavaud@inria.fr, alfredo.pironti@inria.fr, agl@google.com, maray@microsoft.com +# RFC7628 || W. Mills, T. Showalter, H. Tschofenig || wmills_92105@yahoo.com, tjs@psaux.com, Hannes.Tschofenig@gmx.net +# RFC7629 || S. Gundavelli, Ed., K. Leung, G. Tsirtsis, A. Petrescu || sgundave@cisco.com, kleung@cisco.com, tsirtsis@qualcomm.com, alexandru.petrescu@cea.fr +# RFC7630 || J. Merkle, Ed., M. Lochter || johannes.merkle@secunet.com, manfred.lochter@bsi.bund.de +# RFC7631 || C. Dearlove, T. Clausen || chris.dearlove@baesystems.com, T.Clausen@computer.org +# RFC7632 || D. Waltermire, D. Harrington || david.waltermire@nist.gov, ietfdbh@gmail.com +# RFC7633 || P. Hallam-Baker || philliph@comodo.com +# RFC7634 || Y. Nir || ynir.ietf@gmail.com +# RFC7635 || T. Reddy, P. Patil, R. Ravindranath, J. Uberti || tireddy@cisco.com, praspati@cisco.com, rmohanr@cisco.com, justin@uberti.name +# RFC7636 || N. Sakimura, Ed., J. Bradley, N. Agarwal || n-sakimura@nri.co.jp, ve7jtb@ve7jtb.com, naa@google.com +# RFC7637 || P. Garg, Ed., Y. Wang, Ed. || pankajg@microsoft.com, yushwang@microsoft.com +# RFC7638 || M. Jones, N. Sakimura || mbj@microsoft.com, n-sakimura@nri.co.jp +# RFC7639 || A. Hutton, J. Uberti, M. Thomson || andrew.hutton@unify.com, justin@uberti.name, martin.thomson@gmail.com +# RFC7640 || B. Constantine, R. Krishnan || barry.constantine@jdsu.com, ramkri123@gmail.com +# RFC7641 || K. Hartke || hartke@tzi.org +# RFC7642 || K. LI, Ed., P. Hunt, B. Khasnabish, A. Nadalin, Z. Zeltsan || kepeng.lkp@alibaba-inc.com, phil.hunt@oracle.com, vumip1@gmail.com, tonynad@microsoft.com, zachary.zeltsan@gmail.com +# RFC7643 || P. Hunt, Ed., K. Grizzle, E. Wahlstroem, C. Mortimore || phil.hunt@yahoo.com, kelly.grizzle@sailpoint.com, erik.wahlstrom@nexusgroup.com, cmortimore@salesforce.com +# RFC7644 || P. Hunt, Ed., K. Grizzle, M. Ansari, E. Wahlstroem, C. Mortimore || phil.hunt@yahoo.com, kelly.grizzle@sailpoint.com, morteza.ansari@cisco.com, erik.wahlstrom@nexusgroup.com, cmortimore@salesforce.com +# RFC7645 || U. Chunduri, A. Tian, W. Lu || uma.chunduri@ericsson.com, albert.tian@ericsson.com, wenhu.lu@ericsson.com +# RFC7646 || P. Ebersman, W. Kumari, C. Griffiths, J. Livingood, R. Weber || ebersman-ietf@dragon.net, warren@kumari.net, cgriffiths@gmail.com, jason_livingood@cable.comcast.com, ralf.weber@nominum.com +# RFC7647 || R. Sparks, A.B. Roach || rjsparks@nostrum.com, adam@nostrum.com +# RFC7648 || S. Perreault, M. Boucadair, R. Penno, D. Wing, S. Cheshire || sperreault@jive.com, mohamed.boucadair@orange.com, repenno@cisco.com, dwing-ietf@fuggles.com, cheshire@apple.com +# RFC7649 || P. Saint-Andre, D. York || peter@andyet.com, york@isoc.org +# RFC7650 || J. Jimenez, J. Lopez-Vega, J. Maenpaa, G. Camarillo || jaime.jimenez@ericsson.com, jmlvega@ugr.es, jouni.maenpaa@ericsson.com, gonzalo.camarillo@ericsson.com +# RFC7651 || A. Dodd-Noble, S. Gundavelli, J. Korhonen, F. Baboescu, B. Weis || noblea@cisco.com, sgundave@cisco.com, jouni.nospam@gmail.com, baboescu@broadcom.com, bew@cisco.com +# RFC7652 || M. Cullen, S. Hartman, D. Zhang, T. Reddy || margaret@painless-security.com, hartmans@painless-security.com, zhang_dacheng@hotmail.com, tireddy@cisco.com +# RFC7653 || D. Raghuvanshi, K. Kinnear, D. Kukrety || draghuva@cisco.com, kkinnear@cisco.com, dkukrety@cisco.com +# RFC7654 || S. Banks, F. Calabria, G. Czirjak, R. Machat || sbanks@encrypted.net, fcalabri@cisco.com, gczirjak@juniper.net, rmachat@juniper.net +# RFC7655 || M. Ramalho, Ed., P. Jones, N. Harada, M. Perumal, L. Miao || mramalho@cisco.com, paulej@packetizer.com, harada.noboru@lab.ntt.co.jp, muthu.arul@gmail.com, lei.miao@huawei.com +# RFC7656 || J. Lennox, K. Gross, S. Nandakumar, G. Salgueiro, B. Burman, Ed. || jonathan@vidyo.com, kevin.gross@avanw.com, snandaku@cisco.com, gsalguei@cisco.com, bo.burman@ericsson.com +# RFC7657 || D. Black, Ed., P. Jones || david.black@emc.com, paulej@packetizer.com +# RFC7658 || S. Perreault, T. Tsou, S. Sivakumar, T. Taylor || sperreault@jive.com, tina.tsou.zouting@huawei.com, ssenthil@cisco.com, tom.taylor.stds@gmail.com +# RFC7659 || S. Perreault, T. Tsou, S. Sivakumar, T. Taylor || sperreault@jive.com, tina.tsou.zouting@huawei.com, ssenthil@cisco.com, tom.taylor.stds@gmail.com +# RFC7660 || L. Bertz, S. Manning, B. Hirschman || lyleb551144@gmail.com, sergem913@gmail.com, Brent.Hirschman@gmail.com +# RFC7661 || G. Fairhurst, A. Sathiaseelan, R. Secchi || gorry@erg.abdn.ac.uk, arjuna@erg.abdn.ac.uk, raffaello@erg.abdn.ac.uk +# RFC7662 || J. Richer, Ed. || ietf@justin.richer.org +# RFC7663 || B. Trammell, Ed., M. Kuehlewind, Ed. || ietf@trammell.ch, mirja.kuehlewind@tik.ee.ethz.ch +# RFC7664 || D. Harkins, Ed. || dharkins@arubanetworks.com +# RFC7665 || J. Halpern, Ed., C. Pignataro, Ed. || jmh@joelhalpern.com, cpignata@cisco.com +# RFC7666 || H. Asai, M. MacFaden, J. Schoenwaelder, K. Shima, T. Tsou || panda@hongo.wide.ad.jp, mrm@vmware.com, j.schoenwaelder@jacobs-university.de, keiichi@iijlab.net, tina.tsou.zouting@huawei.com +# RFC7667 || M. Westerlund, S. Wenger || magnus.westerlund@ericsson.com, stewe@stewe.org +# RFC7668 || J. Nieminen, T. Savolainen, M. Isomaki, B. Patil, Z. Shelby, C. Gomez || johannamaria.nieminen@gmail.com, teemu.savolainen@nokia.com, markus.isomaki@nokia.com, basavaraj.patil@att.com, zach.shelby@arm.com, carlesgo@entel.upc.edu +# RFC7669 || J. Levine || standards@taugh.com +# RFC7670 || T. Kivinen, P. Wouters, H. Tschofenig || kivinen@iki.fi, pwouters@redhat.com, Hannes.Tschofenig@gmx.net +# RFC7671 || V. Dukhovni, W. Hardaker || ietf-dane@dukhovni.org, ietf@hardakers.net +# RFC7672 || V. Dukhovni, W. Hardaker || ietf-dane@dukhovni.org, ietf@hardakers.net +# RFC7673 || T. Finch, M. Miller, P. Saint-Andre || dot@dotat.at, mamille2@cisco.com, peter@andyet.com +# RFC7674 || J. Haas, Ed. || jhaas@juniper.net +# RFC7675 || M. Perumal, D. Wing, R. Ravindranath, T. Reddy, M. Thomson || muthu.arul@gmail.com, dwing-ietf@fuggles.com, rmohanr@cisco.com, tireddy@cisco.com, martin.thomson@gmail.com +# RFC7676 || C. Pignataro, R. Bonica, S. Krishnan || cpignata@cisco.com, rbonica@juniper.net, suresh.krishnan@ericsson.com +# RFC7677 || T. Hansen || tony+scramsha256@maillennium.att.com +# RFC7678 || C. Zhou, T. Taylor, Q. Sun, M. Boucadair || cathy.zhou@huawei.com, tom.taylor.stds@gmail.com, sunqiong@ctbri.com.cn, mohamed.boucadair@orange.com +# RFC7679 || G. Almes, S. Kalidindi, M. Zekauskas, A. Morton, Ed. || almes@acm.org, skalidindi@ixiacom.com, matt@internet2.edu, acmorton@att.com +# RFC7680 || G. Almes, S. Kalidindi, M. Zekauskas, A. Morton, Ed. || almes@acm.org, skalidindi@ixiacom.com, matt@internet2.edu, acmorton@att.com +# RFC7681 || J. Davin || info@eesst.org +# RFC7682 || D. McPherson, S. Amante, E. Osterweil, L. Blunk, D. Mitchell || dmcpherson@verisign.com, amante@apple.com, eosterweil@verisign.com, ljb@merit.edu, dave@singularity.cx +# RFC7683 || J. Korhonen, Ed., S. Donovan, Ed., B. Campbell, L. Morand || jouni.nospam@gmail.com, srdonovan@usdonovans.com, ben@nostrum.com, lionel.morand@orange.com +# RFC7684 || P. Psenak, H. Gredler, R. Shakir, W. Henderickx, J. Tantsura, A. Lindem || ppsenak@cisco.com, hannes@gredler.at, rjs@rob.sh, wim.henderickx@alcatel-lucent.com, jeff.tantsura@ericsson.com, acee@cisco.com +# RFC7685 || A. Langley || agl@google.com +# RFC7686 || J. Appelbaum, A. Muffett || jacob@appelbaum.net, alecm@fb.com +# RFC7687 || S. Farrell, R. Wenning, B. Bos, M. Blanchet, H. Tschofenig || stephen.farrell@cs.tcd.ie, rigo@w3.org, bert@w3.org, Marc.Blanchet@viagenie.ca, Hannes.Tschofenig@gmx.net +# RFC7688 || Y. Lee, Ed., G. Bernstein, Ed. || leeyoung@huawei.com, gregb@grotto-networking.com +# RFC7689 || G. Bernstein, Ed., S. Xu, Y. Lee, Ed., G. Martinelli, H. Harai || gregb@grotto-networking.com, xsg@nict.go.jp, leeyoung@huawei.com, giomarti@cisco.com, harai@nict.go.jp +# RFC7690 || M. Byerly, M. Hite, J. Jaeggli || suckawha@gmail.com, mhite@hotmail.com, joelja@gmail.com +# RFC7691 || S. Bradner, Ed. || sob@harvard.edu +# RFC7692 || T. Yoshino || tyoshino@google.com +# RFC7693 || M-J. Saarinen, Ed., J-P. Aumasson || m.saarinen@qub.ac.uk, jean-philippe.aumasson@nagra.com +# RFC7694 || J. Reschke || julian.reschke@greenbytes.de +# RFC7695 || P. Pfister, B. Paterson, J. Arkko || pierre.pfister@darou.fr, paterson.b@gmail.com, jari.arkko@piuha.net +# RFC7696 || R. Housley || housley@vigilsec.com +# RFC7697 || P. Pan, S. Aldrin, M. Venkatesan, K. Sampath, T. Nadeau, S. Boutros || none, aldrin.ietf@gmail.com, venkat.mahalingams@gmail.com, kannankvs@gmail.com, tnadeau@lucidvision.com, sboutros@vmware.com +# RFC7698 || O. Gonzalez de Dios, Ed., R. Casellas, Ed., F. Zhang, X. Fu, D. Ceccarelli, I. Hussain || oscar.gonzalezdedios@telefonica.com, ramon.casellas@cttc.es, zhangfatai@huawei.com, fu.xihua@stairnote.com, daniele.ceccarelli@ericsson.com, ihussain@infinera.com +# RFC7699 || A. Farrel, D. King, Y. Li, F. Zhang || adrian@olddog.co.uk, daniel@olddog.co.uk, wsliguotou@hotmail.com, zhangfatai@huawei.com +# RFC7700 || P. Saint-Andre || peter@andyet.com +# RFC7701 || A. Niemi, M. Garcia-Martin, G. Sandbakken || aki.niemi@iki.fi, miguel.a.garcia@ericsson.com, geirsand@cisco.com +# RFC7702 || P. Saint-Andre, S. Ibarra, S. Loreto || peter@andyet.com, saul@ag-projects.com, Salvatore.Loreto@ericsson.com +# RFC7703 || E. Cordeiro, R. Carnier, A. Moreiras || edwin@scordeiro.net, rodrigocarnier@gmail.com, moreiras@nic.br +# RFC7704 || D. Crocker, N. Clark || dcrocker@bbiw.net, narelle.clark@pavonis.com.au +# RFC7705 || W. George, S. Amante || wesley.george@twcable.com, amante@apple.com +# RFC7706 || W. Kumari, P. Hoffman || warren@kumari.net, paul.hoffman@icann.org +# RFC7707 || F. Gont, T. Chown || fgont@si6networks.com, tim.chown@jisc.ac.uk +# RFC7708 || T. Nadeau, L. Martini, S. Bryant || tnadeau@lucidvision.com, lmartini@cisco.com, stewart.bryant@gmail.com +# RFC7709 || A. Malis, Ed., B. Wilson, G. Clapp, V. Shukla || agmalis@gmail.com, bwilson@appcomsci.com, clapp@research.att.com, vishnu.shukla@verizon.com +# RFC7710 || W. Kumari, O. Gudmundsson, P. Ebersman, S. Sheng || warren@kumari.net, olafur@cloudflare.com, ebersman-ietf@dragon.net, steve.sheng@icann.org +# RFC7711 || M. Miller, P. Saint-Andre || mamille2@cisco.com, peter@andyet.com +# RFC7712 || P. Saint-Andre, M. Miller, P. Hancke || peter@andyet.com, mamille2@cisco.com, fippo@andyet.com +# RFC7713 || M. Mathis, B. Briscoe || mattmathis@google.com, ietf@bobbriscoe.net +# RFC7714 || D. McGrew, K. Igoe || mcgrew@cisco.com, mythicalkevin@yahoo.com +# RFC7715 || IJ. Wijnands, Ed., K. Raza, A. Atlas, J. Tantsura, Q. Zhao || ice@cisco.com, skraza@cisco.com, akatlas@juniper.net, jeff.tantsura@ericsson.com, quintin.zhao@huawei.com +# RFC7716 || J. Zhang, L. Giuliano, E. Rosen, Ed., K. Subramanian, D. Pacella || zzhang@juniper.net, lenny@juniper.net, erosen@juniper.net, kartsubr@cisco.com, dante.j.pacella@verizonbusiness.com +# RFC7717 || K. Pentikousis, Ed., E. Zhang, Y. Cui || k.pentikousis@eict.de, emma.zhanglijia@huawei.com, cuiyang@huawei.com +# RFC7718 || A. Morton || acmorton@att.com +# RFC7719 || P. Hoffman, A. Sullivan, K. Fujiwara || paul.hoffman@icann.org, asullivan@dyn.com, fujiwara@jprs.co.jp +# RFC7720 || M. Blanchet, L-J. Liman || Marc.Blanchet@viagenie.ca, liman@netnod.se +# RFC7721 || A. Cooper, F. Gont, D. Thaler || alcoop@cisco.com, fgont@si6networks.com, dthaler@microsoft.com +# RFC7722 || C. Dearlove, T. Clausen || chris.dearlove@baesystems.com, T.Clausen@computer.org +# RFC7723 || S. Kiesel, R. Penno || ietf-pcp@skiesel.de, repenno@cisco.com +# RFC7724 || K. Kinnear, M. Stapp, B. Volz, N. Russell || kkinnear@cisco.com, mjs@cisco.com, volz@cisco.com, neil.e.russell@gmail.com +# RFC7725 || T. Bray || tbray@textuality.com +# RFC7726 || V. Govindan, K. Rajaraman, G. Mirsky, N. Akiya, S. Aldrin || venggovi@cisco.com, kalyanir@cisco.com, gregory.mirsky@ericsson.com, nobo.akiya.dev@gmail.com, aldrin.ietf@gmail.com +# RFC7727 || M. Zhang, H. Wen, J. Hu || zhangmingui@huawei.com, wenhuafeng@huawei.com, hujie@ctbri.com.cn +# RFC7728 || B. Burman, A. Akram, R. Even, M. Westerlund || bo.burman@ericsson.com, akram.muhammadazam@gmail.com, roni.even@mail01.huawei.com, magnus.westerlund@ericsson.com +# RFC7729 || B. Khasnabish, E. Haleplidis, J. Hadi Salim, Ed. || vumip1@gmail.com, ehalep@ece.upatras.gr, hadi@mojatatu.com +# RFC7730 || G. Huston, S. Weiler, G. Michaelson, S. Kent || gih@apnic.net, weiler@tislabs.com, ggm@apnic.net, kent@bbn.com +# RFC7731 || J. Hui, R. Kelsey || jonhui@nestlabs.com, richard.kelsey@silabs.com +# RFC7732 || P. van der Stok, R. Cragie || consultancy@vanderstok.org, robert.cragie@arm.com +# RFC7733 || A. Brandt, E. Baccelli, R. Cragie, P. van der Stok || anders_brandt@sigmadesigns.com, Emmanuel.Baccelli@inria.fr, robert.cragie@arm.com, consultancy@vanderstok.org +# RFC7734 || D. Allan, Ed., J. Tantsura, D. Fedyk, A. Sajassi || david.i.allan@ericsson.com, jeff.tantsura@ericsson.com, don.fedyk@hpe.com, sajassi@cisco.com +# RFC7735 || R. Sparks, T. Kivinen || rjsparks@nostrum.com, kivinen@iki.fi +# RFC7736 || K. Ma || kevin.j.ma@ericsson.com +# RFC7737 || N. Akiya, G. Swallow, C. Pignataro, L. Andersson, M. Chen || nobo.akiya.dev@gmail.com, swallow@cisco.com, cpignata@cisco.com, loa@mail01.huawei.com, mach.chen@huawei.com +# RFC7738 || M. Blanchet, A. Schiltknecht, P. Shames || Marc.Blanchet@viagenie.ca, audric.schiltknecht@viagenie.ca, peter.m.shames@jpl.nasa.gov +# RFC7739 || F. Gont || fgont@si6networks.com +# RFC7740 || Z. Zhang, Y. Rekhter, A. Dolganow || zzhang@juniper.net, none, andrew.dolganow@alcatel-lucent.com +# RFC7741 || P. Westin, H. Lundin, M. Glover, J. Uberti, F. Galligan || patrik.westin@gmail.com, hlundin@google.com, michaelglover262@gmail.com, justin@uberti.name, fgalligan@google.com +# RFC7742 || A.B. Roach || adam@nostrum.com +# RFC7743 || J. Luo, Ed., L. Jin, Ed., T. Nadeau, Ed., G. Swallow, Ed. || luo.jian@zte.com.cn, lizho.jin@gmail.com, tnadeau@lucidvision.com, swallow@cisco.com +# RFC7744 || L. Seitz, Ed., S. Gerdes, Ed., G. Selander, M. Mani, S. Kumar || ludwig@sics.se, gerdes@tzi.org, goran.selander@ericsson.com, mehdi.mani@itron.com, sandeep.kumar@philips.com +# RFC7745 || T. Manderson || terry.manderson@icann.org +# RFC7746 || R. Bonica, I. Minei, M. Conn, D. Pacella, L. Tomotaki || rbonica@juniper.net, inaminei@google.com, meconn26@gmail.com, dante.j.pacella@verizon.com, luis.tomotaki@verizon.com +# RFC7747 || R. Papneja, B. Parise, S. Hares, D. Lee, I. Varlashkin || rajiv.papneja@huawei.com, bparise@skyportsystems.com, shares@ndzh.com, dlee@ixiacom.com, ilya@nobulus.com +# RFC7748 || A. Langley, M. Hamburg, S. Turner || agl@google.com, mike@shiftleft.org, sean@sn3rd.com +# RFC7749 || J. Reschke || julian.reschke@greenbytes.de +# RFC7750 || J. Hedin, G. Mirsky, S. Baillargeon || jonas.hedin@ericsson.com, gregory.mirsky@ericsson.com, steve.baillargeon@ericsson.com +# RFC7751 || S. Sorce, T. Yu || ssorce@redhat.com, tlyu@mit.edu +# RFC7752 || H. Gredler, Ed., J. Medved, S. Previdi, A. Farrel, S. Ray || hannes@gredler.at, jmedved@cisco.com, sprevidi@cisco.com, adrian@olddog.co.uk, raysaikat@gmail.com +# RFC7753 || Q. Sun, M. Boucadair, S. Sivakumar, C. Zhou, T. Tsou, S. Perreault || sunqiong@ctbri.com.cn, mohamed.boucadair@orange.com, ssenthil@cisco.com, cathy.zhou@huawei.com, tina.tsou@philips.com, sperreault@jive.com +# RFC7754 || R. Barnes, A. Cooper, O. Kolkman, D. Thaler, E. Nordmark || rlb@ipv.sx, alcoop@cisco.com, kolkman@isoc.org, dthaler@microsoft.com, nordmark@arista.com +# RFC7755 || T. Anderson || tore@redpill-linpro.com +# RFC7756 || T. Anderson, S. Steffann || tore@redpill-linpro.com, sander@steffann.nl +# RFC7757 || T. Anderson, A. Leiva Popper || tore@redpill-linpro.com, ydahhrk@gmail.com +# RFC7758 || T. Mizrahi, Y. Moses || dew@tx.technion.ac.il, moses@ee.technion.ac.il +# RFC7759 || E. Bellagamba, G. Mirsky, L. Andersson, P. Skoldstrom, D. Ward, J. Drake || elisa.bellagamba@gmail.com, gregory.mirsky@ericsson.com, loa@mail01.huawei.com, pontus.skoldstrom@acreo.se, dward@cisco.com, jdrake@juniper.net +# RFC7760 || R. Housley || housley@vigilsec.com +# RFC7761 || B. Fenner, M. Handley, H. Holbrook, I. Kouvelas, R. Parekh, Z. Zhang, L. Zheng || fenner@arista.com, m.handley@cs.ucl.ac.uk, holbrook@arista.com, kouvelas@arista.com, riparekh@cisco.com, zzhang@juniper.net, vero.zheng@huawei.com +# RFC7762 || M. West || mkwst@google.com +# RFC7763 || S. Leonard || dev+ietf@seantek.com +# RFC7764 || S. Leonard || dev+ietf@seantek.com +# RFC7765 || P. Hurtig, A. Brunstrom, A. Petlund, M. Welzl || per.hurtig@kau.se, anna.brunstrom@kau.se, apetlund@simula.no, michawe@ifi.uio.no +# RFC7766 || J. Dickinson, S. Dickinson, R. Bellis, A. Mankin, D. Wessels || jad@sinodun.com, sara@sinodun.com, ray@isc.org, allison.mankin@gmail.com, dwessels@verisign.com +# RFC7767 || S. Vinapamula, S. Sivakumar, M. Boucadair, T. Reddy || sureshk@juniper.net, ssenthil@cisco.com, mohamed.boucadair@orange.com, tireddy@cisco.com +# RFC7768 || T. Tsou, W. Li, T. Taylor, J. Huang || tina.tsou@philips.com, mweiboli@gmail.com, tom.taylor.stds@gmail.com, james.huang@huawei.com +# RFC7769 || S. Sivabalan, S. Boutros, H. Shah, S. Aldrin, M. Venkatesan || msiva@cisco.com, sboutros@cisco.com, hshah@ciena.com, aldrin.ietf@gmail.com, mannan_venkatesan@cable.comcast.com +# RFC7770 || A. Lindem, Ed., N. Shen, JP. Vasseur, R. Aggarwal, S. Shaffer || acee@cisco.com, naiming@cisco.com, jpv@cisco.com, raggarwa_1@yahoo.com, sshaffer@akamai.com +# RFC7771 || A. Malis, Ed., L. Andersson, H. van Helvoort, J. Shin, L. Wang, A. D'Alessandro || agmalis@gmail.com, loa@mail01.huawei.com, huubatwork@gmail.com, jongyoon.shin@sk.com, wangleiyj@chinamobile.com, alessandro.dalessandro@telecomitalia.it +# RFC7772 || A. Yourtchenko, L. Colitti || ayourtch@cisco.com, lorenzo@google.com +# RFC7773 || S. Santesson || sts@aaa-sec.com +# RFC7774 || Y. Doi, M. Gillmore || yusuke.doi@toshiba.co.jp, matthew.gillmore@itron.com +# RFC7775 || L. Ginsberg, S. Litkowski, S. Previdi || ginsberg@cisco.com, stephane.litkowski@orange.com, sprevidi@cisco.com +# RFC7776 || P. Resnick, A. Farrel || presnick@qti.qualcomm.com, adrian@olddog.co.uk +# RFC7777 || S. Hegde, R. Shakir, A. Smirnov, Z. Li, B. Decraene || shraddha@juniper.net, rjs@rob.sh, as@cisco.com, lizhenbin@huawei.com, bruno.decraene@orange.com +# RFC7778 || D. Kutscher, F. Mir, R. Winter, S. Krishnan, Y. Zhang, CJ. Bernardos || kutscher@neclab.eu, faisal.mir@gmail.com, rolf.winter@neclab.eu, suresh.krishnan@ericsson.com, ying.zhang13@hp.com, cjbc@it.uc3m.es +# RFC7779 || H. Rogge, E. Baccelli || henning.rogge@fkie.fraunhofer.de, Emmanuel.Baccelli@inria.fr +# RFC7780 || D. Eastlake 3rd, M. Zhang, R. Perlman, A. Banerjee, A. Ghanwani, S. Gupta || d3e3e3@gmail.com, zhangmingui@huawei.com, radia@alum.mit.edu, ayabaner@cisco.com, anoop@alumni.duke.edu, sujay.gupta@ipinfusion.com +# RFC7781 || H. Zhai, T. Senevirathne, R. Perlman, M. Zhang, Y. Li || honjun.zhai@tom.com, tsenevir@gmail.com, radia@alum.mit.edu, zhangmingui@huawei.com, liyizhou@huawei.com +# RFC7782 || M. Zhang, R. Perlman, H. Zhai, M. Durrani, S. Gupta || zhangmingui@huawei.com, radia@alum.mit.edu, honjun.zhai@tom.com, mdurrani@cisco.com, sujay.gupta@ipinfusion.com +# RFC7783 || T. Senevirathne, J. Pathangi, J. Hudson || tsenevir@gmail.com, pathangi_janardhanan@dell.com, jon.hudson@gmail.com +# RFC7784 || D. Kumar, S. Salam, T. Senevirathne || dekumar@cisco.com, ssalam@cisco.com, tsenevir@gmail.com +# RFC7785 || S. Vinapamula, M. Boucadair || sureshk@juniper.net, mohamed.boucadair@orange.com +# RFC7786 || M. Kuehlewind, Ed., R. Scheffenegger || mirja.kuehlewind@tik.ee.ethz.ch, rs.ietf@gmx.at +# RFC7787 || M. Stenberg, S. Barth || markus.stenberg@iki.fi, cyrus@openwrt.org +# RFC7788 || M. Stenberg, S. Barth, P. Pfister || markus.stenberg@iki.fi, cyrus@openwrt.org, pierre.pfister@darou.fr +# RFC7789 || C. Cardona, P. Francois, P. Lucente || juancamilo.cardona@imdea.org, pifranco@cisco.com, plucente@cisco.com +# RFC7790 || Y. Yoneya, T. Nemoto || yoshiro.yoneya@jprs.co.jp, t.nemo10@kmd.keio.ac.jp +# RFC7791 || D. Migault, Ed., V. Smyslov || daniel.migault@ericsson.com, svan@elvis.ru +# RFC7792 || F. Zhang, X. Zhang, A. Farrel, O. Gonzalez de Dios, D. Ceccarelli || zhangfatai@huawei.com, zhang.xian@huawei.com, adrian@olddog.co.uk, oscar.gonzalezdedios@telefonica.com, daniele.ceccarelli@ericsson.com +# RFC7793 || M. Andrews || marka@isc.org +# RFC7794 || L. Ginsberg, Ed., B. Decraene, S. Previdi, X. Xu, U. Chunduri || ginsberg@cisco.com, bruno.decraene@orange.com, sprevidi@cisco.com, xuxiaohu@huawei.com, uma.chunduri@ericsson.com +# RFC7795 || J. Dong, H. Wang || jie.dong@huawei.com, rainsword.wang@huawei.com +# RFC7796 || Y. Jiang, Ed., L. Yong, M. Paul || jiangyuanlong@huawei.com, lucyyong@huawei.com, Manuel.Paul@telekom.de +# RFC7797 || M. Jones || mbj@microsoft.com +# RFC7798 || Y.-K. Wang, Y. Sanchez, T. Schierl, S. Wenger, M. M. Hannuksela || yekui.wang@gmail.com, yago.sanchez@hhi.fraunhofer.de, thomas.schierl@hhi.fraunhofer.de, stewe@stewe.org, miska.hannuksela@nokia.com +# RFC7799 || A. Morton || acmorton@att.com +# RFC7800 || M. Jones, J. Bradley, H. Tschofenig || mbj@microsoft.com, ve7jtb@ve7jtb.com, Hannes.Tschofenig@gmx.net +# RFC7801 || V. Dolmatov, Ed. || dol@srcc.msu.ru +# RFC7802 || S. Emery, N. Williams || shawn.emery@oracle.com, nico@cryptonector.com +# RFC7803 || B. Leiba || barryleiba@computer.org +# RFC7804 || A. Melnikov || alexey.melnikov@isode.com +# RFC7805 || A. Zimmermann, W. Eddy, L. Eggert || alexander@zimmermann.eu.com, wes@mti-systems.com, lars@netapp.com +# RFC7806 || F. Baker, R. Pan || fred@cisco.com, ropan@cisco.com +# RFC7807 || M. Nottingham, E. Wilde || mnot@mnot.net, erik.wilde@dret.net +# RFC7808 || M. Douglass, C. Daboo || mdouglass@sphericalcowgroup.com, cyrus@daboo.name +# RFC7809 || C. Daboo || cyrus@daboo.name +# RFC7810 || S. Previdi, Ed., S. Giacalone, D. Ward, J. Drake, Q. Wu || sprevidi@cisco.com, spencer.giacalone@gmail.com, wardd@cisco.com, jdrake@juniper.net, sunseawq@huawei.com +# RFC7811 || G. Enyedi, A. Csaszar, A. Atlas, C. Bowers, A. Gopalan || Gabor.Sandor.Enyedi@ericsson.com, Andras.Csaszar@ericsson.com, akatlas@juniper.net, cbowers@juniper.net, abishek@ece.arizona.edu +# RFC7812 || A. Atlas, C. Bowers, G. Enyedi || akatlas@juniper.net, cbowers@juniper.net, Gabor.Sandor.Enyedi@ericsson.com +# RFC7813 || J. Farkas, Ed., N. Bragg, P. Unbehagen, G. Parsons, P. Ashwood-Smith, C. Bowers || janos.farkas@ericsson.com, nbragg@ciena.com, unbehagen@avaya.com, glenn.parsons@ericsson.com, Peter.AshwoodSmith@huawei.com, cbowers@juniper.net +# RFC7814 || X. Xu, C. Jacquenet, R. Raszuk, T. Boyes, B. Fee || xuxiaohu@huawei.com, christian.jacquenet@orange.com, robert@raszuk.net, tboyes@bloomberg.net, bfee@extremenetworks.com +# RFC7815 || T. Kivinen || kivinen@iki.fi +# RFC7816 || S. Bortzmeyer || bortzmeyer+ietf@nic.fr +# RFC7817 || A. Melnikov || alexey.melnikov@isode.com +# RFC7818 || M. Jethanandani || mjethanandani@gmail.com +# RFC7819 || S. Jiang, S. Krishnan, T. Mrugalski || jiangsheng@huawei.com, suresh.krishnan@ericsson.com, tomasz.mrugalski@gmail.com +# RFC7820 || T. Mizrahi || talmi@marvell.com +# RFC7821 || T. Mizrahi || talmi@marvell.com +# RFC7822 || T. Mizrahi, D. Mayer || talmi@marvell.com, mayer@ntp.org +# RFC7823 || A. Atlas, J. Drake, S. Giacalone, S. Previdi || akatlas@juniper.net, jdrake@juniper.net, spencer.giacalone@gmail.com, sprevidi@cisco.com +# RFC7824 || S. Krishnan, T. Mrugalski, S. Jiang || suresh.krishnan@ericsson.com, tomasz.mrugalski@gmail.com, jiangsheng@huawei.com +# RFC7825 || J. Goldberg, M. Westerlund, T. Zeng || jgoldber@cisco.com, magnus.westerlund@ericsson.com, thomas.zeng@gmail.com +# RFC7826 || H. Schulzrinne, A. Rao, R. Lanphier, M. Westerlund, M. Stiemerling, Ed. || schulzrinne@cs.columbia.edu, anrao@cisco.com, robla@robla.net, magnus.westerlund@ericsson.com, mls.ietf@gmail.com +# RFC7827 || L. Eggert || lars@netapp.com +# RFC7828 || P. Wouters, J. Abley, S. Dickinson, R. Bellis || pwouters@redhat.com, jabley@dyn.com, sara@sinodun.com, ray@isc.org +# RFC7829 || Y. Nishida, P. Natarajan, A. Caro, P. Amer, K. Nielsen || nishida@wide.ad.jp, prenatar@cisco.com, acaro@bbn.com, amer@udel.edu, karen.nielsen@tieto.com +# RFC7830 || A. Mayrhofer || alex.mayrhofer.ietf@gmail.com +# RFC7831 || J. Howlett, S. Hartman, H. Tschofenig, J. Schaad || josh.howlett@ja.net, hartmans-ietf@mit.edu, Hannes.Tschofenig@gmx.net, ietf@augustcellars.com +# RFC7832 || R. Smith, Ed. || rhys.smith@jisc.ac.uk +# RFC7833 || J. Howlett, S. Hartman, A. Perez-Mendez, Ed. || josh.howlett@ja.net, hartmans-ietf@mit.edu, alex@um.es +# RFC7834 || D. Saucez, L. Iannone, A. Cabellos, F. Coras || damien.saucez@inria.fr, ggx@gigix.net, acabello@ac.upc.edu, fcoras@ac.upc.edu +# RFC7835 || D. Saucez, L. Iannone, O. Bonaventure || damien.saucez@inria.fr, ggx@gigix.net, Olivier.Bonaventure@uclouvain.be +# RFC7836 || S. Smyshlyaev, Ed., E. Alekseev, I. Oshkin, V. Popov, S. Leontiev, V. Podobaev, D. Belyavsky || svs@cryptopro.ru, alekseev@cryptopro.ru, oshkin@cryptopro.ru, vpopov@cryptopro.ru, lse@CryptoPro.ru, v_podobaev@factor-ts.ru, beldmit@gmail.com +# RFC7837 || S. Krishnan, M. Kuehlewind, B. Briscoe, C. Ralli || suresh.krishnan@ericsson.com, mirja.kuehlewind@tik.ee.ethz.ch, ietf@bobbriscoe.net, ralli@tid.es +# RFC7838 || M. Nottingham, P. McManus, J. Reschke || mnot@mnot.net, mcmanus@ducksong.com, julian.reschke@greenbytes.de +# RFC7839 || S. Bhandari, S. Gundavelli, M. Grayson, B. Volz, J. Korhonen || shwethab@cisco.com, sgundave@cisco.com, mgrayson@cisco.com, volz@cisco.com, jouni.nospam@gmail.com +# RFC7840 || J. Winterbottom, H. Tschofenig, L. Liess || a.james.winterbottom@gmail.com, Hannes.Tschofenig@gmx.net, L.Liess@telekom.de +# RFC7841 || J. Halpern, Ed., L. Daigle, Ed., O. Kolkman, Ed. || jmh@joelhalpern.com, ldaigle@thinkingcat.com, kolkman@isoc.org +# RFC7842 || R. Sparks || rjsparks@nostrum.com +# RFC7843 || A. Ripke, R. Winter, T. Dietz, J. Quittek, R. da Silva || ripke@neclab.eu, winter@neclab.eu, dietz@neclab.eu, quittek@neclab.eu, rafaelalejandro.lopezdasilva@telefonica.com +# RFC7844 || C. Huitema, T. Mrugalski, S. Krishnan || huitema@microsoft.com, tomasz.mrugalski@gmail.com, suresh.krishnan@ericsson.com +# RFC7845 || T. Terriberry, R. Lee, R. Giles || tterribe@xiph.org, ron@debian.org, giles@xiph.org +# RFC7846 || R. Cruz, M. Nunes, J. Xia, R. Huang, Ed., J. Taveira, D. Lingli || rui.cruz@ieee.org, mario.nunes@inov.pt, xiajinwei@huawei.com, rachel.huang@huawei.com, joao.silva@inov.pt, denglingli@chinamobile.com +# RFC7847 || T. Melia, Ed., S. Gundavelli, Ed. || telemaco.melia@gmail.com, sgundave@cisco.com +# RFC7848 || G. Lozano || gustavo.lozano@icann.org +# RFC7849 || D. Binet, M. Boucadair, A. Vizdal, G. Chen, N. Heatley, R. Chandler, D. Michaud, D. Lopez, W. Haeffner || david.binet@orange.com, mohamed.boucadair@orange.com, Ales.Vizdal@T-Mobile.cz, phdgang@gmail.com, nick.heatley@ee.co.uk, ross@eircom.net, dave.michaud@rci.rogers.com, diego.r.lopez@telefonica.com, walter.haeffner@vodafone.com +# RFC7850 || S. Nandakumar || snandaku@cisco.com +# RFC7851 || H. Song, X. Jiang, R. Even, D. Bryan, Y. Sun || haibin.song@huawei.com, jiangxingfeng@huawei.com, ron.even.tlv@gmail.com, dbryan@ethernot.org, sunyi@ict.ac.cn +# RFC7852 || R. Gellens, B. Rosen, H. Tschofenig, R. Marshall, J. Winterbottom || rg+ietf@randy.pensive.org, br@brianrosen.net, Hannes.Tschofenig@gmx.net, rmarshall@telecomsys.com, a.james.winterbottom@gmail.com +# RFC7853 || S. Martin, S. Tuecke, B. McCollam, M. Lidman || sjmartin@uchicago.edu, tuecke@globus.org, bmccollam@uchicago.edu, mattias@uchicago.edu< +# RFC7854 || J. Scudder, Ed., R. Fernando, S. Stuart || jgs@juniper.net, rex@cisco.com, sstuart@google.com +# RFC7855 || S. Previdi, Ed., C. Filsfils, Ed., B. Decraene, S. Litkowski, M. Horneffer, R. Shakir || sprevidi@cisco.com, cfilsfil@cisco.com, bruno.decraene@orange.com, stephane.litkowski@orange.com, Martin.Horneffer@telekom.de, rjs@rob.sh +# RFC7856 || Y. Cui, J. Dong, P. Wu, M. Xu, A. Yla-Jaaski || yong@csnet1.cs.tsinghua.edu.cn, knight.dongjiang@gmail.com, weapon9@gmail.com, xmw@cernet.edu.cn, antti.yla-jaaski@aalto.fi +# RFC7857 || R. Penno, S. Perreault, M. Boucadair, Ed., S. Sivakumar, K. Naito || repenno@cisco.com, sperreault@jive.com, mohamed.boucadair@orange.com, ssenthil@cisco.com, k.naito@nttv6.jp +# RFC7858 || Z. Hu, L. Zhu, J. Heidemann, A. Mankin, D. Wessels, P. Hoffman || zihu@outlook.com, liangzhu@usc.edu, johnh@isi.edu, allison.mankin@gmail.com, dwessels@verisign.com, paul.hoffman@icann.org +# RFC7859 || C. Dearlove || chris.dearlove@baesystems.com +# RFC7860 || J. Merkle, Ed., M. Lochter || johannes.merkle@secunet.com, manfred.lochter@bsi.bund.de +# RFC7861 || A. Adamson, N. Williams || andros@netapp.com, nico@cryptonector.com +# RFC7862 || T. Haynes || thomas.haynes@primarydata.com +# RFC7863 || T. Haynes || thomas.haynes@primarydata.com +# RFC7864 || CJ. Bernardos, Ed. || cjbc@it.uc3m.es +# RFC7865 || R. Ravindranath, P. Ravindran, P. Kyzivat || rmohanr@cisco.com, partha@parthasarathi.co.in, pkyzivat@alum.mit.edu +# RFC7866 || L. Portman, H. Lum, Ed., C. Eckel, A. Johnston, A. Hutton || leon.portman@gmail.com, henry.lum@genesyslab.com, eckelcu@cisco.com, alan.b.johnston@gmail.com, andrew.hutton@unify.com +# RFC7867 || R. Huang || rachel.huang@huawei.com +# RFC7868 || D. Savage, J. Ng, S. Moore, D. Slice, P. Paluch, R. White || dsavage@cisco.com, jamng@cisco.com, smoore@cisco.com, dslice@cumulusnetworks.com, peter.paluch@fri.uniza.sk, russ@riw.us +# RFC7869 || D. Warden, I. Iordanov || david_warden@dell.com, iiordanov@gmail.com +# RFC7870 || Y. Fu, S. Jiang, J. Dong, Y. Chen || fuyu@cnnic.cn, jiangsheng@huawei.com, knight.dongjiang@gmail.com, flashfoxmx@gmail.com +# RFC7871 || C. Contavalli, W. van der Gaast, D. Lawrence, W. Kumari || ccontavalli@google.com, wilmer@google.com, tale@akamai.com, warren@kumari.net +# RFC7872 || F. Gont, J. Linkova, T. Chown, W. Liu || fgont@si6networks.com, furry@google.com, tim.chown@jisc.ac.uk, liushucheng@huawei.com +# RFC7873 || D. Eastlake 3rd, M. Andrews || d3e3e3@gmail.com, marka@isc.org +# RFC7874 || JM. Valin, C. Bran || jmvalin@jmvalin.ca, cary.bran@plantronics.com +# RFC7875 || S. Proust, Ed. || stephane.proust@orange.com +# RFC7876 || S. Bryant, S. Sivabalan, S. Soni || stewart.bryant@gmail.com, msiva@cisco.com, sagsoni@cisco.com +# RFC7877 || K. Cartwright, V. Bhatia, S. Ali, D. Schwartz || kcartwright@tnsi.com, vbhatia@tnsi.com, syed.ali@neustar.biz, dschwartz@xconnect.net +# RFC7878 || K. Cartwright, V. Bhatia, J-F. Mule, A. Mayrhofer || kcartwright@tnsi.com, vbhatia@tnsi.com, jfmule@apple.com, alexander.mayrhofer@nic.at +# RFC7879 || R. Ravindranath, T. Reddy, G. Salgueiro, V. Pascual, P. Ravindran || rmohanr@cisco.com, tireddy@cisco.com, gsalguei@cisco.com, victor.pascual.avila@oracle.com, partha@parthasarathi.co.in +# RFC7880 || C. Pignataro, D. Ward, N. Akiya, M. Bhatia, S. Pallagatti || cpignata@cisco.com, wardd@cisco.com, nobo.akiya.dev@gmail.com, manav@ionosnetworks.com, santosh.pallagatti@gmail.com +# RFC7881 || C. Pignataro, D. Ward, N. Akiya || cpignata@cisco.com, wardd@cisco.com, nobo.akiya.dev@gmail.com +# RFC7882 || S. Aldrin, C. Pignataro, G. Mirsky, N. Kumar || aldrin.ietf@gmail.com, cpignata@cisco.com, gregory.mirsky@ericsson.com, naikumar@cisco.com +# RFC7883 || L. Ginsberg, N. Akiya, M. Chen || ginsberg@cisco.com, nobo.akiya.dev@gmail.com, mach.chen@huawei.com +# RFC7884 || C. Pignataro, M. Bhatia, S. Aldrin, T. Ranganath || cpignata@cisco.com, manav@ionosnetworks.com, aldrin.ietf@gmail.com, trilok.ranganatha@nokia.com +# RFC7885 || V. Govindan, C. Pignataro || venggovi@cisco.com, cpignata@cisco.com +# RFC7886 || V. Govindan, C. Pignataro || venggovi@cisco.com, cpignata@cisco.com +# RFC7887 || S. Venaas, J. Arango, I. Kouvelas || stig@cisco.com, jearango@cisco.com, kouvelas@arista.com +# RFC7888 || A. Melnikov, Ed. || alexey.melnikov@isode.com +# RFC7889 || J. SrimushnamBoovaraghamoorthy, N. Bisht || jayantheesh.sb@gmail.com, narendrasingh.bisht@gmail.com +# RFC7890 || D. Bryan, P. Matthews, E. Shim, D. Willis, S. Dawkins || dbryan@ethernot.org, philip_matthews@magma.ca, eunsooshim@gmail.com, dean.willis@softarmor.com, spencerdawkins.ietf@gmail.com +# RFC7891 || J. Asghar, IJ. Wijnands, Ed., S. Krishnaswamy, A. Karan, V. Arya || jasghar@cisco.com, ice@cisco.com, sowkrish@cisco.com, apoorva@cisco.com, varya@directv.com +# RFC7892 || Z. Ali, A. Bonfanti, M. Hartley, F. Zhang || zali@cisco.com, abonfant@cisco.com, mhartley@cisco.com, zhangfatai@huawei.com +# RFC7893 || Y(J) Stein, D. Black, B. Briscoe || yaakov_s@rad.com, david.black@emc.com, ietf@bobbriscoe.net +# RFC7894 || M. Pritikin, C. Wallace || pritikin@cisco.com, carl@redhoundsoftware.com +# RFC7895 || A. Bierman, M. Bjorklund, K. Watsen || andy@yumaworks.com, mbj@tail-f.com, kwatsen@juniper.net +# RFC7896 || D. Dhody || dhruv.ietf@gmail.com +# RFC7897 || D. Dhody, U. Palle, R. Casellas || dhruv.ietf@gmail.com, udayasree.palle@huawei.com, ramon.casellas@cttc.es +# RFC7898 || D. Dhody, U. Palle, V. Kondreddy, R. Casellas || dhruv.ietf@gmail.com, udayasree.palle@huawei.com, venugopalreddyk@huawei.com, ramon.casellas@cttc.es +# RFC7899 || T. Morin, Ed., S. Litkowski, K. Patel, Z. Zhang, R. Kebler, J. Haas || thomas.morin@orange.com, stephane.litkowski@orange.com, keyupate@cisco.com, zzhang@juniper.net, rkebler@juniper.net, jhaas@juniper.net +# RFC7900 || Y. Rekhter, Ed., E. Rosen, Ed., R. Aggarwal, Y. Cai, T. Morin || none, erosen@juniper.net, raggarwa_1@yahoo.com, yiqun.cai@alibaba-inc.com, thomas.morin@orange.com +# RFC7901 || P. Wouters || pwouters@redhat.com +# RFC7902 || E. Rosen, T. Morin || erosen@juniper.net, thomas.morin@orange.com +# RFC7903 || S. Leonard || dev+ietf@seantek.com +# RFC7904 || C. Jennings, B. Lowekamp, E. Rescorla, S. Baset, H. Schulzrinne, T. Schmidt, Ed. || fluffy@cisco.com, bbl@lowekamp.net, ekr@rtfm.com, sabaset@us.ibm.com, hgs@cs.columbia.edu, t.schmidt@haw-hamburg.de +# RFC7905 || A. Langley, W. Chang, N. Mavrogiannopoulos, J. Strombergson, S. Josefsson || agl@google.com, wtc@google.com, nmav@redhat.com, joachim@secworks.se, simon@josefsson.org +# RFC7906 || P. Timmel, R. Housley, S. Turner || pstimme@nsa.gov, housley@vigilsec.com, turners@ieca.com +# RFC7908 || K. Sriram, D. Montgomery, D. McPherson, E. Osterweil, B. Dickson || ksriram@nist.gov, dougm@nist.gov, dmcpherson@verisign.com, eosterweil@verisign.com, brian.peter.dickson@gmail.com +# RFC7909 || R. Kisteleki, B. Haberman || robert@ripe.net, brian@innovationslab.net +# RFC7910 || W. Zhou || zhouweiisu@gmail.com +# RFC7911 || D. Walton, A. Retana, E. Chen, J. Scudder || dwalton@cumulusnetworks.com, aretana@cisco.com, enkechen@cisco.com, jgs@juniper.net +# RFC7912 || A. Melnikov || alexey.melnikov@isode.com +# RFC7913 || C. Holmberg || christer.holmberg@ericsson.com +# RFC7914 || C. Percival, S. Josefsson || cperciva@tarsnap.com, simon@josefsson.org +# RFC7915 || C. Bao, X. Li, F. Baker, T. Anderson, F. Gont || congxiao@cernet.edu.cn, xing@cernet.edu.cn, fred@cisco.com, tore@redpill-linpro.com, fgont@si6networks.com +# RFC7916 || S. Litkowski, Ed., B. Decraene, C. Filsfils, K. Raza, M. Horneffer, P. Sarkar || stephane.litkowski@orange.com, bruno.decraene@orange.com, cfilsfil@cisco.com, skraza@cisco.com, Martin.Horneffer@telekom.de, pushpasis.ietf@gmail.com +# RFC7917 || P. Sarkar, Ed., H. Gredler, S. Hegde, S. Litkowski, B. Decraene || pushpasis.ietf@gmail.com, hannes@rtbrick.com, shraddha@juniper.net, stephane.litkowski@orange.com, bruno.decraene@orange.com +# RFC7918 || A. Langley, N. Modadugu, B. Moeller || agl@google.com, nagendra@cs.stanford.edu, bmoeller@acm.org +# RFC7919 || D. Gillmor || dkg@fifthhorseman.net +# RFC7920 || A. Atlas, Ed., T. Nadeau, Ed., D. Ward || akatlas@juniper.net, tnadeau@lucidvision.com, wardd@cisco.com +# RFC7921 || A. Atlas, J. Halpern, S. Hares, D. Ward, T. Nadeau || akatlas@juniper.net, joel.halpern@ericsson.com, shares@ndzh.com, wardd@cisco.com, tnadeau@lucidvision.com +# RFC7922 || J. Clarke, G. Salgueiro, C. Pignataro || jclarke@cisco.com, gsalguei@cisco.com, cpignata@cisco.com +# RFC7923 || E. Voit, A. Clemm, A. Gonzalez Prieto || evoit@cisco.com, alex@cisco.com, albertgo@cisco.com +# RFC7924 || S. Santesson, H. Tschofenig || sts@aaa-sec.com, Hannes.Tschofenig@gmx.net +# RFC7925 || H. Tschofenig, Ed., T. Fossati || Hannes.Tschofenig@gmx.net, thomas.fossati@nokia.com +# RFC7926 || A. Farrel, Ed., J. Drake, N. Bitar, G. Swallow, D. Ceccarelli, X. Zhang || adrian@olddog.co.uk, jdrake@juniper.net, nbitar40@gmail.com, swallow@cisco.com, daniele.ceccarelli@ericsson.com, zhang.xian@huawei.com +# RFC7927 || D. Kutscher, Ed., S. Eum, K. Pentikousis, I. Psaras, D. Corujo, D. Saucez, T. Schmidt, M. Waehlisch || kutscher@neclab.eu, suyong@ist.osaka-u.ac.jp, k.pentikousis@travelping.com, i.psaras@ucl.ac.uk, dcorujo@av.it.pt, damien.saucez@inria.fr, t.schmidt@haw-hamburg.de, waehlisch@ieee.org +# RFC7928 || N. Kuhn, Ed., P. Natarajan, Ed., N. Khademi, Ed., D. Ros || nicolas.kuhn@cnes.fr, prenatar@cisco.com, naeemk@ifi.uio.no, dros@simula.no +# RFC7929 || P. Wouters || pwouters@redhat.com +# RFC7930 || S. Hartman || hartmans-ietf@mit.edu +# RFC7931 || D. Noveck, Ed., P. Shivam, C. Lever, B. Baker || davenoveck@gmail.com, piyush.shivam@oracle.com, chuck.lever@oracle.com, bill.baker@oracle.com +# RFC7932 || J. Alakuijala, Z. Szabadka || jyrki@google.com, szabadka@google.com +# RFC7933 || C. Westphal, Ed., S. Lederer, D. Posch, C. Timmerer, A. Azgin, W. Liu, C. Mueller, A. Detti, D. Corujo, J. Wang, M. Montpetit, N. Murray || Cedric.Westphal@huawei.com, stefan.lederer@itec.aau.at, daniel.posch@itec.aau.at, christian.timmerer@itec.aau.at, aytac.azgin@huawei.com, liushucheng@huawei.com, christopher.mueller@bitmovin.net, andrea.detti@uniroma2.it, dcorujo@av.it.pt, jianwang@cityu.edu.hk, marie@mjmontpetit.com, nmurray@research.ait.ie +# RFC7934 || L. Colitti, V. Cerf, S. Cheshire, D. Schinazi || lorenzo@google.com, vint@google.com, cheshire@apple.com, dschinazi@apple.com +# RFC7935 || G. Huston, G. Michaelson, Ed. || gih@apnic.net, ggm@apnic.net +# RFC7936 || T. Hardie || ted.ietf@gmail.com +# RFC7937 || F. Le Faucheur, Ed., G. Bertrand, Ed., I. Oprescu, Ed., R. Peterkofsky || flefauch@gmail.com, gilbertrand@gmail.com, iuniana.oprescu@gmail.com, peterkofsky@google.com +# RFC7938 || P. Lapukhov, A. Premji, J. Mitchell, Ed. || petr@fb.com, ariff@arista.com, jrmitche@puck.nether.net +# RFC7939 || U. Herberg, R. Cole, I. Chakeres, T. Clausen || ulrich@herberg.name, rgcole01@comcast.net, ian.chakeres@gmail.com, T.Clausen@computer.org +# RFC7940 || K. Davies, A. Freytag || kim.davies@icann.org, asmus@unicode.org +# RFC7941 || M. Westerlund, B. Burman, R. Even, M. Zanaty || magnus.westerlund@ericsson.com, bo.burman@ericsson.com, roni.even@mail01.huawei.com, mzanaty@cisco.com +# RFC7942 || Y. Sheffer, A. Farrel || yaronf.ietf@gmail.com, adrian@olddog.co.uk +# RFC7943 || F. Gont, W. Liu || fgont@si6networks.com, liushucheng@huawei.com +# RFC7944 || S. Donovan || srdonovan@usdonovans.com +# RFC7945 || K. Pentikousis, Ed., B. Ohlman, E. Davies, S. Spirou, G. Boggia || k.pentikousis@travelping.com, Borje.Ohlman@ericsson.com, davieseb@scss.tcd.ie, spis@intracom-telecom.com, g.boggia@poliba.it +# RFC7946 || H. Butler, M. Daly, A. Doyle, S. Gillies, S. Hagen, T. Schaub || howard@hobu.co, martin.daly@cadcorp.com, adoyle@intl-interfaces.com, sean.gillies@gmail.com, stefan@hagen.link, tim.schaub@gmail.com +# RFC7947 || E. Jasinska, N. Hilliard, R. Raszuk, N. Bakker || elisa@bigwaveit.org, nick@inex.ie, robert@raszuk.net, nbakker@akamai.com +# RFC7948 || N. Hilliard, E. Jasinska, R. Raszuk, N. Bakker || nick@inex.ie, elisa@bigwaveit.org, robert@raszuk.net, nbakker@akamai.com +# RFC7949 || I. Chen, A. Lindem, R. Atkinson || ichen@kuatrotech.com, acee@cisco.com, rja.lists@gmail.com +# RFC7950 || M. Bjorklund, Ed. || mbj@tail-f.com +# RFC7951 || L. Lhotka || lhotka@nic.cz +# RFC7952 || L. Lhotka || lhotka@nic.cz +# RFC7953 || C. Daboo, M. Douglass || cyrus@daboo.name, mdouglass@sphericalcowgroup.com +# RFC7954 || L. Iannone, D. Lewis, D. Meyer, V. Fuller || ggx@gigix.net, darlewis@cisco.com, dmm@1-4-5.net, vaf@vaf.net +# RFC7955 || L. Iannone, R. Jorgensen, D. Conrad, G. Huston || ggx@gigix.net, rogerj@gmail.com, drc@virtualized.org, gih@apnic.net +# RFC7956 || W. Hao, Y. Li, A. Qu, M. Durrani, P. Sivamurugan || haoweiguo@huawei.com, liyizhou@huawei.com, laodulaodu@gmail.com, mdurrani@equinix.com, ponkarthick.sivamurugan@ipinfusion.com +# RFC7957 || B. Campbell, Ed., A. Cooper, B. Leiba || ben@nostrum.com, alcoop@cisco.com, barryleiba@computer.org +# RFC7958 || J. Abley, J. Schlyter, G. Bailey, P. Hoffman || jabley@dyn.com, jakob@kirei.se, guillaumebailey@outlook.com, paul.hoffman@icann.org +# RFC7959 || C. Bormann, Z. Shelby, Ed. || cabo@tzi.org, zach.shelby@arm.com +# RFC7960 || F. Martin, Ed., E. Lear, Ed., T. Draegen. Ed., E. Zwicky, Ed., K. Andersen, Ed. || fmartin@linkedin.com, lear@cisco.com, tim@dmarcian.com, zwicky@yahoo-inc.com, kandersen@linkedin.com +# RFC7961 || D. Eastlake 3rd, L. Yizhou || d3e3e3@gmail.com, liyizhou@huawei.com +# RFC7962 || J. Saldana, Ed., A. Arcia-Moret, B. Braem, E. Pietrosemoli, A. Sathiaseelan, M. Zennaro || jsaldana@unizar.es, andres.arcia@cl.cam.ac.uk, bart.braem@iminds.be, ermanno@ictp.it, arjuna.sathiaseelan@cl.cam.ac.uk, mzennaro@ictp.it +# RFC7963 || Z. Ali, A. Bonfanti, M. Hartley, F. Zhang || zali@cisco.com, abonfant@cisco.com, mhartley@cisco.com, zhangfatai@huawei.com +# RFC7964 || D. Walton, A. Retana, E. Chen, J. Scudder || dwalton@cumulusnetworks.com, aretana@cisco.com, enkechen@cisco.com, jgs@juniper.net +# RFC7965 || M. Chen, W. Cao, A. Takacs, P. Pan || mach.chen@huawei.com, wayne.caowei@huawei.com, attila.takacs@ericsson.com, none +# RFC7966 || H. Tschofenig, J. Korhonen, Ed., G. Zorn, K. Pillay || Hannes.tschofenig@gmx.net, jouni.nospam@gmail.com, glenzorn@gmail.com, kervin.pillay@gmail.com +# RFC7967 || A. Bhattacharyya, S. Bandyopadhyay, A. Pal, T. Bose || abhijan.bhattacharyya@tcs.com, soma.bandyopadhyay@tcs.com, arpan.pal@tcs.com, tulika.bose@tcs.com +# RFC7968 || Y. Li, D. Eastlake 3rd, W. Hao, H. Chen, S. Chatterjee || liyizhou@huawei.com, d3e3e3@gmail.com, haoweiguo@huawei.com, philips.chenhao@huawei.com, somnath.chatterjee01@gmail.com +# RFC7969 || T. Lemon, T. Mrugalski || ted.lemon@nominum.com, tomasz.mrugalski@gmail.com +# RFC7970 || R. Danyliw || rdd@cert.org +# RFC7971 || M. Stiemerling, S. Kiesel, M. Scharf, H. Seidel, S. Previdi || mls.ietf@gmail.com, ietf-alto@skiesel.de, michael.scharf@nokia.com, hseidel@benocs.com, sprevidi@cisco.com +# RFC7972 || P. Lemieux || pal@sandflow.com +# RFC7973 || R. Droms, P. Duffy || rdroms.ietf@gmail.com, paduffy@cisco.com +# RFC7974 || B. Williams, M. Boucadair, D. Wing || brandon.williams@akamai.com, mohamed.boucadair@orange.com, dwing-ietf@fuggles.com +# RFC7975 || B. Niven-Jenkins, Ed., R. van Brandenburg, Ed. || ben.niven-jenkins@nokia.com, ray.vanbrandenburg@tno.nl +# RFC7976 || C. Holmberg, N. Biondic, G. Salgueiro || christer.holmberg@ericsson.com, nevenka.biondic@ericsson.com, gsalguei@cisco.com +# RFC7977 || P. Dunkley, G. Llewellyn, V. Pascual, G. Salgueiro, R. Ravindranath || peter.dunkley@xura.com, gavin.llewellyn@xura.com, victor.pascual.avila@oracle.com, gsalguei@cisco.com, rmohanr@cisco.com +# RFC7978 || D. Eastlake 3rd, M. Umair, Y. Li || d3e3e3@gmail.com, mohammed.umair2@gmail.com, liyizhou@huawei.com +# RFC7979 || E. Lear, Ed., R. Housley, Ed. || lear@cisco.com, housley@vigilsec.com +# RFC7980 || M. Behringer, A. Retana, R. White, G. Huston || mbehring@cisco.com, aretana@cisco.com, russw@riw.us, gih@apnic.net +# RFC7981 || L. Ginsberg, S. Previdi, M. Chen || ginsberg@cisco.com, sprevidi@cisco.com, mach.chen@huawei.com +# RFC7982 || P. Martinsen, T. Reddy, D. Wing, V. Singh || palmarti@cisco.com, tireddy@cisco.com, dwing-ietf@fuggles.com, varun@callstats.io +# RFC7983 || M. Petit-Huguenin, G. Salgueiro || marc@petit-huguenin.org, gsalguei@cisco.com +# RFC7984 || O. Johansson, G. Salgueiro, V. Gurbani, D. Worley, Ed. || oej@edvina.net, gsalguei@cisco.com, vkg@bell-labs.com, worley@ariadne.com +# RFC7985 || J. Yi, T. Clausen, U. Herberg || jiazi@jiaziyi.com, T.Clausen@computer.org, ulrich@herberg.name +# RFC7986 || C. Daboo || cyrus@daboo.name +# RFC7987 || L. Ginsberg, P. Wells, B. Decraene, T. Przygienda, H. Gredler || ginsberg@cisco.com, pauwells@cisco.com, bruno.decraene@orange.com, prz@juniper.net, hannes@rtbrick.com +# RFC7988 || E. Rosen, Ed., K. Subramanian, Z. Zhang || erosen@juniper.net, karthik@sproute.com, zzhang@juniper.net +# RFC7989 || P. Jones, G. Salgueiro, C. Pearce, P. Giralt || paulej@packetizer.com, gsalguei@cisco.com, chrep@cisco.com, pgiralt@cisco.com +# RFC7990 || H. Flanagan || rse@rfc-editor.org +# RFC7991 || P. Hoffman || paul.hoffman@icann.org +# RFC7992 || J. Hildebrand, Ed., P. Hoffman || joe-ietf@cursive.net, paul.hoffman@icann.org +# RFC7993 || H. Flanagan || rse@rfc-editor.org +# RFC7994 || H. Flanagan || rse@rfc-editor.org +# RFC7995 || T. Hansen, Ed., L. Masinter, M. Hardy || tony@att.com, masinter@adobe.com, mahardy@adobe.com +# RFC7996 || N. Brownlee || n.brownlee@auckland.ac.nz +# RFC7997 || H. Flanagan, Ed. || rse@rfc-editor.org +# RFC7998 || P. Hoffman, J. Hildebrand || paul.hoffman@icann.org, joe-ietf@cursive.net +# RFC7999 || T. King, C. Dietzel, J. Snijders, G. Doering, G. Hankins || thomas.king@de-cix.net, christoph.dietzel@de-cix.net, job@ntt.net, gert@space.net, greg.hankins@nokia.com +# RFC8000 || A. Adamson, N. Williams || andros@netapp.com, nico@cryptonector.com +# RFC8001 || F. Zhang, Ed., O. Gonzalez de Dios, Ed., C. Margaria, M. Hartley, Z. Ali || zhangfatai@huawei.com, oscar.gonzalezdedios@telefonica.com, cmargaria@juniper.net, mhartley@cisco.com, zali@cisco.com +# RFC8002 || T. Heer, S. Varjonen || heer@hs-albsig.de, samu.varjonen@helsinki.fi +# RFC8003 || J. Laganier, L. Eggert || julien.ietf@gmail.com, lars@netapp.com +# RFC8004 || J. Laganier, L. Eggert || julien.ietf@gmail.com, lars@netapp.com +# RFC8005 || J. Laganier || julien.ietf@gmail.com +# RFC8006 || B. Niven-Jenkins, R. Murray, M. Caulfield, K. Ma || ben.niven-jenkins@nokia.com, rob.murray@nokia.com, mcaulfie@cisco.com, kevin.j.ma@ericsson.com +# RFC8007 || R. Murray, B. Niven-Jenkins || rob.murray@nokia.com, ben.niven-jenkins@nokia.com +# RFC8008 || J. Seedorf, J. Peterson, S. Previdi, R. van Brandenburg, K. Ma || jan.seedorf@hft-stuttgart.de, jon.peterson@neustar.biz, sprevidi@cisco.com, ray.vanbrandenburg@tno.nl, kevin.j.ma@ericsson.com +# RFC8009 || M. Jenkins, M. Peck, K. Burgin || mjjenki@tycho.ncsc.mil, mpeck@mitre.org, kelley.burgin@gmail.com +# RFC8010 || M. Sweet, I. McDonald || msweet@apple.com, blueroofmusic@gmail.com +# RFC8011 || M. Sweet, I. McDonald || msweet@apple.com, blueroofmusic@gmail.com +# RFC8012 || N. Akiya, G. Swallow, C. Pignataro, A. Malis, S. Aldrin || nobo.akiya.dev@gmail.com, swallow@cisco.com, cpignata@cisco.com, agmalis@gmail.com, aldrin.ietf@gmail.com +# RFC8013 || D. Joachimpillai, J. Hadi Salim || damascene.joachimpillai@verizon.com, hadi@mojatatu.com +# RFC8014 || D. Black, J. Hudson, L. Kreeger, M. Lasserre, T. Narten || david.black@dell.com, jon.hudson@gmail.com, lkreeger@gmail.com, mmlasserre@gmail.com, narten@us.ibm.com +# RFC8015 || V. Singh, C. Perkins, A. Clark, R. Huang || varun@callstats.io, csp@csperkins.org, alan.d.clark@telchemy.com, Rachel@huawei.com +# RFC8016 || T. Reddy, D. Wing, P. Patil, P. Martinsen || tireddy@cisco.com, dwing-ietf@fuggles.com, praspati@cisco.com, palmarti@cisco.com +# RFC8017 || K. Moriarty, Ed., B. Kaliski, J. Jonsson, A. Rusch || Kathleen.Moriarty@emc.com, bkaliski@verisign.com, jakob.jonsson@subset.se, andreas.rusch@rsa.com +# RFC8018 || K. Moriarty, Ed., B. Kaliski, A. Rusch || Kathleen.Moriarty@Dell.com, bkaliski@verisign.com, andreas.rusch@rsa.com +# RFC8019 || Y. Nir, V. Smyslov || ynir.ietf@gmail.com, svan@elvis.ru +# RFC8020 || S. Bortzmeyer, S. Huque || bortzmeyer+ietf@nic.fr, shuque@verisign.com +# RFC8021 || F. Gont, W. Liu, T. Anderson || fgont@si6networks.com, liushucheng@huawei.com, tore@redpill-linpro.com +# RFC8022 || L. Lhotka, A. Lindem || lhotka@nic.cz, acee@cisco.com +# RFC8023 || M. Thomas, A. Mankin, L. Zhang || mthomas@verisign.com, allison.mankin@gmail.com, lixia@cs.ucla.edu +# RFC8024 || Y. Jiang, Ed., Y. Luo, E. Mallette, Ed., Y. Shen, W. Cheng || jiangyuanlong@huawei.com, dennis.luoyong@huawei.com, edwin.mallette@gmail.com, yshen@juniper.net, chengweiqiang@chinamobile.com +# RFC8025 || P. Thubert, Ed., R. Cragie || pthubert@cisco.com, robert.cragie@gridmerge.com +# RFC8026 || M. Boucadair, I. Farrer || mohamed.boucadair@orange.com, ian.farrer@telekom.de +# RFC8027 || W. Hardaker, O. Gudmundsson, S. Krishnaswamy || ietf@hardakers.net, olafur+ietf@cloudflare.com, suresh@tislabs.com +# RFC8028 || F. Baker, B. Carpenter || fredbaker.ietf@gmail.com, brian.e.carpenter@gmail.com +# RFC8029 || K. Kompella, G. Swallow, C. Pignataro, Ed., N. Kumar, S. Aldrin, M. Chen || kireeti.kompella@gmail.com, swallow.ietf@gmail.com, cpignata@cisco.com, naikumar@cisco.com, aldrin.ietf@gmail.com, mach.chen@huawei.com +# RFC8030 || M. Thomson, E. Damaggio, B. Raymor, Ed. || martin.thomson@gmail.com, elioda@microsoft.com, brian.raymor@microsoft.com +# RFC8031 || Y. Nir, S. Josefsson || ynir.ietf@gmail.com, simon@josefsson.org +# RFC8032 || S. Josefsson, I. Liusvaara || simon@josefsson.org, ilariliusvaara@welho.com +# RFC8033 || R. Pan, P. Natarajan, F. Baker, G. White || ropan@cisco.com, prenatar@cisco.com, fredbaker.ietf@gmail.com, g.white@cablelabs.com +# RFC8034 || G. White, R. Pan || g.white@cablelabs.com, ropan@cisco.com +# RFC8035 || C. Holmberg || christer.holmberg@ericsson.com +# RFC8036 || N. Cam-Winget, Ed., J. Hui, D. Popa || ncamwing@cisco.com, jonhui@nestlabs.com, daniel.popa@itron.com +# RFC8037 || I. Liusvaara || ilariliusvaara@welho.com +# RFC8039 || A. Shpiner, R. Tse, C. Schelp, T. Mizrahi || alexshp@mellanox.com, Richard.Tse@microsemi.com, craig.schelp@oracle.com, talmi@marvell.com +# RFC8040 || A. Bierman, M. Bjorklund, K. Watsen || andy@yumaworks.com, mbj@tail-f.com, kwatsen@juniper.net +# RFC8041 || O. Bonaventure, C. Paasch, G. Detal || Olivier.Bonaventure@uclouvain.be, cpaasch@apple.com, gregory.detal@tessares.net +# RFC8042 || Z. Zhang, L. Wang, A. Lindem || zzhang@juniper.net, liliw@juniper.net, acee@cisco.com +# RFC8043 || B. Sarikaya, M. Boucadair || sarikaya@ieee.org, mohamed.boucadair@orange.com +# RFC8044 || A. DeKok || aland@freeradius.org +# RFC8045 || D. Cheng, J. Korhonen, M. Boucadair, S. Sivakumar || dean.cheng@huawei.com, jouni.nospam@gmail.com, mohamed.boucadair@orange.com, ssenthil@cisco.com +# RFC8046 || T. Henderson, Ed., C. Vogt, J. Arkko || tomhend@u.washington.edu, mail@christianvogt.net, jari.arkko@piuha.net +# RFC8047 || T. Henderson, Ed., C. Vogt, J. Arkko || tomhend@u.washington.edu, mail@christianvogt.net, jari.arkko@piuha.net +# RFC8048 || P. Saint-Andre || peter@filament.com +# RFC8049 || S. Litkowski, L. Tomotaki, K. Ogaki || stephane.litkowski@orange.com, luis.tomotaki@verizon.com, ke-oogaki@kddi.com +# RFC8051 || X. Zhang, Ed., I. Minei, Ed. || zhang.xian@huawei.com, inaminei@google.com +# RFC8053 || Y. Oiwa, H. Watanabe, H. Takagi, K. Maeda, T. Hayashi, Y. Ioku || y.oiwa@aist.go.jp, h-watanabe@aist.go.jp, takagi.hiromitsu@aist.go.jp, maeda@lepidum.co.jp, hayashi@lepidum.co.jp, mutual-work@ioku.org +# RFC8054 || K. Murchison, J. Elie || murch@andrew.cmu.edu, julien@trigofacile.com +# RFC8055 || C. Holmberg, Y. Jiang || christer.holmberg@ericsson.com, jiangyi@chinamobile.com +# RFC8056 || J. Gould || jgould@verisign.com +# RFC8057 || B. Stark, D. Sinicrope, W. Lupton || barbara.stark@att.com, david.sinicrope@ericsson.com, wlupton@broadband-forum.org +# RFC8058 || J. Levine, T. Herkula || standards@taugh.com, t.herkula@optivo.com +# RFC8059 || J. Arango, S. Venaas, I. Kouvelas, D. Farinacci || jearango@cisco.com, stig@cisco.com, kouvelas@arista.com, farinacci@gmail.com +# RFC8060 || D. Farinacci, D. Meyer, J. Snijders || farinacci@gmail.com, dmm@1-4-5.net, job@ntt.net +# RFC8061 || D. Farinacci, B. Weis || farinacci@gmail.com, bew@cisco.com +# RFC8062 || L. Zhu, P. Leach, S. Hartman, S. Emery, Ed. || larry.zhu@microsoft.com, pauljleach@msn.com, hartmans-ietf@mit.edu, shawn.emery@gmail.com +# RFC8063 || H.W. Ribbers, M.W. Groeneweg, R. Gieben, A.L.J. Verschuren || rik.ribbers@sidn.nl, marc.groeneweg@sidn.nl, miek@miek.nl, ietf@antoin.nl +# RFC8064 || F. Gont, A. Cooper, D. Thaler, W. Liu || fgont@si6networks.com, alcoop@cisco.com, dthaler@microsoft.com, liushucheng@huawei.com +# RFC8065 || D. Thaler || dthaler@microsoft.com +# RFC8066 || S. Chakrabarti, G. Montenegro, R. Droms, J. Woodyatt || samitac.ietf@gmail.com, Gabriel.Montenegro@microsoft.com, rdroms.ietf@gmail.com, jhw@google.com +# RFC8067 || B. Leiba || barryleiba@computer.org +# RFC8068 || R. Ravindranath, P. Ravindran, P. Kyzivat || rmohanr@cisco.com, partha@parthasarathi.co.in, pkyzivat@alum.mit.edu +# RFC8069 || A. Thomas || a.n.thomas@ieee.org +# RFC8070 || M. Short, Ed., S. Moore, P. Miller || michikos@microsoft.com, sethmo@microsoft.com, paumil@microsoft.com +# RFC8071 || K. Watsen || kwatsen@juniper.net +# RFC8072 || A. Bierman, M. Bjorklund, K. Watsen || andy@yumaworks.com, mbj@tail-f.com, kwatsen@juniper.net +# RFC8073 || K. Moriarty, M. Ford || Kathleen.Moriarty@dell.com, ford@isoc.org +# RFC8074 || J. Bi, G. Yao, J. Halpern, E. Levy-Abegnoli, Ed. || junbi@tsinghua.edu.cn, yaoguang.china@gmail.com, joel.halpern@ericsson.com, elevyabe@cisco.com +# RFC8075 || A. Castellani, S. Loreto, A. Rahman, T. Fossati, E. Dijk || angelo@castellani.net, Salvatore.Loreto@ericsson.com, Akbar.Rahman@InterDigital.com, thomas.fossati@nokia.com, esko.dijk@philips.com +# RFC8076 || A. Knauf, T. Schmidt, Ed., G. Hege, M. Waehlisch || alexanderknauf@gmail.com, t.schmidt@haw-hamburg.de, hege@daviko.com, mw@link-lab.net +# RFC8077 || L. Martini, Ed., G. Heron, Ed. || lmartini@monoski.com, giheron@cisco.com +# RFC8078 || O. Gudmundsson, P. Wouters || olafur+ietf@cloudflare.com, pwouters@redhat.com +# RFC8079 || L. Miniero, S. Garcia Murillo, V. Pascual || lorenzo@meetecho.com, sergio.garcia.murillo@gmail.com, victor.pascual.avila@oracle.com +# RFC8080 || O. Sury, R. Edmonds || ondrej.sury@nic.cz, edmonds@mycre.ws +# RFC8081 || C. Lilley || chris@w3.org +# RFC8082 || S. Wenger, J. Lennox, B. Burman, M. Westerlund || stewe@stewe.org, jonathan@vidyo.com, bo.burman@ericsson.com, magnus.westerlund@ericsson.com +# RFC8083 || C. Perkins, V. Singh || csp@csperkins.org, varun@callstats.io +# RFC8084 || G. Fairhurst || gorry@erg.abdn.ac.uk +# RFC8085 || L. Eggert, G. Fairhurst, G. Shepherd || lars@netapp.com, gorry@erg.abdn.ac.uk, gjshep@gmail.com +# RFC8086 || L. Yong, Ed., E. Crabbe, X. Xu, T. Herbert || lucy.yong@huawei.com, edward.crabbe@gmail.com, xuxiaohu@huawei.com, tom@herbertland.com +# RFC8087 || G. Fairhurst, M. Welzl || gorry@erg.abdn.ac.uk, michawe@ifi.uio.no +# RFC8089 || M. Kerwin || matthew.kerwin@qut.edu.au +# RFC8090 || R. Housley || housley@vigilsec.com +# RFC8091 || E. Wilde || erik.wilde@dret.net +# RFC8092 || J. Heitz, Ed., J. Snijders, Ed., K. Patel, I. Bagdonas, N. Hilliard || jheitz@cisco.com, job@ntt.net, keyur@arrcus.com, ibagdona.ietf@gmail.com, nick@inex.ie +# RFC8093 || J. Snijders || job@ntt.net +# RFC8094 || T. Reddy, D. Wing, P. Patil || tireddy@cisco.com, dwing-ietf@fuggles.com, praspati@cisco.com +# RFC8095 || G. Fairhurst, Ed., B. Trammell, Ed., M. Kuehlewind, Ed. || gorry@erg.abdn.ac.uk, ietf@trammell.ch, mirja.kuehlewind@tik.ee.ethz.ch +# RFC8096 || B. Fenner || fenner@fenron.com +# RFC8097 || P. Mohapatra, K. Patel, J. Scudder, D. Ward, R. Bush || mpradosh@yahoo.com, keyur@arrcus.com, jgs@juniper.net, dward@cisco.com, randy@psg.com +# RFC8098 || T. Hansen, Ed., A. Melnikov, Ed. || tony@att.com, alexey.melnikov@isode.com +# RFC8099 || H. Chen, R. Li, A. Retana, Y. Yang, Z. Liu || huaimo.chen@huawei.com, renwei.li@huawei.com, aretana@cisco.com, yyang1998@gmail.com, liu.cmri@gmail.com +# RFC8100 || R. Geib, Ed., D. Black || Ruediger.Geib@telekom.de, david.black@dell.com +# RFC8101 || C. Holmberg, J. Axell || christer.holmberg@ericsson.com, jorgen.axell@ericsson.com +# RFC8102 || P. Sarkar, Ed., S. Hegde, C. Bowers, H. Gredler, S. Litkowski || pushpasis.ietf@gmail.com, shraddha@juniper.net, cbowers@juniper.net, hannes@rtbrick.com, stephane.litkowski@orange.com +# RFC8103 || R. Housley || housley@vigilsec.com +# RFC8104 || Y. Shen, R. Aggarwal, W. Henderickx, Y. Jiang || yshen@juniper.net, raggarwa_1@yahoo.com, wim.henderickx@nokia.com, jiangyuanlong@huawei.com +# RFC8106 || J. Jeong, S. Park, L. Beloeil, S. Madanapalli || pauljeong@skku.edu, soohong.park@samsung.com, luc.beloeil@orange.com, smadanapalli@gmail.com +# RFC8107 || J. Wold || jwold@ad-id.org +# RFC8108 || J. Lennox, M. Westerlund, Q. Wu, C. Perkins || jonathan@vidyo.com, magnus.westerlund@ericsson.com, bill.wu@huawei.com, csp@csperkins.org +# RFC8109 || P. Koch, M. Larson, P. Hoffman || pk@DENIC.DE, matt.larson@icann.org, paul.hoffman@icann.org +# RFC8110 || D. Harkins, Ed., W. Kumari, Ed. || dharkins@arubanetworks.com, warren@kumari.net +# RFC8113 || M. Boucadair, C. Jacquenet || mohamed.boucadair@orange.com, christian.jacquenet@orange.com +# RFC8114 || M. Boucadair, C. Qin, C. Jacquenet, Y. Lee, Q. Wang || mohamed.boucadair@orange.com, jacni@jacni.com, christian.jacquenet@orange.com, yiu_lee@cable.comcast.com, 13301168516@189.cn +# RFC8115 || M. Boucadair, J. Qin, T. Tsou, X. Deng || mohamed.boucadair@orange.com, jacni@jacni.com, tina.tsou@philips.com, dxhbupt@gmail.com +# RFC8117 || C. Huitema, D. Thaler, R. Winter || huitema@huitema.net, dthaler@microsoft.com, rolf.winter@hs-augsburg.de +# RFC8118 || M. Hardy, L. Masinter, D. Markovic, D. Johnson, M. Bailey || mahardy@adobe.com, masinter@adobe.com, dmarkovi@adobe.com, duff.johnson@pdfa.org, martin.bailey@globalgraphics.com +# RFC8119 || M. Mohali, M. Barnes || marianne.mohali@orange.com, mary.ietf.barnes@gmail.com +# RFC8120 || Y. Oiwa, H. Watanabe, H. Takagi, K. Maeda, T. Hayashi, Y. Ioku || y.oiwa@aist.go.jp, h-watanabe@aist.go.jp, takagi.hiromitsu@aist.go.jp, kaorumaeda.ml@gmail.com, hayashi@lepidum.co.jp, mutual-work@ioku.org +# RFC8121 || Y. Oiwa, H. Watanabe, H. Takagi, K. Maeda, T. Hayashi, Y. Ioku || y.oiwa@aist.go.jp, h-watanabe@aist.go.jp, takagi.hiromitsu@aist.go.jp, kaorumaeda.ml@gmail.com, hayashi@lepidum.co.jp, mutual-work@ioku.org +# RFC8122 || J. Lennox, C. Holmberg || jonathan@vidyo.com, christer.holmberg@ericsson.com +# RFC8123 || P. Dawes, C. Arunachalam || peter.dawes@vodafone.com, carunach@cisco.com +# RFC8124 || R. Ravindranath, G. Salgueiro || rmohanr@cisco.com, gsalguei@cisco.com +# RFC8128 || C. Morgan || cmorgan@amsl.com +# RFC8129 || A. Jain, N. Kinder, N. McCallum || ajain323@gatech.edu, nkinder@redhat.com, npmccallum@redhat.com +# RFC8130 || V. Demjanenko, D. Satterlee || victor.demjanenko@vocal.com, david.satterlee@vocal.com +# RFC8131 || X. Zhang, H. Zheng, Ed., R. Gandhi, Ed., Z. Ali, P. Brzozowski || zhang.xian@huawei.com, zhenghaomian@huawei.com, rgandhi@cisco.com, zali@cisco.com, pbrzozowski@advaoptical.com +# RFC8132 || P. van der Stok, C. Bormann, A. Sehgal || consultancy@vanderstok.org, cabo@tzi.org, anuj.sehgal@navomi.com +# RFC8133 || S. Smyshlyaev. Ed., E. Alekseev, I. Oshkin, V. Popov || svs@cryptopro.ru, alekseev@cryptopro.ru, oshkin@cryptopro.ru, vpopov@cryptopro.ru +# RFC8135 || M. Danielson, M. Nilsson || magda@netinsight.net, mansaxel@besserwisser.org +# RFC8136 || B. Carpenter, R. Hinden || brian.e.carpenter@gmail.com, bob.hinden@gmail.com +# RFC8138 || P. Thubert, Ed., C. Bormann, L. Toutain, R. Cragie || pthubert@cisco.com, cabo@tzi.org, Laurent.Toutain@IMT-Atlantique.fr, robert.cragie@arm.com +# RFC8140 || A. Farrel || adrian@olddog.co.uk +# RFC8144 || K. Murchison || murch@andrew.cmu.edu +# RFC8145 || D. Wessels, W. Kumari, P. Hoffman || dwessels@verisign.com, warren@kumari.net, paul.hoffman@icann.org""".split('\n') + + +# # Many of these are addresses that the draft parser found incorrectly +# ignore_addresses =[ +# '0004454742@mcimail.com', +# '0006423401@mcimail.com', +# 'cabo@tzi.orgemail', +# 'california@san', +# 'cdl@rincon.com', +# 'hss@lando.hns.com', +# 'ietf-info@cnri.reston.va.us', +# 'illinois@urbana-champaign', +# 'jasdips@rwhois.net', +# 'labs@network', +# 'member@the', +# 'park@mit', +# 'research@icsi', +# 'research@isci', +# 'technopark@chaichee', +# 'texas@arlington', +# 'ura-bunyip@bunyip.com', +# ] + +# def get_rfc_data(): +# author_names = dict() +# author_emails = dict() +# for line in rfced_data: +# (rfc,names,emails) = line.split('||') +# rfc = int(rfc.lower().strip()[3:]) +# author_names[rfc] = [ x for x in map(str.lower,map(str.strip,names.split(','))) if x not in ['Ed.', 'ed.', '' ] ] +# author_emails[rfc] = [ x for x in map(unicode,map(str.lower,map(str.strip,emails.split(',')))) if x not in [ '', ] ] +# return author_names, author_emails + +# def get_all_the_email(): +# all_the_email = Email.objects.all() +# for e in all_the_email: +# e.l_address = e.address.lower() +# return all_the_email + +# def get_matching_emails(all_the_email,addrlist): +# """ Find Email objects with addresses case-insensitively matching things in the supplied list (for lack of __iin) """ +# l_addrlist = map(unicode.lower,addrlist) +# return [ e for e in all_the_email if e.l_address in l_addrlist ] + +# def show_verbose(rfc_num,*args): +# print "rfc%-4d :"%rfc_num,' '.join(map(str,args)) + +# ParsedAuthor = namedtuple('ParsedAuthor',['name','address']) + +# def get_parsed_authors(rfc_num): +# h,n = mkstemp() +# os.close(h) +# f = open(n,"w") +# f.write('%s/rfc%d.txt\n'%(settings.RFC_PATH,rfc_num)) +# f.close() +# lines = subprocess.check_output(['ietf/utils/draft.py','-a',n]) +# os.unlink(n) +# if not 'docauthors ' in lines: +# return [] +# authorline = [l for l in lines.split('\n') if l.startswith('docauthors ')][0] +# authstrings = authorline.split(':')[1].split(',') +# retval = [] +# for a in authstrings: +# if '<' in a: +# retval.append(ParsedAuthor(a[:a.find('<')].strip(),a[a.find('<'):a.find('>')][1:])) +# else: +# retval.append(ParsedAuthor(a.strip(),None)) + +# return retval + +# def calculate_changes(tracker_persons,tracker_emails,names,emails): +# adds = set() +# deletes = set() +# for email in emails: +# if email and email!='none' and email not in ignore_addresses: +# p = Person.objects.filter(email__address=email).first() +# if p: +# if not set(map(unicode.lower,p.email_set.values_list('address',flat=True))).intersection(tracker_emails): +# adds.add(email) +# else: +# #person_name = names[emails.index(email)] +# adds.add(email) +# for person in tracker_persons: +# if not set(map(unicode.lower,person.email_set.values_list('address',flat=True))).intersection(emails): +# match = False +# for index in [i for i,j in enumerate(emails) if j=='none' or not j]: +# if names[index].split()[-1].lower()==person.last_name().lower(): +# match = True +# if not match: +# deletes.add(person) +# return adds, deletes + +# def _main(): + +# parser = argparse.ArgumentParser(description="Recalculate RFC documentauthor_set"+'\n\n'+__doc__, +# formatter_class=argparse.RawDescriptionHelpFormatter,) +# parser.add_argument('-v','--verbose',help="Show the action taken for each RFC",action='store_true') +# parser.add_argument('--rfc',type=int, nargs='*',help="Only recalculate the given rfc numbers",dest='rfcnumberlist') +# args = parser.parse_args() + +# probable_email_match = set() +# probable_duplicates = [] + +# all_the_email = get_all_the_email() +# author_names, author_emails = get_rfc_data() + +# stats = { 'rfc not in tracker' :0, +# 'same addresses' :0, +# 'different addresses belonging to same people' :0, +# 'same names, rfced emails do not match' :0, +# 'rfced data is unusable' :0, +# "data doesn't match but no changes found" :0, +# 'changed authors' :0, } + +# for rfc_num in args.rfcnumberlist or sorted(author_names.keys()): + +# rfc = Document.objects.filter(docalias__name='rfc%s'%rfc_num).first() + +# if not rfc: +# if args.verbose: +# show_verbose(rfc_num,'rfc not in tracker') +# stats['rfc not in tracker'] += 1 +# continue + +# rfced_emails = set(author_emails[rfc_num]) +# tracker_emails = set(map(unicode.lower,rfc.authors.values_list('address',flat=True))) +# tracker_persons = set([x.person for x in rfc.authors.all()]) +# matching_emails = get_matching_emails(all_the_email,rfced_emails) +# rfced_persons = set([x.person for x in matching_emails]) +# known_emails = set([e.l_address for e in matching_emails]) +# unknown_emails = rfced_emails - known_emails +# unknown_persons = tracker_persons-rfced_persons + +# rfced_lastnames = sorted([n.split()[-1].lower() for n in author_names[rfc_num]]) +# tracker_lastnames = sorted([p.last_name().lower() for p in tracker_persons]) + +# if rfced_emails == tracker_emails: +# if args.verbose: +# show_verbose(rfc_num,'tracker and rfc editor have the same addresses') +# stats['same addresses'] += 1 +# continue + +# if len(rfced_emails)==len(tracker_emails) and not 'none' in author_emails[rfc_num]: +# if tracker_persons == rfced_persons: +# if args.verbose: +# show_verbose(rfc_num,'tracker and rfc editor have the different addresses belonging to same people') +# stats['different addresses belonging to same people'] += 1 +# continue +# else: +# if len(unknown_emails)==1 and len(tracker_persons-rfced_persons)==1: +# p = list(tracker_persons-rfced_persons)[0] +# probable_email_match.add(u"%s is probably %s (%s) : %s "%(list(unknown_emails)[0], p, p.pk, rfc_num)) +# elif len(unknown_emails)==len(unknown_persons): +# probable_email_match.add(u"%s are probably %s : %s"%(unknown_emails,[(p.ascii,p.pk) for p in unknown_persons],rfc_num)) +# else: +# probable_duplicates.append((tracker_persons^rfced_persons,rfc_num)) + +# if tracker_lastnames == rfced_lastnames: +# if args.verbose: +# show_verbose(rfc_num,"emails don't match up, but person names appear to be the same") +# stats[ 'same names, rfced emails do not match'] += 1 +# continue + +# use_rfc_data = bool(len(author_emails[rfc_num])==len(author_names[rfc_num])) +# if not use_rfc_data: +# if args.verbose: +# print 'Ignoring rfc database for rfc%d'%rfc_num +# stats[ 'rfced data is unusable'] += 1 + +# if use_rfc_data: +# adds, deletes = calculate_changes(tracker_persons,tracker_emails,author_names[rfc_num],author_emails[rfc_num]) +# parsed_authors=get_parsed_authors(rfc_num) +# parsed_adds, parsed_deletes = calculate_changes(tracker_persons,tracker_emails,[x.name for x in parsed_authors],[x.address for x in parsed_authors]) + +# for e in adds.union(parsed_adds) if use_rfc_data else parsed_adds: +# if not e or e in ignore_addresses: +# continue +# if not Person.objects.filter(email__address=e).exists(): +# if e not in parsed_adds: +# #print rfc_num,"Would add",e,"as",author_names[rfc_num][author_emails[rfc_num].index(e)],"(rfced database)" +# print "(address='%s',name='%s'),"%(e,author_names[rfc_num][author_emails[rfc_num].index(e)]),"# (rfced %d)"%rfc_num +# for p in Person.objects.filter(name__iendswith=author_names[rfc_num][author_emails[rfc_num].index(e)].split(' ')[-1]): +# print "\t", p.pk, p.ascii +# else: +# name = [x.name for x in parsed_authors if x.address==e][0] +# p = Person.objects.filter(name=name).first() +# if p: +# #print e,"is probably",p.pk,p +# print "'%s': %d, # %s (%d)"%(e,p.pk,p.ascii,rfc_num) + +# else: +# p = Person.objects.filter(ascii=name).first() +# if p: +# print e,"is probably",p.pk,p +# print "'%s': %d, # %s (%d)"%(e,p.pk,p.ascii,rfc_num) +# else: +# p = Person.objects.filter(ascii_short=name).first() +# if p: +# print e,"is probably",p.pk,p +# print "'%s': %d, # %s (%d)"%(e,p.pk,p.ascii,rfc_num) +# #print rfc_num,"Would add",e,"as",name,"(parsed)" +# print "(address='%s',name='%s'),"%(e,name),"# (parsed %d)"%rfc_num +# for p in Person.objects.filter(name__iendswith=name.split(' ')[-1]): +# print "\t", p.pk, p.ascii + +# if False: # This was a little useful, but the noise in the rfc_ed file keeps it from being completely useful +# for p in deletes: +# for n in author_names[rfc_num]: +# if p.last_name().lower()==n.split()[-1].lower(): +# email_candidate = author_emails[rfc_num][author_names[rfc_num].index(n)] +# email_found = Email.objects.filter(address=email_candidate).first() +# if email_found: +# probable_duplicates.append((set([p,email_found.person]),rfc_num)) +# else: +# probable_email_match.add(u"%s is probably %s (%s) : %s"%(email_candidate, p, p.pk, rfc_num)) + +# if args.verbose: +# if use_rfc_data: +# working_adds = parsed_adds +# seen_people = set(Email.objects.get(address=e).person for e in parsed_adds) +# for addr in adds: +# person = Email.objects.get(address=addr).person +# if person not in seen_people: +# working_adds.add(addr) +# seen_people.add(person) +# working_deletes = deletes.union(parsed_deletes) +# else: +# working_adds = parsed_adds +# working_deletes = parsed_deletes +# # unique_adds = set() # TODO don't add different addresses for the same person from the two sources +# if working_adds or working_deletes: +# show_verbose(rfc_num,"Changing original list",tracker_persons,"by adding",working_adds," and deleting",working_deletes) +# print "(",rfc_num,",",[e for e in working_adds],",",[p.pk for p in working_deletes],"), #",[p.ascii for p in working_deletes] +# else: +# stats["data doesn't match but no changes found"] += 1 +# show_verbose(rfc_num,"Couldn't figure out what to change") + +# if False: +# #if tracker_persons: +# #if any(['iab@' in e for e in adds]) or any(['iesg@' in e for e in adds]) or any(['IESG'==p.name for p in deletes]) or any(['IAB'==p.name for p in deletes]): +# print rfc_num +# print "tracker_persons",tracker_persons +# print "author_names",author_names[rfc_num] +# print "author_emails",author_emails[rfc_num] +# print "Adds:", adds +# print "Deletes:", deletes + +# stats['changed authors'] += 1 + +# if False: +# debug.show('rfc_num') +# debug.show('rfced_emails') +# debug.show('tracker_emails') +# debug.show('known_emails') +# debug.show('unknown_emails') +# debug.show('tracker_persons') +# debug.show('rfced_persons') +# debug.show('tracker_persons==rfced_persons') +# debug.show('[p.id for p in tracker_persons]') +# debug.show('[p.id for p in rfced_persons]') +# exit() + +# if True: +# for p in sorted(list(probable_email_match)): +# print p +# if True: +# print "Probable duplicate persons" +# for d,r in sorted(probable_duplicates): +# print [(p,p.pk) for p in d], r +# else: +# print len(probable_duplicates)," probable duplicate persons" + +# print stats + +# if __name__ == "__main__": +# _main() + diff --git a/dev/mq/Dockerfile b/dev/mq/Dockerfile new file mode 100644 index 00000000000..1738c4b3d20 --- /dev/null +++ b/dev/mq/Dockerfile @@ -0,0 +1,19 @@ +# Dockerfile for RabbitMQ worker +# +ARG RABBITMQ_VERSION=3.11-alpine + +FROM rabbitmq:${RABBITMQ_VERSION} +LABEL maintainer="IETF Tools Team " + +# Copy the startup file +COPY dev/mq/ietf-rabbitmq-server.bash /ietf-rabbitmq-server.bash +RUN sed -i 's/\r$//' /ietf-rabbitmq-server.bash && \ + chmod +x /ietf-rabbitmq-server.bash + +# Put the rabbitmq.conf in the conf.d so it runs after 10-defaults.conf. +# Can override this for an individual container by mounting additional +# config files in /etc/rabbitmq/conf.d. +COPY dev/mq/rabbitmq.conf /etc/rabbitmq/conf.d/20-ietf-config.conf +COPY dev/mq/definitions.json /definitions.json + +CMD ["/ietf-rabbitmq-server.bash"] diff --git a/dev/mq/definitions.json b/dev/mq/definitions.json new file mode 100644 index 00000000000..60e4fdba070 --- /dev/null +++ b/dev/mq/definitions.json @@ -0,0 +1,30 @@ +{ + "permissions": [ + { + "configure": ".*", + "read": ".*", + "user": "datatracker", + "vhost": "dt", + "write": ".*" + } + ], + "users": [ + { + "hashing_algorithm": "rabbit_password_hashing_sha256", + "limits": {}, + "name": "datatracker", + "password_hash": "", + "tags": [] + } + ], + "vhosts": [ + { + "limits": [], + "metadata": { + "description": "", + "tags": [] + }, + "name": "dt" + } + ] +} diff --git a/dev/mq/ietf-rabbitmq-server.bash b/dev/mq/ietf-rabbitmq-server.bash new file mode 100755 index 00000000000..56effba1794 --- /dev/null +++ b/dev/mq/ietf-rabbitmq-server.bash @@ -0,0 +1,22 @@ +#!/bin/bash -x +# +# Environment parameters: +# +# CELERY_PASSWORD - password for the datatracker celery user +# +export RABBITMQ_PID_FILE=/tmp/rabbitmq.pid + +update_celery_password () { + rabbitmqctl wait "${RABBITMQ_PID_FILE}" --timeout 300 + rabbitmqctl await_startup --timeout 300 + if [[ -n "${CELERY_PASSWORD}" ]]; then + rabbitmqctl change_password datatracker < { + result.push( + `"${key}": ${template(value.replaceAll('{', '{data.'), { interpolate, variable: 'data' }).source.replace('function(obj)', '(obj) =>')}` + ) + }, + [] + ) + + return { + code: code.replace('/* __COMPILED_URLS__ */', compiledUrls.join(',\n')), + map: null + } + } + } +} diff --git a/dev/vite-plugins/serve-preview-assets.js b/dev/vite-plugins/serve-preview-assets.js new file mode 100644 index 00000000000..1b8dfe79f18 --- /dev/null +++ b/dev/vite-plugins/serve-preview-assets.js @@ -0,0 +1,16 @@ +import send from 'send' +import path from 'path' +import url from 'url' + +export default function servePreviewAssets() { + return { + name: 'serve-preview-assets', + configurePreviewServer(server) { + server.middlewares.use('/media/floor', (req, res, _next) => { + send(req, url.parse(req.url).pathname, { + root: path.join(process.cwd(), 'playwright/data/floor-plan-images') + }).pipe(res) + }) + } + } +} diff --git a/docker-compose.yml b/docker-compose.yml index 13f628bf491..073d04b896a 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,5 +1,3 @@ -version: '3.8' - services: app: build: @@ -15,16 +13,20 @@ services: # network_mode: service:db depends_on: + - blobdb + - blobstore - db + - mq ipc: host - # environment: + environment: + DISPLAY: host.docker.internal:0 # USER: django # UID: 1001 # GID: 1001 # DATADIR: data - # DJANGO_SETTINGS_MODULE: settings_sqlitetest + # DJANGO_SETTINGS_MODULE: settings_test # Uncomment the next line to use a non-root user for all processes. # user: dev @@ -35,29 +37,135 @@ services: db: image: ghcr.io/ietf-tools/datatracker-db:latest # build: - # context: .. + # context: . # dockerfile: docker/db.Dockerfile restart: unless-stopped volumes: - - mariadb-data:/var/lib/mysql - environment: - MYSQL_ROOT_PASSWORD: RkTkDPFnKpko - MYSQL_DATABASE: ietf_utf8 - MYSQL_USER: django - MYSQL_PASSWORD: RkTkDPFnKpko - command: - - '--character-set-server=utf8' - - '--collation-server=utf8_unicode_ci' - - '--innodb-buffer-pool-size=1G' - - '--innodb-log-buffer-size=128M' - - '--innodb-log-file-size=256M' - - '--innodb-write-io-threads=8' - - '--innodb-flush-log-at-trx-commit=0' - - '--performance-schema=1' + - postgresdb-data:/var/lib/postgresql/data # Add "forwardPorts": ["5432"] to **devcontainer.json** to forward PostgreSQL locally. # (Adding the "ports" property to this file will not forward from a Codespace.) + pgadmin: + image: dpage/pgadmin4:latest + restart: unless-stopped + environment: + - PGADMIN_DEFAULT_EMAIL=dev@ietf.org + - PGADMIN_DEFAULT_PASSWORD=dev + - PGADMIN_CONFIG_LOGIN_BANNER="Login with dev@ietf.org / dev" + - PGADMIN_DISABLE_POSTFIX=True + - PGADMIN_CONFIG_MASTER_PASSWORD_REQUIRED=False + - SCRIPT_NAME=/pgadmin + volumes: + - ./docker/configs/pgadmin-servers.json:/pgadmin4/servers.json + + static: + image: ghcr.io/ietf-tools/static:latest + restart: unless-stopped + + mq: + image: rabbitmq:3-alpine + restart: unless-stopped + + celery: + build: + context: . + dockerfile: docker/celery.Dockerfile + init: true + environment: + CELERY_APP: ietf + CELERY_ROLE: worker + UPDATE_REQUIREMENTS_FROM: requirements.txt + DEV_MODE: "yes" + command: + - '--loglevel=INFO' + depends_on: + - blobdb + - blobstore + - db + - mq + restart: unless-stopped + stop_grace_period: 1m + volumes: + - .:/workspace + - app-assets:/assets + + replicator: + build: + context: . + dockerfile: docker/celery.Dockerfile + init: true + environment: + CELERY_APP: ietf + CELERY_ROLE: worker + UPDATE_REQUIREMENTS_FROM: requirements.txt + DEV_MODE: "yes" + command: + - '--loglevel=INFO' + - '--queues=blobdb' + - '--concurrency=1' + + depends_on: + - blobdb + - blobstore + - db + - mq + restart: unless-stopped + stop_grace_period: 1m + volumes: + - .:/workspace + - app-assets:/assets + + blobstore: + image: ghcr.io/ietf-tools/datatracker-devblobstore:latest + restart: unless-stopped + volumes: + - "minio-data:/data" + + blobdb: + image: postgres:17 + restart: unless-stopped + environment: + POSTGRES_DB: blob + POSTGRES_USER: dt + POSTGRES_PASSWORD: abcd1234 + volumes: + - blobdb-data:/var/lib/postgresql/data + +# typesense: +# image: typesense/typesense:30.1 +# restart: on-failure +# ports: +# - "8108:8108" +# volumes: +# - ./typesense-data:/data +# command: +# - '--data-dir=/data' +# - '--api-key=typesense-api-key' +# - '--enable-cors' + +# Celery Beat is a periodic task runner. It is not normally needed for development, +# but can be enabled by uncommenting the following. +# +# beat: +# image: "${COMPOSE_PROJECT_NAME}-celery" +# init: true +# environment: +# CELERY_APP: ietf +# CELERY_ROLE: beat +# UPDATE_REQUIREMENTS_FROM: requirements.txt +# command: +# - '--loglevel=INFO' +# depends_on: +# - db +# restart: unless-stopped +# stop_grace_period: 1m +# volumes: +# - .:/workspace +# - app-assets:/assets + volumes: - mariadb-data: + postgresdb-data: app-assets: + minio-data: + blobdb-data: diff --git a/docker/README.md b/docker/README.md index a78e705a47c..0ca79a6e899 100644 --- a/docker/README.md +++ b/docker/README.md @@ -1,14 +1,28 @@ # Datatracker Development in Docker +- [Getting started](#getting-started) +- [Using Visual Studio Code](#using-visual-studio-code) + - [Initial Setup](#initial-setup) + - [Subsequent Launch](#subsequent-launch) + - [Usage](#usage) +- [Using Other Editors / Generic](#using-other-editors--generic) + - [Exit Environment](#exit-environment) + - [Accessing PostgreSQL Port](#accessing-postgresql-port) +- [Clean and Rebuild DB from latest image](#clean-and-rebuild-db-from-latest-image) +- [Clean all](#clean-all) +- [Updating an older environment](#updating-an-older-environment) +- [Notes / Troubleshooting](#notes--troubleshooting) + ## Getting started 1. [Set up Docker](https://docs.docker.com/get-started/) on your preferred platform. On Windows, it is highly recommended to use the [WSL 2 *(Windows Subsystem for Linux)*](https://docs.docker.com/desktop/windows/wsl/) backend. +> [!IMPORTANT] > See the [IETF Tools Windows Dev guide](https://github.com/ietf-tools/.github/blob/main/docs/windows-dev.md) on how to get started when using Windows. -2. On Linux, you must also install [Docker Compose](https://docs.docker.com/compose/install/). Docker Desktop for Mac and Windows already include Docker Compose. +2. On Linux, you must [install Docker Compose manually](https://docs.docker.com/compose/install/linux/#install-the-plugin-manually) and not install Docker Desktop. On Mac and Windows install Docker Desktop which already includes Docker Compose. -2. If you have a copy of the datatracker code checked out already, simply `cd` to the top-level directory. +3. If you have a copy of the datatracker code checked out already, simply `cd` to the top-level directory. If not, check out a datatracker branch as usual. We'll check out `main` below, but you can use any branch: @@ -18,7 +32,7 @@ git checkout main ``` -3. Follow the instructions for your preferred editor: +4. Follow the instructions for your preferred editor: - [Visual Studio Code](#using-visual-studio-code) - [Other Editors / Generic](#using-other-editors--generic) @@ -27,9 +41,11 @@ This project includes a devcontainer configuration which automates the setup of the development environment with all the required dependencies. ### Initial Setup - + 1. Launch [VS Code](https://code.visualstudio.com/) -2. Under the **Extensions** tab, ensure you have the **Remote - Containers** ([ms-vscode-remote.remote-containers](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers)) extension installed. On Windows, you also need the **Remote - WSL** ([ms-vscode-remote.remote-wsl](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-wsl)) extension to take advantage of the WSL 2 *(Windows Subsystem for Linux)* native integration. +2. Under the **Extensions** tab, ensure you have the **Dev Containers** ([ms-vscode-remote.remote-containers](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers)) extension installed. + * On Linux, note that the Snap installation of VS Code is [incompatible with this plugin](https://code.visualstudio.com/docs/devcontainers/containers#_system-requirements:~:text=snap%20package%20is%20not%20supported). + * On Windows, you also need the **WSL** ([ms-vscode-remote.remote-wsl](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-wsl)) extension to take advantage of the WSL 2 *(Windows Subsystem for Linux)* native integration. 2. Open the top-level directory of the datatracker code you fetched above. 3. A prompt inviting you to reopen the project in containers will appear in the bottom-right corner. Click the **Reopen in Container** button. If you missed the prompt, you can press `F1`, start typing `reopen in container` task and launch it. 4. VS Code will relaunch in the dev environment and create the containers automatically. @@ -43,9 +59,9 @@ You can also open the datatracker project folder and click the **Reopen in conta ### Usage -- Under the **Run and Debug** tab, you can run the server with the debugger attached using **Run Server** (F5). Once the server is ready to accept connections, you'll be prompted to open in a browser. You can also open [http://localhost:8000](http://localhost:8000) in a browser. - - > An alternate profile **Run Server with Debug Toolbar** is also available from the dropdown menu, which displays various tools +- Under the **Run and Debug** tab, you can run the server with the debugger attached using **Run Server** (F5). Once the server is ready to accept connections, you'll be prompted to open in a browser. Navigate to [http://localhost:8000](http://localhost:8000) in your preferred browser. + + > An alternate profile **Run Server with Debug Toolbar** is also available from the dropdown menu, which displays various tools on top of the webpage. However, note that this configuration has a significant performance impact. To add a **Breakpoint**, simply click to the left of the line gutter you wish to stop at. You can also add **Conditional Breakpoints** and **Logpoint** by right-clicking at the same location. @@ -62,11 +78,7 @@ You can also open the datatracker project folder and click the **Reopen in conta ![](assets/vscode-terminal-new.png) -- Under the **SQL Tools** tab, a connection **Local Dev** is preconfigured to connect to the DB container. Using this tool, you can list tables, view records and execute SQL queries directly from VS Code. - - > The port `3306` is also exposed to the host automatically, should you prefer to use your own SQL tool. - - ![](assets/vscode-sqltools.png) +- The pgAdmin web interface, a PostgreSQL DB browser / management UI, is available at [http://localhost:8000/pgadmin/](http://localhost:8000/pgadmin/). - Under the **Task Explorer** tab, a list of available preconfigured tasks is displayed. *(You may need to expand the tree to `src > vscode` to see it.)* These are common scritps you can run *(e.g. run tests, fetch assets, etc.)*. @@ -85,24 +97,23 @@ You can also open the datatracker project folder and click the **Reopen in conta On Linux / macOS: ```sh - cd docker - ./run + ./docker/run # or whatever path you need ``` - - > Note that you can pass the `-r` flag to `./run` to force a rebuild of the containers. This is useful if you switched branches and that the existing containers still contain configurations from the old branch. You should also use this if you don't regularly keep up with main and your containers reflect a much older version of the branch. + + > Note that you can pass the `-r` flag to `run` to force a rebuild of the containers. This is useful if you switched branches and that the existing containers still contain configurations from the old branch. You should also use this if you don't regularly keep up with main and your containers reflect a much older version of the branch. On Windows *(using Powershell)*: ```sh Copy-Item "docker/docker-compose.extend.yml" -Destination "docker/docker-compose.extend-custom.yml" (Get-Content -path docker/docker-compose.extend-custom.yml -Raw) -replace 'CUSTOM_PORT','8000' | Set-Content -Path docker/docker-compose.extend-custom.yml - docker-compose -f docker-compose.yml -f docker/docker-compose.extend-custom.yml up -d - docker-compose exec app /bin/sh /docker-init.sh + docker compose -f docker-compose.yml -f docker/docker-compose.extend-custom.yml up -d + docker compose exec app /bin/sh /docker-init.sh ``` 2. Wait for the containers to initialize. Upon completion, you will be dropped into a shell from which you can start the datatracker and execute related commands as usual, for example ``` - ietf/manage.py runserver 0.0.0.0:8000 + ietf/manage.py runserver 8001 ``` to start the datatracker. @@ -120,12 +131,19 @@ The containers will automatically be shut down on Linux / macOS. On Windows, type the command ```sh -docker-compose down +docker compose down ``` to terminate the containers. -### Clean and Rebuild DB from latest image +### Accessing PostgreSQL Port + +The port is exposed but not automatically mapped to `5432` to avoid potential conflicts with the host. To get the mapped port, run the command *(from the project `/docker` directory)*: +```sh +docker compose port db 5432 +``` + +## Clean and Rebuild DB from latest image To delete the active DB container, its volume and get the latest image / DB dump, simply run the following command: @@ -138,12 +156,12 @@ cd docker On Windows: ```sh -docker-compose down -v -docker-compose pull db -docker-compose build --no-cache db +docker compose down -v +docker compose pull db +docker compose build --no-cache db ``` -### Clean all +## Clean all To delete all containers for this project, its associated images and purge any remaining dangling images, simply run the following command: @@ -156,15 +174,23 @@ cd docker On Windows: ```sh -docker-compose down -v --rmi all -docker image prune +docker compose down -v --rmi all +docker image prune ``` -### Accessing MariaDB Port +## Updating an older environment + +If you already have a clone, such as from a previous codesprint, and are updating that clone, before starting the datatracker from the updated image: +1. `rm ietf/settings_local.py` *(The startup script will put a new one, appropriate to the current release, in place)* +1. Execute the [Clean all](#clean-all) sequence above. + +If the dev environment fails to start, even after running the [Clean all](#clean-all) sequence above, you can fully purge all docker cache, containers, images and volumes by running the command below. + +> [!CAUTION] +> Note that this will delete everything docker-related, including non-datatracker docker resources you might have. -The port is exposed but not mapped to `3306` to avoid potential conflicts with the host. To get the mapped port, run the command *(from the project `/docker` directory)*: ```sh -docker-compose port db 3306 +docker system prune -a --volumes ``` ## Notes / Troubleshooting @@ -186,3 +212,17 @@ The content of the source files will be copied into the target `.ics` files. Mak ### Missing assets in the data folder Because including all assets in the image would significantly increase the file size, they are not included by default. You can however fetch them by running the **Fetch assets via rsync** task in VS Code or run manually the script `docker/scripts/app-rsync-extras.sh` + +### Linux file permissions leaking to the host system + +If on the host filesystem you have permissions that look like this, + +```bash +$ ls -la +total 4624 +drwxrwxr-x 2 100999 100999 4096 May 25 07:56 bin +drwxrwxr-x 5 100999 100999 4096 May 25 07:56 client +(etc...) +``` + +Try uninstalling Docker Desktop and installing Docker Compose manually. The Docker Compose bundled with Docker Desktop is incompatible with our software. See also [Rootless Docker: file ownership changes #3343](https://github.com/lando/lando/issues/3343), [Docker context desktop-linux has container permission issues #75](https://github.com/docker/desktop-linux/issues/75). diff --git a/docker/app.Dockerfile b/docker/app.Dockerfile index 6d539b1a561..dd4cf72ffd9 100644 --- a/docker/app.Dockerfile +++ b/docker/app.Dockerfile @@ -9,6 +9,7 @@ ARG USER_UID=1000 ARG USER_GID=$USER_UID COPY docker/scripts/app-setup-debian.sh /tmp/library-scripts/docker-setup-debian.sh RUN sed -i 's/\r$//' /tmp/library-scripts/docker-setup-debian.sh && chmod +x /tmp/library-scripts/docker-setup-debian.sh + RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \ # Remove imagemagick due to https://security-tracker.debian.org/tracker/CVE-2019-10131 && apt-get purge -y imagemagick imagemagick-6-common \ @@ -24,12 +25,21 @@ COPY docker/scripts/app-setup-python.sh /tmp/library-scripts/docker-setup-python RUN sed -i 's/\r$//' /tmp/library-scripts/docker-setup-python.sh && chmod +x /tmp/library-scripts/docker-setup-python.sh RUN bash /tmp/library-scripts/docker-setup-python.sh "none" "/usr/local" "${PIPX_HOME}" "${USERNAME}" +# Setup nginx +COPY docker/scripts/app-setup-nginx.sh /tmp/library-scripts/docker-setup-nginx.sh +RUN sed -i 's/\r$//' /tmp/library-scripts/docker-setup-nginx.sh && chmod +x /tmp/library-scripts/docker-setup-nginx.sh +RUN bash /tmp/library-scripts/docker-setup-nginx.sh +COPY docker/configs/nginx-proxy.conf /etc/nginx/sites-available/default +COPY docker/configs/nginx-502.html /var/www/html/502.html + # Remove library scripts for final image RUN rm -rf /tmp/library-scripts # Copy the startup file COPY docker/scripts/app-init.sh /docker-init.sh -RUN sed -i 's/\r$//' /docker-init.sh && chmod +x /docker-init.sh +COPY docker/scripts/app-start.sh /docker-start.sh +RUN sed -i 's/\r$//' /docker-init.sh && chmod +rx /docker-init.sh +RUN sed -i 's/\r$//' /docker-start.sh && chmod +rx /docker-start.sh # Fix user UID / GID to match host RUN groupmod --gid $USER_GID $USERNAME \ diff --git a/docker/base.Dockerfile b/docker/base.Dockerfile index 97604e62f95..7caba501d7c 100644 --- a/docker/base.Dockerfile +++ b/docker/base.Dockerfile @@ -1,132 +1,153 @@ -FROM python:3.9-bullseye -LABEL maintainer="IETF Tools Team " - -ENV DEBIAN_FRONTEND=noninteractive - -# Update system packages -RUN apt-get update \ - && apt-get -qy upgrade \ - && apt-get -y install --no-install-recommends apt-utils dialog 2>&1 - -# Add Node.js Source -RUN curl -fsSL https://deb.nodesource.com/setup_16.x | bash - - -# Add Docker Source -RUN curl -fsSL https://download.docker.com/linux/debian/gpg | gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg -RUN echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/debian \ - $(lsb_release -cs) stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null - -# Install the packages we need -RUN apt-get update --fix-missing && apt-get install -qy \ - apache2-utils \ - apt-file \ - bash \ - build-essential \ - curl \ - default-jdk \ - docker-ce-cli \ - enscript \ - gawk \ - g++ \ - gcc \ - ghostscript \ - git \ - gnupg \ - jq \ - less \ - libcairo2-dev \ - libgtk2.0-0 \ - libgtk-3-0 \ - libnotify-dev \ - libgconf-2-4 \ - libgbm-dev \ - libnss3 \ - libxss1 \ - libasound2 \ - libxtst6 \ - libmagic-dev \ - libmariadb-dev \ - libmemcached-tools \ - locales \ - make \ - mariadb-client \ - memcached \ - nano \ - netcat \ - nodejs \ - pigz \ - pv \ - python3-ipython \ - ripgrep \ - rsync \ - rsyslog \ - ruby \ - ruby-rubygems \ - unzip \ - wget \ - xauth \ - xvfb \ - yang-tools \ - zsh - -# Install kramdown-rfc2629 (ruby) -RUN gem install kramdown-rfc2629 - -# Install chromedriver -COPY docker/scripts/app-install-chromedriver.sh /tmp/app-install-chromedriver.sh -RUN sed -i 's/\r$//' /tmp/app-install-chromedriver.sh && \ - chmod +x /tmp/app-install-chromedriver.sh -RUN /tmp/app-install-chromedriver.sh - -# Fix /dev/shm permissions for chromedriver -RUN chmod 1777 /dev/shm - -# Activate Yarn -RUN corepack enable - -# Get rid of installation files we don't need in the image, to reduce size -RUN apt-get autoremove -y && apt-get clean -y && rm -rf /var/lib/apt/lists/* - -# "fake" dbus address to prevent errors -# https://github.com/SeleniumHQ/docker-selenium/issues/87 -ENV DBUS_SESSION_BUS_ADDRESS=/dev/null - -# avoid million NPM install messages -ENV npm_config_loglevel warn -# allow installing when the main user is root -ENV npm_config_unsafe_perm true -# disable NPM funding messages -ENV npm_config_fund false - -# Set locale to en_US.UTF-8 -RUN echo "LC_ALL=en_US.UTF-8" >> /etc/environment && \ - echo "en_US.UTF-8 UTF-8" >> /etc/locale.gen && \ - echo "LANG=en_US.UTF-8" > /etc/locale.conf && \ - dpkg-reconfigure locales && \ - locale-gen en_US.UTF-8 && \ - update-locale LC_ALL en_US.UTF-8 -ENV LC_ALL en_US.UTF-8 - -# Install idnits -ADD https://raw.githubusercontent.com/ietf-tools/idnits-mirror/main/idnits /usr/local/bin/ -RUN chmod +rx /usr/local/bin/idnits - -# Turn off rsyslog kernel logging (doesn't work in Docker) -RUN sed -i '/imklog/s/^/#/' /etc/rsyslog.conf - -# Colorize the bash shell -RUN sed -i 's/#force_color_prompt=/force_color_prompt=/' /root/.bashrc - -# Turn off rsyslog kernel logging (doesn't work in Docker) -RUN sed -i '/imklog/s/^/#/' /etc/rsyslog.conf - -# Fetch wait-for utility -ADD https://raw.githubusercontent.com/eficode/wait-for/v2.1.3/wait-for /usr/local/bin/ -RUN chmod +rx /usr/local/bin/wait-for - -# Create assets directory -RUN mkdir -p /assets - -# Create workspace -RUN mkdir -p /workspace -WORKDIR /workspace +FROM python:3.12-trixie +LABEL maintainer="IETF Tools Team " + +ENV DEBIAN_FRONTEND=noninteractive +ENV NODE_MAJOR=26 + +# Update system packages +RUN apt-get update \ + && apt-get -qy upgrade \ + && apt-get -y install --no-install-recommends dialog 2>&1 + +# Add Node.js Source +RUN apt-get install -y --no-install-recommends ca-certificates curl gnupg \ + && mkdir -p /etc/apt/keyrings \ + && curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg \ + && echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_$NODE_MAJOR.x nodistro main" | tee /etc/apt/sources.list.d/nodesource.list +RUN echo "Package: nodejs" >> /etc/apt/preferences.d/preferences \ + && echo "Pin: origin deb.nodesource.com" >> /etc/apt/preferences.d/preferences \ + && echo "Pin-Priority: 1001" >> /etc/apt/preferences.d/preferences + +# Add Docker Source +RUN mkdir -p /etc/apt/keyrings \ + && curl -fsSL https://download.docker.com/linux/debian/gpg | gpg --dearmor -o /etc/apt/keyrings/docker-archive-keyring.gpg \ + && echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/debian $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | tee /etc/apt/sources.list.d/docker.list + +# Add PostgreSQL Source +RUN mkdir -p /etc/apt/keyrings \ + && curl -fsSL https://www.postgresql.org/media/keys/ACCC4CF8.asc | gpg --dearmor -o /etc/apt/keyrings/apt.postgresql.org.gpg \ + && echo "deb [signed-by=/etc/apt/keyrings/apt.postgresql.org.gpg] https://apt.postgresql.org/pub/repos/apt $(. /etc/os-release && echo "$VERSION_CODENAME")-pgdg main" | tee /etc/apt/sources.list.d/pgdg.list + +# Install the packages we need +RUN apt-get update --fix-missing && apt-get install -qy --no-install-recommends \ + apache2-utils \ + apt-file \ + bash \ + build-essential \ + curl \ + default-jdk \ + docker-ce-cli \ + enscript \ + firefox-esr \ + gawk \ + g++ \ + gcc \ + ghostscript \ + git \ + gnupg \ + jq \ + less \ + libcairo2-dev \ + libgtk2.0-0 \ + libgtk-3-0 \ + libnotify-dev \ + libgbm-dev \ + libnss3 \ + libxss1 \ + libasound2 \ + libxtst6 \ + libmagic-dev \ + libmariadb-dev \ + libmemcached-tools \ + libyang3-tools \ + locales \ + make \ + mariadb-client \ + memcached \ + nano \ + netcat-traditional \ + nodejs \ + pgloader \ + pigz \ + postgresql-client-17 \ + pv \ + python3-ipython \ + ripgrep \ + rsync \ + rsyslog \ + ruby \ + ruby-rubygems \ + unzip \ + wget \ + xauth \ + xvfb \ + zsh + +# Install kramdown-rfc2629 (ruby) +RUN gem install kramdown-rfc2629 + +# GeckoDriver +ARG GECKODRIVER_VERSION=latest +RUN GK_VERSION=$(if [ ${GECKODRIVER_VERSION:-latest} = "latest" ]; then echo "0.34.0"; else echo $GECKODRIVER_VERSION; fi) \ + && echo "Using GeckoDriver version: "$GK_VERSION \ + && wget --no-verbose -O /tmp/geckodriver.tar.gz https://github.com/mozilla/geckodriver/releases/download/v$GK_VERSION/geckodriver-v$GK_VERSION-linux64.tar.gz \ + && rm -rf /opt/geckodriver \ + && tar -C /opt -zxf /tmp/geckodriver.tar.gz \ + && rm /tmp/geckodriver.tar.gz \ + && mv /opt/geckodriver /opt/geckodriver-$GK_VERSION \ + && chmod 755 /opt/geckodriver-$GK_VERSION \ + && ln -fs /opt/geckodriver-$GK_VERSION /usr/bin/geckodriver + +# Get rid of installation files we don't need in the image, to reduce size +RUN apt-get autoremove -y && apt-get clean -y && rm -rf /var/lib/apt/lists/* /var/cache/apt/* + +# "fake" dbus address to prevent errors +# https://github.com/SeleniumHQ/docker-selenium/issues/87 +ENV DBUS_SESSION_BUS_ADDRESS=/dev/null + +# avoid million NPM install messages +ENV npm_config_loglevel=warn +# disable NPM funding messages +ENV npm_config_fund=false + +# Set locale to en_US.UTF-8 +RUN echo "LC_ALL=en_US.UTF-8" >> /etc/environment && \ + echo "en_US.UTF-8 UTF-8" >> /etc/locale.gen && \ + echo "LANG=en_US.UTF-8" > /etc/locale.conf && \ + dpkg-reconfigure locales && \ + locale-gen en_US.UTF-8 && \ + update-locale LC_ALL en_US.UTF-8 +ENV LC_ALL=en_US.UTF-8 + +# Install idnits +ADD https://raw.githubusercontent.com/ietf-tools/idnits-mirror/main/idnits /usr/local/bin/ +RUN chmod +rx /usr/local/bin/idnits + +# Install required fonts +RUN mkdir -p /tmp/fonts && \ + wget -q -O /tmp/fonts.tar.gz https://github.com/ietf-tools/xml2rfc-fonts/archive/refs/tags/3.22.0.tar.gz && \ + tar zxf /tmp/fonts.tar.gz -C /tmp/fonts && \ + mv /tmp/fonts/*/noto/* /usr/local/share/fonts/ && \ + mv /tmp/fonts/*/roboto_mono/* /usr/local/share/fonts/ && \ + rm -rf /tmp/fonts.tar.gz /tmp/fonts/ && \ + fc-cache -f + +# Turn off rsyslog kernel logging (doesn't work in Docker) +RUN sed -i '/imklog/s/^/#/' /etc/rsyslog.conf + +# Colorize the bash shell +RUN sed -i 's/#force_color_prompt=/force_color_prompt=/' /root/.bashrc + +# Turn off rsyslog kernel logging (doesn't work in Docker) +RUN sed -i '/imklog/s/^/#/' /etc/rsyslog.conf + +# Fetch wait-for utility +ADD https://raw.githubusercontent.com/eficode/wait-for/v2.1.3/wait-for /usr/local/bin/ +RUN chmod +rx /usr/local/bin/wait-for + +# Create assets directory +RUN mkdir -p /assets + +# Create workspace +RUN mkdir -p /workspace +WORKDIR /workspace diff --git a/docker/celery.Dockerfile b/docker/celery.Dockerfile new file mode 100644 index 00000000000..e93ca3cf77c --- /dev/null +++ b/docker/celery.Dockerfile @@ -0,0 +1,55 @@ +FROM ghcr.io/ietf-tools/datatracker-app-base:latest +LABEL maintainer="IETF Tools Team " + +ENV DEBIAN_FRONTEND=noninteractive + +# Install needed packages and setup non-root user. +ARG USERNAME=dev +ARG USER_UID=1000 +ARG USER_GID=$USER_UID +COPY docker/scripts/app-setup-debian.sh /tmp/library-scripts/docker-setup-debian.sh +RUN sed -i 's/\r$//' /tmp/library-scripts/docker-setup-debian.sh && chmod +x /tmp/library-scripts/docker-setup-debian.sh + +RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \ + # Remove imagemagick due to https://security-tracker.debian.org/tracker/CVE-2019-10131 + && apt-get purge -y imagemagick imagemagick-6-common \ + # Install common packages, non-root user + # Syntax: ./docker-setup-debian.sh [install zsh flag] [username] [user UID] [user GID] [upgrade packages flag] [install Oh My Zsh! flag] [Add non-free packages] + && bash /tmp/library-scripts/docker-setup-debian.sh "true" "${USERNAME}" "${USER_UID}" "${USER_GID}" "false" "true" "true" + +# Setup default python tools in a venv via pipx to avoid conflicts +ENV PIPX_HOME=/usr/local/py-utils \ + PIPX_BIN_DIR=/usr/local/py-utils/bin +ENV PATH=${PATH}:${PIPX_BIN_DIR} +COPY docker/scripts/app-setup-python.sh /tmp/library-scripts/docker-setup-python.sh +RUN sed -i 's/\r$//' /tmp/library-scripts/docker-setup-python.sh && chmod +x /tmp/library-scripts/docker-setup-python.sh +RUN bash /tmp/library-scripts/docker-setup-python.sh "none" "/usr/local" "${PIPX_HOME}" "${USERNAME}" + +# Remove library scripts for final image +RUN rm -rf /tmp/library-scripts + +# Copy the startup file +COPY docker/scripts/app-init-celery.sh /docker-init.sh +RUN sed -i 's/\r$//' /docker-init.sh && \ + chmod +x /docker-init.sh + +ENTRYPOINT [ "/docker-init.sh" ] + +# Fix user UID / GID to match host +RUN groupmod --gid $USER_GID $USERNAME \ + && usermod --uid $USER_UID --gid $USER_GID $USERNAME \ + && chown -R $USER_UID:$USER_GID /home/$USERNAME \ + || exit 0 + +# Switch to local dev user +USER dev:dev + +# Install current datatracker python dependencies +COPY requirements.txt /tmp/pip-tmp/ +RUN pip3 --disable-pip-version-check --no-cache-dir install --user --no-warn-script-location -r /tmp/pip-tmp/requirements.txt +RUN pip3 --disable-pip-version-check --no-cache-dir install --user --no-warn-script-location watchdog[watchmedo] + +RUN sudo rm -rf /tmp/pip-tmp + +VOLUME [ "/assets" ] + diff --git a/docker/cleanall b/docker/cleanall index 91eac1764bf..c6104aaef99 100755 --- a/docker/cleanall +++ b/docker/cleanall @@ -1,5 +1,11 @@ #!/bin/bash +if test $(basename $PWD ) != "docker" +then + echo "Run this from the docker directory" 1>&2 + exit 1 +fi + read -p "Stop and remove all containers, volumes and images for this project? [y/N] " -n 1 -r echo if [[ $REPLY =~ ^[Yy]$ ]] @@ -7,6 +13,5 @@ then cd .. echo "Shutting down any instance still running and purge images..." docker compose down -v --rmi all - cd docker echo "Done!" fi diff --git a/docker/cleandb b/docker/cleandb index f772ebce396..c881503eae7 100755 --- a/docker/cleandb +++ b/docker/cleandb @@ -1,13 +1,19 @@ #!/bin/bash +if test $(basename $PWD ) != "docker" +then + echo "Run this from the docker directory" 1>&2 + exit 1 +fi + cd .. echo "Shutting down any instance still running..." docker compose down echo "Removing DB volume..." PROJNAME=$(basename $PWD) -docker volume rm -f "${PROJNAME}_mariadb-data" +docker volume rm -f "${PROJNAME}_postgresdb-data" echo "Rebuilding the DB image..." docker compose pull db docker compose build --no-cache db -cd docker + echo "Done!" diff --git a/docker/configs/nginx-502.html b/docker/configs/nginx-502.html new file mode 100644 index 00000000000..b5577d3e179 --- /dev/null +++ b/docker/configs/nginx-502.html @@ -0,0 +1,61 @@ + + + + + + Datatracker DEV + + + + IETF +

Datatracker

+

Could not connect to dev server.

+
+

Is the datatracker server running?

+

Using VS Code, open the Run and Debug tab on the left and click the symbol (Run Server) to start the server.

+

Otherwise, run the command ietf/manage.py runserver 8001 from the terminal.

+
+
+

You can manage the database at /pgadmin.

+
+

For more information, check out the Datatracker Development in Docker guide.

+ + diff --git a/docker/configs/nginx-proxy.conf b/docker/configs/nginx-proxy.conf new file mode 100644 index 00000000000..0a9dde04eb4 --- /dev/null +++ b/docker/configs/nginx-proxy.conf @@ -0,0 +1,41 @@ +upstream datatracker_backend { + server 127.0.0.1:8001; +# Uncomment when changing to nginx 1.29.7 or later. +# keepalive 0; # default = 32 since nginx 1.29.7 +} + +server { + listen 8000 default_server; + listen [::]:8000 default_server; + + proxy_read_timeout 1d; + proxy_send_timeout 1d; + client_max_body_size 0; # disable checking + + root /var/www/html; + index index.html index.htm index.nginx-debian.html; + + server_name _; + + location /_static/ { + proxy_pass http://static/; + } + + location /pgadmin/ { + proxy_set_header X-Script-Name /pgadmin; + proxy_set_header Host $host; + proxy_pass http://pgadmin; + proxy_redirect off; + } + + location / { + error_page 502 /502.html; + proxy_pass http://datatracker_backend/; + proxy_set_header Host localhost:8000; + } + + location /502.html { + root /var/www/html; + internal; + } +} diff --git a/docker/configs/pgadmin-servers.json b/docker/configs/pgadmin-servers.json new file mode 100644 index 00000000000..b4458af9235 --- /dev/null +++ b/docker/configs/pgadmin-servers.json @@ -0,0 +1,22 @@ +{ + "Servers": { + "1": { + "Name": "Local Dev", + "Group": "Servers", + "Host": "db", + "Port": 5432, + "MaintenanceDB": "postgres", + "Username": "django", + "UseSSHTunnel": 0, + "TunnelPort": "22", + "TunnelAuthentication": 0, + "KerberosAuthentication": false, + "ConnectionParameters": { + "sslmode": "prefer", + "connect_timeout": 10, + "sslcert": "/.postgresql/postgresql.crt", + "sslkey": "/.postgresql/postgresql.key" + } + } + } +} diff --git a/docker/configs/settings_local.py b/docker/configs/settings_local.py index 2b3d541387b..94adc516a47 100644 --- a/docker/configs/settings_local.py +++ b/docker/configs/settings_local.py @@ -1,35 +1,30 @@ -# Copyright The IETF Trust 2007-2019, All Rights Reserved +# Copyright The IETF Trust 2007-2025, All Rights Reserved # -*- coding: utf-8 -*- -from ietf.settings import * # pyflakes:ignore +from ietf.settings import * # pyflakes:ignore +from ietf.settings import ( + ARTIFACT_STORAGE_NAMES, + STORAGES, + BLOBSTORAGE_MAX_ATTEMPTS, + BLOBSTORAGE_READ_TIMEOUT, + BLOBSTORAGE_CONNECT_TIMEOUT, +) ALLOWED_HOSTS = ['*'] -DATABASES = { - 'default': { - 'HOST': 'db', - 'PORT': 3306, - 'NAME': 'ietf_utf8', - 'ENGINE': 'django.db.backends.mysql', - 'USER': 'django', - 'PASSWORD': 'RkTkDPFnKpko', - 'OPTIONS': { - 'sql_mode': 'STRICT_TRANS_TABLES', - 'init_command': 'SET storage_engine=InnoDB; SET names "utf8"', - }, - }, -} - -DATABASE_TEST_OPTIONS = { - 'init_command': 'SET storage_engine=InnoDB', +from ietf.settings_postgresqldb import DATABASES # pyflakes:ignore +DATABASE_ROUTERS = ["ietf.blobdb.routers.BlobdbStorageRouter"] +BLOBDB_DATABASE = "blobdb" +BLOBDB_REPLICATION = { + "ENABLED": True, + "DEST_STORAGE_PATTERN": "r2-{bucket}", + "INCLUDE_BUCKETS": ARTIFACT_STORAGE_NAMES, + "EXCLUDE_BUCKETS": ["staging"], + "VERBOSE_LOGGING": True, } IDSUBMIT_IDNITS_BINARY = "/usr/local/bin/idnits" -IDSUBMIT_REPOSITORY_PATH = "test/id/" -IDSUBMIT_STAGING_PATH = "test/staging/" -INTERNET_DRAFT_ARCHIVE_DIR = "test/archive/" -INTERNET_ALL_DRAFTS_ARCHIVE_DIR = "test/archive/" -RFC_PATH = "test/rfc/" +IDSUBMIT_STAGING_PATH = "/assets/www6s/staging/" AGENDA_PATH = '/assets/www6s/proceedings/' MEETINGHOST_LOGO_PATH = AGENDA_PATH @@ -47,30 +42,81 @@ SUBMIT_YANG_CATALOG_MODEL_DIR = '/assets/ietf-ftp/yang/catalogmod/' SUBMIT_YANG_DRAFT_MODEL_DIR = '/assets/ietf-ftp/yang/draftmod/' -SUBMIT_YANG_INVAL_MODEL_DIR = '/assets/ietf-ftp/yang/invalmod/' SUBMIT_YANG_IANA_MODEL_DIR = '/assets/ietf-ftp/yang/ianamod/' SUBMIT_YANG_RFC_MODEL_DIR = '/assets/ietf-ftp/yang/rfcmod/' # Set INTERNAL_IPS for use within Docker. See https://knasmueller.net/fix-djangos-debug-toolbar-not-showing-inside-docker import socket hostname, _, ips = socket.gethostbyname_ex(socket.gethostname()) -INTERNAL_IPS = [".".join(ip.split(".")[:-1] + ["1"]) for ip in ips] +INTERNAL_IPS = [".".join(ip.split(".")[:-1] + ["1"]) for ip in ips] + ['127.0.0.1'] # DEV_TEMPLATE_CONTEXT_PROCESSORS = [ # 'ietf.context_processors.sql_debug', # ] -DOCUMENT_PATH_PATTERN = '/assets/ietf-ftp/{doc.type_id}/' +DOCUMENT_PATH_PATTERN = '/assets/ietfdata/doc/{doc.type_id}/' INTERNET_DRAFT_PATH = '/assets/ietf-ftp/internet-drafts/' RFC_PATH = '/assets/ietf-ftp/rfc/' CHARTER_PATH = '/assets/ietf-ftp/charter/' BOFREQ_PATH = '/assets/ietf-ftp/bofreq/' CONFLICT_REVIEW_PATH = '/assets/ietf-ftp/conflict-reviews/' STATUS_CHANGE_PATH = '/assets/ietf-ftp/status-changes/' -INTERNET_DRAFT_ARCHIVE_DIR = '/assets/ietf-ftp/internet-drafts/' -INTERNET_ALL_DRAFTS_ARCHIVE_DIR = '/assets/ietf-ftp/internet-drafts/' +INTERNET_DRAFT_ARCHIVE_DIR = '/assets/collection/draft-archive' +INTERNET_ALL_DRAFTS_ARCHIVE_DIR = '/assets/archive/id' +BIBXML_BASE_PATH = '/assets/ietfdata/derived/bibxml' +IDSUBMIT_REPOSITORY_PATH = INTERNET_DRAFT_PATH +FTP_DIR = '/assets/ftp' +NFS_METRICS_TMP_DIR = '/assets/tmp' NOMCOM_PUBLIC_KEYS_DIR = 'data/nomcom_keys/public_keys/' -SLIDE_STAGING_PATH = 'test/staging/' +SLIDE_STAGING_PATH = '/assets/www6s/staging/' DE_GFM_BINARY = '/usr/local/bin/de-gfm' + +STATIC_IETF_ORG = "/_static" +STATIC_IETF_ORG_INTERNAL = "http://static" + + +# Blob replication storage for dev +import botocore.config +for storagename in ARTIFACT_STORAGE_NAMES: + replica_storagename = f"r2-{storagename}" + STORAGES[replica_storagename] = { + "BACKEND": "ietf.doc.storage.MetadataS3Storage", + "OPTIONS": dict( + endpoint_url="http://blobstore:9000", + access_key="minio_root", + secret_key="minio_pass", + security_token=None, + client_config=botocore.config.Config( + request_checksum_calculation="when_required", + response_checksum_validation="when_required", + signature_version="s3v4", + connect_timeout=BLOBSTORAGE_CONNECT_TIMEOUT, + read_timeout=BLOBSTORAGE_READ_TIMEOUT, + retries={"total_max_attempts": BLOBSTORAGE_MAX_ATTEMPTS}, + ), + verify=False, + bucket_name=f"{storagename}", + ), + } + +# For dev on rfc-index generation, create a red_bucket/ directory in the project root +# and uncomment these settings. Generated files will appear in this directory. To +# generate an accurate index, put up-to-date copies of unusable-rfc-numbers.json, +# april-first-rfc-numbers.json, and publication-std-levels.json in this directory +# before generating the index. +# +# STORAGES["red_bucket"] = { +# "BACKEND": "django.core.files.storage.FileSystemStorage", +# "OPTIONS": {"location": "red_bucket"}, +# } + +APP_API_TOKENS = { + "ietf.api.red_api" : ["devtoken", "redtoken"], # Not a real secret + "ietf.api.views_rpc" : ["devtoken"], # Not a real secret +} + +# Errata system api configuration +ERRATA_METADATA_NOTIFICATION_URL = "http://host.docker.internal:8808/api/rfc_metadata_update/" +ERRATA_METADATA_NOTIFICATION_API_KEY = "not a real secret" diff --git a/docker/configs/settings_local_sqlitetest.py b/docker/configs/settings_local_sqlitetest.py deleted file mode 100644 index 268fe6ec1d5..00000000000 --- a/docker/configs/settings_local_sqlitetest.py +++ /dev/null @@ -1,81 +0,0 @@ -# Copyright The IETF Trust 2010-2020, All Rights Reserved -# -*- coding: utf-8 -*- - - -# Standard settings except we use SQLite and skip migrations, this is -# useful for speeding up tests that depend on the test database, try -# for instance: -# -# ./manage.py test --settings=settings_sqlitetest doc.ChangeStateTestCase -# - -import os -from ietf.settings import * # pyflakes:ignore -from ietf.settings import TEST_CODE_COVERAGE_CHECKER -import debug # pyflakes:ignore -debug.debug = True - -# Workaround to avoid spending minutes stepping through the migrations in -# every test run. The result of this is to use the 'syncdb' way of creating -# the test database instead of doing it through the migrations. Taken from -# https://gist.github.com/NotSqrt/5f3c76cd15e40ef62d09 - -class DisableMigrations(object): - - def __contains__(self, item): - return True - - def __getitem__(self, item): - return None - -MIGRATION_MODULES = DisableMigrations() - -DATABASES = { - 'default': { - 'NAME': 'test.db', - 'ENGINE': 'django.db.backends.sqlite3', - }, - } - -if TEST_CODE_COVERAGE_CHECKER and not TEST_CODE_COVERAGE_CHECKER._started: # pyflakes:ignore - TEST_CODE_COVERAGE_CHECKER.start() # pyflakes:ignore - -NOMCOM_PUBLIC_KEYS_DIR=os.path.abspath("tmp-nomcom-public-keys-dir") - -# Undo any developer-dependent middleware when running the tests -MIDDLEWARE = [ c for c in MIDDLEWARE if not c in DEV_MIDDLEWARE ] # pyflakes:ignore - -TEMPLATES[0]['OPTIONS']['context_processors'] = [ p for p in TEMPLATES[0]['OPTIONS']['context_processors'] if not p in DEV_TEMPLATE_CONTEXT_PROCESSORS ] # pyflakes:ignore - -REQUEST_PROFILE_STORE_ANONYMOUS_SESSIONS = False - -IDSUBMIT_IDNITS_BINARY = "/usr/local/bin/idnits" -IDSUBMIT_REPOSITORY_PATH = "test/id/" -IDSUBMIT_STAGING_PATH = "test/staging/" -INTERNET_DRAFT_ARCHIVE_DIR = "test/archive/" -INTERNET_ALL_DRAFTS_ARCHIVE_DIR = "test/archive/" -RFC_PATH = "test/rfc/" - -AGENDA_PATH = '/assets/www6s/proceedings/' -MEETINGHOST_LOGO_PATH = AGENDA_PATH - -USING_DEBUG_EMAIL_SERVER=True -EMAIL_HOST='localhost' -EMAIL_PORT=2025 - -MEDIA_BASE_DIR = 'test' -MEDIA_ROOT = MEDIA_BASE_DIR + '/media/' -MEDIA_URL = '/media/' - -PHOTOS_DIRNAME = 'photo' -PHOTOS_DIR = MEDIA_ROOT + PHOTOS_DIRNAME - -DOCUMENT_PATH_PATTERN = '/assets/ietf-ftp/{doc.type_id}/' - -SUBMIT_YANG_CATALOG_MODEL_DIR = '/assets/ietf-ftp/yang/catalogmod/' -SUBMIT_YANG_DRAFT_MODEL_DIR = '/assets/ietf-ftp/yang/draftmod/' -SUBMIT_YANG_INVAL_MODEL_DIR = '/assets/ietf-ftp/yang/invalmod/' -SUBMIT_YANG_IANA_MODEL_DIR = '/assets/ietf-ftp/yang/ianamod/' -SUBMIT_YANG_RFC_MODEL_DIR = '/assets/ietf-ftp/yang/rfcmod/' - -DE_GFM_BINARY = '/usr/local/bin/de-gfm' diff --git a/docker/configs/settings_local_vite.py b/docker/configs/settings_local_vite.py index 7fb12a003d1..9116905b124 100644 --- a/docker/configs/settings_local_vite.py +++ b/docker/configs/settings_local_vite.py @@ -2,5 +2,9 @@ # -*- coding: utf-8 -*- from ietf.settings_local import * # pyflakes:ignore +from ietf.settings_local import DJANGO_VITE -DJANGO_VITE_DEV_MODE = True +DJANGO_VITE["default"] |= { + "dev_mode": True, + "dev_server_port": 3000, +} diff --git a/docker/configs/settings_postgresqldb.py b/docker/configs/settings_postgresqldb.py new file mode 100644 index 00000000000..9b98586658e --- /dev/null +++ b/docker/configs/settings_postgresqldb.py @@ -0,0 +1,18 @@ +DATABASES = { + 'default': { + 'HOST': 'db', + 'PORT': 5432, + 'NAME': 'datatracker', + 'ENGINE': 'django.db.backends.postgresql', + 'USER': 'django', + 'PASSWORD': 'RkTkDPFnKpko', + }, + 'blobdb': { + 'HOST': 'blobdb', + 'PORT': 5432, + 'NAME': 'blob', + 'ENGINE': 'django.db.backends.postgresql', + 'USER': 'dt', + 'PASSWORD': 'abcd1234', + }, +} diff --git a/docker/db.Dockerfile b/docker/db.Dockerfile index 5f55401c761..48ab2987807 100644 --- a/docker/db.Dockerfile +++ b/docker/db.Dockerfile @@ -1,32 +1,37 @@ # ===================== # --- Builder Stage --- # ===================== -FROM mariadb:10 AS builder +FROM postgres:17 AS builder -# That file does the DB initialization but also runs mysql daemon, by removing the last line it will only init -RUN ["sed", "-i", "s/exec \"$@\"/echo \"not running $@\"/", "/usr/local/bin/docker-entrypoint.sh"] +ENV POSTGRES_PASSWORD=hk2j22sfiv +ENV POSTGRES_USER=django +ENV POSTGRES_DB=datatracker +ENV POSTGRES_HOST_AUTH_METHOD=trust +ENV PGDATA=/data -# needed for intialization -ENV MARIADB_ROOT_PASSWORD=RkTkDPFnKpko -ENV MARIADB_DATABASE=ietf_utf8 -ENV MARIADB_USER=django -ENV MARIADB_PASSWORD=RkTkDPFnKpko +COPY docker/scripts/db-load-default-extensions.sh /docker-entrypoint-initdb.d/ +COPY docker/scripts/db-import.sh /docker-entrypoint-initdb.d/ +COPY datatracker.dump / -# Import the latest database dump -ADD https://www.ietf.org/lib/dt/sprint/ietf_utf8.sql.gz /docker-entrypoint-initdb.d/ -RUN chmod 0777 /docker-entrypoint-initdb.d/ietf_utf8.sql.gz - -# Need to change the datadir to something else that /var/lib/mysql because the parent docker file defines it as a volume. -# https://docs.docker.com/engine/reference/builder/#volume : -# Changing the volume from within the Dockerfile: If any build steps change the data within the volume after -# it has been declared, those changes will be discarded. -RUN ["/usr/local/bin/docker-entrypoint.sh", "mysqld", "--datadir", "/initialized-db", "--aria-log-dir-path", "/initialized-db"] +RUN ["sed", "-i", "s/exec \"$@\"/echo \"skipping...\"/", "/usr/local/bin/docker-entrypoint.sh"] +RUN ["/usr/local/bin/docker-entrypoint.sh", "postgres"] # =================== # --- Final Image --- # =================== -FROM mariadb:10 +FROM postgres:17 LABEL maintainer="IETF Tools Team " -# Copy the mysql data folder from the builder stage -COPY --from=builder /initialized-db /var/lib/mysql +COPY --from=builder /data $PGDATA + +ENV POSTGRES_PASSWORD=hk2j22sfiv +ENV POSTGRES_USER=django +ENV POSTGRES_DB=datatracker +ENV POSTGRES_HOST_AUTH_METHOD=trust + +# build-args for db dump tagging - exposed in the environment and +# in image metadata +ARG datatracker_dumpinfo_date="" +ENV DATATRACKER_DUMPINFO_DATE=$datatracker_dumpinfo_date +ARG datatracker_snapshot="" +ENV DATATRACKER_SNAPSHOT=$datatracker_snapshot diff --git a/docker/devblobstore.Dockerfile b/docker/devblobstore.Dockerfile new file mode 100644 index 00000000000..40bfbd0e961 --- /dev/null +++ b/docker/devblobstore.Dockerfile @@ -0,0 +1,9 @@ +ARG MINIO_VERSION=latest +FROM quay.io/minio/minio:${MINIO_VERSION} +LABEL maintainer="IETF Tools Team " + +ENV MINIO_ROOT_USER=minio_root +ENV MINIO_ROOT_PASSWORD=minio_pass +ENV MINIO_DEFAULT_BUCKETS=defaultbucket + +CMD ["server", "--console-address", ":9001", "/data"] diff --git a/docker/docker-compose.extend.yml b/docker/docker-compose.extend.yml index 30402394c4d..12ebe447d5c 100644 --- a/docker/docker-compose.extend.yml +++ b/docker/docker-compose.extend.yml @@ -1,5 +1,3 @@ -version: '3.8' - services: app: ports: @@ -14,4 +12,15 @@ services: - app-assets:/assets db: ports: - - '3306' + - '5432' + pgadmin: + ports: + - '5433' + blobstore: + ports: + - '9000:9000' + - '9001:9001' + celery: + volumes: + - .:/workspace + - app-assets:/assets diff --git a/docker/misc/build b/docker/misc/build deleted file mode 100644 index b3cc97e52c8..00000000000 --- a/docker/misc/build +++ /dev/null @@ -1,96 +0,0 @@ -#!/bin/bash - -version=0.20 -program=${0##*/} -progdir=${0%/*} -if [ "$progdir" = "$program" ]; then progdir="."; fi -if [ "$progdir" = "." ]; then progdir="$PWD"; fi -parent=$(dirname "$progdir") -if [ "$parent" = "." ]; then parent="$PWD"; fi -if [[ $(uname) =~ CYGWIN.* ]]; then parent=$(echo "$parent" | sed -e 's/^\/cygdrive\/\(.\)/\1:/'); fi - - -function usage() { - cat < - Lars Eggert, - -COPYRIGHT - Copyright (c) 2016 IETF Trust and the persons identified as authors of - the code. All rights reserved. Redistribution and use in source and - binary forms, with or without modification, is permitted pursuant to, - and subject to the license terms contained in, the Revised BSD - License set forth in Section 4.c of the IETF Trust’s Legal Provisions - Relating to IETF Documents(https://trustee.ietf.org/license-info). - -EOF -} - - -function die() { - echo -e "\n$program: error: $*" >&2 - exit 1 -} - - -function version() { - echo -e "$program $version" -} - - -trap 'echo "$program($LINENO): Command failed with error code $? ([$$] $0 $*)"; exit 1' ERR - -# Default values -IMAGE=ietf/datatracker-environment -TAG=$(basename "$(svn info "$parent" | grep ^URL | awk '{print $2}' | tr -d '\r')") -LOCAL=1 - -# Option parsing -shortopts=hut:V -args=$(getopt -o$shortopts $*) -if [ $? != 0 ] ; then die "Terminating..." >&2 ; exit 1 ; fi -set -- $args - -while true ; do - case "$1" in - -h) usage; exit;; # Show this help, then exit - -u) LOCAL=0;; # Upload image to repository after build - -t) TAG=$2; shift;; # Use this docker image tag - -V) version; exit;; # Show program version, then exit - --) shift; break;; - *) die "Internal error, inconsistent option specification: '$1'";; - esac - shift -done - -# The program itself -docker rmi -f $IMAGE:trunk 2>/dev/null || true -docker build --progress plain -t "$IMAGE-app:$TAG" -f docker/app.Dockerfile . -docker build --progress plain -t "$IMAGE-db:$TAG" -f docker/db.Dockerfile . -docker tag "$(docker images -q $IMAGE-app | head -n 1)" $IMAGE-app:latest -docker tag "$(docker images -q $IMAGE-db | head -n 1)" $IMAGE-db:latest -if [ -z "$LOCAL" ]; then - docker push $IMAGE-app:latest - docker push "$IMAGE-app:$TAG" - docker push $IMAGE-db:latest - docker push "$IMAGE-db:$TAG" -fi \ No newline at end of file diff --git a/docker/misc/copydb b/docker/misc/copydb deleted file mode 100644 index 748189bd6a7..00000000000 --- a/docker/misc/copydb +++ /dev/null @@ -1,97 +0,0 @@ -#!/bin/bash - -version=0.11 -program=${0##*/} -progdir=${0%/*} -if [ "$progdir" = "$program" ]; then progdir="."; fi -if [ "$progdir" = "." ]; then progdir="$PWD"; fi -parent=$(dirname "$progdir") -if [ "$parent" = "." ]; then parent="$PWD"; fi -if [[ $(uname) =~ CYGWIN.* ]]; then parent=$(echo "$parent" | sed -e 's/^\/cygdrive\/\(.\)/\1:/'); fi - - -function usage() { - cat < - Lars Eggert, - -COPYRIGHT - Copyright (c) 2016 IETF Trust and the persons identified as authors of - the code. All rights reserved. Redistribution and use in source and - binary forms, with or without modification, is permitted pursuant to, - and subject to the license terms contained in, the Revised BSD - License set forth in Section 4.c of the IETF Trust’s Legal Provisions - Relating to IETF Documents(https://trustee.ietf.org/license-info). - -EOF -} - - -function die() { - echo -e "\n$program: error: $*" >&2 - exit 1 -} - - -function version() { - echo -e "$program $version" -} - - -trap 'echo "$program($LINENO): Command failed with error code $? ([$$] $0 $*)"; exit 1' ERR - -# Option parsing -shortopts=hV -args=$(getopt -o$shortopts $*) -if [ $? != 0 ] ; then die "Terminating..." >&2 ; exit 1 ; fi -set -- $args - -while true ; do - case "$1" in - -h) usage; exit;; # Show this help, then exit - -V) version; exit;; # Show program version, then exit - --) shift; break;; - *) die "Internal error, inconsistent option specification: '$1'";; - esac - shift -done - -# The program itself -if [ -e "/.dockerenv" -o -n "$(grep -s '/docker/' /proc/self/cgroup)" ]; then - die "It looks as if you're running inside docker -- please quit docker first." -fi - -workdir=$(realpath $progdir/../data/mysql/..) -echo "Working directory: $workdir" -cd $workdir -echo "Building tarfile ..." -tar cjf ietf_utf8.bin.tar.bz2 mysql -echo "Copying tarfile to ietfa.amsl.com ..." -scp ietf_utf8.bin.tar.bz2 ietfa.amsl.com:/a/www/www6s/lib/dt/sprint/ \ No newline at end of file diff --git a/docker/rabbitmq.conf b/docker/rabbitmq.conf new file mode 100644 index 00000000000..8603d0a4cb1 --- /dev/null +++ b/docker/rabbitmq.conf @@ -0,0 +1,19 @@ +# prevent guest from logging in over tcp +loopback_users.guest = true + +# load saved definitions +load_definitions = /ietf-conf/definitions.json + +# Ensure that enough disk is available to flush to disk. To do this, need to limit the +# memory available to the container to something reasonable. See +# https://www.rabbitmq.com/production-checklist.html#monitoring-and-resource-usage +# for recommendations. + +# 1-1.5 times the memory available to the container is adequate for disk limit +disk_free_limit.absolute = 1.5GB + +# This should be ~40% of the memory available to the container. Use an +# absolute number because relative will be proprtional to the full machine +# memory. +vm_memory_high_watermark.absolute = 400MB + diff --git a/docker/run b/docker/run index cc0a19941f2..71e794aaa91 100755 --- a/docker/run +++ b/docker/run @@ -37,12 +37,22 @@ while getopts "hp:r" opt; do esac done +# Ensure the run script is in our directory. +dirname=$(dirname $0) +if [ "$dirname" = "." -o "$dirname" = "" ] ; then + : +else + echo "Changing to directory $dirname" + cd $dirname || exit 1 +fi + # Remove mounted temp directories rm -rf .parcel-cache __pycache__ # Create extended docker-compose definition -cp docker-compose.extend.yml docker-compose.extend-custom.yml -sed -i -r -e "s/CUSTOM_PORT/$CUSTOM_PORT/" docker-compose.extend-custom.yml +sed -e "s/CUSTOM_PORT/$CUSTOM_PORT/" \ + docker-compose.extend-custom.yml cd .. # Set UID/GID mappings diff --git a/docker/scripts/app-configure-blobstore.py b/docker/scripts/app-configure-blobstore.py new file mode 100755 index 00000000000..9ae64e00418 --- /dev/null +++ b/docker/scripts/app-configure-blobstore.py @@ -0,0 +1,44 @@ +#!/usr/bin/env python +# Copyright The IETF Trust 2024, All Rights Reserved + +import boto3 +import botocore.config +import botocore.exceptions +import os +import sys + +from ietf.settings import ARTIFACT_STORAGE_NAMES + + +def init_blobstore(): + blobstore = boto3.resource( + "s3", + endpoint_url=os.environ.get("BLOB_STORE_ENDPOINT_URL", "http://blobstore:9000"), + aws_access_key_id=os.environ.get("BLOB_STORE_ACCESS_KEY", "minio_root"), + aws_secret_access_key=os.environ.get("BLOB_STORE_SECRET_KEY", "minio_pass"), + aws_session_token=None, + config=botocore.config.Config( + request_checksum_calculation="when_required", + response_checksum_validation="when_required", + signature_version="s3v4", + ), + ) + for bucketname in ARTIFACT_STORAGE_NAMES: + adjusted_bucket_name = ( + os.environ.get("BLOB_STORE_BUCKET_PREFIX", "") + + bucketname + + os.environ.get("BLOB_STORE_BUCKET_SUFFIX", "") + ).strip() + try: + blobstore.create_bucket(Bucket=adjusted_bucket_name) + except botocore.exceptions.ClientError as err: + if err.response["Error"]["Code"] == "BucketAlreadyExists": + print(f"Bucket {bucketname} already exists") + else: + print(f"Error creating {bucketname}: {err.response['Error']['Code']}") + else: + print(f"Bucket {bucketname} created") + + +if __name__ == "__main__": + sys.exit(init_blobstore()) diff --git a/docker/scripts/app-create-dirs.sh b/docker/scripts/app-create-dirs.sh index 807522e25b1..3eb328a2807 100755 --- a/docker/scripts/app-create-dirs.sh +++ b/docker/scripts/app-create-dirs.sh @@ -1,13 +1,9 @@ #!/bin/bash for sub in \ - test/id \ - test/staging \ - test/archive \ - test/rfc \ - test/media \ - test/wiki/ietf \ - data/nomcom_keys/public_keys \ + /assets/archive/id \ + /assets/collection \ + /assets/collection/draft-archive \ /assets/ietf-ftp \ /assets/ietf-ftp/bofreq \ /assets/ietf-ftp/charter \ @@ -20,6 +16,11 @@ for sub in \ /assets/ietf-ftp/yang/ianamod \ /assets/ietf-ftp/yang/invalmod \ /assets/ietf-ftp/yang/rfcmod \ + /assets/ietfdata \ + /assets/ietfdata/derived \ + /assets/ietfdata/derived/bibxml \ + /assets/ietfdata/derived/bibxml/bibxml-ids \ + /assets/ietfdata/doc/draft/repository \ /assets/www6s \ /assets/www6s/staging \ /assets/www6s/wg-descriptions \ @@ -28,6 +29,11 @@ for sub in \ /assets/www6/iesg \ /assets/www6/iesg/evaluation \ /assets/media/photo \ + /assets/tmp \ + /assets/ftp \ + /assets/ftp/charter \ + /assets/ftp/internet-drafts \ + /assets/ftp/review \ ; do if [ ! -d "$sub" ]; then echo "Creating dir $sub" diff --git a/docker/scripts/app-cypress.sh b/docker/scripts/app-cypress.sh deleted file mode 100755 index 81e510592bf..00000000000 --- a/docker/scripts/app-cypress.sh +++ /dev/null @@ -1,23 +0,0 @@ -#!/bin/bash - -WORKSPACEDIR="/workspace" - -pushd . -cd $WORKSPACEDIR - -echo "Starting datatracker server..." -ietf/manage.py runserver 0.0.0.0:8000 --settings=settings_local > /dev/null 2>&1 & -serverPID=$! - -echo "Waiting for server to come online ..." -/usr/local/bin/wait-for localhost:8000 -- echo "Server ready" - -echo "Run dbus process to silence warnings..." -sudo mkdir -p /run/dbus -sudo dbus-daemon --system &> /dev/null - -echo "Starting JS tests..." -yarn cypress - -kill $serverPID -popd diff --git a/docker/scripts/app-init-celery.sh b/docker/scripts/app-init-celery.sh new file mode 100755 index 00000000000..17925633d2e --- /dev/null +++ b/docker/scripts/app-init-celery.sh @@ -0,0 +1,119 @@ +#!/bin/bash -e +# +# Environment parameters: +# +# CELERY_APP - name of application to pass to celery (defaults to ietf) +# +# CELERY_ROLE - 'worker' or 'beat' (defaults to 'worker') +# +# CELERY_UID - numeric uid for the celery worker process +# +# CELERY_GID - numeric gid for the celery worker process +# +# UPDATES_REQUIREMENTS_FROM - path, relative to /workspace mount, to a pip requirements +# file that should be installed at container startup. Default is no package install/update. +# +# DEBUG_TERM_TIMING - if non-empty, writes debug messages during shutdown after a TERM signal +# +# DEV_MODE - if non-empty, restart celery worker on Python file change +# +WORKSPACEDIR="/workspace" +CELERY_ROLE="${CELERY_ROLE:-worker}" + +cd "$WORKSPACEDIR" || exit 255 + +if [[ -n "${UPDATE_REQUIREMENTS_FROM}" ]]; then + # Need to run as root in the container for this + reqs_file="${WORKSPACEDIR}/${UPDATE_REQUIREMENTS_FROM}" + echo "Updating requirements from ${reqs_file}..." + pip install --upgrade -r "${reqs_file}" +fi + +CELERY_OPTS=( "${CELERY_ROLE}" ) +if [[ -n "${CELERY_UID}" ]]; then + # ensure that a user with the necessary UID exists in container + if ! id "${CELERY_UID}" ; then + adduser --system --uid "${CELERY_UID}" --no-create-home --disabled-login "celery-user-${CELERY_UID}" + fi + CELERY_OPTS+=("--uid=${CELERY_UID}") + CELERY_USERNAME="$(id -nu ${CELERY_UID})" +fi + +if [[ -n "${CELERY_GID}" ]]; then + # ensure that some group with the necessary GID exists in container + if ! getent group "${CELERY_GID}" ; then + addgroup --gid "${CELERY_GID}" "celery-group-${CELERY_GID}" + fi + CELERY_OPTS+=("--gid=${CELERY_GID}") + CELERY_GROUP="$(getent group ${CELERY_GID} | awk -F: '{print $1}')" +fi + +run_as_celery_uid () { + IAM=$(whoami) + if [ "${IAM}" = "${CELERY_USERNAME:-root}" ]; then + SU_OPTS=() + if [[ -n "${CELERY_GROUP}" ]]; then + SU_OPTS+=("-g" "${CELERY_GROUP}") + fi + su "${SU_OPTS[@]}" "${CELERY_USERNAME:-root}" -s /bin/sh -c "$*" + else + /bin/sh -c "$*" + fi +} + +log_term_timing_msgs () { + # output periodic debug message + while true; do + echo "Waiting for celery worker shutdown ($(date --utc --iso-8601=ns))" + sleep 0.5s + done +} + +cleanup () { + # Cleanly terminate the celery app by sending it a TERM, then waiting for it to exit. + if [[ -n "${celery_pid}" ]]; then + echo "Gracefully terminating celery worker. This may take a few minutes if tasks are in progress..." + kill -TERM "${celery_pid}" + if [[ -n "${DEBUG_TERM_TIMING}" ]]; then + log_term_timing_msgs & + fi + wait "${celery_pid}" + fi +} + +echo "Running checks as root to apply patches..." +/usr/local/bin/python $WORKSPACEDIR/ietf/manage.py check + +if [[ "${CELERY_ROLE}" == "worker" ]]; then + echo "Running initial checks..." + # Run checks as celery worker if one was specified + run_as_celery_uid /usr/local/bin/python $WORKSPACEDIR/ietf/manage.py check +fi + +USER_BIN_PATH="/home/dev/.local/bin" +WATCHMEDO="$USER_BIN_PATH/watchmedo" +# Find a celery that works +if [[ -x "$USER_BIN_PATH/celery" ]]; then + # This branch is used for dev + CELERY="$USER_BIN_PATH/celery" +else + # This branch is used for sandbox instances + CELERY="/usr/local/bin/celery" +fi +trap 'trap "" TERM; cleanup' TERM +# start celery in the background so we can trap the TERM signal +if [[ -n "${DEV_MODE}" && -x "${WATCHMEDO}" ]]; then + $WATCHMEDO auto-restart \ + --patterns '*.py' \ + --directory 'ietf' \ + --recursive \ + --debounce-interval 5 \ + -- \ + $CELERY --app="${CELERY_APP:-ietf}" "${CELERY_OPTS[@]}" $@ & + celery_pid=$! +else + $CELERY --app="${CELERY_APP:-ietf}" "${CELERY_OPTS[@]}" "$@" & + celery_pid=$! +fi + +wait "${celery_pid}" diff --git a/docker/scripts/app-init.sh b/docker/scripts/app-init.sh index 81811beab3b..da2e110ed11 100755 --- a/docker/scripts/app-init.sh +++ b/docker/scripts/app-init.sh @@ -2,8 +2,17 @@ WORKSPACEDIR="/workspace" +# Handle Linux host mounting the workspace dir as root +if [ ! -O "${WORKSPACEDIR}/ietf" ]; then + sudo chown -R dev:dev $WORKSPACEDIR +fi + +# Start rsyslog service sudo service rsyslog start &>/dev/null +# Add /workspace as a safe git directory +git config --global --add safe.directory /workspace + # Turn off git info in zsh prompt (causes slowdowns) git config oh-my-zsh.hide-info 1 @@ -12,66 +21,50 @@ echo "Fixing volumes ownership..." sudo chown -R dev:dev "$WORKSPACEDIR/.parcel-cache" sudo chown -R dev:dev "$WORKSPACEDIR/__pycache__" sudo chown -R dev:dev "$WORKSPACEDIR/.vite" -sudo chown -R dev:dev "$WORKSPACEDIR/.yarn/unplugged" sudo chown dev:dev "/assets" -echo "Fix chromedriver /dev/shm permissions..." -sudo chmod 1777 /dev/shm +# Run nginx +echo "Starting nginx..." +sudo nginx # Build node packages that requrie native compilation echo "Compiling native node packages..." -yarn rebuild +npm install + +# Silence Browserlist warnings +export BROWSERSLIST_IGNORE_OLD_DATA=1 # Generate static assets echo "Building static assets... (this could take a minute or two)" -yarn build -yarn legacy:build +npm run build +npm run legacy:build # Copy config files if needed +cp $WORKSPACEDIR/docker/configs/settings_postgresqldb.py $WORKSPACEDIR/ietf/settings_postgresqldb.py if [ ! -f "$WORKSPACEDIR/ietf/settings_local.py" ]; then echo "Setting up a default settings_local.py ..." - cp $WORKSPACEDIR/docker/configs/settings_local.py $WORKSPACEDIR/ietf/settings_local.py else - echo "Using existing ietf/settings_local.py file" - if ! cmp -s $WORKSPACEDIR/docker/configs/settings_local.py $WORKSPACEDIR/ietf/settings_local.py; then - echo "NOTE: Differences detected compared to docker/configs/settings_local.py!" - echo "We'll assume you made these deliberately." - fi + echo "Renaming existing ietf/settings_local.py to ietf/settings_local.py.bak" + mv -f $WORKSPACEDIR/ietf/settings_local.py $WORKSPACEDIR/ietf/settings_local.py.bak fi +cp $WORKSPACEDIR/docker/configs/settings_local.py $WORKSPACEDIR/ietf/settings_local.py if [ ! -f "$WORKSPACEDIR/ietf/settings_local_debug.py" ]; then echo "Setting up a default settings_local_debug.py ..." - cp $WORKSPACEDIR/docker/configs/settings_local_debug.py $WORKSPACEDIR/ietf/settings_local_debug.py -else - echo "Using existing ietf/settings_local_debug.py file" - if ! cmp -s $WORKSPACEDIR/docker/configs/settings_local_debug.py $WORKSPACEDIR/ietf/settings_local_debug.py; then - echo "NOTE: Differences detected compared to docker/configs/settings_local_debug.py!" - echo "We'll assume you made these deliberately." - fi -fi - -if [ ! -f "$WORKSPACEDIR/ietf/settings_local_sqlitetest.py" ]; then - echo "Setting up a default settings_local_sqlitetest.py ..." - cp $WORKSPACEDIR/docker/configs/settings_local_sqlitetest.py $WORKSPACEDIR/ietf/settings_local_sqlitetest.py else - echo "Using existing ietf/settings_local_sqlitetest.py file" - if ! cmp -s $WORKSPACEDIR/docker/configs/settings_local_sqlitetest.py $WORKSPACEDIR/ietf/settings_local_sqlitetest.py; then - echo "NOTE: Differences detected compared to docker/configs/settings_local_sqlitetest.py!" - echo "We'll assume you made these deliberately." - fi + echo "Renaming existing ietf/settings_local_debug.py to ietf/settings_local_debug.py.bak" + mv -f $WORKSPACEDIR/ietf/settings_local_debug.py $WORKSPACEDIR/ietf/settings_local_debug.py.bak fi +cp $WORKSPACEDIR/docker/configs/settings_local_debug.py $WORKSPACEDIR/ietf/settings_local_debug.py if [ ! -f "$WORKSPACEDIR/ietf/settings_local_vite.py" ]; then echo "Setting up a default settings_local_vite.py ..." - cp $WORKSPACEDIR/docker/configs/settings_local_vite.py $WORKSPACEDIR/ietf/settings_local_vite.py else - echo "Using existing ietf/settings_local_vite.py file" - if ! cmp -s $WORKSPACEDIR/docker/configs/settings_local_vite.py $WORKSPACEDIR/ietf/settings_local_vite.py; then - echo "NOTE: Differences detected compared to docker/configs/settings_local_vite.py!" - echo "We'll assume you made these deliberately." - fi + echo "Renaming existing ietf/settings_local_vite.py to ietf/settings_local_vite.py.bak" + mv -f $WORKSPACEDIR/ietf/settings_local_vite.py $WORKSPACEDIR/ietf/settings_local_vite.py.bak fi +cp $WORKSPACEDIR/docker/configs/settings_local_vite.py $WORKSPACEDIR/ietf/settings_local_vite.py # Create data directories @@ -79,16 +72,21 @@ echo "Creating data directories..." chmod +x ./docker/scripts/app-create-dirs.sh ./docker/scripts/app-create-dirs.sh +# Configure the development blobstore + +echo "Configuring blobstore..." +PYTHONPATH=/workspace python ./docker/scripts/app-configure-blobstore.py + # Download latest coverage results file echo "Downloading latest coverage results file..." -curl -fsSL https://github.com/ietf-tools/datatracker/releases/latest/download/coverage.json -o release-coverage.json +curl -fsSL https://github.com/ietf-tools/datatracker/releases/download/baseline/coverage.json -o release-coverage.json # Wait for DB container if [ -n "$EDITOR_VSCODE" ]; then echo "Waiting for DB container to come online ..." - /usr/local/bin/wait-for localhost:3306 -- echo "DB ready" + /usr/local/bin/wait-for db:5432 -- echo "PostgreSQL ready" fi # Run memcached @@ -100,24 +98,28 @@ echo "Starting memcached..." echo "Running initial checks..." /usr/local/bin/python $WORKSPACEDIR/ietf/manage.py check --settings=settings_local -# /usr/local/bin/python $WORKSPACEDIR/ietf/manage.py migrate --settings=settings_local -echo "-----------------------------------------------------------------" -echo "Done!" -echo "-----------------------------------------------------------------" +# Migrate, adjusting to what the current state of the underlying database might be: +/usr/local/bin/python $WORKSPACEDIR/ietf/manage.py migrate --fake-initial --settings=settings_local + +# Apply migrations to the blobdb database as well (most are skipped) +/usr/local/bin/python $WORKSPACEDIR/ietf/manage.py migrate --settings=settings_local --database=blobdb if [ -z "$EDITOR_VSCODE" ]; then CODE=0 - python -m smtpd -n -c DebuggingServer localhost:2025 & + python -m aiosmtpd -n -c ietf.utils.aiosmtpd.DevDebuggingHandler -l localhost:2025 & if [ -z "$*" ]; then + echo "-----------------------------------------------------------------" + echo "Ready!" + echo "-----------------------------------------------------------------" echo echo "You can execute arbitrary commands now, e.g.," echo - echo " ietf/manage.py runserver 0.0.0.0:8000" + echo " ietf/manage.py runserver 8001" echo echo "to start a development instance of the Datatracker." echo - echo " ietf/manage.py test --settings=settings_sqlitetest" + echo " ietf/manage.py test --settings=settings_test" echo echo "to run all the python tests." echo diff --git a/docker/scripts/app-install-chromedriver.sh b/docker/scripts/app-install-chromedriver.sh deleted file mode 100755 index 43532a1cf68..00000000000 --- a/docker/scripts/app-install-chromedriver.sh +++ /dev/null @@ -1,18 +0,0 @@ -#!/bin/bash - -HOSTARCH=$(arch) -if [ $HOSTARCH == "x86_64" ]; then - echo "Installing chrome driver..." - wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add - - echo "deb http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google.list - apt-get update -y - apt-get install -y google-chrome-stable - CHROMEVER=$(google-chrome --product-version | grep -o "[^\.]*\.[^\.]*\.[^\.]*") - DRIVERVER=$(curl -s "https://chromedriver.storage.googleapis.com/LATEST_RELEASE_$CHROMEVER") - wget -q --continue -P /chromedriver "http://chromedriver.storage.googleapis.com/$DRIVERVER/chromedriver_linux64.zip" - unzip /chromedriver/chromedriver* -d /chromedriver - ln -s /chromedriver/chromedriver /usr/local/bin/chromedriver - ln -s /chromedriver/chromedriver /usr/bin/chromedriver -else - echo "This architecture doesn't support chromedriver. Skipping installation..." -fi \ No newline at end of file diff --git a/docker/scripts/app-rsync-extras.sh b/docker/scripts/app-rsync-extras.sh index ef6966224f0..660670d20c9 100755 --- a/docker/scripts/app-rsync-extras.sh +++ b/docker/scripts/app-rsync-extras.sh @@ -42,8 +42,6 @@ cat << EOF > "$EXCLUDE" *.diff *.doc *.exe -*.html -*.json *.mib *.new *.p7s diff --git a/docker/scripts/app-setup-debian.sh b/docker/scripts/app-setup-debian.sh index a66ba819795..ea9cc3fb879 100644 --- a/docker/scripts/app-setup-debian.sh +++ b/docker/scripts/app-setup-debian.sh @@ -10,7 +10,6 @@ # Syntax: ./common-debian.sh [install zsh flag] [username] [user UID] [user GID] [upgrade packages flag] [install Oh My Zsh! flag] [Add non-free packages] set -e - INSTALL_ZSH=${1:-"true"} USERNAME=${2:-"automatic"} USER_UID=${3:-"automatic"} @@ -116,18 +115,9 @@ if [ "${PACKAGES_ALREADY_INSTALLED}" != "true" ]; then # Needed for adding manpages-posix and manpages-posix-dev which are non-free packages in Debian if [ "${ADD_NON_FREE_PACKAGES}" = "true" ]; then # Bring in variables from /etc/os-release like VERSION_CODENAME - . /etc/os-release - sed -i -E "s/deb http:\/\/(deb|httpredir)\.debian\.org\/debian ${VERSION_CODENAME} main/deb http:\/\/\1\.debian\.org\/debian ${VERSION_CODENAME} main contrib non-free/" /etc/apt/sources.list - sed -i -E "s/deb-src http:\/\/(deb|httredir)\.debian\.org\/debian ${VERSION_CODENAME} main/deb http:\/\/\1\.debian\.org\/debian ${VERSION_CODENAME} main contrib non-free/" /etc/apt/sources.list - sed -i -E "s/deb http:\/\/(deb|httpredir)\.debian\.org\/debian ${VERSION_CODENAME}-updates main/deb http:\/\/\1\.debian\.org\/debian ${VERSION_CODENAME}-updates main contrib non-free/" /etc/apt/sources.list - sed -i -E "s/deb-src http:\/\/(deb|httpredir)\.debian\.org\/debian ${VERSION_CODENAME}-updates main/deb http:\/\/\1\.debian\.org\/debian ${VERSION_CODENAME}-updates main contrib non-free/" /etc/apt/sources.list - sed -i "s/deb http:\/\/security\.debian\.org\/debian-security ${VERSION_CODENAME}\/updates main/deb http:\/\/security\.debian\.org\/debian-security ${VERSION_CODENAME}\/updates main contrib non-free/" /etc/apt/sources.list - sed -i "s/deb-src http:\/\/security\.debian\.org\/debian-security ${VERSION_CODENAME}\/updates main/deb http:\/\/security\.debian\.org\/debian-security ${VERSION_CODENAME}\/updates main contrib non-free/" /etc/apt/sources.list - sed -i "s/deb http:\/\/deb\.debian\.org\/debian ${VERSION_CODENAME}-backports main/deb http:\/\/deb\.debian\.org\/debian ${VERSION_CODENAME}-backports main contrib non-free/" /etc/apt/sources.list - sed -i "s/deb-src http:\/\/deb\.debian\.org\/debian ${VERSION_CODENAME}-backports main/deb http:\/\/deb\.debian\.org\/debian ${VERSION_CODENAME}-backports main contrib non-free/" /etc/apt/sources.list - # Handle bullseye location for security https://www.debian.org/releases/bullseye/amd64/release-notes/ch-information.en.html - sed -i "s/deb http:\/\/security\.debian\.org\/debian-security ${VERSION_CODENAME}-security main/deb http:\/\/security\.debian\.org\/debian-security ${VERSION_CODENAME}-security main contrib non-free/" /etc/apt/sources.list - sed -i "s/deb-src http:\/\/security\.debian\.org\/debian-security ${VERSION_CODENAME}-security main/deb http:\/\/security\.debian\.org\/debian-security ${VERSION_CODENAME}-security main contrib non-free/" /etc/apt/sources.list + . /etc/os-release + sed -i -E "s/Components: main/Components: main contrib non-free/" /etc/apt/sources.list.d/debian.sources + echo "Running apt-get update..." apt-get update package_list="${package_list} manpages-posix manpages-posix-dev" @@ -193,14 +183,14 @@ if id -u ${USERNAME} > /dev/null 2>&1; then else # Create user if [ "${USER_GID}" = "automatic" ]; then - groupadd $USERNAME + groupadd --force $USERNAME else - groupadd --gid $USER_GID $USERNAME + groupadd --force --gid $USER_GID $USERNAME fi if [ "${USER_UID}" = "automatic" ]; then - useradd -s /bin/bash --gid $USERNAME -m $USERNAME + useradd -s /bin/bash --gid $USERNAME -m $USERNAME || true else - useradd -s /bin/bash --uid $USER_UID --gid $USERNAME -m $USERNAME + useradd -s /bin/bash --uid $USER_UID --gid $USERNAME -m $USERNAME || true fi fi diff --git a/docker/scripts/app-setup-nginx.sh b/docker/scripts/app-setup-nginx.sh new file mode 100644 index 00000000000..cdeb2ea4cb3 --- /dev/null +++ b/docker/scripts/app-setup-nginx.sh @@ -0,0 +1,4 @@ +#!/usr/bin/env bash + +apt-get update -y +apt-get install -y nginx diff --git a/docker/scripts/app-start.sh b/docker/scripts/app-start.sh new file mode 100644 index 00000000000..c3369bab93c --- /dev/null +++ b/docker/scripts/app-start.sh @@ -0,0 +1,17 @@ +#!/bin/bash + +sudo service rsyslog start &>/dev/null + +# Run nginx + +echo "Starting nginx..." +pidof nginx >/dev/null && echo "nginx is already running [ OK ]" || sudo nginx + +# Run memcached + +echo "Starting memcached..." +pidof memcached >/dev/null && echo "memcached is already running [ OK ]" || /usr/bin/memcached -u dev -d + +echo "-----------------------------------------------------------------" +echo "Ready!" +echo "-----------------------------------------------------------------" diff --git a/docker/scripts/db-import.sh b/docker/scripts/db-import.sh new file mode 100644 index 00000000000..a0f22cd8fc2 --- /dev/null +++ b/docker/scripts/db-import.sh @@ -0,0 +1,12 @@ +#!/bin/bash +set -e + +echo "Drop dummy datatracker DB if it exists..." +dropdb -U django --if-exists datatracker + +# Extensions and search paths will be loaded from the dump +echo "Import DB dump into datatracker..." +pg_restore --clean --if-exists --create --no-owner -U django -d postgres datatracker.dump +echo "alter role django set search_path=datatracker,django,public;" | psql -U django -d datatracker + +echo "Done!" diff --git a/docker/scripts/db-load-default-extensions.sh b/docker/scripts/db-load-default-extensions.sh new file mode 100644 index 00000000000..efb64b75d00 --- /dev/null +++ b/docker/scripts/db-load-default-extensions.sh @@ -0,0 +1,10 @@ +#!/bin/bash +set -e + +# Adding the extension to the default template is needed to allow the test-suite +# to be run on postgres (see ietf.settings_test). The test runner always +# makes a fresh test database instance, and since we are bypassing the migration +# framework and using a fixture to set the database structure, there's no reaonable +# way to install the extension as part of the test run. +psql -U django -d template1 -v ON_ERROR_STOP=1 -c 'CREATE EXTENSION IF NOT EXISTS citext;' + diff --git a/docker/scripts/updatedb b/docker/scripts/updatedb deleted file mode 100644 index 85386daa4a1..00000000000 --- a/docker/scripts/updatedb +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/bash - -echo "This script is deprecated. Please use the `cleandb` script in the parent folder instead." - -# Modified on 2021-12-20, remove this file after a while \ No newline at end of file diff --git a/ietf/.gitignore b/ietf/.gitignore index 322cc214d08..af738db98cb 100644 --- a/ietf/.gitignore +++ b/ietf/.gitignore @@ -1,7 +1,8 @@ /*.pyc /settings_local.py -/settings_local.py.bak /settings_local_debug.py -/settings_local_sqlitetest.py /settings_local_vite.py +/settings_mysqldb.py +/settings_postgresqldb.py +/settings_*.py.bak /ietfdb.sql.gz diff --git a/ietf/.yarnrc b/ietf/.yarnrc deleted file mode 100644 index 2464981b981..00000000000 --- a/ietf/.yarnrc +++ /dev/null @@ -1 +0,0 @@ ---modules-folder ../webassets/ diff --git a/ietf/__init__.py b/ietf/__init__.py index 133a5d5abf6..26124c3c67a 100644 --- a/ietf/__init__.py +++ b/ietf/__init__.py @@ -6,7 +6,7 @@ # Version must stay in single quotes for automatic CI replace # Don't add patch number here: -__version__ = '8.0.0-dev' +__version__ = '1.0.0-dev' # Release hash must stay in single quotes for automatic CI replace __release_hash__ = '' @@ -16,3 +16,28 @@ # set this to ".p1", ".p2", etc. after patching __patch__ = "" + +if __version__ == '1.0.0-dev' and __release_hash__ == '' and __release_branch__ == '': + import subprocess + branch = subprocess.run( + ["/usr/bin/git", "branch", "--show-current"], + capture_output=True, + ).stdout.decode().strip() + git_hash = subprocess.run( + ["/usr/bin/git", "rev-parse", "head"], + capture_output=True, + ).stdout.decode().strip() + rev = subprocess.run( + ["/usr/bin/git", "describe", "--tags", git_hash], + capture_output=True, + ).stdout.decode().strip().split('-', 1)[0] + __version__ = f"{rev}-dev" + __release_branch__ = branch + __release_hash__ = git_hash + + +# This will make sure the app is always imported when +# Django starts so that shared_task will use this app. +from .celeryapp import app as celery_app + +__all__ = ('celery_app',) diff --git a/ietf/ietfauth/management/commands/__init__.py b/ietf/admin/__init__.py similarity index 100% rename from ietf/ietfauth/management/commands/__init__.py rename to ietf/admin/__init__.py diff --git a/ietf/admin/apps.py b/ietf/admin/apps.py new file mode 100644 index 00000000000..20b762cfec9 --- /dev/null +++ b/ietf/admin/apps.py @@ -0,0 +1,6 @@ +# Copyright The IETF Trust 2024, All Rights Reserved +from django.contrib.admin import apps as admin_apps + + +class AdminConfig(admin_apps.AdminConfig): + default_site = "ietf.admin.sites.AdminSite" diff --git a/ietf/admin/sites.py b/ietf/admin/sites.py new file mode 100644 index 00000000000..69cb62ae200 --- /dev/null +++ b/ietf/admin/sites.py @@ -0,0 +1,15 @@ +# Copyright The IETF Trust 2024, All Rights Reserved +from django.contrib.admin import AdminSite as _AdminSite +from django.conf import settings +from django.utils.safestring import mark_safe + + +class AdminSite(_AdminSite): + site_title = "Datatracker admin" + + @staticmethod + def site_header(): + if settings.SERVER_MODE == "production": + return "Datatracker administration" + else: + return mark_safe('Datatracker administration δ') diff --git a/ietf/api/__init__.py b/ietf/api/__init__.py index b4c6203d985..30254221d12 100644 --- a/ietf/api/__init__.py +++ b/ietf/api/__init__.py @@ -1,78 +1,159 @@ # Copyright The IETF Trust 2014-2020, All Rights Reserved -# -*- coding: utf-8 -*- import datetime import re - +import sys from urllib.parse import urlencode -from django.conf import settings -from django.core.exceptions import ObjectDoesNotExist - -import debug # pyflakes:ignore - -import tastypie import tastypie.resources +import tastypie.serializers +from django.apps import apps as django_apps +from django.core.exceptions import ObjectDoesNotExist +from django.db import DataError, transaction +from django.http import HttpResponseNotAllowed +from django.utils.module_loading import autodiscover_modules from tastypie.api import Api from tastypie.bundle import Bundle -from tastypie.exceptions import ApiFieldError -from tastypie.serializers import Serializer # pyflakes:ignore (we're re-exporting this) +from tastypie.exceptions import ApiFieldError, BadRequest, InvalidFilterError from tastypie.fields import ApiField +import debug # noqa: F401 (pyflakes:ignore) +from ietf.utils.log import log + _api_list = [] -for _app in settings.INSTALLED_APPS: +OMITTED_APPS_APIS = ["ietf.status"] + +# Pre-py3.11, fromisoformat() does not handle Z or +HH tz offsets +HAVE_BROKEN_FROMISOFORMAT = sys.version_info < (3, 11, 0, "", 0) + + +def populate_api_list(): _module_dict = globals() - if '.' in _app: - _root, _name = _app.split('.', 1) - if _root == 'ietf': - if not '.' in _name: + for app_config in django_apps.get_app_configs(): + if "." in app_config.name and app_config.name not in OMITTED_APPS_APIS: + _root, _name = app_config.name.split(".", 1) + if _root == "ietf" and "." not in _name: _api = Api(api_name=_name) _module_dict[_name] = _api _api_list.append((_name, _api)) + def autodiscover(): """ Auto-discover INSTALLED_APPS resources.py modules and fail silently when - not present. This forces an import on them to register any admin bits they + not present. This forces an import on them to register any resources they may want. """ + autodiscover_modules("resources") - from importlib import import_module - from django.conf import settings - from django.utils.module_loading import module_has_submodule - for app in settings.INSTALLED_APPS: - mod = import_module(app) - # Attempt to import the app's admin module. +class ModelResource(tastypie.resources.ModelResource): + def dispatch(self, request_type, request, **kwargs): + """Turn a database error caused by request data into a bad request + + Filter values reach the database with very little validation, and some of + them only fail once the query actually runs - below tastypie, and long + after build_filters() had any chance to reject them. Left alone those + surface as unhandled exceptions. + + Only DataError is treated this way: it is the DBAPI error for a problem + with the data in the query, so it is the client's to fix. The other + DatabaseError subclasses (OperationalError, ProgrammingError, + InternalError) indicate a broken database or a bug of ours, and are left + alone so they still raise and report. + + The database's message is logged rather than returned - it can quote the + offending value, and this response body is not escaped. + """ try: - import_module('%s.resources' % (app, )) - except: - # Decide whether to bubble up this error. If the app just - # doesn't have an admin module, we can ignore the error - # attempting to import it, otherwise we want it to bubble up. - if module_has_submodule(mod, "resources"): - raise + return super().dispatch(request_type, request, **kwargs) + except DataError as err: + # The failed statement has aborted the transaction if there is one, so + # nothing more can be done with the connection until it is rolled back. + # Requests normally run in autocommit, where there is no transaction to + # roll back and this is a no-op, but without it the guard would quietly + # stop working if ATOMIC_REQUESTS were ever turned on: the 400 would be + # built and then lost when the atomic block failed to commit. + if not transaction.get_autocommit(): + transaction.set_rollback(True) + log(f"DataError handling {request.method} {request.get_full_path()}: {err}") + raise BadRequest( + "The database could not process this request. This is usually a " + "malformed filter value." + ) + + def post_detail(self, request, **kwargs): + return HttpResponseNotAllowed(["GET"]) -class ModelResource(tastypie.resources.ModelResource): def generate_cache_key(self, *args, **kwargs): """ Creates a unique-enough cache key. This is based off the current api_name/resource_name/args/kwargs. """ - #smooshed = ["%s=%s" % (key, value) for key, value in kwargs.items()] + # smooshed = ["%s=%s" % (key, value) for key, value in kwargs.items()] smooshed = urlencode(kwargs) # Use a list plus a ``.join()`` because it's faster than concatenation. - return "%s:%s:%s:%s" % (self._meta.api_name, self._meta.resource_name, ':'.join(args), smooshed) + return f"{self._meta.api_name}:{self._meta.resource_name}:{':'.join(args)}:{smooshed}" + + def _z_aware_fromisoformat(self, value: str) -> datetime.datetime: + """datetime.datetime.fromisoformat replacement that works with python < 3.11""" + if HAVE_BROKEN_FROMISOFORMAT: + if value.upper().endswith("Z"): + value = value[:-1] + "+00:00" # Z -> UTC + elif re.match(r"[+-][0-9][0-9]$", value[-3:]): + value = value + ":00" # -04 -> -04:00 + return datetime.datetime.fromisoformat(value) + + def filter_value_to_python( + self, value, field_name, filters, filter_expr, filter_type + ): + try: + py_value = super().filter_value_to_python( + value, field_name, filters, filter_expr, filter_type + ) + except TypeError: + # For "in" and "range" filters tastypie calls len() on the value, but + # string_to_python() has already mapped "true"/"false"/"nil"/"none" to a + # bool or None, which have no len(). + raise InvalidFilterError( + f"Invalid value for the '{filter_type}' filter on '{field_name}'" + ) + if filter_type == "range" and len(py_value) != 2: + # Django renders a range lookup as "BETWEEN %s AND %s" and indexes the + # value without checking its length, so anything other than exactly two + # values raises IndexError (or ValueError) when the query is compiled - + # long after this method has returned, where it can only become a 500. + # Reject it here, while it can still be reported as a bad request. + raise InvalidFilterError( + f"The '{filter_type}' filter on '{field_name}' requires exactly two " + f"comma-separated values" + ) + if isinstance( + self.fields[field_name], tastypie.fields.DateTimeField + ) and isinstance(py_value, str): + # Ensure datetime values are TZ-aware, using UTC by default + try: + dt = self._z_aware_fromisoformat(py_value) + except ValueError: + pass # let tastypie deal with the original value + else: + if dt.tzinfo is None: + dt = dt.replace(tzinfo=datetime.timezone.utc) + py_value = dt.isoformat() + return py_value -TIMEDELTA_REGEX = re.compile(r'^(?P\d+d)?\s?(?P\d+h)?\s?(?P\d+m)?\s?(?P\d+s?)$') +TIMEDELTA_REGEX = re.compile( + r"^(?P\d+d)?\s?(?P\d+h)?\s?(?P\d+m)?\s?(?P\d+s?)$" +) + class TimedeltaField(ApiField): - dehydrated_type = 'timedelta' + dehydrated_type = "timedelta" help_text = "A timedelta field, with duration expressed in seconds. Ex: 132" def convert(self, value): @@ -84,33 +165,50 @@ def convert(self, value): if match: data = match.groupdict() - return datetime.timedelta(int(data['days']), int(data['hours']), int(data['minutes']), int(data['seconds'])) + return datetime.timedelta( + int(data["days"]), + int(data["hours"]), + int(data["minutes"]), + int(data["seconds"]), + ) else: - raise ApiFieldError("Timedelta provided to '%s' field doesn't appear to be a valid timedelta string: '%s'" % (self.instance_name, value)) + raise ApiFieldError( + f"Timedelta provided to '{self.instance_name}' field doesn't appear to be a valid timedelta string: '{value}'" + ) return value def hydrate(self, bundle): - value = super(TimedeltaField, self).hydrate(bundle) + value = super().hydrate(bundle) - if value and not hasattr(value, 'seconds'): + if value and not hasattr(value, "seconds"): if isinstance(value, str): try: match = TIMEDELTA_REGEX.search(value) if match: data = match.groupdict() - value = datetime.timedelta(int(data['days']), int(data['hours']), int(data['minutes']), int(data['seconds'])) + value = datetime.timedelta( + int(data["days"]), + int(data["hours"]), + int(data["minutes"]), + int(data["seconds"]), + ) else: raise ValueError() except (ValueError, TypeError): - raise ApiFieldError("Timedelta provided to '%s' field doesn't appear to be a valid datetime string: '%s'" % (self.instance_name, value)) + raise ApiFieldError( + f"Timedelta provided to '{self.instance_name}' field doesn't appear to be a valid datetime string: '{value}'" + ) else: - raise ApiFieldError("Datetime provided to '%s' field must be a string: %s" % (self.instance_name, value)) + raise ApiFieldError( + f"Datetime provided to '{self.instance_name}' field must be a string: {value}" + ) return value + class ToOneField(tastypie.fields.ToOneField): "Subclass of tastypie.fields.ToOneField which adds caching in the dehydrate method." @@ -118,7 +216,7 @@ def dehydrate(self, bundle, for_list=True): foreign_obj = None previous_obj = None attrib = None - + if callable(self.attribute): previous_obj = bundle.obj foreign_obj = self.attribute(bundle) @@ -136,19 +234,67 @@ def dehydrate(self, bundle, for_list=True): if not foreign_obj: if not self.null: if callable(self.attribute): - raise ApiFieldError("The related resource for resource %s could not be found." % (previous_obj)) + raise ApiFieldError( + f"The related resource for resource {previous_obj} could not be found." + ) else: - raise ApiFieldError("The model '%r' has an empty attribute '%s' and doesn't allow a null value." % (previous_obj, attrib)) + raise ApiFieldError( + f"The model '{previous_obj!r}' has an empty attribute '{attrib}' and doesn't allow a null value." + ) return None fk_resource = self.get_related_resource(foreign_obj) # Up to this point we've copied the code from tastypie 0.13.1. Now # we add caching. - cache_key = fk_resource.generate_cache_key('related', pk=foreign_obj.pk, for_list=for_list, ) + cache_key = fk_resource.generate_cache_key( + "related", + pk=foreign_obj.pk, + for_list=for_list, + ) dehydrated = fk_resource._meta.cache.get(cache_key) if dehydrated is None: fk_bundle = Bundle(obj=foreign_obj, request=bundle.request) - dehydrated = self.dehydrate_related(fk_bundle, fk_resource, for_list=for_list) + dehydrated = self.dehydrate_related( + fk_bundle, fk_resource, for_list=for_list + ) fk_resource._meta.cache.set(cache_key, dehydrated) return dehydrated + + +# XML 1.0 forbids all control characters except tab (#x9), LF (#xA), and CR (#xD). +# Replace each with its Unicode control picture (U+2400 + codepoint) so the +# substitution is lossless and the result is valid XML. +_XML_INVALID_CTRL_RE = re.compile(r"[\x00-\x08\x0b\x0c\x0e-\x1f]") + + +class Serializer(tastypie.serializers.Serializer): + OPTION_ESCAPE_XML_INVALID = "datatracker-escape-xml-invalid" + + def format_datetime(self, data): + return ( + data.astimezone(datetime.UTC) + .replace(tzinfo=None) + .isoformat(timespec="seconds") + + "Z" + ) + + def to_simple(self, data, options): + options = options or {} + simple_data = super().to_simple(data, options) + if options.get(self.OPTION_ESCAPE_XML_INVALID, False) and isinstance( + simple_data, str + ): + # Replace control chars invalid in XML 1.0 with their Unicode + # control pictures (U+2400-U+241F) so lxml won't reject the string. + simple_data = _XML_INVALID_CTRL_RE.sub( + lambda m: chr(ord(m.group()) + 0x2400), simple_data + ) + return simple_data + + def to_etree(self, data, options=None, name=None, depth=0): + # lxml rejects control characters that are invalid in XML 1.0. + # Ask to_simple() to escape them before they reach lxml. + options = options or {} + options[self.OPTION_ESCAPE_XML_INVALID] = True + return super().to_etree(data, options, name, depth) diff --git a/ietf/api/__init__.pyi b/ietf/api/__init__.pyi index 63d9bc513ba..ededea90a7d 100644 --- a/ietf/api/__init__.pyi +++ b/ietf/api/__init__.pyi @@ -30,4 +30,5 @@ class Serializer(): ... class ToOneField(tastypie.fields.ToOneField): ... class TimedeltaField(tastypie.fields.ApiField): ... +def populate_api_list() -> None: ... def autodiscover() -> None: ... diff --git a/ietf/api/apps.py b/ietf/api/apps.py new file mode 100644 index 00000000000..4549e0d7f20 --- /dev/null +++ b/ietf/api/apps.py @@ -0,0 +1,19 @@ +from django.apps import AppConfig +from . import populate_api_list + + +class ApiConfig(AppConfig): + name = "ietf.api" + + def ready(self): + """Hook to do init after the app registry is fully populated + + Importing models or accessing the app registry is ok here, but do not + interact with the database. See + https://docs.djangoproject.com/en/4.2/ref/applications/#django.apps.AppConfig.ready + """ + # Populate our API list now that the app registry is set up + populate_api_list() + + # Import drf-spectacular extensions + import ietf.api.schema # pyflakes: ignore diff --git a/ietf/api/authentication.py b/ietf/api/authentication.py new file mode 100644 index 00000000000..dfab0d72b8b --- /dev/null +++ b/ietf/api/authentication.py @@ -0,0 +1,19 @@ +# Copyright The IETF Trust 2024, All Rights Reserved +# +from rest_framework import authentication +from django.contrib.auth.models import AnonymousUser + + +class ApiKeyAuthentication(authentication.BaseAuthentication): + """API-Key header authentication""" + + def authenticate(self, request): + """Extract the authentication token, if present + + This does not validate the token, it just arranges for it to be available in request.auth. + It's up to a Permissions class to validate it for the appropriate endpoint. + """ + token = request.META.get("HTTP_X_API_KEY", None) + if token is None: + return None + return AnonymousUser(), token # available as request.user and request.auth diff --git a/ietf/api/ietf_utils.py b/ietf/api/ietf_utils.py new file mode 100644 index 00000000000..50767a5afd5 --- /dev/null +++ b/ietf/api/ietf_utils.py @@ -0,0 +1,76 @@ +# Copyright The IETF Trust 2023, All Rights Reserved + +# This is not utils.py because Tastypie implicitly consumes ietf.api.utils. +# See ietf.api.__init__.py for details. +from functools import wraps +from typing import Callable, Optional, Union + +from django.conf import settings +from django.http import HttpResponseForbidden + + +def is_valid_token(endpoint, token): + # This is where we would consider integration with vault + # Settings implementation for now. + if hasattr(settings, "APP_API_TOKENS"): + token_store = settings.APP_API_TOKENS + if endpoint in token_store: + endpoint_tokens = token_store[endpoint] + # Be sure endpoints is a list or tuple so we don't accidentally use substring matching! + if not isinstance(endpoint_tokens, (list, tuple)): + endpoint_tokens = [endpoint_tokens] + if token in endpoint_tokens: + return True + return False + + +def requires_api_token(func_or_endpoint: Optional[Union[Callable, str]] = None): + """Validate API token before executing the wrapped method + + Usage: + * Basic: endpoint defaults to the qualified name of the wrapped method. E.g., in ietf.api.views, + + @requires_api_token + def my_view(request): + ... + + will require a token for "ietf.api.views.my_view" + + * Custom endpoint: specify the endpoint explicitly + + @requires_api_token("ietf.api.views.some_other_thing") + def my_view(request): + ... + + will require a token for "ietf.api.views.some_other_thing" + """ + + def decorate(f): + if _endpoint is None: + fname = getattr(f, "__qualname__", None) + if fname is None: + raise TypeError( + "Cannot automatically decorate function that does not support __qualname__. " + "Explicitly set the endpoint." + ) + endpoint = "{}.{}".format(f.__module__, fname) + else: + endpoint = _endpoint + + @wraps(f) + def wrapped(request, *args, **kwargs): + authtoken = request.META.get("HTTP_X_API_KEY", None) + if authtoken is None or not is_valid_token(endpoint, authtoken): + return HttpResponseForbidden() + return f(request, *args, **kwargs) + + return wrapped + + # Magic to allow decorator to be used with or without parentheses + if callable(func_or_endpoint): + func = func_or_endpoint + _endpoint = None + return decorate(func) + else: + _endpoint = func_or_endpoint + return decorate diff --git a/ietf/api/management/commands/makeresources.py b/ietf/api/management/commands/makeresources.py index 07f8402e7dc..8e2c6f4b5cf 100644 --- a/ietf/api/management/commands/makeresources.py +++ b/ietf/api/management/commands/makeresources.py @@ -1,9 +1,8 @@ -# Copyright The IETF Trust 2014-2020, All Rights Reserved +# Copyright The IETF Trust 2014-2026, All Rights Reserved # -*- coding: utf-8 -*- import os -import datetime import collections import io @@ -14,8 +13,9 @@ from django.core.management.base import AppCommand from django.db import models from django.template import Template, Context +from django.utils import timezone -from tastypie.resources import ModelResource +from ietf.api import ModelResource resource_head_template = """# Copyright The IETF Trust {{date}}, All Rights Reserved @@ -23,7 +23,7 @@ # Generated by the makeresources management command {{date}} -from tastypie.resources import ModelResource +from ietf.api import ModelResource from tastypie.fields import ToManyField # pyflakes:ignore from tastypie.constants import ALL, ALL_WITH_RELATIONS # pyflakes:ignore from tastypie.cache import SimpleCache @@ -89,7 +89,7 @@ def handle_app_config(self, app, **options): info = dict( app=app.name, app_label=app.label, - date=datetime.datetime.now() + date=timezone.now() ) new_models = {} for model, rclass_name in missing_resources: diff --git a/ietf/api/permissions.py b/ietf/api/permissions.py new file mode 100644 index 00000000000..8f7fdd026fd --- /dev/null +++ b/ietf/api/permissions.py @@ -0,0 +1,39 @@ +# Copyright The IETF Trust 2024, All Rights Reserved +# +from rest_framework import permissions +from ietf.api.ietf_utils import is_valid_token + + +class HasApiKey(permissions.BasePermission): + """Permissions class that validates a token using is_valid_token + + The view class must indicate the relevant endpoint by setting `api_key_endpoint`. + Must be used with an Authentication class that puts a token in request.auth. + """ + def has_permission(self, request, view): + endpoint = getattr(view, "api_key_endpoint", None) + auth_token = getattr(request, "auth", None) + if endpoint is not None and auth_token is not None: + return is_valid_token(endpoint, auth_token) + return False + + +class IsOwnPerson(permissions.BasePermission): + """Permission to access own Person object""" + def has_object_permission(self, request, view, obj): + if not (request.user.is_authenticated and hasattr(request.user, "person")): + return False + return obj == request.user.person + + +class BelongsToOwnPerson(permissions.BasePermission): + """Permission to access objects associated with own Person + + Requires that the object have a "person" field that indicates ownership. + """ + def has_object_permission(self, request, view, obj): + if not (request.user.is_authenticated and hasattr(request.user, "person")): + return False + return ( + hasattr(obj, "person") and obj.person == request.user.person + ) diff --git a/ietf/api/routers.py b/ietf/api/routers.py new file mode 100644 index 00000000000..99afdb242af --- /dev/null +++ b/ietf/api/routers.py @@ -0,0 +1,31 @@ +# Copyright The IETF Trust 2024, All Rights Reserved +"""Custom django-rest-framework routers""" +from django.core.exceptions import ImproperlyConfigured +from rest_framework import routers + + +class PrefixedBasenameMixin: + """Mixin to add a prefix to the basename of a rest_framework BaseRouter""" + def __init__(self, name_prefix="", *args, **kwargs): + self.name_prefix = name_prefix + if len(self.name_prefix) == 0 or self.name_prefix[-1] == ".": + raise ImproperlyConfigured("Cannot use a name_prefix that is empty or ends with '.'") + super().__init__(*args, **kwargs) + + def register(self, prefix, viewset, basename=None): + # Get the superclass "register" method from the class this is mixed-in with. + # This avoids typing issues with calling super().register() directly in a + # mixin class. + super_register = getattr(super(), "register") + if not super_register or not callable(super_register): + raise TypeError("Must mixin with superclass that has register() method") + super_register(prefix, viewset, basename=f"{self.name_prefix}.{basename}") + + +class PrefixedSimpleRouter(PrefixedBasenameMixin, routers.SimpleRouter): + """SimpleRouter that adds a dot-separated prefix to its basename""" + + +class PrefixedDefaultRouter(PrefixedBasenameMixin, routers.DefaultRouter): + """DefaultRouter that adds a dot-separated prefix to its basename""" + diff --git a/ietf/api/schema.py b/ietf/api/schema.py new file mode 100644 index 00000000000..7340149685b --- /dev/null +++ b/ietf/api/schema.py @@ -0,0 +1,20 @@ +# Copyright The IETF Trust 2024, All Rights Reserved +# +from drf_spectacular.extensions import OpenApiAuthenticationExtension + + +class ApiKeyAuthenticationScheme(OpenApiAuthenticationExtension): + """Authentication scheme extension for the ApiKeyAuthentication + + Used by drf-spectacular when rendering the OpenAPI schema + """ + target_class = "ietf.api.authentication.ApiKeyAuthentication" + name = "apiKeyAuth" + + def get_security_definition(self, auto_schema): + return { + "type": "apiKey", + "description": "Shared secret in the X-Api-Key header", + "name": "X-Api-Key", + "in": "header", + } diff --git a/ietf/api/serializer.py b/ietf/api/serializer.py index 9d6cf1ebb86..d5bca430e00 100644 --- a/ietf/api/serializer.py +++ b/ietf/api/serializer.py @@ -1,6 +1,9 @@ -# Copyright The IETF Trust 2018-2020, All Rights Reserved +# Copyright The IETF Trust 2018-2024, All Rights Reserved # -*- coding: utf-8 -*- +"""Serialization utilities +This is _not_ for django-rest-framework! +""" import hashlib import json @@ -9,11 +12,12 @@ from django.core.exceptions import ObjectDoesNotExist, FieldError from django.core.serializers.json import Serializer from django.http import HttpResponse -from django.utils.encoding import smart_text +from django.utils.encoding import smart_str from django.db.models import Field -from django.db.models.query import QuerySet from django.db.models.signals import post_save, post_delete, m2m_changed +from django_stubs_ext import QuerySetAny + import debug # pyflakes:ignore @@ -121,7 +125,7 @@ def end_object(self, obj): for name in expansions: try: field = getattr(obj, name) - #self._current["_"+name] = smart_text(field) + #self._current["_"+name] = smart_str(field) if not isinstance(field, Field): options = self.options.copy() options["expand"] = [ v[len(name)+2:] for v in options["expand"] if v.startswith(name+"__") ] @@ -145,7 +149,7 @@ def end_object(self, obj): field_value = None else: field_value = field - if isinstance(field_value, QuerySet) or isinstance(field_value, list): + if isinstance(field_value, QuerySetAny) or isinstance(field_value, list): self._current[name] = dict([ (rel.pk, self.expand_related(rel, name)) for rel in field_value ]) else: if hasattr(field_value, "_meta"): @@ -188,10 +192,10 @@ def handle_fk_field(self, obj, field): related = related.natural_key() elif field.remote_field.field_name == related._meta.pk.name: # Related to remote object via primary key - related = smart_text(related._get_pk_val(), strings_only=True) + related = smart_str(related._get_pk_val(), strings_only=True) else: # Related to remote object via other field - related = smart_text(getattr(related, field.remote_field.field_name), strings_only=True) + related = smart_str(getattr(related, field.remote_field.field_name), strings_only=True) self._current[field.name] = related def handle_m2m_field(self, obj, field): @@ -201,7 +205,7 @@ def handle_m2m_field(self, obj, field): elif self.use_natural_keys and hasattr(field.remote_field.to, 'natural_key'): m2m_value = lambda value: value.natural_key() else: - m2m_value = lambda value: smart_text(value._get_pk_val(), strings_only=True) + m2m_value = lambda value: smart_str(value._get_pk_val(), strings_only=True) self._current[field.name] = [m2m_value(related) for related in getattr(obj, field.name).iterator()] @@ -221,7 +225,7 @@ class JsonExportMixin(object): # obj = None # # if obj is None: -# raise Http404(_('%(name)s object with primary key %(key)r does not exist.') % {'name': force_text(self.model._meta.verbose_name), 'key': escape(object_id)}) +# raise Http404(_('%(name)s object with primary key %(key)r does not exist.') % {'name': force_str(self.model._meta.verbose_name), 'key': escape(object_id)}) # # content_type = 'application/json' # return HttpResponse(serialize([ obj ], sort_keys=True, indent=3)[2:-2], content_type=content_type) @@ -264,6 +268,6 @@ def json_view(self, request, filter=None, expand=None): qd = dict( ( k, json.loads(v)[0] ) for k,v in items ) except (FieldError, ValueError) as e: return HttpResponse(json.dumps({"error": str(e)}, sort_keys=True, indent=3), content_type=content_type) - text = json.dumps({smart_text(self.model._meta): qd}, sort_keys=True, indent=3) + text = json.dumps({smart_str(self.model._meta): qd}, sort_keys=True, indent=3) return HttpResponse(text, content_type=content_type) diff --git a/ietf/api/serializers_rpc.py b/ietf/api/serializers_rpc.py new file mode 100644 index 00000000000..ca605fe6441 --- /dev/null +++ b/ietf/api/serializers_rpc.py @@ -0,0 +1,871 @@ +# Copyright The IETF Trust 2025-2026, All Rights Reserved +import datetime +from pathlib import Path +from typing import Literal, Optional + +from django.db import transaction +from django.urls import reverse as urlreverse +from django.utils import timezone +from drf_spectacular.types import OpenApiTypes +from drf_spectacular.utils import extend_schema_field +from rest_framework import fields, serializers + +from ietf.doc.expire import move_draft_files_to_archive +from ietf.doc.models import ( + DocumentAuthor, + Document, + RelatedDocument, + State, + DocEvent, + RfcAuthor, +) +from ietf.doc.serializers import RfcAuthorSerializer +from ietf.doc.tasks import trigger_red_precomputer_task, update_rfc_searchindex_task +from ietf.doc.utils import ( + default_consensus, + prettify_std_name, + update_action_holders, + update_rfcauthors, +) +from ietf.group.models import Group, Role +from ietf.group.serializers import AreaSerializer +from ietf.name.models import StreamName, StdLevelName +from ietf.person.models import Person +from ietf.utils import log + + +class PersonSerializer(serializers.ModelSerializer): + email = serializers.EmailField(read_only=True) + picture = serializers.URLField(source="cdn_photo_url", read_only=True) + url = serializers.SerializerMethodField( + help_text="relative URL for datatracker person page" + ) + + class Meta: + model = Person + fields = ["id", "plain_name", "email", "picture", "url"] + read_only_fields = ["id", "plain_name", "email", "picture", "url"] + + @extend_schema_field(OpenApiTypes.URI) + def get_url(self, object: Person): + return urlreverse( + "ietf.person.views.profile", + kwargs={"email_or_name": object.email_address() or object.name}, + ) + + +class EmailPersonSerializer(serializers.Serializer): + email = serializers.EmailField(source="address") + person_pk = serializers.IntegerField(source="person.pk") + name = serializers.CharField(source="person.name") + last_name = serializers.CharField(source="person.last_name") + initials = serializers.CharField(source="person.initials") + + +class LowerCaseEmailField(serializers.EmailField): + def to_representation(self, value): + return super().to_representation(value).lower() + + +class AuthorPersonSerializer(serializers.ModelSerializer): + person_pk = serializers.IntegerField(source="pk", read_only=True) + last_name = serializers.CharField() + initials = serializers.CharField() + email_addresses = serializers.ListField( + source="email_set.all", child=LowerCaseEmailField() + ) + + class Meta: + model = Person + fields = ["person_pk", "name", "last_name", "initials", "email_addresses"] + + +class RfcWithAuthorsSerializer(serializers.ModelSerializer): + authors = AuthorPersonSerializer(many=True, source="author_persons") + + class Meta: + model = Document + fields = ["rfc_number", "authors"] + + +class DraftWithAuthorsSerializer(serializers.ModelSerializer): + draft_name = serializers.CharField(source="name") + authors = AuthorPersonSerializer(many=True, source="author_persons") + + class Meta: + model = Document + fields = ["draft_name", "authors"] + + +class WgChairSerializer(serializers.Serializer): + """Serialize a WG chair's name and email from a Role""" + + name = serializers.SerializerMethodField() + email = serializers.SerializerMethodField() + + @extend_schema_field(serializers.CharField) + def get_name(self, role: Role) -> str: + return role.person.plain_name() + + @extend_schema_field(serializers.EmailField) + def get_email(self, role: Role) -> str: + return role.email.email_address() + + +class DocumentAuthorSerializer(serializers.ModelSerializer): + """Serializer for a Person in a response""" + + plain_name = serializers.SerializerMethodField() + + class Meta: + model = DocumentAuthor + fields = ["person", "plain_name", "affiliation"] + + def get_plain_name(self, document_author: DocumentAuthor) -> str: + return document_author.person.plain_name() + + +class FullDraftSerializer(serializers.ModelSerializer): + # Redefine these fields so they don't pick up the regex validator patterns. + # There seem to be some non-compliant drafts in the system! If this serializer + # is used for a writeable view, the validation will need to be added back. + name = serializers.CharField(max_length=255) + title = serializers.CharField(max_length=255) + group = serializers.SlugRelatedField(slug_field="acronym", read_only=True) + area = AreaSerializer(read_only=True) + + # Other fields we need to add / adjust + source_format = serializers.SerializerMethodField() + authors = DocumentAuthorSerializer(many=True, source="documentauthor_set") + shepherd = serializers.PrimaryKeyRelatedField( + source="shepherd.person", read_only=True + ) + consensus = serializers.SerializerMethodField() + wg_chairs = serializers.SerializerMethodField() + + class Meta: + model = Document + fields = [ + "id", + "name", + "rev", + "stream", + "title", + "group", + "area", + "abstract", + "pages", + "source_format", + "authors", + "intended_std_level", + "consensus", + "shepherd", + "ad", + "wg_chairs", + ] + + def get_consensus(self, doc: Document) -> Optional[bool]: + return default_consensus(doc) + + @extend_schema_field(WgChairSerializer(many=True)) + def get_wg_chairs(self, doc: Document): + if doc.group is None: + return [] + chairs = doc.group.role_set.filter(name_id="chair").select_related( + "person", "email" + ) + return WgChairSerializer(chairs, many=True).data + + def get_source_format( + self, doc: Document + ) -> Literal["unknown", "xml-v2", "xml-v3", "txt"]: + submission = doc.submission() + if submission is None: + return "unknown" + if ".xml" in submission.file_types: + if submission.xml_version == "3": + return "xml-v3" + else: + return "xml-v2" + elif ".txt" in submission.file_types: + return "txt" + return "unknown" + + +class DraftSerializer(FullDraftSerializer): + class Meta: + model = Document + fields = [ + "id", + "name", + "rev", + "stream", + "title", + "group", + "pages", + "source_format", + "authors", + "consensus", + ] + + +class SubmittedToQueueSerializer(FullDraftSerializer): + submitted = serializers.SerializerMethodField() + consensus = serializers.SerializerMethodField() + + class Meta: + model = Document + fields = [ + "id", + "name", + "stream", + "submitted", + "consensus", + ] + + def get_submitted(self, doc) -> Optional[datetime.datetime]: + event = doc.sent_to_rfc_editor_event() + return None if event is None else event.time + + def get_consensus(self, doc) -> Optional[bool]: + return default_consensus(doc) + + +class OriginalStreamSerializer(serializers.ModelSerializer): + stream = serializers.CharField(read_only=True, source="orig_stream_id") + + class Meta: + model = Document + fields = ["rfc_number", "stream"] + + +class ReferenceSerializer(serializers.ModelSerializer): + class Meta: + model = Document + fields = ["id", "name"] + read_only_fields = ["id", "name"] + + +def _update_authors(rfc, authors_data): + # Construct unsaved instances from validated author data + new_authors = [RfcAuthor(**authdata) for authdata in authors_data] + # Update the RFC with the new author set + with transaction.atomic(): + change_events = update_rfcauthors(rfc, new_authors) + for event in change_events: + event.save() + return change_events + + +class SubseriesNameField(serializers.RegexField): + + def __init__(self, **kwargs): + # pattern: no leading 0, finite length (arbitrarily set to 5 digits) + regex = r"^(bcp|std|fyi)[1-9][0-9]{0,4}$" + super().__init__(regex, **kwargs) + + +class RfcGroupRelatedField(serializers.SlugRelatedField): + """SlugRelatedField that translates None / "" to the acronym "none" """ + + def __init__(self, **kwargs): + super().__init__( + slug_field="acronym", + queryset=Group.objects.all(), + allow_null=True, + required=False, + ) + + def run_validation(self, data=fields.empty): + # Use the Group with acronym "none" when group is not specified + if data is fields.empty or data is None or data == "": + data = "none" + return super().run_validation(data) + + +class RfcPubSerializer(serializers.ModelSerializer): + """Write-only serializer for RFC publication""" + # publication-related fields + published = serializers.DateTimeField(default_timezone=datetime.timezone.utc) + draft_name = serializers.RegexField( + required=False, regex=r"^draft-[a-zA-Z0-9-]+$" + ) + draft_rev = serializers.RegexField( + required=False, regex=r"^[0-9][0-9]$" + ) + + # fields on the RFC Document that need tweaking from ModelSerializer defaults + rfc_number = serializers.IntegerField(min_value=1, required=True) + group = RfcGroupRelatedField() + stream = serializers.PrimaryKeyRelatedField( + queryset=StreamName.objects.filter(used=True) + ) + std_level = serializers.PrimaryKeyRelatedField( + queryset=StdLevelName.objects.filter(used=True), + ) + ad = serializers.PrimaryKeyRelatedField( + queryset=Person.objects.all(), + allow_null=True, + required=False, + ) + obsoletes = serializers.SlugRelatedField( + many=True, + required=False, + slug_field="rfc_number", + queryset=Document.objects.filter(type_id="rfc"), + ) + updates = serializers.SlugRelatedField( + many=True, + required=False, + slug_field="rfc_number", + queryset=Document.objects.filter(type_id="rfc"), + ) + subseries = serializers.ListField(child=SubseriesNameField(required=False)) + # N.b., authors is _not_ a field on Document! + authors = RfcAuthorSerializer(many=True) + + class Meta: + model = Document + fields = [ + "published", + "draft_name", + "draft_rev", + "rfc_number", + "title", + "authors", + "group", + "stream", + "abstract", + "pages", + "std_level", + "ad", + "obsoletes", + "updates", + "subseries", + "keywords", + ] + + def validate(self, data): + if "draft_name" in data or "draft_rev" in data: + if "draft_name" not in data: + raise serializers.ValidationError( + {"draft_name": "Missing draft_name"}, + code="invalid-draft-spec", + ) + if "draft_rev" not in data: + raise serializers.ValidationError( + {"draft_rev": "Missing draft_rev"}, + code="invalid-draft-spec", + ) + return data + + def update(self, instance, validated_data): + raise RuntimeError("Cannot update with this serializer") + + def create(self, validated_data): + """Publish an RFC""" + published = validated_data.pop("published") + draft_name = validated_data.pop("draft_name", None) + draft_rev = validated_data.pop("draft_rev", None) + obsoletes = validated_data.pop("obsoletes", []) + updates = validated_data.pop("updates", []) + subseries = validated_data.pop("subseries", []) + + system_person = Person.objects.get(name="(System)") + + # If specified, retrieve draft and extract RFC default values from it + if draft_name is None: + draft = None + else: + # validation enforces that draft_name and draft_rev are both present + draft = Document.objects.filter( + type_id="draft", + name=draft_name, + rev=draft_rev, + ).first() + if draft is None: + raise serializers.ValidationError( + { + "draft_name": "No such draft", + "draft_rev": "No such draft", + }, + code="invalid-draft" + ) + elif draft.get_state_slug() == "rfc": + raise serializers.ValidationError( + { + "draft_name": "Draft already published as RFC", + }, + code="already-published-draft", + ) + + # Transaction to clean up if something fails + with transaction.atomic(): + # create rfc, letting validated request data override draft defaults + rfc = self._create_rfc(validated_data) + DocEvent.objects.create( + doc=rfc, + rev=rfc.rev, + type="published_rfc", + time=published, + by=system_person, + desc="RFC published", + ) + rfc.set_state(State.objects.get(used=True, type_id="rfc", slug="published")) + + # create updates / obsoletes relations + for obsoleted_rfc_pk in obsoletes: + RelatedDocument.objects.get_or_create( + source=rfc, target=obsoleted_rfc_pk, relationship_id="obs" + ) + for updated_rfc_pk in updates: + RelatedDocument.objects.get_or_create( + source=rfc, target=updated_rfc_pk, relationship_id="updates" + ) + + # create subseries relations + for subseries_doc_name in subseries: + ss_slug = subseries_doc_name[:3] + subseries_doc, ss_doc_created = Document.objects.get_or_create( + type_id=ss_slug, name=subseries_doc_name + ) + if ss_doc_created: + subseries_doc.docevent_set.create( + type=f"{ss_slug}_doc_created", + by=system_person, + desc=f"Created {subseries_doc_name} via publication of {rfc.name}", + ) + _, ss_rel_created = subseries_doc.relateddocument_set.get_or_create( + relationship_id="contains", target=rfc + ) + if ss_rel_created: + subseries_doc.docevent_set.create( + type="sync_from_rfc_editor", + by=system_person, + desc=f"Added {rfc.name} to {subseries_doc.name}", + ) + rfc.docevent_set.create( + type="sync_from_rfc_editor", + by=system_person, + desc=f"Added {rfc.name} to {subseries_doc.name}", + ) + + + # create relation with draft and update draft state + if draft is not None: + draft_changes = [] + draft_events = [] + if draft.get_state_slug() != "rfc": + draft.set_state( + State.objects.get(used=True, type="draft", slug="rfc") + ) + move_draft_files_to_archive(draft, draft.rev) + draft_changes.append(f"changed state to {draft.get_state()}") + + r, created_relateddoc = RelatedDocument.objects.get_or_create( + source=draft, target=rfc, relationship_id="became_rfc", + ) + if created_relateddoc: + change = "created {rel_name} relationship between {pretty_draft_name} and {pretty_rfc_name}".format( + rel_name=r.relationship.name.lower(), + pretty_draft_name=prettify_std_name(draft_name), + pretty_rfc_name=prettify_std_name(rfc.name), + ) + draft_changes.append(change) + + # Always set the "draft-iesg" state. This state should be set for all drafts, so + # log a warning if it is not set. What should happen here is that ietf stream + # RFCs come in as "rfcqueue" and are set to "pub" when they appear in the RFC index. + # Other stream documents should normally be "idexists" and be left that way. The + # code here *actually* leaves "draft-iesg" state alone if it is "idexists" or "pub", + # and changes any other state to "pub". If unset, it changes it to "idexists". + # This reflects historical behavior and should probably be updated, but a migration + # of existing drafts (and validation of the change) is needed before we change the + # handling. + prev_iesg_state = draft.get_state("draft-iesg") + if prev_iesg_state is None: + log.log(f'Warning while processing {rfc.name}: {draft.name} has no "draft-iesg" state') + new_iesg_state = State.objects.get(type_id="draft-iesg", slug="idexists") + elif prev_iesg_state.slug not in ("pub", "idexists"): + if prev_iesg_state.slug != "rfcqueue": + log.log( + 'Warning while processing {}: {} is in "draft-iesg" state {} (expected "rfcqueue")'.format( + rfc.name, draft.name, prev_iesg_state.slug + ) + ) + new_iesg_state = State.objects.get(type_id="draft-iesg", slug="pub") + else: + new_iesg_state = prev_iesg_state + + if new_iesg_state != prev_iesg_state: + draft.set_state(new_iesg_state) + draft_changes.append(f"changed {new_iesg_state.type.label} to {new_iesg_state}") + e = update_action_holders(draft, prev_iesg_state, new_iesg_state) + if e: + draft_events.append(e) + + # If the draft and RFC streams agree, move draft to "pub" stream state. If not, complain. + if draft.stream != rfc.stream: + log.log("Warning while processing {}: draft {} stream is {} but RFC stream is {}".format( + rfc.name, draft.name, draft.stream, rfc.stream + )) + elif draft.stream.slug in ["iab", "irtf", "ise", "editorial"]: + stream_slug = f"draft-stream-{draft.stream.slug}" + prev_state = draft.get_state(stream_slug) + if prev_state is not None and prev_state.slug != "pub": + new_state = State.objects.select_related("type").get(used=True, type__slug=stream_slug, slug="pub") + draft.set_state(new_state) + draft_changes.append( + f"changed {new_state.type.label} to {new_state}" + ) + e = update_action_holders(draft, prev_state, new_state) + if e: + draft_events.append(e) + if draft_changes: + draft_events.append( + DocEvent.objects.create( + doc=draft, + rev=draft.rev, + by=system_person, + type="sync_from_rfc_editor", + desc=f"Updated while publishing {rfc.name} ({', '.join(draft_changes)})", + ) + ) + draft.save_with_history(draft_events) + + return rfc + + def _create_rfc(self, validated_data): + authors_data = validated_data.pop("authors") + rfc = Document.objects.create( + type_id="rfc", + name=f"rfc{validated_data['rfc_number']}", + **validated_data, + ) + for order, author_data in enumerate(authors_data): + rfc.rfcauthor_set.create( + order=order, + **author_data, + ) + return rfc + + +class EditableRfcSerializer(serializers.ModelSerializer): + # Would be nice to reconcile this with ietf.doc.serializers.RfcSerializer. + # The purposes of that serializer (representing data for Red) and this one + # (accepting updates from Purple) are different enough that separate formats + # may be needed, but if not it'd be nice to have a single RfcSerializer that + # can serve both. + # + # Should also consider whether this and RfcPubSerializer should merge. + # + # Treats published and subseries fields as write-only. This isn't quite correct, + # but makes it easier and we don't currently use the serialized value except for + # debugging. + published = serializers.DateTimeField( + default_timezone=datetime.timezone.utc, + write_only=True, + ) + authors = RfcAuthorSerializer(many=True, min_length=1, source="rfcauthor_set") + subseries = serializers.ListField( + child=SubseriesNameField(required=False), + write_only=True, + ) + updates = serializers.ListField( + child=serializers.IntegerField(), + required=False, + write_only=True, + help_text="List of RFC numbers this document updates." + ) + obsoletes = serializers.ListField( + child=serializers.IntegerField(), + required=False, + write_only=True, + help_text="List of RFC numbers this document obsoletes." + ) + + class Meta: + model = Document + fields = [ + "published", + "title", + "authors", + "stream", + "abstract", + "pages", + "std_level", + "subseries", + "keywords", + "updates", + "obsoletes", + ] + + def _validate_rfc_number_list(self, field_name, rfc_numbers): + """Raise ValidationError if any RFC numbers in the list don't exist.""" + unknown = [ + n for n in rfc_numbers + if not Document.objects.filter(rfc_number=n, type_id="rfc").exists() + ] + if unknown: + raise serializers.ValidationError( + {field_name: [f"Unknown RFC number: {n}" for n in unknown]} + ) + return rfc_numbers + + def validate_updates(self, value): + return self._validate_rfc_number_list("updates", value) + + def validate_obsoletes(self, value): + return self._validate_rfc_number_list("obsoletes", value) + + def create(self, validated_data): + raise RuntimeError("Cannot create with this serializer") + + def update(self, instance, validated_data): + assert isinstance(instance, Document) + assert instance.type_id == "rfc" + rfc = instance # get better name + + system_person = Person.objects.get(name="(System)") + + # Remove data that needs special handling. Use a singleton object to detect + # missing values in case we ever support a value that needs None as an option. + omitted = object() + published = validated_data.pop("published", omitted) + subseries = validated_data.pop("subseries", omitted) + authors_data = validated_data.pop("rfcauthor_set", omitted) + updates = validated_data.pop("updates", omitted) + obsoletes = validated_data.pop("obsoletes", omitted) + + # Transaction to clean up if something fails + with transaction.atomic(): + # update the rfc Document itself + rfc_changes = [] + rfc_events = [] + + for attr, new_value in validated_data.items(): + old_value = getattr(rfc, attr) + if new_value != old_value: + rfc_changes.append( + f"changed {attr} to '{new_value}' from '{old_value}'" + ) + setattr(rfc, attr, new_value) + if len(rfc_changes) > 0: + rfc_change_summary = f"{', '.join(rfc_changes)}" + rfc_events.append( + DocEvent.objects.create( + doc=rfc, + rev=rfc.rev, + by=system_person, + type="sync_from_rfc_editor", + desc=f"Changed metadata: {rfc_change_summary}", + ) + ) + if authors_data is not omitted: + rfc_events.extend(_update_authors(instance, authors_data)) + + if published is not omitted: + published_event = rfc.latest_event(type="published_rfc") + if published_event is None: + # unexpected, but possible in theory + rfc_events.append( + DocEvent.objects.create( + doc=rfc, + rev=rfc.rev, + type="published_rfc", + time=published, + by=system_person, + desc="RFC published", + ) + ) + rfc_events.append( + DocEvent.objects.create( + doc=rfc, + rev=rfc.rev, + type="sync_from_rfc_editor", + by=system_person, + desc=( + f"Set publication timestamp to {published.isoformat()}" + ), + ) + ) + else: + original_pub_time = published_event.time + if published != original_pub_time: + published_event.time = published + published_event.save() + rfc_events.append( + DocEvent.objects.create( + doc=rfc, + rev=rfc.rev, + type="sync_from_rfc_editor", + by=system_person, + desc=( + f"Changed publication time to " + f"{published.isoformat()} from " + f"{original_pub_time.isoformat()}" + ) + ) + ) + if updates is not omitted: + RelatedDocument.objects.filter( + source=rfc, relationship_id="updates" + ).exclude(target__rfc_number__in=updates).delete() + for rfc_num in updates: + target = Document.objects.get(rfc_number=rfc_num, type_id="rfc") + RelatedDocument.objects.get_or_create( + source=rfc, relationship_id="updates", target=target + ) + if obsoletes is not omitted: + RelatedDocument.objects.filter( + source=rfc, relationship_id="obs" + ).exclude(target__rfc_number__in=obsoletes).delete() + for rfc_num in obsoletes: + target = Document.objects.get(rfc_number=rfc_num, type_id="rfc") + RelatedDocument.objects.get_or_create( + source=rfc, relationship_id="obs", target=target + ) + + # update subseries relations + if subseries is not omitted: + for subseries_doc_name in subseries: + ss_slug = subseries_doc_name[:3] + subseries_doc, ss_doc_created = Document.objects.get_or_create( + type_id=ss_slug, name=subseries_doc_name + ) + if ss_doc_created: + subseries_doc.docevent_set.create( + type=f"{ss_slug}_doc_created", + by=system_person, + desc=f"Created {subseries_doc_name} via update of {rfc.name}", + ) + _, ss_rel_created = subseries_doc.relateddocument_set.get_or_create( + relationship_id="contains", target=rfc + ) + if ss_rel_created: + subseries_doc.docevent_set.create( + type="sync_from_rfc_editor", + by=system_person, + desc=f"Added {rfc.name} to {subseries_doc.name}", + ) + rfc_events.append( + rfc.docevent_set.create( + type="sync_from_rfc_editor", + by=system_person, + desc=f"Added {rfc.name} to {subseries_doc.name}", + ) + ) + # Delete subseries relations that are no longer current + stale_subseries_relations = rfc.relations_that("contains").exclude( + source__name__in=subseries + ) + for stale_relation in stale_subseries_relations: + stale_subseries_doc = stale_relation.source + rfc_events.append( + rfc.docevent_set.create( + type="sync_from_rfc_editor", + by=system_person, + desc=f"Removed {rfc.name} from {stale_subseries_doc.name}", + ) + ) + stale_subseries_doc.docevent_set.create( + type="sync_from_rfc_editor", + by=system_person, + desc=f"Removed {rfc.name} from {stale_subseries_doc.name}", + ) + stale_subseries_relations.delete() + if len(rfc_events) > 0: + rfc.save_with_history(rfc_events) + # Gather obs and updates in both directions as a title/author change to + # this doc affects the info rendering of all of the other RFCs + needs_updating = sorted( + [ + d.rfc_number + for d in [rfc] + + rfc.related_that_doc(("obs", "updates")) + + rfc.related_that(("obs", "updates")) + ] + ) + trigger_red_precomputer_task.delay(rfc_number_list=needs_updating) + # Update the search index also + update_rfc_searchindex_task.delay(rfc.rfc_number) + return rfc + + +class RfcFileSerializer(serializers.Serializer): + # The structure of this serializer is constrained by what openapi-generator-cli's + # python generator can correctly serialize as multipart/form-data. It does not + # handle nested serializers well (or perhaps at all). ListFields with child + # ChoiceField or RegexField do not serialize correctly. DictFields don't seem + # to work. + # + # It does seem to correctly send filenames along with FileFields, even as a child + # in a ListField, so we use that to convey the file format of each item. There + # are other options we could consider (e.g., a structured CharField) but this + # works. + allowed_extensions = ( + ".html", + ".json", # deprecated - accepted but ignored, datatracker generates its own + ".notprepped.xml", + ".pdf", + ".txt", + ".xml", + ) + + rfc = serializers.SlugRelatedField( + slug_field="rfc_number", + queryset=Document.objects.filter(type_id="rfc"), + help_text="RFC number to which the contents belong", + ) + contents = serializers.ListField( + child=serializers.FileField( + allow_empty_file=False, + use_url=False, + ), + help_text=( + "List of content files. Filename extensions are used to identify " + "file types, but filenames are otherwise ignored." + ), + ) + mtime = serializers.DateTimeField( + required=False, + default=timezone.now, + default_timezone=datetime.UTC, + help_text="Modification timestamp to apply to uploaded files", + ) + replace = serializers.BooleanField( + required=False, + default=False, + help_text=( + "Replace existing files for this RFC. Defaults to false. When false, " + "if _any_ files already exist for the specified RFC the upload will be " + "rejected regardless of which files are being uploaded. When true," + "existing files will be removed and new ones will be put in place. BE" + "VERY CAREFUL WITH THIS OPTION IN PRODUCTION." + ), + ) + + def validate_contents(self, data): + found_extensions = [] + for uploaded_file in data: + if not hasattr(uploaded_file, "name"): + raise serializers.ValidationError( + "filename not specified for uploaded file", + code="missing-filename", + ) + ext = "".join(Path(uploaded_file.name).suffixes) + if ext not in self.allowed_extensions: + raise serializers.ValidationError( + f"File uploaded with invalid extension '{ext}'", + code="invalid-filename-ext", + ) + if ext in found_extensions: + raise serializers.ValidationError( + f"More than one file uploaded with extension '{ext}'", + code="duplicate-filename-ext", + ) + return data + + +class NotificationAckSerializer(serializers.Serializer): + message = serializers.CharField(default="ack") diff --git a/ietf/api/tests.py b/ietf/api/tests.py index b887a6d46a6..204d2120f59 100644 --- a/ietf/api/tests.py +++ b/ietf/api/tests.py @@ -1,18 +1,24 @@ -# Copyright The IETF Trust 2015-2020, All Rights Reserved +# Copyright The IETF Trust 2015-2024, All Rights Reserved # -*- coding: utf-8 -*- - +import base64 +import copy import datetime import json import html +from unittest import mock import os import sys from importlib import import_module -from mock import patch +from pathlib import Path +from random import randrange +from urllib.parse import quote, urlencode, urljoin from django.apps import apps from django.conf import settings -from django.test import Client +from django.http import HttpResponseForbidden +from django.test import Client, RequestFactory +from django.test.utils import override_settings from django.urls import reverse as urlreverse from django.utils import timezone @@ -21,40 +27,36 @@ import debug # pyflakes:ignore import ietf +from ietf.doc.storage_utils import retrieve_str +from ietf.doc.utils import get_unicode_document_content +from ietf.doc.models import RelatedDocument, State +from ietf.doc.factories import IndividualDraftFactory, WgDraftFactory, WgRfcFactory, RfcAuthorFactory, DocEventFactory from ietf.group.factories import RoleFactory from ietf.meeting.factories import MeetingFactory, SessionFactory -from ietf.meeting.test_data import make_meeting_test_data -from ietf.meeting.models import Session -from ietf.person.factories import PersonFactory, random_faker -from ietf.person.models import User -from ietf.person.models import PersonalApiKey -from ietf.stats.models import MeetingRegistration -from ietf.utils.mail import outbox, get_payload_text -from ietf.utils.test_utils import TestCase, login_testing_unauthorized +from ietf.meeting.models import Session, Registration +from ietf.nomcom.models import Volunteer +from ietf.nomcom.factories import NomComFactory, nomcom_kwargs_for_year +from ietf.person.factories import PersonFactory, random_faker, EmailFactory, PersonalApiKeyFactory +from ietf.person.models import Email, User +from ietf.utils.mail import empty_outbox, outbox, get_payload_text +from ietf.utils.models import DumpInfo +from ietf.utils.test_utils import TestCase, login_testing_unauthorized, reload_db_objects + +from . import Serializer +from .ietf_utils import is_valid_token, requires_api_token +from .views import EmailIngestionError OMITTED_APPS = ( 'ietf.secr.meetings', 'ietf.secr.proceedings', 'ietf.ipr', + 'ietf.status', + 'ietf.blobdb', ) class CustomApiTests(TestCase): settings_temp_path_overrides = TestCase.settings_temp_path_overrides + ['AGENDA_PATH'] - # Using mock to patch the import functions in ietf.meeting.views, where - # api_import_recordings() are using them: - @patch('ietf.meeting.views.import_audio_files') - def test_notify_meeting_import_audio_files(self, mock_import_audio): - meeting = make_meeting_test_data() - client = Client(Accept='application/json') - # try invalid method GET - url = urlreverse('ietf.meeting.views.api_import_recordings', kwargs={'number':meeting.number}) - r = client.get(url) - self.assertEqual(r.status_code, 405) - # try valid method POST - r = client.post(url) - self.assertEqual(r.status_code, 201) - def test_api_help_page(self): url = urlreverse('ietf.api.views.api_help') r = self.client.get(url) @@ -65,14 +67,14 @@ def test_api_openid_issuer(self): r = self.client.get(url) self.assertContains(r, 'OpenID Connect Issuer', status_code=200) - def test_api_set_session_video_url(self): + def test_deprecated_api_set_session_video_url(self): url = urlreverse('ietf.meeting.views.api_set_session_video_url') recmanrole = RoleFactory(group__type_id='ietf', name_id='recman') recman = recmanrole.person meeting = MeetingFactory(type_id='ietf') session = SessionFactory(group__type_id='wg', meeting=meeting) group = session.group - apikey = PersonalApiKey.objects.create(endpoint=url, person=recman) + apikey = PersonalApiKeyFactory(endpoint=url, person=recman) video = 'https://foo.example.com/bar/beer/' # error cases @@ -80,7 +82,7 @@ def test_api_set_session_video_url(self): self.assertContains(r, "Missing apikey parameter", status_code=400) badrole = RoleFactory(group__type_id='ietf', name_id='ad') - badapikey = PersonalApiKey.objects.create(endpoint=url, person=badrole.person) + badapikey = PersonalApiKeyFactory(endpoint=url, person=badrole.person) badrole.person.user.last_login = timezone.now() badrole.person.user.save() r = self.client.post(url, {'apikey': badapikey.hash()} ) @@ -94,7 +96,7 @@ def test_api_set_session_video_url(self): r = self.client.get(url, {'apikey': apikey.hash()} ) self.assertContains(r, "Method not allowed", status_code=405) - r = self.client.post(url, {'apikey': apikey.hash()} ) + r = self.client.post(url, {'apikey': apikey.hash(), 'group': group.acronym} ) self.assertContains(r, "Missing meeting parameter", status_code=400) @@ -146,17 +148,160 @@ def test_api_set_session_video_url(self): event = doc.latest_event() self.assertEqual(event.by, recman) - def test_api_add_session_attendees(self): + def test_api_set_session_video_url(self): + url = urlreverse("ietf.meeting.views.api_set_session_video_url") + recmanrole = RoleFactory(group__type_id="ietf", name_id="recman") + recman = recmanrole.person + meeting = MeetingFactory(type_id="ietf") + session = SessionFactory(group__type_id="wg", meeting=meeting) + apikey = PersonalApiKeyFactory(endpoint=url, person=recman) + video = "https://foo.example.com/bar/beer/" + + # error cases + r = self.client.post(url, {}) + self.assertContains(r, "Missing apikey parameter", status_code=400) + + badrole = RoleFactory(group__type_id="ietf", name_id="ad") + badapikey = PersonalApiKeyFactory(endpoint=url, person=badrole.person) + badrole.person.user.last_login = timezone.now() + badrole.person.user.save() + r = self.client.post(url, {"apikey": badapikey.hash()}) + self.assertContains(r, "Restricted to role: Recording Manager", status_code=403) + + r = self.client.post(url, {"apikey": apikey.hash()}) + self.assertContains(r, "Too long since last regular login", status_code=400) + recman.user.last_login = timezone.now() + recman.user.save() + + r = self.client.get(url, {"apikey": apikey.hash()}) + self.assertContains(r, "Method not allowed", status_code=405) + + r = self.client.post(url, {"apikey": apikey.hash()}) + self.assertContains(r, "Missing session_id parameter", status_code=400) + + r = self.client.post(url, {"apikey": apikey.hash(), "session_id": session.pk}) + self.assertContains(r, "Missing url parameter", status_code=400) + + bad_pk = int(Session.objects.order_by("-pk").first().pk) + 1 + r = self.client.post( + url, + { + "apikey": apikey.hash(), + "session_id": bad_pk, + "url": video, + }, + ) + self.assertContains(r, "Session not found", status_code=400) + + r = self.client.post( + url, + { + "apikey": apikey.hash(), + "session_id": "foo", + "url": video, + }, + ) + self.assertContains(r, "Invalid session_id", status_code=400) + + r = self.client.post( + url, + { + "apikey": apikey.hash(), + "session_id": session.pk, + "url": "foobar", + }, + ) + self.assertContains(r, "Invalid url value: 'foobar'", status_code=400) + + r = self.client.post( + url, {"apikey": apikey.hash(), "session_id": session.pk, "url": video} + ) + self.assertContains(r, "Done", status_code=200) + + recordings = session.recordings() + self.assertEqual(len(recordings), 1) + doc = recordings[0] + self.assertEqual(doc.external_url, video) + event = doc.latest_event() + self.assertEqual(event.by, recman) + + def test_api_set_meetecho_recording_name(self): + url = urlreverse("ietf.meeting.views.api_set_meetecho_recording_name") + recmanrole = RoleFactory(group__type_id="ietf", name_id="recman") + recman = recmanrole.person + meeting = MeetingFactory(type_id="ietf") + session = SessionFactory(group__type_id="wg", meeting=meeting) + apikey = PersonalApiKeyFactory(endpoint=url, person=recman) + name = "testname" + + # error cases + r = self.client.post(url, {}) + self.assertContains(r, "Missing apikey parameter", status_code=400) + + badrole = RoleFactory(group__type_id="ietf", name_id="ad") + badapikey = PersonalApiKeyFactory(endpoint=url, person=badrole.person) + badrole.person.user.last_login = timezone.now() + badrole.person.user.save() + r = self.client.post(url, {"apikey": badapikey.hash()}) + self.assertContains(r, "Restricted to role: Recording Manager", status_code=403) + + r = self.client.post(url, {"apikey": apikey.hash()}) + self.assertContains(r, "Too long since last regular login", status_code=400) + recman.user.last_login = timezone.now() + recman.user.save() + + r = self.client.get(url, {"apikey": apikey.hash()}) + self.assertContains(r, "Method not allowed", status_code=405) + + r = self.client.post(url, {"apikey": apikey.hash()}) + self.assertContains(r, "Missing session_id parameter", status_code=400) + + r = self.client.post(url, {"apikey": apikey.hash(), "session_id": session.pk}) + self.assertContains(r, "Missing name parameter", status_code=400) + + bad_pk = int(Session.objects.order_by("-pk").first().pk) + 1 + r = self.client.post( + url, + { + "apikey": apikey.hash(), + "session_id": bad_pk, + "name": name, + }, + ) + self.assertContains(r, "Session not found", status_code=400) + + r = self.client.post( + url, + { + "apikey": apikey.hash(), + "session_id": "foo", + "name": name, + }, + ) + self.assertContains(r, "Invalid session_id", status_code=400) + + r = self.client.post( + url, {"apikey": apikey.hash(), "session_id": session.pk, "name": name} + ) + self.assertContains(r, "Done", status_code=200) + + session.refresh_from_db() + self.assertEqual(session.meetecho_recording_name, name) + + + def test_api_add_session_attendees_deprecated(self): + # Deprecated test - should be removed when we stop accepting a simple list of user PKs in + # the add_session_attendees() view url = urlreverse('ietf.meeting.views.api_add_session_attendees') otherperson = PersonFactory() recmanrole = RoleFactory(group__type_id='ietf', name_id='recman') recman = recmanrole.person meeting = MeetingFactory(type_id='ietf') session = SessionFactory(group__type_id='wg', meeting=meeting) - apikey = PersonalApiKey.objects.create(endpoint=url, person=recman) + apikey = PersonalApiKeyFactory(endpoint=url, person=recman) badrole = RoleFactory(group__type_id='ietf', name_id='ad') - badapikey = PersonalApiKey.objects.create(endpoint=url, person=badrole.person) + badapikey = PersonalApiKeyFactory(endpoint=url, person=badrole.person) badrole.person.user.last_login = timezone.now() badrole.person.user.save() @@ -212,20 +357,224 @@ def test_api_add_session_attendees(self): self.assertTrue(session.attended_set.filter(person=recman).exists()) self.assertTrue(session.attended_set.filter(person=otherperson).exists()) - def test_api_upload_bluesheet(self): - url = urlreverse('ietf.meeting.views.api_upload_bluesheet') - recmanrole = RoleFactory(group__type_id='ietf', name_id='recman') + def test_api_add_session_attendees(self): + url = urlreverse("ietf.meeting.views.api_add_session_attendees") + otherperson = PersonFactory() + recmanrole = RoleFactory(group__type_id="ietf", name_id="recman") recman = recmanrole.person + meeting = MeetingFactory(type_id="ietf") + session = SessionFactory(group__type_id="wg", meeting=meeting) + apikey = PersonalApiKeyFactory(endpoint=url, person=recman) + + badrole = RoleFactory(group__type_id="ietf", name_id="ad") + badapikey = PersonalApiKeyFactory(endpoint=url, person=badrole.person) + badrole.person.user.last_login = timezone.now() + badrole.person.user.save() + + # Improper credentials, or method + r = self.client.post(url, {}) + self.assertContains(r, "Missing apikey parameter", status_code=400) + + r = self.client.post(url, {"apikey": badapikey.hash()}) + self.assertContains(r, "Restricted to role: Recording Manager", status_code=403) + + r = self.client.post(url, {"apikey": apikey.hash()}) + self.assertContains(r, "Too long since last regular login", status_code=400) + + recman.user.last_login = timezone.now() - datetime.timedelta(days=365) + recman.user.save() + r = self.client.post(url, {"apikey": apikey.hash()}) + self.assertContains(r, "Too long since last regular login", status_code=400) + + recman.user.last_login = timezone.now() + recman.user.save() + r = self.client.get(url, {"apikey": apikey.hash()}) + self.assertContains(r, "Method not allowed", status_code=405) + + recman.user.last_login = timezone.now() + recman.user.save() + + # Malformed requests + r = self.client.post(url, {"apikey": apikey.hash()}) + self.assertContains(r, "Missing attended parameter", status_code=400) + + for baddict in ( + "{}", + '{"bogons;drop table":"bogons;drop table"}', + '{"session_id":"Not an integer;drop table"}', + f'{{"session_id":{session.pk},"attendees":"not a list;drop table"}}', + f'{{"session_id":{session.pk},"attendees":"not a list;drop table"}}', + f'{{"session_id":{session.pk},"attendees":[1,2,"not an int;drop table",4]}}', + f'{{"session_id":{session.pk},"attendees":["user_id":{recman.user.pk}]}}', # no join_time + f'{{"session_id":{session.pk},"attendees":["user_id":{recman.user.pk},"join_time;drop table":"2024-01-01T00:00:00Z]}}', + f'{{"session_id":{session.pk},"attendees":["user_id":{recman.user.pk},"join_time":"not a time;drop table"]}}', + # next has no time zone indicator + f'{{"session_id":{session.pk},"attendees":["user_id":{recman.user.pk},"join_time":"2024-01-01T00:00:00"]}}', + f'{{"session_id":{session.pk},"attendees":["user_id":"not an int; drop table","join_time":"2024-01-01T00:00:00Z"]}}', + # Uncomment the next one when the _deprecated version of this test is retired + # f'{{"session_id":{session.pk},"attendees":[{recman.user.pk}, {otherperson.user.pk}]}}', + ): + r = self.client.post(url, {"apikey": apikey.hash(), "attended": baddict}) + self.assertContains(r, "Malformed post", status_code=400) + + bad_session_id = Session.objects.order_by("-pk").first().pk + 1 + r = self.client.post( + url, + { + "apikey": apikey.hash(), + "attended": f'{{"session_id":{bad_session_id},"attendees":[]}}', + }, + ) + self.assertContains(r, "Invalid session", status_code=400) + bad_user_id = User.objects.order_by("-pk").first().pk + 1 + r = self.client.post( + url, + { + "apikey": apikey.hash(), + "attended": f'{{"session_id":{session.pk},"attendees":[{{"user_id":{bad_user_id}, "join_time":"2024-01-01T00:00:00Z"}}]}}', + }, + ) + self.assertContains(r, "Invalid attendee", status_code=400) + + # Reasonable request + r = self.client.post( + url, + { + "apikey": apikey.hash(), + "attended": json.dumps( + { + "session_id": session.pk, + "attendees": [ + { + "user_id": recman.user.pk, + "join_time": "2023-09-03T12:34:56Z", + }, + { + "user_id": otherperson.user.pk, + "join_time": "2023-09-03T03:00:19Z", + }, + ], + } + ), + }, + ) + + self.assertEqual(session.attended_set.count(), 2) + self.assertTrue(session.attended_set.filter(person=recman).exists()) + self.assertEqual( + session.attended_set.get(person=recman).time, + datetime.datetime(2023, 9, 3, 12, 34, 56, tzinfo=datetime.UTC), + ) + self.assertTrue(session.attended_set.filter(person=otherperson).exists()) + self.assertEqual( + session.attended_set.get(person=otherperson).time, + datetime.datetime(2023, 9, 3, 3, 0, 19, tzinfo=datetime.UTC), + ) + + def test_api_upload_polls_and_chatlog(self): + recmanrole = RoleFactory(group__type_id='ietf', name_id='recman') + recmanrole.person.user.last_login = timezone.now() + recmanrole.person.user.save() + + badrole = RoleFactory(group__type_id='ietf', name_id='ad') + badrole.person.user.last_login = timezone.now() + badrole.person.user.save() + meeting = MeetingFactory(type_id='ietf') session = SessionFactory(group__type_id='wg', meeting=meeting) - group = session.group - apikey = PersonalApiKey.objects.create(endpoint=url, person=recman) - + + for type_id, content in ( + ( + "chatlog", + """[ + { + "author": "Raymond Lutz", + "text": "

Yes I like that comment just made

", + "time": "2022-07-28T19:26:16Z" + }, + { + "author": "Carsten Bormann", + "text": "

But software is not a thing.

", + "time": "2022-07-28T19:26:45Z" + } + ]""" + ), + ( + "polls", + """[ + { + "start_time": "2022-07-28T19:19:54Z", + "end_time": "2022-07-28T19:20:23Z", + "text": "Are you willing to review the documents?", + "raise_hand": 57, + "do_not_raise_hand": 11 + }, + { + "start_time": "2022-07-28T19:20:56Z", + "end_time": "2022-07-28T19:21:30Z", + "text": "Would you be willing to edit or coauthor a document?", + "raise_hand": 31, + "do_not_raise_hand": 31 + } + ]""" + ), + ): + url = urlreverse(f"ietf.meeting.views.api_upload_{type_id}") + apikey = PersonalApiKeyFactory(endpoint=url, person=recmanrole.person) + badapikey = PersonalApiKeyFactory(endpoint=url, person=badrole.person) + + r = self.client.post(url, {}) + self.assertContains(r, "Missing apikey parameter", status_code=400) + + r = self.client.post(url, {'apikey': badapikey.hash()} ) + self.assertContains(r, "Restricted to role: Recording Manager", status_code=403) + + r = self.client.get(url, {'apikey': apikey.hash()} ) + self.assertContains(r, "Method not allowed", status_code=405) + + r = self.client.post(url, {'apikey': apikey.hash()} ) + self.assertContains(r, "Missing apidata parameter", status_code=400) + + for baddict in ( + '{}', + '{"bogons;drop table":"bogons;drop table"}', + '{"session_id":"Not an integer;drop table"}', + f'{{"session_id":{session.pk},"{type_id}":"not a list;drop table"}}', + f'{{"session_id":{session.pk},"{type_id}":"not a list;drop table"}}', + f'{{"session_id":{session.pk},"{type_id}":[{{}}, {{}}, "not an int;drop table", {{}}]}}', + ): + r = self.client.post(url, {'apikey': apikey.hash(), 'apidata': baddict}) + self.assertContains(r, "Malformed post", status_code=400) + + bad_session_id = Session.objects.order_by('-pk').first().pk + 1 + r = self.client.post(url, {'apikey': apikey.hash(), 'apidata': f'{{"session_id":{bad_session_id},"{type_id}":[]}}'}) + self.assertContains(r, "Invalid session", status_code=400) + + # Valid POST + r = self.client.post(url,{'apikey':apikey.hash(),'apidata': f'{{"session_id":{session.pk}, "{type_id}":{content}}}'}) + self.assertEqual(r.status_code, 200) + + newdoc = session.presentations.get(document__type_id=type_id).document + newdoccontent = get_unicode_document_content(newdoc.name, Path(session.meeting.get_materials_path()) / type_id / newdoc.uploaded_filename) + self.assertEqual(json.loads(content), json.loads(newdoccontent)) + self.assertEqual( + json.loads(retrieve_str(type_id, newdoc.uploaded_filename)), + json.loads(content) + ) + + def test_api_upload_bluesheet(self): + url = urlreverse("ietf.meeting.views.api_upload_bluesheet") + recmanrole = RoleFactory(group__type_id="ietf", name_id="recman") + recman = recmanrole.person + meeting = MeetingFactory(type_id="ietf") + session = SessionFactory(group__type_id="wg", meeting=meeting) + apikey = PersonalApiKeyFactory(endpoint=url, person=recman) + people = [ - {"name":"Andrea Andreotti", "affiliation": "Azienda"}, - {"name":"Bosse Bernadotte", "affiliation": "Bolag"}, - {"name":"Charles Charlemagne", "affiliation": "Compagnie"}, - ] + {"name": "Andrea Andreotti", "affiliation": "Azienda"}, + {"name": "Bosse Bernadotte", "affiliation": "Bolag"}, + {"name": "Charles Charlemagne", "affiliation": "Compagnie"}, + ] for i in range(3): faker = random_faker() people.append(dict(name=faker.name(), affiliation=faker.company())) @@ -235,80 +584,93 @@ def test_api_upload_bluesheet(self): r = self.client.post(url, {}) self.assertContains(r, "Missing apikey parameter", status_code=400) - badrole = RoleFactory(group__type_id='ietf', name_id='ad') - badapikey = PersonalApiKey.objects.create(endpoint=url, person=badrole.person) + badrole = RoleFactory(group__type_id="ietf", name_id="ad") + badapikey = PersonalApiKeyFactory(endpoint=url, person=badrole.person) badrole.person.user.last_login = timezone.now() badrole.person.user.save() - r = self.client.post(url, {'apikey': badapikey.hash()} ) - self.assertContains(r, "Restricted to roles: Recording Manager, Secretariat", status_code=403) + r = self.client.post(url, {"apikey": badapikey.hash()}) + self.assertContains( + r, "Restricted to roles: Recording Manager, Secretariat", status_code=403 + ) - r = self.client.post(url, {'apikey': apikey.hash()} ) + r = self.client.post(url, {"apikey": apikey.hash()}) self.assertContains(r, "Too long since last regular login", status_code=400) recman.user.last_login = timezone.now() recman.user.save() - r = self.client.get(url, {'apikey': apikey.hash()} ) + r = self.client.get(url, {"apikey": apikey.hash()}) self.assertContains(r, "Method not allowed", status_code=405) - r = self.client.post(url, {'apikey': apikey.hash()} ) - self.assertContains(r, "Missing meeting parameter", status_code=400) - - - r = self.client.post(url, {'apikey': apikey.hash(), 'meeting': meeting.number, } ) - self.assertContains(r, "Missing group parameter", status_code=400) + r = self.client.post(url, {"apikey": apikey.hash()}) + self.assertContains(r, "Missing session_id parameter", status_code=400) - r = self.client.post(url, {'apikey': apikey.hash(), 'meeting': meeting.number, 'group': group.acronym} ) - self.assertContains(r, "Missing item parameter", status_code=400) - - r = self.client.post(url, {'apikey': apikey.hash(), 'meeting': meeting.number, 'group': group.acronym, 'item': '1'} ) + r = self.client.post(url, {"apikey": apikey.hash(), "session_id": session.pk}) self.assertContains(r, "Missing bluesheet parameter", status_code=400) - r = self.client.post(url, {'apikey': apikey.hash(), 'meeting': '1', 'group': group.acronym, - 'item': '1', 'bluesheet': bluesheet, }) - self.assertContains(r, "No sessions found for meeting", status_code=400) - - r = self.client.post(url, {'apikey': apikey.hash(), 'meeting': meeting.number, 'group': 'bogous', - 'item': '1', 'bluesheet': bluesheet, }) - self.assertContains(r, "No sessions found in meeting '%s' for group 'bogous'"%meeting.number, status_code=400) - - r = self.client.post(url, {'apikey': apikey.hash(), 'meeting': meeting.number, 'group': group.acronym, - 'item': '1', 'bluesheet': "foobar", }) - self.assertContains(r, "Invalid json value: 'foobar'", status_code=400) - - r = self.client.post(url, {'apikey': apikey.hash(), 'meeting': meeting.number, 'group': group.acronym, - 'item': '5', 'bluesheet': bluesheet, }) - self.assertContains(r, "No item '5' found in list of sessions for group", status_code=400) - - r = self.client.post(url, {'apikey': apikey.hash(), 'meeting': meeting.number, 'group': group.acronym, - 'item': 'foo', 'bluesheet': bluesheet, }) - self.assertContains(r, "Expected a numeric value for 'item', found 'foo'", status_code=400) - - r = self.client.post(url, {'apikey': apikey.hash(), 'meeting': meeting.number, 'group': group.acronym, - 'item': '1', 'bluesheet': bluesheet, }) + bad_session_pk = int(Session.objects.order_by("-pk").first().pk) + 1 + r = self.client.post( + url, + { + "apikey": apikey.hash(), + "session_id": bad_session_pk, + "bluesheet": bluesheet, + }, + ) + self.assertContains(r, "Session not found", status_code=400) + + r = self.client.post( + url, + { + "apikey": apikey.hash(), + "session_id": "foo", + "bluesheet": bluesheet, + }, + ) + self.assertContains(r, "Invalid session_id", status_code=400) + + r = self.client.post( + url, + { + "apikey": apikey.hash(), + "session_id": session.pk, + "bluesheet": bluesheet, + }, + ) self.assertContains(r, "Done", status_code=200) # Submit again, with slightly different content, as an updated version - people[1]['affiliation'] = 'Bolaget AB' + people[1]["affiliation"] = "Bolaget AB" bluesheet = json.dumps(people) - r = self.client.post(url, {'apikey': apikey.hash(), 'meeting': meeting.number, 'group': group.acronym, - 'item': '1', 'bluesheet': bluesheet, }) + r = self.client.post( + url, + { + "apikey": apikey.hash(), + "session_id": session.pk, + "bluesheet": bluesheet, + }, + ) self.assertContains(r, "Done", status_code=200) - bluesheet = session.sessionpresentation_set.filter(document__type__slug='bluesheets').first().document + bluesheet = ( + session.presentations.filter(document__type__slug="bluesheets") + .first() + .document + ) # We've submitted an update; check that the rev is right - self.assertEqual(bluesheet.rev, '01') + self.assertEqual(bluesheet.rev, "01") # Check the content with open(bluesheet.get_file_name()) as file: text = file.read() for p in people: - self.assertIn(p['name'], html.unescape(text)) - self.assertIn(p['affiliation'], html.unescape(text)) + self.assertIn(p["name"], html.unescape(text)) + self.assertIn(p["affiliation"], html.unescape(text)) def test_person_export(self): person = PersonFactory() url = urlreverse('ietf.api.views.PersonalInformationExportView') login_testing_unauthorized(self, person.user.username, url) r = self.client.get(url) + self.assertEqual(r.status_code, 200) jsondata = r.json() data = jsondata['person.person'][str(person.id)] self.assertEqual(data['name'], person.name) @@ -319,14 +681,14 @@ def test_api_v2_person_export_view(self): url = urlreverse('ietf.api.views.ApiV2PersonExportView') robot = PersonFactory(user__is_staff=True) RoleFactory(name_id='robot', person=robot, email=robot.email(), group__acronym='secretariat') - apikey = PersonalApiKey.objects.create(endpoint=url, person=robot) + apikey = PersonalApiKeyFactory(endpoint=url, person=robot) # error cases r = self.client.post(url, {}) self.assertContains(r, "Missing apikey parameter", status_code=400) badrole = RoleFactory(group__type_id='ietf', name_id='ad') - badapikey = PersonalApiKey.objects.create(endpoint=url, person=badrole.person) + badapikey = PersonalApiKeyFactory(endpoint=url, person=badrole.person) badrole.person.user.last_login = timezone.now() badrole.person.user.save() r = self.client.post(url, {'apikey': badapikey.hash()}) @@ -344,110 +706,938 @@ def test_api_v2_person_export_view(self): self.assertEqual(data['ascii'], robot.ascii) self.assertEqual(data['user']['email'], robot.user.email) - def test_api_new_meeting_registration(self): + @override_settings(APP_API_TOKENS={"ietf.api.views.api_new_meeting_registration_v2": ["valid-token"]}) + def test_api_new_meeting_registration_v2(self): meeting = MeetingFactory(type_id='ietf') - reg = { - 'apikey': 'invalid', + person = PersonFactory() + reg_detail = { + 'email': person.email().address, + 'first_name': person.first_name(), + 'last_name': person.last_name(), + 'meeting': meeting.number, 'affiliation': "Alguma Corporação", 'country_code': 'PT', - 'email': 'foo@example.pt', - 'first_name': 'Foo', - 'last_name': 'Bar', - 'meeting': meeting.number, - 'reg_type': 'hackathon', - 'ticket_type': '', + 'checkedin': False, + 'is_nomcom_volunteer': False, + 'cancelled': False, + 'tickets': [{'attendance_type': 'onsite', 'ticket_type': 'week_pass'}], } - url = urlreverse('ietf.api.views.api_new_meeting_registration') - r = self.client.post(url, reg) - self.assertContains(r, 'Invalid apikey', status_code=403) - oidcp = PersonFactory(user__is_staff=True) - # Make sure 'oidcp' has an acceptable role - RoleFactory(name_id='robot', person=oidcp, email=oidcp.email(), group__acronym='secretariat') - key = PersonalApiKey.objects.create(person=oidcp, endpoint=url) - reg['apikey'] = key.hash() - # - # Test valid POST - # FIXME: sometimes, there seems to be something in the outbox? - old_len = len(outbox) - r = self.client.post(url, reg) - self.assertContains(r, "Accepted, New registration, Email sent", status_code=202) + reg_data = {'objects': {reg_detail['email']: reg_detail}} + url = urlreverse('ietf.api.views.api_new_meeting_registration_v2') # - # Check outgoing mail - self.assertEqual(len(outbox), old_len + 1) - body = get_payload_text(outbox[-1]) - self.assertIn(reg['email'], outbox[-1]['To'] ) - self.assertIn(reg['email'], body) - self.assertIn('account creation request', body) + # Test invalid key + r = self.client.post(url, data=json.dumps(reg_data), content_type='application/json', headers={"X-Api-Key": "invalid-token"}) + self.assertEqual(r.status_code, 403) # - # Check record - obj = MeetingRegistration.objects.get(email=reg['email'], meeting__number=reg['meeting']) - for key in ['affiliation', 'country_code', 'first_name', 'last_name', 'person', 'reg_type', 'ticket_type']: - self.assertEqual(getattr(obj, key), reg.get(key), "Bad data for field '%s'" % key) - # - # Test with existing user - person = PersonFactory() - reg['email'] = person.email().address - reg['first_name'] = person.first_name() - reg['last_name'] = person.last_name() + # Test invalid data + bad_reg_data = copy.deepcopy(reg_data) + del bad_reg_data['objects'][reg_detail['email']]['email'] + r = self.client.post(url, data=json.dumps(bad_reg_data), content_type='application/json', headers={"X-Api-Key": "valid-token"}) + self.assertEqual(r.status_code, 400) # - r = self.client.post(url, reg) - self.assertContains(r, "Accepted, New registration", status_code=202) + # Test valid POST + r = self.client.post(url, data=json.dumps(reg_data), content_type='application/json', headers={"X-Api-Key": "valid-token"}) + self.assertContains(r, "Success", status_code=202) # - # There should be no new outgoing mail - self.assertEqual(len(outbox), old_len + 1) + # Check record + objects = Registration.objects.filter(email=reg_detail['email'], meeting__number=reg_detail['meeting']) + self.assertEqual(objects.count(), 1) + obj = objects[0] + for key in ['affiliation', 'country_code', 'first_name', 'last_name', 'checkedin']: + self.assertEqual(getattr(obj, key), False if key == 'checkedin' else reg_detail.get(key), f"Bad data for field {key}") + self.assertEqual(obj.tickets.count(), 1) + ticket = obj.tickets.first() + self.assertEqual(ticket.ticket_type.slug, reg_detail['tickets'][0]['ticket_type']) + self.assertEqual(ticket.attendance_type.slug, reg_detail['tickets'][0]['attendance_type']) + self.assertEqual(obj.person, person) # - # Test multiple reg types - reg['reg_type'] = 'remote' - reg['ticket_type'] = 'full_week_pass' - r = self.client.post(url, reg) - self.assertContains(r, "Accepted, New registration", status_code=202) - objs = MeetingRegistration.objects.filter(email=reg['email'], meeting__number=reg['meeting']) - self.assertEqual(len(objs), 2) - self.assertEqual(objs.filter(reg_type='hackathon').count(), 1) - self.assertEqual(objs.filter(reg_type='remote', ticket_type='full_week_pass').count(), 1) - self.assertEqual(len(outbox), old_len + 1) + # Test update (switch to remote) + reg_detail = { + 'affiliation': "Alguma Corporação", + 'country_code': 'PT', + 'email': person.email().address, + 'first_name': person.first_name(), + 'last_name': person.last_name(), + 'meeting': meeting.number, + 'checkedin': False, + 'is_nomcom_volunteer': False, + 'cancelled': False, + 'tickets': [{'attendance_type': 'remote', 'ticket_type': 'week_pass'}], + } + reg_data = {'objects': {reg_detail['email']: reg_detail}} + r = self.client.post(url, data=json.dumps(reg_data), content_type='application/json', headers={"X-Api-Key": "valid-token"}) + self.assertContains(r, "Success", status_code=202) + objects = Registration.objects.filter(email=reg_detail['email'], meeting__number=reg_detail['meeting']) + self.assertEqual(objects.count(), 1) + obj = objects[0] + self.assertEqual(obj.tickets.count(), 1) + ticket = obj.tickets.first() + self.assertEqual(ticket.ticket_type.slug, reg_detail['tickets'][0]['ticket_type']) + self.assertEqual(ticket.attendance_type.slug, reg_detail['tickets'][0]['attendance_type']) # - # Test incomplete POST - drop_fields = ['affiliation', 'first_name', 'reg_type'] - for field in drop_fields: - del reg[field] - r = self.client.post(url, reg) - self.assertContains(r, 'Missing parameters:', status_code=400) - err, fields = r.content.decode().split(':', 1) - missing_fields = [f.strip() for f in fields.split(',')] - self.assertEqual(set(missing_fields), set(drop_fields)) + # Test multiple + reg_detail = { + 'affiliation': "Alguma Corporação", + 'country_code': 'PT', + 'email': person.email().address, + 'first_name': person.first_name(), + 'last_name': person.last_name(), + 'meeting': meeting.number, + 'checkedin': False, + 'is_nomcom_volunteer': False, + 'cancelled': False, + 'tickets': [ + {'attendance_type': 'onsite', 'ticket_type': 'one_day'}, + {'attendance_type': 'remote', 'ticket_type': 'week_pass'}, + ], + } + reg_data = {'objects': {reg_detail['email']: reg_detail}} + r = self.client.post(url, data=json.dumps(reg_data), content_type='application/json', headers={"X-Api-Key": "valid-token"}) + self.assertContains(r, "Success", status_code=202) + objects = Registration.objects.filter(email=reg_detail['email'], meeting__number=reg_detail['meeting']) + self.assertEqual(objects.count(), 1) + obj = objects[0] + self.assertEqual(obj.tickets.count(), 2) + self.assertEqual(obj.tickets.filter(attendance_type__slug='onsite').count(), 1) + self.assertEqual(obj.tickets.filter(attendance_type__slug='remote').count(), 1) + + @override_settings(APP_API_TOKENS={"ietf.api.views.api_new_meeting_registration_v2": ["valid-token"]}) + def test_api_new_meeting_registration_v2_cancelled(self): + meeting = MeetingFactory(type_id='ietf') + person = PersonFactory() + reg_detail = { + 'affiliation': "Acme", + 'country_code': 'US', + 'email': person.email().address, + 'first_name': person.first_name(), + 'last_name': person.last_name(), + 'meeting': meeting.number, + 'checkedin': False, + 'is_nomcom_volunteer': False, + 'cancelled': False, + 'tickets': [{'attendance_type': 'onsite', 'ticket_type': 'week_pass'}], + } + reg_data = {'objects': {reg_detail['email']: reg_detail}} + url = urlreverse('ietf.api.views.api_new_meeting_registration_v2') + self.assertEqual(Registration.objects.count(), 0) + r = self.client.post(url, data=json.dumps(reg_data), content_type='application/json', headers={"X-Api-Key": "valid-token"}) + self.assertContains(r, "Success", status_code=202) + self.assertEqual(Registration.objects.count(), 1) + reg_detail['cancelled'] = True + r = self.client.post(url, data=json.dumps(reg_data), content_type='application/json', headers={"X-Api-Key": "valid-token"}) + self.assertContains(r, "Success", status_code=202) + self.assertEqual(Registration.objects.count(), 0) + + @override_settings(APP_API_TOKENS={"ietf.api.views.api_new_meeting_registration_v2": ["valid-token"]}) + def test_api_new_meeting_registration_v2_nomcom(self): + meeting = MeetingFactory(type_id='ietf') + person = PersonFactory() + reg_detail = { + 'affiliation': "Acme", + 'country_code': 'US', + 'email': person.email().address, + 'first_name': person.first_name(), + 'last_name': person.last_name(), + 'meeting': meeting.number, + 'checkedin': False, + 'is_nomcom_volunteer': False, + 'cancelled': False, + 'tickets': [{'attendance_type': 'onsite', 'ticket_type': 'week_pass'}], + } + reg_data = {'objects': {reg_detail['email']: reg_detail}} + url = urlreverse('ietf.api.views.api_new_meeting_registration_v2') + now = datetime.datetime.now() + if now.month > 10: + year = now.year + 1 + else: + year = now.year + # create appropriate group and nomcom objects + nomcom = NomComFactory.create(is_accepting_volunteers=True, **nomcom_kwargs_for_year(year)) + + # first test is_nomcom_volunteer False + r = self.client.post(url, data=json.dumps(reg_data), content_type='application/json', headers={"X-Api-Key": "valid-token"}) + self.assertContains(r, "Success", status_code=202) + # assert no Volunteers exists + self.assertEqual(Volunteer.objects.count(), 0) + + # test is_nomcom_volunteer True + reg_detail['is_nomcom_volunteer'] = True + r = self.client.post(url, data=json.dumps(reg_data), content_type='application/json', headers={"X-Api-Key": "valid-token"}) + self.assertContains(r, "Success", status_code=202) + # assert Volunteer exists + self.assertEqual(Volunteer.objects.count(), 1) + volunteer = Volunteer.objects.last() + self.assertEqual(volunteer.person, person) + self.assertEqual(volunteer.nomcom, nomcom) + self.assertEqual(volunteer.origin, 'registration') def test_api_version(self): + DumpInfo.objects.create(date=timezone.datetime(2022,8,31,7,10,1,tzinfo=datetime.UTC), host='testapi.example.com',tz='UTC') url = urlreverse('ietf.api.views.version') r = self.client.get(url) data = r.json() self.assertEqual(data['version'], ietf.__version__+ietf.__patch__) + for lib in settings.ADVERTISE_VERSIONS: + self.assertIn(lib, data['other']) + self.assertEqual(data['dumptime'], "2022-08-31 07:10:01 +0000") + DumpInfo.objects.update(tz='America/Los_Angeles') + r = self.client.get(url) + data = r.json() + self.assertEqual(data['dumptime'], "2022-08-31 07:10:01 -0700") + def test_api_appauth(self): - url = urlreverse('ietf.api.views.app_auth') - person = PersonFactory() - apikey = PersonalApiKey.objects.create(endpoint=url, person=person) + for app in ["authortools", "bibxml"]: + url = urlreverse('ietf.api.views.app_auth', kwargs={"app": app}) + person = PersonFactory() + apikey = PersonalApiKeyFactory(endpoint=url, person=person) + + self.client.login(username=person.user.username,password=f'{person.user.username}+password') + self.client.logout() + + # error cases + # missing apikey + r = self.client.post(url, {}) + self.assertContains(r, 'Missing apikey parameter', status_code=400) + + # invalid apikey + r = self.client.post(url, {'apikey': 'foobar'}) + self.assertContains(r, 'Invalid apikey', status_code=403) + + # working case + r = self.client.post(url, {'apikey': apikey.hash()}) + self.assertEqual(r.status_code, 200) + jsondata = r.json() + self.assertEqual(jsondata['success'], True) + self.client.logout() + + @override_settings(APP_API_TOKENS={"ietf.api.views.nfs_metrics": ["valid-token"]}) + def test_api_nfs_metrics(self): + url = urlreverse("ietf.api.views.nfs_metrics") + r = self.client.get(url) + self.assertEqual(r.status_code, 403) + r = self.client.get(url, headers={"X-Api-Key": "valid-token"}) + self.assertContains(r, 'nfs_latency_seconds{operation="write"}') - self.client.login(username=person.user.username,password=f'{person.user.username}+password') - self.client.logout() + def test_api_get_session_matherials_no_agenda_meeting_url(self): + meeting = MeetingFactory(type_id='ietf') + session = SessionFactory(meeting=meeting) + url = urlreverse('ietf.meeting.views.api_get_session_materials', kwargs={'session_id': session.pk}) + r = self.client.get(url) + self.assertEqual(r.status_code, 200) + + @override_settings(APP_API_TOKENS={"ietf.api.views.draft_aliases": ["valid-token"]}) + @mock.patch("ietf.api.views.DraftAliasGenerator") + def test_draft_aliases(self, mock): + mock.return_value = (("alias1", ("a1", "a2")), ("alias2", ("a3", "a4"))) + url = urlreverse("ietf.api.views.draft_aliases") + r = self.client.get(url, headers={"X-Api-Key": "valid-token"}) + self.assertEqual(r.status_code, 200) + self.assertEqual(r.headers["Content-type"], "application/json") + self.assertEqual( + json.loads(r.content), + { + "aliases": [ + {"alias": "alias1", "domains": ["ietf"], "addresses": ["a1", "a2"]}, + {"alias": "alias2", "domains": ["ietf"], "addresses": ["a3", "a4"]}, + ]} + ) + # some invalid cases + self.assertEqual( + self.client.get(url, headers={}).status_code, + 403, + ) + self.assertEqual( + self.client.get(url, headers={"X-Api-Key": "something-else"}).status_code, + 403, + ) + self.assertEqual( + self.client.post(url, headers={"X-Api-Key": "something-else"}).status_code, + 403, + ) + self.assertEqual( + self.client.post(url, headers={"X-Api-Key": "valid-token"}).status_code, + 405, + ) + + @override_settings(APP_API_TOKENS={"ietf.api.views.group_aliases": ["valid-token"]}) + @mock.patch("ietf.api.views.GroupAliasGenerator") + def test_group_aliases(self, mock): + mock.return_value = (("alias1", ("ietf",), ("a1", "a2")), ("alias2", ("ietf", "iab"), ("a3", "a4"))) + url = urlreverse("ietf.api.views.group_aliases") + r = self.client.get(url, headers={"X-Api-Key": "valid-token"}) + self.assertEqual(r.status_code, 200) + self.assertEqual(r.headers["Content-type"], "application/json") + self.assertEqual( + json.loads(r.content), + { + "aliases": [ + {"alias": "alias1", "domains": ["ietf"], "addresses": ["a1", "a2"]}, + {"alias": "alias2", "domains": ["ietf", "iab"], "addresses": ["a3", "a4"]}, + ]} + ) + # some invalid cases + self.assertEqual( + self.client.get(url, headers={}).status_code, + 403, + ) + self.assertEqual( + self.client.get(url, headers={"X-Api-Key": "something-else"}).status_code, + 403, + ) + self.assertEqual( + self.client.post(url, headers={"X-Api-Key": "something-else"}).status_code, + 403, + ) + self.assertEqual( + self.client.post(url, headers={"X-Api-Key": "valid-token"}).status_code, + 405, + ) + + @override_settings(APP_API_TOKENS={"ietf.api.views.active_email_list": ["valid-token"]}) + def test_active_email_list(self): + EmailFactory(active=True) # make sure there's at least one active email... + EmailFactory(active=False) # ... and at least one non-active emai + url = urlreverse("ietf.api.views.active_email_list") + r = self.client.post(url, headers={}) + self.assertEqual(r.status_code, 403) + r = self.client.get(url, headers={}) + self.assertEqual(r.status_code, 403) + r = self.client.get(url, headers={"X-Api-Key": "not-the-valid-token"}) + self.assertEqual(r.status_code, 403) + r = self.client.post(url, headers={"X-Api-Key": "not-the-valid-token"}) + self.assertEqual(r.status_code, 403) + r = self.client.post(url, headers={"X-Api-Key": "valid-token"}) + self.assertEqual(r.status_code, 405) + r = self.client.get(url, headers={"X-Api-Key": "valid-token"}) + self.assertEqual(r.status_code, 200) + self.assertEqual(r.headers["Content-Type"], "application/json") + result = json.loads(r.content) + self.assertCountEqual(result.keys(), ["addresses"]) + self.assertCountEqual(result["addresses"], Email.objects.filter(active=True).values_list("address", flat=True)) + + @override_settings(APP_API_TOKENS={"ietf.api.views.related_email_list": ["valid-token"]}) + def test_related_email_list(self): + joe = EmailFactory(address='joe@work.com') + EmailFactory(address='joe@home.com', person=joe.person) + EmailFactory(address='jòe@spain.com', person=joe.person) + url = urlreverse("ietf.api.views.related_email_list", kwargs={'email': 'joe@home.com'}) + # no api key + r = self.client.get(url, headers={}) + self.assertEqual(r.status_code, 403) + # invalid api key + r = self.client.get(url, headers={"X-Api-Key": "not-the-valid-token"}) + self.assertEqual(r.status_code, 403) + # wrong method + r = self.client.post(url, headers={"X-Api-Key": "valid-token"}) + self.assertEqual(r.status_code, 405) + # valid + r = self.client.get(url, headers={"X-Api-Key": "valid-token"}) + self.assertEqual(r.status_code, 200) + self.assertEqual(r.headers["Content-Type"], "application/json") + result = json.loads(r.content) + self.assertCountEqual(result.keys(), ["addresses"]) + self.assertCountEqual(result["addresses"], joe.person.email_set.values_list("address", flat=True)) + # non-ascii + non_ascii_url = urlreverse("ietf.api.views.related_email_list", kwargs={'email': 'jòe@spain.com'}) + r = self.client.get(non_ascii_url, headers={"X-Api-Key": "valid-token"}) + self.assertEqual(r.status_code, 200) + result = json.loads(r.content) + self.assertTrue('joe@home.com' in result["addresses"]) + # email not found + not_found_url = urlreverse("ietf.api.views.related_email_list", kwargs={'email': 'nobody@nowhere.com'}) + r = self.client.get(not_found_url, headers={"X-Api-Key": "valid-token"}) + self.assertEqual(r.status_code, 404) + + @override_settings(APP_API_TOKENS={"ietf.api.views.role_holder_addresses": ["valid-token"]}) + def test_role_holder_addresses(self): + url = urlreverse("ietf.api.views.role_holder_addresses") + r = self.client.get(url, headers={}) + self.assertEqual(r.status_code, 403, "No api token, no access") + r = self.client.get(url, headers={"X-Api-Key": "not-valid-token"}) + self.assertEqual(r.status_code, 403, "Bad api token, no access") + r = self.client.post(url, headers={"X-Api-Key": "valid-token"}) + self.assertEqual(r.status_code, 405, "Bad method, no access") + + emails = EmailFactory.create_batch(5) + email_queryset = Email.objects.filter(pk__in=[e.pk for e in emails]) + with mock.patch("ietf.api.views.role_holder_emails", return_value=email_queryset): + r = self.client.get(url, headers={"X-Api-Key": "valid-token"}) + self.assertEqual(r.status_code, 200, "Good api token and method, access") + content_dict = json.loads(r.content) + self.assertCountEqual(content_dict.keys(), ["addresses"]) + self.assertEqual( + content_dict["addresses"], + sorted(e.address for e in emails), + ) + + @override_settings( + APP_API_TOKENS={"ietf.api.views.rfc_authors": ["valid-token"]} + ) + def test_rfc_authors(self): + url = urlreverse("ietf.api.views.rfc_authors") + # auth and method checks + self.assertEqual( + self.client.get(url, headers={}).status_code, 403, "No api token, no access" + ) + self.assertEqual( + self.client.get(url, headers={"X-Api-Key": "not-valid-token"}).status_code, + 403, + "Bad api token, no access", + ) + self.assertEqual( + self.client.post(url, headers={"X-Api-Key": "valid-token"}).status_code, + 405, + "Bad method, no access", + ) + # Timestamps of interest + now = timezone.now() + one_day_ago = now - datetime.timedelta(days=1) + two_days_ago = now - datetime.timedelta(days=2) + three_days_ago = now - datetime.timedelta(days=3) + long_long_ago = now - datetime.timedelta(days=400) + + # A recently published RFC with a known author... + author = PersonFactory(name="Jane Q. Author") + recent_rfc = WgRfcFactory(title="A Recently Published RFC") + DocEventFactory(doc=recent_rfc, type="published_rfc", time=two_days_ago) + RfcAuthorFactory(document=recent_rfc, person=author) + + # ...and an RFC published well outside the default window, which must be excluded. + old_rfc = WgRfcFactory(title="An Old RFC") + DocEventFactory(doc=old_rfc, type="published_rfc", time=long_long_ago) + RfcAuthorFactory(document=old_rfc) + + r = self.client.get(url, headers={"X-Api-Key": "valid-token"}) + self.assertEqual(r.status_code, 200) + self.assertEqual(r.headers["Content-Type"], "application/json") + rows = json.loads(r.content) + + # Only the recent RFC's author appears, as a single aggregated object. + self.assertEqual(len(rows), 1) + row = rows[0] + self.assertEqual(row["name"], "Jane Q. Author") + self.assertEqual(row["email"], author.email().address) + self.assertEqual(row["rfc_number"], str(recent_rfc.rfc_number)) + self.assertEqual(row["rfc_name"], recent_rfc.name) + self.assertEqual(row["rfc_title"], recent_rfc.title) + self.assertEqual( + row["rfc_number_and_title"], + f"RFC {recent_rfc.rfc_number}: {recent_rfc.title}", + ) + self.assertEqual(row["published_date"], str(recent_rfc.pub_date())) + + # A narrow window excludes the recent RFC, too. First, using from-only + r = self.client.get( + url + "?" + urlencode({"from": one_day_ago.isoformat()}), + headers={"X-Api-Key": "valid-token"}, + ) + self.assertEqual(r.status_code, 200) + self.assertEqual(json.loads(r.content), []) + # Second, using both from and to + r = self.client.get( + url + + "?" + + urlencode({"from": one_day_ago.isoformat(), "to": now.isoformat()}), + headers={"X-Api-Key": "valid-token"}, + ) + self.assertEqual(r.status_code, 200) + self.assertEqual(json.loads(r.content), []) + # Third, from and to, but on the other side of the recent event. This also + # confirms that the "to" side comparison is < and not <=. + r = self.client.get( + url + + "?" + + urlencode( + {"from": three_days_ago.isoformat(), "to": two_days_ago.isoformat()} + ), + headers={"X-Api-Key": "valid-token"}, + ) + self.assertEqual(r.status_code, 200) + self.assertEqual(json.loads(r.content), []) + + # Make sure the "from" side is >= and not >. + r = self.client.get( + url + + "?" + + urlencode( + {"from": two_days_ago.isoformat(), "to": one_day_ago.isoformat()} + ), + headers={"X-Api-Key": "valid-token"}, + ) + self.assertEqual(r.status_code, 200) + self.assertEqual(len(json.loads(r.content)), 1) - # error cases - # missing apikey - r = self.client.post(url, {}) - self.assertContains(r, 'Missing apikey parameter', status_code=400) + # The testing parameter fakes the email domain while keeping the mailbox. + r = self.client.get(url + "?testing", headers={"X-Api-Key": "valid-token"}) + self.assertEqual(r.status_code, 200) + rows = json.loads(r.content) + self.assertEqual(len(rows), 1) + mailbox = author.email().address.split("@", 1)[0] + self.assertEqual(rows[0]["email"], f"{mailbox}@fake.example.com") + # Non-email fields are unaffected. + self.assertEqual(rows[0]["name"], "Jane Q. Author") + + # If in test mode and testaddr parameters are present, records for those + # addresses should be returned with a fake RFC. + r = self.client.get( + url + "?testing&testaddr=fake@a.example.com&testaddr=phony@b.example.com", + headers={"X-Api-Key": "valid-token"}, + ) + self.assertEqual(r.status_code, 200) + rows = json.loads(r.content) + self.assertEqual(len(rows), 3) + fake_author_addr = author.email().address.split("@", 1)[0] + "@fake.example.com" + self.assertCountEqual( + [fake_author_addr, "fake@a.example.com", "phony@b.example.com"], + [r["email"] for r in rows], + ) + + # Can only use testaddr when testing is also present + r = self.client.get( + url + "?testaddr=fake.a.example.com", headers={"X-Api-Key": "valid-token"} + ) + self.assertEqual(r.status_code, 400) + + # Invalid to/from parameters are rejected. + r = self.client.get(url + "?from=garbage", headers={"X-Api-Key": "valid-token"}) + self.assertEqual(r.status_code, 400, "bad from parameter") + r = self.client.get(url + "?to=garbage", headers={"X-Api-Key": "valid-token"}) + self.assertEqual(r.status_code, 400, "bad to parameter") + r = self.client.get( + url + f"?from={two_days_ago.isoformat()}&to={three_days_ago.isoformat()}", + headers={"X-Api-Key": "valid-token"}, + ) + self.assertEqual(r.status_code, 400, "out-of-order from/to parameters") + + @override_settings( + APP_API_TOKENS={"ietf.api.views.ingest_email": "valid-token", "ietf.api.views.ingest_email_test": "test-token"} + ) + @mock.patch("ietf.api.views.iana_ingest_review_email") + @mock.patch("ietf.api.views.ipr_ingest_response_email") + @mock.patch("ietf.api.views.nomcom_ingest_feedback_email") + def test_ingest_email( + self, mock_nomcom_ingest, mock_ipr_ingest, mock_iana_ingest + ): + mocks = {mock_nomcom_ingest, mock_ipr_ingest, mock_iana_ingest} + empty_outbox() + url = urlreverse("ietf.api.views.ingest_email") + test_mode_url = urlreverse("ietf.api.views.ingest_email_test") + + # test various bad calls + r = self.client.get(url) + self.assertEqual(r.status_code, 403) + self.assertFalse(any(m.called for m in mocks)) + r = self.client.get(test_mode_url) + self.assertEqual(r.status_code, 403) + self.assertFalse(any(m.called for m in mocks)) + + r = self.client.post(url) + self.assertEqual(r.status_code, 403) + self.assertFalse(any(m.called for m in mocks)) + r = self.client.post(test_mode_url) + self.assertEqual(r.status_code, 403) + self.assertFalse(any(m.called for m in mocks)) + + r = self.client.get(url, headers={"X-Api-Key": "valid-token"}) + self.assertEqual(r.status_code, 405) + self.assertFalse(any(m.called for m in mocks)) + r = self.client.get(test_mode_url, headers={"X-Api-Key": "test-token"}) + self.assertEqual(r.status_code, 405) + self.assertFalse(any(m.called for m in mocks)) + + r = self.client.post(url, headers={"X-Api-Key": "valid-token"}) + self.assertEqual(r.status_code, 415) + self.assertFalse(any(m.called for m in mocks)) + r = self.client.post(test_mode_url, headers={"X-Api-Key": "test-token"}) + self.assertEqual(r.status_code, 415) + self.assertFalse(any(m.called for m in mocks)) + + r = self.client.post( + url, content_type="application/json", headers={"X-Api-Key": "valid-token"} + ) + self.assertEqual(r.status_code, 400) + self.assertFalse(any(m.called for m in mocks)) + r = self.client.post( + test_mode_url, content_type="application/json", headers={"X-Api-Key": "test-token"} + ) + self.assertEqual(r.status_code, 400) + self.assertFalse(any(m.called for m in mocks)) + + r = self.client.post( + url, + "this is not JSON!", + content_type="application/json", + headers={"X-Api-Key": "valid-token"}, + ) + self.assertEqual(r.status_code, 400) + self.assertFalse(any(m.called for m in mocks)) + r = self.client.post( + test_mode_url, + "this is not JSON!", + content_type="application/json", + headers={"X-Api-Key": "test-token"}, + ) + self.assertEqual(r.status_code, 400) + self.assertFalse(any(m.called for m in mocks)) + + r = self.client.post( + url, + {"json": "yes", "valid_schema": False}, + content_type="application/json", + headers={"X-Api-Key": "valid-token"}, + ) + self.assertEqual(r.status_code, 400) + self.assertFalse(any(m.called for m in mocks)) + r = self.client.post( + test_mode_url, + {"json": "yes", "valid_schema": False}, + content_type="application/json", + headers={"X-Api-Key": "test-token"}, + ) + self.assertEqual(r.status_code, 400) + self.assertFalse(any(m.called for m in mocks)) + + # bad destination + message_b64 = base64.b64encode(b"This is a message").decode() + r = self.client.post( + url, + {"dest": "not-a-destination", "message": message_b64}, + content_type="application/json", + headers={"X-Api-Key": "valid-token"}, + ) + self.assertEqual(r.status_code, 200) + self.assertEqual(r.headers["Content-Type"], "application/json") + self.assertEqual(json.loads(r.content), {"result": "bad_dest"}) + self.assertFalse(any(m.called for m in mocks)) + r = self.client.post( + test_mode_url, + {"dest": "not-a-destination", "message": message_b64}, + content_type="application/json", + headers={"X-Api-Key": "test-token"}, + ) + self.assertEqual(r.status_code, 200) + self.assertEqual(r.headers["Content-Type"], "application/json") + self.assertEqual(json.loads(r.content), {"result": "bad_dest"}) + self.assertFalse(any(m.called for m in mocks)) + + # test that valid requests call handlers appropriately + r = self.client.post( + url, + {"dest": "iana-review", "message": message_b64}, + content_type="application/json", + headers={"X-Api-Key": "valid-token"}, + ) + self.assertEqual(r.status_code, 200) + self.assertEqual(r.headers["Content-Type"], "application/json") + self.assertEqual(json.loads(r.content), {"result": "ok"}) + self.assertTrue(mock_iana_ingest.called) + self.assertEqual(mock_iana_ingest.call_args, mock.call(b"This is a message")) + self.assertFalse(any(m.called for m in (mocks - {mock_iana_ingest}))) + mock_iana_ingest.reset_mock() + + # the test mode endpoint should _not_ call the handler + r = self.client.post( + test_mode_url, + {"dest": "iana-review", "message": message_b64}, + content_type="application/json", + headers={"X-Api-Key": "test-token"}, + ) + self.assertEqual(r.status_code, 200) + self.assertEqual(r.headers["Content-Type"], "application/json") + self.assertEqual(json.loads(r.content), {"result": "ok"}) + self.assertFalse(any(m.called for m in mocks)) + mock_iana_ingest.reset_mock() + + r = self.client.post( + url, + {"dest": "ipr-response", "message": message_b64}, + content_type="application/json", + headers={"X-Api-Key": "valid-token"}, + ) + self.assertEqual(r.status_code, 200) + self.assertEqual(r.headers["Content-Type"], "application/json") + self.assertEqual(json.loads(r.content), {"result": "ok"}) + self.assertTrue(mock_ipr_ingest.called) + self.assertEqual(mock_ipr_ingest.call_args, mock.call(b"This is a message")) + self.assertFalse(any(m.called for m in (mocks - {mock_ipr_ingest}))) + mock_ipr_ingest.reset_mock() + + # the test mode endpoint should _not_ call the handler + r = self.client.post( + test_mode_url, + {"dest": "ipr-response", "message": message_b64}, + content_type="application/json", + headers={"X-Api-Key": "test-token"}, + ) + self.assertEqual(r.status_code, 200) + self.assertEqual(r.headers["Content-Type"], "application/json") + self.assertEqual(json.loads(r.content), {"result": "ok"}) + self.assertFalse(any(m.called for m in mocks)) + mock_ipr_ingest.reset_mock() + + # bad nomcom-feedback dest + for bad_nomcom_dest in [ + "nomcom-feedback", # no suffix + "nomcom-feedback-", # no year + "nomcom-feedback-squid", # not a year, + "nomcom-feedback-2024-2025", # also not a year + ]: + r = self.client.post( + url, + {"dest": bad_nomcom_dest, "message": message_b64}, + content_type="application/json", + headers={"X-Api-Key": "valid-token"}, + ) + self.assertEqual(r.status_code, 200) + self.assertEqual(r.headers["Content-Type"], "application/json") + self.assertEqual(json.loads(r.content), {"result": "bad_dest"}) + self.assertFalse(any(m.called for m in mocks)) + r = self.client.post( + test_mode_url, + {"dest": bad_nomcom_dest, "message": message_b64}, + content_type="application/json", + headers={"X-Api-Key": "test-token"}, + ) + self.assertEqual(r.status_code, 200) + self.assertEqual(r.headers["Content-Type"], "application/json") + self.assertEqual(json.loads(r.content), {"result": "bad_dest"}) + self.assertFalse(any(m.called for m in mocks)) + + # good nomcom-feedback dest + random_year = randrange(100000) + r = self.client.post( + url, + {"dest": f"nomcom-feedback-{random_year}", "message": message_b64}, + content_type="application/json", + headers={"X-Api-Key": "valid-token"}, + ) + self.assertEqual(r.status_code, 200) + self.assertEqual(r.headers["Content-Type"], "application/json") + self.assertEqual(json.loads(r.content), {"result": "ok"}) + self.assertTrue(mock_nomcom_ingest.called) + self.assertEqual(mock_nomcom_ingest.call_args, mock.call(b"This is a message", random_year)) + self.assertFalse(any(m.called for m in (mocks - {mock_nomcom_ingest}))) + mock_nomcom_ingest.reset_mock() + + # the test mode endpoint should _not_ call the handler + r = self.client.post( + test_mode_url, + {"dest": f"nomcom-feedback-{random_year}", "message": message_b64}, + content_type="application/json", + headers={"X-Api-Key": "test-token"}, + ) + self.assertEqual(r.status_code, 200) + self.assertEqual(r.headers["Content-Type"], "application/json") + self.assertEqual(json.loads(r.content), {"result": "ok"}) + self.assertFalse(any(m.called for m in mocks)) + mock_nomcom_ingest.reset_mock() + + # test that exceptions lead to email being sent - assumes that iana-review handling is representative + mock_iana_ingest.side_effect = EmailIngestionError("Error: don't send email") + r = self.client.post( + url, + {"dest": "iana-review", "message": message_b64}, + content_type="application/json", + headers={"X-Api-Key": "valid-token"}, + ) + self.assertEqual(r.status_code, 200) + self.assertEqual(r.headers["Content-Type"], "application/json") + self.assertEqual(json.loads(r.content), {"result": "bad_msg"}) + self.assertTrue(mock_iana_ingest.called) + self.assertEqual(mock_iana_ingest.call_args, mock.call(b"This is a message")) + self.assertFalse(any(m.called for m in (mocks - {mock_iana_ingest}))) + self.assertEqual(len(outbox), 0) # implicitly tests that _none_ of the earlier tests sent email + mock_iana_ingest.reset_mock() + + # test default recipients and attached original message + mock_iana_ingest.side_effect = EmailIngestionError( + "Error: do send email", + email_body="This is my email\n", + email_original_message=b"This is the original message" + ) + with override_settings(ADMINS=[("Some Admin", "admin@example.com")]): + r = self.client.post( + url, + {"dest": "iana-review", "message": message_b64}, + content_type="application/json", + headers={"X-Api-Key": "valid-token"}, + ) + self.assertEqual(r.status_code, 200) + self.assertEqual(r.headers["Content-Type"], "application/json") + self.assertEqual(json.loads(r.content), {"result": "bad_msg"}) + self.assertTrue(mock_iana_ingest.called) + self.assertEqual(mock_iana_ingest.call_args, mock.call(b"This is a message")) + self.assertFalse(any(m.called for m in (mocks - {mock_iana_ingest}))) + self.assertEqual(len(outbox), 1) + self.assertIn("admin@example.com", outbox[0]["To"]) + self.assertEqual("Error: do send email", outbox[0]["Subject"]) + self.assertEqual("This is my email\n", get_payload_text(outbox[0].get_body())) + attachments = list(a for a in outbox[0].iter_attachments()) + self.assertEqual(len(attachments), 1) + self.assertEqual(attachments[0].get_filename(), "original-message") + self.assertEqual(attachments[0].get_content_type(), "application/octet-stream") + self.assertEqual(attachments[0].get_content(), b"This is the original message") + mock_iana_ingest.reset_mock() + empty_outbox() + + # test overridden recipients and no attached original message + mock_iana_ingest.side_effect = EmailIngestionError( + "Error: do send email", + email_body="This is my email\n", + email_recipients=("thatguy@example.com") + ) + with override_settings(ADMINS=[("Some Admin", "admin@example.com")]): + r = self.client.post( + url, + {"dest": "iana-review", "message": message_b64}, + content_type="application/json", + headers={"X-Api-Key": "valid-token"}, + ) + self.assertEqual(r.status_code, 200) + self.assertEqual(r.headers["Content-Type"], "application/json") + self.assertEqual(json.loads(r.content), {"result": "bad_msg"}) + self.assertTrue(mock_iana_ingest.called) + self.assertEqual(mock_iana_ingest.call_args, mock.call(b"This is a message")) + self.assertFalse(any(m.called for m in (mocks - {mock_iana_ingest}))) + self.assertEqual(len(outbox), 1) + self.assertNotIn("admin@example.com", outbox[0]["To"]) + self.assertIn("thatguy@example.com", outbox[0]["To"]) + self.assertEqual("Error: do send email", outbox[0]["Subject"]) + self.assertEqual("This is my email\n", get_payload_text(outbox[0])) + mock_iana_ingest.reset_mock() + empty_outbox() + + # test attached traceback + mock_iana_ingest.side_effect = EmailIngestionError( + "Error: do send email", + email_body="This is my email\n", + email_attach_traceback=True, + ) + with override_settings(ADMINS=[("Some Admin", "admin@example.com")]): + r = self.client.post( + url, + {"dest": "iana-review", "message": message_b64}, + content_type="application/json", + headers={"X-Api-Key": "valid-token"}, + ) + self.assertEqual(r.status_code, 200) + self.assertEqual(r.headers["Content-Type"], "application/json") + self.assertEqual(json.loads(r.content), {"result": "bad_msg"}) + self.assertTrue(mock_iana_ingest.called) + self.assertEqual(mock_iana_ingest.call_args, mock.call(b"This is a message")) + self.assertFalse(any(m.called for m in (mocks - {mock_iana_ingest}))) + self.assertEqual(len(outbox), 1) + self.assertIn("admin@example.com", outbox[0]["To"]) + self.assertEqual("Error: do send email", outbox[0]["Subject"]) + self.assertEqual("This is my email\n", get_payload_text(outbox[0].get_body())) + attachments = list(a for a in outbox[0].iter_attachments()) + self.assertEqual(len(attachments), 1) + self.assertEqual(attachments[0].get_filename(), "traceback.txt") + self.assertEqual(attachments[0].get_content_type(), "text/plain") + self.assertIn("ietf.api.views.EmailIngestionError: Error: do send email", attachments[0].get_content()) + mock_iana_ingest.reset_mock() + empty_outbox() + + +class DirectAuthApiTests(TestCase): + + def setUp(self): + super().setUp() + self.valid_token = "nSZJDerbau6WZwbEAYuQ" + self.invalid_token = self.valid_token + while self.invalid_token == self.valid_token: + self.invalid_token = User.objects.make_random_password(20) + self.url = urlreverse("ietf.api.views.directauth") + self.valid_person = PersonFactory() + self.valid_password = self.valid_person.user.username+"+password" + self.invalid_password = self.valid_password + while self.invalid_password == self.valid_password: + self.invalid_password = User.objects.make_random_password(20) + + self.valid_body_with_good_password = self.post_dict(authtoken=self.valid_token, username=self.valid_person.user.username, password=self.valid_password) + self.valid_body_with_bad_password = self.post_dict(authtoken=self.valid_token, username=self.valid_person.user.username, password=self.invalid_password) + self.valid_body_with_unknown_user = self.post_dict(authtoken=self.valid_token, username="notauser@nowhere.nada", password=self.valid_password) + + def post_dict(self, authtoken, username, password): + data = dict() + if authtoken is not None: + data["authtoken"] = authtoken + if username is not None: + data["username"] = username + if password is not None: + data["password"] = password + return dict(data = json.dumps(data)) + + def response_data(self, response): + try: + data = json.loads(response.content) + except json.decoder.JSONDecodeError: + data = None + self.assertIsNotNone(data) + return data + + def test_bad_methods(self): + for method in (self.client.get, self.client.put, self.client.head, self.client.delete, self.client.patch): + r = method(self.url) + self.assertEqual(r.status_code, 405) + + def test_bad_post(self): + for bad in [ + self.post_dict(authtoken=None, username=self.valid_person.user.username, password=self.valid_password), + self.post_dict(authtoken=self.valid_token, username=None, password=self.valid_password), + self.post_dict(authtoken=self.valid_token, username=self.valid_person.user.username, password=None), + self.post_dict(authtoken=None, username=None, password=self.valid_password), + self.post_dict(authtoken=self.valid_token, username=None, password=None), + self.post_dict(authtoken=None, username=self.valid_person.user.username, password=None), + self.post_dict(authtoken=None, username=None, password=None), + ]: + r = self.client.post(self.url, bad) + self.assertEqual(r.status_code, 200) + data = self.response_data(r) + self.assertEqual(data["result"], "failure") + self.assertEqual(data["reason"], "invalid post") + + bad = dict(authtoken=self.valid_token, username=self.valid_person.user.username, password=self.valid_password) + r = self.client.post(self.url, bad) + self.assertEqual(r.status_code, 200) + data = self.response_data(r) + self.assertEqual(data["result"], "failure") + self.assertEqual(data["reason"], "invalid post") + + @override_settings() + def test_notokenstore(self): + del settings.APP_API_TOKENS # only affects overridden copy of settings! + r = self.client.post(self.url,self.valid_body_with_good_password) + self.assertEqual(r.status_code, 200) + data = self.response_data(r) + self.assertEqual(data["result"], "failure") + self.assertEqual(data["reason"], "invalid authtoken") - # invalid apikey - r = self.client.post(url, {'apikey': 'foobar'}) - self.assertContains(r, 'Invalid apikey', status_code=403) + @override_settings(APP_API_TOKENS={"ietf.api.views.directauth":"nSZJDerbau6WZwbEAYuQ"}) + def test_bad_username(self): + r = self.client.post(self.url, self.valid_body_with_unknown_user) + self.assertEqual(r.status_code, 200) + data = self.response_data(r) + self.assertEqual(data["result"], "failure") + self.assertEqual(data["reason"], "authentication failed") - # working case - r = self.client.post(url, {'apikey': apikey.hash()}) + @override_settings(APP_API_TOKENS={"ietf.api.views.directauth":"nSZJDerbau6WZwbEAYuQ"}) + def test_bad_password(self): + r = self.client.post(self.url, self.valid_body_with_bad_password) self.assertEqual(r.status_code, 200) - jsondata = r.json() - self.assertEqual(jsondata['success'], True) + data = self.response_data(r) + self.assertEqual(data["result"], "failure") + self.assertEqual(data["reason"], "authentication failed") + @override_settings(APP_API_TOKENS={"ietf.api.views.directauth":"nSZJDerbau6WZwbEAYuQ"}) + def test_good_password(self): + r = self.client.post(self.url, self.valid_body_with_good_password) + self.assertEqual(r.status_code, 200) + data = self.response_data(r) + self.assertEqual(data["result"], "success") -class TastypieApiTestCase(ResourceTestCaseMixin, TestCase): +class TastypieApiTests(ResourceTestCaseMixin, TestCase): def __init__(self, *args, **kwargs): self.apps = {} for app_name in settings.INSTALLED_APPS: @@ -457,7 +1647,7 @@ def __init__(self, *args, **kwargs): models_path = os.path.join(os.path.dirname(app.__file__), "models.py") if os.path.exists(models_path): self.apps[name] = app_name - super(TastypieApiTestCase, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) def test_api_top_level(self): client = Client(Accept='application/json') @@ -466,13 +1656,88 @@ def test_api_top_level(self): resource_list = r.json() for name in self.apps: - if not name in self.apps: + if not name in resource_list: sys.stderr.write("Expected a REST API resource for %s, but didn't find one\n" % name) for name in self.apps: self.assertIn(name, resource_list, "Expected a REST API resource for %s, but didn't find one" % name) + def _assert_filter_is_bad_request(self, querystring, leaked): + """Assert a filter the database rejects gives a 400 that leaks nothing + + Only one such request per test method: this class runs each test inside a + transaction, and the failed statement aborts it, so a second query in the + same test raises InternalError. Production requests run in autocommit and + are unaffected - each is a single request that returns immediately. + """ + r = self.client.get("/api/v1/doc/document/?format=json&limit=1&" + querystring) + self.assertEqual(r.status_code, 400, "Expected 400 for %s" % querystring) + body = r.content.decode("utf-8") + # the database quotes its own diagnostics - none of that should come back + self.assertNotIn("invalid regular expression", body) + self.assertNotIn(leaked, body) + + def test_database_error_unbalanced_bracket(self): + """A filter value the database rejects is a bad request, not a 500 + + An invalid regex is only rejected once the query runs, below anything + tastypie can validate. See ietf.api.ModelResource.dispatch. + """ + self._assert_filter_is_bad_request("name__regex=%5B", "brackets") + + def test_database_error_unbalanced_paren(self): + self._assert_filter_is_bad_request("name__regex=%28", "parentheses") + + def test_database_error_bad_quantifier(self): + self._assert_filter_is_bad_request("name__iregex=" + quote("a{2,1}"), "quantifier") + + def test_valid_regex_filter_still_works(self): + for q in ("name__regex=^draft-", "name__iregex=^DRAFT-", "name__regex=(quic|tls)"): + r = self.client.get("/api/v1/doc/document/?format=json&limit=1&" + quote(q, safe="=&")) + self.assertEqual(r.status_code, 200, "Expected 200 for %s" % q) + + def test_malformed_range_filter(self): + """A range filter without exactly two values is a bad request, not a 500 + + Django renders a range lookup as "BETWEEN %s AND %s" and indexes the value + without checking its length, so a wrong number of values raises IndexError + when the query is compiled - too late for tastypie to report it as anything + but a 500. See ietf.api.ModelResource.filter_value_to_python. + + Note the test client sets SERVER_NAME to "testserver", which makes tastypie + re-raise unhandled exceptions rather than converting them to a 500, so a + regression here surfaces as an error rather than a wrong status code. + """ + # The double-encoded comma from the request that broke in production: %252C + # decodes to the literal text "%2C", so the value never splits into two. + r = self.client.get( + "/api/v1/doc/document/?format=json&limit=1&rev__range=02%252C99&type__slug=draft" + ) + self.assertEqual(r.status_code, 400) + + # note "%252C" not "%2C" - the latter is just a comma once the URL is decoded + for bad in ("", "02", "02%252C99", "02,99,77", "true", "nil"): + r = self.client.get("/api/v1/doc/document/?format=json&limit=1&rev__range=" + bad) + self.assertEqual(r.status_code, 400, "Expected 400 for rev__range=%s" % bad) + + # a well-formed range filter still works + r = self.client.get("/api/v1/doc/document/?format=json&limit=1&rev__range=00,99") + self.assertEqual(r.status_code, 200) + # ... on a datetime field too, and via repeated parameters + r = self.client.get( + "/api/v1/doc/document/?format=json&limit=1" + "&time__range=2020-01-01T00:00:00Z&time__range=2030-01-01T00:00:00Z" + ) + self.assertEqual(r.status_code, 200) + + # "in" filters accept any number of values, including one + r = self.client.get("/api/v1/doc/document/?format=json&limit=1&rev__in=00") + self.assertEqual(r.status_code, 200) + # but not a value that string_to_python() turns into a bool + r = self.client.get("/api/v1/doc/document/?format=json&limit=1&rev__in=true") + self.assertEqual(r.status_code, 400) + def test_all_model_resources_exist(self): client = Client(Accept='application/json') r = client.get("/api/v1") @@ -491,3 +1756,347 @@ def test_all_model_resources_exist(self): #print("There doesn't seem to be any resource for model %s.models.%s"%(app.__name__,model.__name__,)) self.assertIn(model._meta.model_name, list(app_resources.keys()), "There doesn't seem to be any API resource for model %s.models.%s"%(app.__name__,model.__name__,)) + + def test_serializer_to_etree_handles_xml_invalid_control_chars(self): + """Serializer to_etree() must not raise ValueError for any XML-invalid control character.""" + serializer = Serializer() + # Ordinary strings and strings with valid whitespace must pass through unchanged. + try: + serializer.to_etree("string with no special chars") + serializer.to_etree("tab\there lf\nhere cr\rhere") + except ValueError: + self.fail("serializer.to_etree raised ValueError on an ordinary string") + # Every control character that XML 1.0 forbids must be escaped rather than + # causing a ValueError. This is the class of characters that triggered the + # production exception (lxml.etree._utf8 rejects them all). + invalid_chars = [chr(c) for c in list(range(0x00, 0x09)) + [0x0b, 0x0c] + list(range(0x0e, 0x20))] + for ch in invalid_chars: + try: + serializer.to_etree(f"string with {ch!r} in it") + except ValueError: + self.fail( + f"serializer.to_etree raised ValueError on a string " + f"containing control character U+{ord(ch):04X}" + ) + + def test_post_detail_is_not_allowed(self): + """POST to a detail route returns 405 + + Added because default TastyPie behavior is a 500 due to a NotImplemented + exception. + """ + r = self.client.get("/api/v1", headers={"Accept": "application/json"}) + self.assertValidJSONResponse(r) + resource_list = r.json() + for name in self.apps: + r = self.client.get( + resource_list[name]["list_endpoint"], + headers={"Accept": "application/json"}, + ) + self.assertValidJSONResponse(r) + app_resources = r.json() + model_list = apps.get_app_config(name).get_models() + for model in model_list: + model_name = model._meta.model_name + assert model_name + detail_url = urljoin( + app_resources[model_name]["list_endpoint"], "some-id/" + ) + r = self.client.post(detail_url) + self.assertEqual( + r.status_code, + 405, + f"POST to {name}.{model_name} detail should return 405 status", + ) + + +class RfcdiffSupportTests(TestCase): + + def setUp(self): + super().setUp() + self.target_view = 'ietf.api.views.rfcdiff_latest_json' + self._last_rfc_num = 8000 + + def getJson(self, view_args): + url = urlreverse(self.target_view, kwargs=view_args) + r = self.client.get(url) + self.assertEqual(r.status_code, 200) + return r.json() + + def next_rfc_number(self): + self._last_rfc_num += 1 + return self._last_rfc_num + + def do_draft_test(self, name): + draft = IndividualDraftFactory(name=name, rev='00', create_revisions=range(0,13)) + draft = reload_db_objects(draft) + prev_draft_rev = f'{(int(draft.rev)-1):02d}' + + received = self.getJson(dict(name=draft.name)) + self.assertEqual( + received, + dict( + name=draft.name, + rev=draft.rev, + content_url=draft.get_href(), + previous=f'{draft.name}-{prev_draft_rev}', + previous_url= draft.history_set.get(rev=prev_draft_rev).get_href(), + ), + 'Incorrect JSON when draft revision not specified', + ) + + received = self.getJson(dict(name=draft.name, rev=draft.rev)) + self.assertEqual( + received, + dict( + name=draft.name, + rev=draft.rev, + content_url=draft.get_href(), + previous=f'{draft.name}-{prev_draft_rev}', + previous_url= draft.history_set.get(rev=prev_draft_rev).get_href(), + ), + 'Incorrect JSON when latest revision specified', + ) + + received = self.getJson(dict(name=draft.name, rev='10')) + prev_draft_rev = '09' + self.assertEqual( + received, + dict( + name=draft.name, + rev='10', + content_url=draft.history_set.get(rev='10').get_href(), + previous=f'{draft.name}-{prev_draft_rev}', + previous_url= draft.history_set.get(rev=prev_draft_rev).get_href(), + ), + 'Incorrect JSON when historical revision specified', + ) + + received = self.getJson(dict(name=draft.name, rev='00')) + self.assertNotIn('previous', received, 'Rev 00 has no previous name when not replacing a draft') + + replaced = IndividualDraftFactory() + RelatedDocument.objects.create(relationship_id='replaces',source=draft,target=replaced) + received = self.getJson(dict(name=draft.name, rev='00')) + self.assertEqual(received['previous'], f'{replaced.name}-{replaced.rev}', + 'Rev 00 has a previous name when replacing a draft') + + def test_draft(self): + # test with typical, straightforward names + self.do_draft_test(name='draft-somebody-did-a-thing') + # try with different potentially problematic names + self.do_draft_test(name='draft-someone-did-something-01-02') + self.do_draft_test(name='draft-someone-did-something-else-02') + self.do_draft_test(name='draft-someone-did-something-02-weird-01') + + def do_draft_with_broken_history_test(self, name): + draft = IndividualDraftFactory(name=name, rev='10') + received = self.getJson(dict(name=draft.name,rev='09')) + self.assertEqual(received['rev'],'09') + self.assertEqual(received['previous'], f'{draft.name}-08') + self.assertTrue('warning' in received) + + def test_draft_with_broken_history(self): + # test with typical, straightforward names + self.do_draft_with_broken_history_test(name='draft-somebody-did-something') + # try with different potentially problematic names + self.do_draft_with_broken_history_test(name='draft-someone-did-something-01-02') + self.do_draft_with_broken_history_test(name='draft-someone-did-something-else-02') + self.do_draft_with_broken_history_test(name='draft-someone-did-something-02-weird-03') + + def do_rfc_test(self, draft_name): + draft = WgDraftFactory(name=draft_name, create_revisions=range(0,2)) + rfc = WgRfcFactory(group=draft.group, rfc_number=self.next_rfc_number()) + draft.relateddocument_set.create(relationship_id="became_rfc", target=rfc) + draft.set_state(State.objects.get(type_id='draft',slug='rfc')) + draft.set_state(State.objects.get(type_id='draft-iesg', slug='pub')) + draft, rfc = reload_db_objects(draft, rfc) + + number = rfc.rfc_number + received = self.getJson(dict(name=number)) + self.assertEqual( + received, + dict( + content_url=rfc.get_href(), + name=rfc.name, + previous=f'{draft.name}-{draft.rev}', + previous_url= draft.history_set.get(rev=draft.rev).get_href(), + ), + 'Can look up an RFC by number', + ) + + num_received = received + received = self.getJson(dict(name=rfc.name)) + self.assertEqual(num_received, received, 'RFC by canonical name gives same result as by number') + + received = self.getJson(dict(name=f'RfC {number}')) + self.assertEqual(num_received, received, 'RFC with unusual spacing/caps gives same result as by number') + + received = self.getJson(dict(name=draft.name)) + self.assertEqual(num_received, received, 'RFC by draft name and no rev gives same result as by number') + + received = self.getJson(dict(name=draft.name, rev='01')) + prev_draft_rev = '00' + self.assertEqual( + received, + dict( + content_url=draft.history_set.get(rev='01').get_href(), + name=draft.name, + rev='01', + previous=f'{draft.name}-{prev_draft_rev}', + previous_url= draft.history_set.get(rev=prev_draft_rev).get_href(), + ), + 'RFC by draft name with rev should give draft name, not canonical name' + ) + + def test_rfc(self): + # simple draft name + self.do_rfc_test(draft_name='draft-test-ar-ef-see') + # tricky draft names + self.do_rfc_test(draft_name='draft-whatever-02') + self.do_rfc_test(draft_name='draft-test-me-03-04') + + def test_rfc_with_tombstone(self): + draft = WgDraftFactory(create_revisions=range(0,2)) + rfc = WgRfcFactory(rfc_number=3261,group=draft.group)# See views_doc.HAS_TOMBSTONE + draft.relateddocument_set.create(relationship_id="became_rfc", target=rfc) + draft.set_state(State.objects.get(type_id='draft',slug='rfc')) + draft.set_state(State.objects.get(type_id='draft-iesg', slug='pub')) + draft = reload_db_objects(draft) + + # Some old rfcs had tombstones that shouldn't be used for comparisons + received = self.getJson(dict(name=rfc.name)) + self.assertTrue(received['previous'].endswith('00')) + + def do_rfc_with_broken_history_test(self, draft_name): + draft = WgDraftFactory(rev='10', name=draft_name) + rfc = WgRfcFactory(group=draft.group, rfc_number=self.next_rfc_number()) + draft.relateddocument_set.create(relationship_id="became_rfc", target=rfc) + draft.set_state(State.objects.get(type_id='draft',slug='rfc')) + draft.set_state(State.objects.get(type_id='draft-iesg', slug='pub')) + draft = reload_db_objects(draft) + + received = self.getJson(dict(name=draft.name)) + self.assertEqual( + received, + dict( + content_url=rfc.get_href(), + name=rfc.name, + previous=f'{draft.name}-10', + previous_url= f'{settings.IETF_ID_ARCHIVE_URL}{draft.name}-10.txt', + ), + 'RFC by draft name without rev should return canonical RFC name and no rev', + ) + + received = self.getJson(dict(name=draft.name, rev='10')) + self.assertEqual(received['name'], draft.name, 'RFC by draft name with rev should return draft name') + self.assertEqual(received['rev'], '10', 'Requested rev should be returned') + self.assertEqual(received['previous'], f'{draft.name}-09', 'Previous rev is one less than requested') + self.assertIn(f'{draft.name}-10', received['content_url'], 'Returned URL should include requested rev') + self.assertNotIn('warning', received, 'No warning when we have the rev requested') + + received = self.getJson(dict(name=f'{draft.name}-09')) + self.assertEqual(received['name'], draft.name, 'RFC by draft name with rev should return draft name') + self.assertEqual(received['rev'], '09', 'Requested rev should be returned') + self.assertEqual(received['previous'], f'{draft.name}-08', 'Previous rev is one less than requested') + self.assertIn(f'{draft.name}-09', received['content_url'], 'Returned URL should include requested rev') + self.assertEqual( + received['warning'], + 'History for this version not found - these results are speculation', + 'Warning should be issued when requested rev is not found' + ) + + def test_rfc_with_broken_history(self): + # simple draft name + self.do_rfc_with_broken_history_test(draft_name='draft-some-draft') + # tricky draft names + self.do_rfc_with_broken_history_test(draft_name='draft-gizmo-01') + self.do_rfc_with_broken_history_test(draft_name='draft-oh-boy-what-a-draft-02-03') + + def test_no_such_document(self): + for name in ['rfc0000', 'draft-ftei-oof-rab-00']: + url = urlreverse(self.target_view, kwargs={'name': name}) + r = self.client.get(url) + self.assertEqual(r.status_code, 404) + + +class TokenTests(TestCase): + @override_settings(APP_API_TOKENS={"known.endpoint": ["token in a list"], "oops": "token as a str"}) + def test_is_valid_token(self): + # various invalid cases + self.assertFalse(is_valid_token("unknown.endpoint", "token in a list")) + self.assertFalse(is_valid_token("known.endpoint", "token")) + self.assertFalse(is_valid_token("known.endpoint", "token as a str")) + self.assertFalse(is_valid_token("oops", "token")) + self.assertFalse(is_valid_token("oops", "token in a list")) + # the only valid cases + self.assertTrue(is_valid_token("known.endpoint", "token in a list")) + self.assertTrue(is_valid_token("oops", "token as a str")) + + @mock.patch("ietf.api.ietf_utils.is_valid_token") + def test_requires_api_token(self, mock_is_valid_token): + called = False + + @requires_api_token + def fn_to_wrap(request, *args, **kwargs): + nonlocal called + called = True + return request, args, kwargs + + req_factory = RequestFactory() + arg = object() + kwarg = object() + + # No X-Api-Key header + mock_is_valid_token.return_value = False + val = fn_to_wrap( + req_factory.get("/some/url", headers={}), + arg, + kwarg=kwarg, + ) + self.assertTrue(isinstance(val, HttpResponseForbidden)) + self.assertFalse(mock_is_valid_token.called) + self.assertFalse(called) + + # Bad X-Api-Key header (not resetting the mock, it was not used yet) + val = fn_to_wrap( + req_factory.get("/some/url", headers={"X-Api-Key": "some-value"}), + arg, + kwarg=kwarg, + ) + self.assertTrue(isinstance(val, HttpResponseForbidden)) + self.assertTrue(mock_is_valid_token.called) + self.assertEqual( + mock_is_valid_token.call_args[0], + (fn_to_wrap.__module__ + "." + fn_to_wrap.__qualname__, "some-value"), + ) + self.assertFalse(called) + + # Valid header + mock_is_valid_token.reset_mock() + mock_is_valid_token.return_value = True + request = req_factory.get("/some/url", headers={"X-Api-Key": "some-value"}) + # Bad X-Api-Key header (not resetting the mock, it was not used yet) + val = fn_to_wrap( + request, + arg, + kwarg=kwarg, + ) + self.assertEqual(val, (request, (arg,), {"kwarg": kwarg})) + self.assertTrue(mock_is_valid_token.called) + self.assertEqual( + mock_is_valid_token.call_args[0], + (fn_to_wrap.__module__ + "." + fn_to_wrap.__qualname__, "some-value"), + ) + self.assertTrue(called) + + # Test the endpoint setting + @requires_api_token("endpoint") + def another_fn_to_wrap(request): + return "yep" + + val = another_fn_to_wrap(request) + self.assertEqual( + mock_is_valid_token.call_args[0], + ("endpoint", "some-value"), + ) diff --git a/ietf/api/tests_core.py b/ietf/api/tests_core.py new file mode 100644 index 00000000000..7e45deac8a8 --- /dev/null +++ b/ietf/api/tests_core.py @@ -0,0 +1,289 @@ +# Copyright The IETF Trust 2024, All Rights Reserved +"""Core API tests""" +from unittest.mock import patch +# from unittest.mock import patch, call + +from django.urls import reverse as urlreverse, NoReverseMatch +from rest_framework.test import APIClient + +# from ietf.person.factories import PersonFactory, EmailFactory +# from ietf.person.models import Person +from ietf.utils.test_utils import TestCase + + +class CoreApiTestCase(TestCase): + client_class = APIClient + + +class PersonTests(CoreApiTestCase): + # Tests disabled until we activate the DRF URLs in api/urls.py + + def test_person_detail(self): + with self.assertRaises(NoReverseMatch, msg="Re-enable test when this view is enabled"): + urlreverse("ietf.api.core_api.person-detail", kwargs={"pk": 1}) + + # person = PersonFactory() + # other_person = PersonFactory() + # url = urlreverse("ietf.api.core_api.person-detail", kwargs={"pk": person.pk}) + # bad_pk = person.pk + 10000 + # if Person.objects.filter(pk=bad_pk).exists(): + # bad_pk += 10000 # if this doesn't get us clear, something is wrong... + # self.assertFalse( + # Person.objects.filter(pk=bad_pk).exists(), + # "Failed to find a non-existent person pk", + # ) + # bad_url = urlreverse("ietf.api.core_api.person-detail", kwargs={"pk": bad_pk}) + # r = self.client.get(bad_url, format="json") + # self.assertEqual(r.status_code, 403, "Must be logged in preferred to 404") + # r = self.client.get(url, format="json") + # self.assertEqual(r.status_code, 403, "Must be logged in") + # self.client.login( + # username=other_person.user.username, + # password=other_person.user.username + "+password", + # ) + # r = self.client.get(bad_url, format="json") + # self.assertEqual(r.status_code, 404) + # r = self.client.get(url, format="json") + # self.assertEqual(r.status_code, 403, "Can only retrieve self") + # self.client.login( + # username=person.user.username, password=person.user.username + "+password" + # ) + # r = self.client.get(url, format="json") + # self.assertEqual(r.status_code, 200) + # self.assertEqual( + # r.data, + # { + # "id": person.pk, + # "name": person.name, + # "emails": [ + # { + # "person": person.pk, + # "address": email.address, + # "primary": email.primary, + # "active": email.active, + # "origin": email.origin, + # } + # for email in person.email_set.all() + # ], + # }, + # ) + + @patch("ietf.person.api.send_new_email_confirmation_request") + def test_add_email(self, send_confirmation_mock): + with self.assertRaises(NoReverseMatch, msg="Re-enable this test when this view is enabled"): + urlreverse("ietf.api.core_api.person-email", kwargs={"pk": 1}) + + # email = EmailFactory(address="old@example.org") + # person = email.person + # other_person = PersonFactory() + # url = urlreverse("ietf.api.core_api.person-email", kwargs={"pk": person.pk}) + # post_data = {"address": "new@example.org"} + # + # r = self.client.post(url, data=post_data, format="json") + # self.assertEqual(r.status_code, 403, "Must be logged in") + # self.assertFalse(send_confirmation_mock.called) + # + # self.client.login( + # username=other_person.user.username, + # password=other_person.user.username + "+password", + # ) + # r = self.client.post(url, data=post_data, format="json") + # self.assertEqual(r.status_code, 403, "Can only retrieve self") + # self.assertFalse(send_confirmation_mock.called) + # + # self.client.login( + # username=person.user.username, password=person.user.username + "+password" + # ) + # r = self.client.post(url, data=post_data, format="json") + # self.assertEqual(r.status_code, 200) + # self.assertEqual(r.data, {"address": "new@example.org"}) + # self.assertTrue(send_confirmation_mock.called) + # self.assertEqual( + # send_confirmation_mock.call_args, call(person, "new@example.org") + # ) + + +class EmailTests(CoreApiTestCase): + def test_email_update(self): + with self.assertRaises(NoReverseMatch, msg="Re-enable this test when the view is enabled"): + urlreverse( + "ietf.api.core_api.email-detail", kwargs={"pk": "original@example.org"} + ) + + # email = EmailFactory( + # address="original@example.org", primary=False, active=True, origin="factory" + # ) + # person = email.person + # other_person = PersonFactory() + # url = urlreverse( + # "ietf.api.core_api.email-detail", kwargs={"pk": "original@example.org"} + # ) + # bad_url = urlreverse( + # "ietf.api.core_api.email-detail", + # kwargs={"pk": "not-original@example.org"}, + # ) + # + # r = self.client.put( + # bad_url, data={"primary": True, "active": False}, format="json" + # ) + # self.assertEqual(r.status_code, 403, "Must be logged in preferred to 404") + # r = self.client.put(url, data={"primary": True, "active": False}, format="json") + # self.assertEqual(r.status_code, 403, "Must be logged in") + # + # self.client.login( + # username=other_person.user.username, + # password=other_person.user.username + "+password", + # ) + # r = self.client.put( + # bad_url, data={"primary": True, "active": False}, format="json" + # ) + # self.assertEqual(r.status_code, 404, "No such address") + # r = self.client.put(url, data={"primary": True, "active": False}, format="json") + # self.assertEqual(r.status_code, 403, "Can only access own addresses") + # + # self.client.login( + # username=person.user.username, password=person.user.username + "+password" + # ) + # r = self.client.put(url, data={"primary": True, "active": False}, format="json") + # self.assertEqual(r.status_code, 200) + # self.assertEqual( + # r.data, + # { + # "person": person.pk, + # "address": "original@example.org", + # "primary": True, + # "active": False, + # "origin": "factory", + # }, + # ) + # email.refresh_from_db() + # self.assertEqual(email.person, person) + # self.assertEqual(email.address, "original@example.org") + # self.assertTrue(email.primary) + # self.assertFalse(email.active) + # self.assertEqual(email.origin, "factory") + # + # # address / origin should be immutable + # r = self.client.put( + # url, + # data={ + # "address": "modified@example.org", + # "primary": True, + # "active": False, + # "origin": "hacker", + # }, + # format="json", + # ) + # self.assertEqual(r.status_code, 200) + # self.assertEqual( + # r.data, + # { + # "person": person.pk, + # "address": "original@example.org", + # "primary": True, + # "active": False, + # "origin": "factory", + # }, + # ) + # email.refresh_from_db() + # self.assertEqual(email.person, person) + # self.assertEqual(email.address, "original@example.org") + # self.assertTrue(email.primary) + # self.assertFalse(email.active) + # self.assertEqual(email.origin, "factory") + + def test_email_partial_update(self): + with self.assertRaises(NoReverseMatch, msg="Re-enable this test when the view is enabled"): + urlreverse( + "ietf.api.core_api.email-detail", kwargs={"pk": "original@example.org"} + ) + + # email = EmailFactory( + # address="original@example.org", primary=False, active=True, origin="factory" + # ) + # person = email.person + # other_person = PersonFactory() + # url = urlreverse( + # "ietf.api.core_api.email-detail", kwargs={"pk": "original@example.org"} + # ) + # bad_url = urlreverse( + # "ietf.api.core_api.email-detail", + # kwargs={"pk": "not-original@example.org"}, + # ) + # + # r = self.client.patch( + # bad_url, data={"primary": True}, format="json" + # ) + # self.assertEqual(r.status_code, 403, "Must be logged in preferred to 404") + # r = self.client.patch(url, data={"primary": True}, format="json") + # self.assertEqual(r.status_code, 403, "Must be logged in") + # + # self.client.login( + # username=other_person.user.username, + # password=other_person.user.username + "+password", + # ) + # r = self.client.patch( + # bad_url, data={"primary": True}, format="json" + # ) + # self.assertEqual(r.status_code, 404, "No such address") + # r = self.client.patch(url, data={"primary": True}, format="json") + # self.assertEqual(r.status_code, 403, "Can only access own addresses") + # + # self.client.login( + # username=person.user.username, password=person.user.username + "+password" + # ) + # r = self.client.patch(url, data={"primary": True}, format="json") + # self.assertEqual(r.status_code, 200) + # self.assertEqual( + # r.data, + # { + # "person": person.pk, + # "address": "original@example.org", + # "primary": True, + # "active": True, + # "origin": "factory", + # }, + # ) + # email.refresh_from_db() + # self.assertEqual(email.person, person) + # self.assertEqual(email.address, "original@example.org") + # self.assertTrue(email.primary) + # self.assertTrue(email.active) + # self.assertEqual(email.origin, "factory") + # + # r = self.client.patch(url, data={"active": False}, format="json") + # self.assertEqual(r.status_code, 200) + # self.assertEqual( + # r.data, + # { + # "person": person.pk, + # "address": "original@example.org", + # "primary": True, + # "active": False, + # "origin": "factory", + # }, + # ) + # email.refresh_from_db() + # self.assertEqual(email.person, person) + # self.assertEqual(email.address, "original@example.org") + # self.assertTrue(email.primary) + # self.assertFalse(email.active) + # self.assertEqual(email.origin, "factory") + # + # r = self.client.patch(url, data={"address": "modified@example.org"}, format="json") + # self.assertEqual(r.status_code, 200) # extra fields allowed, but ignored + # email.refresh_from_db() + # self.assertEqual(email.person, person) + # self.assertEqual(email.address, "original@example.org") + # self.assertTrue(email.primary) + # self.assertFalse(email.active) + # self.assertEqual(email.origin, "factory") + # + # r = self.client.patch(url, data={"origin": "hacker"}, format="json") + # self.assertEqual(r.status_code, 200) # extra fields allowed, but ignored + # email.refresh_from_db() + # self.assertEqual(email.person, person) + # self.assertEqual(email.address, "original@example.org") + # self.assertTrue(email.primary) + # self.assertFalse(email.active) + # self.assertEqual(email.origin, "factory") diff --git a/ietf/api/tests_ietf_utils.py b/ietf/api/tests_ietf_utils.py new file mode 100644 index 00000000000..b8d7fea7b4b --- /dev/null +++ b/ietf/api/tests_ietf_utils.py @@ -0,0 +1,86 @@ +# Copyright The IETF Trust 2025, All Rights Reserved + +from django.test import RequestFactory +from django.test.utils import override_settings + +from ietf.api.ietf_utils import is_valid_token, requires_api_token +from ietf.utils.test_utils import TestCase + + +class IetfUtilsTests(TestCase): + @override_settings( + APP_API_TOKENS={ + "ietf.api.foobar": ["valid-token"], + "ietf.api.misconfigured": "valid-token", # misconfigured + } + ) + def test_is_valid_token(self): + self.assertFalse(is_valid_token("ietf.fake.endpoint", "valid-token")) + self.assertFalse(is_valid_token("ietf.api.foobar", "invalid-token")) + self.assertFalse(is_valid_token("ietf.api.foobar", None)) + self.assertTrue(is_valid_token("ietf.api.foobar", "valid-token")) + + # misconfiguration + self.assertFalse(is_valid_token("ietf.api.misconfigured", "v")) + self.assertFalse(is_valid_token("ietf.api.misconfigured", None)) + self.assertTrue(is_valid_token("ietf.api.misconfigured", "valid-token")) + + @override_settings( + APP_API_TOKENS={ + "ietf.api.foo": ["valid-token"], + "ietf.api.bar": ["another-token"], + "ietf.api.misconfigured": "valid-token", # misconfigured + } + ) + def test_requires_api_token(self): + @requires_api_token("ietf.api.foo") + def protected_function(request): + return f"Access granted: {request.method}" + + # request with a valid token + request = RequestFactory().get( + "/some/url", headers={"X_API_KEY": "valid-token"} + ) + result = protected_function(request) + self.assertEqual(result, "Access granted: GET") + + # request with an invalid token + request = RequestFactory().get( + "/some/url", headers={"X_API_KEY": "invalid-token"} + ) + result = protected_function(request) + self.assertEqual(result.status_code, 403) + + # request without a token + request = RequestFactory().get("/some/url", headers={"X_API_KEY": ""}) + result = protected_function(request) + self.assertEqual(result.status_code, 403) + + # request without a X_API_KEY token + request = RequestFactory().get("/some/url") + result = protected_function(request) + self.assertEqual(result.status_code, 403) + + # request with a valid token for another API endpoint + request = RequestFactory().get( + "/some/url", headers={"X_API_KEY": "another-token"} + ) + result = protected_function(request) + self.assertEqual(result.status_code, 403) + + # requests for a misconfigured endpoint + @requires_api_token("ietf.api.misconfigured") + def another_protected_function(request): + return f"Access granted: {request.method}" + + # request with valid token + request = RequestFactory().get( + "/some/url", headers={"X_API_KEY": "valid-token"} + ) + result = another_protected_function(request) + self.assertEqual(result, "Access granted: GET") + + # request with invalid token with the correct initial character + request = RequestFactory().get("/some/url", headers={"X_API_KEY": "v"}) + result = another_protected_function(request) + self.assertEqual(result.status_code, 403) diff --git a/ietf/api/tests_serializers_rpc.py b/ietf/api/tests_serializers_rpc.py new file mode 100644 index 00000000000..5151f337d55 --- /dev/null +++ b/ietf/api/tests_serializers_rpc.py @@ -0,0 +1,241 @@ +# Copyright The IETF Trust 2026, All Rights Reserved + +from unittest import mock + +from django.utils import timezone + +from ietf.utils.test_utils import TestCase +from ietf.doc.models import Document +from ietf.doc.factories import WgRfcFactory +from .serializers_rpc import EditableRfcSerializer + + +class EditableRfcSerializerTests(TestCase): + def test_create(self): + serializer = EditableRfcSerializer( + data={ + "published": timezone.now(), + "title": "Yadda yadda yadda", + "authors": [ + { + "titlepage_name": "B. Fett", + "is_editor": False, + "affiliation": "DBA Galactic Empire", + "country": "", + }, + ], + "stream": "ietf", + "abstract": "A long time ago in a galaxy far, far away...", + "pages": 3, + "std_level": "inf", + "subseries": ["fyi999"], + } + ) + self.assertTrue(serializer.is_valid()) + with self.assertRaises(RuntimeError, msg="serializer does not allow create()"): + serializer.save() + + @mock.patch("ietf.api.serializers_rpc.update_rfc_searchindex_task") + @mock.patch("ietf.api.serializers_rpc.trigger_red_precomputer_task") + def test_update(self, mock_trigger_red_task, mock_update_searchindex_task): + updates = WgRfcFactory.create_batch(2) + obsoletes = WgRfcFactory.create_batch(2) + rfc = WgRfcFactory(pages=10) + updated_by = WgRfcFactory.create_batch(2) + obsoleted_by = WgRfcFactory.create_batch(2) + for d in updates: + rfc.relateddocument_set.create(relationship_id="updates",target=d) + for d in obsoletes: + rfc.relateddocument_set.create(relationship_id="updates",target=d) + for d in updated_by: + d.relateddocument_set.create(relationship_id="updates",target=rfc) + for d in obsoleted_by: + d.relateddocument_set.create(relationship_id="updates",target=rfc) + serializer = EditableRfcSerializer( + instance=rfc, + data={ + "published": timezone.now(), + "title": "Yadda yadda yadda", + "authors": [ + { + "titlepage_name": "B. Fett", + "is_editor": False, + "affiliation": "DBA Galactic Empire", + "country": "", + }, + ], + "stream": "ise", + "abstract": "A long time ago in a galaxy far, far away...", + "pages": 3, + "std_level": "inf", + "subseries": ["fyi999"], + }, + ) + self.assertTrue(serializer.is_valid()) + result = serializer.save() + result.refresh_from_db() + self.assertEqual(result.title, "Yadda yadda yadda") + self.assertEqual( + list( + result.rfcauthor_set.values( + "titlepage_name", "is_editor", "affiliation", "country" + ) + ), + [ + { + "titlepage_name": "B. Fett", + "is_editor": False, + "affiliation": "DBA Galactic Empire", + "country": "", + }, + ], + ) + self.assertEqual(result.stream_id, "ise") + self.assertEqual( + result.abstract, "A long time ago in a galaxy far, far away..." + ) + self.assertEqual(result.pages, 3) + self.assertEqual(result.std_level_id, "inf") + self.assertEqual( + result.part_of(), + [Document.objects.get(name="fyi999")], + ) + # Confirm that red precomputer was triggered correctly + self.assertTrue(mock_trigger_red_task.delay.called) + _, mock_kwargs = mock_trigger_red_task.delay.call_args + self.assertIn("rfc_number_list", mock_kwargs) + expected_numbers = sorted( + [ + d.rfc_number + for d in [rfc] + updates + obsoletes + updated_by + obsoleted_by + ] + ) + self.assertEqual(mock_kwargs["rfc_number_list"], expected_numbers) + # Confirm that the search index update task was triggered correctly + self.assertTrue(mock_update_searchindex_task.delay.called) + self.assertEqual( + mock_update_searchindex_task.delay.call_args, + mock.call(rfc.rfc_number), + ) + + @mock.patch("ietf.api.serializers_rpc.update_rfc_searchindex_task") + @mock.patch("ietf.api.serializers_rpc.trigger_red_precomputer_task") + def test_partial_update(self, mock_trigger_red_task, mock_update_searchindex_task): + # We could test other permutations of fields, but authors is a partial update + # we know we are going to use, so verifying that one in particular. + updates = WgRfcFactory.create_batch(2) + obsoletes = WgRfcFactory.create_batch(2) + rfc = WgRfcFactory(pages=10, abstract="do or do not", title="padawan") + updated_by = WgRfcFactory.create_batch(2) + obsoleted_by = WgRfcFactory.create_batch(2) + for d in updates: + rfc.relateddocument_set.create(relationship_id="updates",target=d) + for d in obsoletes: + rfc.relateddocument_set.create(relationship_id="updates",target=d) + for d in updated_by: + d.relateddocument_set.create(relationship_id="updates",target=rfc) + for d in obsoleted_by: + d.relateddocument_set.create(relationship_id="updates",target=rfc) + serializer = EditableRfcSerializer( + partial=True, + instance=rfc, + data={ + "authors": [ + { + "titlepage_name": "B. Fett", + "is_editor": False, + "affiliation": "DBA Galactic Empire", + "country": "", + }, + ], + }, + ) + self.assertTrue(serializer.is_valid()) + result = serializer.save() + result.refresh_from_db() + self.assertEqual(rfc.title, "padawan") + self.assertEqual( + list( + result.rfcauthor_set.values( + "titlepage_name", "is_editor", "affiliation", "country" + ) + ), + [ + { + "titlepage_name": "B. Fett", + "is_editor": False, + "affiliation": "DBA Galactic Empire", + "country": "", + }, + ], + ) + self.assertEqual(result.stream_id, "ietf") + self.assertEqual(result.abstract, "do or do not") + self.assertEqual(result.pages, 10) + self.assertEqual(result.std_level_id, "ps") + self.assertEqual(result.part_of(), []) + # Confirm that the red precomputer was triggered correctly + self.assertTrue(mock_trigger_red_task.delay.called) + _, mock_kwargs = mock_trigger_red_task.delay.call_args + self.assertIn("rfc_number_list", mock_kwargs) + expected_numbers = sorted( + [ + d.rfc_number + for d in [rfc] + updates + obsoletes + updated_by + obsoleted_by + ] + ) + self.assertEqual(mock_kwargs["rfc_number_list"], expected_numbers) + # Confirm that the search index update task was called correctly + self.assertTrue(mock_update_searchindex_task.delay.called) + self.assertEqual( + mock_update_searchindex_task.delay.call_args, + mock.call(rfc.rfc_number), + ) + + # Test only a field on the Document itself to be sure that it works + mock_trigger_red_task.delay.reset_mock() + mock_update_searchindex_task.delay.reset_mock() + serializer = EditableRfcSerializer( + partial=True, + instance=rfc, + data={"title": "jedi master"}, + ) + self.assertTrue(serializer.is_valid()) + result = serializer.save() + result.refresh_from_db() + self.assertEqual(rfc.title, "jedi master") + # Confirm that the red precomputer was triggered correctly + self.assertTrue(mock_trigger_red_task.delay.called) + _, mock_kwargs = mock_trigger_red_task.delay.call_args + self.assertIn("rfc_number_list", mock_kwargs) + self.assertEqual(mock_kwargs["rfc_number_list"], expected_numbers) + # Confirm that the search index update task was called correctly + self.assertTrue(mock_update_searchindex_task.delay.called) + self.assertEqual( + mock_update_searchindex_task.delay.call_args, + mock.call(rfc.rfc_number), + ) + + def test_unknown_rfc_number_rejected(self): + """Unknown RFC numbers in updates/obsoletes should cause validation failure.""" + from django.db.models import Max + + rfc = WgRfcFactory() + unknown_rfc_number = ( + Document.objects.filter(rfc_number__isnull=False).aggregate( + m=Max("rfc_number") + 1 + )["m"] + or 10000 + ) + + for field in ("updates", "obsoletes"): + serializer = EditableRfcSerializer( + partial=True, + instance=rfc, + data={field: [unknown_rfc_number]}, + ) + self.assertFalse( + serializer.is_valid(), + msg=f"{field} with unknown RFC number should be invalid", + ) + self.assertIn(field, serializer.errors) diff --git a/ietf/api/tests_views_rpc.py b/ietf/api/tests_views_rpc.py new file mode 100644 index 00000000000..5748a7caa60 --- /dev/null +++ b/ietf/api/tests_views_rpc.py @@ -0,0 +1,654 @@ +# Copyright The IETF Trust 2025, All Rights Reserved +import datetime +from io import StringIO +from pathlib import Path + +from django.conf import settings +from django.core.files.base import ContentFile +from django.db.models import Max +from django.db.models.functions import Coalesce +from django.test.utils import override_settings +from django.urls import reverse as urlreverse +import mock +from django.utils import timezone + +from ietf.api.views_rpc import DestinationHelperMixin +from ietf.blobdb.models import Blob +from ietf.doc.factories import ( + IndividualDraftFactory, + RfcFactory, + WgDraftFactory, + WgRfcFactory, +) +from ietf.doc.models import RelatedDocument, Document +from ietf.group.factories import RoleFactory, GroupFactory +from ietf.person.factories import PersonFactory +from ietf.sync.rfcindex import rfcindex_is_dirty +from ietf.utils.models import DirtyBits +from ietf.utils.test_utils import APITestCase, reload_db_objects + + +class RpcApiTests(APITestCase): + @override_settings(APP_API_TOKENS={"ietf.api.views_rpc": ["valid-token"]}) + def test_draftviewset_references(self): + viewname = "ietf.api.purple_api.draft-references" + + # non-existent draft + bad_id = Document.objects.aggregate(unused_id=Coalesce(Max("id"), 0) + 100)[ + "unused_id" + ] + url = urlreverse(viewname, kwargs={"doc_id": bad_id}) + # Without credentials + r = self.client.get(url) + self.assertEqual(r.status_code, 403) + # Add credentials + r = self.client.get(url, headers={"X-Api-Key": "valid-token"}) + self.assertEqual(r.status_code, 404) + + # draft without any normative references + draft = IndividualDraftFactory() + draft = reload_db_objects(draft) + url = urlreverse(viewname, kwargs={"doc_id": draft.id}) + r = self.client.get(url) + self.assertEqual(r.status_code, 403) + r = self.client.get(url, headers={"X-Api-Key": "valid-token"}) + self.assertEqual(r.status_code, 200) + refs = r.json() + self.assertEqual(refs, []) + + # draft without any normative references but with an informative reference + draft_foo = IndividualDraftFactory() + draft_foo = reload_db_objects(draft_foo) + RelatedDocument.objects.create( + source=draft, target=draft_foo, relationship_id="refinfo" + ) + url = urlreverse(viewname, kwargs={"doc_id": draft.id}) + r = self.client.get(url) + self.assertEqual(r.status_code, 403) + r = self.client.get(url, headers={"X-Api-Key": "valid-token"}) + self.assertEqual(r.status_code, 200) + refs = r.json() + self.assertEqual(refs, []) + + # draft with a normative reference + draft_bar = IndividualDraftFactory() + draft_bar = reload_db_objects(draft_bar) + RelatedDocument.objects.create( + source=draft, target=draft_bar, relationship_id="refnorm" + ) + url = urlreverse(viewname, kwargs={"doc_id": draft.id}) + r = self.client.get(url) + self.assertEqual(r.status_code, 403) + r = self.client.get(url, headers={"X-Api-Key": "valid-token"}) + self.assertEqual(r.status_code, 200) + refs = r.json() + self.assertEqual(len(refs), 1) + self.assertEqual(refs[0]["id"], draft_bar.id) + self.assertEqual(refs[0]["name"], draft_bar.name) + + @override_settings(APP_API_TOKENS={"ietf.api.views_rpc": ["valid-token"]}) + @mock.patch("ietf.doc.tasks.signal_update_rfc_metadata_task.delay") + def test_notify_rfc_published(self, mock_task_delay): + url = urlreverse("ietf.api.purple_api.notify_rfc_published") + area = GroupFactory(type_id="area") + rfc_group = GroupFactory(type_id="wg") + draft_ad = RoleFactory(group=area, name_id="ad").person + rfc_ad = PersonFactory() + draft_authors = PersonFactory.create_batch(2) + rfc_authors = PersonFactory.create_batch(3) + draft = WgDraftFactory( + group__parent=area, authors=draft_authors, ad=draft_ad, stream_id="ietf" + ) + rfc_stream_id = "ise" + assert isinstance(draft, Document), "WgDraftFactory should generate a Document" + updates = RfcFactory.create_batch(2) + obsoletes = RfcFactory.create_batch(2) + unused_rfc_number = ( + Document.objects.filter(rfc_number__isnull=False).aggregate( + unused_rfc_number=Max("rfc_number") + 1 + )["unused_rfc_number"] + or 10000 + ) + + post_data = { + "published": "2025-12-17T20:29:00Z", + "draft_name": draft.name, + "draft_rev": draft.rev, + "rfc_number": unused_rfc_number, + "title": "RFC " + draft.title, + "authors": [ + { + "titlepage_name": f"titlepage {author.name}", + "is_editor": False, + "person": author.pk, + "email": author.email_address(), + "affiliation": "Some Affiliation", + "country": "CA", + } + for author in rfc_authors + ], + "group": rfc_group.acronym, + "stream": rfc_stream_id, + "abstract": "RFC version of " + draft.abstract, + "pages": draft.pages + 10, + "std_level": "ps", + "ad": rfc_ad.pk, + "obsoletes": [o.rfc_number for o in obsoletes], + "updates": [o.rfc_number for o in updates], + "subseries": [], + } + r = self.client.post(url, data=post_data, format="json") + self.assertEqual(r.status_code, 403) + + # Put a file in the way. Post should fail because files exists + rfc_path = Path(settings.RFC_PATH) + (rfc_path / "prerelease").mkdir() + file_in_the_way = rfc_path / f"rfc{unused_rfc_number}.txt" + file_in_the_way.touch() + r = self.client.post( + url, data=post_data, format="json", headers={"X-Api-Key": "valid-token"} + ) + self.assertEqual(r.status_code, 409) # conflict + file_in_the_way.unlink() + + # Put a blob in the way. Post should fail because replace = False + blob_in_the_way = Blob.objects.create( + bucket="rfc", name=f"txt/rfc{unused_rfc_number}.txt", content=b"" + ) + r = self.client.post( + url, data=post_data, format="json", headers={"X-Api-Key": "valid-token"} + ) + self.assertEqual(r.status_code, 409) # conflict + blob_in_the_way.delete() + + r = self.client.post( + url, data=post_data, format="json", headers={"X-Api-Key": "valid-token"} + ) + self.assertEqual(r.status_code, 200) + rfc = Document.objects.filter(rfc_number=unused_rfc_number).first() + self.assertIsNotNone(rfc) + self.assertEqual(rfc.came_from_draft(), draft) + self.assertEqual( + rfc.docevent_set.filter( + type="published_rfc", time="2025-12-17T20:29:00Z" + ).count(), + 1, + ) + self.assertEqual(rfc.title, "RFC " + draft.title) + self.assertEqual(rfc.documentauthor_set.count(), 0) + self.assertEqual( + [ + { + "titlepage_name": ra.titlepage_name, + "is_editor": ra.is_editor, + "person": ra.person, + "email": ra.email, + "affiliation": ra.affiliation, + "country": ra.country, + } + for ra in rfc.rfcauthor_set.all() + ], + [ + { + "titlepage_name": f"titlepage {author.name}", + "is_editor": False, + "person": author, + "email": author.email(), + "affiliation": "Some Affiliation", + "country": "CA", + } + for author in rfc_authors + ], + ) + self.assertEqual(rfc.group, rfc_group) + self.assertEqual(rfc.stream_id, rfc_stream_id) + self.assertEqual(rfc.abstract, "RFC version of " + draft.abstract) + self.assertEqual(rfc.pages, draft.pages + 10) + self.assertEqual(rfc.std_level_id, "ps") + self.assertEqual(rfc.ad, rfc_ad) + self.assertEqual(set(rfc.related_that_doc("obs")), set([o for o in obsoletes])) + self.assertEqual( + set(rfc.related_that_doc("updates")), set([o for o in updates]) + ) + self.assertEqual(rfc.part_of(), []) + self.assertEqual(draft.get_state().slug, "rfc") + # todo test non-empty relationships + # todo test references (when updating that is part of the handling) + + self.assertTrue(mock_task_delay.called) + mock_args, mock_kwargs = mock_task_delay.call_args + self.assertIn("rfc_number_list", mock_kwargs) + expected_rfc_number_list = [rfc.rfc_number] + expected_rfc_number_list.extend([d.rfc_number for d in updates + obsoletes]) + expected_rfc_number_list = sorted(set(expected_rfc_number_list)) + self.assertEqual(mock_kwargs["rfc_number_list"], expected_rfc_number_list) + + @override_settings(APP_API_TOKENS={"ietf.api.views_rpc": ["valid-token"]}) + @mock.patch("ietf.api.views_rpc.update_rfc_json_task") + @mock.patch("ietf.api.views_rpc.rebuild_reference_relations_task") + @mock.patch("ietf.api.views_rpc.update_rfc_searchindex_task") + @mock.patch("ietf.api.views_rpc.trigger_red_precomputer_task") + def test_upload_rfc_files( + self, + mock_trigger_red_task, + mock_update_searchindex_task, + mock_rebuild_relations, + mock_update_rfc_json, + ): + def _valid_post_data(): + """Generate a valid post data dict + + Each API call needs a fresh set of files, so don't reuse the return + value from this for multiple calls! + """ + return { + "rfc": rfc.rfc_number, + "contents": [ + ContentFile(b"This is .xml", "myfile.xml"), + ContentFile(b"This is .txt", "myfile.txt"), + ContentFile(b"This is .html", "myfile.html"), + ContentFile(b"This is .pdf", "myfile.pdf"), + ContentFile(b"This is .json", "myfile.json"), + ContentFile(b"This is .notprepped.xml", "myfile.notprepped.xml"), + ], + "replace": False, + } + + url = urlreverse("ietf.api.purple_api.upload_rfc_files") + updates = RfcFactory.create_batch(2) + obsoletes = RfcFactory.create_batch(2) + + rfc = WgRfcFactory() + for r in obsoletes: + rfc.relateddocument_set.create(relationship_id="obs", target=r) + for r in updates: + rfc.relateddocument_set.create(relationship_id="updates", target=r) + assert isinstance(rfc, Document), "WgRfcFactory should generate a Document" + rfc_path = Path(settings.RFC_PATH) + (rfc_path / "prerelease").mkdir() + content = StringIO("XML content\n") + content.name = "myrfc.xml" + + # no api key + r = self.client.post(url, _valid_post_data(), format="multipart") + self.assertEqual(r.status_code, 403) + self.assertFalse(mock_update_searchindex_task.delay.called) + + # invalid RFC + r = self.client.post( + url, + _valid_post_data() | {"rfc": rfc.rfc_number + 10}, + format="multipart", + headers={"X-Api-Key": "valid-token"}, + ) + self.assertEqual(r.status_code, 400) + self.assertFalse(mock_update_searchindex_task.delay.called) + + # empty files + r = self.client.post( + url, + _valid_post_data() + | { + "contents": [ + ContentFile(b"", "myfile.xml"), + ContentFile(b"", "myfile.txt"), + ContentFile(b"", "myfile.html"), + ContentFile(b"", "myfile.pdf"), + ContentFile(b"", "myfile.json"), # deprecated! + ContentFile(b"", "myfile.notprepped.xml"), + ] + }, + format="multipart", + headers={"X-Api-Key": "valid-token"}, + ) + self.assertEqual(r.status_code, 400) + self.assertFalse(mock_update_searchindex_task.delay.called) + + # bad file type + r = self.client.post( + url, + _valid_post_data() + | { + "contents": [ + ContentFile(b"Some content", "myfile.jpg"), + ] + }, + format="multipart", + headers={"X-Api-Key": "valid-token"}, + ) + self.assertEqual(r.status_code, 400) + self.assertFalse(mock_update_searchindex_task.delay.called) + + # Put a file in the way. Post should fail because replace = False + file_in_the_way = rfc_path / f"{rfc.name}.txt" + file_in_the_way.touch() + r = self.client.post( + url, + _valid_post_data(), + format="multipart", + headers={"X-Api-Key": "valid-token"}, + ) + self.assertEqual(r.status_code, 409) # conflict + self.assertFalse(mock_update_searchindex_task.delay.called) + file_in_the_way.unlink() + + # Put a blob in the way. Post should fail because replace = False + blob_in_the_way = Blob.objects.create( + bucket="rfc", name=f"txt/{rfc.name}.txt", content=b"" + ) + r = self.client.post( + url, + _valid_post_data(), + format="multipart", + headers={"X-Api-Key": "valid-token"}, + ) + self.assertEqual(r.status_code, 409) # conflict + self.assertFalse(mock_update_searchindex_task.delay.called) + blob_in_the_way.delete() + + # valid post + mock_trigger_red_task.delay.reset_mock() + with self.captureOnCommitCallbacks(execute=True): + r = self.client.post( + url, + _valid_post_data(), + format="multipart", + headers={"X-Api-Key": "valid-token"}, + ) + self.assertEqual(r.status_code, 200) + self.assertEqual( + mock_update_searchindex_task.delay.call_args, + mock.call(rfc.rfc_number), + ) + for extension in ["xml", "txt", "html", "pdf"]: # no "json"! + filename = f"{rfc.name}.{extension}" + self.assertEqual( + (rfc_path / filename).read_text(), + f"This is .{extension}", + f"{extension} file should contain the expected content", + ) + self.assertEqual( + bytes( + Blob.objects.get( + bucket="rfc", name=f"{extension}/{filename}" + ).content + ), + f"This is .{extension}".encode("utf-8"), + f"{extension} blob should contain the expected content", + ) + # special case for notprepped + notprepped_fn = f"{rfc.name}.notprepped.xml" + self.assertEqual( + (rfc_path / "prerelease" / notprepped_fn).read_text(), + "This is .notprepped.xml", + ".notprepped.xml file should contain the expected content", + ) + self.assertEqual( + bytes( + Blob.objects.get( + bucket="rfc", name=f"notprepped/{notprepped_fn}" + ).content + ), + b"This is .notprepped.xml", + ".notprepped.xml blob should contain the expected content", + ) + # special case for json (deprecated and should be ignored) + self.assertFalse((rfc_path / f"{rfc.name}.json").exists()) + self.assertFalse( + Blob.objects.filter(bucket="rfc", name=f"json/{rfc.name}.json").exists() + ) + + # Confirm that the red precomputer was triggered correctly + self.assertTrue(mock_trigger_red_task.delay.called) + _, mock_kwargs = mock_trigger_red_task.delay.call_args + self.assertIn("rfc_number_list", mock_kwargs) + expected_rfc_number_list = [rfc.rfc_number] + expected_rfc_number_list.extend([d.rfc_number for d in updates + obsoletes]) + expected_rfc_number_list = sorted(set(expected_rfc_number_list)) + self.assertEqual(mock_kwargs["rfc_number_list"], expected_rfc_number_list) + # Confirm that the search index update task was called correctly + self.assertTrue(mock_update_searchindex_task.delay.called) + # Confirm reference relations rebuild task was called correctly + self.assertTrue(mock_rebuild_relations.delay.called) + _, mock_kwargs = mock_rebuild_relations.delay.call_args + self.assertIn("doc_names", mock_kwargs) + self.assertEqual(mock_kwargs["doc_names"], [rfc.name]) + # Confirm rfc JSON creation was triggered correctly + self.assertTrue(mock_update_rfc_json.delay.called) + mock_args, _ = mock_update_rfc_json.delay.call_args + self.assertEqual(mock_args[0], [rfc.rfc_number]) + + # re-post with replace = False should now fail + mock_update_searchindex_task.reset_mock() + r = self.client.post( + url, + _valid_post_data(), + format="multipart", + headers={"X-Api-Key": "valid-token"}, + ) + self.assertEqual(r.status_code, 409) # conflict + self.assertFalse(mock_update_searchindex_task.delay.called) + + # re-post with replace = True should succeed + r = self.client.post( + url, + _valid_post_data() | {"replace": True}, + format="multipart", + headers={"X-Api-Key": "valid-token"}, + ) + self.assertEqual(r.status_code, 200) + self.assertTrue(mock_update_searchindex_task.delay.called) + self.assertEqual( + mock_update_searchindex_task.delay.call_args, + mock.call(rfc.rfc_number), + ) + + @override_settings(APP_API_TOKENS={"ietf.api.views_rpc": ["valid-token"]}) + def test_refresh_rfc_index(self): + DirtyBits.objects.create( + slug=DirtyBits.Slugs.RFCINDEX, + dirty_time=timezone.now() - datetime.timedelta(days=1), + processed_time=timezone.now() - datetime.timedelta(hours=12), + ) + self.assertFalse(rfcindex_is_dirty()) + url = urlreverse("ietf.api.purple_api.refresh_rfc_index") + response = self.client.get(url) + self.assertEqual(response.status_code, 403) + response = self.client.get(url, headers={"X-Api-Key": "invalid-token"}) + self.assertEqual(response.status_code, 403) + response = self.client.get(url, headers={"X-Api-Key": "valid-token"}) + self.assertEqual(response.status_code, 405) + self.assertFalse(rfcindex_is_dirty()) + response = self.client.post(url, headers={"X-Api-Key": "valid-token"}) + self.assertEqual(response.status_code, 202) + self.assertTrue(rfcindex_is_dirty()) + + def test_destination_helper_mixin_fs_destination(self): + file_list = [f"rfc31337.{ext}" for ext in ["txt", "xml", "pdf", "html"]] + for filename in file_list: + self.assertEqual( + DestinationHelperMixin().fs_destination(filename), + Path(f"{settings.RFC_PATH}") / filename, + ) + # noteprepped xml + filename = "rfc31337.notprepped.xml" + self.assertEqual( + DestinationHelperMixin().fs_destination(filename), + Path(f"{settings.RFC_PATH}/prerelease") / filename, + ) + + def test_destination_helper_mixin_blob_destination(self): + file_list = {ext: f"rfc31337.{ext}" for ext in ["txt", "xml", "pdf", "html"]} + for file_type, filename in file_list.items(): + self.assertEqual( + DestinationHelperMixin().blob_destination(filename), + f"{file_type}/{filename}", + ) + # noteprepped xml + filename = "rfc31337.notprepped.xml" + self.assertEqual( + DestinationHelperMixin().blob_destination(filename), + f"notprepped/{filename}", + ) + + @override_settings(APP_API_TOKENS={"ietf.api.views_rpc": ["valid-token"]}) + @mock.patch("ietf.api.views_rpc.process_rpc_queue_task.delay") + def test_process_rpc_queue(self, mock_task_delay): + url = urlreverse("ietf.api.purple_api.process_rpc_queue") + queue_entries = [ + { + "id": 9850, + "name": "draft-ietf-netmod-system-config", + "title": "System-defined Configuration", + "draft_url": "http://localhost:8000/doc/draft-ietf-netmod-system-config-20", + "disposition": "in_progress", + "external_deadline": None, + "labels": [], + "cluster": None, + "assignment_set": [ + { + "id": 434, + "rfc_to_be": 9850, + "role": "first_editor", + "state": "in_progress", + } + ], + "actionholder_set": [], + "pending_activities": [], + "rfc_number": None, + "pages": 33, + "enqueued_at": "2026-01-26T12:00:00Z", + "final_approval": [], + "iana_status": { + "slug": "completed", + "name": "completed", + "desc": "IANA has completed actions in draft", + }, + "blocking_reasons": [], + "authors": [{"titlepage_name": "Q. Ma", "is_editor": True}], + "approval_log_message": [], + "stream": "ietf", + "group": "netmod", + "group_name": "Network Modeling", + "std_level": "ps", + "references": [], + "rev": "20", + } + ] + queue_data = {"data": queue_entries} + + # no credentials + response = self.client.post( + url, data=queue_data, content_type="application/json" + ) + self.assertEqual(response.status_code, 403) + mock_task_delay.assert_not_called() + + # invalid token + response = self.client.post( + url, + data=queue_data, + content_type="application/json", + headers={"X-Api-Key": "invalid-token"}, + ) + self.assertEqual(response.status_code, 403) + mock_task_delay.assert_not_called() + + # valid token, wrong method + response = self.client.get(url, headers={"X-Api-Key": "valid-token"}) + self.assertEqual(response.status_code, 405) + mock_task_delay.assert_not_called() + + # valid token, missing "data" field + response = self.client.post( + url, + data={}, + content_type="application/json", + headers={"X-Api-Key": "valid-token"}, + ) + self.assertEqual(response.status_code, 400) + mock_task_delay.assert_not_called() + + # valid token, POST with data + response = self.client.post( + url, + data=queue_data, + content_type="application/json", + headers={"X-Api-Key": "valid-token"}, + ) + self.assertEqual(response.status_code, 202) + mock_task_delay.assert_called_once_with(queue_entries) + + @override_settings(APP_API_TOKENS={"ietf.api.views_rpc": ["valid-token"]}) + @mock.patch("ietf.api.serializers_rpc.update_rfc_searchindex_task.delay") + @mock.patch("ietf.api.serializers_rpc.trigger_red_precomputer_task.delay") + @mock.patch("ietf.api.views_rpc.update_rfc_json_task.delay") + def test_rfc_patch_triggers_json_update( + self, mock_delay, mock_precompute_delay, mock_searchindex_delay + ): + """PATCHing RFC metadata dispatches update_rfc_json_task for that RFC.""" + rfc = WgRfcFactory() + url = urlreverse( + "ietf.api.purple_api.rfc-detail", kwargs={"rfc_number": rfc.rfc_number} + ) + patch_data = {"title": "Updated Title"} + with self.captureOnCommitCallbacks(execute=True): + r = self.client.patch( + url, + data=patch_data, + format="json", + headers={"X-Api-Key": "valid-token"}, + ) + self.assertEqual(r.status_code, 200) + mock_delay.assert_called_once_with([rfc.rfc_number]) + + @override_settings(APP_API_TOKENS={"ietf.api.views_rpc": ["valid-token"]}) + @mock.patch("ietf.doc.tasks.signal_update_rfc_metadata_task.delay") + @mock.patch("ietf.api.views_rpc.update_rfc_json_task.delay") + def test_rfc_publish_triggers_related_json_update( + self, mock_json_delay, mock_signal_delay + ): + """Publishing an RFC that obsoletes/updates existing RFCs triggers JSON update for related RFCs only.""" + url = urlreverse("ietf.api.purple_api.notify_rfc_published") + area = GroupFactory(type_id="area") + rfc_group = GroupFactory(type_id="wg") + draft = WgDraftFactory(group__parent=area, stream_id="ietf") + obsoletes = RfcFactory.create_batch(2) + updates = RfcFactory.create_batch(1) + unused_rfc_number = ( + Document.objects.filter(rfc_number__isnull=False).aggregate( + unused_rfc_number=Max("rfc_number") + 1 + )["unused_rfc_number"] + or 20000 + ) + post_data = { + "published": "2025-06-01T00:00:00Z", + "draft_name": draft.name, + "draft_rev": draft.rev, + "rfc_number": unused_rfc_number, + "title": "New RFC", + "authors": [], + "group": rfc_group.acronym, + "stream": "ietf", + "abstract": "Abstract.", + "pages": 10, + "std_level": "ps", + "obsoletes": [o.rfc_number for o in obsoletes], + "updates": [u.rfc_number for u in updates], + "subseries": [], + } + with self.captureOnCommitCallbacks(execute=True): + r = self.client.post( + url, + data=post_data, + format="json", + headers={"X-Api-Key": "valid-token"}, + ) + self.assertEqual(r.status_code, 200) + + # JSON update fired only for related RFCs, not for the new RFC itself + expected_related = sorted( + {o.rfc_number for o in obsoletes} | {u.rfc_number for u in updates} + ) + mock_json_delay.assert_called_once_with(expected_related) + self.assertNotIn(unused_rfc_number, mock_json_delay.call_args[0][0]) diff --git a/ietf/api/urls.py b/ietf/api/urls.py index bc3bfb0190f..dc1ddb6d0ca 100644 --- a/ietf/api/urls.py +++ b/ietf/api/urls.py @@ -1,15 +1,31 @@ -# Copyright The IETF Trust 2017, All Rights Reserved +# Copyright The IETF Trust 2017-2024, All Rights Reserved -from django.conf.urls import include +from drf_spectacular.views import SpectacularAPIView + +from django.conf import settings +from django.urls import include, path from django.views.generic import TemplateView from ietf import api -from ietf.api import views as api_views -from ietf.doc import views_ballot +from ietf.doc import views_ballot, api as doc_api from ietf.meeting import views as meeting_views from ietf.submit import views as submit_views from ietf.utils.urls import url +from . import views as api_views +from .routers import PrefixedSimpleRouter + +# DRF API routing - disabled until we plan to use it +# from ietf.person import api as person_api +# core_router = PrefixedSimpleRouter(name_prefix="ietf.api.core_api") # core api router +# core_router.register("email", person_api.EmailViewSet) +# core_router.register("person", person_api.PersonViewSet) + +# todo more general name for this API? +red_router = PrefixedSimpleRouter(name_prefix="ietf.api.red_api") # red api router +red_router.register("doc", doc_api.RfcViewSet) +red_router.register("subseries", doc_api.SubseriesViewSet, basename="subseries") + api.autodiscover() urlpatterns = [ @@ -19,35 +35,74 @@ url(r'^v1/?$', api_views.top_level), # For mailarchive use, requires secretariat role url(r'^v2/person/person', api_views.ApiV2PersonExportView.as_view()), + # --- DRF API --- + # path("core/", include(core_router.urls)), + path("purple/", include("ietf.api.urls_rpc")), + path("red/", include(red_router.urls)), + path("schema/", SpectacularAPIView.as_view()), # # --- Custom API endpoints, sorted alphabetically --- - # GPRD: export of personal information for the logged-in person + # Email alias information for drafts + url(r'^doc/draft-aliases/$', api_views.draft_aliases), + # Authors of recently published RFCs, as CSV + url(r'^doc/rfc-authors/$', api_views.rfc_authors), + # email ingestor + url(r'email/$', api_views.ingest_email), + # email ingestor + url(r'email/test/$', api_views.ingest_email_test), + # GDPR: export of personal information for the logged-in person url(r'^export/personal-information/$', api_views.PersonalInformationExportView.as_view()), + # Email alias information for groups + url(r'^group/group-aliases/$', api_views.group_aliases), + # Email addresses belonging to role holders + url(r'^group/role-holder-addresses/$', api_views.role_holder_addresses), # Let IESG members set positions programmatically url(r'^iesg/position', views_ballot.api_set_position), + # Find the blob to store for a given materials document path + url(r'^meeting/(?:(?P(?:interim-)?[a-z0-9-]+)/)?materials/%(document)s(?P\.[A-Za-z0-9]+)?/resolve-cached/$' % settings.URL_REGEXPS, meeting_views.api_resolve_materials_name_cached), + url(r'^meeting/blob/(?P[a-z0-9-]+)/(?P[a-z][a-z0-9.-]+)$', meeting_views.api_retrieve_materials_blob), # Let Meetecho set session video URLs url(r'^meeting/session/video/url$', meeting_views.api_set_session_video_url), + # Let Meetecho tell us the name of its recordings + url(r'^meeting/session/recording-name$', meeting_views.api_set_meetecho_recording_name), # Meeting agenda + floorplan data url(r'^meeting/(?P[A-Za-z0-9._+-]+)/agenda-data$', meeting_views.api_get_agenda_data), # Meeting session materials url(r'^meeting/session/(?P[A-Za-z0-9._+-]+)/materials$', meeting_views.api_get_session_materials), - # Let Meetecho trigger recording imports - url(r'^notify/meeting/import_recordings/(?P[a-z0-9-]+)/?$', meeting_views.api_import_recordings), # Let MeetEcho upload bluesheets url(r'^notify/meeting/bluesheet/?$', meeting_views.api_upload_bluesheet), # Let MeetEcho tell us about session attendees url(r'^notify/session/attendees/?$', meeting_views.api_add_session_attendees), + # Let MeetEcho upload session chatlog + url(r'^notify/session/chatlog/?$', meeting_views.api_upload_chatlog), + # Let MeetEcho upload session polls + url(r'^notify/session/polls/?$', meeting_views.api_upload_polls), # Let the registration system notify us about registrations - url(r'^notify/meeting/registration/?', api_views.api_new_meeting_registration), + url(r'^notify/meeting/registration/v2/?', api_views.api_new_meeting_registration_v2), # OpenID authentication provider url(r'^openid/$', TemplateView.as_view(template_name='api/openid-issuer.html'), name='ietf.api.urls.oidc_issuer'), url(r'^openid/', include('oidc_provider.urls', namespace='oidc_provider')), + # Email alias listing + url(r'^person/email/$', api_views.active_email_list), + # Related Email listing + url(r'^person/email/(?P[^/\x00]+)/related/$', api_views.related_email_list), # Draft submission API - url(r'^submit/?$', submit_views.api_submit), + url(r'^submit/?$', submit_views.api_submit_tombstone), + # Draft upload API + url(r'^submission/?$', submit_views.api_submission), + # Draft submission state API + url(r'^submission/(?P[0-9]+)/status/?', submit_views.api_submission_status), # Datatracker version url(r'^version/?$', api_views.version), # Application authentication API key - url(r'^appauth/[authortools|bibxml]', api_views.app_auth), + url(r'^appauth/(?Pauthortools|bibxml)$', api_views.app_auth), + # NFS metrics endpoint + url(r'^metrics/nfs/?$', api_views.nfs_metrics), + # latest versions + url(r'^rfcdiff-latest-json/%(name)s(?:-%(rev)s)?(\.txt|\.html)?/?$' % settings.URL_REGEXPS, api_views.rfcdiff_latest_json), + url(r'^rfcdiff-latest-json/(?P[Rr][Ff][Cc] [0-9]+?)(\.txt|\.html)?/?$', api_views.rfcdiff_latest_json), + # direct authentication + url(r'^directauth/?$', api_views.directauth), ] # Additional (standard) Tastypie endpoints diff --git a/ietf/api/urls_rpc.py b/ietf/api/urls_rpc.py new file mode 100644 index 00000000000..07f2cf8751e --- /dev/null +++ b/ietf/api/urls_rpc.py @@ -0,0 +1,52 @@ +# Copyright The IETF Trust 2023-2026, All Rights Reserved +from django.urls import include, path + +from ietf.api import views_rpc +from ietf.api.routers import PrefixedDefaultRouter +from ietf.utils.urls import url + +router = PrefixedDefaultRouter(use_regex_path=False, name_prefix="ietf.api.purple_api") +router.include_format_suffixes = False +router.register(r"draft", views_rpc.DraftViewSet, basename="draft") +router.register(r"person", views_rpc.PersonViewSet) +router.register(r"rfc", views_rpc.RfcViewSet, basename="rfc") + +router.register( + r"rfc//authors", + views_rpc.RfcAuthorViewSet, + basename="rfc-authors", +) + +urlpatterns = [ + url(r"^doc/drafts_by_names/", views_rpc.DraftsByNamesView.as_view()), + url(r"^persons/search/", views_rpc.RpcPersonSearch.as_view()), + path( + r"rfc/publish/", + views_rpc.RfcPubNotificationView.as_view(), + name="ietf.api.purple_api.notify_rfc_published", + ), + path( + r"rfc/publish/files/", + views_rpc.RfcPubFilesView.as_view(), + name="ietf.api.purple_api.upload_rfc_files", + ), + path( + r"rfc_index/refresh/", + views_rpc.RfcIndexView.as_view(), + name="ietf.api.purple_api.refresh_rfc_index", + ), + path(r"subject//person/", views_rpc.SubjectPersonView.as_view()), + path( + r"queue/process/", + views_rpc.ProcessRpcQueueView.as_view(), + name="ietf.api.purple_api.process_rpc_queue", + ), +] + +# add routers at the end so individual routes can steal parts of their address +# space (e.g., ^rfc/publish/ superseding the ^rfc/ routes of RfcViewSet) +urlpatterns.extend( + [ + path("", include(router.urls)), + ] +) diff --git a/ietf/api/views.py b/ietf/api/views.py index 91068da28ae..1c62d8a1ea2 100644 --- a/ietf/api/views.py +++ b/ietf/api/views.py @@ -1,41 +1,56 @@ -# Copyright The IETF Trust 2017-2020, All Rights Reserved -# -*- coding: utf-8 -*- - +# Copyright The IETF Trust 2017-2026, All Rights Reserved +import base64 +import binascii +import datetime import json +from pathlib import Path +from tempfile import NamedTemporaryFile +import jsonschema import pytz +import re -from jwcrypto.jwk import JWK - +from contextlib import suppress from django.conf import settings +from django.contrib.auth import authenticate from django.contrib.auth.decorators import login_required from django.contrib.auth.models import User -from django.core.exceptions import ValidationError -from django.core.validators import validate_email -from django.http import HttpResponse +from django.http import HttpResponse, Http404, JsonResponse, HttpResponseBadRequest from django.shortcuts import render, get_object_or_404 from django.urls import reverse +from django.utils import timezone from django.utils.decorators import method_decorator from django.views.decorators.csrf import csrf_exempt from django.views.decorators.gzip import gzip_page from django.views.generic.detail import DetailView - +from email.message import EmailMessage +from importlib.metadata import version as metadata_version +from jwcrypto.jwk import JWK from tastypie.exceptions import BadRequest -from tastypie.utils.mime import determine_format, build_content_type -from tastypie.utils import is_valid_jsonp_callback_value from tastypie.serializers import Serializer - -import debug # pyflakes:ignore +from tastypie.utils import is_valid_jsonp_callback_value +from tastypie.utils.mime import determine_format, build_content_type +from textwrap import dedent +from traceback import format_exception, extract_tb +from typing import Iterable, Optional, Literal import ietf -from ietf.person.models import Person, Email from ietf.api import _api_list +from ietf.api.ietf_utils import is_valid_token, requires_api_token from ietf.api.serializer import JsonExportMixin -from ietf.ietfauth.views import send_account_creation_email +from ietf.doc.models import Document +from ietf.doc.utils import DraftAliasGenerator, fuzzy_find_documents +from ietf.group.utils import GroupAliasGenerator, role_holder_emails from ietf.ietfauth.utils import role_required +from ietf.ipr.utils import ingest_response_email as ipr_ingest_response_email from ietf.meeting.models import Meeting -from ietf.stats.models import MeetingRegistration +from ietf.meeting.utils import import_registration_json_validator, process_single_registration +from ietf.nomcom.utils import ingest_feedback_email as nomcom_ingest_feedback_email +from ietf.person.models import Person, Email +from ietf.sync.iana import ingest_review_email as iana_ingest_review_email +from ietf.utils import log from ietf.utils.decorators import require_api_key +from ietf.utils.mail import send_smtp from ietf.utils.models import DumpInfo @@ -50,7 +65,10 @@ def top_level(request): } serializer = Serializer() - desired_format = determine_format(request, serializer) + try: + desired_format = determine_format(request, serializer) + except BadRequest as err: + return HttpResponseBadRequest(str(err)) options = {} @@ -58,10 +76,12 @@ def top_level(request): callback = request.GET.get('callback', 'callback') if not is_valid_jsonp_callback_value(callback): - raise BadRequest('JSONP callback name is invalid.') + return HttpResponseBadRequest("JSONP callback name is invalid") options['callback'] = callback + # This might raise UnsupportedFormat, but that indicates a real server misconfiguration + # so let it bubble up unhandled and trigger a 500 / email to admins. serialized = serializer.serialize(available_resources, desired_format, options) return HttpResponse(content=serialized, content_type=build_content_type(desired_format)) @@ -78,13 +98,13 @@ class PersonalInformationExportView(DetailView, JsonExportMixin): def get(self, request): person = get_object_or_404(self.model, user=request.user) - expand = ['searchrule', 'documentauthor', 'ad_document_set', 'ad_dochistory_set', 'docevent', + expand = ['searchrule', 'documentauthor', 'rfcauthor', 'ad_document_set', 'ad_dochistory_set', 'docevent', 'ballotpositiondocevent', 'deletedevent', 'email_set', 'groupevent', 'role', 'rolehistory', 'iprdisclosurebase', - 'iprevent', 'liaisonstatementevent', 'whitelisted', 'schedule', 'constraint', 'schedulingevent', 'message', + 'iprevent', 'liaisonstatementevent', 'allowlisted', 'schedule', 'constraint', 'schedulingevent', 'message', 'sendqueue', 'nominee', 'topicfeedbacklastseen', 'alias', 'email', 'apikeys', 'personevent', 'reviewersettings', 'reviewsecretarysettings', 'unavailableperiod', 'reviewwish', 'nextreviewerinteam', 'reviewrequest', 'meetingregistration', 'submissionevent', 'preapproval', - 'user', 'user__communitylist', 'personextresource_set', ] + 'user', 'communitylist', 'personextresource_set', ] return self.json_view(request, filter={'id':person.id}, expand=expand) @@ -95,7 +115,11 @@ class ApiV2PersonExportView(DetailView, JsonExportMixin): model = Person def err(self, code, text): - return HttpResponse(text, status=code, content_type='text/plain') + return HttpResponse( + text, + status=code, + content_type=f"text/plain; charset={settings.DEFAULT_CHARSET}", + ) def post(self, request): querydict = request.POST.copy() @@ -127,84 +151,81 @@ def post(self, request): # else: # return HttpResponse(status=405) -@require_api_key -@role_required('Robot') + +@requires_api_token @csrf_exempt -def api_new_meeting_registration(request): +def api_new_meeting_registration_v2(request): '''REST API to notify the datatracker about a new meeting registration''' - def err(code, text): - return HttpResponse(text, status=code, content_type='text/plain') - required_fields = [ 'meeting', 'first_name', 'last_name', 'affiliation', 'country_code', - 'email', 'reg_type', 'ticket_type', ] - fields = required_fields + [] - if request.method == 'POST': - # parameters: - # apikey: - # meeting - # name - # email - # reg_type (In Person, Remote, Hackathon Only) - # ticket_type (full_week, one_day, student) - # - data = {'attended': False, } - missing_fields = [] - for item in fields: - value = request.POST.get(item, None) - if value is None and item in required_fields: - missing_fields.append(item) - data[item] = value - if missing_fields: - return err(400, "Missing parameters: %s" % ', '.join(missing_fields)) - number = data['meeting'] - try: - meeting = Meeting.objects.get(number=number) - except Meeting.DoesNotExist: - return err(400, "Invalid meeting value: '%s'" % (number, )) - reg_type = data['reg_type'] - email = data['email'] - try: - validate_email(email) - except ValidationError: - return err(400, "Invalid email value: '%s'" % (email, )) - if request.POST.get('cancelled', 'false') == 'true': - MeetingRegistration.objects.filter( - meeting_id=meeting.pk, - email=email, - reg_type=reg_type).delete() - return HttpResponse('OK', status=200, content_type='text/plain') - else: - object, created = MeetingRegistration.objects.get_or_create( - meeting_id=meeting.pk, - email=email, - reg_type=reg_type) - try: - # Update attributes - for key in set(data.keys())-set(['attended', 'apikey', 'meeting', 'email']): - new = data.get(key) - setattr(object, key, new) - person = Person.objects.filter(email__address=email) - if person.exists(): - object.person = person.first() - object.save() - except ValueError as e: - return err(400, "Unexpected POST data: %s" % e) - response = "Accepted, New registration" if created else "Accepted, Updated registration" - if User.objects.filter(username=email).exists() or Email.objects.filter(address=email).exists(): - pass - else: - send_account_creation_email(request, email) - response += ", Email sent" - return HttpResponse(response, status=202, content_type='text/plain') - else: - return HttpResponse(status=405) + def _http_err(code, text): + return HttpResponse( + text, + status=code, + content_type=f"text/plain; charset={settings.DEFAULT_CHARSET}", + ) + + def _api_response(result): + return JsonResponse(data={"result": result}) + + if request.method != "POST": + return _http_err(405, "Method not allowed") + + if request.content_type != "application/json": + return _http_err(415, "Content-Type must be application/json") + + # Validate + try: + payload = json.loads(request.body) + import_registration_json_validator.validate(payload) + except json.decoder.JSONDecodeError as err: + return _http_err(400, f"JSON parse error at line {err.lineno} col {err.colno}: {err.msg}") + except jsonschema.exceptions.ValidationError as err: + return _http_err(400, f"JSON schema error at {err.json_path}: {err.message}") + except Exception: + return _http_err(400, "Invalid request format") + + # Get the meeting ID from the first registration, the API only deals with one meeting at a time + first_email = next(iter(payload['objects'])) + meeting_number = payload['objects'][first_email]['meeting'] + try: + meeting = Meeting.objects.get(number=meeting_number) + except Meeting.DoesNotExist: + return _http_err(400, f"Invalid meeting value: {meeting_number}") + + # confirm email exists + try: + Email.objects.get(address=first_email) + except Email.DoesNotExist: + return _http_err(400, f"Unknown email: {first_email}") + + reg_data = payload['objects'][first_email] + + process_single_registration(reg_data, meeting) + + return HttpResponse( + 'Success', + status=202, + content_type=f"text/plain; charset={settings.DEFAULT_CHARSET}", + ) def version(request): + dumpdate = None dumpinfo = DumpInfo.objects.order_by('-date').first() - dumptime = pytz.timezone(dumpinfo.tz).localize(dumpinfo.date).strftime('%Y-%m-%d %H:%M:%S %z') if dumpinfo else None + if dumpinfo: + dumpdate = dumpinfo.date + if dumpinfo.tz != "UTC": + dumpdate = pytz.timezone(dumpinfo.tz).localize(dumpinfo.date.replace(tzinfo=None)) + dumptime = dumpdate.strftime('%Y-%m-%d %H:%M:%S %z') if dumpinfo else None + + # important libraries + __version_extra__ = {} + for lib in settings.ADVERTISE_VERSIONS: + __version_extra__[lib] = metadata_version(lib) + return HttpResponse( json.dumps({ 'version': ietf.__version__+ietf.__patch__, + 'other': __version_extra__, 'dumptime': dumptime, }), content_type='application/json', @@ -213,7 +234,650 @@ def version(request): @require_api_key @csrf_exempt -def app_auth(request): +def app_auth(request, app: Literal["authortools", "bibxml"]): return HttpResponse( json.dumps({'success': True}), content_type='application/json') + +@requires_api_token +@csrf_exempt +def nfs_metrics(request): + with NamedTemporaryFile(dir=settings.NFS_METRICS_TMP_DIR,delete=False) as fp: + fp.close() + mark = datetime.datetime.now() + with open(fp.name, mode="w") as f: + f.write("whyioughta"*1024) + write_latency = (datetime.datetime.now() - mark).total_seconds() + mark = datetime.datetime.now() + with open(fp.name, "r") as f: + _=f.read() + read_latency = (datetime.datetime.now() - mark).total_seconds() + Path(f.name).unlink() + response=f'nfs_latency_seconds{{operation="write"}} {write_latency}\nnfs_latency_seconds{{operation="read"}} {read_latency}\n' + return HttpResponse(response) + +def find_doc_for_rfcdiff(name, rev): + """rfcdiff lookup heuristics + + Returns a tuple with: + [0] - condition string + [1] - document found (or None) + [2] - historic version + [3] - revision actually found (may differ from :rev: input) + """ + found = fuzzy_find_documents(name, rev) + condition = 'no such document' + if found.documents.count() != 1: + return (condition, None, None, rev) + doc = found.documents.get() + if found.matched_rev is None or doc.rev == found.matched_rev: + condition = 'current version' + return (condition, doc, None, found.matched_rev) + else: + candidate = doc.history_set.filter(rev=found.matched_rev).order_by("-time").first() + if candidate: + condition = 'historic version' + return (condition, doc, candidate, found.matched_rev) + else: + condition = 'version dochistory not found' + return (condition, doc, None, found.matched_rev) + +# This is a proof of concept of a service that would redirect to the current revision +# def rfcdiff_latest(request, name, rev=None): +# condition, doc, history = find_doc_for_rfcdiff(name, rev) +# if not doc: +# raise Http404 +# if history: +# return redirect(history.get_href()) +# else: +# return redirect(doc.get_href()) + +HAS_TOMBSTONE = [ + 2821, 2822, 2873, 2919, 2961, 3023, 3029, 3031, 3032, 3033, 3034, 3035, 3036, + 3037, 3038, 3042, 3044, 3050, 3052, 3054, 3055, 3056, 3057, 3059, 3060, 3061, + 3062, 3063, 3064, 3067, 3068, 3069, 3070, 3071, 3072, 3073, 3074, 3075, 3076, + 3077, 3078, 3080, 3081, 3082, 3084, 3085, 3086, 3087, 3088, 3089, 3090, 3094, + 3095, 3096, 3097, 3098, 3101, 3102, 3103, 3104, 3105, 3106, 3107, 3108, 3109, + 3110, 3111, 3112, 3113, 3114, 3115, 3116, 3117, 3118, 3119, 3120, 3121, 3123, + 3124, 3126, 3127, 3128, 3130, 3131, 3132, 3133, 3134, 3135, 3136, 3137, 3138, + 3139, 3140, 3141, 3142, 3143, 3144, 3145, 3147, 3149, 3150, 3151, 3152, 3153, + 3154, 3155, 3156, 3157, 3158, 3159, 3160, 3161, 3162, 3163, 3164, 3165, 3166, + 3167, 3168, 3169, 3170, 3171, 3172, 3173, 3174, 3176, 3179, 3180, 3181, 3182, + 3183, 3184, 3185, 3186, 3187, 3188, 3189, 3190, 3191, 3192, 3193, 3194, 3197, + 3198, 3201, 3202, 3203, 3204, 3205, 3206, 3207, 3208, 3209, 3210, 3211, 3212, + 3213, 3214, 3215, 3216, 3217, 3218, 3220, 3221, 3222, 3224, 3225, 3226, 3227, + 3228, 3229, 3230, 3231, 3232, 3233, 3234, 3235, 3236, 3237, 3238, 3240, 3241, + 3242, 3243, 3244, 3245, 3246, 3247, 3248, 3249, 3250, 3253, 3254, 3255, 3256, + 3257, 3258, 3259, 3260, 3261, 3262, 3263, 3264, 3265, 3266, 3267, 3268, 3269, + 3270, 3271, 3272, 3273, 3274, 3275, 3276, 3278, 3279, 3280, 3281, 3282, 3283, + 3284, 3285, 3286, 3287, 3288, 3289, 3290, 3291, 3292, 3293, 3294, 3295, 3296, + 3297, 3298, 3301, 3302, 3303, 3304, 3305, 3307, 3308, 3309, 3310, 3311, 3312, + 3313, 3315, 3317, 3318, 3319, 3320, 3321, 3322, 3323, 3324, 3325, 3326, 3327, + 3329, 3330, 3331, 3332, 3334, 3335, 3336, 3338, 3340, 3341, 3342, 3343, 3346, + 3348, 3349, 3351, 3352, 3353, 3354, 3355, 3356, 3360, 3361, 3362, 3363, 3364, + 3366, 3367, 3368, 3369, 3370, 3371, 3372, 3374, 3375, 3377, 3378, 3379, 3383, + 3384, 3385, 3386, 3387, 3388, 3389, 3390, 3391, 3394, 3395, 3396, 3397, 3398, + 3401, 3402, 3403, 3404, 3405, 3406, 3407, 3408, 3409, 3410, 3411, 3412, 3413, + 3414, 3415, 3416, 3417, 3418, 3419, 3420, 3421, 3422, 3423, 3424, 3425, 3426, + 3427, 3428, 3429, 3430, 3431, 3433, 3434, 3435, 3436, 3437, 3438, 3439, 3440, + 3441, 3443, 3444, 3445, 3446, 3447, 3448, 3449, 3450, 3451, 3452, 3453, 3454, + 3455, 3458, 3459, 3460, 3461, 3462, 3463, 3464, 3465, 3466, 3467, 3468, 3469, + 3470, 3471, 3472, 3473, 3474, 3475, 3476, 3477, 3480, 3481, 3483, 3485, 3488, + 3494, 3495, 3496, 3497, 3498, 3501, 3502, 3503, 3504, 3505, 3506, 3507, 3508, + 3509, 3511, 3512, 3515, 3516, 3517, 3518, 3520, 3521, 3522, 3523, 3524, 3525, + 3527, 3529, 3530, 3532, 3533, 3534, 3536, 3537, 3538, 3539, 3541, 3543, 3544, + 3545, 3546, 3547, 3548, 3549, 3550, 3551, 3552, 3555, 3556, 3557, 3558, 3559, + 3560, 3562, 3563, 3564, 3565, 3568, 3569, 3570, 3571, 3572, 3573, 3574, 3575, + 3576, 3577, 3578, 3579, 3580, 3581, 3582, 3583, 3584, 3588, 3589, 3590, 3591, + 3592, 3593, 3594, 3595, 3597, 3598, 3601, 3607, 3609, 3610, 3612, 3614, 3615, + 3616, 3625, 3627, 3630, 3635, 3636, 3637, 3638 +] + + +def get_previous_url(name, rev=None): + '''Return previous url''' + condition, document, history, found_rev = find_doc_for_rfcdiff(name, rev) + previous_url = '' + if condition in ('historic version', 'current version'): + doc = history if history else document + previous_url = doc.get_href() + elif condition == 'version dochistory not found': + document.rev = found_rev + previous_url = document.get_href() + return previous_url + + +def rfcdiff_latest_json(request, name, rev=None): + response = dict() + condition, document, history, found_rev = find_doc_for_rfcdiff(name, rev) + if document and document.type_id == "rfc": + draft = document.came_from_draft() + if condition == 'no such document': + raise Http404 + elif condition in ('historic version', 'current version'): + doc = history if history else document + if doc.type_id == "rfc": + response['content_url'] = doc.get_href() + response['name']=doc.name + if draft: + prev_rev = draft.rev + if doc.rfc_number in HAS_TOMBSTONE and prev_rev != '00': + prev_rev = f'{(int(draft.rev)-1):02d}' + response['previous'] = f'{draft.name}-{prev_rev}' + response['previous_url'] = get_previous_url(draft.name, prev_rev) + elif doc.type_id == "draft" and not found_rev and doc.relateddocument_set.filter(relationship_id="became_rfc").exists(): + rfc = doc.related_that_doc("became_rfc")[0] + response['content_url'] = rfc.get_href() + response['name']=rfc.name + prev_rev = doc.rev + if rfc.rfc_number in HAS_TOMBSTONE and prev_rev != '00': + prev_rev = f'{(int(doc.rev)-1):02d}' + response['previous'] = f'{doc.name}-{prev_rev}' + response['previous_url'] = get_previous_url(doc.name, prev_rev) + else: + response['content_url'] = doc.get_href() + response['rev'] = doc.rev + response['name'] = doc.name + if doc.rev == '00': + replaces_docs = (history.doc if condition=='historic version' else doc).related_that_doc('replaces') + if replaces_docs: + replaces = replaces_docs[0] + response['previous'] = f'{replaces.name}-{replaces.rev}' + response['previous_url'] = get_previous_url(replaces.name, replaces.rev) + else: + match = re.search("-(rfc)?([0-9][0-9][0-9]+)bis(-.*)?$", name) + if match and match.group(2): + response['previous'] = f'rfc{match.group(2)}' + response['previous_url'] = get_previous_url(f'rfc{match.group(2)}') + else: + # not sure what to do if non-numeric values come back, so at least log it + log.assertion('doc.rev.isdigit()') + prev_rev = f'{(int(doc.rev)-1):02d}' + response['previous'] = f'{doc.name}-{prev_rev}' + response['previous_url'] = get_previous_url(doc.name, prev_rev) + elif condition == 'version dochistory not found': + response['warning'] = 'History for this version not found - these results are speculation' + response['name'] = document.name + response['rev'] = found_rev + document.rev = found_rev + response['content_url'] = document.get_href() + # not sure what to do if non-numeric values come back, so at least log it + log.assertion('found_rev.isdigit()') + if int(found_rev) > 0: + prev_rev = f'{(int(found_rev)-1):02d}' + response['previous'] = f'{document.name}-{prev_rev}' + response['previous_url'] = get_previous_url(document.name, prev_rev) + else: + match = re.search("-(rfc)?([0-9][0-9][0-9]+)bis(-.*)?$", name) + if match and match.group(2): + response['previous'] = f'rfc{match.group(2)}' + response['previous_url'] = get_previous_url(f'rfc{match.group(2)}') + if not response: + raise Http404 + return HttpResponse(json.dumps(response), content_type='application/json') + +@csrf_exempt +def directauth(request): + if request.method == "POST": + raw_data = request.POST.get("data", None) + if raw_data: + try: + data = json.loads(raw_data) + except json.decoder.JSONDecodeError: + data = None + + if raw_data is None or data is None: + log.log("Request body is either missing or invalid") + return HttpResponse(json.dumps(dict(result="failure",reason="invalid post")), content_type='application/json') + + authtoken = data.get('authtoken', None) + username = data.get('username', None) + password = data.get('password', None) + + if any([item is None for item in (authtoken, username, password)]): + log.log("One or more mandatory fields are missing: authtoken, username, password") + return HttpResponse(json.dumps(dict(result="failure",reason="invalid post")), content_type='application/json') + + if not is_valid_token("ietf.api.views.directauth", authtoken): + log.log("Auth token provided is invalid") + return HttpResponse(json.dumps(dict(result="failure",reason="invalid authtoken")), content_type='application/json') + + user_query = User.objects.filter(username__iexact=username) + + # Matching email would be consistent with auth everywhere else in the app, but until we can map users well + # in the imap server, people's annotations are associated with a very specific login. + # If we get a second user of this API, add an "allow_any_email" argument. + + + # Note well that we are using user.username, not what was passed to the API. + user_count = user_query.count() + if user_count == 1 and authenticate(username = user_query.first().username, password = password): + user = user_query.get() + if user_query.filter(person__isnull=True).count() == 1: # Can't inspect user.person direclty here + log.log(f"Direct auth success (personless user): {user.pk}:{user.username}") + else: + log.log(f"Direct auth success: {user.pk}:{user.person.plain_name()}") + return HttpResponse(json.dumps(dict(result="success")), content_type='application/json') + + log.log(f"Direct auth failure: {username} ({user_count} user(s) found)") + return HttpResponse(json.dumps(dict(result="failure", reason="authentication failed")), content_type='application/json') + + else: + log.log(f"Request must be POST: {request.method} received") + return HttpResponse(status=405) + + +@requires_api_token +@csrf_exempt +def draft_aliases(request): + if request.method == "GET": + return JsonResponse( + { + "aliases": [ + { + "alias": alias, + "domains": ["ietf"], + "addresses": address_list, + } + for alias, address_list in DraftAliasGenerator() + ] + } + ) + return HttpResponse(status=405) + + +@requires_api_token +@csrf_exempt +def group_aliases(request): + if request.method == "GET": + return JsonResponse( + { + "aliases": [ + { + "alias": alias, + "domains": domains, + "addresses": address_list, + } + for alias, domains, address_list in GroupAliasGenerator() + ] + } + ) + return HttpResponse(status=405) + + +@requires_api_token +@csrf_exempt +def active_email_list(request): + if request.method == "GET": + return JsonResponse( + { + "addresses": list(Email.objects.filter(active=True).values_list("address", flat=True)), + } + ) + return HttpResponse(status=405) + + +@requires_api_token +@csrf_exempt +def related_email_list(request, email): + """Given an email address, returns all other email addresses known + to Datatracker, via Person object + """ + def _http_err(code, text): + return HttpResponse( + text, + status=code, + content_type=f"text/plain; charset={settings.DEFAULT_CHARSET}", + ) + + if request.method == "GET": + try: + email_obj = Email.objects.get(address=email) + except Email.DoesNotExist: + return _http_err(404, "Email not found") + person = email_obj.person + if not person: + return JsonResponse({"addresses": []}) + return JsonResponse( + { + "addresses": list(person.email_set.values_list("address", flat=True)), + } + ) + return HttpResponse(status=405) + + +@requires_api_token +def role_holder_addresses(request): + if request.method == "GET": + return JsonResponse( + { + "addresses": list( + role_holder_emails() + .order_by("address") + .values_list("address", flat=True) + ) + } + ) + return HttpResponse(status=405) + + +@requires_api_token +@csrf_exempt +def rfc_authors(request): + """Return authors of published RFCs as a JSON list of objects. + + Finds authors by date, though this could be extended to other selection + criteria in the future. Specify the range as ?from=&to=. + Each is an ISO-8601 timestamp, treated as UTC if it does not include + time zone information. Defaults to `to`=now, `from`=14 days before `to` + + Each author appears once, with their RFC numbers, names, titles, and + publication dates accumulated across every RFC they published in the window. + + When the ?testing query parameter is supplied, each author's real email + address is replaced with a fake one that keeps the original mailbox but uses + the "fake.example.com" domain, so the output can be shared without exposing + real addresses. + + When the ?testing query parameter is supplied, one or more testaddr=ADDRESS query + parameters can also be specified. The value of each parameter is an email + address. When these parameters are present, the response data will include an + entry for each address as though it belonged to the author of a recently published + RFC. + """ + if request.method != "GET": + return HttpResponse(status=405) + + # Test mode parameters + testing = "testing" in request.GET + test_addresses = request.GET.getlist("testaddr", []) + if len(test_addresses) > 0: + if not testing: + return HttpResponseBadRequest( + "Must include the testing parameter when using testaddr" + ) + + # filter parameters + to_param = request.GET.get("to") + if to_param is None: + # Did not receive a to parameter. Default to now(). + time_range_end = datetime.datetime.now(datetime.UTC) + else: + # Did receive a to parameter. Parse it. + try: + time_range_end = datetime.datetime.fromisoformat(to_param) + except ValueError: + return HttpResponseBadRequest("Invalid to parameter") + if time_range_end.tzinfo is None: + time_range_end = time_range_end.replace(tzinfo=datetime.UTC) + + from_param = request.GET.get("from") + if from_param is None: + # Did not receive a from parameter. Default to 14 days before end time. + time_range_start = time_range_end - datetime.timedelta(days=14) + else: + # Did receive a from parameter. Parse it. + try: + time_range_start = datetime.datetime.fromisoformat(from_param) + except ValueError: + return HttpResponseBadRequest("Invalid from parameter") + if time_range_start.tzinfo is None: + time_range_start = time_range_start.replace(tzinfo=datetime.UTC) + if time_range_start > time_range_end: + return HttpResponseBadRequest("Invalid time range, from is later than to") + + rfcs = Document.objects.filter( + type_id="rfc", + docevent__type="published_rfc", + docevent__time__gte=time_range_start, + docevent__time__lt=time_range_end, + ).distinct() + + # Collect per-author data keyed by email so each author gets one row. + # Values accumulate RFC numbers, names, titles, and dates across all RFCs. + author_data = {} + + for rfc in rfcs: + # RfcAuthor is the authoritative source for RFC authors. Documents of + # type "rfc" always have an rfcauthor_set, so no fallback is needed. + authors = [ + { + "name": a.person.name if a.person else a.titlepage_name, + "email": a.person.email().address + if (a.person and a.person.email()) + else None, + } + for a in rfc.rfcauthor_set.select_related("person").order_by("order") + ] + + for author in authors: + if not author["email"]: + continue + + if testing: + mailbox = author["email"].split("@", 1)[0] + email = f"{mailbox}@fake.example.com" + else: + email = author["email"] + + if email not in author_data: + author_data[email] = { + "name": author["name"], + "email": email, + "rfc_numbers": [], + "rfc_names": [], + "rfc_titles": [], + "published_dates": [], + } + author_data[email]["rfc_numbers"].append(str(rfc.rfc_number)) + author_data[email]["rfc_names"].append(rfc.name) + author_data[email]["rfc_titles"].append(rfc.title) + author_data[email]["published_dates"].append(str(rfc.pub_date())) + + if testing: + for n, email in enumerate(test_addresses): + if email in author_data: + continue # author will already be included + author_data[email] = { + "name": f"Test Author {n + 1}", + "email": email, + "rfc_numbers": ["99999"], + "rfc_names": ["rfc99999"], + "rfc_titles": ["A Fake RFC for Testing"], + "published_dates": [str(timezone.now().date())], + } + + rows = [] + for entry in author_data.values(): + rows.append( + { + "name": entry["name"], + "email": entry["email"], + "rfc_number": ", ".join(entry["rfc_numbers"]), + "rfc_name": ", ".join(entry["rfc_names"]), + "rfc_title": ", ".join(entry["rfc_titles"]), + "rfc_number_and_title": ", ".join( + f"RFC {num}: {title}" + for num, title in zip(entry["rfc_numbers"], entry["rfc_titles"]) + ), + "published_date": ", ".join(entry["published_dates"]), + } + ) + + return JsonResponse(rows, safe=False) + + +_response_email_json_validator = jsonschema.Draft202012Validator( + schema={ + "type": "object", + "properties": { + "dest": { + "type": "string", + }, + "message": { + "type": "string", # base64-encoded mail message + }, + }, + "required": ["dest", "message"], + } +) + + +class EmailIngestionError(Exception): + """Exception indicating ingestion failed""" + def __init__( + self, + msg="Message rejected", + *, + email_body: Optional[str] = None, + email_recipients: Optional[Iterable[str]] = None, + email_attach_traceback=False, + email_original_message: Optional[bytes]=None, + ): + self.msg = msg + self.email_body = email_body + self.email_subject = msg + self.email_recipients = email_recipients + self.email_attach_traceback = email_attach_traceback + self.email_original_message = email_original_message + self.email_from = settings.SERVER_EMAIL + + @staticmethod + def _summarize_error(error): + frame = extract_tb(error.__traceback__)[-1] + return dedent(f"""\ + Error details: + Exception type: {type(error).__module__}.{type(error).__name__} + File: {frame.filename} + Line: {frame.lineno}""") + + def as_emailmessage(self) -> Optional[EmailMessage]: + """Generate an EmailMessage to report an error""" + if self.email_body is None: + return None + error = self if self.__cause__ is None else self.__cause__ + format_values = dict( + error=error, + error_summary=self._summarize_error(error), + ) + msg = EmailMessage() + if self.email_recipients is None: + msg["To"] = tuple(adm[1] for adm in settings.ADMINS) + else: + msg["To"] = self.email_recipients + msg["From"] = self.email_from + msg["Subject"] = self.msg + msg.set_content( + self.email_body.format(**format_values) + ) + if self.email_attach_traceback: + msg.add_attachment( + "".join(format_exception(None, error, error.__traceback__)), + filename="traceback.txt", + ) + if self.email_original_message is not None: + # Attach incoming message if it was provided. Send as a generic media + # type because we don't know for sure that it was actually a valid + # message. + msg.add_attachment( + self.email_original_message, + 'application', 'octet-stream', # media type + filename='original-message', + ) + return msg + + +def ingest_email_handler(request, test_mode=False): + """Ingest incoming email - handler + + Returns a 4xx or 5xx status code if the HTTP request was invalid or something went + wrong while processing it. If the request was valid, returns a 200. This may or may + not indicate that the message was accepted. + + If test_mode is true, actual processing of a valid message will be skipped. In this + mode, a valid request with a valid destination will be treated as accepted. The + "bad_dest" error may still be returned. + """ + + def _http_err(code, text): + return HttpResponse( + text, + status=code, + content_type=f"text/plain; charset={settings.DEFAULT_CHARSET}", + ) + + def _api_response(result): + return JsonResponse(data={"result": result}) + + if request.method != "POST": + return _http_err(405, "Method not allowed") + + if request.content_type != "application/json": + return _http_err(415, "Content-Type must be application/json") + + # Validate + try: + payload = json.loads(request.body) + _response_email_json_validator.validate(payload) + except json.decoder.JSONDecodeError as err: + return _http_err(400, f"JSON parse error at line {err.lineno} col {err.colno}: {err.msg}") + except jsonschema.exceptions.ValidationError as err: + return _http_err(400, f"JSON schema error at {err.json_path}: {err.message}") + except Exception: + return _http_err(400, "Invalid request format") + + try: + message = base64.b64decode(payload["message"], validate=True) + except binascii.Error: + return _http_err(400, "Invalid message: bad base64 encoding") + + dest = payload["dest"] + valid_dest = False + try: + if dest == "iana-review": + valid_dest = True + if not test_mode: + iana_ingest_review_email(message) + elif dest == "ipr-response": + valid_dest = True + if not test_mode: + ipr_ingest_response_email(message) + elif dest.startswith("nomcom-feedback-"): + maybe_year = dest[len("nomcom-feedback-"):] + if maybe_year.isdecimal(): + valid_dest = True + if not test_mode: + nomcom_ingest_feedback_email(message, int(maybe_year)) + except EmailIngestionError as err: + error_email = err.as_emailmessage() + if error_email is not None: + with suppress(Exception): # send_smtp logs its own exceptions, ignore them here + send_smtp(error_email) + return _api_response("bad_msg") + + if not valid_dest: + return _api_response("bad_dest") + + return _api_response("ok") + + +@requires_api_token +@csrf_exempt +def ingest_email(request): + """Ingest incoming email + + Hands off to ingest_email_handler() with test_mode=False. This allows @requires_api_token to + give the test endpoint a distinct token from the real one. + """ + return ingest_email_handler(request, test_mode=False) + + +@requires_api_token +@csrf_exempt +def ingest_email_test(request): + """Ingest incoming email test endpoint + + Hands off to ingest_email_handler() with test_mode=True. This allows @requires_api_token to + give the test endpoint a distinct token from the real one. + """ + return ingest_email_handler(request, test_mode=True) diff --git a/ietf/api/views_rpc.py b/ietf/api/views_rpc.py new file mode 100644 index 00000000000..21d59e3f14c --- /dev/null +++ b/ietf/api/views_rpc.py @@ -0,0 +1,615 @@ +# Copyright The IETF Trust 2023-2026, All Rights Reserved +import os +import shutil +from functools import partial +from pathlib import Path +from tempfile import TemporaryDirectory + +from django.conf import settings +from django.db import IntegrityError, transaction +from drf_spectacular.utils import OpenApiParameter +from rest_framework import mixins, parsers, serializers, viewsets, status +from rest_framework.decorators import action +from rest_framework.exceptions import APIException +from rest_framework.views import APIView +from rest_framework.response import Response + +from django.db.models import CharField as ModelCharField, OuterRef, Subquery, Q +from django.db.models.functions import Coalesce +from django.http import Http404 +from drf_spectacular.utils import extend_schema_view, extend_schema +from rest_framework import generics +from rest_framework.fields import CharField as DrfCharField +from rest_framework.filters import SearchFilter +from rest_framework.pagination import LimitOffsetPagination + +from ietf.api.serializers_rpc import ( + PersonSerializer, + FullDraftSerializer, + DraftSerializer, + SubmittedToQueueSerializer, + OriginalStreamSerializer, + ReferenceSerializer, + EmailPersonSerializer, + RfcWithAuthorsSerializer, + DraftWithAuthorsSerializer, + NotificationAckSerializer, + RfcPubSerializer, + RfcFileSerializer, + EditableRfcSerializer, +) +from ietf.doc.models import Document, DocHistory, RfcAuthor, DocEvent +from ietf.doc.serializers import RfcAuthorSerializer +from ietf.doc.storage_utils import remove_from_storage, store_file, exists_in_storage +from ietf.doc.tasks import ( + signal_update_rfc_metadata_task, + rebuild_reference_relations_task, + trigger_red_precomputer_task, + update_rfc_searchindex_task, +) +from ietf.person.models import Email, Person +from ietf.sync.rfcindex import mark_rfcindex_as_dirty +from ietf.sync.tasks import process_rpc_queue_task, update_rfc_json_task + + +class Conflict(APIException): + status_code = status.HTTP_409_CONFLICT + default_detail = "Conflict." + default_code = "conflict" + + +@extend_schema_view( + retrieve=extend_schema( + operation_id="get_person_by_id", + summary="Find person by ID", + description="Returns a single person", + parameters=[ + OpenApiParameter( + name="person_id", + type=int, + location="path", + description="Person ID identifying this person.", + ), + ], + ), +) +class PersonViewSet(mixins.RetrieveModelMixin, viewsets.GenericViewSet): + queryset = Person.objects.all() + serializer_class = PersonSerializer + api_key_endpoint = "ietf.api.views_rpc" + lookup_url_kwarg = "person_id" + + @extend_schema( + operation_id="get_persons", + summary="Get a batch of persons", + description="Returns a list of persons matching requested ids. Omits any that are missing.", + request=list[int], + responses=PersonSerializer(many=True), + ) + @action(detail=False, methods=["post"]) + def batch(self, request): + """Get a batch of rpc person names""" + pks = request.data + return Response( + self.get_serializer(Person.objects.filter(pk__in=pks), many=True).data + ) + + @extend_schema( + operation_id="persons_by_email", + summary="Get a batch of persons by email addresses", + description=( + "Returns a list of persons matching requested ids. " + "Omits any that are missing." + ), + request=list[str], + responses=EmailPersonSerializer(many=True), + ) + @action(detail=False, methods=["post"], serializer_class=EmailPersonSerializer) + def batch_by_email(self, request): + emails = Email.objects.filter(address__in=request.data, person__isnull=False) + serializer = self.get_serializer(emails, many=True) + return Response(serializer.data) + + +class SubjectPersonView(APIView): + api_key_endpoint = "ietf.api.views_rpc" + + @extend_schema( + operation_id="get_subject_person_by_id", + summary="Find person for OIDC subject by ID", + description="Returns a single person", + responses=PersonSerializer, + parameters=[ + OpenApiParameter( + name="subject_id", + type=str, + description="subject ID of person to return", + location="path", + ), + ], + ) + def get(self, request, subject_id: str): + try: + user_id = int(subject_id) + except ValueError: + raise serializers.ValidationError( + {"subject_id": "This field must be an integer value."} + ) + person = Person.objects.filter(user__pk=user_id).first() + if person: + return Response(PersonSerializer(person).data) + raise Http404 + + +class RpcLimitOffsetPagination(LimitOffsetPagination): + default_limit = 10 + max_limit = 100 + + +class SingleTermSearchFilter(SearchFilter): + """SearchFilter backend that does not split terms + + The default SearchFilter treats comma or whitespace-separated terms as individual + search terms. This backend instead searches for the exact term. + """ + + def get_search_terms(self, request): + value = request.query_params.get(self.search_param, "") + field = DrfCharField(trim_whitespace=False, allow_blank=True) + cleaned_value = field.run_validation(value) + return [cleaned_value] + + +@extend_schema_view( + get=extend_schema( + operation_id="search_person", + description="Get a list of persons, matching by partial name or email", + ), +) +class RpcPersonSearch(generics.ListAPIView): + # n.b. the OpenAPI schema for this can be generated by running + # ietf/manage.py spectacular --file spectacular.yaml + # and extracting / touching up the rpc_person_search_list operation + api_key_endpoint = "ietf.api.views_rpc" + queryset = Person.objects.all() + serializer_class = PersonSerializer + pagination_class = RpcLimitOffsetPagination + + # Searchable on all name-like fields or email addresses + filter_backends = [SingleTermSearchFilter] + search_fields = ["name", "plain", "email__address"] + + +@extend_schema_view( + retrieve=extend_schema( + operation_id="get_draft_by_id", + summary="Get a draft", + description="Returns the draft for the requested ID", + parameters=[ + OpenApiParameter( + name="doc_id", + type=int, + location="path", + description="Doc ID identifying this draft.", + ), + ], + ), + submitted_to_rpc=extend_schema( + operation_id="submitted_to_rpc", + summary="List documents ready to enter the RFC Editor Queue", + description="List documents ready to enter the RFC Editor Queue", + responses=SubmittedToQueueSerializer(many=True), + ), +) +class DraftViewSet(mixins.RetrieveModelMixin, viewsets.GenericViewSet): + queryset = Document.objects.filter(type_id="draft") + serializer_class = FullDraftSerializer + api_key_endpoint = "ietf.api.views_rpc" + lookup_url_kwarg = "doc_id" + + @action(detail=False, serializer_class=SubmittedToQueueSerializer) + def submitted_to_rpc(self, request): + """Return documents in datatracker that have been submitted to the RPC but are not yet in the queue + + Those queries overreturn - there may be things, particularly not from the IETF stream that are already in the queue. + """ + ietf_docs = Q(states__type_id="draft-iesg", states__slug__in=["ann"]) + irtf_iab_ise_editorial_docs = Q( + states__type_id__in=[ + "draft-stream-iab", + "draft-stream-irtf", + "draft-stream-ise", + "draft-stream-editorial", + ], + states__slug__in=["rfc-edit"], + ) + docs = ( + self.get_queryset() + .filter(type_id="draft") + .filter(ietf_docs | irtf_iab_ise_editorial_docs) + ) + serializer = self.get_serializer(docs, many=True) + return Response(serializer.data) + + @extend_schema( + operation_id="get_draft_references", + summary="Get normative references to I-Ds", + description=( + "Returns the id and name of each normatively " + "referenced Internet-Draft for the given docId" + ), + parameters=[ + OpenApiParameter( + name="doc_id", + type=int, + location="path", + description="Doc ID identifying this draft.", + ), + ], + responses=ReferenceSerializer(many=True), + ) + @action(detail=True, serializer_class=ReferenceSerializer) + def references(self, request, doc_id=None): + doc = self.get_object() + serializer = self.get_serializer( + [ + reference + for reference in doc.related_that_doc("refnorm") + if reference.type_id == "draft" + ], + many=True, + ) + return Response(serializer.data) + + @extend_schema( + operation_id="get_draft_authors", + summary="Gather authors of the drafts with the given names", + description="returns a list mapping draft names to objects describing authors", + request=list[str], + responses=DraftWithAuthorsSerializer(many=True), + ) + @action(detail=False, methods=["post"], serializer_class=DraftWithAuthorsSerializer) + def bulk_authors(self, request): + drafts = self.get_queryset().filter(name__in=request.data) + serializer = self.get_serializer(drafts, many=True) + return Response(serializer.data) + + +@extend_schema_view( + rfc_original_stream=extend_schema( + operation_id="get_rfc_original_streams", + summary="Get the streams RFCs were originally published into", + description="returns a list of dicts associating an RFC with its originally published stream", + responses=OriginalStreamSerializer(many=True), + ) +) +class RfcViewSet(mixins.UpdateModelMixin, viewsets.GenericViewSet): + queryset = Document.objects.filter(type_id="rfc") + api_key_endpoint = "ietf.api.views_rpc" + lookup_field = "rfc_number" + serializer_class = EditableRfcSerializer + + def perform_update(self, serializer): + DocEvent.objects.create( + doc=serializer.instance, + rev=serializer.instance.rev, + by=Person.objects.get(name="(System)"), + type="sync_from_rfc_editor", + desc="Metadata update from RFC Editor", + ) + super().perform_update(serializer) + rfc_number = serializer.instance.rfc_number + transaction.on_commit(lambda: update_rfc_json_task.delay([rfc_number])) + + @action(detail=False, serializer_class=OriginalStreamSerializer) + def rfc_original_stream(self, request): + rfcs = self.get_queryset().annotate( + orig_stream_id=Coalesce( + Subquery( + DocHistory.objects.filter(doc=OuterRef("pk")) + .exclude(stream__isnull=True) + .order_by("time") + .values_list("stream_id", flat=True)[:1] + ), + "stream_id", + output_field=ModelCharField(), + ), + ) + serializer = self.get_serializer(rfcs, many=True) + return Response(serializer.data) + + @extend_schema( + operation_id="get_rfc_authors", + summary="Gather authors of the RFCs with the given numbers", + description="returns a list mapping rfc numbers to objects describing authors", + request=list[int], + responses=RfcWithAuthorsSerializer(many=True), + ) + @action(detail=False, methods=["post"], serializer_class=RfcWithAuthorsSerializer) + def bulk_authors(self, request): + rfcs = self.get_queryset().filter(rfc_number__in=request.data) + serializer = self.get_serializer(rfcs, many=True) + return Response(serializer.data) + + +class DraftsByNamesView(APIView): + api_key_endpoint = "ietf.api.views_rpc" + + @extend_schema( + operation_id="get_drafts_by_names", + summary="Get a batch of drafts by draft names", + description="returns a list of drafts with matching names", + request=list[str], + responses=DraftSerializer(many=True), + ) + def post(self, request): + names = request.data + docs = Document.objects.filter(type_id="draft", name__in=names) + return Response(DraftSerializer(docs, many=True).data) + + +class RfcAuthorViewSet(viewsets.ReadOnlyModelViewSet): + """ViewSet for RfcAuthor model + + Router needs to provide rfc_number as a kwarg + """ + + api_key_endpoint = "ietf.api.views_rpc" + + queryset = RfcAuthor.objects.all() + serializer_class = RfcAuthorSerializer + lookup_url_kwarg = "author_id" + rfc_number_param = "rfc_number" + + def get_queryset(self): + return ( + super() + .get_queryset() + .filter( + document__type_id="rfc", + document__rfc_number=self.kwargs[self.rfc_number_param], + ) + ) + + +class DestinationHelperMixin: + def fs_destination(self, filename: str | Path) -> Path: + """Destination for an uploaded RFC file in the filesystem + + Strips any path components in filename and returns an absolute Path. + """ + rfc_path = Path(settings.RFC_PATH) + filename = Path(filename) # could potentially have directory components + extension = "".join(filename.suffixes) + if extension == ".notprepped.xml": + return rfc_path / "prerelease" / filename.name + return rfc_path / filename.name + + def blob_destination(self, filename: str | Path) -> str: + """Destination name for an uploaded RFC file in the blob store + + Strips any path components in filename and returns an absolute Path. + """ + filename = Path(filename) # could potentially have directory components + extension = "".join(filename.suffixes) + if extension == ".notprepped.xml": + file_type = "notprepped" + elif extension[0] == ".": + file_type = extension[1:] + else: + raise serializers.ValidationError( + f"Extension does not begin with '.'!? ({filename})", + ) + return f"{file_type}/{filename.name}" + + +class RfcPubNotificationView(DestinationHelperMixin, APIView): + api_key_endpoint = "ietf.api.views_rpc" + + @extend_schema( + operation_id="notify_rfc_published", + summary="Notify datatracker of RFC publication", + request=RfcPubSerializer, + responses=NotificationAckSerializer, + ) + def post(self, request): + serializer = RfcPubSerializer(data=request.data) + serializer.is_valid(raise_exception=True) + # Check blobstore & filesystem for conflicts + rfc_number = serializer.validated_data["rfc_number"] + dest_stem = f"rfc{rfc_number}" + blob_kind = "rfc" + possible_rfc_files = [ + self.fs_destination(dest_stem + ext) + for ext in RfcFileSerializer.allowed_extensions + ] + possible_rfc_blobs = [ + self.blob_destination(dest_stem + ext) + for ext in RfcFileSerializer.allowed_extensions + ] + for possible_existing_file in possible_rfc_files: + if possible_existing_file.exists(): + raise Conflict( + "File(s) already exist for this RFC", + code="files-exist", + ) + for possible_existing_blob in possible_rfc_blobs: + if exists_in_storage(kind=blob_kind, name=possible_existing_blob): + raise Conflict( + "Blob(s) already exist for this RFC", + code="blobs-exist", + ) + # Create RFC + try: + rfc = serializer.save() + except IntegrityError as err: + if Document.objects.filter( + rfc_number=serializer.validated_data["rfc_number"] + ): + raise serializers.ValidationError( + "RFC with that number already exists", + code="rfc-number-in-use", + ) + raise serializers.ValidationError( + f"Unable to publish: {err}", + code="unknown-integrity-error", + ) + rfc_number_list = [rfc.rfc_number] + rfc_number_list.extend( + [d.rfc_number for d in rfc.related_that_doc(("updates", "obs"))] + ) + rfc_number_list = sorted(set(rfc_number_list)) + signal_update_rfc_metadata_task.delay(rfc_number_list=rfc_number_list) + related_numbers = sorted( + {d.rfc_number for d in rfc.related_that_doc(("updates", "obs"))} + ) + if related_numbers: + # Only update json for related rfcs. We can't generate json for _this_ rfc + # until we receive the files and know what formats we have. + transaction.on_commit(partial(update_rfc_json_task.delay, related_numbers)) + return Response(NotificationAckSerializer().data) + + +class RfcPubFilesView(DestinationHelperMixin, APIView): + api_key_endpoint = "ietf.api.views_rpc" + parser_classes = [parsers.MultiPartParser] + + @extend_schema( + operation_id="upload_rfc_files", + summary="Upload files for a published RFC", + request=RfcFileSerializer, + responses=NotificationAckSerializer, + ) + def post(self, request): + serializer = RfcFileSerializer( + # many=True, + data=request.data, + ) + serializer.is_valid(raise_exception=True) + rfc = serializer.validated_data["rfc"] + uploaded_files = serializer.validated_data["contents"] # list[UploadedFile] + replace = serializer.validated_data["replace"] + dest_stem = f"rfc{rfc.rfc_number}" + mtime = serializer.validated_data["mtime"] + mtimestamp = mtime.timestamp() + blob_kind = "rfc" + + # List of files that might exist for an RFC + possible_rfc_files = [ + self.fs_destination(dest_stem + ext) + for ext in serializer.allowed_extensions + ] + possible_rfc_blobs = [ + self.blob_destination(dest_stem + ext) + for ext in serializer.allowed_extensions + ] + if not replace: + # this is the default: refuse to overwrite anything if not replacing + for possible_existing_file in possible_rfc_files: + if possible_existing_file.exists(): + raise Conflict( + "File(s) already exist for this RFC", + code="files-exist", + ) + for possible_existing_blob in possible_rfc_blobs: + if exists_in_storage(kind=blob_kind, name=possible_existing_blob): + raise Conflict( + "Blob(s) already exist for this RFC", + code="blobs-exist", + ) + + with TemporaryDirectory() as tempdir: + # Save files in a temporary directory. Use the uploaded filename + # extensions to identify files, but ignore the stems and generate our own. + files_to_move = [] # list[Path] + tmpfile_stem = Path(tempdir) / dest_stem + for upfile in uploaded_files: + uploaded_filename = Path(upfile.name) # name supplied by request + uploaded_ext = "".join(uploaded_filename.suffixes) + # Ignore json files, which are deprecated. Remove this when purple no + # longer tries to send them. + if uploaded_ext == ".json": + continue + tempfile_path = tmpfile_stem.with_suffix(uploaded_ext) + with tempfile_path.open("wb") as dest: + for chunk in upfile.chunks(): + dest.write(chunk) + os.utime(tempfile_path, (mtimestamp, mtimestamp)) + files_to_move.append(tempfile_path) + # copy files to final location, removing any existing ones first if the + # remove flag was set + if replace: + for possible_existing_file in possible_rfc_files: + possible_existing_file.unlink(missing_ok=True) + for possible_existing_blob in possible_rfc_blobs: + remove_from_storage( + blob_kind, possible_existing_blob, warn_if_missing=False + ) + for ftm in files_to_move: + with ftm.open("rb") as f: + store_file( + kind=blob_kind, + name=self.blob_destination(ftm), + file=f, + doc_name=rfc.name, + doc_rev=rfc.rev, # expect blank, but match whatever it is + mtime=mtime, + ) + destination = self.fs_destination(ftm) + if ( + settings.SERVER_MODE != "production" + and not destination.parent.exists() + ): + destination.parent.mkdir() + shutil.move(ftm, destination) + + # Trigger red precomputer + needs_updating = [rfc.rfc_number] + for rel in rfc.relateddocument_set.filter( + relationship_id__in=["obs", "updates"] + ): + needs_updating.append(rel.target.rfc_number) + trigger_red_precomputer_task.delay(rfc_number_list=sorted(needs_updating)) + # Trigger search index update + update_rfc_searchindex_task.delay(rfc.rfc_number) + # Trigger reference relations rebuild + rebuild_reference_relations_task.delay(doc_names=[rfc.name]) + # Build rfc json (json for related rfcs was updated in RfcPubNotificationView) + transaction.on_commit(partial(update_rfc_json_task.delay, [rfc.rfc_number])) + return Response(NotificationAckSerializer().data) + + +class RfcIndexView(APIView): + api_key_endpoint = "ietf.api.views_rpc" + + @extend_schema( + operation_id="refresh_rfc_index", + summary="Refresh rfc-index files", + description="Requests creation of various index files.", + responses={202: None}, + request=None, + ) + def post(self, request): + mark_rfcindex_as_dirty() + return Response(status=202) + + +class RpcQueueDataSerializer(serializers.Serializer): + data = serializers.JSONField() + + +class ProcessRpcQueueView(APIView): + api_key_endpoint = "ietf.api.views_rpc" + + @extend_schema( + operation_id="process_rpc_queue", + summary="Process the provided RPC queue", + description="Schedules parsing the provided queue to update documents with change dqueue data", + responses={202: None}, + request=RpcQueueDataSerializer, + ) + def post(self, request): + serializer = RpcQueueDataSerializer(data=request.data) + serializer.is_valid(raise_exception=True) + process_rpc_queue_task.delay(serializer.validated_data["data"]) + return Response(status=202) diff --git a/ietf/bin/.gitignore b/ietf/bin/.gitignore deleted file mode 100644 index c7013ced9df..00000000000 --- a/ietf/bin/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -/*.pyc -/settings_local.py diff --git a/ietf/bin/2016-05-25-collect-photos b/ietf/bin/2016-05-25-collect-photos deleted file mode 100755 index dedda767a8e..00000000000 --- a/ietf/bin/2016-05-25-collect-photos +++ /dev/null @@ -1,296 +0,0 @@ -#!/usr/bin/env python - -import os, re, sys, shutil, pathlib -from collections import namedtuple -from PIL import Image - -# boilerplate -basedir = os.path.abspath(os.path.join(os.path.dirname(__file__), "../..")) -sys.path = [ basedir ] + sys.path -os.environ["DJANGO_SETTINGS_MODULE"] = "ietf.settings" - -virtualenv_activation = os.path.join(basedir, "env", "bin", "activate_this.py") -if os.path.exists(virtualenv_activation): - execfile(virtualenv_activation, dict(__file__=virtualenv_activation)) - -import django -django.setup() - -from django.conf import settings -from django.utils.text import slugify - -import debug - -from ietf.group.models import Role, Person -from ietf.person.name import name_parts - -old_images_dir = '' -new_images_dir = settings.PHOTOS_DIR - -if not os.path.exists(new_images_dir): - print("New images directory does not exist: %s" % new_images_dir) - sys.exit(1) - -old_image_files = [] -for dir in settings.OLD_PHOTO_DIRS: - if not os.path.exists(dir): - print("Old images directory does not exist: %s" % dir) - sys.exit(1) - old_image_files += [ f for f in pathlib.Path(dir).iterdir() if f.is_file() and f.suffix.lower() in ['.jpg', '.jpeg', '.png'] ] - -photo = namedtuple('photo', ['path', 'name', 'ext', 'width', 'height', 'time', 'file']) - -old_images = [] -for f in old_image_files: - path = str(f) - img = Image.open(path) - old_images.append(photo(path, f.stem.decode('utf8'), f.suffix, img.size[0], img.size[1], f.stat().st_mtime, f)) - -# Fix up some names: - -def fix_missing_surnames(images): - replacement = { - "alissa": "alissa-cooper", - "alissa1": "alissa-cooper", - "andrei": "andrei-robachevsky", - "bernard": "bernard-aboba", - "danny": "danny-mcpherson", - "danny1": "danny-mcpherson", - "dthaler": "dave-thaler", - "eliot-mug": "eliot-lear", - "erik.nordmark-300": "erik-nordmark", - "hannes": "hannes-tschofenig", - "hildebrand": "joe-hildebrand", - "housley": "russ-housley", - "jariarkko": "jari-arkko", - "joel": "joel-jaeggli", - "joel1": "joel-jaeggli", - "joel2": "joel-jaeggli", - "jon": "jon-peterson", - "kessens": "david-kessens", - "klensin": "john-klensin", - "lars": "lars-eggert", - "lars1": "lars-eggert", - "marc_blanchet": "marc-blanchet", - "marcelo": "marcelo-bagnulo", - "olaf": "olaf-kolkman", - "olaf1": "olaf-kolkman", - "ross": "ross-callon", - "spencer": "spencer-dawkins", - "spencer1": "spencer-dawkins", - "vijay": "vijay-gurbani", - "xing": "xing-li", - } - - for i in range(len(images)): - img = images[i] - name = re.sub('-[0-9]+x[0-9]+', '', img.name) - if '/iab/' in img.path and name in replacement: - name = replacement[name] - images[i] = photo(img.path, name, img.ext, img.width, img.height, img.time, img.file) - - -fix_missing_surnames(old_images) - -interesting_persons = set(Person.objects.all()) - -name_alias = { - u"andy": [u"andrew", ], - u"ben": [u"benjamin", ], - u"bill": [u"william", ], - u"bob": [u"robert", ], - u"chris": [u"christopher", u"christian"], - u"dan": [u"daniel", ], - u"dave": [u"david", ], - u"dick": [u"richard", ], - u"fred": [u"alfred", ], - u"geoff": [u"geoffrey", ], - u"jake": [u"jacob", ], - u"jerry": [u"gerald", ], - u"jim": [u"james", ], - u"joe": [u"joseph", ], - u"jon": [u"jonathan", ], - u"mike": [u"michael", ], - u"ned": [u"edward", ], - u"pete": [u"peter", ], - u"ron": [u"ronald", ], - u"russ": [u"russel", ], - u"steve": [u"stephen", ], - u"ted": [u"edward", ], - u"terry": [u"terence", ], - u"tom": [u"thomas", ], - u"wes": [u"wesley", ], - u"will": [u"william", ], - - u"beth": [u"elizabeth", ], - u"liz": [u"elizabeth", ], - u"lynn": [u"carolyn", ], - u"pat": [u"patricia", u"patrick", ], - u"sue": [u"susan", ], -} -# Add lookups from long to short, from the initial set -for key,value in name_alias.items(): - for item in value: - if item in name_alias: - name_alias[item] += [ key ]; - else: - name_alias[item] = [ key ]; - -exceptions = { -'Aboba' : 'aboba-bernard', -'Bernardos' : 'cano-carlos', -'Bormann' : 'bormann-carsten', -'Hinden' : 'hinden-bob', -'Hutton' : 'hutton-andy', -'Narten' : 'narten-thomas', # but there's no picture of him -'O\'Donoghue' : 'odonoghue-karen', -'Przygienda' : 'przygienda-antoni', -'Salowey' : 'salowey-joe', -'Gunter Van de Velde' : 'vandevelde-gunter', -'Eric Vyncke' : 'vynke-eric', -'Zuniga' : 'zuniga-carlos-juan', -'Zhen Cao' : 'zhen-cao', -'Jamal Hadi Salim': 'hadi-salim-jamal', -} - -# Manually copied Bo Burman and Thubert Pascal from wg/photos/ -# Manually copied Victor Pascual (main image, not thumb) from wg/ -# Manually copied Eric Vync?ke (main image, not thumb) from wg/photos/ -# Manually copied Danial King (main image, not thumb) from wg/photos/ -# Manually copied the thumb (not labelled as such) for Tianran Zhou as both the main and thumb image from wg/photos/ - -processed_files = [] - -for person in sorted(list(interesting_persons),key=lambda x:x.last_name()+x.ascii): - substr_pattern = None - for exception in exceptions: - if exception in person.ascii: - substr_pattern = exceptions[exception] - break - if not person.ascii.strip(): - print(" Setting person.ascii for %s" % person.name) - person.ascii = person.name.encode('ascii', errors='replace').decode('ascii') - - _, first, _, last, _ = person.ascii_parts() - first = first.lower() - last = last. lower() - if not substr_pattern: - substr_pattern = slugify("%s %s" % (last, first)) - - if first in ['', '<>'] or last in ['', '<>']: - continue - - #debug.show('1, substr_pattern') - - candidates = [x for x in old_images if x.name.lower().startswith(substr_pattern)] - # Also check the reverse the name order (necessary for Deng Hui, for instance) - substr_pattern = slugify("%s %s" % (first, last)) - #debug.show('2, substr_pattern') - prev_len = len(candidates) - candidates += [x for x in old_images if x.name.lower().startswith(substr_pattern)] - if prev_len < len(candidates) : - print(" Found match with '%s %s' for '%s %s'" % (last, first, first, last, )) - # If no joy, try a short name - if first in name_alias: - prev_len = len(candidates) - for alias in name_alias[first]: - substr_pattern = slugify("%s %s" % (last, alias)) - #debug.show('3, substr_pattern') - candidates += [x for x in old_images if x.name.lower().startswith(substr_pattern)] - if prev_len < len(candidates): - print(" Found match with '%s %s' for '%s %s'" % (alias, last, first, last, )) - - -# # If still no joy, try with Person.plain_name() (necessary for Donald Eastlake) -# if not candidates: -# prefix, first, middle, last, suffix = person.name_parts() -# name_parts = person.plain_name().lower().split() -# -# substr_pattern = u'-'.join(name_parts[-1:]+name_parts[0:1]) -# candidates = [x for x in old_images if x.name.lower().startswith(substr_pattern)] -# # If no joy, try a short name -# if not candidates and first in name_alias: -# prev_len = len(candidates) -# for alias in name_alias[first]: -# substr_pattern = u'-'.join(name_parts[-1:]+[alias]) -# candidates += [x for x in old_images if x.name.lower().startswith(substr_pattern)] -# if prev_len < len(candidates) : -# print(" Used '%s %s' instead of '%s %s'" % (alias, last, first, last, )) - -# # Fixup for other exceptional cases -# if person.ascii=="David Oran": -# candidates = ['oran-dave-th.jpg','oran-david.jpg'] -# -# if person.ascii=="Susan Hares": -# candidates = ['hares-sue-th.jpg','hares-susan.JPG'] -# -# if person.ascii=="Mahesh Jethanandani": -# candidates = ['Mahesh-Jethanandani-th.jpg','Jethanandani-Mahesh.jpg'] - - processed_files += [ c.path for c in candidates ] - - # We now have a list of candidate photos. - # * Consider anything less than 200x200 a thumbnail - # * For the full photo, sort by size (width) and time - # * For the thumbnail: - # - first look for a square photo less than 200x200 - # - if none found, then for the first in the sorted list less than 200x200 - # - if none found, then the smallest photo - if candidates: - candidates.sort(key=lambda x: "%04d-%d" % (x.width, x.time)) - iesg_cand = [ c for c in candidates if '/iesg/' in c.path ] - iab_cand = [ c for c in candidates if '/iab/' in c.path ] - if iesg_cand: - full = iesg_cand[-1] - thumb = iesg_cand[-1] - elif iab_cand: - full = iab_cand[-1] - thumb = iab_cand[0] - else: - full = candidates[-1] - thumbs = [ c for c in candidates if c.width==c.height and c.width <= 200 ] - if not thumbs: - thumbs = [ c for c in candidates if c.width==c.height ] - if not thumbs: - thumbs = [ c for c in candidates if c.width <= 200 ] - if not thumbs: - thumbs = candidates[:1] - thumb = thumbs[-1] - candidates = [ thumb, full ] - - # At this point we either have no candidates or two. If two, the first will be the thumb - - def copy(old, new): - if not os.path.exists(new): - print("Copying "+old+" to "+new) - shutil.copy(old, new) - shutil.copystat(old, new) - - assert(len(candidates) in [0,2]) - if len(candidates)==2: - thumb, full = candidates - - new_name = person.photo_name(thumb=False)+full.ext.lower() - new_thumb_name = person.photo_name(thumb=True)+thumb.ext.lower() - - copy( full.path, os.path.join(new_images_dir,new_name) ) - - # - copy( thumb.path, os.path.join(new_images_dir,new_thumb_name) ) - - -print("") -not_processed = 0 -for file in old_image_files: - if ( file.is_file() - and not file.suffix.lower() in ['.txt', '.lck', '.html',] - and not file.name.startswith('index.') - and not file.name.startswith('milestoneupdate') - and not file.name.startswith('nopicture') - and not file.name.startswith('robots.txt') - ): - if not str(file).decode('utf8') in processed_files: - not_processed += 1 - print(u"Not processed: "+str(file).decode('utf8')) -print("") -print("Not processed: %s files" % not_processed) diff --git a/ietf/bin/aliases-from-json.py b/ietf/bin/aliases-from-json.py new file mode 100644 index 00000000000..0da5d1f8b97 --- /dev/null +++ b/ietf/bin/aliases-from-json.py @@ -0,0 +1,104 @@ +# Copyright The IETF Trust 2024, All Rights Reserved +# +# Uses only Python standard lib +# + +import argparse +import datetime +import json +import shutil +import stat +import sys + +from pathlib import Path +from tempfile import TemporaryDirectory + +# Default options +POSTCONFIRM_PATH = "/a/postconfirm/wrapper" +VDOMAIN = "virtual.ietf.org" + +# Map from domain label to dns domain +ADOMAINS = { + "ietf": "ietf.org", + "irtf": "irtf.org", + "iab": "iab.org", +} + + +def generate_files(records, adest, vdest, postconfirm, vdomain): + """Generate files from an iterable of records + + If adest or vdest exists as a file, it will be overwritten. If it is a directory, files + with the default names (draft-aliases and draft-virtual) will be created, but existing + files _will not_ be overwritten! + """ + with TemporaryDirectory() as tmpdir: + tmppath = Path(tmpdir) + apath = tmppath / "aliases" + vpath = tmppath / "virtual" + + with apath.open("w") as afile, vpath.open("w") as vfile: + date = datetime.datetime.now(datetime.UTC) + signature = f"# Generated by {Path(__file__).absolute()} at {date}\n" + afile.write(signature) + vfile.write(signature) + vfile.write(f"{vdomain} anything\n") + + for item in records: + alias = item["alias"] + domains = item["domains"] + address_list = item["addresses"] + filtername = f"xfilter-{alias}" + afile.write(f'{filtername + ":":64s} "|{postconfirm} filter expand-{alias} {vdomain}"\n') + for dom in domains: + vfile.write(f"{f'{alias}@{ADOMAINS[dom]}':64s} {filtername}\n") + vfile.write(f"{f'expand-{alias}@{vdomain}':64s} {', '.join(sorted(address_list))}\n") + + perms = stat.S_IWUSR | stat.S_IRUSR | stat.S_IRGRP | stat.S_IROTH + apath.chmod(perms) + vpath.chmod(perms) + shutil.move(apath, adest) + shutil.move(vpath, vdest) + + +def directory_path(val): + p = Path(val) + if p.is_dir(): + return p + else: + raise argparse.ArgumentTypeError(f"{p} is not a directory") + +if __name__ == "__main__": + parser = argparse.ArgumentParser( + description="Convert a JSON stream of draft alias definitions into alias / virtual alias files." + ) + parser.add_argument( + "--prefix", + required=True, + help="Prefix for output files. Files will be named -aliases and -virtual." + ) + parser.add_argument( + "--output-dir", + default="./", + type=directory_path, + help="Destination for output files.", + ) + parser.add_argument( + "--postconfirm", + default=POSTCONFIRM_PATH, + help=f"Full path to postconfirm executable (defaults to {POSTCONFIRM_PATH}", + ) + parser.add_argument( + "--vdomain", + default=VDOMAIN, + help=f"Virtual domain (defaults to {VDOMAIN}_", + ) + args = parser.parse_args() + data = json.load(sys.stdin) + generate_files( + data["aliases"], + adest=args.output_dir / f"{args.prefix}-aliases", + vdest=args.output_dir / f"{args.prefix}-virtual", + postconfirm=args.postconfirm, + vdomain=args.vdomain, + ) diff --git a/ietf/bin/announce-header-change b/ietf/bin/announce-header-change deleted file mode 100755 index 256324e31a8..00000000000 --- a/ietf/bin/announce-header-change +++ /dev/null @@ -1,48 +0,0 @@ -#!/usr/bin/env python - -import sys, os, sys -import datetime - -# boilerplate -basedir = os.path.abspath(os.path.join(os.path.dirname(__file__), "../..")) -sys.path = [ basedir ] + sys.path -os.environ["DJANGO_SETTINGS_MODULE"] = "ietf.settings" - -virtualenv_activation = os.path.join(basedir, "env", "bin", "activate_this.py") -if os.path.exists(virtualenv_activation): - execfile(virtualenv_activation, dict(__file__=virtualenv_activation)) - -import django -django.setup() - -from django.core import management -from django.template.loader import render_to_string - -from ietf import settings -from ietf.utils.mail import send_mail_preformatted -from ietf.utils.mail import send_mail - -target_date=datetime.date(year=2014,month=1,day=24) - -send_mail(request = None, - to = "IETF-Announce ", - frm = "The IESG ", - subject = "Upcoming change to announcement email header fields (using old header)", - template = "utils/header_change_content.txt", - context = dict(oldornew='old', target_date=target_date), - extra = {'Reply-To' : 'ietf@ietf.org', - 'Sender' : '', - } - ) - -send_mail(request = None, - to = "IETF-Announce:;", - frm = "The IESG ", - subject = "Upcoming change to announcement email header fields (using new header)", - template = "utils/header_change_content.txt", - context = dict(oldornew='new', target_date=target_date), - extra = {'Reply-To' : 'IETF Discussion List ', - 'Sender' : '', - }, - bcc = '', - ) diff --git a/ietf/bin/create-break-sessions b/ietf/bin/create-break-sessions deleted file mode 100755 index 52ce044d8c8..00000000000 --- a/ietf/bin/create-break-sessions +++ /dev/null @@ -1,43 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- -# -*- Python -*- -# - -import os, sys - -basedir = os.path.abspath(os.path.join(os.path.dirname(__file__), "../..")) -sys.path = [ basedir ] + sys.path -os.environ["DJANGO_SETTINGS_MODULE"] = "ietf.settings" - -virtualenv_activation = os.path.join(basedir, "env", "bin", "activate_this.py") -if os.path.exists(virtualenv_activation): - execfile(virtualenv_activation, dict(__file__=virtualenv_activation)) - -import django -django.setup() - -from ietf.group.models import Group -from ietf.person.models import Person -from ietf.name.models import SessionStatusName -from ietf.meeting.models import Meeting, Session, ScheduledSession as ScheduleTimeslotSSessionAssignment - -secretariat = Group.objects.get(acronym='secretariat') -system = Person.objects.get(id=1, name='(System)') -scheduled = SessionStatusName.objects.get(slug='sched') - -for meeting in Meeting.objects.filter(type="ietf").order_by("date"): - print "Checking %s schedules ..." % meeting - brk, __ = Session.objects.get_or_create(meeting=meeting, group=secretariat, requested_by=system, status=scheduled, name='Break', type_id='break',) - reg, __ = Session.objects.get_or_create(meeting=meeting, group=secretariat, requested_by=system, status=scheduled, name='Registration', type_id='reg',) - - for schedule in meeting.schedule_set.all(): - print " Checking for missing Break and Reg sessions in %s" % schedule - for timeslot in meeting.timeslot_set.all(): - if timeslot.type_id == 'break' and not (schedule.base and SchedTimeSessAssignment.objects.filter(timeslot=timeslot, session=brk, schedule=schedule.base).exists()): - assignment, created = SchedTimeSessAssignment.objects.get_or_create(timeslot=timeslot, session=brk, schedule=schedule) - if created: - print " Added %s break assignment" % timeslot - if timeslot.type_id == 'reg' and not (schedule.base and SchedTimeSessAssignment.objects.filter(timeslot=timeslot, session=reg, schedule=schedule.base).exists()): - assignment, created = SchedTimeSessAssignment.objects.get_or_create(timeslot=timeslot, session=reg, schedule=schedule) - if created: - print " Added %s registration assignment" % timeslot diff --git a/ietf/bin/create-charter-newrevisiondocevents b/ietf/bin/create-charter-newrevisiondocevents deleted file mode 100755 index c7ce9c5220d..00000000000 --- a/ietf/bin/create-charter-newrevisiondocevents +++ /dev/null @@ -1,72 +0,0 @@ -#!/usr/bin/env python - -import os -import sys - -version = "0.10" -program = os.path.basename(sys.argv[0]) -progdir = os.path.dirname(sys.argv[0]) - -# boilerplate -basedir = os.path.abspath(os.path.join(os.path.dirname(__file__), "../..")) -sys.path = [ basedir ] + sys.path -os.environ["DJANGO_SETTINGS_MODULE"] = "ietf.settings" - -virtualenv_activation = os.path.join(basedir, "env", "bin", "activate_this.py") -if os.path.exists(virtualenv_activation): - execfile(virtualenv_activation, dict(__file__=virtualenv_activation)) - - -# ---------------------------------------------------------------------- -def note(string): - sys.stdout.write("%s\n" % (string)) - -# ---------------------------------------------------------------------- -def warn(string): - sys.stderr.write(" * %s\n" % (string)) - -# ------------------------------------------------------------------------------ - -import re -from datetime import datetime as Datetime - -import django -django.setup() - -from django.conf import settings - -from ietf.utils.path import path as Path -from ietf.doc.models import Document, NewRevisionDocEvent -from ietf.person.models import Person - -system_entity = Person.objects.get(name="(System)") - -charterdir = Path(settings.CHARTER_PATH) -for file in charterdir.files("charter-ietf-*.txt"): - fname = file.name - ftime = Datetime.fromtimestamp(file.mtime) - match = re.search("^(?P[a-z0-9-]+)-(?P\d\d-\d\d)\.txt$", fname) - if match: - name = match.group("name") - rev = match.group("rev") - else: - match = re.search("^(?P[a-z0-9-]+)-(?P\d\d)\.txt$", fname) - if match: - name = match.group("name") - rev = match.group("rev") - else: - warn("Failed extracting revision from filename: '%s'" % fname) - try: - doc = Document.objects.get(type="charter", name=name) - try: - event = NewRevisionDocEvent.objects.get(doc=doc, type='new_revision', rev=rev) - note(".") - except NewRevisionDocEvent.MultipleObjectsReturned, e: - warn("Multiple NewRevisionDocEvent exists for '%s'" % fname) - except NewRevisionDocEvent.DoesNotExist: - event = NewRevisionDocEvent(doc=doc, type='new_revision', rev=rev, by=system_entity, time=ftime, desc="") - event.save() - note("Created new NewRevisionDocEvent for %s-%s" % (name, rev)) - except Document.DoesNotExist: - warn("Document not found: '%s'; no NewRevisionDocEvent created for '%s'" % (name, fname)) - diff --git a/ietf/bin/dump-draft-info b/ietf/bin/dump-draft-info deleted file mode 100755 index 3ac2e4a58a4..00000000000 --- a/ietf/bin/dump-draft-info +++ /dev/null @@ -1,41 +0,0 @@ -#!/usr/bin/env python - -import os -import sys - -version = "0.10" -program = os.path.basename(sys.argv[0]) -progdir = os.path.dirname(sys.argv[0]) - -# boilerplate -basedir = os.path.abspath(os.path.join(os.path.dirname(__file__), "../..")) -sys.path = [ basedir ] + sys.path -os.environ["DJANGO_SETTINGS_MODULE"] = "ietf.settings" - -virtualenv_activation = os.path.join(basedir, "env", "bin", "activate_this.py") -if os.path.exists(virtualenv_activation): - execfile(virtualenv_activation, dict(__file__=virtualenv_activation)) - -import django -django.setup() - -from django.template import Template, Context - -from ietf.doc.models import Document -from ietf.person.models import Person - -drafts = Document.objects.filter(type="draft") - -ads = {} -for p in Person.objects.filter(ad_document_set__type="draft").distinct(): - ads[p.id] = p.role_email("ad") - -for d in drafts: - d.ad_email = ads.get(d.ad_id) - -templ_text = """{% for draft in drafts %}{% if draft.notify or draft.ad_email %}{{ draft.name }}{% if draft.notify %} docnotify='{{ draft.notify|cut:"<"|cut:">" }}'{% endif %}{% if draft.ad_email %} docsponsor='{{ draft.ad_email }}'{% endif %} -{% endif %}{% endfor %}""" -template = Template(templ_text) -context = Context({ 'drafts':drafts }) - -print template.render(context).encode('utf-8') diff --git a/ietf/bin/email-sync-discrepancies b/ietf/bin/email-sync-discrepancies deleted file mode 100755 index 3593fd126f2..00000000000 --- a/ietf/bin/email-sync-discrepancies +++ /dev/null @@ -1,37 +0,0 @@ -#!/usr/bin/env python - -import sys, os, sys -import syslog - -# boilerplate -basedir = os.path.abspath(os.path.join(os.path.dirname(__file__), "../..")) -sys.path = [ basedir ] + sys.path -os.environ["DJANGO_SETTINGS_MODULE"] = "ietf.settings" - -virtualenv_activation = os.path.join(basedir, "env", "bin", "activate_this.py") -if os.path.exists(virtualenv_activation): - execfile(virtualenv_activation, dict(__file__=virtualenv_activation)) - -from optparse import OptionParser - -parser = OptionParser() -parser.add_option("-t", "--to", dest="to", - help="Email address to send report to", metavar="EMAIL") - -options, args = parser.parse_args() - -syslog.openlog(os.path.basename(__file__), syslog.LOG_PID, syslog.LOG_USER) - -import django -django.setup() - -from ietf.sync.mails import email_discrepancies - -receivers = ["iesg-secretary@ietf.org"] - -if options.to: - receivers = [options.to] - -email_discrepancies(receivers) - -syslog.syslog("Emailed sync discrepancies to %s" % receivers) diff --git a/ietf/bin/expire-ids b/ietf/bin/expire-ids index a23423d3b1a..bb0b94ee61b 100755 --- a/ietf/bin/expire-ids +++ b/ietf/bin/expire-ids @@ -13,10 +13,6 @@ basedir = os.path.abspath(os.path.join(os.path.dirname(__file__), "../..")) sys.path = [ basedir ] + sys.path os.environ["DJANGO_SETTINGS_MODULE"] = "ietf.settings" -virtualenv_activation = os.path.join(basedir, "env", "bin", "activate_this.py") -if os.path.exists(virtualenv_activation): - execfile(virtualenv_activation, dict(__file__=virtualenv_activation)) - syslog.openlog(os.path.basename(__file__), syslog.LOG_PID, syslog.LOG_USER) import django @@ -27,6 +23,7 @@ django.setup() from ietf.utils.log import logger try: + from ietf.utils.timezone import datetime_today from ietf.doc.expire import ( in_draft_expire_freeze, get_expired_drafts, expirable_drafts, send_expire_notice_for_draft, expire_draft, clean_up_draft_files ) from ietf.doc.models import Document @@ -42,7 +39,7 @@ try: # the purpose of double-checking that a document is still expirable when it is actually # being marked as expired. if (expirable_drafts(Document.objects.filter(pk=doc.pk)).exists() - and doc.expires < datetime.datetime.today() + datetime.timedelta(1)): + and doc.expires < datetime_today() + datetime.timedelta(1)): send_expire_notice_for_draft(doc) expire_draft(doc) syslog.syslog(" Expired draft %s-%s" % (doc.name, doc.rev)) diff --git a/ietf/bin/expire-last-calls b/ietf/bin/expire-last-calls deleted file mode 100755 index 83b565e1924..00000000000 --- a/ietf/bin/expire-last-calls +++ /dev/null @@ -1,34 +0,0 @@ -#!/usr/bin/env python - -# This script requires that the proper virtual python environment has been -# invoked before start - -import os -import sys -import syslog - -# boilerplate -basedir = os.path.abspath(os.path.join(os.path.dirname(__file__), "../..")) -sys.path = [ basedir ] + sys.path -os.environ["DJANGO_SETTINGS_MODULE"] = "ietf.settings" - -virtualenv_activation = os.path.join(basedir, "env", "bin", "activate_this.py") -if os.path.exists(virtualenv_activation): - execfile(virtualenv_activation, dict(__file__=virtualenv_activation)) - -syslog.openlog(os.path.basename(__file__), syslog.LOG_PID, syslog.LOG_USER) - -import django -django.setup() - -# ---------------------------------------------------------------------- - -from ietf.doc.lastcall import get_expired_last_calls, expire_last_call - -drafts = get_expired_last_calls() -for doc in drafts: - try: - expire_last_call(doc) - syslog.syslog("Expired last call for %s (id=%s)" % (doc.file_tag(), doc.pk)) - except Exception as e: - syslog.syslog(syslog.LOG_ERR, "ERROR: Failed to expire last call for %s (id=%s)" % (doc.file_tag(), doc.pk)) diff --git a/ietf/bin/expire-submissions b/ietf/bin/expire-submissions index 22db38322d8..113a53ddfa0 100755 --- a/ietf/bin/expire-submissions +++ b/ietf/bin/expire-submissions @@ -8,10 +8,6 @@ basedir = os.path.abspath(os.path.join(os.path.dirname(__file__), "../..")) sys.path = [ basedir ] + sys.path os.environ["DJANGO_SETTINGS_MODULE"] = "ietf.settings" -virtualenv_activation = os.path.join(basedir, "env", "bin", "activate_this.py") -if os.path.exists(virtualenv_activation): - execfile(virtualenv_activation, dict(__file__=virtualenv_activation)) - syslog.openlog(os.path.basename(__file__), syslog.LOG_PID, syslog.LOG_USER) import django diff --git a/ietf/bin/find-submission-confirmation-email-in-postfix-log b/ietf/bin/find-submission-confirmation-email-in-postfix-log deleted file mode 100755 index 6bf41574a10..00000000000 --- a/ietf/bin/find-submission-confirmation-email-in-postfix-log +++ /dev/null @@ -1,106 +0,0 @@ -#!/usr/bin/env python - -import io -import os -import sys - -version = "0.10" -program = os.path.basename(sys.argv[0]) -progdir = os.path.dirname(sys.argv[0]) - -# boilerplate -basedir = os.path.abspath(os.path.join(os.path.dirname(__file__), "../..")) -sys.path = [ basedir ] + sys.path -os.environ["DJANGO_SETTINGS_MODULE"] = "ietf.settings" - -virtualenv_activation = os.path.join(basedir, "env", "bin", "activate_this.py") -if os.path.exists(virtualenv_activation): - execfile(virtualenv_activation, dict(__file__=virtualenv_activation)) - -# ---------------------------------------------------------------------- -def note(string): - sys.stdout.write("%s\n" % (string)) - -# ---------------------------------------------------------------------- -def warn(string): - sys.stderr.write(" * %s\n" % (string)) - -# ------------------------------------------------------------------------------ - -import re -from datetime import datetime as Datetime -import time -import warnings -warnings.filterwarnings('ignore', message='the sets module is deprecated', append=True) - -import django -django.setup() - -from django.conf import settings - -from ietf.utils.path import path as Path - -from ietf.submit.models import Submission -from ietf.doc.models import Document - - - -args = sys.argv[1:] -if len(args) < 3: - warn("Expected '$ %s DRAFTNAME USER.LOG POSTFIX.LOG', but found no arguments -- exiting" % program) - sys.exit(1) - -draft = args[0] -if re.search("\.txt$", draft): - draft = draft[:-4] -if re.search("-\d\d$", draft): - draft = draft[:-3] - -if len(args) == 1: - logfiles = [ arg[1] ] -else: - logfiles = args[1:] - -from_email = settings.IDSUBMIT_FROM_EMAIL -if "<" in from_email: - from_email = from_email.split("<")[1].split(">")[0] - -submission = Submission.objects.filter(name=draft).latest('submission_date') -document = Document.objects.get(name=draft) -emails = [ author.email.address for author in document.documentauthor_set.all() if author.email ] - -timestrings = [] -for file in [ Path(settings.INTERNET_DRAFT_PATH) / ("%s-%s.txt"%(draft, submission.rev)), - Path(settings.IDSUBMIT_STAGING_PATH) / ("%s-%s.txt"%(draft, submission.rev)) ]: - if os.path.exists(file): - upload_time = time.localtime(file.mtime) - ts = time.strftime("%b %d %H:%M", upload_time) - timestrings += [ ts ] - timestrings += [ ts[:-1] + chr(((ord(ts[-1])-ord('0')+1)%10)+ord('0')) ] - print "Looking for mail log lines timestamped %s, also checking %s ..." % (timestrings[0], timestrings[1]) - -for log in logfiles: - print "\n Checking %s ...\n" % log - if log.endswith('.gz'): - import gzip - logfile = gzip.open(log) - else: - logfile = io.open(log) - queue_ids = [] - for line in logfile: - if from_email in line and "Confirmation for Auto-Post of I-D "+draft in line: - ts = line[:12] - timestrings += [ ts ] - print "Found a mention of %s, adding timestamp %s: \n %s" % (draft, ts, line) - for ts in timestrings: - if line.startswith(ts): - if from_email in line: - for to_email in emails: - if to_email in line: - sys.stdout.write(line) - if "queued_as:" in line: - queue_ids += [ line.split("queued_as:")[1].split(",")[0] ] - elif queue_ids: - for qi in queue_ids: - if qi in line: - sys.stdout.write(line) diff --git a/ietf/bin/iana-changes-updates b/ietf/bin/iana-changes-updates index 817f7e53345..b0ea6712e7e 100755 --- a/ietf/bin/iana-changes-updates +++ b/ietf/bin/iana-changes-updates @@ -18,6 +18,7 @@ django.setup() from django.conf import settings from optparse import OptionParser +from zoneinfo import ZoneInfo parser = OptionParser() parser.add_option("-f", "--from", dest="start", @@ -38,13 +39,16 @@ CLOCK_SKEW_COMPENSATION = 5 # seconds MAX_INTERVAL_ACCEPTED_BY_IANA = datetime.timedelta(hours=23) +local_tzinfo = ZoneInfo(settings.TIME_ZONE) start = datetime.datetime.now() - datetime.timedelta(hours=23) + datetime.timedelta(seconds=CLOCK_SKEW_COMPENSATION) if options.start: start = datetime.datetime.strptime(options.start, "%Y-%m-%d %H:%M:%S") +start = start.replace(tzinfo=local_tzinfo).astimezone(datetime.timezone.utc) end = start + datetime.timedelta(hours=23) if options.end: - end = datetime.datetime.strptime(options.end, "%Y-%m-%d %H:%M:%S") + end = datetime.datetime.strptime(options.end, "%Y-%m-%d %H:%M:%S").replace(tzinfo=local_tzinfo) +end = end.astimezone(datetime.timezone.utc) syslog.openlog(os.path.basename(__file__), syslog.LOG_PID, syslog.LOG_USER) @@ -52,7 +56,13 @@ syslog.openlog(os.path.basename(__file__), syslog.LOG_PID, syslog.LOG_USER) from ietf.sync.iana import fetch_changes_json, parse_changes_json, update_history_with_changes -syslog.syslog("Updating history log with new changes from IANA from %s, period %s - %s" % (settings.IANA_SYNC_CHANGES_URL, start, end)) +syslog.syslog( + "Updating history log with new changes from IANA from %s, period %s - %s" % ( + settings.IANA_SYNC_CHANGES_URL, + start.astimezone(local_tzinfo), + end.astimezone(local_tzinfo), + ) +) t = start while t < end: diff --git a/ietf/bin/iana-protocols-updates b/ietf/bin/iana-protocols-updates index 668ee54f911..bdbeef8c8ef 100755 --- a/ietf/bin/iana-protocols-updates +++ b/ietf/bin/iana-protocols-updates @@ -29,7 +29,7 @@ def chunks(l, n): syslog.syslog("Updating history log with new RFC entries from IANA protocols page %s" % settings.IANA_SYNC_PROTOCOLS_URL) # FIXME: this needs to be the date where this tool is first deployed -rfc_must_published_later_than = datetime.datetime(2012, 11, 26, 0, 0, 0) +rfc_must_published_later_than = datetime.datetime(2012, 11, 26, 0, 0, 0, tzinfo=datetime.timezone.utc) try: response = requests.get( diff --git a/ietf/bin/iana-review-email b/ietf/bin/iana-review-email index 5c7a7183b9c..27aee4015ec 100755 --- a/ietf/bin/iana-review-email +++ b/ietf/bin/iana-review-email @@ -8,10 +8,6 @@ basedir = os.path.abspath(os.path.join(os.path.dirname(__file__), "../..")) sys.path = [ basedir ] + sys.path os.environ["DJANGO_SETTINGS_MODULE"] = "ietf.settings" -virtualenv_activation = os.path.join(basedir, "env", "bin", "activate_this.py") -if os.path.exists(virtualenv_activation): - execfile(virtualenv_activation, dict(__file__=virtualenv_activation)) - syslog.openlog(os.path.basename(__file__), syslog.LOG_PID, syslog.LOG_USER) import django diff --git a/ietf/bin/interim_minutes_reminder b/ietf/bin/interim_minutes_reminder deleted file mode 100755 index 7f2f84f739e..00000000000 --- a/ietf/bin/interim_minutes_reminder +++ /dev/null @@ -1,27 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- -# -*- Python -*- -# -''' -This script calls ietf.meeting.helpers.check_interim_minutes() which sends -a reminder email for interim meetings that occurred 10 days ago but still -don't have minutes. -''' - -# Set PYTHONPATH and load environment variables for standalone script ----------------- -import os, sys -basedir = os.path.abspath(os.path.join(os.path.dirname(__file__), "../..")) -sys.path = [ basedir ] + sys.path -os.environ["DJANGO_SETTINGS_MODULE"] = "ietf.settings" - -virtualenv_activation = os.path.join(basedir, "env", "bin", "activate_this.py") -if os.path.exists(virtualenv_activation): - execfile(virtualenv_activation, dict(__file__=virtualenv_activation)) - -import django -django.setup() -# ------------------------------------------------------------------------------------- - -from ietf.meeting.helpers import check_interim_minutes - -check_interim_minutes() diff --git a/ietf/bin/list-role-holder-emails b/ietf/bin/list-role-holder-emails deleted file mode 100755 index 6d6c1604640..00000000000 --- a/ietf/bin/list-role-holder-emails +++ /dev/null @@ -1,36 +0,0 @@ -#!/usr/bin/env python - - -import os, sys -import syslog - -# boilerplate -basedir = os.path.abspath(os.path.join(os.path.dirname(__file__), "../..")) -sys.path = [ basedir ] + sys.path -os.environ["DJANGO_SETTINGS_MODULE"] = "ietf.settings" - -virtualenv_activation = os.path.join(basedir, "env", "bin", "activate_this.py") -if os.path.exists(virtualenv_activation): - execfile(virtualenv_activation, dict(__file__=virtualenv_activation)) - -syslog.openlog(os.path.basename(__file__), syslog.LOG_PID, syslog.LOG_USER) - -import django -django.setup() - -from django.utils.encoding import force_str -from ietf.group.models import Role - -addresses = set() -for role in Role.objects.filter( - group__state__slug='active', - group__type__in=['ag','area','dir','iab','ietf','irtf','nomcom','rg','team','wg','rag']): - #sys.stderr.write(str(role)+'\n') - for e in role.person.email_set.all(): - if e.active and not e.address.startswith('unknown-email-'): - addresses.add(e.address) - -addresses = list(addresses) -addresses.sort() -for a in addresses: - print(force_str(a)) diff --git a/ietf/bin/mailman_listinfo.py b/ietf/bin/mailman_listinfo.py deleted file mode 100755 index f7e4cfe4c1b..00000000000 --- a/ietf/bin/mailman_listinfo.py +++ /dev/null @@ -1,50 +0,0 @@ -#!/usr/bin/python2.7 -# Copyright The IETF Trust 2022, All Rights Reserved -# Note the shebang. This specifically targets deployment on IETFA and intends to use its system python2.7. - -# This is an adaptor to pull information out of Mailman2 using its python libraries (which are only available for python2). -# It is NOT django code, and does not have access to django.conf.settings. - -import json -import sys - -from collections import defaultdict - -def main(): - - sys.path.append('/usr/lib/mailman') - - have_mailman = False - try: - from Mailman import Utils - from Mailman import MailList - from Mailman import MemberAdaptor - have_mailman = True - except ImportError: - pass - - - if not have_mailman: - sys.stderr.write("Could not import mailman modules -- skipping import of mailman list info") - sys.exit() - - names = list(Utils.list_names()) - - # need to emit dict of names, each name has an mlist, and each mlist has description, advertised, and members (calculated as below) - result = defaultdict(dict) - for name in names: - mlist = MailList.MailList(name, lock=False) - result[name] = dict() - result[name]['internal_name'] = mlist.internal_name() - result[name]['real_name'] = mlist.real_name - result[name]['description'] = mlist.description # Not attempting to change encoding - result[name]['advertised'] = mlist.advertised - result[name]['members'] = list() - if mlist.advertised: - members = mlist.getRegularMemberKeys() + mlist.getDigestMemberKeys() - members = set([ m for m in members if mlist.getDeliveryStatus(m) == MemberAdaptor.ENABLED ]) - result[name]['members'] = list(members) - json.dump(result, sys.stdout) - -if __name__ == "__main__": - main() diff --git a/ietf/bin/merge-person-records b/ietf/bin/merge-person-records deleted file mode 100755 index 155e5755f6b..00000000000 --- a/ietf/bin/merge-person-records +++ /dev/null @@ -1,65 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- -# -*- Python -*- -# -''' -This script merges two Person records into one. It determines which record is the target -based on most current User record (last_login) unless -f (force) option is used to -force SOURCE TARGET as specified on the command line. The order of operations is -important. We must complete all source.save() operations before moving the aliases to -the target, this is to avoid extra "Possible duplicate Person" emails going out, if the -Person is saved without an alias the Person.save() creates another one, which then -conflicts with the moved one. -''' - -# Set PYTHONPATH and load environment variables for standalone script ----------------- -import os, sys -basedir = os.path.abspath(os.path.join(os.path.dirname(__file__), "../..")) -sys.path = [ basedir ] + sys.path -os.environ["DJANGO_SETTINGS_MODULE"] = "ietf.settings" - -virtualenv_activation = os.path.join(basedir, "env", "bin", "activate_this.py") -if os.path.exists(virtualenv_activation): - execfile(virtualenv_activation, dict(__file__=virtualenv_activation)) - -import django -django.setup() -# ------------------------------------------------------------------------------------- - -import argparse -from django.contrib import admin -from ietf.person.models import Person -from ietf.person.utils import (merge_persons, send_merge_notification, handle_users, - determine_merge_order) - - -def main(): - parser = argparse.ArgumentParser() - parser.add_argument("source_id",type=int) - parser.add_argument("target_id",type=int) - parser.add_argument('-f','--force', help='force merge order',action='store_true') - parser.add_argument('-v','--verbose', help='verbose output',action='store_true') - args = parser.parse_args() - - source = Person.objects.get(pk=args.source_id) - target = Person.objects.get(pk=args.target_id) - - # set merge order - if not args.force: - source,target = determine_merge_order(source,target) - - # confirm - print "Merging person {}({}) to {}({})".format(source.ascii,source.pk,target.ascii,target.pk) - print handle_users(source,target,check_only=True) - response = raw_input('Ok to continue y/n? ') - if response.lower() != 'y': - sys.exit() - - # perform merge - success, changes = merge_persons(source, target, verbose=args.verbose) - - # send email notification - send_merge_notification(target,changes) - -if __name__ == "__main__": - main() diff --git a/ietf/bin/notify-expirations b/ietf/bin/notify-expirations index 0270c137659..fc2fd86a31b 100755 --- a/ietf/bin/notify-expirations +++ b/ietf/bin/notify-expirations @@ -7,10 +7,6 @@ basedir = os.path.abspath(os.path.join(os.path.dirname(__file__), "../..")) sys.path = [ basedir ] + sys.path os.environ["DJANGO_SETTINGS_MODULE"] = "ietf.settings" -virtualenv_activation = os.path.join(basedir, "env", "bin", "activate_this.py") -if os.path.exists(virtualenv_activation): - execfile(virtualenv_activation, dict(__file__=virtualenv_activation)) - import django django.setup() diff --git a/ietf/bin/pretty-xml-dump b/ietf/bin/pretty-xml-dump deleted file mode 100755 index 22abc08a649..00000000000 --- a/ietf/bin/pretty-xml-dump +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/sh -python manage.py dumpdata --format=xml "$@" | sed -e 's/<\/*object/\ - &/g' -e 's/')][1:])) - else: - retval.append(ParsedAuthor(a.strip(),None)) - - return retval - -def calculate_changes(tracker_persons,tracker_emails,names,emails): - adds = set() - deletes = set() - for email in emails: - if email and email!='none' and email not in ignore_addresses: - p = Person.objects.filter(email__address=email).first() - if p: - if not set(map(unicode.lower,p.email_set.values_list('address',flat=True))).intersection(tracker_emails): - adds.add(email) - else: - #person_name = names[emails.index(email)] - adds.add(email) - for person in tracker_persons: - if not set(map(unicode.lower,person.email_set.values_list('address',flat=True))).intersection(emails): - match = False - for index in [i for i,j in enumerate(emails) if j=='none' or not j]: - if names[index].split()[-1].lower()==person.last_name().lower(): - match = True - if not match: - deletes.add(person) - return adds, deletes - -def _main(): - - parser = argparse.ArgumentParser(description="Recalculate RFC documentauthor_set"+'\n\n'+__doc__, - formatter_class=argparse.RawDescriptionHelpFormatter,) - parser.add_argument('-v','--verbose',help="Show the action taken for each RFC",action='store_true') - parser.add_argument('--rfc',type=int, nargs='*',help="Only recalculate the given rfc numbers",dest='rfcnumberlist') - args = parser.parse_args() - - probable_email_match = set() - probable_duplicates = [] - - all_the_email = get_all_the_email() - author_names, author_emails = get_rfc_data() - - stats = { 'rfc not in tracker' :0, - 'same addresses' :0, - 'different addresses belonging to same people' :0, - 'same names, rfced emails do not match' :0, - 'rfced data is unusable' :0, - "data doesn't match but no changes found" :0, - 'changed authors' :0, } - - for rfc_num in args.rfcnumberlist or sorted(author_names.keys()): - - rfc = Document.objects.filter(docalias__name='rfc%s'%rfc_num).first() - - if not rfc: - if args.verbose: - show_verbose(rfc_num,'rfc not in tracker') - stats['rfc not in tracker'] += 1 - continue - - rfced_emails = set(author_emails[rfc_num]) - tracker_emails = set(map(unicode.lower,rfc.authors.values_list('address',flat=True))) - tracker_persons = set([x.person for x in rfc.authors.all()]) - matching_emails = get_matching_emails(all_the_email,rfced_emails) - rfced_persons = set([x.person for x in matching_emails]) - known_emails = set([e.l_address for e in matching_emails]) - unknown_emails = rfced_emails - known_emails - unknown_persons = tracker_persons-rfced_persons - - rfced_lastnames = sorted([n.split()[-1].lower() for n in author_names[rfc_num]]) - tracker_lastnames = sorted([p.last_name().lower() for p in tracker_persons]) - - if rfced_emails == tracker_emails: - if args.verbose: - show_verbose(rfc_num,'tracker and rfc editor have the same addresses') - stats['same addresses'] += 1 - continue - - if len(rfced_emails)==len(tracker_emails) and not 'none' in author_emails[rfc_num]: - if tracker_persons == rfced_persons: - if args.verbose: - show_verbose(rfc_num,'tracker and rfc editor have the different addresses belonging to same people') - stats['different addresses belonging to same people'] += 1 - continue - else: - if len(unknown_emails)==1 and len(tracker_persons-rfced_persons)==1: - p = list(tracker_persons-rfced_persons)[0] - probable_email_match.add(u"%s is probably %s (%s) : %s "%(list(unknown_emails)[0], p, p.pk, rfc_num)) - elif len(unknown_emails)==len(unknown_persons): - probable_email_match.add(u"%s are probably %s : %s"%(unknown_emails,[(p.ascii,p.pk) for p in unknown_persons],rfc_num)) - else: - probable_duplicates.append((tracker_persons^rfced_persons,rfc_num)) - - if tracker_lastnames == rfced_lastnames: - if args.verbose: - show_verbose(rfc_num,"emails don't match up, but person names appear to be the same") - stats[ 'same names, rfced emails do not match'] += 1 - continue - - use_rfc_data = bool(len(author_emails[rfc_num])==len(author_names[rfc_num])) - if not use_rfc_data: - if args.verbose: - print 'Ignoring rfc database for rfc%d'%rfc_num - stats[ 'rfced data is unusable'] += 1 - - if use_rfc_data: - adds, deletes = calculate_changes(tracker_persons,tracker_emails,author_names[rfc_num],author_emails[rfc_num]) - parsed_authors=get_parsed_authors(rfc_num) - parsed_adds, parsed_deletes = calculate_changes(tracker_persons,tracker_emails,[x.name for x in parsed_authors],[x.address for x in parsed_authors]) - - for e in adds.union(parsed_adds) if use_rfc_data else parsed_adds: - if not e or e in ignore_addresses: - continue - if not Person.objects.filter(email__address=e).exists(): - if e not in parsed_adds: - #print rfc_num,"Would add",e,"as",author_names[rfc_num][author_emails[rfc_num].index(e)],"(rfced database)" - print "(address='%s',name='%s'),"%(e,author_names[rfc_num][author_emails[rfc_num].index(e)]),"# (rfced %d)"%rfc_num - for p in Person.objects.filter(name__iendswith=author_names[rfc_num][author_emails[rfc_num].index(e)].split(' ')[-1]): - print "\t", p.pk, p.ascii - else: - name = [x.name for x in parsed_authors if x.address==e][0] - p = Person.objects.filter(name=name).first() - if p: - #print e,"is probably",p.pk,p - print "'%s': %d, # %s (%d)"%(e,p.pk,p.ascii,rfc_num) - - else: - p = Person.objects.filter(ascii=name).first() - if p: - print e,"is probably",p.pk,p - print "'%s': %d, # %s (%d)"%(e,p.pk,p.ascii,rfc_num) - else: - p = Person.objects.filter(ascii_short=name).first() - if p: - print e,"is probably",p.pk,p - print "'%s': %d, # %s (%d)"%(e,p.pk,p.ascii,rfc_num) - #print rfc_num,"Would add",e,"as",name,"(parsed)" - print "(address='%s',name='%s'),"%(e,name),"# (parsed %d)"%rfc_num - for p in Person.objects.filter(name__iendswith=name.split(' ')[-1]): - print "\t", p.pk, p.ascii - - if False: # This was a little useful, but the noise in the rfc_ed file keeps it from being completely useful - for p in deletes: - for n in author_names[rfc_num]: - if p.last_name().lower()==n.split()[-1].lower(): - email_candidate = author_emails[rfc_num][author_names[rfc_num].index(n)] - email_found = Email.objects.filter(address=email_candidate).first() - if email_found: - probable_duplicates.append((set([p,email_found.person]),rfc_num)) - else: - probable_email_match.add(u"%s is probably %s (%s) : %s"%(email_candidate, p, p.pk, rfc_num)) - - if args.verbose: - if use_rfc_data: - working_adds = parsed_adds - seen_people = set(Email.objects.get(address=e).person for e in parsed_adds) - for addr in adds: - person = Email.objects.get(address=addr).person - if person not in seen_people: - working_adds.add(addr) - seen_people.add(person) - working_deletes = deletes.union(parsed_deletes) - else: - working_adds = parsed_adds - working_deletes = parsed_deletes - # unique_adds = set() # TODO don't add different addresses for the same person from the two sources - if working_adds or working_deletes: - show_verbose(rfc_num,"Changing original list",tracker_persons,"by adding",working_adds," and deleting",working_deletes) - print "(",rfc_num,",",[e for e in working_adds],",",[p.pk for p in working_deletes],"), #",[p.ascii for p in working_deletes] - else: - stats["data doesn't match but no changes found"] += 1 - show_verbose(rfc_num,"Couldn't figure out what to change") - - if False: - #if tracker_persons: - #if any(['iab@' in e for e in adds]) or any(['iesg@' in e for e in adds]) or any(['IESG'==p.name for p in deletes]) or any(['IAB'==p.name for p in deletes]): - print rfc_num - print "tracker_persons",tracker_persons - print "author_names",author_names[rfc_num] - print "author_emails",author_emails[rfc_num] - print "Adds:", adds - print "Deletes:", deletes - - stats['changed authors'] += 1 - - if False: - debug.show('rfc_num') - debug.show('rfced_emails') - debug.show('tracker_emails') - debug.show('known_emails') - debug.show('unknown_emails') - debug.show('tracker_persons') - debug.show('rfced_persons') - debug.show('tracker_persons==rfced_persons') - debug.show('[p.id for p in tracker_persons]') - debug.show('[p.id for p in rfced_persons]') - exit() - - if True: - for p in sorted(list(probable_email_match)): - print p - if True: - print "Probable duplicate persons" - for d,r in sorted(probable_duplicates): - print [(p,p.pk) for p in d], r - else: - print len(probable_duplicates)," probable duplicate persons" - - print stats - -if __name__ == "__main__": - _main() - diff --git a/ietf/bin/redirect-dump b/ietf/bin/redirect-dump deleted file mode 100755 index ef35bbf0de9..00000000000 --- a/ietf/bin/redirect-dump +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/sh -# -# Copyright The IETF Trust 2007, All Rights Reserved -# -#python manage.py dumpdata --format=xml redirects | xmllint --format - -python manage.py dumpdata --format=xml redirects | sed -e 's/<\/*object/\ - &/g' -e 's/ {self.bucket}:{self.blob}" diff --git a/ietf/blobdb/replication.py b/ietf/blobdb/replication.py new file mode 100644 index 00000000000..d251d3b95c1 --- /dev/null +++ b/ietf/blobdb/replication.py @@ -0,0 +1,178 @@ +# Copyright The IETF Trust 2025, All Rights Reserved +import datetime +from dataclasses import dataclass +from io import BytesIO +from typing import Optional + +from django.conf import settings +from django.core.files import File +from django.core.files.storage import storages, InvalidStorageError +from django.db import connections + +from ietf.utils import log + +DEFAULT_SETTINGS = { + "ENABLED": False, + "DEST_STORAGE_PATTERN": "r2-{bucket}", + "INCLUDE_BUCKETS": (), # empty means include all + "EXCLUDE_BUCKETS": (), # empty means exclude none + "VERBOSE_LOGGING": False, +} + + +class SimpleMetadataFile(File): + def __init__(self, file, name=None): + super().__init__(file, name) + self.custom_metadata = {} + self.content_type = "" + + +def get_replication_settings(): + return DEFAULT_SETTINGS | getattr(settings, "BLOBDB_REPLICATION", {}) + + +def validate_replication_settings(): + replicator_settings = get_replication_settings() + # No extra settings allowed + unknown_settings = set(DEFAULT_SETTINGS.keys()) - set(replicator_settings.keys()) + if len(unknown_settings) > 0: + raise RuntimeError( + f"Unrecognized BLOBDB_REPLICATOR settings: {', '.join(str(unknown_settings))}" + ) + # destination storage pattern must be a string that includes {bucket} + pattern = replicator_settings["DEST_STORAGE_PATTERN"] + if not isinstance(pattern, str): + raise RuntimeError( + f"DEST_STORAGE_PATTERN must be a str, not {type(pattern).__name__}" + ) + if "{bucket}" not in pattern: + raise RuntimeError( + f"DEST_STORAGE_PATTERN must contain the substring '{{bucket}}' (found '{pattern}')" + ) + # include/exclude buckets must be list-like + include_buckets = replicator_settings["INCLUDE_BUCKETS"] + if not isinstance(include_buckets, (list, tuple, set)): + raise RuntimeError("INCLUDE_BUCKETS must be a list, tuple, or set") + exclude_buckets = replicator_settings["EXCLUDE_BUCKETS"] + if not isinstance(exclude_buckets, (list, tuple, set)): + raise RuntimeError("EXCLUDE_BUCKETS must be a list, tuple, or set") + # if we have explicit include_buckets, make sure the necessary storages exist + if len(include_buckets) > 0: + include_storages = {destination_storage_name_for(b) for b in include_buckets} + exclude_storages = {destination_storage_name_for(b) for b in exclude_buckets} + configured_storages = set(settings.STORAGES.keys()) + missing_storages = include_storages - exclude_storages - configured_storages + if len(missing_storages) > 0: + raise RuntimeError( + f"Replication requires unknown storage(s): {', '.join(missing_storages)}" + ) + + +def destination_storage_name_for(bucket: str): + pattern = get_replication_settings()["DEST_STORAGE_PATTERN"] + return pattern.format(bucket=bucket) + + +def destination_storage_for(bucket: str): + storage_name = destination_storage_name_for(bucket) + return storages[storage_name] + + +def replication_enabled(bucket: str): + replication_settings = get_replication_settings() + if not replication_settings["ENABLED"]: + return False + # Default is all buckets are included + included = ( + len(replication_settings["INCLUDE_BUCKETS"]) == 0 + or bucket in replication_settings["INCLUDE_BUCKETS"] + ) + # Default is no buckets are excluded + excluded = ( + len(replication_settings["EXCLUDE_BUCKETS"]) > 0 + and bucket in replication_settings["EXCLUDE_BUCKETS"] + ) + return included and not excluded + + +def verbose_logging_enabled(): + return bool(get_replication_settings()["VERBOSE_LOGGING"]) + + +@dataclass +class SqlBlob: + content: bytes + checksum: str + modified: datetime.datetime + mtime: Optional[datetime.datetime] + content_type: str + + +def fetch_blob_via_sql(bucket: str, name: str) -> Optional[SqlBlob]: + blobdb_connection = connections["blobdb"] + cursor = blobdb_connection.cursor() + cursor.execute( + """ + SELECT content, checksum, modified, mtime, content_type FROM blobdb_blob + WHERE bucket=%s AND name=%s LIMIT 1 + """, + [bucket, name], + ) + row = cursor.fetchone() + col_names = [col[0] for col in cursor.description] + return None if row is None else SqlBlob(**{ + col_name: row_val + for col_name, row_val in zip(col_names, row) + }) + + +def replicate_blob(bucket, name): + """Replicate a Blobdb blob to a Storage""" + if not replication_enabled(bucket): + if verbose_logging_enabled(): + log.log( + f"Not replicating {bucket}:{name} because replication is not enabled for {bucket}" + ) + return + + try: + destination_storage = destination_storage_for(bucket) + except InvalidStorageError as e: + log.log( + f"Failed to replicate {bucket}:{name} because destination storage for {bucket} is not configured" + ) + raise ReplicationError from e + + blob = fetch_blob_via_sql(bucket, name) + if blob is None: + if verbose_logging_enabled(): + log.log(f"Deleting {bucket}:{name} from replica") + try: + destination_storage.delete(name) + except Exception as e: + log.log(f"Failed to delete {bucket}:{name} from replica: {e}") + raise ReplicationError from e + else: + # Add metadata expected by the MetadataS3Storage + file_with_metadata = SimpleMetadataFile(file=BytesIO(blob.content)) + file_with_metadata.content_type = blob.content_type + file_with_metadata.custom_metadata = { + "sha384": blob.checksum, + "mtime": (blob.mtime or blob.modified).isoformat(), + } + if verbose_logging_enabled(): + log.log( + f"Saving {bucket}:{name} to replica (" + f"sha384: '{file_with_metadata.custom_metadata['sha384'][:16]}...', " + f"content_type: '{file_with_metadata.content_type}', " + f"mtime: '{file_with_metadata.custom_metadata['mtime']})" + ) + try: + destination_storage.save(name, file_with_metadata) + except Exception as e: + log.log(f"Failed to save {bucket}:{name} to replica: {e}") + raise ReplicationError from e + + +class ReplicationError(Exception): + pass diff --git a/ietf/blobdb/routers.py b/ietf/blobdb/routers.py new file mode 100644 index 00000000000..319c0fbc71a --- /dev/null +++ b/ietf/blobdb/routers.py @@ -0,0 +1,58 @@ +# Copyright The IETF Trust 2025, All Rights Reserved +from django.apps import apps + +from .apps import BlobdbConfig, get_blobdb + + +class BlobdbStorageRouter: + """Database router for the Blobdb""" + + _app_label = None + + @property + def app_label(self): + if self._app_label is None: + for app in apps.get_app_configs(): + if isinstance(app, BlobdbConfig): + self._app_label = app.label + break + if self._app_label is None: + raise RuntimeError( + f"{BlobdbConfig.name} is not present in the Django app registry" + ) + return self._app_label + + @property + def db(self): + return get_blobdb() + + def db_for_read(self, model, **hints): + """Suggest the database that should be used for read operations for objects of type model + + Returns None if there is no suggestion. + """ + if model._meta.app_label == self.app_label: + return self.db + return None # no suggestion + + def db_for_write(self, model, **hints): + """Suggest the database that should be used for write of objects of type model + + Returns None if there is no suggestion. + """ + if model._meta.app_label == self.app_label: + return self.db + return None # no suggestion + + def allow_migrate(self, db, app_label, model_name=None, **hints): + """Determine if the migration operation is allowed to run on the database with alias db + + Return True if the operation should run, False if it shouldn’t run, or + None if the router has no opinion. + """ + if self.db is None: + return None # no opinion, use the default db + is_our_app = app_label == self.app_label + is_our_db = db == self.db + if is_our_app or is_our_db: + return is_our_app and is_our_db diff --git a/ietf/blobdb/storage.py b/ietf/blobdb/storage.py new file mode 100644 index 00000000000..e304dabc5dd --- /dev/null +++ b/ietf/blobdb/storage.py @@ -0,0 +1,106 @@ +# Copyright The IETF Trust 2025-2026, All Rights Reserved +from typing import Optional + +from django.core.exceptions import SuspiciousFileOperation +from django.core.files.base import ContentFile +from django.core.files.storage import Storage +from django.db.models.functions import Length +from django.utils.deconstruct import deconstructible +from django.utils import timezone + +from ietf.utils.storage import MetadataFile +from .models import Blob +from .utils import queue_for_replication + + +class BlobFile(MetadataFile): + + def __init__(self, content, name=None, mtime=None, content_type=""): + super().__init__( + file=ContentFile(content), + name=name, + mtime=mtime, + content_type=content_type, + ) + + +@deconstructible +class BlobdbStorage(Storage): + + def __init__(self, bucket_name: Optional[str]=None): + if bucket_name is None: + raise ValueError("BlobdbStorage bucket_name must be specified") + self.bucket_name = bucket_name + + def get_queryset(self): + return Blob.objects.filter(bucket=self.bucket_name) + + def delete(self, name): + blob = self.get_queryset().filter(name=name).first() + if blob is not None: + blob.delete() + + def exists(self, name): + return self.get_queryset().filter(name=name).exists() + + def size(self, name): + sizes = ( + self.get_queryset() + .filter(name=name) + .annotate(object_size=Length("content")) + .values_list("object_size", flat=True) + ) + if len(sizes) == 0: + raise FileNotFoundError( + f"No object '{name}' exists in bucket '{self.bucket_name}'" + ) + return sizes[0] # unique constraint guarantees 0 or 1 entry + + def _open(self, name, mode="rb"): + try: + blob = self.get_queryset().get(name=name) + except Blob.DoesNotExist: + raise FileNotFoundError( + f"No object '{name}' exists in bucket '{self.bucket_name}'" + ) + return BlobFile( + content=blob.content, + name=blob.name, + mtime=blob.mtime or blob.modified, # fall back to modified time + content_type=blob.content_type, + ) + + def _save(self, name, content): + """Perform the save operation + + The storage API allows _save() to save to a different name than was requested. This method will + never do that, instead overwriting the existing blob. + """ + Blob.objects.update_or_create( + name=name, + bucket=self.bucket_name, + defaults={ + "content": content.read(), + "modified": timezone.now(), + "mtime": getattr(content, "mtime", None), + "content_type": getattr(content, "content_type", ""), + }, + ) + return name + + def get_available_name(self, name, max_length=None): + if max_length is not None and len(name) > max_length: + raise SuspiciousFileOperation( + f"BlobdbStorage only allows names up to {max_length}, but was" + f"asked to store the name '{name[:5]}...{name[-5:]} of length {len(name)}" + ) + return name # overwrite is permitted + + def force_replication(self, name: str): + """Force replication of a blob by name + + Be careful with this - replication includes replicating deletion of blobs, so + if you call it with a name that does not exist in blobdb, it will be removed + from R2 if it exists there! + """ + queue_for_replication(bucket=self.bucket_name, name=name) diff --git a/ietf/blobdb/tasks.py b/ietf/blobdb/tasks.py new file mode 100644 index 00000000000..538d4158304 --- /dev/null +++ b/ietf/blobdb/tasks.py @@ -0,0 +1,17 @@ +# Copyright The IETF Trust 2025, All Rights Reserved + +import json + +from celery import shared_task + +from .replication import replicate_blob, ReplicationError + + +@shared_task( + autoretry_for=(ReplicationError,), retry_backoff=10, retry_kwargs={"max_retries": 5} +) +def pybob_the_blob_replicator_task(body: str): + request = json.loads(body) + bucket = request["bucket"] + name = request["name"] + replicate_blob(bucket, name) diff --git a/ietf/blobdb/tests.py b/ietf/blobdb/tests.py new file mode 100644 index 00000000000..0eadad0a1f7 --- /dev/null +++ b/ietf/blobdb/tests.py @@ -0,0 +1,80 @@ +# Copyright The IETF Trust 2025, All Rights Reserved +import datetime + +from django.core.files.base import ContentFile + +from ietf.utils.test_utils import TestCase +from .factories import BlobFactory +from .models import Blob +from .storage import BlobFile, BlobdbStorage + + +class StorageTests(TestCase): + def test_save(self): + storage = BlobdbStorage(bucket_name="my-bucket") + timestamp = datetime.datetime( + 2025, + 3, + 17, + 1, + 2, + 3, + tzinfo=datetime.timezone.utc, + ) + # Create file to save + my_file = BlobFile( + content=b"These are my bytes.", + mtime=timestamp, + content_type="application/x-my-content-type", + ) + # save the file + saved_name = storage.save("myfile.txt", my_file) + # validate the outcome + self.assertEqual(saved_name, "myfile.txt") + blob = Blob.objects.filter(bucket="my-bucket", name="myfile.txt").first() + self.assertIsNotNone(blob) # validates bucket and name + self.assertEqual(bytes(blob.content), b"These are my bytes.") + self.assertEqual(blob.mtime, timestamp) + self.assertEqual(blob.content_type, "application/x-my-content-type") + + def test_save_naive_file(self): + storage = BlobdbStorage(bucket_name="my-bucket") + my_naive_file = ContentFile(content=b"These are my naive bytes.") + # save the file + saved_name = storage.save("myfile.txt", my_naive_file) + # validate the outcome + self.assertEqual(saved_name, "myfile.txt") + blob = Blob.objects.filter(bucket="my-bucket", name="myfile.txt").first() + self.assertIsNotNone(blob) # validates bucket and name + self.assertEqual(bytes(blob.content), b"These are my naive bytes.") + self.assertIsNone(blob.mtime) + self.assertEqual(blob.content_type, "") + + def test_open(self): + """BlobdbStorage open yields a BlobFile with specific mtime and content_type""" + mtime = datetime.datetime(2021, 1, 2, 3, 45, tzinfo=datetime.timezone.utc) + blob = BlobFactory(mtime=mtime, content_type="application/x-oh-no-you-didnt") + storage = BlobdbStorage(bucket_name=blob.bucket) + with storage.open(blob.name, "rb") as f: + self.assertTrue(isinstance(f, BlobFile)) + assert isinstance(f, BlobFile) # redundant, narrows type for linter + self.assertEqual(f.read(), bytes(blob.content)) + self.assertEqual(f.mtime, mtime) + self.assertEqual(f.content_type, "application/x-oh-no-you-didnt") + + def test_open_null_mtime(self): + """BlobdbStorage open yields a BlobFile with default mtime and content_type""" + blob = BlobFactory(content_type="application/x-oh-no-you-didnt") # does not set mtime + storage = BlobdbStorage(bucket_name=blob.bucket) + with storage.open(blob.name, "rb") as f: + self.assertTrue(isinstance(f, BlobFile)) + assert isinstance(f, BlobFile) # redundant, narrows type for linter + self.assertEqual(f.read(), bytes(blob.content)) + self.assertIsNotNone(f.mtime) + self.assertEqual(f.mtime, blob.modified) + self.assertEqual(f.content_type, "application/x-oh-no-you-didnt") + + def test_open_file_not_found(self): + storage = BlobdbStorage(bucket_name="not-a-bucket") + with self.assertRaises(FileNotFoundError): + storage.open("definitely/not-a-file.txt") diff --git a/ietf/blobdb/utils.py b/ietf/blobdb/utils.py new file mode 100644 index 00000000000..93f8f2f5217 --- /dev/null +++ b/ietf/blobdb/utils.py @@ -0,0 +1,32 @@ +# Copyright The IETF Trust 2026, All Rights Reserved +import json +from functools import partial + +from django.db import transaction + +from ietf.blobdb.replication import replication_enabled +from ietf.blobdb.tasks import pybob_the_blob_replicator_task + + +def queue_for_replication(bucket: str, name: str, using: str | None=None): + """Queue a blob for replication + + This is private to the blobdb app. Do not call it directly from other apps. + """ + if not replication_enabled(bucket): + return + + # For now, fire a celery task we've arranged to guarantee in-order processing. + # Later becomes pushing an event onto a queue to a dedicated worker. + transaction.on_commit( + partial( + pybob_the_blob_replicator_task.delay, + json.dumps( + { + "name": name, + "bucket": bucket, + } + ) + ), + using=using, + ) diff --git a/ietf/celeryapp.py b/ietf/celeryapp.py new file mode 100644 index 00000000000..fda89c30bec --- /dev/null +++ b/ietf/celeryapp.py @@ -0,0 +1,53 @@ +import os +import scout_apm.celery + +import celery +from scout_apm.api import Config + + +# Disable celery's internal logging configuration, we set it up via Django +@celery.signals.setup_logging.connect +def on_setup_logging(**kwargs): + pass + + +# Set the default Django settings module for the 'celery' program +os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'ietf.settings') + +app = celery.Celery('ietf') + +# Using a string here means the worker doesn't have to serialize +# the configuration object to child processes. +# - namespace='CELERY' means all celery-related configuration keys +# should have a `CELERY_` prefix. +app.config_from_object('django.conf:settings', namespace='CELERY') + +# Turn on Scout APM celery instrumentation if configured in the environment +scout_key = os.environ.get("DATATRACKER_SCOUT_KEY", None) +if scout_key is not None: + scout_name = os.environ.get("DATATRACKER_SCOUT_NAME", "Datatracker") + scout_core_agent_socket_path = "tcp://{host}:{port}".format( + host=os.environ.get("DATATRACKER_SCOUT_CORE_AGENT_HOST", "localhost"), + port=os.environ.get("DATATRACKER_SCOUT_CORE_AGENT_PORT", "6590"), + ) + Config.set( + key=scout_key, + name=scout_name, + monitor=True, + core_agent_download=False, + core_agent_launch=False, + core_agent_path=scout_core_agent_socket_path, + ) + # Note: Passing the Celery app to install() method as recommended in the + # Scout documentation causes failure at startup, likely because Scout + # ingests the config greedily before Django is ready. Have not found a + # workaround for this other than explicitly configuring Scout. + scout_apm.celery.install() + +# Load task modules from all registered Django apps. +app.autodiscover_tasks() + + +@app.task(bind=True) +def debug_task(self): + print(f'Request: {self.request!r}') diff --git a/ietf/checks.py b/ietf/checks.py index 53e695a7690..f911d081f0b 100644 --- a/ietf/checks.py +++ b/ietf/checks.py @@ -28,81 +28,6 @@ def already_ran(): checks_run.append(name) return False -@checks.register('directories') -def check_cdn_directory_exists(app_configs, **kwargs): - """This checks that the path from which the CDN will serve static files for - this version of the datatracker actually exists. In development and test - mode STATIC_ROOT will normally be just static/, but in production it will be - set to a different part of the file system which is served via CDN, and the - path will contain the datatracker release version. - """ - if already_ran(): - return [] - # - errors = [] - if settings.SERVER_MODE == 'production' and not os.path.exists(settings.STATIC_ROOT): - errors.append(checks.Error( - "The static files directory has not been set up.", - hint="Please run 'ietf/manage.py collectstatic'.", - obj=None, - id='datatracker.E001', - )) - return errors - -@checks.register('files') -def check_group_email_aliases_exists(app_configs, **kwargs): - from ietf.group.views import check_group_email_aliases - # - if already_ran(): - return [] - # - errors = [] - try: - ok = check_group_email_aliases() - if not ok: - errors.append(checks.Error( - "Found no aliases in the group email aliases file\n'%s'."%settings.GROUP_ALIASES_PATH, - hint="Please run the generate_group_aliases management command to generate them.", - obj=None, - id="datatracker.E0002", - )) - except IOError as e: - errors.append(checks.Error( - "Could not read group email aliases:\n %s" % e, - hint="Please run the generate_group_aliases management command to generate them.", - obj=None, - id="datatracker.E0003", - )) - - return errors - -@checks.register('files') -def check_doc_email_aliases_exists(app_configs, **kwargs): - from ietf.doc.views_doc import check_doc_email_aliases - # - if already_ran(): - return [] - # - errors = [] - try: - ok = check_doc_email_aliases() - if not ok: - errors.append(checks.Error( - "Found no aliases in the document email aliases file\n'%s'."%settings.DRAFT_VIRTUAL_PATH, - hint="Please run the generate_draft_aliases management command to generate them.", - obj=None, - id="datatracker.E0004", - )) - except IOError as e: - errors.append(checks.Error( - "Could not read document email aliases:\n %s" % e, - hint="Please run the generate_draft_aliases management command to generate them.", - obj=None, - id="datatracker.E0005", - )) - - return errors - @checks.register('directories') def check_id_submission_directories(app_configs, **kwargs): # @@ -114,7 +39,7 @@ def check_id_submission_directories(app_configs, **kwargs): p = getattr(settings, s) if not os.path.exists(p): errors.append(checks.Critical( - "A directory used by the ID submission tool does not\n" + "A directory used by the I-D submission tool does not\n" "exist at the path given in the settings file. The setting is:\n" " %s = %s" % (s, p), hint = ("Please either update the local settings to point at the correct\n" @@ -134,7 +59,7 @@ def check_id_submission_files(app_configs, **kwargs): p = getattr(settings, s) if not os.path.exists(p): errors.append(checks.Critical( - "A file used by the ID submission tool does not exist\n" + "A file used by the I-D submission tool does not exist\n" "at the path given in the settings file. The setting is:\n" " %s = %s" % (s, p), hint = ("Please either update the local settings to point at the correct\n" @@ -179,7 +104,7 @@ def check_id_submission_checkers(app_configs, **kwargs): except Exception as e: errors.append(checks.Critical( "An exception was raised when trying to import the\n" - "draft submission checker class '%s':\n %s" % (checker_path, e), + "Internet-Draft submission checker class '%s':\n %s" % (checker_path, e), hint = "Please check that the class exists and can be imported.\n", id = "datatracker.E0008", )) @@ -188,7 +113,7 @@ def check_id_submission_checkers(app_configs, **kwargs): except Exception as e: errors.append(checks.Critical( "An exception was raised when trying to instantiate\n" - "the draft submission checker class '%s':\n %s" % (checker_path, e), + "the Internet-Draft submission checker class '%s':\n %s" % (checker_path, e), hint = "Please check that the class can be instantiated.\n", id = "datatracker.E0009", )) @@ -196,7 +121,7 @@ def check_id_submission_checkers(app_configs, **kwargs): for attr in ('name',): if not hasattr(checker, attr): errors.append(checks.Critical( - "The draft submission checker\n '%s'\n" + "The Internet-Draft submission checker\n '%s'\n" "has no attribute '%s', which is required" % (checker_path, attr), hint = "Please update the class.\n", id = "datatracker.E0010", @@ -207,7 +132,7 @@ def check_id_submission_checkers(app_configs, **kwargs): break else: errors.append(checks.Critical( - "The draft submission checker\n '%s'\n" + "The Internet-Draft submission checker\n '%s'\n" " has no recognised checker method; " "should be one or more of %s." % (checker_path, checker_methods), hint = "Please update the class.\n", diff --git a/ietf/community/admin.py b/ietf/community/admin.py index 890819d9d98..4c947ad3f78 100644 --- a/ietf/community/admin.py +++ b/ietf/community/admin.py @@ -7,8 +7,8 @@ from ietf.community.models import CommunityList, SearchRule, EmailSubscription class CommunityListAdmin(admin.ModelAdmin): - list_display = ['id', 'user', 'group'] - raw_id_fields = ['user', 'group', 'added_docs'] + list_display = ['id', 'person', 'group'] + raw_id_fields = ['person', 'group', 'added_docs'] admin.site.register(CommunityList, CommunityListAdmin) class SearchRuleAdmin(admin.ModelAdmin): diff --git a/ietf/community/apps.py b/ietf/community/apps.py new file mode 100644 index 00000000000..ab0a6d6054b --- /dev/null +++ b/ietf/community/apps.py @@ -0,0 +1,12 @@ +# Copyright The IETF Trust 2024, All Rights Reserved + +from django.apps import AppConfig + + +class CommunityConfig(AppConfig): + name = "ietf.community" + + def ready(self): + """Initialize the app after the registry is populated""" + # implicitly connects @receiver-decorated signals + from . import signals # pyflakes: ignore diff --git a/ietf/community/forms.py b/ietf/community/forms.py index a8709c787a7..d3fa01dd19d 100644 --- a/ietf/community/forms.py +++ b/ietf/community/forms.py @@ -13,7 +13,7 @@ from ietf.person.fields import SearchablePersonField class AddDocumentsForm(forms.Form): - documents = SearchableDocumentsField(label="Add documents to track", doc_type="draft") + documents = SearchableDocumentsField(label="Add Internet-Drafts to track", doc_type="draft") class SearchRuleTypeForm(forms.Form): rule_type = forms.ChoiceField(choices=[('', '--------------')] + SearchRule.RULE_TYPES) @@ -30,6 +30,8 @@ def __init__(self, clist, rule_type, *args, **kwargs): super(SearchRuleForm, self).__init__(*args, **kwargs) def restrict_state(state_type, slug=None): + if "state" not in self.fields: + raise RuntimeError(f"Rule type {rule_type} cannot include state filtering") f = self.fields['state'] f.queryset = f.queryset.filter(used=True).filter(type=state_type) if slug: @@ -38,11 +40,15 @@ def restrict_state(state_type, slug=None): f.initial = f.queryset[0].pk f.widget = forms.HiddenInput() + if rule_type.endswith("_rfc"): + del self.fields["state"] # rfc rules must not look at document states + if rule_type in ["group", "group_rfc", "area", "area_rfc", "group_exp"]: if rule_type == "group_exp": restrict_state("draft", "expired") else: - restrict_state("draft", "rfc" if rule_type.endswith("rfc") else "active") + if not rule_type.endswith("_rfc"): + restrict_state("draft", "active") if rule_type.startswith("area"): self.fields["group"].label = "Area" @@ -70,7 +76,8 @@ def restrict_state(state_type, slug=None): del self.fields["text"] elif rule_type in ["author", "author_rfc", "shepherd", "ad"]: - restrict_state("draft", "rfc" if rule_type.endswith("rfc") else "active") + if not rule_type.endswith("_rfc"): + restrict_state("draft", "active") if rule_type.startswith("author"): self.fields["person"].label = "Author" @@ -84,7 +91,8 @@ def restrict_state(state_type, slug=None): del self.fields["text"] elif rule_type == "name_contains": - restrict_state("draft", "rfc" if rule_type.endswith("rfc") else "active") + if not rule_type.endswith("_rfc"): + restrict_state("draft", "active") del self.fields["person"] del self.fields["group"] @@ -106,14 +114,13 @@ def clean_text(self): class SubscriptionForm(forms.ModelForm): - def __init__(self, user, clist, *args, **kwargs): + def __init__(self, person, clist, *args, **kwargs): self.clist = clist - self.user = user super(SubscriptionForm, self).__init__(*args, **kwargs) self.fields["notify_on"].widget = forms.RadioSelect(choices=self.fields["notify_on"].choices) - self.fields["email"].queryset = self.fields["email"].queryset.filter(person__user=user, active=True).order_by("-primary") + self.fields["email"].queryset = self.fields["email"].queryset.filter(person=person, active=True).order_by("-primary") self.fields["email"].widget = forms.RadioSelect(choices=[t for t in self.fields["email"].choices if t[0]]) if self.fields["email"].queryset: diff --git a/ietf/community/migrations/0001_initial.py b/ietf/community/migrations/0001_initial.py index dc1ae75a3f4..44154687f30 100644 --- a/ietf/community/migrations/0001_initial.py +++ b/ietf/community/migrations/0001_initial.py @@ -1,10 +1,6 @@ -# Copyright The IETF Trust 2018-2020, All Rights Reserved -# -*- coding: utf-8 -*- -# Generated by Django 1.11.10 on 2018-02-20 10:52 - - -from typing import List, Tuple # pyflakes:ignore +# Generated by Django 2.2.28 on 2023-03-20 19:22 +from typing import List, Tuple from django.db import migrations, models import django.db.models.deletion import ietf.utils.models @@ -14,8 +10,8 @@ class Migration(migrations.Migration): initial = True - dependencies = [ - ] # type: List[Tuple[str]] + dependencies: List[Tuple[str, str]] = [ + ] operations = [ migrations.CreateModel( @@ -35,7 +31,7 @@ class Migration(migrations.Migration): name='SearchRule', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('rule_type', models.CharField(choices=[('group', 'All I-Ds associated with a particular group'), ('area', 'All I-Ds associated with all groups in a particular Area'), ('group_rfc', 'All RFCs associated with a particular group'), ('area_rfc', 'All RFCs associated with all groups in a particular Area'), ('state_iab', 'All I-Ds that are in a particular IAB state'), ('state_iana', 'All I-Ds that are in a particular IANA state'), ('state_iesg', 'All I-Ds that are in a particular IESG state'), ('state_irtf', 'All I-Ds that are in a particular IRTF state'), ('state_ise', 'All I-Ds that are in a particular ISE state'), ('state_rfceditor', 'All I-Ds that are in a particular RFC Editor state'), ('state_ietf', 'All I-Ds that are in a particular Working Group state'), ('author', 'All I-Ds with a particular author'), ('author_rfc', 'All RFCs with a particular author'), ('ad', 'All I-Ds with a particular responsible AD'), ('shepherd', 'All I-Ds with a particular document shepherd'), ('name_contains', 'All I-Ds with particular text/regular expression in the name')], max_length=30)), + ('rule_type', models.CharField(choices=[('group', 'All I-Ds associated with a particular group'), ('area', 'All I-Ds associated with all groups in a particular Area'), ('group_rfc', 'All RFCs associated with a particular group'), ('area_rfc', 'All RFCs associated with all groups in a particular Area'), ('group_exp', 'All expired I-Ds of a particular group'), ('state_iab', 'All I-Ds that are in a particular IAB state'), ('state_iana', 'All I-Ds that are in a particular IANA state'), ('state_iesg', 'All I-Ds that are in a particular IESG state'), ('state_irtf', 'All I-Ds that are in a particular IRTF state'), ('state_ise', 'All I-Ds that are in a particular ISE state'), ('state_rfceditor', 'All I-Ds that are in a particular RFC Editor state'), ('state_ietf', 'All I-Ds that are in a particular Working Group state'), ('author', 'All I-Ds with a particular author'), ('author_rfc', 'All RFCs with a particular author'), ('ad', 'All I-Ds with a particular responsible AD'), ('shepherd', 'All I-Ds with a particular document shepherd'), ('name_contains', 'All I-Ds with particular text/regular expression in the name')], max_length=30)), ('text', models.CharField(blank=True, default='', max_length=255, verbose_name='Text/RegExp')), ('community_list', ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='community.CommunityList')), ], diff --git a/ietf/community/migrations/0002_auto_20180220_1052.py b/ietf/community/migrations/0002_auto_20180220_1052.py deleted file mode 100644 index cb5658ac19e..00000000000 --- a/ietf/community/migrations/0002_auto_20180220_1052.py +++ /dev/null @@ -1,70 +0,0 @@ -# Copyright The IETF Trust 2018-2020, All Rights Reserved -# -*- coding: utf-8 -*- -# Generated by Django 1.11.10 on 2018-02-20 10:52 - - -from django.conf import settings -from django.db import migrations, models -import django.db.models.deletion -import ietf.utils.models - - -class Migration(migrations.Migration): - - initial = True - - dependencies = [ - ('doc', '0001_initial'), - ('group', '0001_initial'), - migrations.swappable_dependency(settings.AUTH_USER_MODEL), - ('community', '0001_initial'), - ('person', '0001_initial'), - ] - - operations = [ - migrations.AddField( - model_name='searchrule', - name='group', - field=ietf.utils.models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='group.Group'), - ), - migrations.AddField( - model_name='searchrule', - name='name_contains_index', - field=models.ManyToManyField(to='doc.Document'), - ), - migrations.AddField( - model_name='searchrule', - name='person', - field=ietf.utils.models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='person.Person'), - ), - migrations.AddField( - model_name='searchrule', - name='state', - field=ietf.utils.models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='doc.State'), - ), - migrations.AddField( - model_name='emailsubscription', - name='community_list', - field=ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='community.CommunityList'), - ), - migrations.AddField( - model_name='emailsubscription', - name='email', - field=ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='person.Email'), - ), - migrations.AddField( - model_name='communitylist', - name='added_docs', - field=models.ManyToManyField(to='doc.Document'), - ), - migrations.AddField( - model_name='communitylist', - name='group', - field=ietf.utils.models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='group.Group'), - ), - migrations.AddField( - model_name='communitylist', - name='user', - field=ietf.utils.models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL), - ), - ] diff --git a/ietf/community/migrations/0002_auto_20230320_1222.py b/ietf/community/migrations/0002_auto_20230320_1222.py new file mode 100644 index 00000000000..f552cc06e1a --- /dev/null +++ b/ietf/community/migrations/0002_auto_20230320_1222.py @@ -0,0 +1,67 @@ +# Generated by Django 2.2.28 on 2023-03-20 19:22 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion +import ietf.utils.models + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ('person', '0001_initial'), + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('community', '0001_initial'), + ('group', '0001_initial'), + ('doc', '0001_initial'), + ] + + operations = [ + migrations.AddField( + model_name='searchrule', + name='group', + field=ietf.utils.models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='group.Group'), + ), + migrations.AddField( + model_name='searchrule', + name='name_contains_index', + field=models.ManyToManyField(to='doc.Document'), + ), + migrations.AddField( + model_name='searchrule', + name='person', + field=ietf.utils.models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='person.Person'), + ), + migrations.AddField( + model_name='searchrule', + name='state', + field=ietf.utils.models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='doc.State'), + ), + migrations.AddField( + model_name='emailsubscription', + name='community_list', + field=ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='community.CommunityList'), + ), + migrations.AddField( + model_name='emailsubscription', + name='email', + field=ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='person.Email'), + ), + migrations.AddField( + model_name='communitylist', + name='added_docs', + field=models.ManyToManyField(to='doc.Document'), + ), + migrations.AddField( + model_name='communitylist', + name='group', + field=ietf.utils.models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='group.Group'), + ), + migrations.AddField( + model_name='communitylist', + name='user', + field=ietf.utils.models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL), + ), + ] diff --git a/ietf/community/migrations/0003_add_communitylist_docs2_m2m.py b/ietf/community/migrations/0003_add_communitylist_docs2_m2m.py deleted file mode 100644 index 3bfaee9aa9d..00000000000 --- a/ietf/community/migrations/0003_add_communitylist_docs2_m2m.py +++ /dev/null @@ -1,44 +0,0 @@ -# Copyright The IETF Trust 2019-2020, All Rights Reserved -# -*- coding: utf-8 -*- -# Generated by Django 1.11.20 on 2019-05-21 14:23 - - -from django.db import migrations, models -import django.db.models.deletion -import ietf.utils.models - - -class Migration(migrations.Migration): - - dependencies = [ - ('community', '0002_auto_20180220_1052'), - ] - - operations = [ - migrations.CreateModel( - name='CommunityListDocs', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('communitylist', ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='community.CommunityList')), - ('document', ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='doc.Document', to_field=b'id')), - ], - ), - migrations.AddField( - model_name='communitylist', - name='added_docs2', - field=models.ManyToManyField(related_name='communitylists', through='community.CommunityListDocs', to='doc.Document'), - ), - migrations.CreateModel( - name='SearchRuleDocs', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('document', ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='doc.Document', to_field=b'id')), - ('searchrule', ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='community.SearchRule')), - ], - ), - migrations.AddField( - model_name='searchrule', - name='name_contains_index2', - field=models.ManyToManyField(related_name='searchrules', through='community.SearchRuleDocs', to='doc.Document'), - ), - ] diff --git a/ietf/community/migrations/0003_track_rfcs.py b/ietf/community/migrations/0003_track_rfcs.py new file mode 100644 index 00000000000..3c2d04097da --- /dev/null +++ b/ietf/community/migrations/0003_track_rfcs.py @@ -0,0 +1,50 @@ +# Generated by Django 4.2.3 on 2023-07-07 18:33 + +from django.db import migrations + + +def forward(apps, schema_editor): + """Track any RFCs that were created from tracked drafts""" + CommunityList = apps.get_model("community", "CommunityList") + RelatedDocument = apps.get_model("doc", "RelatedDocument") + + # Handle individually tracked documents + for cl in CommunityList.objects.all(): + for rfc in set( + RelatedDocument.objects.filter( + source__in=cl.added_docs.all(), + relationship__slug="became_rfc", + ).values_list("target__docs", flat=True) + ): + cl.added_docs.add(rfc) + + # Handle rules - rules ending with _rfc should no longer filter by state. + # There are 9 CommunityLists with invalid author_rfc rules that are filtering + # by (draft, active) instead of (draft, rfc) state before migration. All but one + # also includes an author rule for (draft, active), so these will start following + # RFCs as well. The one exception will start tracking RFCs instead of I-Ds, which + # is probably what was intended, but will be a change in their user experience. + SearchRule = apps.get_model("community", "SearchRule") + rfc_rules = SearchRule.objects.filter(rule_type__endswith="_rfc") + rfc_rules.update(state=None) + +def reverse(apps, schema_editor): + Document = apps.get_model("doc", "Document") + for rfc in Document.objects.filter(type__slug="rfc"): + rfc.communitylist_set.clear() + + # See the comment above regarding author_rfc + SearchRule = apps.get_model("community", "SearchRule") + State = apps.get_model("doc", "State") + SearchRule.objects.filter(rule_type__endswith="_rfc").update( + state=State.objects.get(type_id="draft", slug="rfc") + ) + + +class Migration(migrations.Migration): + dependencies = [ + ("community", "0002_auto_20230320_1222"), + ("doc", "0014_move_rfc_docaliases"), + ] + + operations = [migrations.RunPython(forward, reverse)] diff --git a/ietf/community/migrations/0004_delete_useless_community_lists.py b/ietf/community/migrations/0004_delete_useless_community_lists.py new file mode 100644 index 00000000000..9f657a3c349 --- /dev/null +++ b/ietf/community/migrations/0004_delete_useless_community_lists.py @@ -0,0 +1,26 @@ +# Generated by Django 4.2.9 on 2024-01-05 21:28 + +from django.db import migrations + + +def forward(apps, schema_editor): + CommunityList = apps.get_model("community", "CommunityList") + # As of 2024-01-05, there are 570 personal CommunityLists with a user + # who has no associated Person. None of these has an EmailSubscription, + # so the lists are doing nothing and can be safely deleted. + personal_lists_no_person = CommunityList.objects.exclude( + user__isnull=True + ).filter( + user__person__isnull=True + ) + # Confirm the assumption that none of the lists to be deleted has an EmailSubscription + assert not personal_lists_no_person.filter(emailsubscription__isnull=False).exists() + personal_lists_no_person.delete() + + +class Migration(migrations.Migration): + dependencies = [ + ("community", "0003_track_rfcs"), + ] + + operations = [migrations.RunPython(forward)] diff --git a/ietf/community/migrations/0004_set_document_m2m_keys.py b/ietf/community/migrations/0004_set_document_m2m_keys.py deleted file mode 100644 index 60e51fc3686..00000000000 --- a/ietf/community/migrations/0004_set_document_m2m_keys.py +++ /dev/null @@ -1,56 +0,0 @@ -# Copyright The IETF Trust 2019-2020, All Rights Reserved -# -*- coding: utf-8 -*- -# Generated by Django 1.11.20 on 2019-05-21 14:27 - - -import sys - -from tqdm import tqdm - -from django.db import migrations - - -def forward(apps, schema_editor): - - Document = apps.get_model('doc','Document') - CommunityList = apps.get_model('community', 'CommunityList') - CommunityListDocs = apps.get_model('community', 'CommunityListDocs') - SearchRule = apps.get_model('community', 'SearchRule') - SearchRuleDocs = apps.get_model('community', 'SearchRuleDocs') - - # Document id fixup ------------------------------------------------------------ - - objs = Document.objects.in_bulk() - nameid = { o.name: o.id for id, o in objs.items() } - - sys.stderr.write('\n') - - sys.stderr.write(' %s.%s:\n' % (CommunityList.__name__, 'added_docs')) - count = 0 - for l in tqdm(CommunityList.objects.all()): - for d in l.added_docs.all(): - count += 1 - CommunityListDocs.objects.get_or_create(communitylist=l, document_id=nameid[d.name]) - sys.stderr.write(' %s CommunityListDocs objects created\n' % (count, )) - - sys.stderr.write(' %s.%s:\n' % (SearchRule.__name__, 'name_contains_index')) - count = 0 - for r in tqdm(SearchRule.objects.all()): - for d in r.name_contains_index.all(): - count += 1 - SearchRuleDocs.objects.get_or_create(searchrule=r, document_id=nameid[d.name]) - sys.stderr.write(' %s SearchRuleDocs objects created\n' % (count, )) - -def reverse(apps, schema_editor): - pass - -class Migration(migrations.Migration): - - dependencies = [ - ('community', '0003_add_communitylist_docs2_m2m'), - ('doc', '0014_set_document_docalias_id'), - ] - - operations = [ - migrations.RunPython(forward, reverse), - ] diff --git a/ietf/community/migrations/0005_1_del_docs_m2m_table.py b/ietf/community/migrations/0005_1_del_docs_m2m_table.py deleted file mode 100644 index 9a7b7f94531..00000000000 --- a/ietf/community/migrations/0005_1_del_docs_m2m_table.py +++ /dev/null @@ -1,32 +0,0 @@ -# Copyright The IETF Trust 2019-2020, All Rights Reserved -# -*- coding: utf-8 -*- -# Generated by Django 1.11.20 on 2019-05-22 08:15 - - -from django.db import migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ('community', '0004_set_document_m2m_keys'), - ] - - # The implementation of AlterField in Django 1.11 applies - # 'ALTER TABLE MODIFY ...;' in order to fix foregn keys - # to the altered field, but as it seems does _not_ fix up m2m - # intermediary tables in an equivalent manner, so here we remove and - # then recreate the m2m tables so they will have the appropriate field - # types. - - operations = [ - # Remove fields - migrations.RemoveField( - model_name='communitylist', - name='added_docs', - ), - migrations.RemoveField( - model_name='searchrule', - name='name_contains_index', - ), - ] diff --git a/ietf/community/migrations/0005_2_add_docs_m2m_table.py b/ietf/community/migrations/0005_2_add_docs_m2m_table.py deleted file mode 100644 index ef1f9bc4f50..00000000000 --- a/ietf/community/migrations/0005_2_add_docs_m2m_table.py +++ /dev/null @@ -1,34 +0,0 @@ -# Copyright The IETF Trust 2019-2020, All Rights Reserved -# -*- coding: utf-8 -*- -# Generated by Django 1.11.20 on 2019-05-22 08:15 - - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('community', '0005_1_del_docs_m2m_table'), - ] - - # The implementation of AlterField in Django 1.11 applies - # 'ALTER TABLE
MODIFY ...;' in order to fix foregn keys - # to the altered field, but as it seems does _not_ fix up m2m - # intermediary tables in an equivalent manner, so here we remove and - # then recreate the m2m tables so they will have the appropriate field - # types. - - operations = [ - # Add fields back (will create the m2m tables with the right field types) - migrations.AddField( - model_name='communitylist', - name='added_docs', - field=models.ManyToManyField(to='doc.Document'), - ), - migrations.AddField( - model_name='searchrule', - name='name_contains_index', - field=models.ManyToManyField(to='doc.Document'), - ), - ] diff --git a/ietf/community/migrations/0005_user_to_person.py b/ietf/community/migrations/0005_user_to_person.py new file mode 100644 index 00000000000..01d8950edb7 --- /dev/null +++ b/ietf/community/migrations/0005_user_to_person.py @@ -0,0 +1,54 @@ +# Generated by Django 4.2.2 on 2023-06-12 19:35 + +from django.conf import settings +from django.db import migrations +import django.db.models.deletion +import ietf.utils.models + + +def forward(apps, schema_editor): + CommunityList = apps.get_model('community', 'CommunityList') + for clist in CommunityList.objects.all(): + try: + clist.person = clist.user.person + except: + clist.person = None + clist.save() + +def reverse(apps, schema_editor): + CommunityList = apps.get_model('community', 'CommunityList') + for clist in CommunityList.objects.all(): + try: + clist.user = clist.person.user + except: + clist.user = None + clist.save() + +class Migration(migrations.Migration): + dependencies = [ + ("community", "0004_delete_useless_community_lists"), + ("person", "0001_initial"), + ] + + operations = [ + migrations.AddField( + model_name="communitylist", + name="person", + field=ietf.utils.models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.CASCADE, + to="person.Person", + ), + ), + migrations.RunPython(forward, reverse), + migrations.RemoveField( + model_name="communitylist", + name="user", + field=ietf.utils.models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.CASCADE, + to=settings.AUTH_USER_MODEL), + ), + ] diff --git a/ietf/community/migrations/0006_copy_docs_m2m_table.py b/ietf/community/migrations/0006_copy_docs_m2m_table.py deleted file mode 100644 index 6d1a5e3a887..00000000000 --- a/ietf/community/migrations/0006_copy_docs_m2m_table.py +++ /dev/null @@ -1,57 +0,0 @@ -# Copyright The IETF Trust 2019-2020, All Rights Reserved -# -*- coding: utf-8 -*- -# Generated by Django 1.11.20 on 2019-05-27 05:56 - - -from django.db import migrations - -import sys, time - -from tqdm import tqdm - - -def forward(apps, schema_editor): - - CommunityList = apps.get_model('community', 'CommunityList') - CommunityListDocs = apps.get_model('community', 'CommunityListDocs') - SearchRule = apps.get_model('community', 'SearchRule') - SearchRuleDocs = apps.get_model('community', 'SearchRuleDocs') - - # Document id fixup ------------------------------------------------------------ - - - sys.stderr.write('\n') - - sys.stderr.write(' %s.%s:\n' % (CommunityList.__name__, 'added_docs')) - for l in tqdm(CommunityList.objects.all()): - l.added_docs.set([ d.document for d in CommunityListDocs.objects.filter(communitylist=l) ]) - - sys.stderr.write(' %s.%s:\n' % (SearchRule.__name__, 'name_contains_index')) - for r in tqdm(SearchRule.objects.all()): - r.name_contains_index.set([ d.document for d in SearchRuleDocs.objects.filter(searchrule=r) ]) - -def reverse(apps, schema_editor): - pass - -def timestamp(apps, schema_editor): - sys.stderr.write('\n %s' % time.strftime('%Y-%m-%d %H:%M:%S')) - -class Migration(migrations.Migration): - - dependencies = [ - ('community', '0005_2_add_docs_m2m_table'), - ] - - operations = [ - #migrations.RunPython(forward, reverse), - # Alternative: - migrations.RunPython(timestamp, timestamp), - migrations.RunSQL( - "INSERT INTO community_communitylist_added_docs SELECT * FROM community_communitylistdocs;", - ""), - migrations.RunPython(timestamp, timestamp), - migrations.RunSQL( - "INSERT INTO community_searchrule_name_contains_index SELECT * FROM community_searchruledocs;", - ""), - migrations.RunPython(timestamp, timestamp), - ] diff --git a/ietf/community/migrations/0007_remove_docs2_m2m.py b/ietf/community/migrations/0007_remove_docs2_m2m.py deleted file mode 100644 index a454fbf0727..00000000000 --- a/ietf/community/migrations/0007_remove_docs2_m2m.py +++ /dev/null @@ -1,46 +0,0 @@ -# Copyright The IETF Trust 2019-2020, All Rights Reserved -# -*- coding: utf-8 -*- -# Generated by Django 1.11.20 on 2019-05-30 03:06 - - -from django.db import migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ('community', '0006_copy_docs_m2m_table'), - ] - - operations = [ - migrations.RemoveField( - model_name='communitylistdocs', - name='communitylist', - ), - migrations.RemoveField( - model_name='communitylistdocs', - name='document', - ), - migrations.RemoveField( - model_name='searchruledocs', - name='document', - ), - migrations.RemoveField( - model_name='searchruledocs', - name='searchrule', - ), - migrations.RemoveField( - model_name='communitylist', - name='added_docs2', - ), - migrations.RemoveField( - model_name='searchrule', - name='name_contains_index2', - ), - migrations.DeleteModel( - name='CommunityListDocs', - ), - migrations.DeleteModel( - name='SearchRuleDocs', - ), - ] diff --git a/ietf/community/migrations/0008_add_group_exp_rule.py b/ietf/community/migrations/0008_add_group_exp_rule.py deleted file mode 100644 index b5ddebe6380..00000000000 --- a/ietf/community/migrations/0008_add_group_exp_rule.py +++ /dev/null @@ -1,18 +0,0 @@ -# Generated by Django 2.2.28 on 2022-06-30 05:59 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('community', '0007_remove_docs2_m2m'), - ] - - operations = [ - migrations.AlterField( - model_name='searchrule', - name='rule_type', - field=models.CharField(choices=[('group', 'All I-Ds associated with a particular group'), ('area', 'All I-Ds associated with all groups in a particular Area'), ('group_rfc', 'All RFCs associated with a particular group'), ('area_rfc', 'All RFCs associated with all groups in a particular Area'), ('group_exp', 'All expired I-Ds of a particular group'), ('state_iab', 'All I-Ds that are in a particular IAB state'), ('state_iana', 'All I-Ds that are in a particular IANA state'), ('state_iesg', 'All I-Ds that are in a particular IESG state'), ('state_irtf', 'All I-Ds that are in a particular IRTF state'), ('state_ise', 'All I-Ds that are in a particular ISE state'), ('state_rfceditor', 'All I-Ds that are in a particular RFC Editor state'), ('state_ietf', 'All I-Ds that are in a particular Working Group state'), ('author', 'All I-Ds with a particular author'), ('author_rfc', 'All RFCs with a particular author'), ('ad', 'All I-Ds with a particular responsible AD'), ('shepherd', 'All I-Ds with a particular document shepherd'), ('name_contains', 'All I-Ds with particular text/regular expression in the name')], max_length=30), - ), - ] diff --git a/ietf/community/migrations/0009_add_group_exp_rule_to_groups.py b/ietf/community/migrations/0009_add_group_exp_rule_to_groups.py deleted file mode 100644 index 1d3222dc6e9..00000000000 --- a/ietf/community/migrations/0009_add_group_exp_rule_to_groups.py +++ /dev/null @@ -1,30 +0,0 @@ -# Generated by Django 2.2.28 on 2022-06-30 23:15 - - -from django.db import migrations - - -def forward(apps, schema_editor): - SearchRule = apps.get_model('community', 'SearchRule') - CommunityList = apps.get_model('community', 'CommunityList') - Group = apps.get_model('group', 'Group') - State = apps.get_model('doc', 'State') - for group in Group.objects.filter(type_id__in=['wg','rg'], state_id='active'): - com_list = CommunityList.objects.filter(group=group).first() - if com_list is not None: - SearchRule.objects.create(community_list=com_list, rule_type="group_exp", group=group, state=State.objects.get(slug="expired", type="draft"),) - - -def reverse(apps, schema_editor): - SearchRule = apps.get_model('community', 'SearchRule') - SearchRule.objects.filter(rule_type='group_exp').delete() - - -class Migration(migrations.Migration): - dependencies = [ - ('community', '0008_add_group_exp_rule'), - ] - - operations = [ - migrations.RunPython(forward, reverse), - ] diff --git a/ietf/community/models.py b/ietf/community/models.py index 8938b1c0973..6945918f9a4 100644 --- a/ietf/community/models.py +++ b/ietf/community/models.py @@ -1,37 +1,35 @@ # Copyright The IETF Trust 2012-2020, All Rights Reserved # -*- coding: utf-8 -*- - -from django.contrib.auth.models import User from django.db import models -from django.db.models import signals from django.urls import reverse as urlreverse -from ietf.doc.models import Document, DocEvent, State +from ietf.doc.models import Document, State from ietf.group.models import Group from ietf.person.models import Person, Email from ietf.utils.models import ForeignKey + class CommunityList(models.Model): - user = ForeignKey(User, blank=True, null=True) + person = ForeignKey(Person, blank=True, null=True) group = ForeignKey(Group, blank=True, null=True) added_docs = models.ManyToManyField(Document) def long_name(self): - if self.user: - return 'Personal ID list of %s' % self.user.username + if self.person: + return 'Personal I-D list of %s' % self.person.plain_name() elif self.group: - return 'ID list for %s' % self.group.name + return 'I-D list for %s' % self.group.name else: - return 'ID list' + return 'I-D list' def __str__(self): return self.long_name() def get_absolute_url(self): import ietf.community.views - if self.user: - return urlreverse(ietf.community.views.view_list, kwargs={ 'username': self.user.username }) + if self.person: + return urlreverse(ietf.community.views.view_list, kwargs={ 'email_or_name': self.person.email() }) elif self.group: return urlreverse("ietf.group.views.group_documents", kwargs={ 'acronym': self.group.acronym }) return "" @@ -95,20 +93,3 @@ class EmailSubscription(models.Model): def __str__(self): return "%s to %s (%s changes)" % (self.email, self.community_list, self.notify_on) - - -def notify_events(sender, instance, **kwargs): - if not isinstance(instance, DocEvent): - return - - if instance.doc.type_id != 'draft': - return - - if getattr(instance, "skip_community_list_notification", False): - return - - from ietf.community.utils import notify_event_to_subscribers - notify_event_to_subscribers(instance) - - -signals.post_save.connect(notify_events) diff --git a/ietf/community/signals.py b/ietf/community/signals.py new file mode 100644 index 00000000000..20ee761129f --- /dev/null +++ b/ietf/community/signals.py @@ -0,0 +1,44 @@ +# Copyright The IETF Trust 2024, All Rights Reserved + +from django.conf import settings +from django.db import transaction +from django.db.models.signals import post_save +from django.dispatch import receiver + +from ietf.doc.models import DocEvent +from .tasks import notify_event_to_subscribers_task + + +def notify_of_event(event: DocEvent): + """Send subscriber notification emails for a 'draft'-related DocEvent + + If the event is attached to a draft of type 'doc', queues a task to send notification emails to + community list subscribers. No emails will be sent when SERVER_MODE is 'test'. + """ + if event.doc.type_id != "draft": + return + + if getattr(event, "skip_community_list_notification", False): + return + + # kludge alert: queuing a celery task in response to a signal can cause unexpected attempts to + # start a Celery task during tests. To prevent this, don't queue a celery task if we're running + # tests. + if settings.SERVER_MODE != "test": + # Wrap in on_commit in case a transaction is open + transaction.on_commit( + lambda: notify_event_to_subscribers_task.delay(event_id=event.pk) + ) + + +# dispatch_uid ensures only a single signal receiver binding is made +@receiver(post_save, dispatch_uid="notify_of_events_receiver_uid") +def notify_of_events_receiver(sender, instance, **kwargs): + """Call notify_of_event after saving a new DocEvent""" + if not isinstance(instance, DocEvent): + return + + if not kwargs.get("created", False): + return # only notify on creation + + notify_of_event(instance) diff --git a/ietf/community/tasks.py b/ietf/community/tasks.py new file mode 100644 index 00000000000..763a5964953 --- /dev/null +++ b/ietf/community/tasks.py @@ -0,0 +1,15 @@ +# Copyright The IETF Trust 2024, All Rights Reserved +from celery import shared_task + +from ietf.doc.models import DocEvent +from ietf.utils.log import log + + +@shared_task +def notify_event_to_subscribers_task(event_id): + from .utils import notify_event_to_subscribers + event = DocEvent.objects.filter(pk=event_id).first() + if event is None: + log(f"Unable to send subscriber notifications because DocEvent {event_id} was not found") + else: + notify_event_to_subscribers(event) diff --git a/ietf/community/tests.py b/ietf/community/tests.py index 3dd86f70e36..04f1433d61a 100644 --- a/ietf/community/tests.py +++ b/ietf/community/tests.py @@ -1,60 +1,112 @@ -# Copyright The IETF Trust 2016-2020, All Rights Reserved +# Copyright The IETF Trust 2016-2023, All Rights Reserved # -*- coding: utf-8 -*- - +from unittest import mock from pyquery import PyQuery +from django.test.utils import override_settings from django.urls import reverse as urlreverse -from django.contrib.auth.models import User - -from django_webtest import WebTest +from lxml import etree -import debug # pyflakes:ignore +import debug # pyflakes:ignore from ietf.community.models import CommunityList, SearchRule, EmailSubscription -from ietf.community.utils import docs_matching_community_list_rule, community_list_rules_matching_doc -from ietf.community.utils import reset_name_contains_index_for_rule +from ietf.community.signals import notify_of_event +from ietf.community.utils import ( + docs_matching_community_list_rule, + community_list_rules_matching_doc, +) +from ietf.community.utils import ( + reset_name_contains_index_for_rule, + notify_event_to_subscribers, +) +from ietf.community.tasks import notify_event_to_subscribers_task import ietf.community.views from ietf.group.models import Group from ietf.group.utils import setup_default_community_list_for_group +from ietf.doc.factories import DocumentFactory from ietf.doc.models import State from ietf.doc.utils import add_state_change_event -from ietf.person.models import Person, Email -from ietf.utils.test_utils import login_testing_unauthorized -from ietf.utils.mail import outbox -from ietf.doc.factories import WgDraftFactory +from ietf.person.models import Person, Email, Alias +from ietf.utils.test_utils import TestCase, login_testing_unauthorized +from ietf.doc.factories import DocEventFactory, WgDraftFactory from ietf.group.factories import GroupFactory, RoleFactory -from ietf.person.factories import PersonFactory +from ietf.person.factories import PersonFactory, EmailFactory, AliasFactory + -class CommunityListTests(WebTest): +class CommunityListTests(TestCase): def test_rule_matching(self): - plain = PersonFactory(user__username='plain') - ad = Person.objects.get(user__username='ad') + plain = PersonFactory(user__username="plain") + ad = Person.objects.get(user__username="ad") draft = WgDraftFactory( - group__parent=Group.objects.get(acronym='farfut' ), + group__parent=Group.objects.get(acronym="farfut"), authors=[ad], ad=ad, shepherd=plain.email(), - states=[('draft-iesg','lc'),('draft','active')], + states=[("draft-iesg", "lc"), ("draft", "active")], ) - clist = CommunityList.objects.create(user=User.objects.get(username="plain")) + clist = CommunityList.objects.create(person=plain) - rule_group = SearchRule.objects.create(rule_type="group", group=draft.group, state=State.objects.get(type="draft", slug="active"), community_list=clist) - rule_group_rfc = SearchRule.objects.create(rule_type="group_rfc", group=draft.group, state=State.objects.get(type="draft", slug="rfc"), community_list=clist) - rule_area = SearchRule.objects.create(rule_type="area", group=draft.group.parent, state=State.objects.get(type="draft", slug="active"), community_list=clist) + rule_group = SearchRule.objects.create( + rule_type="group", + group=draft.group, + state=State.objects.get(type="draft", slug="active"), + community_list=clist, + ) + rule_group_rfc = SearchRule.objects.create( + rule_type="group_rfc", + group=draft.group, + state=State.objects.get(type="rfc", slug="published"), + community_list=clist, + ) + rule_area = SearchRule.objects.create( + rule_type="area", + group=draft.group.parent, + state=State.objects.get(type="draft", slug="active"), + community_list=clist, + ) - rule_state_iesg = SearchRule.objects.create(rule_type="state_iesg", state=State.objects.get(type="draft-iesg", slug="lc"), community_list=clist) + rule_state_iesg = SearchRule.objects.create( + rule_type="state_iesg", + state=State.objects.get(type="draft-iesg", slug="lc"), + community_list=clist, + ) - rule_author = SearchRule.objects.create(rule_type="author", state=State.objects.get(type="draft", slug="active"), person=Person.objects.filter(documentauthor__document=draft).first(), community_list=clist) + rule_author = SearchRule.objects.create( + rule_type="author", + state=State.objects.get(type="draft", slug="active"), + person=Person.objects.filter(documentauthor__document=draft).first(), + community_list=clist, + ) - rule_ad = SearchRule.objects.create(rule_type="ad", state=State.objects.get(type="draft", slug="active"), person=draft.ad, community_list=clist) + rule_ad = SearchRule.objects.create( + rule_type="ad", + state=State.objects.get(type="draft", slug="active"), + person=draft.ad, + community_list=clist, + ) - rule_shepherd = SearchRule.objects.create(rule_type="shepherd", state=State.objects.get(type="draft", slug="active"), person=draft.shepherd.person, community_list=clist) + rule_shepherd = SearchRule.objects.create( + rule_type="shepherd", + state=State.objects.get(type="draft", slug="active"), + person=draft.shepherd.person, + community_list=clist, + ) - rule_group_exp = SearchRule.objects.create(rule_type="group_exp", group=draft.group, state=State.objects.get(type="draft", slug="expired"), community_list=clist) + rule_group_exp = SearchRule.objects.create( + rule_type="group_exp", + group=draft.group, + state=State.objects.get(type="draft", slug="expired"), + community_list=clist, + ) - rule_name_contains = SearchRule.objects.create(rule_type="name_contains", state=State.objects.get(type="draft", slug="active"), text="draft-.*" + "-".join(draft.name.split("-")[2:]), community_list=clist) + rule_name_contains = SearchRule.objects.create( + rule_type="name_contains", + state=State.objects.get(type="draft", slug="active"), + text="draft-.*" + "-".join(draft.name.split("-")[2:]), + community_list=clist, + ) reset_name_contains_index_for_rule(rule_name_contains) # doc -> rules @@ -71,37 +123,71 @@ def test_rule_matching(self): # rule -> docs self.assertTrue(draft in list(docs_matching_community_list_rule(rule_group))) - self.assertTrue(draft not in list(docs_matching_community_list_rule(rule_group_rfc))) + self.assertTrue( + draft not in list(docs_matching_community_list_rule(rule_group_rfc)) + ) self.assertTrue(draft in list(docs_matching_community_list_rule(rule_area))) - self.assertTrue(draft in list(docs_matching_community_list_rule(rule_state_iesg))) + self.assertTrue( + draft in list(docs_matching_community_list_rule(rule_state_iesg)) + ) self.assertTrue(draft in list(docs_matching_community_list_rule(rule_author))) self.assertTrue(draft in list(docs_matching_community_list_rule(rule_ad))) self.assertTrue(draft in list(docs_matching_community_list_rule(rule_shepherd))) - self.assertTrue(draft in list(docs_matching_community_list_rule(rule_name_contains))) - self.assertTrue(draft not in list(docs_matching_community_list_rule(rule_group_exp))) + self.assertTrue( + draft in list(docs_matching_community_list_rule(rule_name_contains)) + ) + self.assertTrue( + draft not in list(docs_matching_community_list_rule(rule_group_exp)) + ) - draft.set_state(State.objects.get(type='draft', slug='expired')) + draft.set_state(State.objects.get(type="draft", slug="expired")) # doc -> rules matching_rules = list(community_list_rules_matching_doc(draft)) self.assertTrue(rule_group_exp in matching_rules) # rule -> docs - self.assertTrue(draft in list(docs_matching_community_list_rule(rule_group_exp))) + self.assertTrue( + draft in list(docs_matching_community_list_rule(rule_group_exp)) + ) - def test_view_list(self): - PersonFactory(user__username='plain') - draft = WgDraftFactory() + def test_view_list_duplicates(self): + person = PersonFactory( + name="John Q. Public", user__username="bazquux@example.com" + ) + PersonFactory(name="John Q. Public", user__username="foobar@example.com") - url = urlreverse(ietf.community.views.view_list, kwargs={ "username": "plain" }) + url = urlreverse( + ietf.community.views.view_list, + kwargs={"email_or_name": person.plain_name()}, + ) + r = self.client.get(url) + self.assertEqual(r.status_code, 404) + def complex_person(self, *args, **kwargs): + person = PersonFactory(*args, **kwargs) + EmailFactory(person=person) + AliasFactory(person=person) + return person + + def email_or_name_set(self, person): + return [e for e in Email.objects.filter(person=person)] + [ + a for a in Alias.objects.filter(person=person) + ] + + def do_view_list_test(self, person): + draft = WgDraftFactory() # without list - r = self.client.get(url) - self.assertEqual(r.status_code, 200) + for id in self.email_or_name_set(person): + url = urlreverse( + ietf.community.views.view_list, kwargs={"email_or_name": id} + ) + r = self.client.get(url) + self.assertEqual(r.status_code, 200, msg=f"id='{id}', url='{url}'") # with list - clist = CommunityList.objects.create(user=User.objects.get(username="plain")) - if not draft in clist.added_docs.all(): + clist = CommunityList.objects.create(person=person) + if draft not in clist.added_docs.all(): clist.added_docs.add(draft) SearchRule.objects.create( community_list=clist, @@ -109,86 +195,135 @@ def test_view_list(self): state=State.objects.get(type="draft", slug="active"), text="test", ) - r = self.client.get(url) - self.assertEqual(r.status_code, 200) - self.assertContains(r, draft.name) + for id in self.email_or_name_set(person): + url = urlreverse( + ietf.community.views.view_list, kwargs={"email_or_name": id} + ) + r = self.client.get(url) + self.assertEqual(r.status_code, 200, msg=f"id='{id}', url='{url}'") + self.assertContains(r, draft.name) - def test_manage_personal_list(self): + def test_view_list(self): + person = self.complex_person(user__username="plain") + self.do_view_list_test(person) + + def test_view_list_without_active_email(self): + person = self.complex_person(user__username="plain") + person.email_set.update(active=False) + self.do_view_list_test(person) - PersonFactory(user__username='plain') - ad = Person.objects.get(user__username='ad') + def test_manage_personal_list(self): + person = self.complex_person(user__username="plain") + ad = Person.objects.get(user__username="ad") draft = WgDraftFactory(authors=[ad]) - url = urlreverse(ietf.community.views.manage_list, kwargs={ "username": "plain" }) + url = urlreverse( + ietf.community.views.manage_list, kwargs={"email_or_name": person.email()} + ) login_testing_unauthorized(self, "plain", url) - page = self.app.get(url, user='plain') - self.assertEqual(page.status_int, 200) - - # add document - self.assertIn('add_document', page.forms) - form = page.forms['add_document'] - form['documents'].options=[(draft.pk, True, draft.name)] - page = form.submit('action',value='add_documents') - self.assertEqual(page.status_int, 302) - clist = CommunityList.objects.get(user__username="plain") - self.assertTrue(clist.added_docs.filter(pk=draft.pk)) - page = page.follow() - - self.assertContains(page, draft.name) - - # remove document - self.assertIn('remove_document_%s' % draft.pk, page.forms) - form = page.forms['remove_document_%s' % draft.pk] - page = form.submit('action',value='remove_document') - self.assertEqual(page.status_int, 302) - clist = CommunityList.objects.get(user__username="plain") - self.assertTrue(not clist.added_docs.filter(pk=draft.pk)) - page = page.follow() - - # add rule - r = self.client.post(url, { - "action": "add_rule", - "rule_type": "author_rfc", - "author_rfc-person": Person.objects.filter(documentauthor__document=draft).first().pk, - "author_rfc-state": State.objects.get(type="draft", slug="rfc").pk, - }) - self.assertEqual(r.status_code, 302) - clist = CommunityList.objects.get(user__username="plain") - self.assertTrue(clist.searchrule_set.filter(rule_type="author_rfc")) - - # add name_contains rule - r = self.client.post(url, { - "action": "add_rule", - "rule_type": "name_contains", - "name_contains-text": "draft.*mars", - "name_contains-state": State.objects.get(type="draft", slug="active").pk, - }) - self.assertEqual(r.status_code, 302) - clist = CommunityList.objects.get(user__username="plain") - self.assertTrue(clist.searchrule_set.filter(rule_type="name_contains")) - - # rule shows up on GET - r = self.client.get(url) - self.assertEqual(r.status_code, 200) - rule = clist.searchrule_set.filter(rule_type="author_rfc").first() - q = PyQuery(r.content) - self.assertEqual(len(q('#r%s' % rule.pk)), 1) - - # remove rule - r = self.client.post(url, { - "action": "remove_rule", - "rule": rule.pk, - }) - - clist = CommunityList.objects.get(user__username="plain") - self.assertTrue(not clist.searchrule_set.filter(rule_type="author_rfc")) + for id in self.email_or_name_set(person): + url = urlreverse( + ietf.community.views.manage_list, kwargs={"email_or_name": id} + ) + r = self.client.get(url, user="plain") + self.assertEqual(r.status_code, 200, msg=f"id='{id}', url='{url}'") + + # We can't call post() with follow=True because that 404's if + # the url contains unicode, because the django test client + # apparently re-encodes the already-encoded url. + def follow(r): + redirect_url = r.url or url + return self.client.get(redirect_url, user="plain") + + # add document + self.assertContains(r, "add_document") + r = self.client.post( + url, {"action": "add_documents", "documents": draft.pk} + ) + self.assertEqual(r.status_code, 302, msg=f"id='{id}', url='{url}'") + clist = CommunityList.objects.get(person__user__username="plain") + self.assertTrue(clist.added_docs.filter(pk=draft.pk)) + r = follow(r) + self.assertContains(r, draft.name, status_code=200) + + # remove document + self.assertContains(r, "remove_document_%s" % draft.pk) + r = self.client.post( + url, {"action": "remove_document", "document": draft.pk} + ) + self.assertEqual(r.status_code, 302, msg=f"id='{id}', url='{url}'") + clist = CommunityList.objects.get(person__user__username="plain") + self.assertTrue(not clist.added_docs.filter(pk=draft.pk)) + r = follow(r) + self.assertNotContains(r, draft.name, status_code=200) + + # add rule + r = self.client.post( + url, + { + "action": "add_rule", + "rule_type": "author_rfc", + "author_rfc-person": Person.objects.filter( + documentauthor__document=draft + ) + .first() + .pk, + "author_rfc-state": State.objects.get( + type="rfc", slug="published" + ).pk, + }, + ) + self.assertEqual(r.status_code, 302, msg=f"id='{id}', url='{url}'") + clist = CommunityList.objects.get(person__user__username="plain") + self.assertTrue(clist.searchrule_set.filter(rule_type="author_rfc")) + + # add name_contains rule + r = self.client.post( + url, + { + "action": "add_rule", + "rule_type": "name_contains", + "name_contains-text": "draft.*mars", + "name_contains-state": State.objects.get( + type="draft", slug="active" + ).pk, + }, + ) + self.assertEqual(r.status_code, 302, msg=f"id='{id}', url='{url}'") + clist = CommunityList.objects.get(person__user__username="plain") + self.assertTrue(clist.searchrule_set.filter(rule_type="name_contains")) + + # rule shows up on GET + r = self.client.get(url) + self.assertEqual(r.status_code, 200, msg=f"id='{id}', url='{url}'") + rule = clist.searchrule_set.filter(rule_type="author_rfc").first() + q = PyQuery(r.content) + self.assertEqual(len(q("#r%s" % rule.pk)), 1) + + # remove rule + r = self.client.post( + url, + { + "action": "remove_rule", + "rule": rule.pk, + }, + ) + + clist = CommunityList.objects.get(person__user__username="plain") + self.assertTrue(not clist.searchrule_set.filter(rule_type="author_rfc")) def test_manage_group_list(self): - draft = WgDraftFactory(group__acronym='mars') - RoleFactory(group__acronym='mars',name_id='chair',person=PersonFactory(user__username='marschairman')) + draft = WgDraftFactory(group__acronym="mars") + RoleFactory( + group__acronym="mars", + name_id="chair", + person=PersonFactory(user__username="marschairman"), + ) - url = urlreverse(ietf.community.views.manage_list, kwargs={ "acronym": draft.group.acronym }) + url = urlreverse( + ietf.community.views.manage_list, kwargs={"acronym": draft.group.acronym} + ) setup_default_community_list_for_group(draft.group) login_testing_unauthorized(self, "marschairman", url) @@ -197,95 +332,132 @@ def test_manage_group_list(self): self.assertEqual(r.status_code, 200) # Verify GET also works with non-WG and RG groups - for gtype in ['area','program']: + for gtype in ["area", "program"]: g = GroupFactory.create(type_id=gtype) # make sure the group's features have been initialized to improve coverage - _ = g.features # pyflakes:ignore + _ = g.features # pyflakes:ignore p = PersonFactory() - g.role_set.create(name_id={'area':'ad','program':'lead'}[gtype],person=p, email=p.email()) - url = urlreverse(ietf.community.views.manage_list, kwargs={ "acronym": g.acronym }) + g.role_set.create( + name_id={"area": "ad", "program": "lead"}[gtype], + person=p, + email=p.email(), + ) + url = urlreverse( + ietf.community.views.manage_list, kwargs={"acronym": g.acronym} + ) setup_default_community_list_for_group(g) - self.client.login(username=p.user.username,password=p.user.username+"+password") + self.client.login( + username=p.user.username, password=p.user.username + "+password" + ) r = self.client.get(url) self.assertEqual(r.status_code, 200) def test_track_untrack_document(self): - PersonFactory(user__username='plain') + person = self.complex_person(user__username="plain") draft = WgDraftFactory() - url = urlreverse(ietf.community.views.track_document, kwargs={ "username": "plain", "name": draft.name }) + url = urlreverse( + ietf.community.views.track_document, + kwargs={"email_or_name": person.email(), "name": draft.name}, + ) login_testing_unauthorized(self, "plain", url) - # track - r = self.client.get(url) - self.assertEqual(r.status_code, 200) - - r = self.client.post(url) - self.assertEqual(r.status_code, 302) - clist = CommunityList.objects.get(user__username="plain") - self.assertEqual(list(clist.added_docs.all()), [draft]) + for id in self.email_or_name_set(person): + url = urlreverse( + ietf.community.views.track_document, + kwargs={"email_or_name": id, "name": draft.name}, + ) - # untrack - url = urlreverse(ietf.community.views.untrack_document, kwargs={ "username": "plain", "name": draft.name }) - r = self.client.get(url) - self.assertEqual(r.status_code, 200) + # track + r = self.client.get(url) + self.assertEqual(r.status_code, 200, msg=f"id='{id}', url='{url}'") + + r = self.client.post(url) + self.assertEqual(r.status_code, 302, msg=f"id='{id}', url='{url}'") + clist = CommunityList.objects.get(person__user__username="plain") + self.assertEqual(list(clist.added_docs.all()), [draft]) + + # untrack + url = urlreverse( + ietf.community.views.untrack_document, + kwargs={"email_or_name": id, "name": draft.name}, + ) + r = self.client.get(url) + self.assertEqual(r.status_code, 200, msg=f"id='{id}', url='{url}'") - r = self.client.post(url) - self.assertEqual(r.status_code, 302) - clist = CommunityList.objects.get(user__username="plain") - self.assertEqual(list(clist.added_docs.all()), []) + r = self.client.post(url) + self.assertEqual(r.status_code, 302, msg=f"id='{id}', url='{url}'") + clist = CommunityList.objects.get(person__user__username="plain") + self.assertEqual(list(clist.added_docs.all()), []) def test_track_untrack_document_through_ajax(self): - PersonFactory(user__username='plain') + person = self.complex_person(user__username="plain") draft = WgDraftFactory() - url = urlreverse(ietf.community.views.track_document, kwargs={ "username": "plain", "name": draft.name }) + url = urlreverse( + ietf.community.views.track_document, + kwargs={"email_or_name": person.email(), "name": draft.name}, + ) login_testing_unauthorized(self, "plain", url) - # track - r = self.client.post(url, HTTP_X_REQUESTED_WITH='XMLHttpRequest') - self.assertEqual(r.status_code, 200) - self.assertEqual(r.json()["success"], True) - clist = CommunityList.objects.get(user__username="plain") - self.assertEqual(list(clist.added_docs.all()), [draft]) - - # untrack - url = urlreverse(ietf.community.views.untrack_document, kwargs={ "username": "plain", "name": draft.name }) - r = self.client.post(url, HTTP_X_REQUESTED_WITH='XMLHttpRequest') - self.assertEqual(r.status_code, 200) - self.assertEqual(r.json()["success"], True) - clist = CommunityList.objects.get(user__username="plain") - self.assertEqual(list(clist.added_docs.all()), []) + for id in self.email_or_name_set(person): + url = urlreverse( + ietf.community.views.track_document, + kwargs={"email_or_name": id, "name": draft.name}, + ) + + # track + r = self.client.post(url, HTTP_X_REQUESTED_WITH="XMLHttpRequest") + self.assertEqual(r.status_code, 200, msg=f"id='{id}', url='{url}'") + self.assertEqual(r.json()["success"], True) + clist = CommunityList.objects.get(person__user__username="plain") + self.assertEqual(list(clist.added_docs.all()), [draft]) + + # untrack + url = urlreverse( + ietf.community.views.untrack_document, + kwargs={"email_or_name": id, "name": draft.name}, + ) + r = self.client.post(url, HTTP_X_REQUESTED_WITH="XMLHttpRequest") + self.assertEqual(r.status_code, 200, msg=f"id='{id}', url='{url}'") + self.assertEqual(r.json()["success"], True) + clist = CommunityList.objects.get(person__user__username="plain") + self.assertEqual(list(clist.added_docs.all()), []) def test_csv(self): - PersonFactory(user__username='plain') + person = self.complex_person(user__username="plain") draft = WgDraftFactory() - url = urlreverse(ietf.community.views.export_to_csv, kwargs={ "username": "plain" }) + for id in self.email_or_name_set(person): + url = urlreverse( + ietf.community.views.export_to_csv, kwargs={"email_or_name": id} + ) - # without list - r = self.client.get(url) - self.assertEqual(r.status_code, 200) - - # with list - clist = CommunityList.objects.create(user=User.objects.get(username="plain")) - if not draft in clist.added_docs.all(): - clist.added_docs.add(draft) - SearchRule.objects.create( - community_list=clist, - rule_type="name_contains", - state=State.objects.get(type="draft", slug="active"), - text="test", - ) - r = self.client.get(url) - self.assertEqual(r.status_code, 200) - # this is a simple-minded test, we don't actually check the fields - self.assertContains(r, draft.name) + # without list + r = self.client.get(url) + self.assertEqual(r.status_code, 200, msg=f"id='{id}', url='{url}'") + + # with list + clist = CommunityList.objects.create(person=person) + if draft not in clist.added_docs.all(): + clist.added_docs.add(draft) + SearchRule.objects.create( + community_list=clist, + rule_type="name_contains", + state=State.objects.get(type="draft", slug="active"), + text="test", + ) + r = self.client.get(url) + self.assertEqual(r.status_code, 200, msg=f"id='{id}', url='{url}'") + # this is a simple-minded test, we don't actually check the fields + self.assertContains(r, draft.name) def test_csv_for_group(self): draft = WgDraftFactory() - url = urlreverse(ietf.community.views.export_to_csv, kwargs={ "acronym": draft.group.acronym }) + url = urlreverse( + ietf.community.views.export_to_csv, kwargs={"acronym": draft.group.acronym} + ) setup_default_community_list_for_group(draft.group) @@ -294,60 +466,85 @@ def test_csv_for_group(self): self.assertEqual(r.status_code, 200) def test_feed(self): - PersonFactory(user__username='plain') + person = self.complex_person(user__username="plain") draft = WgDraftFactory() - url = urlreverse(ietf.community.views.feed, kwargs={ "username": "plain" }) - - # without list - r = self.client.get(url) - self.assertEqual(r.status_code, 200) - - # with list - clist = CommunityList.objects.create(user=User.objects.get(username="plain")) - if not draft in clist.added_docs.all(): - clist.added_docs.add(draft) - SearchRule.objects.create( - community_list=clist, - rule_type="name_contains", - state=State.objects.get(type="draft", slug="active"), - text="test", - ) - r = self.client.get(url) - self.assertEqual(r.status_code, 200) - self.assertContains(r, draft.name) + for id in self.email_or_name_set(person): + url = urlreverse(ietf.community.views.feed, kwargs={"email_or_name": id}) - # only significant - r = self.client.get(url + "?significant=1") - self.assertEqual(r.status_code, 200) - self.assertNotContains(r, '') + # without list + r = self.client.get(url) + self.assertEqual(r.status_code, 200, msg=f"id='{id}', url='{url}'") + + # with list + clist = CommunityList.objects.create(person=person) + if draft not in clist.added_docs.all(): + clist.added_docs.add(draft) + SearchRule.objects.create( + community_list=clist, + rule_type="name_contains", + state=State.objects.get(type="draft", slug="active"), + text="test", + ) + r = self.client.get(url) + self.assertEqual(r.status_code, 200, msg=f"id='{id}', url='{url}'") + self.assertContains(r, draft.name) + + # test atom xml + xml = etree.fromstring(r.content) + ns = {"atom": "http://www.w3.org/2005/Atom"} + updated = xml.xpath("/atom:feed/atom:updated", namespaces=ns)[0].text + entries = xml.xpath("/atom:feed/atom:entry", namespaces=ns) + self.assertIn("+00:00", updated) # RFC 3339 compatible UTC TZ + for entry in entries: + updated = entry.xpath("atom:updated", namespaces=ns)[0].text + published = entry.xpath("atom:published", namespaces=ns)[0].text + entry_id = entry.xpath("atom:id", namespaces=ns)[0].text + self.assertIn("+00:00", updated) + self.assertIn("+00:00", published) + self.assertIn( + "urn:datatracker-ietf-org:event:", entry_id + ) # atom:entry:id must be a valid URN + + # only significant + r = self.client.get(url + "?significant=1") + self.assertEqual(r.status_code, 200, msg=f"id='{id}', url='{url}'") + self.assertNotContains(r, "") def test_feed_for_group(self): draft = WgDraftFactory() - url = urlreverse(ietf.community.views.feed, kwargs={ "acronym": draft.group.acronym }) + url = urlreverse( + ietf.community.views.feed, kwargs={"acronym": draft.group.acronym} + ) setup_default_community_list_for_group(draft.group) # test GET, rest is tested with personal list r = self.client.get(url) self.assertEqual(r.status_code, 200) - + def test_subscription(self): - PersonFactory(user__username='plain') + person = self.complex_person(user__username="plain") draft = WgDraftFactory() - url = urlreverse(ietf.community.views.subscription, kwargs={ "username": "plain" }) - + url = urlreverse( + ietf.community.views.subscription, kwargs={"email_or_name": person.email()} + ) login_testing_unauthorized(self, "plain", url) - # subscription without list - r = self.client.get(url) - self.assertEqual(r.status_code, 404) + for id in self.email_or_name_set(person): + url = urlreverse( + ietf.community.views.subscription, kwargs={"email_or_name": id} + ) + + # subscription without list + r = self.client.get(url) + self.assertEqual(r.status_code, 404, msg=f"id='{id}', url='{url}'") # subscription with list - clist = CommunityList.objects.create(user=User.objects.get(username="plain")) - if not draft in clist.added_docs.all(): + clist = CommunityList.objects.create(person=person) + if draft not in clist.added_docs.all(): clist.added_docs.add(draft) SearchRule.objects.create( community_list=clist, @@ -355,28 +552,51 @@ def test_subscription(self): state=State.objects.get(type="draft", slug="active"), text="test", ) - r = self.client.get(url) - self.assertEqual(r.status_code, 200) - # subscribe - email = Email.objects.filter(person__user__username="plain").first() - r = self.client.post(url, { "email": email.pk, "notify_on": "significant", "action": "subscribe" }) - self.assertEqual(r.status_code, 302) + for email in Email.objects.filter(person=person): + url = urlreverse( + ietf.community.views.subscription, kwargs={"email_or_name": email} + ) - subscription = EmailSubscription.objects.filter(community_list=clist, email=email, notify_on="significant").first() - - self.assertTrue(subscription) + r = self.client.get(url) + self.assertEqual(r.status_code, 200) - # delete subscription - r = self.client.post(url, { "subscription_id": subscription.pk, "action": "unsubscribe" }) - self.assertEqual(r.status_code, 302) - self.assertEqual(EmailSubscription.objects.filter(community_list=clist, email=email, notify_on="significant").count(), 0) + # subscribe + r = self.client.post( + url, + {"email": email.pk, "notify_on": "significant", "action": "subscribe"}, + ) + self.assertEqual(r.status_code, 302) + + subscription = EmailSubscription.objects.filter( + community_list=clist, email=email, notify_on="significant" + ).first() + + self.assertTrue(subscription) + + # delete subscription + r = self.client.post( + url, {"subscription_id": subscription.pk, "action": "unsubscribe"} + ) + self.assertEqual(r.status_code, 302) + self.assertEqual( + EmailSubscription.objects.filter( + community_list=clist, email=email, notify_on="significant" + ).count(), + 0, + ) def test_subscription_for_group(self): - draft = WgDraftFactory(group__acronym='mars') - RoleFactory(group__acronym='mars',name_id='chair',person=PersonFactory(user__username='marschairman')) + draft = WgDraftFactory(group__acronym="mars") + RoleFactory( + group__acronym="mars", + name_id="chair", + person=PersonFactory(user__username="marschairman"), + ) - url = urlreverse(ietf.community.views.subscription, kwargs={ "acronym": draft.group.acronym }) + url = urlreverse( + ietf.community.views.subscription, kwargs={"acronym": draft.group.acronym} + ) setup_default_community_list_for_group(draft.group) @@ -385,27 +605,136 @@ def test_subscription_for_group(self): # test GET, rest is tested with personal list r = self.client.get(url) self.assertEqual(r.status_code, 200) - - def test_notification(self): - PersonFactory(user__username='plain') + + @mock.patch("ietf.community.signals.notify_of_event") + def test_notification_signal_receiver(self, mock_notify_of_event): + """Saving a newly created DocEvent should notify subscribers + + This implicitly tests that notify_of_event_receiver is hooked up to the post_save signal. + """ + # Arbitrary model that's not a DocEvent + person = PersonFactory.build() # builds but does not save... + mock_notify_of_event.reset_mock() # clear any calls that resulted from the factories + person.save() + self.assertFalse(mock_notify_of_event.called) + + # build a DocEvent that is not yet persisted + doc = DocumentFactory() + event = DocEventFactory.build(by=person, doc=doc) # builds but does not save... + mock_notify_of_event.reset_mock() # clear any calls that resulted from the factories + event.save() + self.assertEqual( + mock_notify_of_event.call_count, + 1, + "notify_task should be run on creation of DocEvent", + ) + self.assertEqual(mock_notify_of_event.call_args, mock.call(event)) + + # save the existing DocEvent and see that no notification is sent + mock_notify_of_event.reset_mock() + event.save() + self.assertFalse( + mock_notify_of_event.called, + "notify_task should not be run save of on existing DocEvent", + ) + + # Mock out the on_commit call so we can tell whether the task was actually queued + @mock.patch("ietf.submit.views.transaction.on_commit", side_effect=lambda x: x()) + @mock.patch("ietf.community.signals.notify_event_to_subscribers_task") + def test_notify_of_event(self, mock_notify_task, mock_on_commit): + """The community notification task should be called as intended""" + person = PersonFactory() # builds but does not save... + doc = DocumentFactory() + event = DocEventFactory(by=person, doc=doc) + # be careful overriding SERVER_MODE - we do it here because the method + # under test does not make this call when in "test" mode + with override_settings(SERVER_MODE="not-test"): + notify_of_event(event) + self.assertTrue( + mock_notify_task.delay.called, + "notify_task should run for a DocEvent on a draft", + ) + mock_notify_task.reset_mock() + + event.skip_community_list_notification = True + # be careful overriding SERVER_MODE - we do it here because the method + # under test does not make this call when in "test" mode + with override_settings(SERVER_MODE="not-test"): + notify_of_event(event) + self.assertFalse( + mock_notify_task.delay.called, + "notify_task should not run when skip_community_list_notification is set", + ) + + event = DocEventFactory.build(by=person, doc=DocumentFactory(type_id="rfc")) + # be careful overriding SERVER_MODE - we do it here because the method + # under test does not make this call when in "test" mode + with override_settings(SERVER_MODE="not-test"): + notify_of_event(event) + self.assertFalse( + mock_notify_task.delay.called, + "notify_task should not run on a document with type 'rfc'", + ) + + @mock.patch("ietf.utils.mail.send_mail_text") + def test_notify_event_to_subscribers(self, mock_send_mail_text): + person = PersonFactory(user__username="plain") draft = WgDraftFactory() - clist = CommunityList.objects.create(user=User.objects.get(username="plain")) - if not draft in clist.added_docs.all(): + clist = CommunityList.objects.create(person=person) + if draft not in clist.added_docs.all(): clist.added_docs.add(draft) - EmailSubscription.objects.create(community_list=clist, email=Email.objects.filter(person__user__username="plain").first(), notify_on="significant") + sub_to_significant = EmailSubscription.objects.create( + community_list=clist, + email=Email.objects.filter(person__user__username="plain").first(), + notify_on="significant", + ) + sub_to_all = EmailSubscription.objects.create( + community_list=clist, + email=Email.objects.filter(person__user__username="plain").first(), + notify_on="all", + ) - mailbox_before = len(outbox) active_state = State.objects.get(type="draft", slug="active") system = Person.objects.get(name="(System)") - add_state_change_event(draft, system, None, active_state) - self.assertEqual(len(outbox), mailbox_before) + event = add_state_change_event(draft, system, None, active_state) + notify_event_to_subscribers(event) + self.assertEqual(mock_send_mail_text.call_count, 1) + address = mock_send_mail_text.call_args[0][1] + subject = mock_send_mail_text.call_args[0][3] + content = mock_send_mail_text.call_args[0][4] + self.assertEqual(address, sub_to_all.email.address) + self.assertIn(draft.name, subject) + self.assertIn(clist.long_name(), content) - mailbox_before = len(outbox) rfc_state = State.objects.get(type="draft", slug="rfc") - add_state_change_event(draft, system, active_state, rfc_state) - self.assertEqual(len(outbox), mailbox_before + 1) - self.assertTrue(draft.name in outbox[-1]["Subject"]) - - \ No newline at end of file + event = add_state_change_event(draft, system, active_state, rfc_state) + mock_send_mail_text.reset_mock() + notify_event_to_subscribers(event) + self.assertEqual(mock_send_mail_text.call_count, 2) + addresses = [ + call_args[0][1] for call_args in mock_send_mail_text.call_args_list + ] + subjects = {call_args[0][3] for call_args in mock_send_mail_text.call_args_list} + contents = {call_args[0][4] for call_args in mock_send_mail_text.call_args_list} + self.assertCountEqual( + addresses, + [sub_to_significant.email.address, sub_to_all.email.address], + ) + self.assertEqual(len(subjects), 1) + self.assertIn(draft.name, subjects.pop()) + self.assertEqual(len(contents), 1) + self.assertIn(clist.long_name(), contents.pop()) + + @mock.patch("ietf.community.utils.notify_event_to_subscribers") + def test_notify_event_to_subscribers_task(self, mock_notify): + d = DocEventFactory() + notify_event_to_subscribers_task(event_id=d.pk) + self.assertEqual(mock_notify.call_count, 1) + self.assertEqual(mock_notify.call_args, mock.call(d)) + mock_notify.reset_mock() + + d.delete() + notify_event_to_subscribers_task(event_id=d.pk) + self.assertFalse(mock_notify.called) diff --git a/ietf/community/urls.py b/ietf/community/urls.py index f80547ffad1..3ab132f2dca 100644 --- a/ietf/community/urls.py +++ b/ietf/community/urls.py @@ -4,11 +4,11 @@ from ietf.utils.urls import url urlpatterns = [ - url(r'^personal/(?P[^/]+)/$', views.view_list), - url(r'^personal/(?P[^/]+)/manage/$', views.manage_list), - url(r'^personal/(?P[^/]+)/trackdocument/(?P[^/]+)/$', views.track_document), - url(r'^personal/(?P[^/]+)/untrackdocument/(?P[^/]+)/$', views.untrack_document), - url(r'^personal/(?P[^/]+)/csv/$', views.export_to_csv), - url(r'^personal/(?P[^/]+)/feed/$', views.feed), - url(r'^personal/(?P[^/]+)/subscription/$', views.subscription), + url(r'^personal/(?P[^/]+)/$', views.view_list), + url(r'^personal/(?P[^/]+)/manage/$', views.manage_list), + url(r'^personal/(?P[^/]+)/trackdocument/(?P[^/]+)/$', views.track_document), + url(r'^personal/(?P[^/]+)/untrackdocument/(?P[^/]+)/$', views.untrack_document), + url(r'^personal/(?P[^/]+)/csv/$', views.export_to_csv), + url(r'^personal/(?P[^/]+)/feed/$', views.feed), + url(r'^personal/(?P[^/]+)/subscription/$', views.subscription), ] diff --git a/ietf/community/utils.py b/ietf/community/utils.py index 06da50011c0..b6137095ef5 100644 --- a/ietf/community/utils.py +++ b/ietf/community/utils.py @@ -1,4 +1,4 @@ -# Copyright The IETF Trust 2016-2020, All Rights Reserved +# Copyright The IETF Trust 2016-2023, All Rights Reserved # -*- coding: utf-8 -*- @@ -11,11 +11,9 @@ from ietf.community.models import CommunityList, EmailSubscription, SearchRule from ietf.doc.models import Document, State -from ietf.group.models import Role, Group +from ietf.group.models import Role from ietf.person.models import Person from ietf.ietfauth.utils import has_role -from django.contrib.auth.models import User -from django.shortcuts import get_object_or_404 from ietf.utils.mail import send_mail @@ -29,24 +27,12 @@ def states_of_significant_change(): Q(type="draft", slug__in=['rfc', 'dead']) ) -def lookup_community_list(username=None, acronym=None): - assert username or acronym - - if acronym: - group = get_object_or_404(Group, acronym=acronym) - clist = CommunityList.objects.filter(group=group).first() or CommunityList(group=group) - else: - user = get_object_or_404(User, username=username) - clist = CommunityList.objects.filter(user=user).first() or CommunityList(user=user) - - return clist - def can_manage_community_list(user, clist): if not user or not user.is_authenticated: return False - if clist.user: - return user == clist.user + if clist.person: + return user == clist.person.user elif clist.group: if has_role(user, 'Secretariat'): return True @@ -60,7 +46,7 @@ def reset_name_contains_index_for_rule(rule): if not rule.rule_type == "name_contains": return - rule.name_contains_index.set(Document.objects.filter(docalias__name__regex=rule.text)) + rule.name_contains_index.set(Document.objects.filter(name__regex=rule.text)) def update_name_contains_indexes_with_new_doc(doc): for r in SearchRule.objects.filter(rule_type="name_contains"): @@ -71,71 +57,113 @@ def update_name_contains_indexes_with_new_doc(doc): if re.search(r.text, doc.name) and not doc in r.name_contains_index.all(): r.name_contains_index.add(doc) + def docs_matching_community_list_rule(rule): docs = Document.objects.all() + + if rule.rule_type.endswith("_rfc"): + docs = docs.filter(type_id="rfc") # rule.state is ignored for RFCs + else: + docs = docs.filter(type_id="draft", states=rule.state) + if rule.rule_type in ['group', 'area', 'group_rfc', 'area_rfc']: - return docs.filter(Q(group=rule.group_id) | Q(group__parent=rule.group_id), states=rule.state) + return docs.filter(Q(group=rule.group_id) | Q(group__parent=rule.group_id)) elif rule.rule_type in ['group_exp']: - return docs.filter(group=rule.group_id, states=rule.state) + return docs.filter(group=rule.group_id) elif rule.rule_type.startswith("state_"): - return docs.filter(states=rule.state) - elif rule.rule_type in ["author", "author_rfc"]: - return docs.filter(states=rule.state, documentauthor__person=rule.person) + return docs + elif rule.rule_type == "author": + return docs.filter(documentauthor__person=rule.person) + elif rule.rule_type == "author_rfc": + return docs.filter(Q(rfcauthor__person=rule.person)|Q(rfcauthor__isnull=True,documentauthor__person=rule.person)) elif rule.rule_type == "ad": - return docs.filter(states=rule.state, ad=rule.person) + return docs.filter(ad=rule.person) elif rule.rule_type == "shepherd": - return docs.filter(states=rule.state, shepherd__person=rule.person) + return docs.filter(shepherd__person=rule.person) elif rule.rule_type == "name_contains": - return docs.filter(states=rule.state, searchrule=rule) + return docs.filter(searchrule=rule) raise NotImplementedError -def community_list_rules_matching_doc(doc): - states = list(doc.states.values_list("pk", flat=True)) +def community_list_rules_matching_doc(doc): rules = SearchRule.objects.none() + if doc.type_id not in ["draft", "rfc"]: + return rules # none + states = list(doc.states.values_list("pk", flat=True)) + # group and area rules if doc.group_id: groups = [doc.group_id] if doc.group.parent_id: groups.append(doc.group.parent_id) + rules_to_add = SearchRule.objects.filter(group__in=groups) + if doc.type_id == "rfc": + rules_to_add = rules_to_add.filter(rule_type__in=["group_rfc", "area_rfc"]) + else: + rules_to_add = rules_to_add.filter( + rule_type__in=["group", "area", "group_exp"], + state__in=states, + ) + rules |= rules_to_add + + # state rules (only relevant for I-Ds) + if doc.type_id == "draft": rules |= SearchRule.objects.filter( - rule_type__in=['group', 'area', 'group_rfc', 'area_rfc', 'group_exp'], + rule_type__in=[ + "state_iab", + "state_iana", + "state_iesg", + "state_irtf", + "state_ise", + "state_rfceditor", + "state_ietf", + ], state__in=states, - group__in=groups ) - rules |= SearchRule.objects.filter( - rule_type__in=['state_iab', 'state_iana', 'state_iesg', 'state_irtf', 'state_ise', 'state_rfceditor', 'state_ietf'], - state__in=states, - ) - - rules |= SearchRule.objects.filter( - rule_type__in=["author", "author_rfc"], - state__in=states, - person__in=list(Person.objects.filter(documentauthor__document=doc)), - ) - - if doc.ad_id: + # author rules + if doc.type_id == "rfc": + has_rfcauthors = doc.rfcauthor_set.exists() + rules |= SearchRule.objects.filter( + rule_type="author_rfc", + person__in=list( + Person.objects.filter( + Q(rfcauthor__document=doc) + if has_rfcauthors + else Q(documentauthor__document=doc) + ) + ), + ) + else: rules |= SearchRule.objects.filter( - rule_type="ad", + rule_type="author", state__in=states, - person=doc.ad_id, + person__in=list(Person.objects.filter(documentauthor__document=doc)), ) - if doc.shepherd_id: + # Other draft-only rules rules + if doc.type_id == "draft": + if doc.ad_id: + rules |= SearchRule.objects.filter( + rule_type="ad", + state__in=states, + person=doc.ad_id, + ) + + if doc.shepherd_id: + rules |= SearchRule.objects.filter( + rule_type="shepherd", + state__in=states, + person__email=doc.shepherd_id, + ) + rules |= SearchRule.objects.filter( - rule_type="shepherd", + rule_type="name_contains", state__in=states, - person__email=doc.shepherd_id, + name_contains_index=doc, # search our materialized index to avoid full scan ) - rules |= SearchRule.objects.filter( - rule_type="name_contains", - state__in=states, - name_contains_index=doc, # search our materialized index to avoid full scan - ) - return rules @@ -146,7 +174,11 @@ def docs_tracked_by_community_list(clist): # in theory, we could use an OR query, but databases seem to have # trouble with OR queries and complicated joins so do the OR'ing # manually - doc_ids = set(clist.added_docs.values_list("pk", flat=True)) + doc_ids = set() + for doc in clist.added_docs.all(): + doc_ids.add(doc.pk) + doc_ids.update(rfc.pk for rfc in doc.related_that_doc("became_rfc")) + for rule in clist.searchrule_set.all(): doc_ids = doc_ids | set(docs_matching_community_list_rule(rule).values_list("pk", flat=True)) diff --git a/ietf/community/views.py b/ietf/community/views.py index c67f992d6f8..08b1c24fe58 100644 --- a/ietf/community/views.py +++ b/ietf/community/views.py @@ -1,4 +1,4 @@ -# Copyright The IETF Trust 2012-2020, All Rights Reserved +# Copyright The IETF Trust 2012-2023, All Rights Reserved # -*- coding: utf-8 -*- @@ -10,62 +10,122 @@ from django.http import HttpResponse, HttpResponseRedirect, Http404 from django.shortcuts import get_object_or_404, render from django.contrib.auth.decorators import login_required +from django.utils import timezone from django.utils.html import strip_tags -import debug # pyflakes:ignore - -from ietf.community.models import SearchRule, EmailSubscription -from ietf.community.forms import SearchRuleTypeForm, SearchRuleForm, AddDocumentsForm, SubscriptionForm -from ietf.community.utils import lookup_community_list, can_manage_community_list -from ietf.community.utils import docs_tracked_by_community_list, docs_matching_community_list_rule -from ietf.community.utils import states_of_significant_change, reset_name_contains_index_for_rule +import debug # pyflakes:ignore + +from ietf.community.models import CommunityList, EmailSubscription, SearchRule +from ietf.community.forms import ( + SearchRuleTypeForm, + SearchRuleForm, + AddDocumentsForm, + SubscriptionForm, +) +from ietf.community.utils import can_manage_community_list +from ietf.community.utils import ( + docs_tracked_by_community_list, + docs_matching_community_list_rule, +) +from ietf.community.utils import ( + states_of_significant_change, + reset_name_contains_index_for_rule, +) +from ietf.group.models import Group from ietf.doc.models import DocEvent, Document from ietf.doc.utils_search import prepare_document_table +from ietf.person.utils import lookup_persons +from ietf.utils.decorators import ignore_view_kwargs +from ietf.utils.http import is_ajax from ietf.utils.response import permission_denied -def view_list(request, username=None): - clist = lookup_community_list(username) +def lookup_community_list(request, email_or_name=None, acronym=None): + """Finds a CommunityList for a person or group + + Instantiates an unsaved CommunityList if one is not found. + + If the person or group cannot be found and uniquely identified, raises an Http404 exception + """ + assert email_or_name or acronym + + if acronym: + group = get_object_or_404(Group, acronym=acronym) + clist = CommunityList.objects.filter(group=group).first() or CommunityList( + group=group + ) + else: + persons = lookup_persons(email_or_name) + if len(persons) > 1: + if hasattr(request.user, "person") and request.user.person in persons: + person = request.user.person + else: + raise Http404( + f"Unable to identify the CommunityList for {email_or_name}" + ) + else: + person = persons[0] + clist = CommunityList.objects.filter(person=person).first() or CommunityList( + person=person + ) + return clist + + +def view_list(request, email_or_name=None): + clist = lookup_community_list(request, email_or_name) # may raise Http404 docs = docs_tracked_by_community_list(clist) docs, meta = prepare_document_table(request, docs, request.GET) - subscribed = request.user.is_authenticated and EmailSubscription.objects.filter(community_list=clist, email__person__user=request.user) + subscribed = request.user.is_authenticated and ( + EmailSubscription.objects.none() + if clist.pk is None + else EmailSubscription.objects.filter( + community_list=clist, email__person__user=request.user + ) + ) + + return render( + request, + "community/view_list.html", + { + "clist": clist, + "docs": docs, + "meta": meta, + "can_manage_list": can_manage_community_list(request.user, clist), + "subscribed": subscribed, + "email_or_name": email_or_name, + }, + ) - return render(request, 'community/view_list.html', { - 'clist': clist, - 'docs': docs, - 'meta': meta, - 'can_manage_list': can_manage_community_list(request.user, clist), - 'subscribed': subscribed, - }) @login_required -def manage_list(request, username=None, acronym=None, group_type=None): +@ignore_view_kwargs("group_type") +def manage_list(request, email_or_name=None, acronym=None): # we need to be a bit careful because clist may not exist in the # database so we can't call related stuff on it yet - clist = lookup_community_list(username, acronym) + clist = lookup_community_list(request, email_or_name, acronym) # may raise Http404 if not can_manage_community_list(request.user, clist): permission_denied(request, "You do not have permission to access this view") - action = request.POST.get('action') + action = request.POST.get("action") - if request.method == 'POST' and action == 'add_documents': + if request.method == "POST" and action == "add_documents": add_doc_form = AddDocumentsForm(request.POST) if add_doc_form.is_valid(): if clist.pk is None: clist.save() - for d in add_doc_form.cleaned_data['documents']: - if not d in clist.added_docs.all(): + for d in add_doc_form.cleaned_data["documents"]: + if d not in clist.added_docs.all(): clist.added_docs.add(d) return HttpResponseRedirect("") else: add_doc_form = AddDocumentsForm() - if request.method == 'POST' and action == 'remove_document': - document_id = request.POST.get('document') + if request.method == "POST" and action == "remove_document": + document_id = request.POST.get("document") if clist.pk is not None and document_id: document = get_object_or_404(clist.added_docs, id=document_id) clist.added_docs.remove(document) @@ -73,30 +133,29 @@ def manage_list(request, username=None, acronym=None, group_type=None): return HttpResponseRedirect("") rule_form = None - if request.method == 'POST' and action == 'add_rule': + if request.method == "POST" and action == "add_rule": rule_type_form = SearchRuleTypeForm(request.POST) if rule_type_form.is_valid(): - rule_type = rule_type_form.cleaned_data['rule_type'] - - if rule_type: - rule_form = SearchRuleForm(clist, rule_type, request.POST) - if rule_form.is_valid(): - if clist.pk is None: - clist.save() - - rule = rule_form.save(commit=False) - rule.community_list = clist - rule.rule_type = rule_type - rule.save() - if rule.rule_type == "name_contains": - reset_name_contains_index_for_rule(rule) + rule_type = rule_type_form.cleaned_data["rule_type"] + if rule_type: + rule_form = SearchRuleForm(clist, rule_type, request.POST) + if rule_form.is_valid(): + if clist.pk is None: + clist.save() + + rule = rule_form.save(commit=False) + rule.community_list = clist + rule.rule_type = rule_type + rule.save() + if rule.rule_type == "name_contains": + reset_name_contains_index_for_rule(rule) return HttpResponseRedirect("") else: rule_type_form = SearchRuleTypeForm() - if request.method == 'POST' and action == 'remove_rule': - rule_pk = request.POST.get('rule') + if request.method == "POST" and action == "remove_rule": + rule_pk = request.POST.get("rule") if clist.pk is not None and rule_pk: rule = get_object_or_404(SearchRule, pk=rule_pk, community_list=clist) rule.delete() @@ -107,53 +166,74 @@ def manage_list(request, username=None, acronym=None, group_type=None): for r in rules: r.matching_documents_count = docs_matching_community_list_rule(r).count() - empty_rule_forms = { rule_type: SearchRuleForm(clist, rule_type) for rule_type, _ in SearchRule.RULE_TYPES } + empty_rule_forms = { + rule_type: SearchRuleForm(clist, rule_type) + for rule_type, _ in SearchRule.RULE_TYPES + } total_count = docs_tracked_by_community_list(clist).count() - all_forms = [f for f in [rule_type_form, rule_form, add_doc_form, *empty_rule_forms.values()] - if f is not None] - return render(request, 'community/manage_list.html', { - 'clist': clist, - 'rules': rules, - 'individually_added': clist.added_docs.all() if clist.pk is not None else [], - 'rule_type_form': rule_type_form, - 'rule_form': rule_form, - 'empty_rule_forms': empty_rule_forms, - 'total_count': total_count, - 'add_doc_form': add_doc_form, - 'all_forms': all_forms, - }) + all_forms = [ + f + for f in [rule_type_form, rule_form, add_doc_form, *empty_rule_forms.values()] + if f is not None + ] + return render( + request, + "community/manage_list.html", + { + "clist": clist, + "rules": rules, + "individually_added": ( + clist.added_docs.all() if clist.pk is not None else [] + ), + "rule_type_form": rule_type_form, + "rule_form": rule_form, + "empty_rule_forms": empty_rule_forms, + "total_count": total_count, + "add_doc_form": add_doc_form, + "all_forms": all_forms, + }, + ) @login_required -def track_document(request, name, username=None, acronym=None): - doc = get_object_or_404(Document, docalias__name=name) +def track_document(request, name, email_or_name=None, acronym=None): + doc = get_object_or_404(Document, name=name) if request.method == "POST": - clist = lookup_community_list(username, acronym) + clist = lookup_community_list( + request, email_or_name, acronym + ) # may raise Http404 if not can_manage_community_list(request.user, clist): permission_denied(request, "You do not have permission to access this view") if clist.pk is None: clist.save() - if not doc in clist.added_docs.all(): + if doc not in clist.added_docs.all(): clist.added_docs.add(doc) - if request.is_ajax(): - return HttpResponse(json.dumps({ 'success': True }), content_type='application/json') + if is_ajax(request): + return HttpResponse( + json.dumps({"success": True}), content_type="application/json" + ) else: return HttpResponseRedirect(clist.get_absolute_url()) - return render(request, "community/track_document.html", { - "name": doc.name, - }) + return render( + request, + "community/track_document.html", + { + "name": doc.name, + }, + ) + @login_required -def untrack_document(request, name, username=None, acronym=None): - doc = get_object_or_404(Document, docalias__name=name) - clist = lookup_community_list(username, acronym) +def untrack_document(request, name, email_or_name=None, acronym=None): + doc = get_object_or_404(Document, name=name) + clist = lookup_community_list(request, email_or_name, acronym) # may raise Http404 if not can_manage_community_list(request.user, clist): permission_denied(request, "You do not have permission to access this view") @@ -161,29 +241,35 @@ def untrack_document(request, name, username=None, acronym=None): if clist.pk is not None: clist.added_docs.remove(doc) - if request.is_ajax(): - return HttpResponse(json.dumps({ 'success': True }), content_type='application/json') + if is_ajax(request): + return HttpResponse( + json.dumps({"success": True}), content_type="application/json" + ) else: return HttpResponseRedirect(clist.get_absolute_url()) - return render(request, "community/untrack_document.html", { - "name": doc.name, - }) - + return render( + request, + "community/untrack_document.html", + { + "name": doc.name, + }, + ) -def export_to_csv(request, username=None, acronym=None, group_type=None): - clist = lookup_community_list(username, acronym) - response = HttpResponse(content_type='text/csv') +@ignore_view_kwargs("group_type") +def export_to_csv(request, email_or_name=None, acronym=None): + clist = lookup_community_list(request, email_or_name, acronym) # may raise Http404 + response = HttpResponse(content_type="text/csv") if clist.group: filename = "%s-draft-list.csv" % clist.group.acronym else: filename = "draft-list.csv" - response['Content-Disposition'] = 'attachment; filename=%s' % filename + response["Content-Disposition"] = "attachment; filename=%s" % filename - writer = csv.writer(response, dialect=csv.excel, delimiter=str(',')) + writer = csv.writer(response, dialect=csv.excel, delimiter=str(",")) header = [ "Name", @@ -196,12 +282,12 @@ def export_to_csv(request, username=None, acronym=None, group_type=None): ] writer.writerow(header) - docs = docs_tracked_by_community_list(clist).select_related('type', 'group', 'ad') + docs = docs_tracked_by_community_list(clist).select_related("type", "group", "ad") for doc in docs.prefetch_related("states", "tags"): row = [] row.append(doc.name) row.append(doc.title) - e = doc.latest_event(type='new_revision') + e = doc.latest_event(type="new_revision") row.append(e.time.strftime("%Y-%m-%d") if e else "") row.append(strip_tags(doc.friendly_state())) row.append(doc.group.acronym if doc.group else "") @@ -212,53 +298,73 @@ def export_to_csv(request, username=None, acronym=None, group_type=None): return response -def feed(request, username=None, acronym=None, group_type=None): - clist = lookup_community_list(username, acronym) - significant = request.GET.get('significant', '') == '1' +@ignore_view_kwargs("group_type") +def feed(request, email_or_name=None, acronym=None): + clist = lookup_community_list(request, email_or_name, acronym) # may raise Http404 + significant = request.GET.get("significant", "") == "1" - documents = docs_tracked_by_community_list(clist).values_list('pk', flat=True) - since = datetime.datetime.now() - datetime.timedelta(days=14) + documents = docs_tracked_by_community_list(clist).values_list("pk", flat=True) + updated = timezone.now() + since = updated - datetime.timedelta(days=14) - events = DocEvent.objects.filter( - doc__id__in=documents, - time__gte=since, - ).distinct().order_by('-time', '-id').select_related("doc") + events = ( + DocEvent.objects.filter( + doc__id__in=documents, + time__gte=since, + ) + .distinct() + .order_by("-time", "-id") + .select_related("doc") + ) if significant: - events = events.filter(type="changed_state", statedocevent__state__in=list(states_of_significant_change())) + events = events.filter( + type="changed_state", + statedocevent__state__in=list(states_of_significant_change()), + ) host = request.get_host() - feed_url = 'https://%s%s' % (host, request.get_full_path()) + feed_url = "https://%s%s" % (host, request.get_full_path()) feed_id = uuid.uuid5(uuid.NAMESPACE_URL, str(feed_url)) - title = '%s RSS Feed' % clist.long_name() + title = "%s RSS Feed" % clist.long_name() if significant: - subtitle = 'Significant document changes' + subtitle = "Significant document changes" else: - subtitle = 'Document changes' - - return render(request, 'community/atom.xml', { - 'clist': clist, - 'entries': events[:50], - 'title': title, - 'subtitle': subtitle, - 'id': feed_id.urn, - 'updated': datetime.datetime.now(), - }, content_type='text/xml') + subtitle = "Document changes" + + return render( + request, + "community/atom.xml", + { + "clist": clist, + "entries": events[:50], + "title": title, + "subtitle": subtitle, + "id": feed_id.urn, + "updated": updated, + }, + content_type="text/xml", + ) @login_required -def subscription(request, username=None, acronym=None, group_type=None): - clist = lookup_community_list(username, acronym) +@ignore_view_kwargs("group_type") +def subscription(request, email_or_name=None, acronym=None): + clist = lookup_community_list(request, email_or_name, acronym) # may raise Http404 if clist.pk is None: raise Http404 - existing_subscriptions = EmailSubscription.objects.filter(community_list=clist, email__person__user=request.user) + person = request.user.person + + existing_subscriptions = EmailSubscription.objects.filter( + community_list=clist, email__person=person + ) - if request.method == 'POST': + if request.method == "POST": action = request.POST.get("action") if action == "subscribe": - form = SubscriptionForm(request.user, clist, request.POST) + form = SubscriptionForm(person, clist, request.POST) if form.is_valid(): subscription = form.save(commit=False) subscription.community_list = clist @@ -267,14 +373,20 @@ def subscription(request, username=None, acronym=None, group_type=None): return HttpResponseRedirect("") elif action == "unsubscribe": - existing_subscriptions.filter(pk=request.POST.get("subscription_id")).delete() + existing_subscriptions.filter( + pk=request.POST.get("subscription_id") + ).delete() return HttpResponseRedirect("") else: - form = SubscriptionForm(request.user, clist) - - return render(request, 'community/subscription.html', { - 'clist': clist, - 'form': form, - 'existing_subscriptions': existing_subscriptions, - }) + form = SubscriptionForm(person, clist) + + return render( + request, + "community/subscription.html", + { + "clist": clist, + "form": form, + "existing_subscriptions": existing_subscriptions, + }, + ) diff --git a/ietf/context_processors.py b/ietf/context_processors.py index 618a896acd9..5aaa4ab2567 100644 --- a/ietf/context_processors.py +++ b/ietf/context_processors.py @@ -3,7 +3,9 @@ import sys import django from django.conf import settings +from django.utils import timezone from ietf import __version__, __patch__, __release_branch__, __release_hash__ +from opentelemetry.propagate import inject def server_mode(request): return {'server_mode': settings.SERVER_MODE} @@ -44,4 +46,14 @@ def sql_debug(request): def settings_info(request): return { 'settings': settings, - } \ No newline at end of file + } + +def timezone_now(request): + return { + 'timezone_now': timezone.now(), + } + +def traceparent_id(request): + context_extras = {} + inject(context_extras) + return { "otel": context_extras } diff --git a/ietf/cookies/.gitignore b/ietf/cookies/.gitignore deleted file mode 100644 index a74b07aee47..00000000000 --- a/ietf/cookies/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/*.pyc diff --git a/ietf/database-notes/.gitignore b/ietf/database-notes/.gitignore deleted file mode 100644 index c7013ced9df..00000000000 --- a/ietf/database-notes/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -/*.pyc -/settings_local.py diff --git a/ietf/dbtemplate/fixtures/nomcom_templates.xml b/ietf/dbtemplate/fixtures/nomcom_templates.xml index 369cad73c96..e7065b84cd3 100644 --- a/ietf/dbtemplate/fixtures/nomcom_templates.xml +++ b/ietf/dbtemplate/fixtures/nomcom_templates.xml @@ -1,190 +1,190 @@ - - - - /nomcom/defaults/home.rst - Home page of group - - rst - Home page -========= - -This is the home page of the nomcom group. - - - - /nomcom/defaults/email/inexistent_person.txt - Email sent to chair of nomcom and secretariat when Email and Person are created if some of them don't exist - $email: Newly created email -$fullname: Fullname of the new person -$person_id: Id of the new Person object -$group: Name of the group - plain - Hello, - -A new person with name $fullname and email $email has been created. The new Person object has the following id: '$person_id'. - -Please, check if there is some more action nedeed. - - - - /nomcom/defaults/email/new_nominee.txt - Email sent to nominees when they are nominated - $nominee: Full name of the nominee -$position: Name of the position -$domain: Server domain -$accept_url: Url hash to accept nominations -$decline_url: Url hash to decline nominations - plain - Hi, - -You have been nominated for the position of $position. - -The NomCom would appreciate receiving an indication of whether or not you accept this nomination to stand for consideration as a candidate for this position. - -You can accept the nomination via web going to the following link http://$domain$accept_url or decline the nomination going the following link http://$domain$decline_url - -If you accept, you will need to fill out a questionnaire. You will receive the questionnaire by email. - -Best regards, - - - - - /nomcom/defaults/email/new_nomination.txt - Email sent to nominators and secretariat when the nominators make the nominations - $nominator: Full name of the nominator -$nominator_email: Email of the nominator -$nominee: Full name of the nominee -$nominee_email: Email of the nominee -$position: Nomination position - plain - A new nomination have been received. - -Nominator: $nominator ($nominator_email) -Nominee: $nominee ($nominee_email) -Position: $position - - - - /nomcom/defaults/position/questionnaire.txt - Questionnaire sent to the nomine - $position: Position - plain - Enter here the questionnaire for the position $position: - -Questionnaire - - - - /nomcom/defaults/position/requirements - Position requirements - $position: Position - rst - These are the requirements for the position $position: - -Requirements. - - - - /nomcom/defaults/position/header_questionnaire.txt - Header of the email that contains the questionnaire sent to the nomine - $nominee: Full name of the nomine -$position: Position - plain - Hi $nominee, this is the questionnaire for the position $position: - - - - - - /nomcom/defaults/email/nomination_accept_reminder.txt - Email sent to nominees asking them to accept (or decline) the nominations. - $positions: Nomination positions - plain - Hi, - -You have been nominated for the position of $position. - -The NomCom would appreciate receiving an indication of whether or not you accept this nomination to stand for consideration as a candidate for this position. - -You can accept the nomination via web going to the following link http://$domain$accept_url or decline the nomination going the following link http://$domain$decline_url - -If you accept, you will need to fill out a questionnaire. - -Best regards, - - - - /nomcom/defaults/email/nomination_receipt.txt - Email sent to nominator to get a confirmation mail containing feedback in cleartext - $nominee: Full name of the nominee -$position: Name of the position -$domain: Server domain -$accept_url: Url hash to accept nominations -$decline_url: Url hash to decline nominations - plain - Hi, - -Your nomination of $nominee for the position of -$position has been received and registered. - -The following comments have also been registered: - --------------------------------------------------------------------------- -$comments --------------------------------------------------------------------------- - -Thank you, - - - - /nomcom/defaults/email/feedback_receipt.txt - Email sent to feedback author to get a confirmation mail containing feedback in cleartext - $nominee: Full name of the nominee -$position: Nomination position -$comments: Comments on this candidate - plain - Hi, - -Your input regarding $about has been received and registered. - -The following comments have been registered: - --------------------------------------------------------------------------- -$comments --------------------------------------------------------------------------- - -Thank you, - - - - /nomcom/defaults/email/questionnaire_reminder.txt - Email sent to nominees reminding them to complete a questionnaire - $positions: Nomination positions - plain - -Thank you for accepting your nomination for the position of $position. - -Please remember to complete and return the questionnaire for this position at your earliest opportunity. -The questionaire is repeated below for your convenience. - --------- - - - - /nomcom/defaults/topic/description - Description of Topic - $topic: Topic' - rst - This is a description of the topic "$topic" - -Describe the topic and add any information/instructions for the responder here. - - - - /nomcom/defaults/iesg_requirements - Generic IESG Requirements - rst - Generic IESG Requirements Yo! - - + + + + /nomcom/defaults/home.rst + Home page of group + + rst + Home page +========= + +This is the home page of the nomcom group. + + + + /nomcom/defaults/email/inexistent_person.txt + Email sent to chair of nomcom and secretariat when Email and Person are created if some of them don't exist + $email: Newly created email +$fullname: Fullname of the new person +$person_id: Id of the new Person object +$group: Name of the group + plain + Hello, + +A new person with name $fullname and email $email has been created. The new Person object has the following id: '$person_id'. + +Please, check if there is some more action nedeed. + + + + /nomcom/defaults/email/new_nominee.txt + Email sent to nominees when they are nominated + $nominee: Full name of the nominee +$position: Name of the position +$domain: Server domain +$accept_url: Url hash to accept nominations +$decline_url: Url hash to decline nominations + plain + Hi, + +You have been nominated for the position of $position. + +The NomCom would appreciate receiving an indication of whether or not you accept this nomination to stand for consideration as a candidate for this position. + +You can accept the nomination via web going to the following link https://$domain$accept_url or decline the nomination going the following link https://$domain$decline_url + +If you accept, you will need to fill out a questionnaire. You will receive the questionnaire by email. + +Best regards, + + + + + /nomcom/defaults/email/new_nomination.txt + Email sent to nominators and secretariat when the nominators make the nominations + $nominator: Full name of the nominator +$nominator_email: Email of the nominator +$nominee: Full name of the nominee +$nominee_email: Email of the nominee +$position: Nomination position + plain + A new nomination have been received. + +Nominator: $nominator ($nominator_email) +Nominee: $nominee ($nominee_email) +Position: $position + + + + /nomcom/defaults/position/questionnaire.txt + Questionnaire sent to the nomine + $position: Position + plain + Enter here the questionnaire for the position $position: + +Questionnaire + + + + /nomcom/defaults/position/requirements + Position requirements + $position: Position + rst + These are the requirements for the position $position: + +Requirements. + + + + /nomcom/defaults/position/header_questionnaire.txt + Header of the email that contains the questionnaire sent to the nomine + $nominee: Full name of the nomine +$position: Position + plain + Hi $nominee, this is the questionnaire for the position $position: + + + + + + /nomcom/defaults/email/nomination_accept_reminder.txt + Email sent to nominees asking them to accept (or decline) the nominations. + $positions: Nomination positions + plain + Hi, + +You have been nominated for the position of $position. + +The NomCom would appreciate receiving an indication of whether or not you accept this nomination to stand for consideration as a candidate for this position. + +You can accept the nomination via web going to the following link https://$domain$accept_url or decline the nomination going the following link https://$domain$decline_url + +If you accept, you will need to fill out a questionnaire. + +Best regards, + + + + /nomcom/defaults/email/nomination_receipt.txt + Email sent to nominator to get a confirmation mail containing feedback in cleartext + $nominee: Full name of the nominee +$position: Name of the position +$domain: Server domain +$accept_url: Url hash to accept nominations +$decline_url: Url hash to decline nominations + plain + Hi, + +Your nomination of $nominee for the position of +$position has been received and registered. + +The following comments have also been registered: + +-------------------------------------------------------------------------- +$comments +-------------------------------------------------------------------------- + +Thank you, + + + + /nomcom/defaults/email/feedback_receipt.txt + Email sent to feedback author to get a confirmation mail containing feedback in cleartext + $nominee: Full name of the nominee +$position: Nomination position +$comments: Comments on this candidate + plain + Hi, + +Your input regarding $about has been received and registered. + +The following comments have been registered: + +-------------------------------------------------------------------------- +$comments +-------------------------------------------------------------------------- + +Thank you, + + + + /nomcom/defaults/email/questionnaire_reminder.txt + Email sent to nominees reminding them to complete a questionnaire + $positions: Nomination positions + plain + +Thank you for accepting your nomination for the position of $position. + +Please remember to complete and return the questionnaire for this position at your earliest opportunity. +The questionnaire is repeated below for your convenience. + +-------- + + + + /nomcom/defaults/topic/description + Description of Topic + $topic: Topic' + rst + This is a description of the topic "$topic" + +Describe the topic and add any information/instructions for the responder here. + + + + /nomcom/defaults/iesg_requirements + Generic IESG Requirements + rst + Generic IESG Requirements Yo! + + diff --git a/ietf/dbtemplate/migrations/0001_initial.py b/ietf/dbtemplate/migrations/0001_initial.py index 53defbda2cb..a3a23451f00 100644 --- a/ietf/dbtemplate/migrations/0001_initial.py +++ b/ietf/dbtemplate/migrations/0001_initial.py @@ -1,10 +1,6 @@ -# Copyright The IETF Trust 2018-2020, All Rights Reserved -# -*- coding: utf-8 -*- -# Generated by Django 1.11.10 on 2018-02-20 10:52 - - -from typing import List, Tuple # pyflakes:ignore +# Generated by Django 2.2.28 on 2023-03-20 19:22 +from typing import List, Tuple from django.db import migrations, models @@ -12,8 +8,8 @@ class Migration(migrations.Migration): initial = True - dependencies = [ - ] # type: List[Tuple[str]] + dependencies: List[Tuple[str, str]] = [ + ] operations = [ migrations.CreateModel( diff --git a/ietf/dbtemplate/migrations/0002_auto_20180220_1052.py b/ietf/dbtemplate/migrations/0002_auto_20180220_1052.py deleted file mode 100644 index 9cff93f4afe..00000000000 --- a/ietf/dbtemplate/migrations/0002_auto_20180220_1052.py +++ /dev/null @@ -1,32 +0,0 @@ -# Copyright The IETF Trust 2018-2020, All Rights Reserved -# -*- coding: utf-8 -*- -# Generated by Django 1.11.10 on 2018-02-20 10:52 - - -from django.db import migrations -import django.db.models.deletion -import ietf.utils.models - - -class Migration(migrations.Migration): - - initial = True - - dependencies = [ - ('group', '0001_initial'), - ('name', '0001_initial'), - ('dbtemplate', '0001_initial'), - ] - - operations = [ - migrations.AddField( - model_name='dbtemplate', - name='group', - field=ietf.utils.models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='group.Group'), - ), - migrations.AddField( - model_name='dbtemplate', - name='type', - field=ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='name.DBTemplateTypeName'), - ), - ] diff --git a/ietf/dbtemplate/migrations/0002_auto_20230320_1222.py b/ietf/dbtemplate/migrations/0002_auto_20230320_1222.py new file mode 100644 index 00000000000..5aa713635f4 --- /dev/null +++ b/ietf/dbtemplate/migrations/0002_auto_20230320_1222.py @@ -0,0 +1,29 @@ +# Generated by Django 2.2.28 on 2023-03-20 19:22 + +from django.db import migrations +import django.db.models.deletion +import ietf.utils.models + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ('dbtemplate', '0001_initial'), + ('group', '0001_initial'), + ('name', '0001_initial'), + ] + + operations = [ + migrations.AddField( + model_name='dbtemplate', + name='group', + field=ietf.utils.models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='group.Group'), + ), + migrations.AddField( + model_name='dbtemplate', + name='type', + field=ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='name.DBTemplateTypeName'), + ), + ] diff --git a/ietf/dbtemplate/migrations/0003_adjust_review_templates.py b/ietf/dbtemplate/migrations/0003_adjust_review_templates.py deleted file mode 100644 index d3038c946c6..00000000000 --- a/ietf/dbtemplate/migrations/0003_adjust_review_templates.py +++ /dev/null @@ -1,119 +0,0 @@ -# Copyright The IETF Trust 2019-2020, All Rights Reserved -# -*- coding: utf-8 -*- -# Generated by Django 1.11.20 on 2019-03-05 11:39 - - -from django.db import migrations - -def forward(apps, schema_editor): - DBTemplate = apps.get_model('dbtemplate', 'DBTemplate') - DBTemplate.objects.filter(id=186).update(content="""I am the assigned Gen-ART reviewer for this draft. The General Area -Review Team (Gen-ART) reviews all IETF documents being processed -by the IESG for the IETF Chair. Please treat these comments just -like any other last call comments. - -For more information, please see the FAQ at - -. - -Document: {{ assignment.review_request.doc.name }}-?? -Reviewer: {{ assignment.reviewer.person.plain_name }} -Review Date: {{ today }} -IETF LC End Date: {% if assignment.review_request.doc.most_recent_ietflc %}{{ assignment.review_request.doc.most_recent_ietflc.expires|date:"Y-m-d" }}{% else %}None{% endif %} -IESG Telechat date: {{ assignment.review_request.doc.telechat_date|default:'Not scheduled for a telechat' }} - -Summary: - -Major issues: - -Minor issues: - -Nits/editorial comments: -""") - - DBTemplate.objects.filter(id=187).update(content="""I am the assigned Gen-ART reviewer for this draft. The General Area -Review Team (Gen-ART) reviews all IETF documents being processed -by the IESG for the IETF Chair. Please wait for direction from your -document shepherd or AD before posting a new version of the draft. - -For more information, please see the FAQ at - -. - -Document: {{ assignment.review_request.doc.name }}-?? -Reviewer: {{ assignment.reviewer.person.plain_name }} -Review Date: {{ today }} -IETF LC End Date: {% if assignment.review_req.doc.most_recent_ietflc %}{{ assignment.review_request.doc.most_recent_ietflc.expires|date:"Y-m-d" }}{% else %}None{% endif %} -IESG Telechat date: {{ assignment.review_request.doc.telechat_date|default:'Not scheduled for a telechat' }} - -Summary: - -Major issues: - -Minor issues: - -Nits/editorial comments: - -""") - -def reverse(apps, schema_editor): - DBTemplate = apps.get_model('dbtemplate','DBTemplate') - DBTemplate.objects.filter(id=186).update(content="""I am the assigned Gen-ART reviewer for this draft. The General Area -Review Team (Gen-ART) reviews all IETF documents being processed -by the IESG for the IETF Chair. Please treat these comments just -like any other last call comments. - -For more information, please see the FAQ at - -. - -Document: {{ review_req.doc.name }}-?? -Reviewer: {{ review_req.reviewer.person.plain_name }} -Review Date: {{ today }} -IETF LC End Date: {% if review_req.doc.most_recent_ietflc %}{{ review_req.doc.most_recent_ietflc.expires|date:"Y-m-d" }}{% else %}None{% endif %} -IESG Telechat date: {{ review_req.doc.telechat_date|default:'Not scheduled for a telechat' }} - -Summary: - -Major issues: - -Minor issues: - -Nits/editorial comments: - -""") - DBTemplate.objects.filter(id=187).update(content="""I am the assigned Gen-ART reviewer for this draft. The General Area -Review Team (Gen-ART) reviews all IETF documents being processed -by the IESG for the IETF Chair. Please wait for direction from your -document shepherd or AD before posting a new version of the draft. - -For more information, please see the FAQ at - -. - -Document: {{ review_req.doc.name }}-?? -Reviewer: {{ review_req.reviewer.person.plain_name }} -Review Date: {{ today }} -IETF LC End Date: {% if review_req.doc.most_recent_ietflc %}{{ review_req.doc.most_recent_ietflc.expires|date:"Y-m-d" }}{% else %}None{% endif %} -IESG Telechat date: {{ review_req.doc.telechat_date|default:'Not scheduled for a telechat' }} - -Summary: - -Major issues: - -Minor issues: - -Nits/editorial comments: - -""") - -class Migration(migrations.Migration): - - dependencies = [ - ('dbtemplate', '0002_auto_20180220_1052'), - ('doc','0011_reviewassignmentdocevent'), - ] - - operations = [ - migrations.RunPython(forward, reverse) - ] diff --git a/ietf/dbtemplate/migrations/0004_adjust_assignment_email_summary_templates.py b/ietf/dbtemplate/migrations/0004_adjust_assignment_email_summary_templates.py deleted file mode 100644 index f9a24960908..00000000000 --- a/ietf/dbtemplate/migrations/0004_adjust_assignment_email_summary_templates.py +++ /dev/null @@ -1,290 +0,0 @@ -# Copyright The IETF Trust 2019-2020, All Rights Reserved -# -*- coding: utf-8 -*- -# Generated by Django 1.11.20 on 2019-03-13 13:41 - - -from django.db import migrations - -def forward(apps, schema_editor): - DBTemplate = apps.get_model('dbtemplate','DBTemplate') - - DBTemplate.objects.filter(pk=182).update(content="""{% autoescape off %}Subject: Open review assignments in {{group.acronym}} - -The following reviewers have assignments:{% for r in review_assignments %}{% ifchanged r.section %} - -{{r.section}} - -{% if r.section == 'Early review requests:' %}Reviewer Due Draft{% else %}Reviewer LC end Draft{% endif %}{% endifchanged %} -{{ r.reviewer.person.plain_name|ljust:"22" }} {% if r.section == 'Early review requests:' %}{{ r.review_request.deadline|date:"Y-m-d" }}{% else %}{{ r.lastcall_ends|default:"None " }}{% endif %} {{ r.review_request.doc_id }}-{% if r.review_request..requested_rev %}{{ r.review_request.requested_rev }}{% else %}{{ r.review_request..doc.rev }}{% endif %} {{ r.earlier_review_mark }}{% endfor %} - -* Other revision previously reviewed -** This revision already reviewed - -{% if rotation_list %}Next in the reviewer rotation: - -{% for p in rotation_list %} {{ p }} -{% endfor %}{% endif %}{% endautoescape %} -""") - - DBTemplate.objects.filter(pk=183).update(content="""{% autoescape off %}Subject: Review Assignments - -Hi all, - -The following reviewers have assignments:{% for r in review_assignments %}{% ifchanged r.section %} - -{{r.section}} - -{% if r.section == 'Early review requests:' %}Reviewer Due Draft{% else %}Reviewer Type LC end Draft{% endif %}{% endifchanged %} -{{ r.reviewer.person.plain_name|ljust:"22" }} {% if r.section == 'Early review requests:' %}{{ r.review_request.deadline|date:"Y-m-d" }}{% else %}{{r.review_request.type.name|ljust:"10"}}{{ r.lastcall_ends|default:"None " }}{% endif %} {{ r.review_request.doc_id }}-{% if r.review_request.requested_rev %}{{ r.review_request.requested_rev }}{% else %}{{ r.review_request.doc.rev }}{% endif %}{% if r.earlier_review_mark %} {{ r.earlier_review_mark }}{% endif %}{% endfor %} - -* Other revision previously reviewed -** This revision already reviewed - -{% if rotation_list %}Next in the reviewer rotation: - -{% for p in rotation_list %} {{ p }} -{% endfor %}{% endif %} -The LC and Telechat review templates are included below: -------------------------------------------------------- - --- Begin LC Template -- -I am the assigned Gen-ART reviewer for this draft. The General Area -Review Team (Gen-ART) reviews all IETF documents being processed -by the IESG for the IETF Chair. Please treat these comments just -like any other last call comments. - -For more information, please see the FAQ at - -. - -Document: -Reviewer: -Review Date: -IETF LC End Date: -IESG Telechat date: (if known) - -Summary: - -Major issues: - -Minor issues: - -Nits/editorial comments: - --- End LC Template -- - --- Begin Telechat Template -- -I am the assigned Gen-ART reviewer for this draft. The General Area -Review Team (Gen-ART) reviews all IETF documents being processed -by the IESG for the IETF Chair. Please wait for direction from your -document shepherd or AD before posting a new version of the draft. - -For more information, please see the FAQ at - -. - -Document: -Reviewer: -Review Date: -IETF LC End Date: -IESG Telechat date: (if known) - -Summary: - -Major issues: - -Minor issues: - -Nits/editorial comments: - --- End Telechat Template -- -{% endautoescape %} - -""") - - DBTemplate.objects.filter(pk=184).update(content="""{% autoescape off %}Subject: Assignments - -Review instructions and related resources are at: -http://tools.ietf.org/area/sec/trac/wiki/SecDirReview{% for r in review_assignments %}{% ifchanged r.section %} - -{{r.section}} - -{% if r.section == 'Early review requests:' %}Reviewer Due Draft{% else %}Reviewer LC end Draft{% endif %}{% endifchanged %} -{{ r.reviewer.person.plain_name|ljust:"22" }}{{ r.earlier_review|yesno:'R, , ' }}{% if r.section == 'Early review requests:' %}{{ r.review_request.deadline|date:"Y-m-d" }}{% else %}{{ r.lastcall_ends|default:"None " }}{% endif %} {{ r.review_request.doc_id }}-{% if r.review_request.requested_rev %}{{ r.review_request.requested_rev }}{% else %}{{ r.review_request.doc.rev }}{% endif %}{% endfor %} - -{% if rotation_list %}Next in the reviewer rotation: - -{% for p in rotation_list %} {{ p }} -{% endfor %}{% endif %}{% endautoescape %} - -""") - - DBTemplate.objects.filter(pk=185).update(content="""{% autoescape off %}Subject: Open review assignments in {{group.acronym}} - -Review instructions and related resources are at: - - -The following reviewers have assignments:{% for r in review_assignments %}{% ifchanged r.section %} - -{{r.section}} - -{% if r.section == 'Early review requests:' %}Reviewer Due Draft{% else %}Reviewer LC end Draft{% endif %}{% endifchanged %} -{{ r.reviewer.person.plain_name|ljust:"22" }} {% if r.section == 'Early review requests:' %}{{ r.review_request.deadline|date:"Y-m-d" }}{% else %}{{ r.lastcall_ends|default:"None " }}{% endif %} {{ r.review_request.doc_id }}-{% if r.review_request.requested_rev %}{{ r.review_request.requested_rev }}{% else %}{{ r.review_request.doc.rev }}{% endif %} {{ r.earlier_review_mark }}{% endfor %} - -* Other revision previously reviewed -** This revision already reviewed - -{% if rotation_list %}Next in the reviewer rotation: - -{% for p in rotation_list %} {{ p }} -{% endfor %}{% endif %}{% endautoescape %} - -""") - - -def reverse(apps, schema_editor): - DBTemplate = apps.get_model('dbtemplate','DBTemplate') - - DBTemplate.objects.filter(pk=182).update(content="""{% autoescape off %}Subject: Open review assignments in {{group.acronym}} - -The following reviewers have assignments:{% for r in review_requests %}{% ifchanged r.section %} - -{{r.section}} - -{% if r.section == 'Early review requests:' %}Reviewer Due Draft{% else %}Reviewer LC end Draft{% endif %}{% endifchanged %} -{{ r.reviewer.person.plain_name|ljust:"22" }} {% if r.section == 'Early review requests:' %}{{ r.deadline|date:"Y-m-d" }}{% else %}{{ r.lastcall_ends|default:"None " }}{% endif %} {{ r.doc_id }}-{% if r.requested_rev %}{{ r.requested_rev }}{% else %}{{ r.doc.rev }}{% endif %} {{ r.earlier_review_mark }}{% endfor %} - -* Other revision previously reviewed -** This revision already reviewed - -{% if rotation_list %}Next in the reviewer rotation: - -{% for p in rotation_list %} {{ p }} -{% endfor %}{% endif %}{% endautoescape %} -""") - - DBTemplate.objects.filter(pk=183).update(content="""{% autoescape off %}Subject: Review Assignments - -Hi all, - -The following reviewers have assignments:{% for r in review_requests %}{% ifchanged r.section %} - -{{r.section}} - -{% if r.section == 'Early review requests:' %}Reviewer Due Draft{% else %}Reviewer Type LC end Draft{% endif %}{% endifchanged %} -{{ r.reviewer.person.plain_name|ljust:"22" }} {% if r.section == 'Early review requests:' %}{{ r.deadline|date:"Y-m-d" }}{% else %}{{r.type.name|ljust:"10"}}{{ r.lastcall_ends|default:"None " }}{% endif %} {{ r.doc_id }}-{% if r.requested_rev %}{{ r.requested_rev }}{% else %}{{ r.doc.rev }}{% endif %}{% if r.earlier_review_mark %} {{ r.earlier_review_mark }}{% endif %}{% endfor %} - -* Other revision previously reviewed -** This revision already reviewed - -{% if rotation_list %}Next in the reviewer rotation: - -{% for p in rotation_list %} {{ p }} -{% endfor %}{% endif %} -The LC and Telechat review templates are included below: -------------------------------------------------------- - --- Begin LC Template -- -I am the assigned Gen-ART reviewer for this draft. The General Area -Review Team (Gen-ART) reviews all IETF documents being processed -by the IESG for the IETF Chair. Please treat these comments just -like any other last call comments. - -For more information, please see the FAQ at - -. - -Document: -Reviewer: -Review Date: -IETF LC End Date: -IESG Telechat date: (if known) - -Summary: - -Major issues: - -Minor issues: - -Nits/editorial comments: - --- End LC Template -- - --- Begin Telechat Template -- -I am the assigned Gen-ART reviewer for this draft. The General Area -Review Team (Gen-ART) reviews all IETF documents being processed -by the IESG for the IETF Chair. Please wait for direction from your -document shepherd or AD before posting a new version of the draft. - -For more information, please see the FAQ at - -. - -Document: -Reviewer: -Review Date: -IETF LC End Date: -IESG Telechat date: (if known) - -Summary: - -Major issues: - -Minor issues: - -Nits/editorial comments: - --- End Telechat Template -- -{% endautoescape %} - -""") - - DBTemplate.objects.filter(pk=184).update(content="""{% autoescape off %}Subject: Assignments - -Review instructions and related resources are at: -http://tools.ietf.org/area/sec/trac/wiki/SecDirReview{% for r in review_requests %}{% ifchanged r.section %} - -{{r.section}} - -{% if r.section == 'Early review requests:' %}Reviewer Due Draft{% else %}Reviewer LC end Draft{% endif %}{% endifchanged %} -{{ r.reviewer.person.plain_name|ljust:"22" }}{{ r.earlier_review|yesno:'R, , ' }}{% if r.section == 'Early review requests:' %}{{ r.deadline|date:"Y-m-d" }}{% else %}{{ r.lastcall_ends|default:"None " }}{% endif %} {{ r.doc_id }}-{% if r.requested_rev %}{{ r.requested_rev }}{% else %}{{ r.doc.rev }}{% endif %}{% endfor %} - -{% if rotation_list %}Next in the reviewer rotation: - -{% for p in rotation_list %} {{ p }} -{% endfor %}{% endif %}{% endautoescape %} - -""") - - DBTemplate.objects.filter(pk=185).update(content="""{% autoescape off %}Subject: Open review assignments in {{group.acronym}} - -Review instructions and related resources are at: - - -The following reviewers have assignments:{% for r in review_requests %}{% ifchanged r.section %} - -{{r.section}} - -{% if r.section == 'Early review requests:' %}Reviewer Due Draft{% else %}Reviewer LC end Draft{% endif %}{% endifchanged %} -{{ r.reviewer.person.plain_name|ljust:"22" }} {% if r.section == 'Early review requests:' %}{{ r.deadline|date:"Y-m-d" }}{% else %}{{ r.lastcall_ends|default:"None " }}{% endif %} {{ r.doc_id }}-{% if r.requested_rev %}{{ r.requested_rev }}{% else %}{{ r.doc.rev }}{% endif %} {{ r.earlier_review_mark }}{% endfor %} - -* Other revision previously reviewed -** This revision already reviewed - -{% if rotation_list %}Next in the reviewer rotation: - -{% for p in rotation_list %} {{ p }} -{% endfor %}{% endif %}{% endautoescape %} - -""") - - -class Migration(migrations.Migration): - - dependencies = [ - ('dbtemplate', '0003_adjust_review_templates'), - ] - - operations = [ - migrations.RunPython(forward,reverse), - ] diff --git a/ietf/dbtemplate/migrations/0005_adjust_assignment_email_summary_templates_2526.py b/ietf/dbtemplate/migrations/0005_adjust_assignment_email_summary_templates_2526.py deleted file mode 100644 index 8a07d89364e..00000000000 --- a/ietf/dbtemplate/migrations/0005_adjust_assignment_email_summary_templates_2526.py +++ /dev/null @@ -1,281 +0,0 @@ -# Copyright The IETF Trust 2019-2020, All Rights Reserved -# -*- coding: utf-8 -*- -# Generated by Django 1.11.20 on 2019-03-13 13:41 - - -from django.db import migrations - -def forward(apps, schema_editor): - DBTemplate = apps.get_model('dbtemplate','DBTemplate') - - DBTemplate.objects.filter(pk=182).update(content="""{% autoescape off %}Subject: Open review assignments in {{group.acronym}} - -The following reviewers have assignments:{% for r in review_assignments %}{% ifchanged r.section %} - -{{r.section}} - -{% if r.section == 'Early review requests:' %}Reviewer Due Draft{% else %}Reviewer LC end Draft{% endif %}{% endifchanged %} -{{ r.reviewer.person.plain_name|ljust:"22" }} {% if r.section == 'Early review requests:' %}{{ r.review_request.deadline|date:"Y-m-d" }}{% else %}{{ r.lastcall_ends|default:"None " }}{% endif %} {{ r.review_request.doc.name }}-{% if r.review_request.requested_rev %}{{ r.review_request.requested_rev }}{% else %}{{ r.review_request.doc.rev }}{% endif %} {{ r.earlier_reviews }}{% endfor %} - -{% if rotation_list %}Next in the reviewer rotation: - -{% for p in rotation_list %} {{ p }} -{% endfor %}{% endif %}{% endautoescape %} -""") - - DBTemplate.objects.filter(pk=183).update(content="""{% autoescape off %}Subject: Review Assignments - -Hi all, - -The following reviewers have assignments:{% for r in review_assignments %}{% ifchanged r.section %} - -{{r.section}} - -{% if r.section == 'Early review requests:' %}Reviewer Due Draft{% else %}Reviewer Type LC end Draft{% endif %}{% endifchanged %} -{{ r.reviewer.person.plain_name|ljust:"22" }} {% if r.section == 'Early review requests:' %}{{ r.review_request.deadline|date:"Y-m-d" }}{% else %}{{r.review_request.type.name|ljust:"10"}}{{ r.lastcall_ends|default:"None " }}{% endif %} {{ r.review_request.doc.name }}-{% if r.review_request.requested_rev %}{{ r.review_request.requested_rev }}{% else %}{{ r.review_request.doc.rev }}{% endif %}{% if r.earlier_reviews %} {{ r.earlier_reviews }}{% endif %}{% endfor %} - -{% if rotation_list %}Next in the reviewer rotation: - -{% for p in rotation_list %} {{ p }} -{% endfor %}{% endif %} -The LC and Telechat review templates are included below: -------------------------------------------------------- - --- Begin LC Template -- -I am the assigned Gen-ART reviewer for this draft. The General Area -Review Team (Gen-ART) reviews all IETF documents being processed -by the IESG for the IETF Chair. Please treat these comments just -like any other last call comments. - -For more information, please see the FAQ at - -. - -Document: -Reviewer: -Review Date: -IETF LC End Date: -IESG Telechat date: (if known) - -Summary: - -Major issues: - -Minor issues: - -Nits/editorial comments: - --- End LC Template -- - --- Begin Telechat Template -- -I am the assigned Gen-ART reviewer for this draft. The General Area -Review Team (Gen-ART) reviews all IETF documents being processed -by the IESG for the IETF Chair. Please wait for direction from your -document shepherd or AD before posting a new version of the draft. - -For more information, please see the FAQ at - -. - -Document: -Reviewer: -Review Date: -IETF LC End Date: -IESG Telechat date: (if known) - -Summary: - -Major issues: - -Minor issues: - -Nits/editorial comments: - --- End Telechat Template -- -{% endautoescape %} - -""") - - DBTemplate.objects.filter(pk=184).update(content="""{% autoescape off %}Subject: Assignments - -Review instructions and related resources are at: -http://tools.ietf.org/area/sec/trac/wiki/SecDirReview{% for r in review_assignments %}{% ifchanged r.section %} - -{{r.section}} - -{% if r.section == 'Early review requests:' %}Reviewer Due Draft{% else %}Reviewer LC end Draft{% endif %}{% endifchanged %} -{{ r.reviewer.person.plain_name|ljust:"22" }}{{ r.earlier_review|yesno:'R, , ' }}{% if r.section == 'Early review requests:' %}{{ r.review_request.deadline|date:"Y-m-d" }}{% else %}{{ r.lastcall_ends|default:"None " }}{% endif %} {{ r.review_request.doc.name }}-{% if r.review_request.requested_rev %}{{ r.review_request.requested_rev }}{% else %}{{ r.review_request.doc.rev }}{% endif %}{% endfor %} - -{% if rotation_list %}Next in the reviewer rotation: - -{% for p in rotation_list %} {{ p }} -{% endfor %}{% endif %}{% endautoescape %} - -""") - - DBTemplate.objects.filter(pk=185).update(content="""{% autoescape off %}Subject: Open review assignments in {{group.acronym}} - -Review instructions and related resources are at: - - -The following reviewers have assignments:{% for r in review_assignments %}{% ifchanged r.section %} - -{{r.section}} - -{% if r.section == 'Early review requests:' %}Reviewer Due Draft{% else %}Reviewer LC end Draft{% endif %}{% endifchanged %} -{{ r.reviewer.person.plain_name|ljust:"22" }} {% if r.section == 'Early review requests:' %}{{ r.review_request.deadline|date:"Y-m-d" }}{% else %}{{ r.lastcall_ends|default:"None " }}{% endif %} {{ r.review_request.doc.name }}-{% if r.review_request.requested_rev %}{{ r.review_request.requested_rev }}{% else %}{{ r.review_request.doc.rev }}{% endif %} {{ r.earlier_reviews }}{% endfor %} - -{% if rotation_list %}Next in the reviewer rotation: - -{% for p in rotation_list %} {{ p }} -{% endfor %}{% endif %}{% endautoescape %} - -""") - - -def reverse(apps, schema_editor): - DBTemplate = apps.get_model('dbtemplate','DBTemplate') - - DBTemplate.objects.filter(pk=182).update(content="""{% autoescape off %}Subject: Open review assignments in {{group.acronym}} - -The following reviewers have assignments:{% for r in review_assignments %}{% ifchanged r.section %} - -{{r.section}} - -{% if r.section == 'Early review requests:' %}Reviewer Due Draft{% else %}Reviewer LC end Draft{% endif %}{% endifchanged %} -{{ r.reviewer.person.plain_name|ljust:"22" }} {% if r.section == 'Early review requests:' %}{{ r.review_request.deadline|date:"Y-m-d" }}{% else %}{{ r.lastcall_ends|default:"None " }}{% endif %} {{ r.review_request.doc_id }}-{% if r.review_request..requested_rev %}{{ r.review_request.requested_rev }}{% else %}{{ r.review_request..doc.rev }}{% endif %} {{ r.earlier_review_mark }}{% endfor %} - -* Other revision previously reviewed -** This revision already reviewed - -{% if rotation_list %}Next in the reviewer rotation: - -{% for p in rotation_list %} {{ p }} -{% endfor %}{% endif %}{% endautoescape %} -""") - - DBTemplate.objects.filter(pk=183).update(content="""{% autoescape off %}Subject: Review Assignments - -Hi all, - -The following reviewers have assignments:{% for r in review_assignments %}{% ifchanged r.section %} - -{{r.section}} - -{% if r.section == 'Early review requests:' %}Reviewer Due Draft{% else %}Reviewer Type LC end Draft{% endif %}{% endifchanged %} -{{ r.reviewer.person.plain_name|ljust:"22" }} {% if r.section == 'Early review requests:' %}{{ r.review_request.deadline|date:"Y-m-d" }}{% else %}{{r.review_request.type.name|ljust:"10"}}{{ r.lastcall_ends|default:"None " }}{% endif %} {{ r.review_request.doc.name }}-{% if r.review_request.requested_rev %}{{ r.review_request.requested_rev }}{% else %}{{ r.review_request.doc.rev }}{% endif %}{% if r.earlier_review_mark %} {{ r.earlier_review_mark }}{% endif %}{% endfor %} - -* Other revision previously reviewed -** This revision already reviewed - -{% if rotation_list %}Next in the reviewer rotation: - -{% for p in rotation_list %} {{ p }} -{% endfor %}{% endif %} -The LC and Telechat review templates are included below: -------------------------------------------------------- - --- Begin LC Template -- -I am the assigned Gen-ART reviewer for this draft. The General Area -Review Team (Gen-ART) reviews all IETF documents being processed -by the IESG for the IETF Chair. Please treat these comments just -like any other last call comments. - -For more information, please see the FAQ at - -. - -Document: -Reviewer: -Review Date: -IETF LC End Date: -IESG Telechat date: (if known) - -Summary: - -Major issues: - -Minor issues: - -Nits/editorial comments: - --- End LC Template -- - --- Begin Telechat Template -- -I am the assigned Gen-ART reviewer for this draft. The General Area -Review Team (Gen-ART) reviews all IETF documents being processed -by the IESG for the IETF Chair. Please wait for direction from your -document shepherd or AD before posting a new version of the draft. - -For more information, please see the FAQ at - -. - -Document: -Reviewer: -Review Date: -IETF LC End Date: -IESG Telechat date: (if known) - -Summary: - -Major issues: - -Minor issues: - -Nits/editorial comments: - --- End Telechat Template -- -{% endautoescape %} - -""") - - DBTemplate.objects.filter(pk=184).update(content="""{% autoescape off %}Subject: Assignments - -Review instructions and related resources are at: -http://tools.ietf.org/area/sec/trac/wiki/SecDirReview{% for r in review_assignments %}{% ifchanged r.section %} - -{{r.section}} - -{% if r.section == 'Early review requests:' %}Reviewer Due Draft{% else %}Reviewer LC end Draft{% endif %}{% endifchanged %} -{{ r.reviewer.person.plain_name|ljust:"22" }}{{ r.earlier_review|yesno:'R, , ' }}{% if r.section == 'Early review requests:' %}{{ r.review_request.deadline|date:"Y-m-d" }}{% else %}{{ r.lastcall_ends|default:"None " }}{% endif %} {{ r.review_request.doc.name }}-{% if r.review_request.requested_rev %}{{ r.review_request.requested_rev }}{% else %}{{ r.review_request.doc.rev }}{% endif %}{% endfor %} - -{% if rotation_list %}Next in the reviewer rotation: - -{% for p in rotation_list %} {{ p }} -{% endfor %}{% endif %}{% endautoescape %} - -""") - - DBTemplate.objects.filter(pk=185).update(content="""{% autoescape off %}Subject: Open review assignments in {{group.acronym}} - -Review instructions and related resources are at: - - -The following reviewers have assignments:{% for r in review_assignments %}{% ifchanged r.section %} - -{{r.section}} - -{% if r.section == 'Early review requests:' %}Reviewer Due Draft{% else %}Reviewer LC end Draft{% endif %}{% endifchanged %} -{{ r.reviewer.person.plain_name|ljust:"22" }} {% if r.section == 'Early review requests:' %}{{ r.review_request.deadline|date:"Y-m-d" }}{% else %}{{ r.lastcall_ends|default:"None " }}{% endif %} {{ r.review_request.doc.name }}-{% if r.review_request.requested_rev %}{{ r.review_request.requested_rev }}{% else %}{{ r.review_request.doc.rev }}{% endif %} {{ r.earlier_review_mark }}{% endfor %} - -* Other revision previously reviewed -** This revision already reviewed - -{% if rotation_list %}Next in the reviewer rotation: - -{% for p in rotation_list %} {{ p }} -{% endfor %}{% endif %}{% endautoescape %} - -""") - - -class Migration(migrations.Migration): - - dependencies = [ - ('dbtemplate', '0004_adjust_assignment_email_summary_templates'), - ] - - operations = [ - migrations.RunPython(forward,reverse), - ] diff --git a/ietf/dbtemplate/migrations/0006_add_review_assigned_template.py b/ietf/dbtemplate/migrations/0006_add_review_assigned_template.py deleted file mode 100644 index cedd8432207..00000000000 --- a/ietf/dbtemplate/migrations/0006_add_review_assigned_template.py +++ /dev/null @@ -1,33 +0,0 @@ -# Copyright The IETF Trust 2019-2020, All Rights Reserved -# -*- coding: utf-8 -*- - - -from django.db import migrations - -def forward(apps, schema_editor): - DBTemplate = apps.get_model('dbtemplate', 'DBTemplate') - - DBTemplate.objects.create(path='/group/defaults/email/review_assigned.txt', type_id='django', - content="""{{ assigner.ascii }} has assigned you as a reviewer for this document. - -{% if prev_team_reviews %}This team has completed other reviews of this document:{% endif %}{% for assignment in prev_team_reviews %} -- {{ assignment.completed_on }} {{ assignment.reviewer.person.ascii }} -{% if assignment.reviewed_rev %}{{ assignment.reviewed_rev }}{% else %}{{ assignment.review_request.requested_rev }}{% endif %} {{ assignment.result.name }} -{% endfor %} -""") - - -def reverse(apps, schema_editor): - DBTemplate = apps.get_model('dbtemplate', 'DBTemplate') - - DBTemplate.objects.get(path='/group/defaults/email/review_assigned.txt').delete() - - -class Migration(migrations.Migration): - - dependencies = [ - ('dbtemplate', '0005_adjust_assignment_email_summary_templates_2526'), - ] - - operations = [ - migrations.RunPython(forward,reverse), - ] diff --git a/ietf/dbtemplate/migrations/0007_adjust_review_assigned.py b/ietf/dbtemplate/migrations/0007_adjust_review_assigned.py deleted file mode 100644 index c1e8324ef99..00000000000 --- a/ietf/dbtemplate/migrations/0007_adjust_review_assigned.py +++ /dev/null @@ -1,38 +0,0 @@ -# Copyright The IETF Trust 2019-2020, All Rights Reserved -# -*- coding: utf-8 -*- -# Generated by Django 1.11.26 on 2019-11-19 11:47 - - -from django.db import migrations - -def forward(apps, schema_editor): - DBTemplate = apps.get_model('dbtemplate','DBTemplate') - qs = DBTemplate.objects.filter(path='/group/defaults/email/review_assigned.txt') - qs.update(content="""{{ assigner.ascii }} has assigned {{ reviewer.person.ascii }} as a reviewer for this document. - -{% if prev_team_reviews %}This team has completed other reviews of this document:{% endif %}{% for assignment in prev_team_reviews %} -- {{ assignment.completed_on }} {{ assignment.reviewer.person.ascii }} -{% if assignment.reviewed_rev %}{{ assignment.reviewed_rev }}{% else %}{{ assignment.review_request.requested_rev }}{% endif %} {{ assignment.result.name }} -{% endfor %} -""") - qs.update(title="Default template for review assignment email") - -def reverse(apps, schema_editor): - DBTemplate = apps.get_model('dbtemplate','DBTemplate') - qs = DBTemplate.objects.filter(path='/group/defaults/email/review_assigned.txt') - qs.update(content="""{{ assigner.ascii }} has assigned you as a reviewer for this document. - -{% if prev_team_reviews %}This team has completed other reviews of this document:{% endif %}{% for assignment in prev_team_reviews %} -- {{ assignment.completed_on }} {{ assignment.reviewer.person.ascii }} -{% if assignment.reviewed_rev %}{{ assignment.reviewed_rev }}{% else %}{{ assignment.review_request.requested_rev }}{% endif %} {{ assignment.result.name }} -{% endfor %} -""") - - -class Migration(migrations.Migration): - - dependencies = [ - ('dbtemplate', '0006_add_review_assigned_template'), - ] - - operations = [ - migrations.RunPython(forward, reverse) - ] diff --git a/ietf/dbtemplate/migrations/0008_add_default_iesg_req_template.py b/ietf/dbtemplate/migrations/0008_add_default_iesg_req_template.py deleted file mode 100644 index 3ca9a6fc8e6..00000000000 --- a/ietf/dbtemplate/migrations/0008_add_default_iesg_req_template.py +++ /dev/null @@ -1,32 +0,0 @@ -# Copyright The IETF Trust 2020, All Rights Reserved -# -*- coding: utf-8 -*- -# Generated by Django 1.11.27 on 2020-01-07 09:25 - - -from django.db import migrations - -def forward(apps, schema_editor): - DBTemplate = apps.get_model('dbtemplate', 'DBTemplate') - DBTemplate.objects.create(path='/nomcom/defaults/iesg_requirements', type_id='rst', title='Generic IESG requirements', - content="""============================= -IESG MEMBER DESIRED EXPERTISE -============================= - -Place this year's Generic IESG Member Desired Expertise here. - -This template uses reStructured text for formatting. Feel free to use it (to change the above header for example). -""") - -def reverse(apps, schema_editor): - DBTemplate = apps.get_model('dbtemplate', 'DBTemplate') - DBTemplate.objects.filter(path='/nomcom/defaults/iesg_requirements').delete() - -class Migration(migrations.Migration): - - dependencies = [ - ('dbtemplate', '0007_adjust_review_assigned'), - ] - - operations = [ - migrations.RunPython(forward, reverse) - ] diff --git a/ietf/dbtemplate/templates/dbtemplate/template_edit.html b/ietf/dbtemplate/templates/dbtemplate/template_edit.html index f27ab9c8399..d4f0c755f3a 100644 --- a/ietf/dbtemplate/templates/dbtemplate/template_edit.html +++ b/ietf/dbtemplate/templates/dbtemplate/template_edit.html @@ -15,7 +15,7 @@

Meta information

{{ template.type.name }} {% if template.type.slug == "rst" %}

This template uses the syntax of reStructuredText. Get a quick reference at http://docutils.sourceforge.net/docs/user/rst/quickref.html.

-

You can do variable interpolation with $varialbe if the template allows any variable.

+

You can do variable interpolation with $variable if the template allows any variable.

{% endif %} {% if template.type.slug == "django" %}

This template uses the syntax of the default django template framework. Get more info at https://docs.djangoproject.com/en/dev/topics/templates/.

@@ -43,4 +43,4 @@

Edit template content

-{% endblock %} +{% endblock %} \ No newline at end of file diff --git a/ietf/dbtemplate/templates/dbtemplate/template_list.html b/ietf/dbtemplate/templates/dbtemplate/template_list.html index bfee3c99b07..e67c4f208ec 100644 --- a/ietf/dbtemplate/templates/dbtemplate/template_list.html +++ b/ietf/dbtemplate/templates/dbtemplate/template_list.html @@ -6,7 +6,7 @@

Defined templates for group {{ group }}

{% if template_list %} {% else %} diff --git a/ietf/dbtemplate/templates/dbtemplate/template_show.html b/ietf/dbtemplate/templates/dbtemplate/template_show.html index 60e3bb9c7cd..527c9dedf7e 100644 --- a/ietf/dbtemplate/templates/dbtemplate/template_show.html +++ b/ietf/dbtemplate/templates/dbtemplate/template_show.html @@ -15,7 +15,7 @@

Meta information

{{ template.type.name }} {% if template.type.slug == "rst" %}

This template uses the syntax of reStructuredText. Get a quick reference at http://docutils.sourceforge.net/docs/user/rst/quickref.html.

-

You can do variable interpolation with $varialbe if the template allows any variable.

+

You can do variable interpolation with $variable if the template allows any variable.

{% endif %} {% if template.type.slug == "django" %}

This template uses the syntax of the default django template framework. Get more info at https://docs.djangoproject.com/en/dev/topics/templates/.

@@ -34,7 +34,7 @@

Meta information

Template content

-

{{ template.content }}

+
{{ template.content|escape }}
-{% endblock %} +{% endblock %} \ No newline at end of file diff --git a/ietf/doc/admin.py b/ietf/doc/admin.py index 64b9d9eff8b..86f5ac5fda1 100644 --- a/ietf/doc/admin.py +++ b/ietf/doc/admin.py @@ -1,56 +1,60 @@ -# Copyright The IETF Trust 2010-2021, All Rights Reserved +# Copyright The IETF Trust 2010-2025, All Rights Reserved # -*- coding: utf-8 -*- from django.contrib import admin from django.db import models from django import forms +from django.db.models import QuerySet +from rangefilter.filters import DateRangeQuickSelectListFilterBuilder from .models import (StateType, State, RelatedDocument, DocumentAuthor, Document, RelatedDocHistory, - DocHistoryAuthor, DocHistory, DocAlias, DocReminder, DocEvent, NewRevisionDocEvent, + DocHistoryAuthor, DocHistory, DocReminder, DocEvent, NewRevisionDocEvent, StateDocEvent, ConsensusDocEvent, BallotType, BallotDocEvent, WriteupDocEvent, LastCallDocEvent, TelechatDocEvent, BallotPositionDocEvent, ReviewRequestDocEvent, InitialReviewDocEvent, AddedMessageEvent, SubmissionDocEvent, DeletedEvent, EditedAuthorsDocEvent, DocumentURL, ReviewAssignmentDocEvent, IanaExpertDocEvent, IRSGBallotDocEvent, DocExtResource, DocumentActionHolder, - BofreqEditorDocEvent, BofreqResponsibleDocEvent ) + BofreqEditorDocEvent, BofreqResponsibleDocEvent, StoredObject, RfcAuthor, + EditedRfcAuthorsDocEvent, RpcAssignmentDocEvent) +from ietf.utils.admin import SaferTabularInline from ietf.utils.validators import validate_external_resource_value +from .storage_utils import force_replication +from .utils import replicate_stored_objects_for_document + class StateTypeAdmin(admin.ModelAdmin): list_display = ["slug", "label"] admin.site.register(StateType, StateTypeAdmin) class StateAdmin(admin.ModelAdmin): - list_display = ["slug", "type", 'name', 'order', 'desc'] - list_filter = ["type", ] + list_display = ["slug", "type", 'name', 'order', 'desc', "used"] + list_filter = ["type", "used"] search_fields = ["slug", "type__label", "type__slug", "name", "desc"] filter_horizontal = ["next_states"] admin.site.register(State, StateAdmin) -# class DocAliasInline(admin.TabularInline): -# model = DocAlias -# extra = 1 - -class DocAuthorInline(admin.TabularInline): +class DocAuthorInline(SaferTabularInline): model = DocumentAuthor raw_id_fields = ['person', 'email'] extra = 1 -class DocActionHolderInline(admin.TabularInline): +class DocActionHolderInline(SaferTabularInline): model = DocumentActionHolder raw_id_fields = ['person'] extra = 1 -class RelatedDocumentInline(admin.TabularInline): +class RelatedDocumentInline(SaferTabularInline): model = RelatedDocument + fk_name= 'source' def this(self, instance): - return instance.source.canonical_name() + return instance.source.name readonly_fields = ['this', ] fields = ['this', 'relationship', 'target', ] raw_id_fields = ['target'] extra = 1 -class AdditionalUrlInLine(admin.TabularInline): +class AdditionalUrlInLine(SaferTabularInline): model = DocumentURL fields = ['tag','desc','url',] extra = 1 @@ -70,10 +74,12 @@ class Meta: class DocumentAuthorAdmin(admin.ModelAdmin): list_display = ['id', 'document', 'person', 'email', 'affiliation', 'country', 'order'] - search_fields = ['document__docalias__name', 'person__name', 'email__address', 'affiliation', 'country'] + search_fields = ['document__name', 'person__name', 'email__address', 'affiliation', 'country'] raw_id_fields = ["document", "person", "email"] admin.site.register(DocumentAuthor, DocumentAuthorAdmin) - + + + class DocumentAdmin(admin.ModelAdmin): list_display = ['name', 'rev', 'group', 'pages', 'intended_std_level', 'author_list', 'time'] search_fields = ['name'] @@ -81,6 +87,7 @@ class DocumentAdmin(admin.ModelAdmin): raw_id_fields = ['group', 'shepherd', 'ad'] inlines = [DocAuthorInline, DocActionHolderInline, RelatedDocumentInline, AdditionalUrlInLine] form = DocumentForm + actions = ["replicate_stored_objects"] def save_model(self, request, obj, form, change): e = DocEvent.objects.create( @@ -95,6 +102,22 @@ def save_model(self, request, obj, form, change): def state(self, instance): return self.get_state() + @admin.action(description="Replicate related blobs") + def replicate_stored_objects(self, request, queryset: QuerySet[Document]): + doc_count = 0 + stored_obj_count = 0 + for doc in queryset.all(): + doc_count += 1 + if isinstance(doc, Document): + stored_obj_count += replicate_stored_objects_for_document(doc) + self.message_user( + request, + ( + f"Queued replication of a total of {stored_obj_count} StoredObject(s) " + f"for {doc_count} Document(s)" + ) + ) + admin.site.register(Document, DocumentAdmin) class DocHistoryAdmin(admin.ModelAdmin): @@ -108,14 +131,6 @@ def state(self, instance): admin.site.register(DocHistory, DocHistoryAdmin) -class DocAliasAdmin(admin.ModelAdmin): - list_display = ['name', 'targets'] - search_fields = ['name', 'docs__name'] - raw_id_fields = ['docs'] - def targets(self, obj): - return ', '.join([o.name for o in obj.docs.all()]) -admin.site.register(DocAlias, DocAliasAdmin) - class DocReminderAdmin(admin.ModelAdmin): list_display = ['id', 'event', 'type', 'due', 'active'] list_filter = ['type', 'due', 'active'] @@ -125,7 +140,7 @@ class DocReminderAdmin(admin.ModelAdmin): class RelatedDocumentAdmin(admin.ModelAdmin): list_display = ['source', 'target', 'relationship', ] list_filter = ['relationship', ] - search_fields = ['source__name', 'target__name', 'target__docs__name', ] + search_fields = ['source__name', 'target__name', ] raw_id_fields = ['source', 'target', ] admin.site.register(RelatedDocument, RelatedDocumentAdmin) @@ -153,6 +168,13 @@ class DocumentActionHolderAdmin(admin.ModelAdmin): # events +class DeletedEventAdmin(admin.ModelAdmin): + list_display = ['id', 'content_type', 'json', 'by', 'time'] + list_filter = ['time'] + raw_id_fields = ['content_type', 'by'] +admin.site.register(DeletedEvent, DeletedEventAdmin) + + class DocEventAdmin(admin.ModelAdmin): def event_type(self, obj): return str(obj.type) @@ -170,39 +192,47 @@ def short_desc(self, obj): admin.site.register(StateDocEvent, DocEventAdmin) admin.site.register(ConsensusDocEvent, DocEventAdmin) admin.site.register(BallotDocEvent, DocEventAdmin) +admin.site.register(IRSGBallotDocEvent, DocEventAdmin) admin.site.register(WriteupDocEvent, DocEventAdmin) admin.site.register(LastCallDocEvent, DocEventAdmin) admin.site.register(TelechatDocEvent, DocEventAdmin) -admin.site.register(ReviewRequestDocEvent, DocEventAdmin) -admin.site.register(ReviewAssignmentDocEvent, DocEventAdmin) admin.site.register(InitialReviewDocEvent, DocEventAdmin) -admin.site.register(AddedMessageEvent, DocEventAdmin) -admin.site.register(SubmissionDocEvent, DocEventAdmin) admin.site.register(EditedAuthorsDocEvent, DocEventAdmin) +admin.site.register(EditedRfcAuthorsDocEvent, DocEventAdmin) admin.site.register(IanaExpertDocEvent, DocEventAdmin) -class DeletedEventAdmin(admin.ModelAdmin): - list_display = ['id', 'content_type', 'json', 'by', 'time'] - list_filter = ['time'] - raw_id_fields = ['content_type', 'by'] -admin.site.register(DeletedEvent, DeletedEventAdmin) - class BallotPositionDocEventAdmin(DocEventAdmin): - raw_id_fields = ["doc", "by", "balloter", "ballot"] + raw_id_fields = DocEventAdmin.raw_id_fields + ["balloter", "ballot"] admin.site.register(BallotPositionDocEvent, BallotPositionDocEventAdmin) - -class IRSGBallotDocEventAdmin(DocEventAdmin): - raw_id_fields = ["doc", "by"] -admin.site.register(IRSGBallotDocEvent, IRSGBallotDocEventAdmin) class BofreqEditorDocEventAdmin(DocEventAdmin): - raw_id_fields = ["doc", "by", "editors" ] + raw_id_fields = DocEventAdmin.raw_id_fields + ["editors"] admin.site.register(BofreqEditorDocEvent, BofreqEditorDocEventAdmin) class BofreqResponsibleDocEventAdmin(DocEventAdmin): - raw_id_fields = ["doc", "by", "responsible" ] + raw_id_fields = DocEventAdmin.raw_id_fields + ["responsible"] admin.site.register(BofreqResponsibleDocEvent, BofreqResponsibleDocEventAdmin) +class ReviewRequestDocEventAdmin(DocEventAdmin): + raw_id_fields = DocEventAdmin.raw_id_fields + ["review_request"] +admin.site.register(ReviewRequestDocEvent, ReviewRequestDocEventAdmin) + +class ReviewAssignmentDocEventAdmin(DocEventAdmin): + raw_id_fields = DocEventAdmin.raw_id_fields + ["review_assignment"] +admin.site.register(ReviewAssignmentDocEvent, ReviewAssignmentDocEventAdmin) + +class AddedMessageEventAdmin(DocEventAdmin): + raw_id_fields = DocEventAdmin.raw_id_fields + ["message"] +admin.site.register(AddedMessageEvent, AddedMessageEventAdmin) + +class SubmissionDocEventAdmin(DocEventAdmin): + raw_id_fields = DocEventAdmin.raw_id_fields + ["submission"] +admin.site.register(SubmissionDocEvent, SubmissionDocEventAdmin) + +class RpcAssignmentDocEventAdmin(DocEventAdmin): + search_fields = DocEventAdmin.search_fields + ["assignments"] +admin.site.register(RpcAssignmentDocEvent, RpcAssignmentDocEventAdmin) + class DocumentUrlAdmin(admin.ModelAdmin): list_display = ['id', 'doc', 'tag', 'url', 'desc', ] search_fields = ['doc__name', 'url', ] @@ -219,3 +249,41 @@ class DocExtResourceAdmin(admin.ModelAdmin): search_fields = ['doc__name', 'value', 'display_name', 'name__slug',] raw_id_fields = ['doc', ] admin.site.register(DocExtResource, DocExtResourceAdmin) + +class StoredObjectAdmin(admin.ModelAdmin): + list_display = ['store', 'name', 'doc_name', 'modified', 'is_deleted'] + list_filter = [ + 'store', + ('modified', DateRangeQuickSelectListFilterBuilder()), + ('deleted', DateRangeQuickSelectListFilterBuilder()), + ] + search_fields = ['name', 'doc_name', 'doc_rev'] + list_display_links = ['name'] + actions = ["replicate_stored_object"] + + @admin.display(boolean=True, description="Deleted?", ordering="deleted") + def is_deleted(self, instance): + return instance.deleted is not None + + @admin.action(description="Replicate related blobs") + def replicate_stored_object(self, request, queryset: QuerySet[StoredObject]): + stored_obj_count = 0 + for stored_object in queryset.all(): + if isinstance(stored_object, StoredObject): + force_replication(kind=stored_object.store, name=stored_object.name) + stored_obj_count += 1 + self.message_user( + request, + f"Queued replication of a total of {stored_obj_count} StoredObject(s)", + ) + + +admin.site.register(StoredObject, StoredObjectAdmin) + +class RfcAuthorAdmin(admin.ModelAdmin): + # the email field in the list_display/readonly_fields works through a @property + list_display = ['id', 'document', 'titlepage_name', 'person', 'email', 'affiliation', 'country', 'order'] + search_fields = ['document__name', 'titlepage_name', 'person__name', 'person__email__address', 'affiliation', 'country'] + raw_id_fields = ["document", "person"] + readonly_fields = ["email"] +admin.site.register(RfcAuthor, RfcAuthorAdmin) diff --git a/ietf/doc/api.py b/ietf/doc/api.py new file mode 100644 index 00000000000..73fff6b27ff --- /dev/null +++ b/ietf/doc/api.py @@ -0,0 +1,213 @@ +# Copyright The IETF Trust 2024-2026, All Rights Reserved +"""Doc API implementations""" + +from django.db.models import ( + BooleanField, + Count, + OuterRef, + Prefetch, + Q, + QuerySet, + Subquery, +) +from django.db.models.functions import TruncDate +from django_filters import rest_framework as filters +from rest_framework import filters as drf_filters +from rest_framework.mixins import ListModelMixin, RetrieveModelMixin +from rest_framework.pagination import LimitOffsetPagination +from rest_framework.viewsets import GenericViewSet + +from ietf.group.models import Group +from ietf.name.models import StreamName, DocTypeName +from ietf.utils.timezone import RPC_TZINFO +from .models import ( + Document, + DocEvent, + RelatedDocument, + DocumentAuthor, + SUBSERIES_DOC_TYPE_IDS, +) +from .serializers import ( + RfcMetadataSerializer, + RfcStatus, + RfcSerializer, + SubseriesDocSerializer, +) + + +class RfcLimitOffsetPagination(LimitOffsetPagination): + default_limit = 10 + max_limit = 500 + + +class NumberInFilter(filters.BaseInFilter, filters.NumberFilter): + """Filter against a comma-separated list of numbers""" + pass + + +class RfcFilter(filters.FilterSet): + published = filters.DateFromToRangeFilter() + stream = filters.ModelMultipleChoiceFilter( + queryset=StreamName.objects.filter(used=True) + ) + number = NumberInFilter( + field_name="rfc_number" + ) + group = filters.ModelMultipleChoiceFilter( + queryset=Group.objects.all(), + field_name="group__acronym", + to_field_name="acronym", + ) + area = filters.ModelMultipleChoiceFilter( + queryset=Group.objects.areas(), + field_name="group__parent__acronym", + to_field_name="acronym", + ) + status = filters.MultipleChoiceFilter( + choices=[(slug, slug) for slug in RfcStatus.status_slugs], + method=RfcStatus.filter, + ) + sort = filters.OrderingFilter( + fields=( + ("rfc_number", "number"), # ?sort=number / ?sort=-number + ("published", "published"), # ?sort=published / ?sort=-published + ), + ) + + +class PrefetchRelatedDocument(Prefetch): + """Prefetch via a RelatedDocument + + Prefetches following RelatedDocument relationships to other docs. By default, includes + those for which the current RFC is the `source`. If `reverse` is True, includes those + for which it is the `target` instead. Defaults to only "rfc" documents. + """ + + @staticmethod + def _get_queryset(relationship_id, reverse, doc_type_ids): + """Get queryset to use for the prefetch""" + if isinstance(doc_type_ids, str): + doc_type_ids = (doc_type_ids,) + + return RelatedDocument.objects.filter( + **{ + "relationship_id": relationship_id, + f"{'source' if reverse else 'target'}__type_id__in": doc_type_ids, + } + ).select_related("source" if reverse else "target") + + def __init__(self, to_attr, relationship_id, reverse=False, doc_type_ids="rfc"): + super().__init__( + lookup="targets_related" if reverse else "relateddocument_set", + queryset=self._get_queryset(relationship_id, reverse, doc_type_ids), + to_attr=to_attr, + ) + + +def augment_rfc_queryset(queryset: QuerySet[Document]): + return ( + queryset.select_related("std_level", "stream") + .prefetch_related( + Prefetch( + "group", + Group.objects.select_related("parent"), + ), + Prefetch( + "documentauthor_set", + DocumentAuthor.objects.select_related("email", "person"), + ), + PrefetchRelatedDocument( + to_attr="drafts", + relationship_id="became_rfc", + doc_type_ids="draft", + reverse=True, + ), + PrefetchRelatedDocument(to_attr="obsoletes", relationship_id="obs"), + PrefetchRelatedDocument( + to_attr="obsoleted_by", relationship_id="obs", reverse=True + ), + PrefetchRelatedDocument(to_attr="updates", relationship_id="updates"), + PrefetchRelatedDocument( + to_attr="updated_by", relationship_id="updates", reverse=True + ), + PrefetchRelatedDocument( + to_attr="subseries", + relationship_id="contains", + reverse=True, + doc_type_ids=SUBSERIES_DOC_TYPE_IDS, + ), + ) + .annotate( + published_datetime=Subquery( + DocEvent.objects.filter( + doc_id=OuterRef("pk"), + type="published_rfc", + ) + .order_by("-time") + .values("time")[:1] + ), + ) + .annotate(published=TruncDate("published_datetime", tzinfo=RPC_TZINFO)) + .annotate( + # Count of "verified-errata" tags will be 1 or 0, convert to Boolean + has_errata=Count( + "tags", + filter=Q( + tags__slug="verified-errata", + ), + output_field=BooleanField(), + ) + ) + ) + + +class RfcViewSet(ListModelMixin, RetrieveModelMixin, GenericViewSet): + api_key_endpoint = "ietf.api.red_api" # matches prefix in ietf/api/urls.py + lookup_field = "rfc_number" + queryset = augment_rfc_queryset( + Document.objects.filter(type_id="rfc", rfc_number__isnull=False) + ).order_by("-rfc_number") + + pagination_class = RfcLimitOffsetPagination + filter_backends = [filters.DjangoFilterBackend, drf_filters.SearchFilter] + filterset_class = RfcFilter + search_fields = ["title", "abstract"] + + def get_serializer_class(self): + if self.action == "retrieve": + return RfcSerializer + return RfcMetadataSerializer + + +class PrefetchSubseriesContents(Prefetch): + def __init__(self, to_attr): + super().__init__( + lookup="relateddocument_set", + queryset=RelatedDocument.objects.filter( + relationship_id="contains", + target__type_id="rfc", + ).prefetch_related( + Prefetch( + "target", + queryset=augment_rfc_queryset(Document.objects.all()), + ) + ), + to_attr=to_attr, + ) + + +class SubseriesFilter(filters.FilterSet): + type = filters.ModelMultipleChoiceFilter( + queryset=DocTypeName.objects.filter(pk__in=SUBSERIES_DOC_TYPE_IDS) + ) + + +class SubseriesViewSet(ListModelMixin, RetrieveModelMixin, GenericViewSet): + api_key_endpoint = "ietf.api.red_api" # matches prefix in ietf/api/urls.py + lookup_field = "name" + serializer_class = SubseriesDocSerializer + queryset = Document.objects.subseries_docs().prefetch_related( + PrefetchSubseriesContents(to_attr="contents") + ) + filter_backends = [filters.DjangoFilterBackend] + filterset_class = SubseriesFilter diff --git a/ietf/doc/expire.py b/ietf/doc/expire.py index b780c73bd42..d42af628f80 100644 --- a/ietf/doc/expire.py +++ b/ietf/doc/expire.py @@ -1,22 +1,27 @@ # Copyright The IETF Trust 2010-2020, All Rights Reserved # -*- coding: utf-8 -*- -# expiry of Internet Drafts +# expiry of Internet-Drafts +import debug # pyflakes:ignore + from django.conf import settings +from django.utils import timezone import datetime, os, shutil, glob, re from pathlib import Path from typing import List, Optional # pyflakes:ignore +from ietf.doc.storage_utils import exists_in_storage, remove_from_storage +from ietf.doc.utils import update_action_holders from ietf.utils import log from ietf.utils.mail import send_mail -from ietf.doc.models import Document, DocEvent, State, IESG_SUBSTATE_TAGS +from ietf.doc.models import Document, DocEvent, State from ietf.person.models import Person from ietf.meeting.models import Meeting -from ietf.doc.utils import add_state_change_event, update_action_holders from ietf.mailtrigger.utils import gather_address_lists +from ietf.utils.timezone import date_today, datetime_today, DEADLINE_TZINFO nonexpirable_states: Optional[List[State]] = None @@ -32,37 +37,61 @@ def expirable_drafts(queryset=None): # Populate this first time through (but after django has been set up) if nonexpirable_states is None: - # all IESG states except I-D Exists, AD Watching, and Dead block expiry - nonexpirable_states = list(State.objects.filter(used=True, type="draft-iesg").exclude(slug__in=("idexists","watching", "dead"))) + # all IESG states except I-D Exists and Dead block expiry + nonexpirable_states = list( + State.objects.filter(used=True, type="draft-iesg").exclude( + slug__in=("idexists", "dead") + ) + ) # sent to RFC Editor and RFC Published block expiry (the latter # shouldn't be possible for an active draft, though) - nonexpirable_states += list(State.objects.filter(used=True, type__in=("draft-stream-iab", "draft-stream-irtf", "draft-stream-ise"), slug__in=("rfc-edit", "pub"))) + nonexpirable_states += list( + State.objects.filter( + used=True, + type__in=( + "draft-stream-iab", + "draft-stream-irtf", + "draft-stream-ise", + "draft-stream-editorial", + ), + slug__in=("rfc-edit", "pub"), + ) + ) # other IRTF states that block expiration - nonexpirable_states += list(State.objects.filter(used=True, type_id="draft-stream-irtf", slug__in=("irsgpoll", "iesg-rev",))) - - return queryset.filter( - states__type="draft", states__slug="active" - ).exclude( - expires=None - ).exclude( - states__in=nonexpirable_states - ).exclude( - tags="rfc-rev" # under review by the RFC Editor blocks expiry - ).distinct() + nonexpirable_states += list( + State.objects.filter( + used=True, + type_id="draft-stream-irtf", + slug__in=( + "irsgpoll", + "iesg-rev", + ), + ) + ) + + return ( + queryset.filter(states__type="draft", states__slug="active") + .exclude(expires=None) + .exclude(states__in=nonexpirable_states) + .exclude( + tags="rfc-rev" # under review by the RFC Editor blocks expiry + ) + .distinct() + ) def get_soon_to_expire_drafts(days_of_warning): - start_date = datetime.date.today() - datetime.timedelta(1) + start_date = datetime_today(DEADLINE_TZINFO) - datetime.timedelta(1) end_date = start_date + datetime.timedelta(days_of_warning) return expirable_drafts().filter(expires__gte=start_date, expires__lt=end_date) def get_expired_drafts(): - return expirable_drafts().filter(expires__lt=datetime.date.today() + datetime.timedelta(1)) + return expirable_drafts().filter(expires__lt=datetime_today(DEADLINE_TZINFO) + datetime.timedelta(1)) def in_draft_expire_freeze(when=None): if when == None: - when = datetime.datetime.now() + when = timezone.now() meeting = Meeting.objects.filter(type='ietf', date__gte=when-datetime.timedelta(days=7)).order_by('date').first() @@ -71,10 +100,10 @@ def in_draft_expire_freeze(when=None): d = meeting.get_second_cut_off() # for some reason, the old Perl code started at 9 am - second_cut_off = datetime.datetime.combine(d, datetime.time(9, 0)) + second_cut_off = d.replace(hour=9, minute=0, second=0, microsecond=0) d = meeting.get_ietf_monday() - ietf_monday = datetime.datetime.combine(d, datetime.time(0, 0)) + ietf_monday = datetime.datetime.combine(d, datetime.time(0, 0), tzinfo=meeting.tz()) return second_cut_off <= when < ietf_monday @@ -84,7 +113,14 @@ def send_expire_warning_for_draft(doc): (doc.get_state_slug("draft") != "active")): return # don't warn about dead or inactive documents - expiration = doc.expires.date() + expiration = doc.expires.astimezone(DEADLINE_TZINFO).date() + now_plus_12hours = timezone.now() + datetime.timedelta(hours=12) + soon = now_plus_12hours.date() + if expiration <= soon: + # The document will expire very soon, which will send email to the + # same people, so do not send the warning at this point in time + return + (to,cc) = gather_address_lists('doc_expires_soon',doc=doc) @@ -130,16 +166,32 @@ def move_file(f): if os.path.exists(src): try: + # ghostlinkd would keep this in the combined all archive since it would + # be sourced from a different place. But when ghostlinkd is removed, nothing + # new is needed here - the file will already exist in the combined archive shutil.move(src, dst) except IOError as e: if "No such file or directory" in str(e): pass else: raise - + + def remove_ftp_copy(f): + mark = Path(settings.FTP_DIR) / "internet-drafts" / f + if mark.exists(): + mark.unlink() + + def remove_from_active_draft_storage(file): + # Assumes the glob will never find a file with no suffix + ext = file.suffix[1:] + remove_from_storage("active-draft", f"{ext}/{file.name}", warn_if_missing=False) + + # Note that the object is already in the "draft" storage. src_dir = Path(settings.INTERNET_DRAFT_PATH) for file in src_dir.glob("%s-%s.*" % (doc.name, rev)): move_file(str(file.name)) + remove_ftp_copy(str(file.name)) + remove_from_active_draft_storage(file) def expire_draft(doc): # clean up files @@ -149,29 +201,16 @@ def expire_draft(doc): events = [] - # change the state - if doc.latest_event(type='started_iesg_process'): - new_state = State.objects.get(used=True, type="draft-iesg", slug="dead") - prev_state = doc.get_state(new_state.type_id) - prev_tags = doc.tags.filter(slug__in=IESG_SUBSTATE_TAGS) - if new_state != prev_state: - doc.set_state(new_state) - doc.tags.remove(*prev_tags) - e = add_state_change_event(doc, system, prev_state, new_state, prev_tags=prev_tags, new_tags=[]) - if e: - events.append(e) - e = update_action_holders(doc, prev_state, new_state, prev_tags=prev_tags, new_tags=[]) - if e: - events.append(e) - events.append(DocEvent.objects.create(doc=doc, rev=doc.rev, by=system, type="expired_document", desc="Document has expired")) + prev_draft_state=doc.get_state("draft") doc.set_state(State.objects.get(used=True, type="draft", slug="expired")) + events.append(update_action_holders(doc, prev_draft_state, doc.get_state("draft"),[],[])) doc.save_with_history(events) def clean_up_draft_files(): - """Move unidentified and old files out of the Internet Draft directory.""" - cut_off = datetime.date.today() + """Move unidentified and old files out of the Internet-Draft directory.""" + cut_off = date_today(DEADLINE_TZINFO) pattern = os.path.join(settings.INTERNET_DRAFT_PATH, "draft-*.*") filename_re = re.compile(r'^(.*)-(\d\d)$') @@ -204,8 +243,19 @@ def splitext(fn): filename, revision = match.groups() def move_file_to(subdir): + # Similar to move_draft_files_to_archive shutil.move(path, os.path.join(settings.INTERNET_DRAFT_ARCHIVE_DIR, subdir, basename)) + mark = Path(settings.FTP_DIR) / "internet-drafts" / basename + if mark.exists(): + mark.unlink() + if ext: + # Note that we're not moving these strays anywhere - the assumption + # is that the active-draft blobstore will not get strays. + # See, however, the note about "major system failures" at "unknown_ids" + blobname = f"{ext[1:]}/{basename}" + if exists_in_storage("active-draft", blobname): + remove_from_storage("active-draft", blobname) try: doc = Document.objects.get(name=filename, rev=revision) @@ -214,8 +264,12 @@ def move_file_to(subdir): if state in ("rfc","repl"): move_file_to("") - elif state in ("expired", "auth-rm", "ietf-rm") and doc.expires and doc.expires.date() < cut_off: + elif (state in ("expired", "auth-rm", "ietf-rm") + and doc.expires + and doc.expires.astimezone(DEADLINE_TZINFO).date() < cut_off): move_file_to("") except Document.DoesNotExist: + # All uses of this past 2014 seem related to major system failures. move_file_to("unknown_ids") + diff --git a/ietf/doc/factories.py b/ietf/doc/factories.py index 8fd6feca764..0cf83e4525f 100644 --- a/ietf/doc/factories.py +++ b/ietf/doc/factories.py @@ -1,4 +1,4 @@ -# Copyright The IETF Trust 2016-2020, All Rights Reserved +# Copyright The IETF Trust 2016-2023, All Rights Reserved # -*- coding: utf-8 -*- @@ -7,17 +7,20 @@ import factory.fuzzy import datetime -from typing import Optional # pyflakes:ignore +from typing import Any # pyflakes:ignore from django.conf import settings +from django.utils import timezone -from ietf.doc.models import ( Document, DocEvent, NewRevisionDocEvent, DocAlias, State, DocumentAuthor, +from ietf.doc.models import ( Document, DocEvent, NewRevisionDocEvent, State, DocumentAuthor, StateDocEvent, BallotPositionDocEvent, BallotDocEvent, BallotType, IRSGBallotDocEvent, TelechatDocEvent, - DocumentActionHolder, BofreqEditorDocEvent, BofreqResponsibleDocEvent ) + DocumentActionHolder, BofreqEditorDocEvent, BofreqResponsibleDocEvent, DocExtResource, RfcAuthor ) from ietf.group.models import Group from ietf.person.factories import PersonFactory from ietf.group.factories import RoleFactory +from ietf.name.models import ExtResourceName from ietf.utils.text import xslugify +from ietf.utils.timezone import date_today def draft_name_generator(type_id,group,n): @@ -32,14 +35,18 @@ def draft_name_generator(type_id,group,n): class BaseDocumentFactory(factory.django.DjangoModelFactory): class Meta: model = Document + skip_postgeneration_save = True + # n.b., a few attributes are typed as Any so mypy won't complain when we override in subclasses title = factory.Faker('sentence',nb_words=5) - abstract = factory.Faker('paragraph', nb_sentences=5) + abstract: Any = factory.Faker('paragraph', nb_sentences=5) rev = '00' - std_level_id = None # type: Optional[str] + std_level_id: Any = None intended_std_level_id = None - time = datetime.datetime.now() - expires = factory.LazyAttribute(lambda o: o.time+datetime.timedelta(days=settings.INTERNET_DRAFT_DAYS_TO_EXPIRE)) + time = timezone.now() + expires: Any = factory.LazyAttribute( + lambda o: o.time+datetime.timedelta(days=settings.INTERNET_DRAFT_DAYS_TO_EXPIRE) + ) pages = factory.fuzzy.FuzzyInteger(2,400) @@ -47,16 +54,11 @@ class Meta: def name(self, n): return draft_name_generator(self.type_id,self.group,n) - newrevisiondocevent = factory.RelatedFactory('ietf.doc.factories.NewRevisionDocEventFactory','doc') - @factory.post_generation - def other_aliases(obj, create, extracted, **kwargs): # pylint: disable=no-self-argument - alias = DocAliasFactory(name=obj.name) - alias.docs.add(obj) - if create and extracted: - for name in extracted: - alias = DocAliasFactory(name=name) - alias.docs.add(obj) + def newrevisiondocevent(obj, create, extracted, **kwargs): # pylint: disable=no-self-argument + if create: + if obj.type_id != "rfc": + NewRevisionDocEventFactory(doc=obj) @factory.post_generation def states(obj, create, extracted, **kwargs): # pylint: disable=no-self-argument @@ -79,13 +81,7 @@ def authors(obj, create, extracted, **kwargs): # pylint: disable=no-self-argumen def relations(obj, create, extracted, **kwargs): # pylint: disable=no-self-argument if create and extracted: for (rel_id, doc) in extracted: - if isinstance(doc, Document): - docalias = doc.docalias.first() - elif isinstance(doc, DocAlias): - docalias = doc - else: - continue - obj.relateddocument_set.create(relationship_id=rel_id, target=docalias) + obj.relateddocument_set.create(relationship_id=rel_id, target=doc) @factory.post_generation def create_revisions(obj, create, extracted, **kwargs): # pylint: disable=no-self-argument @@ -115,10 +111,12 @@ class DocumentFactory(BaseDocumentFactory): group = factory.SubFactory('ietf.group.factories.GroupFactory',acronym='none') -class IndividualDraftFactory(BaseDocumentFactory): - - type_id = 'draft' - group = factory.SubFactory('ietf.group.factories.GroupFactory',acronym='none') +class RfcFactory(BaseDocumentFactory): + type_id = "rfc" + rev = "" + rfc_number = factory.Sequence(lambda n: n + 1000) + name = factory.LazyAttribute(lambda o: f"rfc{o.rfc_number:d}") + expires = None @factory.post_generation def states(obj, create, extracted, **kwargs): @@ -127,15 +125,21 @@ def states(obj, create, extracted, **kwargs): if extracted: for (state_type_id,state_slug) in extracted: obj.set_state(State.objects.get(type_id=state_type_id,slug=state_slug)) - if not obj.get_state('draft-iesg'): - obj.set_state(State.objects.get(type_id='draft-iesg',slug='idexists')) else: - obj.set_state(State.objects.get(type_id='draft',slug='active')) - obj.set_state(State.objects.get(type_id='draft-iesg',slug='idexists')) + obj.set_state(State.objects.get(type_id='rfc',slug='published')) -class IndividualRfcFactory(IndividualDraftFactory): + @factory.post_generation + def authors(obj, create, extracted, **kwargs): # pylint: disable=no-self-argument + # Override base class, creating RfcAuthor instead of DocumentAuthor + if create and extracted: + for person in extracted: + RfcAuthorFactory(document=obj, person=person) - alias2 = factory.RelatedFactory('ietf.doc.factories.DocAliasFactory','document',name=factory.Sequence(lambda n: 'rfc%04d'%(n+1000))) + +class IndividualDraftFactory(BaseDocumentFactory): + + type_id = 'draft' + group = factory.SubFactory('ietf.group.factories.GroupFactory',acronym='none') @factory.post_generation def states(obj, create, extracted, **kwargs): @@ -144,17 +148,17 @@ def states(obj, create, extracted, **kwargs): if extracted: for (state_type_id,state_slug) in extracted: obj.set_state(State.objects.get(type_id=state_type_id,slug=state_slug)) + if not obj.get_state('draft-iesg'): + obj.set_state(State.objects.get(type_id='draft-iesg',slug='idexists')) else: - obj.set_state(State.objects.get(type_id='draft',slug='rfc')) + obj.set_state(State.objects.get(type_id='draft',slug='active')) + obj.set_state(State.objects.get(type_id='draft-iesg',slug='idexists')) - @factory.post_generation - def reset_canonical_name(obj, create, extracted, **kwargs): - if hasattr(obj, '_canonical_name'): - del obj._canonical_name - return None +class IndividualRfcFactory(RfcFactory): + group = factory.SubFactory('ietf.group.factories.GroupFactory',acronym='none') -class WgDraftFactory(BaseDocumentFactory): +class WgDraftFactory(BaseDocumentFactory): type_id = 'draft' group = factory.SubFactory('ietf.group.factories.GroupFactory',type_id='wg') stream_id = 'ietf' @@ -173,30 +177,12 @@ def states(obj, create, extracted, **kwargs): obj.set_state(State.objects.get(type_id='draft-stream-ietf',slug='wg-doc')) obj.set_state(State.objects.get(type_id='draft-iesg',slug='idexists')) -class WgRfcFactory(WgDraftFactory): - - alias2 = factory.RelatedFactory('ietf.doc.factories.DocAliasFactory','document',name=factory.Sequence(lambda n: 'rfc%04d'%(n+1000))) +class WgRfcFactory(RfcFactory): + group = factory.SubFactory('ietf.group.factories.GroupFactory',type_id='wg') + stream_id = 'ietf' std_level_id = 'ps' - @factory.post_generation - def states(obj, create, extracted, **kwargs): - if not create: - return - if extracted: - for (state_type_id,state_slug) in extracted: - obj.set_state(State.objects.get(type_id=state_type_id,slug=state_slug)) - if not obj.get_state('draft-iesg'): - obj.set_state(State.objects.get(type_id='draft-iesg', slug='pub')) - else: - obj.set_state(State.objects.get(type_id='draft',slug='rfc')) - obj.set_state(State.objects.get(type_id='draft-iesg', slug='pub')) - - @factory.post_generation - def reset_canonical_name(obj, create, extracted, **kwargs): - if hasattr(obj, '_canonical_name'): - del obj._canonical_name - return None class RgDraftFactory(BaseDocumentFactory): @@ -219,34 +205,11 @@ def states(obj, create, extracted, **kwargs): obj.set_state(State.objects.get(type_id='draft-iesg',slug='idexists')) -class RgRfcFactory(RgDraftFactory): - - alias2 = factory.RelatedFactory('ietf.doc.factories.DocAliasFactory','document',name=factory.Sequence(lambda n: 'rfc%04d'%(n+1000))) - +class RgRfcFactory(RfcFactory): + group = factory.SubFactory('ietf.group.factories.GroupFactory',type_id='rg') + stream_id = 'irtf' std_level_id = 'inf' - @factory.post_generation - def states(obj, create, extracted, **kwargs): - if not create: - return - if extracted: - for (state_type_id,state_slug) in extracted: - obj.set_state(State.objects.get(type_id=state_type_id,slug=state_slug)) - if not obj.get_state('draft-stream-irtf'): - obj.set_state(State.objects.get(type_id='draft-stream-irtf', slug='pub')) - if not obj.get_state('draft-iesg'): - obj.set_state(State.objects.get(type_id='draft-iesg',slug='idexists')) - else: - obj.set_state(State.objects.get(type_id='draft',slug='rfc')) - obj.set_state(State.objects.get(type_id='draft-stream-irtf', slug='pub')) - obj.set_state(State.objects.get(type_id='draft-iesg',slug='idexists')) - - @factory.post_generation - def reset_canonical_name(obj, create, extracted, **kwargs): - if hasattr(obj, '_canonical_name'): - del obj._canonical_name - return None - class CharterFactory(BaseDocumentFactory): @@ -275,7 +238,7 @@ def changes_status_of(obj, create, extracted, **kwargs): for (rel, target) in extracted: obj.relateddocument_set.create(relationship_id=rel,target=target) else: - obj.relateddocument_set.create(relationship_id='tobcp', target=WgRfcFactory().docalias.first()) + obj.relateddocument_set.create(relationship_id='tobcp', target=WgRfcFactory()) @factory.post_generation def states(obj, create, extracted, **kwargs): @@ -302,9 +265,9 @@ def review_of(obj, create, extracted, **kwargs): if not create: return if extracted: - obj.relateddocument_set.create(relationship_id='conflrev',target=extracted.docalias.first()) + obj.relateddocument_set.create(relationship_id='conflrev',target=extracted) else: - obj.relateddocument_set.create(relationship_id='conflrev',target=DocumentFactory(name=obj.name.replace('conflict-review-','draft-'),type_id='draft',group=Group.objects.get(type_id='individ')).docalias.first()) + obj.relateddocument_set.create(relationship_id='conflrev',target=DocumentFactory(name=obj.name.replace('conflict-review-','draft-'),type_id='draft',group=Group.objects.get(type_id='individ'))) @factory.post_generation @@ -320,33 +283,16 @@ def states(obj, create, extracted, **kwargs): # This is very skeletal. It is enough for the tests that use it now, but when it's needed, it will need to be improved with, at least, a group generator that backs the object with a review team. class ReviewFactory(BaseDocumentFactory): type_id = 'review' - name = factory.LazyAttribute(lambda o: 'review-doesnotexist-00-%s-%s'%(o.group.acronym,datetime.date.today().isoformat())) + name = factory.LazyAttribute(lambda o: 'review-doesnotexist-00-%s-%s'%(o.group.acronym,date_today().isoformat())) group = factory.SubFactory('ietf.group.factories.GroupFactory',type_id='review') -class DocAliasFactory(factory.django.DjangoModelFactory): - class Meta: - model = DocAlias - - @factory.post_generation - def document(self, create, extracted, **kwargs): - if create and extracted: - self.docs.add(extracted) - - @factory.post_generation - def docs(self, create, extracted, **kwargs): - if create and extracted: - for doc in extracted: - if not doc in self.docs.all(): - self.docs.add(doc) - - class DocEventFactory(factory.django.DjangoModelFactory): class Meta: model = DocEvent type = 'added_comment' by = factory.SubFactory('ietf.person.factories.PersonFactory') - doc = factory.SubFactory(DocumentFactory) + doc: Any = factory.SubFactory(DocumentFactory) # `Any` to appease mypy when a subclass overrides doc desc = factory.Faker('sentence',nb_words=6) @factory.lazy_attribute @@ -357,7 +303,8 @@ class TelechatDocEventFactory(DocEventFactory): class Meta: model = TelechatDocEvent - telechat_date = datetime.datetime.today()+datetime.timedelta(days=14) + # note: this is evaluated at import time and not updated - all events will have the same telechat_date + telechat_date = timezone.now()+datetime.timedelta(days=14) type = 'scheduled_for_telechat' class NewRevisionDocEventFactory(DocEventFactory): @@ -371,9 +318,16 @@ class Meta: def desc(self): return 'New version available %s-%s'%(self.doc.name,self.rev) +class PublishedRfcDocEventFactory(DocEventFactory): + class Meta: + model = DocEvent + type = "published_rfc" + doc = factory.SubFactory(WgRfcFactory) + class StateDocEventFactory(DocEventFactory): class Meta: model = StateDocEvent + skip_postgeneration_save = True type = 'changed_state' state_type_id = 'draft-iesg' @@ -410,7 +364,7 @@ class IRSGBallotDocEventFactory(BallotDocEventFactory): class Meta: model = IRSGBallotDocEvent - duedate = datetime.datetime.now() + datetime.timedelta(days=14) + duedate = timezone.now() + datetime.timedelta(days=14) ballot_type = factory.SubFactory(BallotTypeFactory, slug='irsg-approve') class BallotPositionDocEventFactory(DocEventFactory): @@ -441,12 +395,25 @@ class Meta: country = factory.Faker('country') order = factory.LazyAttribute(lambda o: o.document.documentauthor_set.count() + 1) +class RfcAuthorFactory(factory.django.DjangoModelFactory): + class Meta: + model = RfcAuthor + + document = factory.SubFactory(DocumentFactory) + titlepage_name = factory.LazyAttribute( + lambda obj: " ".join([obj.person.initials(), obj.person.last_name()]) + ) + person = factory.SubFactory('ietf.person.factories.PersonFactory') + affiliation = factory.Faker('company') + order = factory.LazyAttribute(lambda o: o.document.rfcauthor_set.count() + 1) + class WgDocumentAuthorFactory(DocumentAuthorFactory): document = factory.SubFactory(WgDraftFactory) class BofreqEditorDocEventFactory(DocEventFactory): class Meta: model = BofreqEditorDocEvent + skip_postgeneration_save = True type = "changed_editors" doc = factory.SubFactory('ietf.doc.factories.BofreqFactory') @@ -461,10 +428,12 @@ def editors(obj, create, extracted, **kwargs): else: obj.editors.set(PersonFactory.create_batch(3)) obj.desc = f'Changed editors to {", ".join(obj.editors.values_list("name",flat=True)) or "(None)"}' + obj.save() class BofreqResponsibleDocEventFactory(DocEventFactory): class Meta: model = BofreqResponsibleDocEvent + skip_postgeneration_save = True type = "changed_responsible" doc = factory.SubFactory('ietf.doc.factories.BofreqFactory') @@ -479,7 +448,8 @@ def responsible(obj, create, extracted, **kwargs): else: ad = RoleFactory(group__type_id='area',name_id='ad').person obj.responsible.set([ad]) - obj.desc = f'Changed responsible leadership to {", ".join(obj.responsible.values_list("name",flat=True)) or "(None)"}' + obj.desc = f'Changed responsible leadership to {", ".join(obj.responsible.values_list("name",flat=True)) or "(None)"}' + obj.save() class BofreqFactory(BaseDocumentFactory): type_id = 'bofreq' @@ -517,3 +487,89 @@ def states(obj, create, extracted, **kwargs): obj.set_state(State.objects.get(type_id=state_type_id,slug=state_slug)) else: obj.set_state(State.objects.get(type_id='procmaterials', slug='active')) + +class DocExtResourceFactory(factory.django.DjangoModelFactory): + + name = factory.Iterator(ExtResourceName.objects.filter(type_id='url')) + value = factory.Faker('url') + doc = factory.SubFactory('ietf.doc.factories.BaseDocumentFactory') + class Meta: + model = DocExtResource + +class EditorialDraftFactory(BaseDocumentFactory): + + type_id = 'draft' + group = factory.SubFactory('ietf.group.factories.GroupFactory',acronym='rswg', type_id='edwg') + stream_id = 'editorial' + + @factory.post_generation + def states(obj, create, extracted, **kwargs): + if not create: + return + if extracted: + for (state_type_id,state_slug) in extracted: + obj.set_state(State.objects.get(type_id=state_type_id,slug=state_slug)) + if not obj.get_state('draft-iesg'): + obj.set_state(State.objects.get(type_id='draft-iesg',slug='idexists')) + else: + obj.set_state(State.objects.get(type_id='draft',slug='active')) + obj.set_state(State.objects.get(type_id='draft-stream-editorial',slug='active')) + obj.set_state(State.objects.get(type_id='draft-iesg',slug='idexists')) + +class EditorialRfcFactory(RgRfcFactory): + pass + +class StatementFactory(BaseDocumentFactory): + type_id = "statement" + title = factory.Faker("sentence") + group = factory.SubFactory("ietf.group.factories.GroupFactory", acronym="iab") + + name = factory.LazyAttribute( + lambda o: "statement-%s-%s" % (xslugify(o.group.acronym), xslugify(o.title)) + ) + uploaded_filename = factory.LazyAttribute(lambda o: f"{o.name}-{o.rev}.md") + + published_statement_event = factory.RelatedFactory( + "ietf.doc.factories.DocEventFactory", + "doc", + type="published_statement", + time=timezone.now() - datetime.timedelta(days=1), + ) + + @factory.post_generation + def states(obj, create, extracted, **kwargs): + if not create: + return + if extracted: + for state_type_id, state_slug in extracted: + obj.set_state(State.objects.get(type_id=state_type_id, slug=state_slug)) + else: + obj.set_state(State.objects.get(type_id="statement", slug="active")) + +class SubseriesFactory(factory.django.DjangoModelFactory): + class Meta: + model = Document + skip_postgeneration_save = True + + @factory.lazy_attribute_sequence + def name(self, n): + return f"{self.type_id}{n}" + + @factory.post_generation + def contains(obj, create, extracted, **kwargs): + if not create: + return + if extracted: + for doc in extracted: + obj.relateddocument_set.create(relationship_id="contains",target=doc) + else: + obj.relateddocument_set.create(relationship_id="contains", target=RfcFactory()) + +class BcpFactory(SubseriesFactory): + type_id="bcp" + +class StdFactory(SubseriesFactory): + type_id="std" + +class FyiFactory(SubseriesFactory): + type_id="fyi" diff --git a/ietf/doc/feeds.py b/ietf/doc/feeds.py index 1169db105f5..7472b14c187 100644 --- a/ietf/doc/feeds.py +++ b/ietf/doc/feeds.py @@ -1,35 +1,42 @@ -# Copyright The IETF Trust 2007-2020, All Rights Reserved -# -*- coding: utf-8 -*- +# Copyright The IETF Trust 2007-2026, All Rights Reserved +import debug # pyflakes:ignore import datetime import unicodedata +from django.conf import settings from django.contrib.syndication.views import Feed, FeedDoesNotExist from django.utils.feedgenerator import Atom1Feed, Rss201rev2Feed from django.urls import reverse as urlreverse -from django.template.defaultfilters import truncatewords, truncatewords_html, date as datefilter -from django.template.defaultfilters import linebreaks # type: ignore +from django.template.defaultfilters import ( + truncatewords, + truncatewords_html, + date as datefilter, +) +from django.template.defaultfilters import linebreaks # type: ignore +from django.utils import timezone from django.utils.html import strip_tags from ietf.doc.models import Document, State, LastCallDocEvent, DocEvent from ietf.doc.utils import augment_events_with_revision from ietf.doc.templatetags.ietf_filters import format_textarea +from ietf.utils.timezone import RPC_TZINFO def strip_control_characters(s): """Remove Unicode control / non-printing characters from a string""" - replacement_char = unicodedata.lookup('REPLACEMENT CHARACTER') - return ''.join( - replacement_char if unicodedata.category(c)[0] == 'C' else c - for c in s + replacement_char = unicodedata.lookup("REPLACEMENT CHARACTER") + return "".join( + replacement_char if unicodedata.category(c)[0] == "C" else c for c in s ) + class DocumentChangesFeed(Feed): feed_type = Atom1Feed def get_object(self, request, name): - return Document.objects.get(docalias__name=name) + return Document.objects.get(name=name) def title(self, obj): return "Changes for %s" % obj.display_name() @@ -37,25 +44,37 @@ def title(self, obj): def link(self, obj): if obj is None: raise FeedDoesNotExist - return urlreverse('ietf.doc.views_doc.document_history', kwargs=dict(name=obj.canonical_name())) + return urlreverse( + "ietf.doc.views_doc.document_history", + kwargs=dict(name=obj.name), + ) def subtitle(self, obj): return "History of change entries for %s." % obj.display_name() def items(self, obj): - events = obj.docevent_set.all().order_by("-time","-id") + events = ( + obj.docevent_set.all() + .order_by("-time", "-id") + .select_related("by", "newrevisiondocevent", "submissiondocevent") + ) augment_events_with_revision(obj, events) return events def item_title(self, item): - return strip_control_characters("[%s] %s [rev. %s]" % ( - item.by, - truncatewords(strip_tags(item.desc), 15), - item.rev, - )) + return strip_control_characters( + "[%s] %s [rev. %s]" + % ( + item.by, + truncatewords(strip_tags(item.desc), 15), + item.rev, + ) + ) def item_description(self, item): - return strip_control_characters(truncatewords_html(format_textarea(item.desc), 20)) + return strip_control_characters( + truncatewords_html(format_textarea(item.desc), 20) + ) def item_pubdate(self, item): return item.time @@ -64,17 +83,28 @@ def item_author_name(self, item): return str(item.by) def item_link(self, item): - return urlreverse('ietf.doc.views_doc.document_history', kwargs=dict(name=item.doc.canonical_name())) + "#history-%s" % item.pk + return ( + urlreverse( + "ietf.doc.views_doc.document_history", + kwargs=dict(name=item.doc.name), + ) + + "#history-%s" % item.pk + ) + class InLastCallFeed(Feed): title = "Documents in Last Call" subtitle = "Announcements for documents in last call." feed_type = Atom1Feed - author_name = 'IESG Secretary' + author_name = "IESG Secretary" link = "/doc/iesg/last-call/" def items(self): - docs = list(Document.objects.filter(type="draft", states=State.objects.get(type="draft-iesg", slug="lc"))) + docs = list( + Document.objects.filter( + type="draft", states=State.objects.get(type="draft-iesg", slug="lc") + ) + ) for d in docs: d.lc_event = d.latest_event(LastCallDocEvent, type="sent_last_call") @@ -84,9 +114,11 @@ def items(self): return docs def item_title(self, item): - return "%s (%s - %s)" % (item.name, - datefilter(item.lc_event.time, "F j"), - datefilter(item.lc_event.expires, "F j, Y")) + return "%s (%s - %s)" % ( + item.name, + datefilter(item.lc_event.time, "F j"), + datefilter(item.lc_event.expires, "F j, Y"), + ) def item_description(self, item): return strip_control_characters(linebreaks(item.lc_event.desc)) @@ -94,33 +126,55 @@ def item_description(self, item): def item_pubdate(self, item): return item.lc_event.time + class Rss201WithNamespacesFeed(Rss201rev2Feed): def root_attributes(self): attrs = super(Rss201WithNamespacesFeed, self).root_attributes() - attrs['xmlns:dcterms'] = 'http://purl.org/dc/terms/' - attrs['xmlns:media'] = 'http://search.yahoo.com/mrss/' - attrs['xmlns:xsi'] = 'http://www.w3.org/2001/XMLSchema-instance' + attrs["xmlns:dcterms"] = "http://purl.org/dc/terms/" + attrs["xmlns:media"] = "http://search.yahoo.com/mrss/" + attrs["xmlns:xsi"] = "http://www.w3.org/2001/XMLSchema-instance" return attrs def add_item_elements(self, handler, item): super(Rss201WithNamespacesFeed, self).add_item_elements(handler, item) - for element_name in ['abstract','accessRights', 'format', 'publisher',]: - dc_item_name = 'dcterms_%s' % element_name - dc_element_name = 'dcterms:%s' % element_name - attrs= {'xsi:type':'dcterms:local'} if element_name == 'publisher' else {} + for element_name in [ + "abstract", + "accessRights", + "format", + "publisher", + ]: + dc_item_name = "dcterms_%s" % element_name + dc_element_name = "dcterms:%s" % element_name + attrs = {"xsi:type": "dcterms:local"} if element_name == "publisher" else {} if dc_item_name in item and item[dc_item_name] is not None: - handler.addQuickElement(dc_element_name,item[dc_item_name],attrs) + handler.addQuickElement(dc_element_name, item[dc_item_name], attrs) + + if "doi" in item and item["doi"] is not None: + handler.addQuickElement( + "dcterms:identifier", item["doi"], {"xsi:type": "dcterms:doi"} + ) + if "doiuri" in item and item["doiuri"] is not None: + handler.addQuickElement( + "dcterms:identifier", item["doiuri"], {"xsi:type": "dcterms:uri"} + ) + + # TODO: consider using media:group + if "media_contents" in item and item["media_contents"] is not None: + for media_content in item["media_contents"]: + handler.startElement( + "media:content", + { + "url": media_content["url"], + "type": media_content["media_type"], + }, + ) + if "is_format_of" in media_content: + handler.addQuickElement( + "dcterms:isFormatOf", media_content["is_format_of"] + ) + handler.endElement("media:content") - if 'doi' in item and item['doi'] is not None: - handler.addQuickElement('dcterms:identifier',item['doi'],{'xsi:type':'dcterms:doi'}) - if 'doiuri' in item and item['doiuri'] is not None: - handler.addQuickElement('dcterms:identifier',item['doiuri'],{'xsi:type':'dcterms:uri'}) - - if 'media_content' in item and item['media_content'] is not None: - handler.startElement('media:content',{'url':item['media_content']['url'],'type':'text/plain'}) - handler.addQuickElement('dcterms:isFormatOf',item['media_content']['link_url']) - handler.endElement('media:content') class RfcFeed(Feed): feed_type = Rss201WithNamespacesFeed @@ -128,48 +182,90 @@ class RfcFeed(Feed): author_name = "RFC Editor" link = "https://www.rfc-editor.org/rfc-index2.html" - def get_object(self,request,year=None): + def get_object(self, request, year=None): self.year = year - + def items(self): if self.year: - rfc_events = DocEvent.objects.filter(type='published_rfc',time__year=self.year).order_by('-time') + # Find published RFCs based on their official publication year + start_of_year = datetime.datetime(int(self.year), 1, 1, tzinfo=RPC_TZINFO) + start_of_next_year = datetime.datetime( + int(self.year) + 1, 1, 1, tzinfo=RPC_TZINFO + ) + rfc_events = DocEvent.objects.filter( + type="published_rfc", + time__gte=start_of_year, + time__lt=start_of_next_year, + ).order_by("-time") else: - cutoff = datetime.datetime.now() - datetime.timedelta(days=8) - rfc_events = DocEvent.objects.filter(type='published_rfc',time__gte=cutoff).order_by('-time') + cutoff = timezone.now() - datetime.timedelta(days=8) + rfc_events = DocEvent.objects.filter( + type="published_rfc", time__gte=cutoff + ).order_by("-time") results = [(e.doc, e.time) for e in rfc_events] - for doc,time in results: + for doc, time in results: doc.publication_time = time - return [doc for doc,time in results] - + return [doc for doc, time in results] + def item_title(self, item): - return "%s : %s" % (item.canonical_name(),item.title) + return "%s : %s" % (item.name, item.title) def item_description(self, item): return item.abstract def item_link(self, item): - return "https://rfc-editor.org/info/%s"%item.canonical_name() + return "https://rfc-editor.org/info/%s" % item.name def item_pubdate(self, item): return item.publication_time def item_extra_kwargs(self, item): extra = super(RfcFeed, self).item_extra_kwargs(item) - extra.update({'dcterms_accessRights': 'gratis'}) - extra.update({'dcterms_format': 'text/html'}) - extra.update({'media_content': {'url': 'https://rfc-editor.org/rfc/%s.txt' % item.canonical_name(), - 'link_url': self.item_link(item) - } - }) - extra.update({'doi':'10.17487/%s' % item.canonical_name().upper()}) - extra.update({'doiuri':'http://dx.doi.org/10.17487/%s' % item.canonical_name().upper()}) - - #TODO + extra.update({"dcterms_accessRights": "gratis"}) + extra.update({"dcterms_format": "text/html"}) + media_contents = [] + if item.rfc_number < settings.FIRST_V3_RFC: + if item.rfc_number not in [8, 9, 51, 418, 500, 530, 589]: + for fmt, media_type in [("txt", "text/plain"), ("html", "text/html")]: + media_contents.append( + { + "url": f"https://rfc-editor.org/rfc/{item.name}.{fmt}", + "media_type": media_type, + "is_format_of": self.item_link(item), + } + ) + else: + media_contents.append( + { + "url": f"https://www.rfc-editor.org/rfc/{item.name}.xml", + "media_type": "application/rfc+xml", + } + ) + for fmt, media_type in [ + ("txt", "text/plain"), + ("html", "text/html"), + ("pdf", "application/pdf"), + ]: + media_contents.append( + { + "url": f"https://rfc-editor.org/rfc/{item.name}.{fmt}", + "media_type": media_type, + "is_format_of": f"https://www.rfc-editor.org/rfc/{item.name}.xml", + } + ) + extra.update({"media_contents": media_contents}) + + extra.update( + { + "doi": item.doi, + "doiuri": f"https://doi.org/{item.doi}", + } + ) + # R104 Publisher (Mandatory - but we need a string from them first) - extra.update({'dcterms_publisher':'rfc-editor.org'}) + extra.update({"dcterms_publisher": "rfc-editor.org"}) - #TODO MAYBE (Optional stuff) + # TODO MAYBE (Optional stuff) # R108 License # R115 Creator/Contributor (which would we use?) # F305 Checksum (do they use it?) (or should we put the our digital signature in here somewhere?) @@ -179,4 +275,3 @@ def item_extra_kwargs(self, item): # R118 Keyword return extra - diff --git a/ietf/doc/fields.py b/ietf/doc/fields.py index fde51995094..4a6922bf345 100644 --- a/ietf/doc/fields.py +++ b/ietf/doc/fields.py @@ -13,7 +13,7 @@ import debug # pyflakes:ignore -from ietf.doc.models import Document, DocAlias +from ietf.doc.models import Document from ietf.doc.utils import uppercase_std_abbreviated_name from ietf.utils.fields import SearchableField @@ -69,19 +69,3 @@ def ajax_url(self): class SearchableDocumentField(SearchableDocumentsField): """Specialized to only return one Document""" max_entries = 1 - - -class SearchableDocAliasesField(SearchableDocumentsField): - """Search DocAliases instead of Documents""" - model = DocAlias # type: Type[models.Model] - - def doc_type_filter(self, queryset): - """Filter to include only desired doc type - - For DocAlias, pass through to the docs to check type. - """ - return queryset.filter(docs__type=self.doc_type) - -class SearchableDocAliasField(SearchableDocAliasesField): - """Specialized to only return one DocAlias""" - max_entries = 1 \ No newline at end of file diff --git a/ietf/doc/forms.py b/ietf/doc/forms.py index d209eb0a2fa..768d6f96af2 100644 --- a/ietf/doc/forms.py +++ b/ietf/doc/forms.py @@ -1,4 +1,4 @@ -# Copyright The IETF Trust 2013-2020, All Rights Reserved +# Copyright The IETF Trust 2013-2025, All Rights Reserved # -*- coding: utf-8 -*- @@ -6,15 +6,17 @@ import debug #pyflakes:ignore from django import forms from django.core.exceptions import ObjectDoesNotExist, ValidationError +from django.core.validators import validate_email -from ietf.doc.fields import SearchableDocAliasesField, SearchableDocAliasField -from ietf.doc.models import RelatedDocument, DocExtResource +from ietf.doc.fields import SearchableDocumentField, SearchableDocumentsField +from ietf.doc.models import RelatedDocument, DocExtResource, State from ietf.iesg.models import TelechatDate from ietf.iesg.utils import telechat_page_count from ietf.person.fields import SearchablePersonField, SearchablePersonsField from ietf.person.models import Email, Person from ietf.name.models import ExtResourceName +from ietf.utils.timezone import date_today from ietf.utils.validators import validate_external_resource_value class TelechatForm(forms.Form): @@ -34,7 +36,7 @@ def __init__(self, *args, **kwargs): for d in dates: self.page_count[d] = telechat_page_count(date=d).for_approval choice_display[d] = '%s (%s pages)' % (d.strftime("%Y-%m-%d"),self.page_count[d]) - if d-datetime.date.today() < datetime.timedelta(days=13): + if d - date_today() < datetime.timedelta(days=13): choice_display[d] += ' : WARNING - this may not leave enough time for directorate reviews!' self.fields['telechat_date'].choices = [("", "(not on agenda)")] + [(d, choice_display[d]) for d in dates] @@ -59,7 +61,7 @@ class DocAuthorChangeBasisForm(forms.Form): basis = forms.CharField(max_length=255, label='Reason for change', help_text='What is the source or reasoning for the changes to the author list?') - + class AdForm(forms.Form): ad = forms.ModelChoiceField(Person.objects.filter(role__name="ad", role__group__state="active", role__group__type='area').order_by('name'), label="Shepherding AD", empty_label="(None)", required=True) @@ -74,11 +76,51 @@ def __init__(self, *args, **kwargs): self.fields['ad'].choices = list(choices) + [("", "-------"), (ad_pk, Person.objects.get(pk=ad_pk).plain_name())] class NotifyForm(forms.Form): - notify = forms.CharField(max_length=255, help_text="List of email addresses to receive state notifications, separated by comma.", label="Notification list", required=False) + notify = forms.CharField( + widget=forms.Textarea, + max_length=1023, + help_text="List of email addresses to receive state notifications, separated by comma.", + label="Notification list", + required=False, + ) def clean_notify(self): - addrspecs = [x.strip() for x in self.cleaned_data["notify"].split(',')] - return ', '.join(addrspecs) + # As long as the widget is a Textarea, users will separate addresses with newlines, whether that matches the instructions or not + # We have been allowing nameaddrs for a long time (there are many Documents with namaddrs in their notify field) + # python set doesn't preserve order, so in an attempt to mostly preserve the order of what was entered, we'll use + # a dict (whose keys are guaranteed to be ordered) to cull out duplicates + + nameaddrs=dict() + duplicate_addrspecs = set() + bad_nameaddrs = [] + for nameaddr in self.cleaned_data["notify"].replace("\n", ",").split(","): + stripped = nameaddr.strip() + if stripped == "": + continue + if "<" in stripped: + if stripped[-1] != ">": + bad_nameaddrs.append(nameaddr) + continue + addrspec = stripped[stripped.find("<")+1:-1] + else: + addrspec = stripped + try: + validate_email(addrspec) + except ValidationError: + bad_nameaddrs.append(nameaddr) + if addrspec in nameaddrs: + duplicate_addrspecs.add(addrspec) + continue + else: + nameaddrs[addrspec] = stripped + error_messages = [] + if len(duplicate_addrspecs) != 0: + error_messages.append(f'Duplicate addresses: {", ".join(duplicate_addrspecs)}') + if len(bad_nameaddrs) != 0: + error_messages.append(f'Invalid addresses: {", ".join(bad_nameaddrs)}') + if len(error_messages) != 0: + raise ValidationError(" and ".join(error_messages)) + return ", ".join(nameaddrs.values()) class ActionHoldersForm(forms.Form): action_holders = SearchablePersonsField(required=False) @@ -92,13 +134,14 @@ class ActionHoldersForm(forms.Form): IESG_APPROVED_STATE_LIST = ("ann", "rfcqueue", "pub") class AddDownrefForm(forms.Form): - rfc = SearchableDocAliasField( + rfc = SearchableDocumentField( label="Referenced RFC", help_text="The RFC that is approved for downref", - required=True) - drafts = SearchableDocAliasesField( + required=True, + doc_type="rfc") + drafts = SearchableDocumentsField( label="Internet-Drafts that makes the reference", - help_text="The drafts that approve the downref in their Last Call", + help_text="The Internet-Drafts that approve the downref in their Last Call", required=True) def clean_rfc(self): @@ -106,7 +149,7 @@ def clean_rfc(self): raise forms.ValidationError("Please provide a referenced RFC and a referencing Internet-Draft") rfc = self.cleaned_data['rfc'] - if not rfc.document.is_rfc(): + if rfc.type_id != "rfc": raise forms.ValidationError("Cannot find the RFC: " + rfc.name) return rfc @@ -116,12 +159,12 @@ def clean_drafts(self): v_err_names = [] drafts = self.cleaned_data['drafts'] - for da in drafts: - state = da.document.get_state("draft-iesg") + for d in drafts: + state = d.get_state("draft-iesg") if not state or state.slug not in IESG_APPROVED_STATE_LIST: - v_err_names.append(da.name) + v_err_names.append(d.name) if v_err_names: - raise forms.ValidationError("Draft is not yet approved: " + ", ".join(v_err_names)) + raise forms.ValidationError("Internet-Draft is not yet approved: " + ", ".join(v_err_names)) return drafts def clean(self): @@ -131,23 +174,23 @@ def clean(self): v_err_pairs = [] rfc = self.cleaned_data['rfc'] drafts = self.cleaned_data['drafts'] - for da in drafts: - if RelatedDocument.objects.filter(source=da.document, target=rfc, relationship_id='downref-approval'): - v_err_pairs.append(da.name + " --> RFC " + rfc.document.rfc_number()) + for d in drafts: + if RelatedDocument.objects.filter(source=d, target=rfc, relationship_id='downref-approval'): + v_err_pairs.append(f"{d.name} --> RFC {rfc.rfc_number}") if v_err_pairs: raise forms.ValidationError("Downref is already in the registry: " + ", ".join(v_err_pairs)) if 'save_downref_anyway' not in self.data: # this check is skipped if the save_downref_anyway button is used v_err_refnorm = "" - for da in drafts: - if not RelatedDocument.objects.filter(source=da.document, target=rfc, relationship_id='refnorm'): + for d in drafts: + if not RelatedDocument.objects.filter(source=d, target=rfc, relationship_id='refnorm'): if v_err_refnorm: - v_err_refnorm = v_err_refnorm + " or " + da.name + v_err_refnorm = v_err_refnorm + " or " + d.name else: - v_err_refnorm = da.name + v_err_refnorm = d.name if v_err_refnorm: - v_err_refnorm_prefix = "There does not seem to be a normative reference to RFC " + rfc.document.rfc_number() + " by " + v_err_refnorm_prefix = f"There does not seem to be a normative reference to RFC {rfc.rfc_number} by " raise forms.ValidationError(v_err_refnorm_prefix + v_err_refnorm) @@ -222,4 +265,33 @@ def clean(self): @staticmethod def valid_resource_tags(): - return ExtResourceName.objects.all().order_by('slug').values_list('slug', flat=True) \ No newline at end of file + return ExtResourceName.objects.all().order_by('slug').values_list('slug', flat=True) + +class InvestigateForm(forms.Form): + name_fragment = forms.CharField( + label="File name or fragment to investigate", + required=True, + help_text=( + "Enter a filename such as draft-ietf-some-draft-00.txt or a fragment like draft-ietf-some-draft using at least 8 characters. The search will also work for files that are not necessarily drafts." + ), + min_length=8, + ) + task_id = forms.CharField(required=False, widget=forms.HiddenInput) + + def clean_name_fragment(self): + disallowed_characters = ["%", "/", "\\", "*"] + name_fragment = self.cleaned_data["name_fragment"] + # Manual inspection of the directories at the time of this writing shows + # looking for files with less than 8 characters in the name is not useful + # Requiring this will help protect against the secretariat unintentionally + # matching every draft. + if any(c in name_fragment for c in disallowed_characters): + raise ValidationError(f"The following characters are disallowed: {', '.join(disallowed_characters)}") + return name_fragment + + +class ChangeStatementStateForm(forms.Form): + state = forms.ModelChoiceField( + State.objects.filter(used=True, type="statement"), + empty_label=None, + ) diff --git a/ietf/doc/lastcall.py b/ietf/doc/lastcall.py index fab3001b1a9..dd38fd3909f 100644 --- a/ietf/doc/lastcall.py +++ b/ietf/doc/lastcall.py @@ -1,6 +1,4 @@ -# helpers for handling last calls on Internet Drafts - -import datetime +# helpers for handling last calls on Internet-Drafts from django.db.models import Q @@ -10,6 +8,8 @@ from ietf.doc.utils import add_state_change_event, update_action_holders from ietf.doc.mails import generate_ballot_writeup, generate_approval_mail, generate_last_call_announcement from ietf.doc.mails import send_last_call_request, email_last_call_expired, email_last_call_expired_with_downref +from ietf.utils.timezone import date_today, DEADLINE_TZINFO + def request_last_call(request, doc): if not doc.latest_event(type="changed_ballot_writeup_text"): @@ -33,11 +33,10 @@ def request_last_call(request, doc): e.save() def get_expired_last_calls(): - today = datetime.date.today() for d in Document.objects.filter(Q(states__type="draft-iesg", states__slug="lc") | Q(states__type="statchg", states__slug="in-lc")): e = d.latest_event(LastCallDocEvent, type="sent_last_call") - if e and e.expires.date() <= today: + if e and e.expires.astimezone(DEADLINE_TZINFO).date() <= date_today(DEADLINE_TZINFO): yield d def expire_last_call(doc): @@ -74,4 +73,4 @@ def expire_last_call(doc): if doc.type_id == 'draft': lc_text = doc.latest_event(LastCallDocEvent, type="sent_last_call").desc if "document makes the following downward references" in lc_text: - email_last_call_expired_with_downref(doc, lc_text) \ No newline at end of file + email_last_call_expired_with_downref(doc, lc_text) diff --git a/ietf/doc/mails.py b/ietf/doc/mails.py index 0f344f0159c..ddecbb6b54b 100644 --- a/ietf/doc/mails.py +++ b/ietf/doc/mails.py @@ -10,7 +10,8 @@ from django.utils.html import strip_tags from django.conf import settings from django.urls import reverse as urlreverse -from django.utils.encoding import force_text +from django.utils import timezone +from django.utils.encoding import force_str import debug # pyflakes:ignore from ietf.doc.templatetags.mail_filters import std_level_prompt @@ -18,12 +19,13 @@ from ietf.utils import log from ietf.utils.mail import send_mail, send_mail_text from ietf.ipr.utils import iprs_from_docs, related_docs -from ietf.doc.models import WriteupDocEvent, LastCallDocEvent, DocAlias, ConsensusDocEvent +from ietf.doc.models import WriteupDocEvent, LastCallDocEvent, ConsensusDocEvent from ietf.doc.utils import needed_ballot_positions from ietf.doc.utils_bofreq import bofreq_editors, bofreq_responsible from ietf.group.models import Role from ietf.doc.models import Document from ietf.mailtrigger.utils import gather_address_lists +from ietf.utils.timezone import date_today, DEADLINE_TZINFO def email_state_changed(request, doc, text, mailtrigger_id=None): @@ -52,7 +54,7 @@ def email_ad_approved_doc(request, doc, text): def email_ad_approved_conflict_review(request, review, ok_to_publish): """Email notification when AD approves a conflict review""" - conflictdoc = review.relateddocument_set.get(relationship__slug='conflrev').target.document + conflictdoc = review.relateddocument_set.get(relationship__slug='conflrev').target (to, cc) = gather_address_lists("ad_approved_conflict_review") frm = request.user.person.formatted_email() send_mail(request, @@ -96,7 +98,7 @@ def email_stream_changed(request, doc, old_stream, new_stream, text=""): text = strip_tags(text) send_mail(request, to, None, - "ID Tracker Stream Change Notice: %s" % doc.file_tag(), + "I-D Tracker Stream Change Notice: %s" % doc.file_tag(), "doc/mail/stream_changed_email.txt", dict(text=text, url=settings.IDTRACKER_BASE_URL + doc.get_absolute_url()), @@ -173,7 +175,7 @@ def generate_ballot_writeup(request, doc): e.doc = doc e.rev = doc.rev e.desc = "Ballot writeup was generated" - e.text = force_text(render_to_string("doc/mail/ballot_writeup.txt", {'iana': iana})) + e.text = force_str(render_to_string("doc/mail/ballot_writeup.txt", {'iana': iana, 'doc': doc })) # caller is responsible for saving, if necessary return e @@ -185,13 +187,13 @@ def generate_ballot_rfceditornote(request, doc): e.doc = doc e.rev = doc.rev e.desc = "RFC Editor Note for ballot was generated" - e.text = force_text(render_to_string("doc/mail/ballot_rfceditornote.txt")) + e.text = force_str(render_to_string("doc/mail/ballot_rfceditornote.txt")) e.save() return e def generate_last_call_announcement(request, doc): - expiration_date = datetime.date.today() + datetime.timedelta(days=14) + expiration_date = date_today(DEADLINE_TZINFO) + datetime.timedelta(days=14) if doc.group.type_id in ("individ", "area"): group = "an individual submitter" expiration_date += datetime.timedelta(days=14) @@ -200,7 +202,7 @@ def generate_last_call_announcement(request, doc): doc.filled_title = textwrap.fill(doc.title, width=70, subsequent_indent=" " * 3) - iprs = iprs_from_docs(related_docs(DocAlias.objects.get(name=doc.canonical_name()))) + iprs = iprs_from_docs(related_docs(Document.objects.get(name=doc.name))) if iprs: ipr_links = [ urlreverse("ietf.ipr.views.show", kwargs=dict(id=i.id)) for i in iprs] ipr_links = [ settings.IDTRACKER_BASE_URL+url if not url.startswith("http") else url for url in ipr_links ] @@ -230,7 +232,7 @@ def generate_last_call_announcement(request, doc): e.doc = doc e.rev = doc.rev e.desc = "Last call announcement was generated" - e.text = force_text(mail) + e.text = force_str(mail) # caller is responsible for saving, if necessary return e @@ -250,7 +252,7 @@ def generate_approval_mail(request, doc): e.doc = doc e.rev = doc.rev e.desc = "Ballot approval text was generated" - e.text = force_text(mail) + e.text = force_str(mail) # caller is responsible for saving, if necessary return e @@ -286,7 +288,7 @@ def generate_approval_mail_approved(request, doc): else: contacts = "The IESG contact person is %s." % responsible_directors[0] - doc_type = "RFC" if doc.get_state_slug() == "rfc" else "Internet Draft" + doc_type = "RFC" if doc.get_state_slug() == "rfc" else "Internet-Draft" addrs = gather_address_lists('ballot_approved_ietf_stream',doc=doc).as_strings() return render_to_string("doc/mail/approval_mail.txt", @@ -306,7 +308,7 @@ def generate_approval_mail_rfc_editor(request, doc): # This is essentially dead code - it is only exercised if the IESG ballots on some other stream's document, # which does not happen now that we have conflict reviews. disapproved = doc.get_state_slug("draft-iesg") in DO_NOT_PUBLISH_IESG_STATES - doc_type = "RFC" if doc.get_state_slug() == "rfc" else "Internet Draft" + doc_type = "RFC" if doc.get_state_slug() == "rfc" else "Internet-Draft" addrs = gather_address_lists('ballot_approved_conflrev', doc=doc).as_strings() return render_to_string("doc/mail/approval_mail_rfc_editor.txt", @@ -332,6 +334,9 @@ def generate_publication_request(request, doc): if doc.stream_id == "irtf": approving_body = "IRSG" consensus_body = doc.group.acronym.upper() + if doc.stream_id == "editorial": + approving_body = "RSAB" + consensus_body = doc.group.acronym.upper() else: approving_body = str(doc.stream) consensus_body = approving_body @@ -418,7 +423,7 @@ def generate_issue_ballot_mail(request, doc, ballot): e = doc.latest_event(LastCallDocEvent, type="sent_last_call") last_call_expires = e.expires if e else None - last_call_has_expired = last_call_expires and last_call_expires < datetime.datetime.now() + last_call_has_expired = last_call_expires and last_call_expires < timezone.now() return render_to_string("doc/mail/issue_iesg_ballot_mail.txt", dict(doc=doc, @@ -437,7 +442,7 @@ def _send_irsg_ballot_email(request, doc, ballot, subject, template): (to, cc) = gather_address_lists('irsg_ballot_issued', doc=doc) sender = 'IESG Secretary ' - ballot_expired = ballot.duedate < datetime.datetime.now() + ballot_expired = ballot.duedate < timezone.now() active_ballot = doc.active_ballot() if active_ballot is None: needed_bps = '' @@ -484,6 +489,54 @@ def email_irsg_ballot_closed(request, doc, ballot): "doc/mail/close_irsg_ballot_mail.txt", ) +def _send_rsab_ballot_email(request, doc, ballot, subject, template): + """Send email notification when IRSG ballot is issued""" + (to, cc) = gather_address_lists('rsab_ballot_issued', doc=doc) + sender = 'IESG Secretary ' + + active_ballot = doc.active_ballot() + if active_ballot is None: + needed_bps = '' + else: + needed_bps = needed_ballot_positions( + doc, + list(active_ballot.active_balloter_positions().values()) + ) + + return send_mail( + request=request, + frm=sender, + to=to, + cc=cc, + subject=subject, + extra={'Reply-To': [sender]}, + template=template, + context=dict( + doc=doc, + doc_url=settings.IDTRACKER_BASE_URL + doc.get_absolute_url(), + needed_ballot_positions=needed_bps, + )) + +def email_rsab_ballot_issued(request, doc, ballot): + """Send email notification when RSAB ballot is issued""" + return _send_rsab_ballot_email( + request, + doc, + ballot, + 'RSAB ballot issued: %s to %s'%(doc.file_tag(), std_level_prompt(doc)), + 'doc/mail/issue_rsab_ballot_mail.txt', + ) + +def email_rsab_ballot_closed(request, doc, ballot): + """Send email notification when RSAB ballot is closed""" + return _send_rsab_ballot_email( + request, + doc, + ballot, + 'RSAB ballot closed: %s to %s'%(doc.file_tag(), std_level_prompt(doc)), + "doc/mail/close_rsab_ballot_mail.txt", + ) + def email_iana(request, doc, to, msg, cc=None): # fix up message and send it with extra info on doc in headers import email @@ -515,7 +568,7 @@ def email_last_call_expired(doc): send_mail(None, addrs.to, "DraftTracker Mail System ", - "Last Call Expired: %s" % doc.file_tag(), + "IETF Last Call Expired: %s" % doc.file_tag(), "doc/mail/change_notice.txt", dict(text=text, doc=doc, @@ -617,7 +670,7 @@ def send_review_possibly_replaces_request(request, doc, submitter_info): to = set(addrs.to) cc = set(addrs.cc) - possibly_replaces = Document.objects.filter(name__in=[alias.name for alias in doc.related_that_doc("possibly-replaces")]) + possibly_replaces = Document.objects.filter(name__in=[related.name for related in doc.related_that_doc("possibly-replaces")]) for other_doc in possibly_replaces: (other_to, other_cc) = gather_address_lists('doc_replacement_suggested',doc=other_doc) to.update(other_to) diff --git a/ietf/doc/management/commands/find_github_backup_info.py b/ietf/doc/management/commands/find_github_backup_info.py deleted file mode 100644 index f1f71452df2..00000000000 --- a/ietf/doc/management/commands/find_github_backup_info.py +++ /dev/null @@ -1,74 +0,0 @@ -# Copyright The IETF Trust 2020, All Rights Reserved - - -import github3 - -from collections import Counter -from urllib.parse import urlparse - -from django.conf import settings -from django.core.management.base import BaseCommand, CommandError - -from ietf.doc.models import DocExtResource -from ietf.group.models import GroupExtResource -from ietf.person.models import PersonExtResource - -# TODO: Think more about submodules. This currently will only take top level repos, with the assumption that the clone will include arguments to grab all the submodules. -# As a consequence, we might end up pulling more than we need (or that the org or user expected) -# Make sure this is what we want. - -class Command(BaseCommand): - help = ('Locate information about github repositories to backup') - - def add_arguments(self, parser): - parser.add_argument('--verbose', dest='verbose', action='store_true', help='Show counts of types of repositories') - - def handle(self, *args, **options): - - if not (hasattr(settings,'GITHUB_BACKUP_API_KEY') and settings.GITHUB_BACKUP_API_KEY): - raise CommandError("ERROR: can't find GITHUB_BACKUP_API_KEY") # TODO: at >= py3.1, use returncode - - github = github3.login(token = settings.GITHUB_BACKUP_API_KEY) - owners = dict() - repos = set() - - for cls in (DocExtResource, GroupExtResource, PersonExtResource): - for res in cls.objects.filter(name_id__in=('github_repo','github_org')): - path_parts = urlparse(res.value).path.strip('/').split('/') - if not path_parts or not path_parts[0]: - continue - - owner = path_parts[0] - - if owner not in owners: - try: - gh_owner = github.user(username=owner) - owners[owner] = gh_owner - except github3.exceptions.NotFoundError: - continue - - if gh_owner.type in ('User', 'Organization'): - if len(path_parts) > 1: - repo = path_parts[1] - if (owner, repo) not in repos: - try: - github.repository(owner,repo) - repos.add( (owner, repo) ) - except github3.exceptions.NotFoundError: - continue - else: - for repo in github.repositories_by(owner): - repos.add( (owner, repo.name) ) - - owner_types = Counter([owners[owner].type for owner in owners]) - if options['verbose']: - self.stdout.write("Owners:") - for key in owner_types: - self.stdout.write(" %s: %s"%(key,owner_types[key])) - self.stdout.write("Repositories: %d" % len(repos)) - for repo in sorted(repos): - self.stdout.write(" https://github.com/%s/%s" % repo ) - else: - for repo in sorted(repos): - self.stdout.write("%s/%s" % repo ) - diff --git a/ietf/doc/management/commands/fix_105_slides.py b/ietf/doc/management/commands/fix_105_slides.py deleted file mode 100644 index b8689482e81..00000000000 --- a/ietf/doc/management/commands/fix_105_slides.py +++ /dev/null @@ -1,64 +0,0 @@ -# Copyright The IETF Trust 2019-2020, All Rights Reserved -# -*- coding: utf-8 -*- - - -import os - -from collections import Counter - -from django.core.management.base import BaseCommand - -from ietf.doc.models import DocEvent -from ietf.meeting.models import Meeting, SessionPresentation -from ietf.person.models import Person - -from ietf.secr.proceedings.proc_utils import is_powerpoint, post_process - -class Command(BaseCommand): - help = ('Fix uploaded_filename and generate pdf from pptx') - - def add_arguments(self, parser): - parser.add_argument('--dry-run', action='store_true', dest='dry-run', default=False, help='Report on changes that would be made without making them') - - def handle(self, *args, **options): - ietf105 = Meeting.objects.get(number=105) - slides_path = os.path.join(ietf105.get_materials_path(),'slides') - system_person = Person.objects.get(name="(System)") - counts = Counter() - - for sp in SessionPresentation.objects.filter(session__meeting__number=105,document__type='slides'): #.filter(document__name='slides-105-manet-dlep-multicast-support-discussion'): - slides = sp.document - if not os.path.exists(os.path.join(slides_path,slides.uploaded_filename)): - name, ext = os.path.splitext(slides.uploaded_filename) - target_filename = '%s-%s%s' % (name[:name.rfind('-ss')], slides.rev,ext) - if os.path.exists(os.path.join(slides_path,target_filename)): - slides.uploaded_filename = target_filename - if not options['dry-run']: - e = DocEvent.objects.create(doc=slides, rev=slides.rev, by=system_person, type='changed_document', desc='Corrected uploaded_filename') - slides.save_with_history([e]) - counts['uploaded_filename repair succeeded'] += 1 - - else: - self.stderr.write("Unable to repair %s" % slides) - counts['uploaded_filename repair failed'] += 1 - continue - else: - counts['uploaded_filename already ok'] += 1 - - if is_powerpoint(slides): - base, _ = os.path.splitext(slides.uploaded_filename) - if os.path.exists(os.path.join(slides_path,base+'.pdf')): - self.stderr.write("PDF already exists for %s " % slides) - counts['PDF already exists for a repaired file'] += 1 - else: - if not options['dry-run']: - post_process(slides) - counts['PDF conversions'] += 1 - - if options['dry-run']: - self.stdout.write("This is a dry-run. Nothing has actually changed. In a normal run, the output would say the following:") - - for label,count in counts.iteritems(): - self.stdout.write("%s : %d" % (label,count) ) - - diff --git a/ietf/doc/management/commands/generate_draft_aliases.py b/ietf/doc/management/commands/generate_draft_aliases.py deleted file mode 100755 index 796e3db639b..00000000000 --- a/ietf/doc/management/commands/generate_draft_aliases.py +++ /dev/null @@ -1,179 +0,0 @@ -# Copyright The IETF Trust 2012-2021, All Rights Reserved -# -*- coding: utf-8 -*- - -# This was written as a script by Markus Stenberg . -# It was turned into a management command by Russ Housley . - -import datetime -import io -import os -import re -import shutil -import stat -import time - -from tempfile import mkstemp - -from django.conf import settings -from django.core.management.base import BaseCommand - -import debug # pyflakes:ignore - -from ietf.doc.models import Document -from ietf.group.utils import get_group_role_emails, get_group_ad_emails -from ietf.utils.aliases import dump_sublist -from utils.mail import parseaddr - -DEFAULT_YEARS = 2 - - -def get_draft_ad_emails(doc): - """Get AD email addresses for the given draft, if any.""" - ad_emails = set() - # If working group document, return current WG ADs - if doc.group and doc.group.acronym != 'none': - ad_emails.update(get_group_ad_emails(doc.group)) - # Document may have an explicit AD set - if doc.ad: - ad_emails.add(doc.ad.email_address()) - return ad_emails - - -def get_draft_chair_emails(doc): - """Get chair email addresses for the given draft, if any.""" - chair_emails = set() - if doc.group: - chair_emails.update(get_group_role_emails(doc.group, ['chair', 'secr'])) - return chair_emails - - -def get_draft_shepherd_email(doc): - """Get shepherd email addresses for the given draft, if any.""" - shepherd_email = set() - if doc.shepherd: - shepherd_email.add(doc.shepherd.email_address()) - return shepherd_email - - -def get_draft_authors_emails(doc): - """Get list of authors for the given draft.""" - author_emails = set() - for author in doc.documentauthor_set.all(): - if author.email and author.email.email_address(): - author_emails.add(author.email.email_address()) - return author_emails - - -def get_draft_notify_emails(doc): - """Get list of email addresses to notify for the given draft.""" - ad_email_alias_regex = r"^%s.ad@(%s|%s)$" % (doc.name, settings.DRAFT_ALIAS_DOMAIN, settings.TOOLS_SERVER) - all_email_alias_regex = r"^%s.all@(%s|%s)$" % (doc.name, settings.DRAFT_ALIAS_DOMAIN, settings.TOOLS_SERVER) - author_email_alias_regex = r"^%s@(%s|%s)$" % (doc.name, settings.DRAFT_ALIAS_DOMAIN, settings.TOOLS_SERVER) - notify_email_alias_regex = r"^%s.notify@(%s|%s)$" % (doc.name, settings.DRAFT_ALIAS_DOMAIN, settings.TOOLS_SERVER) - shepherd_email_alias_regex = r"^%s.shepherd@(%s|%s)$" % (doc.name, settings.DRAFT_ALIAS_DOMAIN, settings.TOOLS_SERVER) - notify_emails = set() - if doc.notify: - for e in doc.notify.split(','): - e = e.strip() - if re.search(ad_email_alias_regex, e): - notify_emails.update(get_draft_ad_emails(doc)) - elif re.search(author_email_alias_regex, e): - notify_emails.update(get_draft_authors_emails(doc)) - elif re.search(shepherd_email_alias_regex, e): - notify_emails.update(get_draft_shepherd_email(doc)) - elif re.search(all_email_alias_regex, e): - notify_emails.update(get_draft_ad_emails(doc)) - notify_emails.update(get_draft_authors_emails(doc)) - notify_emails.update(get_draft_shepherd_email(doc)) - elif re.search(notify_email_alias_regex, e): - pass - else: - (name, email) = parseaddr(e) - notify_emails.add(email) - return notify_emails - - -class Command(BaseCommand): - help = ('Generate the draft-aliases and draft-virtual files for Internet-Draft ' - 'mail aliases, placing them in the files configured in ' - 'settings.DRAFT_ALIASES_PATH and settings.DRAFT_VIRTUAL_PATH, ' - 'respectively. The generation includes aliases for Internet-Drafts ' - 'that have seen activity in the last %s years.' % (DEFAULT_YEARS)) - - def handle(self, *args, **options): - show_since = datetime.datetime.now() - datetime.timedelta(DEFAULT_YEARS*365) - - date = time.strftime("%Y-%m-%d_%H:%M:%S") - signature = '# Generated by %s at %s\n' % (os.path.abspath(__file__), date) - - ahandle, aname = mkstemp() - os.close(ahandle) - afile = io.open(aname,"w") - - vhandle, vname = mkstemp() - os.close(vhandle) - vfile = io.open(vname,"w") - - afile.write(signature) - vfile.write(signature) - vfile.write("%s anything\n" % settings.DRAFT_VIRTUAL_DOMAIN) - - # Internet-Drafts with active status or expired within DEFAULT_YEARS - drafts = Document.objects.filter(name__startswith='draft-') - active_drafts = drafts.filter(states__slug='active') - inactive_recent_drafts = drafts.exclude(states__slug='active').filter(expires__gte=show_since) - interesting_drafts = active_drafts | inactive_recent_drafts - - alias_domains = ['ietf.org', ] - for draft in interesting_drafts.distinct().iterator(): - # Omit RFCs, unless they were published in the last DEFAULT_YEARS - if draft.docalias.filter(name__startswith='rfc'): - if draft.latest_event(type='published_rfc').time < show_since: - continue - - alias = draft.name - all = set() - - # no suffix and .authors are the same list - emails = get_draft_authors_emails(draft) - all.update(emails) - dump_sublist(afile, vfile, alias, alias_domains, settings.DRAFT_VIRTUAL_DOMAIN, emails) - dump_sublist(afile, vfile, alias+'.authors', alias_domains, settings.DRAFT_VIRTUAL_DOMAIN, emails) - - # .chairs = group chairs - emails = get_draft_chair_emails(draft) - if emails: - all.update(emails) - dump_sublist(afile, vfile, alias+'.chairs', alias_domains, settings.DRAFT_VIRTUAL_DOMAIN, emails) - - # .ad = sponsoring AD / WG AD (WG document) - emails = get_draft_ad_emails(draft) - if emails: - all.update(emails) - dump_sublist(afile, vfile, alias+'.ad', alias_domains, settings.DRAFT_VIRTUAL_DOMAIN, emails) - - # .notify = notify email list from the Document - emails = get_draft_notify_emails(draft) - if emails: - all.update(emails) - dump_sublist(afile, vfile, alias+'.notify', alias_domains, settings.DRAFT_VIRTUAL_DOMAIN, emails) - - # .shepherd = shepherd email from the Document - emails = get_draft_shepherd_email(draft) - if emails: - all.update(emails) - dump_sublist(afile, vfile, alias+'.shepherd', alias_domains, settings.DRAFT_VIRTUAL_DOMAIN, emails) - - # .all = everything from above - dump_sublist(afile, vfile, alias+'.all', alias_domains, settings.DRAFT_VIRTUAL_DOMAIN, all) - - afile.close() - vfile.close() - - os.chmod(aname, stat.S_IWUSR|stat.S_IRUSR|stat.S_IRGRP|stat.S_IROTH) - os.chmod(vname, stat.S_IWUSR|stat.S_IRUSR|stat.S_IRGRP|stat.S_IROTH) - - shutil.move(aname, settings.DRAFT_ALIASES_PATH) - shutil.move(vname, settings.DRAFT_VIRTUAL_PATH) - - \ No newline at end of file diff --git a/ietf/doc/management/commands/generate_draft_bibxml_files.py b/ietf/doc/management/commands/generate_draft_bibxml_files.py deleted file mode 100644 index 8bdaa0a8626..00000000000 --- a/ietf/doc/management/commands/generate_draft_bibxml_files.py +++ /dev/null @@ -1,96 +0,0 @@ -# Copyright The IETF Trust 2012-2020, All Rights Reserved -# -*- coding: utf-8 -*- - - -import datetime -import io -import os -import re -import sys - -from django.conf import settings -from django.core.management.base import BaseCommand -from django.template.loader import render_to_string - -import debug # pyflakes:ignore - -from ietf.doc.models import NewRevisionDocEvent - -DEFAULT_DAYS = 7 - -class Command(BaseCommand): - help = ('Generate draft bibxml files for xml2rfc references, placing them in the ' - 'directory configured in settings.BIBXML_BASE_PATH: %s. ' - 'By default, generate files as needed for new draft revisions from the ' - 'last %s days.' % (settings.BIBXML_BASE_PATH, DEFAULT_DAYS)) - - def add_arguments(self, parser): - parser.add_argument('--all', action='store_true', default=False, help="Process all documents, not only recent submissions") - parser.add_argument('--days', type=int, default=DEFAULT_DAYS, help="Look submissions from the last DAYS days, instead of %s" % DEFAULT_DAYS) - - def say(self, msg): - if self.verbosity > 0: - sys.stdout.write(msg) - sys.stdout.write('\n') - - def note(self, msg): - if self.verbosity > 1: - sys.stdout.write(msg) - sys.stdout.write('\n') - - def mutter(self, msg): - if self.verbosity > 2: - sys.stdout.write(msg) - sys.stdout.write('\n') - - def write(self, fn, new): - # normalize new - new = re.sub(r'\r\n?', r'\n', new) - try: - with io.open(fn, encoding='utf-8') as f: - old = f.read() - except IOError: - old = "" - if old.strip() != new.strip(): - self.note('Writing %s' % os.path.basename(fn)) - with io.open(fn, "w", encoding='utf-8') as f: - f.write(new) - - def handle(self, *args, **options): - self.verbosity = options.get("verbosity", 1) - process_all = options.get("all") - days = options.get("days") - # - bibxmldir = os.path.join(settings.BIBXML_BASE_PATH, 'bibxml-ids') - if not os.path.exists(bibxmldir): - os.makedirs(bibxmldir) - # - if process_all: - doc_events = NewRevisionDocEvent.objects.filter(type='new_revision', doc__type_id='draft') - else: - start = datetime.datetime.now() - datetime.timedelta(days=days) - doc_events = NewRevisionDocEvent.objects.filter(type='new_revision', doc__type_id='draft', time__gte=start) - doc_events = doc_events.order_by('time') - - for e in doc_events: - self.mutter('%s %s' % (e.time, e.doc.name)) - try: - doc = e.doc - if e.rev != doc.rev: - for h in doc.history_set.order_by("-time"): - if e.rev == h.rev: - doc = h - break - doc.date = e.time.date() - ref_text = '%s' % render_to_string('doc/bibxml.xml', {'name':doc.name, 'doc': doc, 'doc_bibtype':'I-D'}) - # if e.rev == e.doc.rev: - # for name in (doc.name, doc.name[6:]): - # ref_file_name = os.path.join(bibxmldir, 'reference.I-D.%s.xml' % (name, )) - # self.write(ref_file_name, ref_text) - # for name in (doc.name, doc.name[6:]): - # ref_rev_file_name = os.path.join(bibxmldir, 'reference.I-D.%s-%s.xml' % (name, doc.rev)) - # self.write(ref_rev_file_name, ref_text) - ref_rev_file_name = os.path.join(bibxmldir, 'reference.I-D.%s-%s.xml' % (doc.name, doc.rev)) - self.write(ref_rev_file_name, ref_text) - except Exception as ee: - sys.stderr.write('\n%s-%s: %s\n' % (doc.name, doc.rev, ee)) diff --git a/ietf/doc/management/commands/generate_idnits2_rfc_status.py b/ietf/doc/management/commands/generate_idnits2_rfc_status.py deleted file mode 100644 index 45be1880181..00000000000 --- a/ietf/doc/management/commands/generate_idnits2_rfc_status.py +++ /dev/null @@ -1,23 +0,0 @@ -# Copyright The IETF Trust 2021 All Rights Reserved - -import os - -from django.conf import settings -from django.core.management.base import BaseCommand - -from ietf.doc.utils import generate_idnits2_rfc_status -from ietf.utils.log import log - -class Command(BaseCommand): - help = ('Generate the rfc_status blob used by idnits2') - - def handle(self, *args, **options): - filename=os.path.join(settings.DERIVED_DIR,'idnits2-rfc-status') - blob = generate_idnits2_rfc_status() - try: - bytes = blob.encode('utf-8') - with open(filename,'wb') as f: - f.write(bytes) - except Exception as e: - log('failed to write idnits2-rfc-status: '+str(e)) - raise e diff --git a/ietf/doc/management/commands/generate_idnits2_rfcs_obsoleted.py b/ietf/doc/management/commands/generate_idnits2_rfcs_obsoleted.py deleted file mode 100644 index 8bd122e87ef..00000000000 --- a/ietf/doc/management/commands/generate_idnits2_rfcs_obsoleted.py +++ /dev/null @@ -1,23 +0,0 @@ -# Copyright The IETF Trust 2021 All Rights Reserved - -import os - -from django.conf import settings -from django.core.management.base import BaseCommand - -from ietf.doc.utils import generate_idnits2_rfcs_obsoleted -from ietf.utils.log import log - -class Command(BaseCommand): - help = ('Generate the rfcs-obsoleted file used by idnits2') - - def handle(self, *args, **options): - filename=os.path.join(settings.DERIVED_DIR,'idnits2-rfcs-obsoleted') - blob = generate_idnits2_rfcs_obsoleted() - try: - bytes = blob.encode('utf-8') - with open(filename,'wb') as f: - f.write(bytes) - except Exception as e: - log('failed to write idnits2-rfcs-obsoleted: '+str(e)) - raise e diff --git a/ietf/doc/migrations/0001_initial.py b/ietf/doc/migrations/0001_initial.py index fd50d34fc78..2823abfe639 100644 --- a/ietf/doc/migrations/0001_initial.py +++ b/ietf/doc/migrations/0001_initial.py @@ -1,12 +1,9 @@ -# Copyright The IETF Trust 2018-2020, All Rights Reserved -# -*- coding: utf-8 -*- -# Generated by Django 1.11.10 on 2018-02-20 10:52 +# Generated by Django 2.2.28 on 2023-03-20 19:22 - -import datetime import django.core.validators from django.db import migrations, models import django.db.models.deletion +import django.utils.timezone import ietf.utils.models @@ -39,13 +36,14 @@ class Migration(migrations.Migration): fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('json', models.TextField(help_text='Deleted object in JSON format, with attribute names chosen to be suitable for passing into the relevant create method.')), - ('time', models.DateTimeField(default=datetime.datetime.now)), + ('time', models.DateTimeField(default=django.utils.timezone.now)), ], ), migrations.CreateModel( name='DocAlias', fields=[ - ('name', models.CharField(max_length=255, primary_key=True, serialize=False)), + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=255, unique=True)), ], options={ 'verbose_name': 'document alias', @@ -56,8 +54,8 @@ class Migration(migrations.Migration): name='DocEvent', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('time', models.DateTimeField(db_index=True, default=datetime.datetime.now, help_text='When the event happened')), - ('type', models.CharField(choices=[(b'new_revision', b'Added new revision'), (b'new_submission', b'Uploaded new revision'), (b'changed_document', b'Changed document metadata'), (b'added_comment', b'Added comment'), (b'added_message', b'Added message'), (b'edited_authors', b'Edited the documents author list'), (b'deleted', b'Deleted document'), (b'changed_state', b'Changed state'), (b'changed_stream', b'Changed document stream'), (b'expired_document', b'Expired document'), (b'extended_expiry', b'Extended expiry of document'), (b'requested_resurrect', b'Requested resurrect'), (b'completed_resurrect', b'Completed resurrect'), (b'changed_consensus', b'Changed consensus'), (b'published_rfc', b'Published RFC'), (b'added_suggested_replaces', b'Added suggested replacement relationships'), (b'reviewed_suggested_replaces', b'Reviewed suggested replacement relationships'), (b'changed_group', b'Changed group'), (b'changed_protocol_writeup', b'Changed protocol writeup'), (b'changed_charter_milestone', b'Changed charter milestone'), (b'initial_review', b'Set initial review time'), (b'changed_review_announcement', b'Changed WG Review text'), (b'changed_action_announcement', b'Changed WG Action text'), (b'started_iesg_process', b'Started IESG process on document'), (b'created_ballot', b'Created ballot'), (b'closed_ballot', b'Closed ballot'), (b'sent_ballot_announcement', b'Sent ballot announcement'), (b'changed_ballot_position', b'Changed ballot position'), (b'changed_ballot_approval_text', b'Changed ballot approval text'), (b'changed_ballot_writeup_text', b'Changed ballot writeup text'), (b'changed_rfc_editor_note_text', b'Changed RFC Editor Note text'), (b'changed_last_call_text', b'Changed last call text'), (b'requested_last_call', b'Requested last call'), (b'sent_last_call', b'Sent last call'), (b'scheduled_for_telechat', b'Scheduled for telechat'), (b'iesg_approved', b'IESG approved document (no problem)'), (b'iesg_disapproved', b'IESG disapproved document (do not publish)'), (b'approved_in_minute', b'Approved in minute'), (b'iana_review', b'IANA review comment'), (b'rfc_in_iana_registry', b'RFC is in IANA registry'), (b'rfc_editor_received_announcement', b'Announcement was received by RFC Editor'), (b'requested_publication', b'Publication at RFC Editor requested'), (b'sync_from_rfc_editor', b'Received updated information from RFC Editor'), (b'requested_review', b'Requested review'), (b'assigned_review_request', b'Assigned review request'), (b'closed_review_request', b'Closed review request'), (b'downref_approved', b'Downref approved')], max_length=50)), + ('time', models.DateTimeField(db_index=True, default=django.utils.timezone.now, help_text='When the event happened')), + ('type', models.CharField(choices=[('new_revision', 'Added new revision'), ('new_submission', 'Uploaded new revision'), ('changed_document', 'Changed document metadata'), ('added_comment', 'Added comment'), ('added_message', 'Added message'), ('edited_authors', 'Edited the documents author list'), ('deleted', 'Deleted document'), ('changed_state', 'Changed state'), ('changed_stream', 'Changed document stream'), ('expired_document', 'Expired document'), ('extended_expiry', 'Extended expiry of document'), ('requested_resurrect', 'Requested resurrect'), ('completed_resurrect', 'Completed resurrect'), ('changed_consensus', 'Changed consensus'), ('published_rfc', 'Published RFC'), ('added_suggested_replaces', 'Added suggested replacement relationships'), ('reviewed_suggested_replaces', 'Reviewed suggested replacement relationships'), ('changed_action_holders', 'Changed action holders for document'), ('changed_group', 'Changed group'), ('changed_protocol_writeup', 'Changed protocol writeup'), ('changed_charter_milestone', 'Changed charter milestone'), ('initial_review', 'Set initial review time'), ('changed_review_announcement', 'Changed WG Review text'), ('changed_action_announcement', 'Changed WG Action text'), ('started_iesg_process', 'Started IESG process on document'), ('created_ballot', 'Created ballot'), ('closed_ballot', 'Closed ballot'), ('sent_ballot_announcement', 'Sent ballot announcement'), ('changed_ballot_position', 'Changed ballot position'), ('changed_ballot_approval_text', 'Changed ballot approval text'), ('changed_ballot_writeup_text', 'Changed ballot writeup text'), ('changed_rfc_editor_note_text', 'Changed RFC Editor Note text'), ('changed_last_call_text', 'Changed last call text'), ('requested_last_call', 'Requested last call'), ('sent_last_call', 'Sent last call'), ('scheduled_for_telechat', 'Scheduled for telechat'), ('iesg_approved', 'IESG approved document (no problem)'), ('iesg_disapproved', 'IESG disapproved document (do not publish)'), ('approved_in_minute', 'Approved in minute'), ('iana_review', 'IANA review comment'), ('rfc_in_iana_registry', 'RFC is in IANA registry'), ('rfc_editor_received_announcement', 'Announcement was received by RFC Editor'), ('requested_publication', 'Publication at RFC Editor requested'), ('sync_from_rfc_editor', 'Received updated information from RFC Editor'), ('requested_review', 'Requested review'), ('assigned_review_request', 'Assigned review request'), ('closed_review_request', 'Closed review request'), ('closed_review_assignment', 'Closed review assignment'), ('downref_approved', 'Downref approved'), ('posted_related_ipr', 'Posted related IPR'), ('removed_related_ipr', 'Removed related IPR'), ('changed_editors', 'Changed BOF Request editors')], max_length=50)), ('rev', models.CharField(blank=True, max_length=16, null=True, verbose_name='revision')), ('desc', models.TextField()), ], @@ -65,11 +63,22 @@ class Migration(migrations.Migration): 'ordering': ['-time', '-id'], }, ), + migrations.CreateModel( + name='DocExtResource', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('display_name', models.CharField(blank=True, default='', max_length=255)), + ('value', models.CharField(max_length=2083)), + ], + options={ + 'abstract': False, + }, + ), migrations.CreateModel( name='DocHistory', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('time', models.DateTimeField(default=datetime.datetime.now)), + ('time', models.DateTimeField(default=django.utils.timezone.now)), ('title', models.CharField(max_length=255, validators=[django.core.validators.RegexValidator(message='Please enter a string without control characters.', regex='^[^\x00-\x1f]*$')])), ('abstract', models.TextField(blank=True)), ('rev', models.CharField(blank=True, max_length=16, verbose_name='revision')), @@ -77,8 +86,9 @@ class Migration(migrations.Migration): ('words', models.IntegerField(blank=True, null=True)), ('order', models.IntegerField(blank=True, default=1)), ('expires', models.DateTimeField(blank=True, null=True)), - ('notify', models.CharField(blank=True, max_length=255)), + ('notify', models.TextField(blank=True, max_length=1023)), ('external_url', models.URLField(blank=True)), + ('uploaded_filename', models.TextField(blank=True)), ('note', models.TextField(blank=True)), ('internal_comments', models.TextField(blank=True)), ('name', models.CharField(max_length=255)), @@ -112,7 +122,8 @@ class Migration(migrations.Migration): migrations.CreateModel( name='Document', fields=[ - ('time', models.DateTimeField(default=datetime.datetime.now)), + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('time', models.DateTimeField(default=django.utils.timezone.now)), ('title', models.CharField(max_length=255, validators=[django.core.validators.RegexValidator(message='Please enter a string without control characters.', regex='^[^\x00-\x1f]*$')])), ('abstract', models.TextField(blank=True)), ('rev', models.CharField(blank=True, max_length=16, verbose_name='revision')), @@ -120,77 +131,17 @@ class Migration(migrations.Migration): ('words', models.IntegerField(blank=True, null=True)), ('order', models.IntegerField(blank=True, default=1)), ('expires', models.DateTimeField(blank=True, null=True)), - ('notify', models.CharField(blank=True, max_length=255)), + ('notify', models.TextField(blank=True, max_length=1023)), ('external_url', models.URLField(blank=True)), + ('uploaded_filename', models.TextField(blank=True)), ('note', models.TextField(blank=True)), ('internal_comments', models.TextField(blank=True)), - ('name', models.CharField(max_length=255, primary_key=True, serialize=False, validators=[django.core.validators.RegexValidator(b'^[-a-z0-9]+$', b'Provide a valid document name consisting of lowercase letters, numbers and hyphens.', b'invalid')])), - ('ad', ietf.utils.models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='ad_document_set', to='person.Person', verbose_name='area director')), - ('formal_languages', models.ManyToManyField(blank=True, help_text='Formal languages used in document', to='name.FormalLanguageName')), + ('name', models.CharField(max_length=255, unique=True, validators=[django.core.validators.RegexValidator('^[-a-z0-9]+$', 'Provide a valid document name consisting of lowercase letters, numbers and hyphens.', 'invalid')])), ], options={ 'abstract': False, }, ), - migrations.CreateModel( - name='DocumentAuthor', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('affiliation', models.CharField(blank=True, help_text='Organization/company used by author for submission', max_length=100)), - ('country', models.CharField(blank=True, help_text='Country used by author for submission', max_length=255)), - ('order', models.IntegerField(default=1)), - ('document', ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='doc.Document')), - ('email', ietf.utils.models.ForeignKey(blank=True, help_text='Email address used by author for submission', null=True, on_delete=django.db.models.deletion.CASCADE, to='person.Email')), - ('person', ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='person.Person')), - ], - options={ - 'ordering': ['document', 'order'], - 'abstract': False, - }, - ), - migrations.CreateModel( - name='DocumentURL', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('desc', models.CharField(blank=True, default='', max_length=255)), - ('url', models.URLField(max_length=512)), - ('doc', ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='doc.Document')), - ('tag', ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='name.DocUrlTagName')), - ], - ), - migrations.CreateModel( - name='RelatedDocHistory', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('relationship', ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='name.DocRelationshipName')), - ('source', ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='doc.DocHistory')), - ('target', ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='reversely_related_document_history_set', to='doc.DocAlias')), - ], - ), - migrations.CreateModel( - name='RelatedDocument', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('relationship', ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='name.DocRelationshipName')), - ('source', ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='doc.Document')), - ('target', ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='doc.DocAlias')), - ], - ), - migrations.CreateModel( - name='State', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('slug', models.SlugField()), - ('name', models.CharField(max_length=255)), - ('used', models.BooleanField(default=True)), - ('desc', models.TextField(blank=True)), - ('order', models.IntegerField(default=0)), - ('next_states', models.ManyToManyField(blank=True, related_name='previous_states', to='doc.State')), - ], - options={ - 'ordering': ['type', 'order'], - }, - ), migrations.CreateModel( name='StateType', fields=[ @@ -221,6 +172,21 @@ class Migration(migrations.Migration): ('discuss_time', models.DateTimeField(blank=True, help_text='Time discuss text was written', null=True)), ('comment', models.TextField(blank=True, help_text='Optional comment')), ('comment_time', models.DateTimeField(blank=True, help_text='Time optional comment was written', null=True)), + ('send_email', models.BooleanField(default=None, null=True)), + ], + bases=('doc.docevent',), + ), + migrations.CreateModel( + name='BofreqEditorDocEvent', + fields=[ + ('docevent_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='doc.DocEvent')), + ], + bases=('doc.docevent',), + ), + migrations.CreateModel( + name='BofreqResponsibleDocEvent', + fields=[ + ('docevent_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='doc.DocEvent')), ], bases=('doc.docevent',), ), @@ -228,7 +194,7 @@ class Migration(migrations.Migration): name='ConsensusDocEvent', fields=[ ('docevent_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='doc.DocEvent')), - ('consensus', models.NullBooleanField(default=None)), + ('consensus', models.BooleanField(default=None, null=True)), ], bases=('doc.docevent',), ), @@ -240,6 +206,13 @@ class Migration(migrations.Migration): ], bases=('doc.docevent',), ), + migrations.CreateModel( + name='IanaExpertDocEvent', + fields=[ + ('docevent_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='doc.DocEvent')), + ], + bases=('doc.docevent',), + ), migrations.CreateModel( name='InitialReviewDocEvent', fields=[ @@ -263,6 +236,13 @@ class Migration(migrations.Migration): ], bases=('doc.docevent',), ), + migrations.CreateModel( + name='ReviewAssignmentDocEvent', + fields=[ + ('docevent_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='doc.DocEvent')), + ], + bases=('doc.docevent',), + ), migrations.CreateModel( name='ReviewRequestDocEvent', fields=[ @@ -301,9 +281,88 @@ class Migration(migrations.Migration): ], bases=('doc.docevent',), ), + migrations.CreateModel( + name='State', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('slug', models.SlugField()), + ('name', models.CharField(max_length=255)), + ('used', models.BooleanField(default=True)), + ('desc', models.TextField(blank=True)), + ('order', models.IntegerField(default=0)), + ('next_states', models.ManyToManyField(blank=True, related_name='previous_states', to='doc.State')), + ('type', ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='doc.StateType')), + ], + options={ + 'ordering': ['type', 'order'], + }, + ), + migrations.CreateModel( + name='RelatedDocument', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('relationship', ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='name.DocRelationshipName')), + ('source', ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='doc.Document')), + ('target', ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='doc.DocAlias')), + ], + ), + migrations.CreateModel( + name='RelatedDocHistory', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('relationship', ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='name.DocRelationshipName')), + ('source', ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='doc.DocHistory')), + ('target', ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='reversely_related_document_history_set', to='doc.DocAlias')), + ], + ), + migrations.CreateModel( + name='DocumentURL', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('desc', models.CharField(blank=True, default='', max_length=255)), + ('url', models.URLField(max_length=2083)), + ('doc', ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='doc.Document')), + ('tag', ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='name.DocUrlTagName')), + ], + ), + migrations.CreateModel( + name='DocumentAuthor', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('affiliation', models.CharField(blank=True, help_text='Organization/company used by author for submission', max_length=100)), + ('country', models.CharField(blank=True, help_text='Country used by author for submission', max_length=255)), + ('order', models.IntegerField(default=1)), + ('document', ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='doc.Document')), + ('email', ietf.utils.models.ForeignKey(blank=True, help_text='Email address used by author for submission', null=True, on_delete=django.db.models.deletion.CASCADE, to='person.Email')), + ('person', ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='person.Person')), + ], + options={ + 'ordering': ['document', 'order'], + 'abstract': False, + }, + ), + migrations.CreateModel( + name='DocumentActionHolder', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('time_added', models.DateTimeField(default=django.utils.timezone.now)), + ('document', ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='doc.Document')), + ('person', ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='person.Person')), + ], + ), + migrations.AddField( + model_name='document', + name='action_holders', + field=models.ManyToManyField(blank=True, through='doc.DocumentActionHolder', to='person.Person'), + ), + migrations.AddField( + model_name='document', + name='ad', + field=ietf.utils.models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='ad_document_set', to='person.Person', verbose_name='area director'), + ), migrations.AddField( - model_name='state', - name='type', - field=ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='doc.StateType'), + model_name='document', + name='formal_languages', + field=models.ManyToManyField(blank=True, help_text='Formal languages used in document', to='name.FormalLanguageName'), ), ] diff --git a/ietf/doc/migrations/0002_auto_20180220_1052.py b/ietf/doc/migrations/0002_auto_20180220_1052.py deleted file mode 100644 index 811e9eb8113..00000000000 --- a/ietf/doc/migrations/0002_auto_20180220_1052.py +++ /dev/null @@ -1,237 +0,0 @@ -# Copyright The IETF Trust 2018-2020, All Rights Reserved -# -*- coding: utf-8 -*- -# Generated by Django 1.11.10 on 2018-02-20 10:52 - - -from django.db import migrations, models -import django.db.models.deletion -import ietf.utils.models - - -class Migration(migrations.Migration): - - initial = True - - dependencies = [ - ('review', '0001_initial'), - ('contenttypes', '0002_remove_content_type_name'), - ('name', '0001_initial'), - ('submit', '0001_initial'), - ('person', '0001_initial'), - ('message', '0001_initial'), - ('doc', '0001_initial'), - ('group', '0001_initial'), - ] - - operations = [ - migrations.AddField( - model_name='document', - name='group', - field=ietf.utils.models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='group.Group'), - ), - migrations.AddField( - model_name='document', - name='intended_std_level', - field=ietf.utils.models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='name.IntendedStdLevelName', verbose_name='Intended standardization level'), - ), - migrations.AddField( - model_name='document', - name='shepherd', - field=ietf.utils.models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='shepherd_document_set', to='person.Email'), - ), - migrations.AddField( - model_name='document', - name='states', - field=models.ManyToManyField(blank=True, to='doc.State'), - ), - migrations.AddField( - model_name='document', - name='std_level', - field=ietf.utils.models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='name.StdLevelName', verbose_name='Standardization level'), - ), - migrations.AddField( - model_name='document', - name='stream', - field=ietf.utils.models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='name.StreamName'), - ), - migrations.AddField( - model_name='document', - name='tags', - field=models.ManyToManyField(blank=True, to='name.DocTagName'), - ), - migrations.AddField( - model_name='document', - name='type', - field=ietf.utils.models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='name.DocTypeName'), - ), - migrations.AddField( - model_name='docreminder', - name='event', - field=ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='doc.DocEvent'), - ), - migrations.AddField( - model_name='docreminder', - name='type', - field=ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='name.DocReminderTypeName'), - ), - migrations.AddField( - model_name='dochistoryauthor', - name='document', - field=ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='documentauthor_set', to='doc.DocHistory'), - ), - migrations.AddField( - model_name='dochistoryauthor', - name='email', - field=ietf.utils.models.ForeignKey(blank=True, help_text='Email address used by author for submission', null=True, on_delete=django.db.models.deletion.CASCADE, to='person.Email'), - ), - migrations.AddField( - model_name='dochistoryauthor', - name='person', - field=ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='person.Person'), - ), - migrations.AddField( - model_name='dochistory', - name='ad', - field=ietf.utils.models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='ad_dochistory_set', to='person.Person', verbose_name='area director'), - ), - migrations.AddField( - model_name='dochistory', - name='doc', - field=ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='history_set', to='doc.Document'), - ), - migrations.AddField( - model_name='dochistory', - name='formal_languages', - field=models.ManyToManyField(blank=True, help_text='Formal languages used in document', to='name.FormalLanguageName'), - ), - migrations.AddField( - model_name='dochistory', - name='group', - field=ietf.utils.models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='group.Group'), - ), - migrations.AddField( - model_name='dochistory', - name='intended_std_level', - field=ietf.utils.models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='name.IntendedStdLevelName', verbose_name='Intended standardization level'), - ), - migrations.AddField( - model_name='dochistory', - name='shepherd', - field=ietf.utils.models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='shepherd_dochistory_set', to='person.Email'), - ), - migrations.AddField( - model_name='dochistory', - name='states', - field=models.ManyToManyField(blank=True, to='doc.State'), - ), - migrations.AddField( - model_name='dochistory', - name='std_level', - field=ietf.utils.models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='name.StdLevelName', verbose_name='Standardization level'), - ), - migrations.AddField( - model_name='dochistory', - name='stream', - field=ietf.utils.models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='name.StreamName'), - ), - migrations.AddField( - model_name='dochistory', - name='tags', - field=models.ManyToManyField(blank=True, to='name.DocTagName'), - ), - migrations.AddField( - model_name='dochistory', - name='type', - field=ietf.utils.models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='name.DocTypeName'), - ), - migrations.AddField( - model_name='docevent', - name='by', - field=ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='person.Person'), - ), - migrations.AddField( - model_name='docevent', - name='doc', - field=ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='doc.Document'), - ), - migrations.AddField( - model_name='docalias', - name='document', - field=ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='doc.Document'), - ), - migrations.AddField( - model_name='deletedevent', - name='by', - field=ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='person.Person'), - ), - migrations.AddField( - model_name='deletedevent', - name='content_type', - field=ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='contenttypes.ContentType'), - ), - migrations.AddField( - model_name='ballottype', - name='doc_type', - field=ietf.utils.models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='name.DocTypeName'), - ), - migrations.AddField( - model_name='ballottype', - name='positions', - field=models.ManyToManyField(blank=True, to='name.BallotPositionName'), - ), - migrations.AddField( - model_name='submissiondocevent', - name='submission', - field=ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='submit.Submission'), - ), - migrations.AddField( - model_name='statedocevent', - name='state', - field=ietf.utils.models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='doc.State'), - ), - migrations.AddField( - model_name='statedocevent', - name='state_type', - field=ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='doc.StateType'), - ), - migrations.AddField( - model_name='reviewrequestdocevent', - name='review_request', - field=ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='review.ReviewRequest'), - ), - migrations.AddField( - model_name='reviewrequestdocevent', - name='state', - field=ietf.utils.models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='name.ReviewRequestStateName'), - ), - migrations.AddField( - model_name='ballotpositiondocevent', - name='ad', - field=ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='person.Person'), - ), - migrations.AddField( - model_name='ballotpositiondocevent', - name='ballot', - field=ietf.utils.models.ForeignKey(default=None, null=True, on_delete=django.db.models.deletion.CASCADE, to='doc.BallotDocEvent'), - ), - migrations.AddField( - model_name='ballotpositiondocevent', - name='pos', - field=ietf.utils.models.ForeignKey(default='norecord', on_delete=django.db.models.deletion.CASCADE, to='name.BallotPositionName', verbose_name='position'), - ), - migrations.AddField( - model_name='ballotdocevent', - name='ballot_type', - field=ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='doc.BallotType'), - ), - migrations.AddField( - model_name='addedmessageevent', - name='in_reply_to', - field=ietf.utils.models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='doc_irtomanual', to='message.Message'), - ), - migrations.AddField( - model_name='addedmessageevent', - name='message', - field=ietf.utils.models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='doc_manualevents', to='message.Message'), - ), - ] diff --git a/ietf/doc/migrations/0002_auto_20230320_1222.py b/ietf/doc/migrations/0002_auto_20230320_1222.py new file mode 100644 index 00000000000..90b2d11a25d --- /dev/null +++ b/ietf/doc/migrations/0002_auto_20230320_1222.py @@ -0,0 +1,292 @@ +# Generated by Django 2.2.28 on 2023-03-20 19:22 + +from django.db import migrations, models +import django.db.models.deletion +import ietf.utils.models + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ('message', '0001_initial'), + ('name', '0001_initial'), + ('person', '0001_initial'), + ('review', '0001_initial'), + ('group', '0001_initial'), + ('contenttypes', '0002_remove_content_type_name'), + ('submit', '0001_initial'), + ('doc', '0001_initial'), + ] + + operations = [ + migrations.AddField( + model_name='document', + name='group', + field=ietf.utils.models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='group.Group'), + ), + migrations.AddField( + model_name='document', + name='intended_std_level', + field=ietf.utils.models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='name.IntendedStdLevelName', verbose_name='Intended standardization level'), + ), + migrations.AddField( + model_name='document', + name='shepherd', + field=ietf.utils.models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='shepherd_document_set', to='person.Email'), + ), + migrations.AddField( + model_name='document', + name='states', + field=models.ManyToManyField(blank=True, to='doc.State'), + ), + migrations.AddField( + model_name='document', + name='std_level', + field=ietf.utils.models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='name.StdLevelName', verbose_name='Standardization level'), + ), + migrations.AddField( + model_name='document', + name='stream', + field=ietf.utils.models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='name.StreamName'), + ), + migrations.AddField( + model_name='document', + name='tags', + field=models.ManyToManyField(blank=True, to='name.DocTagName'), + ), + migrations.AddField( + model_name='document', + name='type', + field=ietf.utils.models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='name.DocTypeName'), + ), + migrations.AddField( + model_name='docreminder', + name='event', + field=ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='doc.DocEvent'), + ), + migrations.AddField( + model_name='docreminder', + name='type', + field=ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='name.DocReminderTypeName'), + ), + migrations.AddField( + model_name='dochistoryauthor', + name='document', + field=ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='documentauthor_set', to='doc.DocHistory'), + ), + migrations.AddField( + model_name='dochistoryauthor', + name='email', + field=ietf.utils.models.ForeignKey(blank=True, help_text='Email address used by author for submission', null=True, on_delete=django.db.models.deletion.CASCADE, to='person.Email'), + ), + migrations.AddField( + model_name='dochistoryauthor', + name='person', + field=ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='person.Person'), + ), + migrations.AddField( + model_name='dochistory', + name='ad', + field=ietf.utils.models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='ad_dochistory_set', to='person.Person', verbose_name='area director'), + ), + migrations.AddField( + model_name='dochistory', + name='doc', + field=ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='history_set', to='doc.Document'), + ), + migrations.AddField( + model_name='dochistory', + name='formal_languages', + field=models.ManyToManyField(blank=True, help_text='Formal languages used in document', to='name.FormalLanguageName'), + ), + migrations.AddField( + model_name='dochistory', + name='group', + field=ietf.utils.models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='group.Group'), + ), + migrations.AddField( + model_name='dochistory', + name='intended_std_level', + field=ietf.utils.models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='name.IntendedStdLevelName', verbose_name='Intended standardization level'), + ), + migrations.AddField( + model_name='dochistory', + name='shepherd', + field=ietf.utils.models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='shepherd_dochistory_set', to='person.Email'), + ), + migrations.AddField( + model_name='dochistory', + name='states', + field=models.ManyToManyField(blank=True, to='doc.State'), + ), + migrations.AddField( + model_name='dochistory', + name='std_level', + field=ietf.utils.models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='name.StdLevelName', verbose_name='Standardization level'), + ), + migrations.AddField( + model_name='dochistory', + name='stream', + field=ietf.utils.models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='name.StreamName'), + ), + migrations.AddField( + model_name='dochistory', + name='tags', + field=models.ManyToManyField(blank=True, to='name.DocTagName'), + ), + migrations.AddField( + model_name='dochistory', + name='type', + field=ietf.utils.models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='name.DocTypeName'), + ), + migrations.AddField( + model_name='docextresource', + name='doc', + field=ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='doc.Document'), + ), + migrations.AddField( + model_name='docextresource', + name='name', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='name.ExtResourceName'), + ), + migrations.AddField( + model_name='docevent', + name='by', + field=ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='person.Person'), + ), + migrations.AddField( + model_name='docevent', + name='doc', + field=ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='doc.Document'), + ), + migrations.AddField( + model_name='docalias', + name='docs', + field=models.ManyToManyField(related_name='docalias', to='doc.Document'), + ), + migrations.AddField( + model_name='deletedevent', + name='by', + field=ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='person.Person'), + ), + migrations.AddField( + model_name='deletedevent', + name='content_type', + field=ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='contenttypes.ContentType'), + ), + migrations.AddField( + model_name='ballottype', + name='doc_type', + field=ietf.utils.models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='name.DocTypeName'), + ), + migrations.AddField( + model_name='ballottype', + name='positions', + field=models.ManyToManyField(blank=True, to='name.BallotPositionName'), + ), + migrations.CreateModel( + name='IRSGBallotDocEvent', + fields=[ + ('ballotdocevent_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='doc.BallotDocEvent')), + ('duedate', models.DateTimeField(blank=True, null=True)), + ], + bases=('doc.ballotdocevent',), + ), + migrations.AddField( + model_name='submissiondocevent', + name='submission', + field=ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='submit.Submission'), + ), + migrations.AddField( + model_name='statedocevent', + name='state', + field=ietf.utils.models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='doc.State'), + ), + migrations.AddField( + model_name='statedocevent', + name='state_type', + field=ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='doc.StateType'), + ), + migrations.AddField( + model_name='reviewrequestdocevent', + name='review_request', + field=ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='review.ReviewRequest'), + ), + migrations.AddField( + model_name='reviewrequestdocevent', + name='state', + field=ietf.utils.models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='name.ReviewRequestStateName'), + ), + migrations.AddField( + model_name='reviewassignmentdocevent', + name='review_assignment', + field=ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='review.ReviewAssignment'), + ), + migrations.AddField( + model_name='reviewassignmentdocevent', + name='state', + field=ietf.utils.models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='name.ReviewAssignmentStateName'), + ), + migrations.AddIndex( + model_name='documentauthor', + index=models.Index(fields=['document', 'order'], name='doc_documen_documen_7fabe2_idx'), + ), + migrations.AddConstraint( + model_name='documentactionholder', + constraint=models.UniqueConstraint(fields=('document', 'person'), name='unique_action_holder'), + ), + migrations.AddIndex( + model_name='dochistoryauthor', + index=models.Index(fields=['document', 'order'], name='doc_dochist_documen_7e2441_idx'), + ), + migrations.AddIndex( + model_name='docevent', + index=models.Index(fields=['type', 'doc'], name='doc_doceven_type_43e53e_idx'), + ), + migrations.AddIndex( + model_name='docevent', + index=models.Index(fields=['-time', '-id'], name='doc_doceven_time_1a258f_idx'), + ), + migrations.AddField( + model_name='bofreqresponsibledocevent', + name='responsible', + field=models.ManyToManyField(blank=True, to='person.Person'), + ), + migrations.AddField( + model_name='bofreqeditordocevent', + name='editors', + field=models.ManyToManyField(blank=True, to='person.Person'), + ), + migrations.AddField( + model_name='ballotpositiondocevent', + name='ballot', + field=ietf.utils.models.ForeignKey(default=None, null=True, on_delete=django.db.models.deletion.CASCADE, to='doc.BallotDocEvent'), + ), + migrations.AddField( + model_name='ballotpositiondocevent', + name='balloter', + field=ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='person.Person'), + ), + migrations.AddField( + model_name='ballotpositiondocevent', + name='pos', + field=ietf.utils.models.ForeignKey(default='norecord', on_delete=django.db.models.deletion.CASCADE, to='name.BallotPositionName', verbose_name='position'), + ), + migrations.AddField( + model_name='ballotdocevent', + name='ballot_type', + field=ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='doc.BallotType'), + ), + migrations.AddField( + model_name='addedmessageevent', + name='in_reply_to', + field=ietf.utils.models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='doc_irtomanual', to='message.Message'), + ), + migrations.AddField( + model_name='addedmessageevent', + name='message', + field=ietf.utils.models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='doc_manualevents', to='message.Message'), + ), + ] diff --git a/ietf/doc/migrations/0003_auto_20180401_1231.py b/ietf/doc/migrations/0003_auto_20180401_1231.py deleted file mode 100644 index 7760b251128..00000000000 --- a/ietf/doc/migrations/0003_auto_20180401_1231.py +++ /dev/null @@ -1,20 +0,0 @@ -# Copyright The IETF Trust 2018-2020, All Rights Reserved -# -*- coding: utf-8 -*- -# Generated by Django 1.11.11 on 2018-04-01 12:31 - - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('doc', '0002_auto_20180220_1052'), - ] - - operations = [ - migrations.AddIndex( - model_name='docevent', - index=models.Index(fields=['type', 'doc'], name='doc_doceven_type_43e53e_idx'), - ), - ] diff --git a/ietf/doc/migrations/0003_remove_document_info_order.py b/ietf/doc/migrations/0003_remove_document_info_order.py new file mode 100644 index 00000000000..dcd324b71fd --- /dev/null +++ b/ietf/doc/migrations/0003_remove_document_info_order.py @@ -0,0 +1,20 @@ +# Copyright The IETF Trust 2023, All Rights Reserved +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('doc', '0002_auto_20230320_1222'), + ] + + operations = [ + migrations.RemoveField( + model_name='dochistory', + name='order', + ), + migrations.RemoveField( + model_name='document', + name='order', + ), + ] diff --git a/ietf/doc/migrations/0004_add_draft_stream_replaced_states.py b/ietf/doc/migrations/0004_add_draft_stream_replaced_states.py deleted file mode 100644 index 9d57cb476f8..00000000000 --- a/ietf/doc/migrations/0004_add_draft_stream_replaced_states.py +++ /dev/null @@ -1,30 +0,0 @@ -# Copyright The IETF Trust 2018-2020, All Rights Reserved -# -*- coding: utf-8 -*- -# Generated by Django 1.11.13 on 2018-05-03 11:50 - - -from django.db import migrations - -def forward(apps, schema_editor): - State = apps.get_model('doc','State') - for type_id in ('draft-stream-iab','draft-stream-ise','draft-stream-irtf'): - State.objects.create(type_id=type_id, - slug='repl', - name='Replaced', - desc='Replaced', - ) - - -def reverse(apps, schema_editor): - State = apps.get_model('doc','State') - State.objects.filter(type_id__in=('draft-stream-iab','draft-stream-ise','draft-stream-irtf'), slug='repl').delete() - -class Migration(migrations.Migration): - - dependencies = [ - ('doc', '0003_auto_20180401_1231'), - ] - - operations = [ - migrations.RunPython(forward,reverse) - ] diff --git a/ietf/doc/migrations/0004_alter_dochistory_ad_alter_dochistory_shepherd_and_more.py b/ietf/doc/migrations/0004_alter_dochistory_ad_alter_dochistory_shepherd_and_more.py new file mode 100644 index 00000000000..adc0e696272 --- /dev/null +++ b/ietf/doc/migrations/0004_alter_dochistory_ad_alter_dochistory_shepherd_and_more.py @@ -0,0 +1,36 @@ +# Generated by Django 4.0.10 on 2023-05-16 20:36 + +from django.db import migrations +import django.db.models.deletion +import ietf.utils.models + + +class Migration(migrations.Migration): + + dependencies = [ + ('person', '0001_initial'), + ('doc', '0003_remove_document_info_order'), + ] + + operations = [ + migrations.AlterField( + model_name='dochistory', + name='ad', + field=ietf.utils.models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='ad_%(class)s_set', to='person.person', verbose_name='area director'), + ), + migrations.AlterField( + model_name='dochistory', + name='shepherd', + field=ietf.utils.models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='shepherd_%(class)s_set', to='person.email'), + ), + migrations.AlterField( + model_name='document', + name='ad', + field=ietf.utils.models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='ad_%(class)s_set', to='person.person', verbose_name='area director'), + ), + migrations.AlterField( + model_name='document', + name='shepherd', + field=ietf.utils.models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='shepherd_%(class)s_set', to='person.email'), + ), + ] diff --git a/ietf/doc/migrations/0005_alter_docevent_type.py b/ietf/doc/migrations/0005_alter_docevent_type.py new file mode 100644 index 00000000000..f8a3cfc7959 --- /dev/null +++ b/ietf/doc/migrations/0005_alter_docevent_type.py @@ -0,0 +1,86 @@ +# Copyright The IETF Trust 2023, All Rights Reserved + +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("doc", "0004_alter_dochistory_ad_alter_dochistory_shepherd_and_more"), + ] + + operations = [ + migrations.AlterField( + model_name="docevent", + name="type", + field=models.CharField( + choices=[ + ("new_revision", "Added new revision"), + ("new_submission", "Uploaded new revision"), + ("changed_document", "Changed document metadata"), + ("added_comment", "Added comment"), + ("added_message", "Added message"), + ("edited_authors", "Edited the documents author list"), + ("deleted", "Deleted document"), + ("changed_state", "Changed state"), + ("changed_stream", "Changed document stream"), + ("expired_document", "Expired document"), + ("extended_expiry", "Extended expiry of document"), + ("requested_resurrect", "Requested resurrect"), + ("completed_resurrect", "Completed resurrect"), + ("changed_consensus", "Changed consensus"), + ("published_rfc", "Published RFC"), + ( + "added_suggested_replaces", + "Added suggested replacement relationships", + ), + ( + "reviewed_suggested_replaces", + "Reviewed suggested replacement relationships", + ), + ("changed_action_holders", "Changed action holders for document"), + ("changed_group", "Changed group"), + ("changed_protocol_writeup", "Changed protocol writeup"), + ("changed_charter_milestone", "Changed charter milestone"), + ("initial_review", "Set initial review time"), + ("changed_review_announcement", "Changed WG Review text"), + ("changed_action_announcement", "Changed WG Action text"), + ("started_iesg_process", "Started IESG process on document"), + ("created_ballot", "Created ballot"), + ("closed_ballot", "Closed ballot"), + ("sent_ballot_announcement", "Sent ballot announcement"), + ("changed_ballot_position", "Changed ballot position"), + ("changed_ballot_approval_text", "Changed ballot approval text"), + ("changed_ballot_writeup_text", "Changed ballot writeup text"), + ("changed_rfc_editor_note_text", "Changed RFC Editor Note text"), + ("changed_last_call_text", "Changed last call text"), + ("requested_last_call", "Requested last call"), + ("sent_last_call", "Sent last call"), + ("scheduled_for_telechat", "Scheduled for telechat"), + ("iesg_approved", "IESG approved document (no problem)"), + ("iesg_disapproved", "IESG disapproved document (do not publish)"), + ("approved_in_minute", "Approved in minute"), + ("iana_review", "IANA review comment"), + ("rfc_in_iana_registry", "RFC is in IANA registry"), + ( + "rfc_editor_received_announcement", + "Announcement was received by RFC Editor", + ), + ("requested_publication", "Publication at RFC Editor requested"), + ( + "sync_from_rfc_editor", + "Received updated information from RFC Editor", + ), + ("requested_review", "Requested review"), + ("assigned_review_request", "Assigned review request"), + ("closed_review_request", "Closed review request"), + ("closed_review_assignment", "Closed review assignment"), + ("downref_approved", "Downref approved"), + ("posted_related_ipr", "Posted related IPR"), + ("removed_related_ipr", "Removed related IPR"), + ("changed_editors", "Changed BOF Request editors"), + ("published_statement", "Published statement"), + ], + max_length=50, + ), + ), + ] diff --git a/ietf/doc/migrations/0005_fix_replaced_iab_irtf_stream_docs.py b/ietf/doc/migrations/0005_fix_replaced_iab_irtf_stream_docs.py deleted file mode 100644 index 3529baf9804..00000000000 --- a/ietf/doc/migrations/0005_fix_replaced_iab_irtf_stream_docs.py +++ /dev/null @@ -1,112 +0,0 @@ -# Copyright The IETF Trust 2018-2020, All Rights Reserved -# -*- coding: utf-8 -*- -# Generated by Django 1.11.13 on 2018-05-03 12:16 - - -from django.db import migrations - -def forward(apps, schema_editor): - Document = apps.get_model('doc','Document') - State = apps.get_model('doc','State') - - iab_active = State.objects.get(type_id='draft-stream-iab',slug='active') - iab_replaced = State.objects.get(type_id='draft-stream-iab',slug='repl') - - irtf_active = State.objects.get(type_id='draft-stream-irtf',slug='active') - irtf_candidate = State.objects.get(type_id='draft-stream-irtf',slug='candidat') - irtf_replaced = State.objects.get(type_id='draft-stream-irtf',slug='repl') - irtf_dead = State.objects.get(type_id='draft-stream-irtf',slug='dead') - - doc = Document.objects.get(name='draft-flanagan-rfc-preservation') - doc.states.remove(iab_active) - doc.states.add(iab_replaced) - - doc = Document.objects.get(name='draft-trammell-semi-report') - doc.states.remove(iab_active) - doc.states.add(iab_replaced) - - doc = Document.objects.get(name='draft-nir-cfrg-chacha20-poly1305') - doc.states.remove(irtf_candidate) - doc.states.add(irtf_replaced) - - doc = Document.objects.get(name='draft-ladd-spake2') - doc.states.remove(irtf_candidate) - doc.states.add(irtf_replaced) - - doc = Document.objects.get(name='draft-lee-nfvrg-resource-management-service-chain') - doc.states.remove(irtf_candidate) - doc.states.add(irtf_replaced) - - doc = Document.objects.get(name='draft-keranen-t2trg-rest-iot') - doc.states.remove(irtf_candidate) - doc.states.add(irtf_replaced) - - doc = Document.objects.get(name='draft-josefsson-argon2') - doc.states.remove(irtf_active) - doc.states.add(irtf_replaced) - - doc = Document.objects.get(name='draft-tenoever-hrpc-research') - doc.states.remove(irtf_active) - doc.states.add(irtf_replaced) - - doc = Document.objects.get(name='draft-kutscher-icnrg-challenges') - doc.states.remove(irtf_dead) - doc.states.add(irtf_replaced) - -def reverse(apps, schema_editor): - Document = apps.get_model('doc','Document') - State = apps.get_model('doc','State') - - iab_active = State.objects.get(type_id='draft-stream-iab',slug='active') - iab_replaced = State.objects.get(type_id='draft-stream-iab',slug='repl') - - irtf_active = State.objects.get(type_id='draft-stream-irtf',slug='active') - irtf_candidate = State.objects.get(type_id='draft-stream-irtf',slug='candidat') - irtf_replaced = State.objects.get(type_id='draft-stream-irtf',slug='repl') - irtf_dead = State.objects.get(type_id='draft-stream-irtf',slug='dead') - - doc = Document.objects.get(name='draft-flanagan-rfc-preservation') - doc.states.add(iab_active) - doc.states.remove(iab_replaced) - - doc = Document.objects.get(name='draft-trammell-semi-report') - doc.states.add(iab_active) - doc.states.remove(iab_replaced) - - doc = Document.objects.get(name='draft-nir-cfrg-chacha20-poly1305') - doc.states.add(irtf_candidate) - doc.states.remove(irtf_replaced) - - doc = Document.objects.get(name='draft-ladd-spake2') - doc.states.add(irtf_candidate) - doc.states.remove(irtf_replaced) - - doc = Document.objects.get(name='draft-lee-nfvrg-resource-management-service-chain') - doc.states.add(irtf_candidate) - doc.states.remove(irtf_replaced) - - doc = Document.objects.get(name='draft-keranen-t2trg-rest-iot') - doc.states.add(irtf_candidate) - doc.states.remove(irtf_replaced) - - doc = Document.objects.get(name='draft-josefsson-argon2') - doc.states.add(irtf_active) - doc.states.remove(irtf_replaced) - - doc = Document.objects.get(name='draft-tenoever-hrpc-research') - doc.states.add(irtf_active) - doc.states.remove(irtf_replaced) - - doc = Document.objects.get(name='draft-kutscher-icnrg-challenges') - doc.states.add(irtf_dead) - doc.states.remove(irtf_replaced) - -class Migration(migrations.Migration): - - dependencies = [ - ('doc', '0004_add_draft_stream_replaced_states'), - ] - - operations = [ - migrations.RunPython(forward, reverse) - ] diff --git a/ietf/doc/migrations/0006_ballotpositiondocevent_send_email.py b/ietf/doc/migrations/0006_ballotpositiondocevent_send_email.py deleted file mode 100644 index 42f58ca02cd..00000000000 --- a/ietf/doc/migrations/0006_ballotpositiondocevent_send_email.py +++ /dev/null @@ -1,21 +0,0 @@ -# Copyright The IETF Trust 2018-2020, All Rights Reserved -# -*- coding: utf-8 -*- -# Generated by Django 1.11.15 on 2018-10-03 06:39 - - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('doc', '0005_fix_replaced_iab_irtf_stream_docs'), - ] - - operations = [ - migrations.AddField( - model_name='ballotpositiondocevent', - name='send_email', - field=models.NullBooleanField(default=None), - ), - ] diff --git a/ietf/doc/migrations/0006_statements.py b/ietf/doc/migrations/0006_statements.py new file mode 100644 index 00000000000..9a074292e5c --- /dev/null +++ b/ietf/doc/migrations/0006_statements.py @@ -0,0 +1,43 @@ +# Copyright The IETF Trust 2023, All Rights Reserved + +from django.db import migrations + + +def forward(apps, schema_editor): + StateType = apps.get_model("doc", "StateType") + State = apps.get_model("doc", "State") + + StateType.objects.create(slug="statement", label="Statement State") + State.objects.create( + slug="active", + type_id="statement", + name="Active", + order=0, + desc="The statement is active", + ) + State.objects.create( + slug="replaced", + type_id="statement", + name="Replaced", + order=0, + desc="The statement has been replaced", + ) + + +def reverse(apps, schema_editor): + StateType = apps.get_model("doc", "StateType") + State = apps.get_model("doc", "State") + + State.objects.filter(type_id="statement").delete() + StateType.objects.filter(slug="statement").delete() + + +class Migration(migrations.Migration): + dependencies = [ + ("doc", "0005_alter_docevent_type"), + ("name", "0004_statements"), + ] + + operations = [ + migrations.RunPython(forward, reverse), + ] diff --git a/ietf/doc/migrations/0007_alter_docevent_type.py b/ietf/doc/migrations/0007_alter_docevent_type.py new file mode 100644 index 00000000000..c98144d70fe --- /dev/null +++ b/ietf/doc/migrations/0007_alter_docevent_type.py @@ -0,0 +1,90 @@ +# Generated by Django 4.2.4 on 2023-08-23 21:38 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("doc", "0006_statements"), + ] + + operations = [ + migrations.AlterField( + model_name="docevent", + name="type", + field=models.CharField( + choices=[ + ("new_revision", "Added new revision"), + ("new_submission", "Uploaded new revision"), + ("changed_document", "Changed document metadata"), + ("added_comment", "Added comment"), + ("added_message", "Added message"), + ("edited_authors", "Edited the documents author list"), + ("deleted", "Deleted document"), + ("changed_state", "Changed state"), + ("changed_stream", "Changed document stream"), + ("expired_document", "Expired document"), + ("extended_expiry", "Extended expiry of document"), + ("requested_resurrect", "Requested resurrect"), + ("completed_resurrect", "Completed resurrect"), + ("changed_consensus", "Changed consensus"), + ("published_rfc", "Published RFC"), + ( + "added_suggested_replaces", + "Added suggested replacement relationships", + ), + ( + "reviewed_suggested_replaces", + "Reviewed suggested replacement relationships", + ), + ("changed_action_holders", "Changed action holders for document"), + ("changed_group", "Changed group"), + ("changed_protocol_writeup", "Changed protocol writeup"), + ("changed_charter_milestone", "Changed charter milestone"), + ("initial_review", "Set initial review time"), + ("changed_review_announcement", "Changed WG Review text"), + ("changed_action_announcement", "Changed WG Action text"), + ("started_iesg_process", "Started IESG process on document"), + ("created_ballot", "Created ballot"), + ("closed_ballot", "Closed ballot"), + ("sent_ballot_announcement", "Sent ballot announcement"), + ("changed_ballot_position", "Changed ballot position"), + ("changed_ballot_approval_text", "Changed ballot approval text"), + ("changed_ballot_writeup_text", "Changed ballot writeup text"), + ("changed_rfc_editor_note_text", "Changed RFC Editor Note text"), + ("changed_last_call_text", "Changed last call text"), + ("requested_last_call", "Requested last call"), + ("sent_last_call", "Sent last call"), + ("scheduled_for_telechat", "Scheduled for telechat"), + ("iesg_approved", "IESG approved document (no problem)"), + ("iesg_disapproved", "IESG disapproved document (do not publish)"), + ("approved_in_minute", "Approved in minute"), + ("iana_review", "IANA review comment"), + ("rfc_in_iana_registry", "RFC is in IANA registry"), + ( + "rfc_editor_received_announcement", + "Announcement was received by RFC Editor", + ), + ("requested_publication", "Publication at RFC Editor requested"), + ( + "sync_from_rfc_editor", + "Received updated information from RFC Editor", + ), + ("requested_review", "Requested review"), + ("assigned_review_request", "Assigned review request"), + ("closed_review_request", "Closed review request"), + ("closed_review_assignment", "Closed review assignment"), + ("downref_approved", "Downref approved"), + ("posted_related_ipr", "Posted related IPR"), + ("removed_related_ipr", "Removed related IPR"), + ( + "removed_objfalse_related_ipr", + "Removed Objectively False related IPR", + ), + ("changed_editors", "Changed BOF Request editors"), + ("published_statement", "Published statement"), + ], + max_length=50, + ), + ), + ] diff --git a/ietf/doc/migrations/0007_idexists.py b/ietf/doc/migrations/0007_idexists.py deleted file mode 100644 index d8df81d5fdb..00000000000 --- a/ietf/doc/migrations/0007_idexists.py +++ /dev/null @@ -1,51 +0,0 @@ -# Copyright The IETF Trust 2018-2020, All Rights Reserved -# -*- coding: utf-8 -*- -# Generated by Django 1.11.16 on 2018-11-04 10:56 - - -from tqdm import tqdm - -from django.db import migrations - - -def forward(apps, schema_editor): - State = apps.get_model('doc','State') - Document = apps.get_model('doc','Document') - DocHistory = apps.get_model('doc','DocHistory') - - idexists = State.objects.create( - type_id = 'draft-iesg', - slug = 'idexists', - name = 'I-D Exists', - used = True, - desc = 'The IESG has not started processing this draft, or has stopped processing it without publicastion.', - order = 0, - ) - idexists.next_states.set(State.objects.filter(type='draft-iesg',slug__in=['pub-req','watching'])) - - #for doc in tqdm(Document.objects.filter(type='draft'): - # if not doc.states.filter(type='draft-iesg').exists(): - # doc.states.add(idexists) - # for dh in doc.history_set.all(): - # if not dh.states.filter(type='draft-iesg').exists(): - # dh.states.add(idexists) - - for doc in tqdm(Document.objects.filter(type_id='draft').exclude(states__type_id='draft-iesg')): - doc.states.add(idexists) - for history in tqdm(DocHistory.objects.filter(type_id='draft').exclude(states__type_id='draft-iesg')): - history.states.add(idexists) - - -def reverse(apps, schema_editor): - State = apps.get_model('doc','State') - State.objects.filter(slug='idexists').delete() - -class Migration(migrations.Migration): - - dependencies = [ - ('doc', '0006_ballotpositiondocevent_send_email'), - ] - - operations = [ - migrations.RunPython(forward, reverse) - ] diff --git a/ietf/doc/migrations/0008_add_uploaded_filename.py b/ietf/doc/migrations/0008_add_uploaded_filename.py deleted file mode 100644 index bf36901080b..00000000000 --- a/ietf/doc/migrations/0008_add_uploaded_filename.py +++ /dev/null @@ -1,26 +0,0 @@ -# Copyright The IETF Trust 2019-2020, All Rights Reserved -# -*- coding: utf-8 -*- -# Generated by Django 1.11.17 on 2018-12-28 13:11 - - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('doc', '0007_idexists'), - ] - - operations = [ - migrations.AddField( - model_name='dochistory', - name='uploaded_filename', - field=models.TextField(blank=True), - ), - migrations.AddField( - model_name='document', - name='uploaded_filename', - field=models.TextField(blank=True), - ), - ] diff --git a/ietf/doc/migrations/0008_alter_docevent_type.py b/ietf/doc/migrations/0008_alter_docevent_type.py new file mode 100644 index 00000000000..52a75f074b3 --- /dev/null +++ b/ietf/doc/migrations/0008_alter_docevent_type.py @@ -0,0 +1,91 @@ +# Generated by Django 4.2.7 on 2023-11-04 13:02 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("doc", "0007_alter_docevent_type"), + ] + + operations = [ + migrations.AlterField( + model_name="docevent", + name="type", + field=models.CharField( + choices=[ + ("new_revision", "Added new revision"), + ("new_submission", "Uploaded new revision"), + ("changed_document", "Changed document metadata"), + ("added_comment", "Added comment"), + ("added_message", "Added message"), + ("edited_authors", "Edited the documents author list"), + ("deleted", "Deleted document"), + ("changed_state", "Changed state"), + ("changed_stream", "Changed document stream"), + ("expired_document", "Expired document"), + ("extended_expiry", "Extended expiry of document"), + ("requested_resurrect", "Requested resurrect"), + ("completed_resurrect", "Completed resurrect"), + ("changed_consensus", "Changed consensus"), + ("published_rfc", "Published RFC"), + ( + "added_suggested_replaces", + "Added suggested replacement relationships", + ), + ( + "reviewed_suggested_replaces", + "Reviewed suggested replacement relationships", + ), + ("changed_action_holders", "Changed action holders for document"), + ("changed_group", "Changed group"), + ("changed_protocol_writeup", "Changed protocol writeup"), + ("changed_charter_milestone", "Changed charter milestone"), + ("initial_review", "Set initial review time"), + ("changed_review_announcement", "Changed WG Review text"), + ("changed_action_announcement", "Changed WG Action text"), + ("started_iesg_process", "Started IESG process on document"), + ("created_ballot", "Created ballot"), + ("closed_ballot", "Closed ballot"), + ("sent_ballot_announcement", "Sent ballot announcement"), + ("changed_ballot_position", "Changed ballot position"), + ("changed_ballot_approval_text", "Changed ballot approval text"), + ("changed_ballot_writeup_text", "Changed ballot writeup text"), + ("changed_rfc_editor_note_text", "Changed RFC Editor Note text"), + ("changed_last_call_text", "Changed last call text"), + ("requested_last_call", "Requested last call"), + ("sent_last_call", "Sent last call"), + ("scheduled_for_telechat", "Scheduled for telechat"), + ("iesg_approved", "IESG approved document (no problem)"), + ("iesg_disapproved", "IESG disapproved document (do not publish)"), + ("approved_in_minute", "Approved in minute"), + ("iana_review", "IANA review comment"), + ("rfc_in_iana_registry", "RFC is in IANA registry"), + ( + "rfc_editor_received_announcement", + "Announcement was received by RFC Editor", + ), + ("requested_publication", "Publication at RFC Editor requested"), + ( + "sync_from_rfc_editor", + "Received updated information from RFC Editor", + ), + ("requested_review", "Requested review"), + ("assigned_review_request", "Assigned review request"), + ("closed_review_request", "Closed review request"), + ("closed_review_assignment", "Closed review assignment"), + ("downref_approved", "Downref approved"), + ("posted_related_ipr", "Posted related IPR"), + ("removed_related_ipr", "Removed related IPR"), + ( + "removed_objfalse_related_ipr", + "Removed Objectively False related IPR", + ), + ("changed_editors", "Changed BOF Request editors"), + ("published_statement", "Published statement"), + ("approved_slides", "Slides approved"), + ], + max_length=50, + ), + ), + ] diff --git a/ietf/doc/migrations/0009_add_rfc_states.py b/ietf/doc/migrations/0009_add_rfc_states.py new file mode 100644 index 00000000000..07a6ac0205f --- /dev/null +++ b/ietf/doc/migrations/0009_add_rfc_states.py @@ -0,0 +1,23 @@ +# Generated by Django 4.2.2 on 2023-06-14 20:57 + +from django.db import migrations + + +def forward(apps, schema_editor): + StateType = apps.get_model("doc", "StateType") + rfc_statetype, _ = StateType.objects.get_or_create(slug="rfc", label="State") + + State = apps.get_model("doc", "State") + State.objects.get_or_create( + type=rfc_statetype, slug="published", name="Published", used=True, order=1 + ) + + +class Migration(migrations.Migration): + dependencies = [ + ("doc", "0008_alter_docevent_type"), + ] + + operations = [ + migrations.RunPython(forward), + ] diff --git a/ietf/doc/migrations/0009_move_non_url_externalurls_to_uploaded_filename.py b/ietf/doc/migrations/0009_move_non_url_externalurls_to_uploaded_filename.py deleted file mode 100644 index f97ebbdffc7..00000000000 --- a/ietf/doc/migrations/0009_move_non_url_externalurls_to_uploaded_filename.py +++ /dev/null @@ -1,49 +0,0 @@ -# Copyright The IETF Trust 2019-2020, All Rights Reserved -# -*- coding: utf-8 -*- -# Generated by Django 1.11.17 on 2018-12-28 13:33 - - -from django.db import migrations -from django.db.models import F - -def forward(apps, schema_editor): - Document = apps.get_model('doc','Document') - Document.objects.exclude(type_id__in=('review','recording')).update(uploaded_filename = F('external_url')) - Document.objects.exclude(type_id__in=('review','recording')).update(external_url="") - - Document.objects.filter(name='slides-100-edu-sessf-patents-at-ietf-an-overview-of-bcp79bis').update(uploaded_filename='slides-100-edu-sessf-patents-at-ietf-an-overview-of-bcp79bis-00.pdf') - - DocHistory = apps.get_model('doc','DocHistory') - DocHistory.objects.exclude(type_id__in=('review','recording')).update(uploaded_filename = F('external_url')) - DocHistory.objects.exclude(type_id__in=('review','recording')).update(external_url="") - - DocHistory.objects.filter(uploaded_filename='https://www.ietf.org/proceedings/97/slides/slides-97-edu-sessb-local-version-of-newcomers-training-in-korean-00.pdf').update(uploaded_filename='slides-97-edu-sessb-local-version-of-newcomers-training-in-korean-00.pdf') - DocHistory.objects.filter(uploaded_filename='http://materials-98-codec-opus-newvectors-00.tar.gz').update(uploaded_filename='materials-98-codec-opus-newvectors-00.tar.gz') - DocHistory.objects.filter(uploaded_filename='http://materials-98-codec-opus-update-00.patch').update(uploaded_filename='materials-98-codec-opus-update-00.patch') - DocHistory.objects.filter(uploaded_filename='http://slides-100-edu-sessf-patents-at-ietf-an-overview-of-bcp79bis-00.pdf').update(uploaded_filename='slides-100-edu-sessf-patents-at-ietf-an-overview-of-bcp79bis-00.pdf') - DocHistory.objects.filter(uploaded_filename='http://bluesheets-97-6man-201611150930-00.pdf/').update(uploaded_filename='bluesheets-97-6man-201611150930-00.pdf') - DocHistory.objects.filter(uploaded_filename='http://agenda-interim-2017-stir-01-stir-01-01.txt').update(uploaded_filename='agenda-interim-2017-stir-01-stir-01-01.txt') - DocHistory.objects.filter(uploaded_filename='http://agenda-interim-2017-icnrg-02-icnrg-01-05.html').update(uploaded_filename='agenda-interim-2017-icnrg-02-icnrg-01-05.html') - - -def reverse(apps, schema_editor): - Document = apps.get_model('doc','Document') - Document.objects.exclude(type_id__in=('review','recording')).update(external_url = F('uploaded_filename')) - Document.objects.exclude(type_id__in=('review','recording')).update(uploaded_filename="") - - DocHistory = apps.get_model('doc','DocHistory') - DocHistory.objects.exclude(type_id__in=('review','recording')).update(external_url = F('uploaded_filename')) - DocHistory.objects.exclude(type_id__in=('review','recording')).update(uploaded_filename="") - - -class Migration(migrations.Migration): - - dependencies = [ - ('doc', '0008_add_uploaded_filename'), - ('review', '0008_remove_reviewrequest_old_id'), - ('meeting', '0011_auto_20190114_0550'), - ] - - operations = [ - migrations.RunPython(forward,reverse), - ] diff --git a/ietf/doc/migrations/0010_auto_20190225_1302.py b/ietf/doc/migrations/0010_auto_20190225_1302.py deleted file mode 100644 index 2f8dfef4592..00000000000 --- a/ietf/doc/migrations/0010_auto_20190225_1302.py +++ /dev/null @@ -1,21 +0,0 @@ -# Copyright The IETF Trust 2019-2020, All Rights Reserved -# -*- coding: utf-8 -*- -# Generated by Django 1.11.20 on 2019-02-25 13:02 - - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('doc', '0009_move_non_url_externalurls_to_uploaded_filename'), - ] - - operations = [ - migrations.AlterField( - model_name='documenturl', - name='url', - field=models.URLField(max_length=2083), - ), - ] diff --git a/ietf/doc/migrations/0010_dochistory_rfc_number_document_rfc_number.py b/ietf/doc/migrations/0010_dochistory_rfc_number_document_rfc_number.py new file mode 100644 index 00000000000..26b2a85c622 --- /dev/null +++ b/ietf/doc/migrations/0010_dochistory_rfc_number_document_rfc_number.py @@ -0,0 +1,22 @@ +# Generated by Django 4.2.2 on 2023-06-14 22:28 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("doc", "0009_add_rfc_states"), + ] + + operations = [ + migrations.AddField( + model_name="dochistory", + name="rfc_number", + field=models.PositiveIntegerField(blank=True, null=True), + ), + migrations.AddField( + model_name="document", + name="rfc_number", + field=models.PositiveIntegerField(blank=True, null=True), + ), + ] diff --git a/ietf/doc/migrations/0011_create_rfc_documents.py b/ietf/doc/migrations/0011_create_rfc_documents.py new file mode 100644 index 00000000000..466ff81bb0f --- /dev/null +++ b/ietf/doc/migrations/0011_create_rfc_documents.py @@ -0,0 +1,76 @@ +# Generated by Django 4.2.2 on 2023-06-15 15:27 + +from django.db import migrations + + +def forward(apps, schema_editor): + Document = apps.get_model("doc", "Document") + DocAlias = apps.get_model("doc", "DocAlias") + DocumentAuthor = apps.get_model("doc", "DocumentAuthor") + + State = apps.get_model("doc", "State") + draft_rfc_state = State.objects.get(type_id="draft", slug="rfc") + rfc_published_state = State.objects.get(type_id="rfc", slug="published") + + # Find draft Documents in the "rfc" state + found_by_state = Document.objects.filter(states=draft_rfc_state).distinct() + + # Find Documents with an "rfc..." alias and confirm they're the same set + rfc_docaliases = DocAlias.objects.filter(name__startswith="rfc") + found_by_name = Document.objects.filter(docalias__in=rfc_docaliases).distinct() + assert set(found_by_name) == set(found_by_state), "mismatch between rfcs identified by state and docalias" + + # As of 2023-06-15, there is one Document with two rfc aliases: rfc6312 and rfc6342 are the same Document. This + # was due to a publication error. Because we go alias-by-alias, no special handling is needed in this migration. + + for rfc_alias in rfc_docaliases.order_by("name"): + assert rfc_alias.docs.count() == 1, f"DocAlias {rfc_alias} is linked to more than 1 Document" + draft = rfc_alias.docs.first() + if draft.name.startswith("rfc"): + rfc = draft + rfc.type_id = "rfc" + rfc.rfc_number = int(draft.name[3:]) + rfc.save() + rfc.states.set([rfc_published_state]) + else: + rfc = Document.objects.create( + type_id="rfc", + name=rfc_alias.name, + rfc_number=int(rfc_alias.name[3:]), + time=draft.time, + title=draft.title, + stream=draft.stream, + group=draft.group, + abstract=draft.abstract, + pages=draft.pages, + words=draft.words, + std_level=draft.std_level, + ad=draft.ad, + external_url=draft.external_url, + uploaded_filename=draft.uploaded_filename, + note=draft.note, + ) + rfc.states.set([rfc_published_state]) + rfc.formal_languages.set(draft.formal_languages.all()) + + # Copy Authors + for da in draft.documentauthor_set.all(): + DocumentAuthor.objects.create( + document=rfc, + person=da.person, + email=da.email, + affiliation=da.affiliation, + country=da.country, + order=da.order, + ) + + +class Migration(migrations.Migration): + dependencies = [ + ("doc", "0010_dochistory_rfc_number_document_rfc_number"), + ("name", "0010_rfc_doctype_names"), + ] + + operations = [ + migrations.RunPython(forward), + ] diff --git a/ietf/doc/migrations/0011_reviewassignmentdocevent.py b/ietf/doc/migrations/0011_reviewassignmentdocevent.py deleted file mode 100644 index e143b53397f..00000000000 --- a/ietf/doc/migrations/0011_reviewassignmentdocevent.py +++ /dev/null @@ -1,29 +0,0 @@ -# Copyright The IETF Trust 2019-2020, All Rights Reserved -# -*- coding: utf-8 -*- -# Generated by Django 1.11.18 on 2019-01-11 11:22 - - -from django.db import migrations, models -import django.db.models.deletion -import ietf.utils.models - - -class Migration(migrations.Migration): - - dependencies = [ - ('review', '0009_refactor_review_request'), - ('name', '0005_reviewassignmentstatename'), - ('doc', '0010_auto_20190225_1302'), - ] - - operations = [ - migrations.CreateModel( - name='ReviewAssignmentDocEvent', - fields=[ - ('docevent_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='doc.DocEvent')), - ('review_assignment', ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='review.ReviewAssignment')), - ('state', ietf.utils.models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='name.ReviewAssignmentStateName')), - ], - bases=('doc.docevent',), - ), - ] diff --git a/ietf/doc/migrations/0012_add_event_type_closed_review_assignment.py b/ietf/doc/migrations/0012_add_event_type_closed_review_assignment.py deleted file mode 100644 index ae9bb3ce831..00000000000 --- a/ietf/doc/migrations/0012_add_event_type_closed_review_assignment.py +++ /dev/null @@ -1,24 +0,0 @@ -# Copyright The IETF Trust 2019-2020, All Rights Reserved -# -*- coding: utf-8 -*- -# Generated by Django 1.11.20 on 2019-05-01 04:43 - - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('doc', '0011_reviewassignmentdocevent'), - # present to facilitate migration to just before review.0010: - ('name', '0006_adjust_statenames'), - ('dbtemplate', '0004_adjust_assignment_email_summary_templates'), - ] - - operations = [ - migrations.AlterField( - model_name='docevent', - name='type', - field=models.CharField(choices=[('new_revision', 'Added new revision'), ('new_submission', 'Uploaded new revision'), ('changed_document', 'Changed document metadata'), ('added_comment', 'Added comment'), ('added_message', 'Added message'), ('edited_authors', 'Edited the documents author list'), ('deleted', 'Deleted document'), ('changed_state', 'Changed state'), ('changed_stream', 'Changed document stream'), ('expired_document', 'Expired document'), ('extended_expiry', 'Extended expiry of document'), ('requested_resurrect', 'Requested resurrect'), ('completed_resurrect', 'Completed resurrect'), ('changed_consensus', 'Changed consensus'), ('published_rfc', 'Published RFC'), ('added_suggested_replaces', 'Added suggested replacement relationships'), ('reviewed_suggested_replaces', 'Reviewed suggested replacement relationships'), ('changed_group', 'Changed group'), ('changed_protocol_writeup', 'Changed protocol writeup'), ('changed_charter_milestone', 'Changed charter milestone'), ('initial_review', 'Set initial review time'), ('changed_review_announcement', 'Changed WG Review text'), ('changed_action_announcement', 'Changed WG Action text'), ('started_iesg_process', 'Started IESG process on document'), ('created_ballot', 'Created ballot'), ('closed_ballot', 'Closed ballot'), ('sent_ballot_announcement', 'Sent ballot announcement'), ('changed_ballot_position', 'Changed ballot position'), ('changed_ballot_approval_text', 'Changed ballot approval text'), ('changed_ballot_writeup_text', 'Changed ballot writeup text'), ('changed_rfc_editor_note_text', 'Changed RFC Editor Note text'), ('changed_last_call_text', 'Changed last call text'), ('requested_last_call', 'Requested last call'), ('sent_last_call', 'Sent last call'), ('scheduled_for_telechat', 'Scheduled for telechat'), ('iesg_approved', 'IESG approved document (no problem)'), ('iesg_disapproved', 'IESG disapproved document (do not publish)'), ('approved_in_minute', 'Approved in minute'), ('iana_review', 'IANA review comment'), ('rfc_in_iana_registry', 'RFC is in IANA registry'), ('rfc_editor_received_announcement', 'Announcement was received by RFC Editor'), ('requested_publication', 'Publication at RFC Editor requested'), ('sync_from_rfc_editor', 'Received updated information from RFC Editor'), ('requested_review', 'Requested review'), ('assigned_review_request', 'Assigned review request'), ('closed_review_request', 'Closed review request'), ('closed_review_assignment', 'Closed review assignment'), ('downref_approved', 'Downref approved')], max_length=50), - ), - ] diff --git a/ietf/doc/migrations/0012_move_rfc_docevents.py b/ietf/doc/migrations/0012_move_rfc_docevents.py new file mode 100644 index 00000000000..9969a8f0add --- /dev/null +++ b/ietf/doc/migrations/0012_move_rfc_docevents.py @@ -0,0 +1,88 @@ +# Generated by Django 4.2.2 on 2023-06-20 18:36 + +from django.db import migrations +from django.db.models import Q + + +def forward(apps, schema_editor): + """Move RFC events from the draft to the rfc Document""" + DocAlias = apps.get_model("doc", "DocAlias") + DocEvent = apps.get_model("doc", "DocEvent") + Document = apps.get_model("doc", "Document") + + # queryset with events migrated regardless of whether before or after the "published_rfc" event + events_always_migrated = DocEvent.objects.filter( + Q( + type__in=[ + "published_rfc", # do not remove this one! + ] + ) + ) + + # queryset with events migrated only after the "published_rfc" event + events_migrated_after_pub = DocEvent.objects.exclude( + type__in=[ + "created_ballot", + "closed_ballot", + "sent_ballot_announcement", + "changed_ballot_position", + "changed_ballot_approval_text", + "changed_ballot_writeup_text", + ] + ).exclude( + type="added_comment", + desc__contains="ballot set", # excludes 311 comments that all apply to drafts + ) + + # special case for rfc 6312/6342 draft, which has two published_rfc events + ignore = ["rfc6312", "rfc6342"] # do not reprocess these later + rfc6312 = Document.objects.get(name="rfc6312") + rfc6342 = Document.objects.get(name="rfc6342") + draft = DocAlias.objects.get(name="rfc6312").docs.first() + assert draft == DocAlias.objects.get(name="rfc6342").docs.first() + published_events = list( + DocEvent.objects.filter(doc=draft, type="published_rfc").order_by("time") + ) + assert len(published_events) == 2 + ( + pub_event_6312, + pub_event_6342, + ) = published_events # order matches pub dates at rfc-editor.org + + pub_event_6312.doc = rfc6312 + pub_event_6312.save() + events_migrated_after_pub.filter( + doc=draft, + time__gte=pub_event_6312.time, + time__lt=pub_event_6342.time, + ).update(doc=rfc6312) + + pub_event_6342.doc = rfc6342 + pub_event_6342.save() + events_migrated_after_pub.filter( + doc=draft, + time__gte=pub_event_6342.time, + ).update(doc=rfc6342) + + # Now handle all the rest + for rfc in Document.objects.filter(type_id="rfc").exclude(name__in=ignore): + draft = DocAlias.objects.get(name=rfc.name).docs.first() + assert draft is not None + published_event = DocEvent.objects.get(doc=draft, type="published_rfc") + events_always_migrated.filter( + doc=draft, + ).update(doc=rfc) + events_migrated_after_pub.filter( + doc=draft, + time__gte=published_event.time, + ).update(doc=rfc) + + +class Migration(migrations.Migration): + dependencies = [ + ("doc", "0011_create_rfc_documents"), + ] + + operations = [ + migrations.RunPython(forward), + ] diff --git a/ietf/doc/migrations/0013_add_document_docalias_id.py b/ietf/doc/migrations/0013_add_document_docalias_id.py deleted file mode 100644 index 1b9d0ab91b7..00000000000 --- a/ietf/doc/migrations/0013_add_document_docalias_id.py +++ /dev/null @@ -1,26 +0,0 @@ -# Copyright The IETF Trust 2019-2020, All Rights Reserved -# -*- coding: utf-8 -*- -# Generated by Django 1.11.20 on 2019-05-08 08:41 - - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('doc', '0012_add_event_type_closed_review_assignment'), - ] - - operations = [ - migrations.AddField( - model_name='docalias', - name='id', - field=models.IntegerField(default=0), - ), - migrations.AddField( - model_name='document', - name='id', - field=models.IntegerField(default=0), - ), - ] diff --git a/ietf/doc/migrations/0013_rfc_relateddocuments.py b/ietf/doc/migrations/0013_rfc_relateddocuments.py new file mode 100644 index 00000000000..9baddaebdb5 --- /dev/null +++ b/ietf/doc/migrations/0013_rfc_relateddocuments.py @@ -0,0 +1,45 @@ +# Generated by Django 4.2.3 on 2023-07-05 22:40 + +from django.db import migrations + + +def forward(apps, schema_editor): + DocAlias = apps.get_model("doc", "DocAlias") + Document = apps.get_model("doc", "Document") + RelatedDocument = apps.get_model("doc", "RelatedDocument") + for rfc_alias in DocAlias.objects.filter(name__startswith="rfc").exclude( + docs__type_id="rfc" + ): + # Move these over to the RFC + RelatedDocument.objects.filter( + relationship__slug__in=( + "tobcp", + "toexp", + "tohist", + "toinf", + "tois", + "tops", + "obs", + "updates", + ), + source__docalias=rfc_alias, + ).update(source=Document.objects.get(name=rfc_alias.name)) + # Duplicate references on the RFC but keep the ones on the draft as well + originals = list( + RelatedDocument.objects.filter( + relationship__slug__in=("refinfo", "refnorm", "refold", "refunk"), + source__docalias=rfc_alias, + ) + ) + for o in originals: + o.pk = None + o.source = Document.objects.get(name=rfc_alias.name) + RelatedDocument.objects.bulk_create(originals) + + +class Migration(migrations.Migration): + dependencies = [ + ("doc", "0012_move_rfc_docevents"), + ] + + operations = [migrations.RunPython(forward)] diff --git a/ietf/doc/migrations/0014_move_rfc_docaliases.py b/ietf/doc/migrations/0014_move_rfc_docaliases.py new file mode 100644 index 00000000000..c82a98e0526 --- /dev/null +++ b/ietf/doc/migrations/0014_move_rfc_docaliases.py @@ -0,0 +1,38 @@ +# Generated by Django 4.2.2 on 2023-06-20 18:36 + +from django.db import migrations + + +def forward(apps, schema_editor): + """Point "rfc..." DocAliases at the rfc-type Document + + Creates a became_rfc RelatedDocument to preserve the connection between the draft and the rfc. + """ + DocAlias = apps.get_model("doc", "DocAlias") + Document = apps.get_model("doc", "Document") + RelatedDocument = apps.get_model("doc", "RelatedDocument") + + for rfc_alias in DocAlias.objects.filter(name__startswith="rfc"): + rfc = Document.objects.get(name=rfc_alias.name) + aliased_doc = rfc_alias.docs.get() # implicitly confirms only one value in rfc_alias.docs + if aliased_doc != rfc: + # If the DocAlias was not already pointing at the rfc, it was pointing at the draft + # it came from. Create the relationship between draft and rfc Documents. + assert aliased_doc.type_id == "draft", f"Alias for {rfc.name} should be pointing at a draft" + RelatedDocument.objects.create( + source=aliased_doc, + target=rfc_alias, + relationship_id="became_rfc", + ) + # Now move the alias from the draft to the rfc + rfc_alias.docs.set([rfc]) + + +class Migration(migrations.Migration): + dependencies = [ + ("doc", "0013_rfc_relateddocuments"), + ] + + operations = [ + migrations.RunPython(forward), + ] diff --git a/ietf/doc/migrations/0014_set_document_docalias_id.py b/ietf/doc/migrations/0014_set_document_docalias_id.py deleted file mode 100644 index a97f6d7e47b..00000000000 --- a/ietf/doc/migrations/0014_set_document_docalias_id.py +++ /dev/null @@ -1,36 +0,0 @@ -# Copyright The IETF Trust 2019-2020, All Rights Reserved -# -*- coding: utf-8 -*- -# Generated by Django 1.11.20 on 2019-05-08 08:42 - - -import sys - -from tqdm import tqdm - -from django.db import migrations - - -def forward(apps, schema_editor): - Document = apps.get_model('doc','Document') - sys.stderr.write('\n') - for i, d in enumerate(tqdm(Document.objects.all()), start=1): - d.id = i - d.save() - - DocAlias = apps.get_model('doc','DocAlias') - for i, d in enumerate(tqdm(DocAlias.objects.all()), start=1): - d.id = i - d.save() - -def reverse(apps, schema_editor): - pass - -class Migration(migrations.Migration): - - dependencies = [ - ('doc', '0013_add_document_docalias_id'), - ] - - operations = [ - migrations.RunPython(forward, reverse), - ] diff --git a/ietf/doc/migrations/0015_1_add_fk_to_document_id.py b/ietf/doc/migrations/0015_1_add_fk_to_document_id.py deleted file mode 100644 index 6d2e7415f2f..00000000000 --- a/ietf/doc/migrations/0015_1_add_fk_to_document_id.py +++ /dev/null @@ -1,122 +0,0 @@ -# Copyright The IETF Trust 2019-2020, All Rights Reserved -# -*- coding: utf-8 -*- -# Generated by Django 1.11.20 on 2019-05-08 10:29 - - -import django.core.validators -from django.db import migrations, models -import django.db.models.deletion -import ietf.utils.models - - -class Migration(migrations.Migration): - - dependencies = [ - ('doc', '0014_set_document_docalias_id'), - ] - - operations = [ - # Fix name and id fields first - migrations.AlterField( - model_name='docalias', - name='name', - field=models.CharField(max_length=255, unique=True), - ), - migrations.AlterField( - model_name='docalias', - name='id', - field=models.IntegerField(primary_key=True, serialize=False), - ), - migrations.AlterField( - model_name='document', - name='name', - field=models.CharField(max_length=255, unique=True, validators=[django.core.validators.RegexValidator('^[-a-z0-9]+$', 'Provide a valid document name consisting of lowercase letters, numbers and hyphens.', 'invalid')]), - ), - migrations.AlterField( - model_name='document', - name='id', - field=models.IntegerField(primary_key=True, serialize=False), - ), - - # Then remaining fields - migrations.AddField( - model_name='docalias', - name='document2', - field=ietf.utils.models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='doc.Document', to_field=b'id'), - ), - migrations.AddField( - model_name='dochistory', - name='doc2', - field=ietf.utils.models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='history_set', to='doc.Document', to_field=b'id'), - ), - migrations.AddField( - model_name='documentauthor', - name='document2', - field=ietf.utils.models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='doc.Document', to_field=b'id'), - ), - migrations.AddField( - model_name='documenturl', - name='doc2', - field=ietf.utils.models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='doc.Document', to_field=b'id'), - ), - migrations.AddField( - model_name='relateddochistory', - name='target2', - field=ietf.utils.models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='reversely_related_document_history_set', to='doc.DocAlias', to_field=b'id'), - ), - migrations.AddField( - model_name='relateddocument', - name='source2', - field=ietf.utils.models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='doc.Document', to_field=b'id'), - ), - migrations.AddField( - model_name='relateddocument', - name='target2', - field=ietf.utils.models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='doc.DocAlias', to_field=b'id'), - ), - migrations.AddField( - model_name='docevent', - name='doc2', - field=ietf.utils.models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='doc.Document', to_field='id'), - ), - migrations.AlterField( - model_name='docalias', - name='document', - field=ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='old_docalias', to='doc.Document', to_field=b'name'), - ), - migrations.AlterField( - model_name='dochistory', - name='doc', - field=ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='old_hist', to='doc.Document', to_field=b'name'), - ), - migrations.AlterField( - model_name='documentauthor', - name='document', - field=ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='old_doc_auth', to='doc.Document', to_field=b'name'), - ), - migrations.AlterField( - model_name='documenturl', - name='doc', - field=ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='old_doc_url', to='doc.Document', to_field=b'name'), - ), - migrations.AlterField( - model_name='relateddochistory', - name='target', - field=ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='old_hist_target', to='doc.DocAlias', to_field=b'name'), - ), - migrations.AlterField( - model_name='relateddocument', - name='source', - field=ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='old_rel_source', to='doc.Document', to_field=b'name'), - ), - migrations.AlterField( - model_name='relateddocument', - name='target', - field=ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='old_rel_target', to='doc.DocAlias', to_field=b'name'), - ), - migrations.AlterField( - model_name='docevent', - name='doc', - field=ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='old_docevent', to='doc.Document', to_field=b'name'), - ), - ] diff --git a/ietf/doc/migrations/0015_2_add_doc_document_m2m_fields.py b/ietf/doc/migrations/0015_2_add_doc_document_m2m_fields.py deleted file mode 100644 index 99ff30c5527..00000000000 --- a/ietf/doc/migrations/0015_2_add_doc_document_m2m_fields.py +++ /dev/null @@ -1,94 +0,0 @@ -# Copyright The IETF Trust 2019-2020, All Rights Reserved -# -*- coding: utf-8 -*- -# Generated by Django 1.11.20 on 2019-05-28 12:42 - - -import sys, time - -from django.db import migrations, models -import django.db.models.deletion -import ietf.utils.models - - -def timestamp(apps, schema_editor): - sys.stderr.write('\n %s' % time.strftime('%Y-%m-%d %H:%M:%S')) - -class Migration(migrations.Migration): - - dependencies = [ - ('name', '0006_adjust_statenames'), - ('doc', '0015_1_add_fk_to_document_id'), - ] - - operations = [ - migrations.CreateModel( - name='DocumentLanguages', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('document', ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='doc.Document', to_field='name', related_name='doclanguages')), - ('formallanguagename', ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='name.FormalLanguageName')), - ], - ), - migrations.CreateModel( - name='DocumentStates', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('document', ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='doc.Document', to_field='name', related_name='docstates')), - ('state', ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='doc.State')), - ], - ), - migrations.CreateModel( - name='DocumentTags', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('document', ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='doc.Document', to_field='name', related_name='doctags')), - ('doctagname', ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='name.DocTagName')), - ], - ), - migrations.AddField( - model_name='document', - name='formal_languages2', - field=models.ManyToManyField(blank=True, related_name='languagedocs', through='doc.DocumentLanguages', to='name.FormalLanguageName'), - ), - migrations.AddField( - model_name='document', - name='states2', - field=models.ManyToManyField(blank=True, related_name='statedocs', through='doc.DocumentStates', to='doc.State'), - ), - migrations.AddField( - model_name='document', - name='tags2', - field=models.ManyToManyField(blank=True, related_name='tagdocs', through='doc.DocumentTags', to='name.DocTagName'), - ), - # Here we copy the content of the existing implicit m2m tables for - # the Document m2m fields into the explicit through tabeles, in order - # to be able to later set the correct id from name - migrations.RunPython(timestamp, timestamp), - migrations.RunSQL( - "INSERT INTO doc_documentlanguages SELECT * FROM doc_document_formal_languages;", - ""), - migrations.RunPython(timestamp, timestamp), - migrations.RunSQL( - "INSERT INTO doc_documentstates SELECT * FROM doc_document_states;", - ""), - migrations.RunPython(timestamp, timestamp), - migrations.RunSQL( - "INSERT INTO doc_documenttags SELECT * FROM doc_document_tags;", - ""), - migrations.RunPython(timestamp, timestamp), - migrations.AddField( - model_name='documentlanguages', - name='document2', - field=ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='doc.Document', to_field='id', null=True, default=None), - ), - migrations.AddField( - model_name='documentstates', - name='document2', - field=ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='doc.Document', to_field='id', null=True, default=None), ), - migrations.AddField( - model_name='documenttags', - name='document2', - field=ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='doc.Document', to_field='id', null=True, default=None), - - ), - ] diff --git a/ietf/doc/migrations/0015_relate_no_aliases.py b/ietf/doc/migrations/0015_relate_no_aliases.py new file mode 100644 index 00000000000..4ba3dd96070 --- /dev/null +++ b/ietf/doc/migrations/0015_relate_no_aliases.py @@ -0,0 +1,84 @@ +# Generated by Django 4.2.2 on 2023-06-16 13:40 + +from django.db import migrations +import django.db.models.deletion +from django.db.models import F, Subquery, OuterRef, CharField +import ietf.utils.models + +def forward(apps, schema_editor): + RelatedDocument = apps.get_model("doc", "RelatedDocument") + DocAlias = apps.get_model("doc", "DocAlias") + target_subquery = Subquery(DocAlias.objects.filter(pk=OuterRef("deprecated_target")).values("docs")[:1]) + name_subquery = Subquery(DocAlias.objects.filter(pk=OuterRef("deprecated_target")).values("name")[:1]) + RelatedDocument.objects.annotate(firstdoc=target_subquery).annotate(aliasname=name_subquery).update(target=F("firstdoc"),originaltargetaliasname=F("aliasname")) + +def reverse(apps, schema_editor): + pass + +class Migration(migrations.Migration): + dependencies = [ + ("doc", "0014_move_rfc_docaliases"), + ] + + operations = [ + migrations.AlterField( + model_name='relateddocument', + name='target', + field=ietf.utils.models.ForeignKey( + db_index=False, + on_delete=django.db.models.deletion.CASCADE, + to='doc.docalias', + ), + ), + migrations.RenameField( + model_name="relateddocument", + old_name="target", + new_name="deprecated_target" + ), + migrations.AlterField( + model_name='relateddocument', + name='deprecated_target', + field=ietf.utils.models.ForeignKey( + db_index=True, + on_delete=django.db.models.deletion.CASCADE, + to='doc.docalias', + ), + ), + migrations.AddField( + model_name="relateddocument", + name="target", + field=ietf.utils.models.ForeignKey( + default=1, # A lie, but a convenient one - no relations point here. + on_delete=django.db.models.deletion.CASCADE, + related_name="targets_related", + to="doc.document", + db_index=False, + ), + preserve_default=False, + ), + migrations.AddField( + model_name="relateddocument", + name="originaltargetaliasname", + field=CharField(max_length=255,null=True,blank=True), + preserve_default=True, + ), + migrations.RunPython(forward, reverse), + migrations.AlterField( + model_name="relateddocument", + name="target", + field=ietf.utils.models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="targets_related", + to="doc.document", + db_index=True, + ), + ), + migrations.RemoveField( + model_name="relateddocument", + name="deprecated_target", + field=ietf.utils.models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + to='doc.DocAlias', + ), + ), + ] diff --git a/ietf/doc/migrations/0016_relate_hist_no_aliases.py b/ietf/doc/migrations/0016_relate_hist_no_aliases.py new file mode 100644 index 00000000000..df5fb3c3259 --- /dev/null +++ b/ietf/doc/migrations/0016_relate_hist_no_aliases.py @@ -0,0 +1,87 @@ +# Generated by Django 4.2.2 on 2023-06-16 13:40 + +from django.db import migrations +import django.db.models.deletion +from django.db.models import F, Subquery, OuterRef, CharField +import ietf.utils.models + +def forward(apps, schema_editor): + RelatedDocHistory = apps.get_model("doc", "RelatedDocHistory") + DocAlias = apps.get_model("doc", "DocAlias") + target_subquery = Subquery(DocAlias.objects.filter(pk=OuterRef("deprecated_target")).values("docs")[:1]) + name_subquery = Subquery(DocAlias.objects.filter(pk=OuterRef("deprecated_target")).values("name")[:1]) + RelatedDocHistory.objects.annotate(firstdoc=target_subquery).annotate(aliasname=name_subquery).update(target=F("firstdoc"),originaltargetaliasname=F("aliasname")) + +def reverse(apps, schema_editor): + pass + +class Migration(migrations.Migration): + dependencies = [ + ("doc", "0015_relate_no_aliases"), + ] + + operations = [ + migrations.AlterField( + model_name='relateddochistory', + name='target', + field=ietf.utils.models.ForeignKey( + db_index=False, + on_delete=django.db.models.deletion.CASCADE, + to='doc.docalias', + related_name='reversely_related_document_history_set', + ), + ), + migrations.RenameField( + model_name="relateddochistory", + old_name="target", + new_name="deprecated_target" + ), + migrations.AlterField( + model_name='relateddochistory', + name='deprecated_target', + field=ietf.utils.models.ForeignKey( + db_index=True, + on_delete=django.db.models.deletion.CASCADE, + to='doc.docalias', + related_name='deprecated_reversely_related_document_history_set', + ), + ), + migrations.AddField( + model_name="relateddochistory", + name="target", + field=ietf.utils.models.ForeignKey( + default=1, # A lie, but a convenient one - no relations point here. + on_delete=django.db.models.deletion.CASCADE, + to="doc.document", + db_index=False, + related_name='reversely_related_document_history_set', + ), + preserve_default=False, + ), + migrations.AddField( + model_name="relateddochistory", + name="originaltargetaliasname", + field=CharField(max_length=255,null=True,blank=True), + preserve_default=True, + ), + migrations.RunPython(forward, reverse), + migrations.AlterField( + model_name="relateddochistory", + name="target", + field=ietf.utils.models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + to="doc.document", + db_index=True, + related_name='reversely_related_document_history_set', + ), + ), + migrations.RemoveField( + model_name="relateddochistory", + name="deprecated_target", + field=ietf.utils.models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + to='doc.DocAlias', + related_name='deprecated_reversely_related_document_history_set', + ), + ), + ] diff --git a/ietf/doc/migrations/0016_set_document_docalias_fk.py b/ietf/doc/migrations/0016_set_document_docalias_fk.py deleted file mode 100644 index 67d1333f387..00000000000 --- a/ietf/doc/migrations/0016_set_document_docalias_fk.py +++ /dev/null @@ -1,113 +0,0 @@ -# Copyright The IETF Trust 2019-2020, All Rights Reserved -# -*- coding: utf-8 -*- -# Generated by Django 1.11.20 on 2019-05-08 14:04 - - -import sys - -from tqdm import tqdm - -from django.db import migrations - -def forward(apps, schema_editor): - - def add_id_fk(o, a, nameid): - n = getattr(o, a+'_id') - if n: - i = nameid[n] - if not isinstance(i, int): - raise ValueError("Inappropriate value: %s: nameid[%s]: %s" % (o.__class__.__name__, n, i)) - if getattr(o, a+'2_id') != i: - setattr(o, a+'2_id', i) - o.save() - - DocAlias = apps.get_model('doc','DocAlias') - DocEvent = apps.get_model('doc', 'DocEvent') - DocHistory = apps.get_model('doc', 'DocHistory') - Document = apps.get_model('doc', 'Document') - DocumentAuthor = apps.get_model('doc', 'DocumentAuthor') - DocumentLanguages = apps.get_model('doc', 'DocumentLanguages') - DocumentStates = apps.get_model('doc', 'DocumentStates') - DocumentTags = apps.get_model('doc', 'DocumentTags') - DocumentURL = apps.get_model('doc', 'DocumentURL') - Group = apps.get_model('group', 'Group') - IprDocRel = apps.get_model('ipr', 'IprDocRel') - LiaisonStatementAttachment = apps.get_model('liaisons', 'LiaisonStatementAttachment') - RelatedDocHistory = apps.get_model('doc', 'RelatedDocHistory') - RelatedDocument = apps.get_model('doc', 'RelatedDocument') - ReviewAssignment = apps.get_model('review', 'ReviewAssignment') - ReviewRequest = apps.get_model('review', 'ReviewRequest') - ReviewWish = apps.get_model('review', 'ReviewWish') - SessionPresentation = apps.get_model('meeting', 'SessionPresentation') - Submission = apps.get_model('submit', 'Submission') - - # Document id fixup ------------------------------------------------------------ - - objs = Document.objects.in_bulk() - nameid = { o.name: o.id for id, o in objs.items() } - - sys.stderr.write('\n') - - sys.stderr.write('Setting Document FKs:\n') - - for C, a in [ - ( DocAlias , 'document'), - ( DocEvent , 'doc'), - ( DocHistory , 'doc'), - ( DocumentAuthor , 'document'), - ( DocumentLanguages , 'document'), - ( DocumentStates , 'document'), - ( DocumentTags , 'document'), - ( DocumentURL , 'doc'), - ( Group , 'charter'), - ( LiaisonStatementAttachment , 'document'), - ( RelatedDocument , 'source'), - ( ReviewAssignment , 'review'), - ( ReviewRequest , 'doc'), - ( ReviewRequest , 'unused_review'), - ( ReviewWish , 'doc'), - ( SessionPresentation , 'document'), - ( Submission , 'draft'), - ]: - sys.stderr.write(' %s.%s:\n' % (C.__name__, a)) - for o in tqdm(C.objects.all()): - add_id_fk(o, a, nameid) - - # DocAlias id fixup ------------------------------------------------------------ - - sys.stderr.write('\n') - - objs = DocAlias.objects.in_bulk() - nameid = { o.name: o.id for id, o in objs.items() } - - sys.stderr.write('Setting DocAlias FKs:\n') - - for C, a in [ - ( IprDocRel , 'document'), - ( RelatedDocument , 'target'), - ( RelatedDocHistory , 'target'), - ]: - sys.stderr.write(' %s.%s:\n' % (C.__name__, a)) - for o in tqdm(C.objects.all()): - add_id_fk(o, a, nameid) - -def reverse(apps, schema_editor): - pass - -class Migration(migrations.Migration): - - dependencies = [ - ('community', '0004_set_document_m2m_keys'), - ('doc', '0015_2_add_doc_document_m2m_fields'), - ('group', '0014_set_document_m2m_keys'), - ('ipr', '0003_add_ipdocrel_document2_fk'), - ('liaisons', '0003_liaison_document2_fk'), - ('meeting', '0015_sessionpresentation_document2_fk'), - ('message', '0003_set_document_m2m_keys'), - ('review', '0011_review_document2_fk'), - ('submit', '0002_submission_document2_fk'), - ] - - operations = [ - migrations.RunPython(forward, reverse), - ] diff --git a/ietf/doc/migrations/0017_delete_docalias.py b/ietf/doc/migrations/0017_delete_docalias.py new file mode 100644 index 00000000000..207ca81e155 --- /dev/null +++ b/ietf/doc/migrations/0017_delete_docalias.py @@ -0,0 +1,16 @@ +# Copyright The IETF Trust 2023, All Rights Reserved + +from django.db import migrations + + +class Migration(migrations.Migration): + dependencies = [ + ("ipr", "0002_iprdocrel_no_aliases"), + ("doc", "0016_relate_hist_no_aliases"), + ] + + operations = [ + migrations.DeleteModel( + name="DocAlias", + ), + ] diff --git a/ietf/doc/migrations/0017_make_document_id_primary_key.py b/ietf/doc/migrations/0017_make_document_id_primary_key.py deleted file mode 100644 index baadd6f725c..00000000000 --- a/ietf/doc/migrations/0017_make_document_id_primary_key.py +++ /dev/null @@ -1,26 +0,0 @@ -# Copyright The IETF Trust 2019-2020, All Rights Reserved -# -*- coding: utf-8 -*- -# Generated by Django 1.11.20 on 2019-05-09 05:46 - - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('doc', '0016_set_document_docalias_fk'), - ] - - operations = [ - migrations.AlterField( - model_name='docalias', - name='id', - field=models.AutoField(primary_key=True, serialize=False), - ), - migrations.AlterField( - model_name='document', - name='id', - field=models.AutoField(primary_key=True, serialize=False), - ), - ] diff --git a/ietf/doc/migrations/0018_move_dochistory.py b/ietf/doc/migrations/0018_move_dochistory.py new file mode 100644 index 00000000000..0bc29b0bc45 --- /dev/null +++ b/ietf/doc/migrations/0018_move_dochistory.py @@ -0,0 +1,45 @@ +# Generated by Django 4.2.5 on 2023-09-11 17:52 + +from django.db import migrations + +from django.db.models import Subquery, OuterRef, F + + +def forward(apps, schema_editor): + DocHistory = apps.get_model("doc", "DocHistory") + RelatedDocument = apps.get_model("doc", "RelatedDocument") + Document = apps.get_model("doc", "Document") + DocHistory.objects.filter(type_id="draft", doc__type_id="rfc").update(type_id="rfc") + DocHistory.objects.filter( + type_id="draft", doc__type_id="draft", name__startswith="rfc" + ).annotate( + rfc_id=Subquery( + RelatedDocument.objects.filter( + source_id=OuterRef("doc_id"), relationship_id="became_rfc" + ).values_list("target_id", flat=True)[:1] + ) + ).update( + doc_id=F("rfc_id"), type_id="rfc" + ) + DocHistory.objects.filter(type_id="rfc").annotate( + rfcno=Subquery( + Document.objects.filter(pk=OuterRef("doc_id")).values_list( + "rfc_number", flat=True + )[:1] + ) + ).update(rfc_number=F("rfcno")) + assert not DocHistory.objects.filter( + name__startswith="rfc", type_id="draft" + ).exists() + assert not DocHistory.objects.filter( + type_id="rfc", rfc_number__isnull=True + ).exists() + + +class Migration(migrations.Migration): + dependencies = [ + ("doc", "0017_delete_docalias"), + ] + + # There is no going back + operations = [migrations.RunPython(forward)] diff --git a/ietf/doc/migrations/0018_remove_old_document_field.py b/ietf/doc/migrations/0018_remove_old_document_field.py deleted file mode 100644 index 887dcc77070..00000000000 --- a/ietf/doc/migrations/0018_remove_old_document_field.py +++ /dev/null @@ -1,125 +0,0 @@ -# Copyright The IETF Trust 2019-2020, All Rights Reserved -# -*- coding: utf-8 -*- -# Generated by Django 1.11.20 on 2019-05-20 09:53 - - -from django.db import migrations, models -import django.db.models.deletion -import ietf.utils.models - - -class Migration(migrations.Migration): - - dependencies = [ - ('doc', '0017_make_document_id_primary_key'), - ] - - operations = [ - migrations.AlterModelOptions( - name='documentauthor', - options={'ordering': ['document2', 'order']}, - ), - migrations.RemoveIndex( - model_name='docevent', - name='doc_doceven_type_43e53e_idx', - ), - migrations.RemoveField( - model_name='docalias', - name='document', - ), - migrations.RemoveField( - model_name='docevent', - name='doc', - ), - migrations.RemoveField( - model_name='dochistory', - name='doc', - ), - migrations.RemoveField( - model_name='documentauthor', - name='document', - ), - migrations.RemoveField( - model_name='documenturl', - name='doc', - ), - migrations.RemoveField( - model_name='relateddochistory', - name='target', - ), - migrations.RemoveField( - model_name='relateddocument', - name='source', - ), - migrations.RemoveField( - model_name='relateddocument', - name='target', - ), - migrations.AddIndex( - model_name='docevent', - index=models.Index(fields=['type', 'doc2'], name='doc_doceven_type_ac7748_idx'), - ), - # The following 9 migrations are related to the m2m fields on Document - # Remove the intermediary model field pointing to Document.name - migrations.RemoveField( - model_name='documentlanguages', - name='document', - ), - migrations.RemoveField( - model_name='documentstates', - name='document', - ), - migrations.RemoveField( - model_name='documenttags', - name='document', - ), - # Rename the intermediary model field pointing to Document.id, to - # match the implicit m2m table - migrations.RenameField( - model_name='documentlanguages', - old_name='document2', - new_name='document', - ), - migrations.RenameField( - model_name='documentstates', - old_name='document2', - new_name='document', - ), - migrations.RenameField( - model_name='documenttags', - old_name='document2', - new_name='document', - ), - # Alter the fields to point to Document.pk instead of Document.name - migrations.AlterField( - model_name='documentlanguages', - name='document', - field=ietf.utils.models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='doc.Document'), - ), - migrations.AlterField( - model_name='documentstates', - name='document', - field=ietf.utils.models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='doc.Document'), - ), - migrations.AlterField( - model_name='documenttags', - name='document', - field=ietf.utils.models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='doc.Document'), - ), - # Remove the implicit m2m tables which point to Document.name - migrations.RemoveField( - model_name='document', - name='formal_languages', - ), - migrations.RemoveField( - model_name='document', - name='states', - ), - migrations.RemoveField( - model_name='document', - name='tags', - ), - # Next (in a separate migration, in order to commit the above before - # we proceed) we'll create the implicit m2m tables again, this time - # pointing to Document.id since that's now the primary key. - ] diff --git a/ietf/doc/migrations/0019_rename_field_document2.py b/ietf/doc/migrations/0019_rename_field_document2.py deleted file mode 100644 index 517ae9ee732..00000000000 --- a/ietf/doc/migrations/0019_rename_field_document2.py +++ /dev/null @@ -1,84 +0,0 @@ -# Copyright The IETF Trust 2019-2020, All Rights Reserved -# -*- coding: utf-8 -*- -# Generated by Django 1.11.20 on 2019-05-21 05:31 - - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('doc', '0018_remove_old_document_field'), - ] - - operations = [ - migrations.AlterModelOptions( - name='documentauthor', - options={'ordering': ['document', 'order']}, - ), - migrations.RemoveIndex( - model_name='docevent', - name='doc_doceven_type_ac7748_idx', - ), - migrations.RenameField( - model_name='docalias', - old_name='document2', - new_name='document', - ), - migrations.RenameField( - model_name='docevent', - old_name='doc2', - new_name='doc', - ), - migrations.RenameField( - model_name='dochistory', - old_name='doc2', - new_name='doc', - ), - migrations.RenameField( - model_name='documentauthor', - old_name='document2', - new_name='document', - ), - migrations.RenameField( - model_name='documenturl', - old_name='doc2', - new_name='doc', - ), - migrations.RenameField( - model_name='relateddochistory', - old_name='target2', - new_name='target', - ), - migrations.RenameField( - model_name='relateddocument', - old_name='source2', - new_name='source', - ), - migrations.RenameField( - model_name='relateddocument', - old_name='target2', - new_name='target', - ), - migrations.AddIndex( - model_name='docevent', - index=models.Index(fields=['type', 'doc'], name='doc_doceven_type_43e53e_idx'), - ), - # Add back the m2m field we removed in 0018_... - migrations.AddField( - model_name='document', - name='formal_languages', - field=models.ManyToManyField(blank=True, help_text='Formal languages used in document', to='name.FormalLanguageName'), - ), - migrations.AddField( - model_name='document', - name='states', - field=models.ManyToManyField(blank=True, to='doc.State'), - ), - migrations.AddField( - model_name='document', - name='tags', - field=models.ManyToManyField(blank=True, to='name.DocTagName'), - ), - ] diff --git a/ietf/doc/migrations/0019_subseries.py b/ietf/doc/migrations/0019_subseries.py new file mode 100644 index 00000000000..be2c612ac0e --- /dev/null +++ b/ietf/doc/migrations/0019_subseries.py @@ -0,0 +1,21 @@ +# Copyright The IETF Trust 2023, All Rights Reserved +from django.db import migrations + + +def forward(apps, schema_editor): + StateType = apps.get_model("doc", "StateType") + for slug in ["bcp", "std", "fyi"]: + StateType.objects.create(slug=slug, label=f"{slug} state") + + +def reverse(apps, schema_editor): + StateType = apps.get_model("doc", "StateType") + StateType.objects.filter(slug__in=["bcp", "std", "fyi"]).delete() + + +class Migration(migrations.Migration): + dependencies = [ + ("doc", "0018_move_dochistory"), + ] + + operations = [migrations.RunPython(forward, reverse)] diff --git a/ietf/doc/migrations/0020_copy_docs_m2m_table.py b/ietf/doc/migrations/0020_copy_docs_m2m_table.py deleted file mode 100644 index 482c4d78529..00000000000 --- a/ietf/doc/migrations/0020_copy_docs_m2m_table.py +++ /dev/null @@ -1,34 +0,0 @@ -# Copyright The IETF Trust 2019-2020, All Rights Reserved -# -*- coding: utf-8 -*- -# Generated by Django 1.11.20 on 2019-05-21 05:31 - - -import sys, time - -from django.db import migrations - -def timestamp(apps, schema_editor): - sys.stderr.write('\n %s' % time.strftime('%Y-%m-%d %H:%M:%S')) - -class Migration(migrations.Migration): - - dependencies = [ - ('doc', '0019_rename_field_document2'), - ] - - operations = [ - # Copy the doc IDs from the explicit m2m table to the implicit table - migrations.RunPython(timestamp, timestamp), - migrations.RunSQL( - "INSERT INTO doc_document_formal_languages SELECT id,document_id,formallanguagename_id FROM doc_documentlanguages;", - ""), - migrations.RunPython(timestamp, timestamp), - migrations.RunSQL( - "INSERT INTO doc_document_states SELECT id,document_id,state_id FROM doc_documentstates;", - ""), - migrations.RunPython(timestamp, timestamp), - migrations.RunSQL( - "INSERT INTO doc_document_tags SELECT id,document_id,doctagname_id FROM doc_documenttags;", - ""), - migrations.RunPython(timestamp, timestamp), - ] diff --git a/ietf/doc/migrations/0020_move_errata_tags.py b/ietf/doc/migrations/0020_move_errata_tags.py new file mode 100644 index 00000000000..897b88f4678 --- /dev/null +++ b/ietf/doc/migrations/0020_move_errata_tags.py @@ -0,0 +1,29 @@ +# Copyright The IETF Trust 2023, All Rights Reserved + +from django.db import migrations + +from django.db.models import Subquery, OuterRef, F + + +def forward(apps, schema_editor): + Document = apps.get_model("doc", "Document") + RelatedDocument = apps.get_model("doc", "RelatedDocument") + Document.tags.through.objects.filter( + doctagname_id__in=["errata", "verified-errata"], document__type_id="draft" + ).annotate( + rfcdoc=Subquery( + RelatedDocument.objects.filter( + relationship_id="became_rfc", source_id=OuterRef("document__pk") + ).values_list("target__pk", flat=True)[:1] + ) + ).update( + document_id=F("rfcdoc") + ) + + +class Migration(migrations.Migration): + dependencies = [ + ("doc", "0019_subseries"), + ] + + operations = [migrations.RunPython(forward)] diff --git a/ietf/doc/migrations/0021_narrativeminutes.py b/ietf/doc/migrations/0021_narrativeminutes.py new file mode 100644 index 00000000000..0f330bd0530 --- /dev/null +++ b/ietf/doc/migrations/0021_narrativeminutes.py @@ -0,0 +1,39 @@ +# Copyright The IETF Trust 2023, All Rights Reserved + +from django.db import migrations + + +def forward(apps, schema_editor): + StateType = apps.get_model("doc", "StateType") + State = apps.get_model("doc", "State") + + StateType.objects.create( + slug="narrativeminutes", + label="State", + ) + for order, slug in enumerate(["active", "deleted"]): + State.objects.create( + slug=slug, + type_id="narrativeminutes", + name=slug.capitalize(), + order=order, + desc="", + used=True, + ) + + +def reverse(apps, schema_editor): + StateType = apps.get_model("doc", "StateType") + State = apps.get_model("doc", "State") + + State.objects.filter(type_id="narrativeminutes").delete() + StateType.objects.filter(slug="narrativeminutes").delete() + + +class Migration(migrations.Migration): + dependencies = [ + ("doc", "0020_move_errata_tags"), + ("name", "0013_narrativeminutes"), + ] + + operations = [migrations.RunPython(forward, reverse)] diff --git a/ietf/doc/migrations/0021_remove_docs2_m2m.py b/ietf/doc/migrations/0021_remove_docs2_m2m.py deleted file mode 100644 index c659b65debc..00000000000 --- a/ietf/doc/migrations/0021_remove_docs2_m2m.py +++ /dev/null @@ -1,63 +0,0 @@ -# Copyright The IETF Trust 2019-2020, All Rights Reserved -# -*- coding: utf-8 -*- -# Generated by Django 1.11.20 on 2019-05-30 03:36 - - -from django.db import migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ('doc', '0020_copy_docs_m2m_table'), - ] - - operations = [ - # Get rid of the explicit m2m tables which we needed only to be - # able to convert from Document.name to Document.id - migrations.RemoveField( - model_name='documentlanguages', - name='document', - ), - migrations.RemoveField( - model_name='documentlanguages', - name='formallanguagename', - ), - migrations.RemoveField( - model_name='documentstates', - name='document', - ), - migrations.RemoveField( - model_name='documentstates', - name='state', - ), - migrations.RemoveField( - model_name='documenttags', - name='doctagname', - ), - migrations.RemoveField( - model_name='documenttags', - name='document', - ), - migrations.RemoveField( - model_name='document', - name='formal_languages2', - ), - migrations.RemoveField( - model_name='document', - name='states2', - ), - migrations.RemoveField( - model_name='document', - name='tags2', - ), - migrations.DeleteModel( - name='DocumentLanguages', - ), - migrations.DeleteModel( - name='DocumentStates', - ), - migrations.DeleteModel( - name='DocumentTags', - ), - ] diff --git a/ietf/doc/migrations/0022_document_primary_key_cleanup.py b/ietf/doc/migrations/0022_document_primary_key_cleanup.py deleted file mode 100644 index 9ddc908f5cb..00000000000 --- a/ietf/doc/migrations/0022_document_primary_key_cleanup.py +++ /dev/null @@ -1,68 +0,0 @@ -# Copyright The IETF Trust 2019-2020, All Rights Reserved -# -*- coding: utf-8 -*- -# Generated by Django 1.11.20 on 2019-06-10 03:47 - - -from django.db import migrations, models -import django.db.models.deletion -import ietf.utils.models - - -class Migration(migrations.Migration): - - dependencies = [ - ('doc', '0021_remove_docs2_m2m'), - ] - - operations = [ - migrations.AlterField( - model_name='docalias', - name='document', - field=ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='doc.Document'), - ), - migrations.AlterField( - model_name='docalias', - name='id', - field=models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID'), - ), - migrations.AlterField( - model_name='docevent', - name='doc', - field=ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='doc.Document'), - ), - migrations.AlterField( - model_name='dochistory', - name='doc', - field=ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='history_set', to='doc.Document'), - ), - migrations.AlterField( - model_name='document', - name='id', - field=models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID'), - ), - migrations.AlterField( - model_name='documentauthor', - name='document', - field=ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='doc.Document'), - ), - migrations.AlterField( - model_name='documenturl', - name='doc', - field=ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='doc.Document'), - ), - migrations.AlterField( - model_name='relateddochistory', - name='target', - field=ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='reversely_related_document_history_set', to='doc.DocAlias'), - ), - migrations.AlterField( - model_name='relateddocument', - name='source', - field=ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='doc.Document'), - ), - migrations.AlterField( - model_name='relateddocument', - name='target', - field=ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='doc.DocAlias'), - ), - ] diff --git a/ietf/doc/migrations/0022_remove_dochistory_internal_comments_and_more.py b/ietf/doc/migrations/0022_remove_dochistory_internal_comments_and_more.py new file mode 100644 index 00000000000..ad27793a833 --- /dev/null +++ b/ietf/doc/migrations/0022_remove_dochistory_internal_comments_and_more.py @@ -0,0 +1,21 @@ +# Generated by Django 4.2.15 on 2024-08-16 16:43 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ("doc", "0021_narrativeminutes"), + ] + + operations = [ + migrations.RemoveField( + model_name="dochistory", + name="internal_comments", + ), + migrations.RemoveField( + model_name="document", + name="internal_comments", + ), + ] diff --git a/ietf/doc/migrations/0023_bofreqspamstate.py b/ietf/doc/migrations/0023_bofreqspamstate.py new file mode 100644 index 00000000000..dbbaf996e9b --- /dev/null +++ b/ietf/doc/migrations/0023_bofreqspamstate.py @@ -0,0 +1,30 @@ +# Copyright The IETF Trust 2024, All Rights Reserved + +from django.db import migrations + + +def forward(apps, schema_editor): + State = apps.get_model("doc", "State") + State.objects.get_or_create( + type_id="bofreq", + slug="spam", + defaults={"name": "Spam", "desc": "The BOF request is spam", "order": 5}, + ) + + +def reverse(apps, schema_editor): + State = apps.get_model("doc", "State") + Document = apps.get_model("doc", "Document") + assert not Document.objects.filter( + states__type="bofreq", states__slug="spam" + ).exists() + State.objects.filter(type_id="bofreq", slug="spam").delete() + + +class Migration(migrations.Migration): + + dependencies = [ + ("doc", "0022_remove_dochistory_internal_comments_and_more"), + ] + + operations = [migrations.RunPython(forward, reverse)] diff --git a/ietf/doc/migrations/0023_one_to_many_docalias.py b/ietf/doc/migrations/0023_one_to_many_docalias.py deleted file mode 100644 index cf3c8330a6d..00000000000 --- a/ietf/doc/migrations/0023_one_to_many_docalias.py +++ /dev/null @@ -1,43 +0,0 @@ -# Copyright The IETF Trust 2019-2020, All Rights Reserved -# -*- coding: utf-8 -*- -# Generated by Django 1.11.20 on 2019-06-10 04:36 - - -import sys - -from tqdm import tqdm - -from django.db import migrations, models - - -def forward(apps, schema_editor): - DocAlias = apps.get_model('doc','DocAlias') - sys.stderr.write('\n') - for a in tqdm(DocAlias.objects.all()): - a.docs.add(a.document) - -def reverse(apps, schema_editor): - DocAlias = apps.get_model('doc','DocAlias') - sys.stderr.write('\n') - for a in tqdm(DocAlias.objects.all()): - a.document = a.document - a.save() - -class Migration(migrations.Migration): - - dependencies = [ - ('doc', '0022_document_primary_key_cleanup'), - ] - - operations = [ - migrations.AddField( - model_name='docalias', - name='docs', - field=models.ManyToManyField(related_name='docalias', to='doc.Document'), - ), - migrations.RunPython(forward, reverse), - migrations.RemoveField( - model_name='docalias', - name='document', - ), - ] diff --git a/ietf/doc/migrations/0024_iana_experts.py b/ietf/doc/migrations/0024_iana_experts.py deleted file mode 100644 index 0922b9c243e..00000000000 --- a/ietf/doc/migrations/0024_iana_experts.py +++ /dev/null @@ -1,59 +0,0 @@ -# Copyright The IETF Trust 2019-2020, All Rights Reserved -# -*- coding: utf-8 -*- -# Generated by Django 1.11.23 on 2019-08-07 12:07 - - -from django.db import migrations - -def forward(apps, schema_editor): - StateType = apps.get_model('doc','StateType') - State = apps.get_model('doc','State') - - StateType.objects.create(slug='draft-iana-experts',label='IANA Experts State') - State.objects.create(type_id='draft-iana-experts', - slug='need-experts', - name='Need IANA Expert(s)', - used=True, - desc='One or more registries need experts assigned', - order=0 - ) - State.objects.create(type_id='draft-iana-experts', - slug='reviews-assigned', - name='Reviews assigned', - used=True, - desc='One or more expert reviews have been assigned', - order=1 - ) - State.objects.create(type_id='draft-iana-experts', - slug='expert-issues', - name='Issues identified', - used=True, - desc='Some expert reviewers have identified issues', - order=2 - ) - State.objects.create(type_id='draft-iana-experts', - slug='reviewers-ok', - name='Expert Reviews OK', - used=True, - desc='All expert reviews have been completed with no blocking issues', - order=2 - ) - -def reverse(apps, schema_editor): - StateType = apps.get_model('doc','StateType') - State = apps.get_model('doc','State') - - State.objects.filter(type_id='draft-iana-experts', slug__in=('need-experts','reviews-assigned','reviews-complete')).delete() - StateType.objects.filter(slug='draft-iana-experts').delete() - - - -class Migration(migrations.Migration): - - dependencies = [ - ('doc', '0023_one_to_many_docalias'), - ] - - operations = [ - migrations.RunPython(forward, reverse) - ] diff --git a/ietf/doc/migrations/0024_remove_ad_is_watching_states.py b/ietf/doc/migrations/0024_remove_ad_is_watching_states.py new file mode 100644 index 00000000000..0c0fb0ad25c --- /dev/null +++ b/ietf/doc/migrations/0024_remove_ad_is_watching_states.py @@ -0,0 +1,121 @@ +# Copyright The IETF Trust 2024, All Rights Reserved + +from django.db import migrations + + +def get_helper(DocHistory, RelatedDocument, RelatedDocHistory, DocumentAuthor, DocHistoryAuthor): + """Dependency injection wrapper""" + + def save_document_in_history(doc): + """Save a snapshot of document and related objects in the database. + + Local copy of ietf.doc.utils.save_document_in_history() to avoid depending on the + code base in a migration. + """ + + def get_model_fields_as_dict(obj): + return dict((field.name, getattr(obj, field.name)) + for field in obj._meta.fields + if field is not obj._meta.pk) + + # copy fields + fields = get_model_fields_as_dict(doc) + fields["doc"] = doc + fields["name"] = doc.name + + dochist = DocHistory(**fields) + dochist.save() + + # copy many to many + for field in doc._meta.many_to_many: + if field.remote_field.through and field.remote_field.through._meta.auto_created: + hist_field = getattr(dochist, field.name) + hist_field.clear() + hist_field.set(getattr(doc, field.name).all()) + + # copy remaining tricky many to many + def transfer_fields(obj, HistModel): + mfields = get_model_fields_as_dict(item) + # map doc -> dochist + for k, v in mfields.items(): + if v == doc: + mfields[k] = dochist + HistModel.objects.create(**mfields) + + for item in RelatedDocument.objects.filter(source=doc): + transfer_fields(item, RelatedDocHistory) + + for item in DocumentAuthor.objects.filter(document=doc): + transfer_fields(item, DocHistoryAuthor) + + return dochist + + return save_document_in_history + + +def forward(apps, schema_editor): + """Mark watching draft-iesg state unused after removing it from Documents""" + StateDocEvent = apps.get_model("doc", "StateDocEvent") + Document = apps.get_model("doc", "Document") + State = apps.get_model("doc", "State") + StateType = apps.get_model("doc", "StateType") + Person = apps.get_model("person", "Person") + + save_document_in_history = get_helper( + DocHistory=apps.get_model("doc", "DocHistory"), + RelatedDocument=apps.get_model("doc", "RelatedDocument"), + RelatedDocHistory=apps.get_model("doc", "RelatedDocHistory"), + DocumentAuthor=apps.get_model("doc", "DocumentAuthor"), + DocHistoryAuthor=apps.get_model("doc", "DocHistoryAuthor"), + ) + + draft_iesg_state_type = StateType.objects.get(slug="draft-iesg") + idexists_state = State.objects.get(type=draft_iesg_state_type, slug="idexists") + watching_state = State.objects.get(type=draft_iesg_state_type, slug="watching") + system_person = Person.objects.get(name="(System)") + + # Remove state from documents that currently have it + for doc in Document.objects.filter(states=watching_state): + assert doc.type_id == "draft" + doc.states.remove(watching_state) + doc.states.add(idexists_state) + e = StateDocEvent.objects.create( + type="changed_state", + by=system_person, + doc=doc, + rev=doc.rev, + desc=f"{draft_iesg_state_type.label} changed to {idexists_state.name} from {watching_state.name}", + state_type=draft_iesg_state_type, + state=idexists_state, + ) + doc.time = e.time + doc.save() + save_document_in_history(doc) + assert not Document.objects.filter(states=watching_state).exists() + + # Mark state as unused + watching_state.used = False + watching_state.save() + + +def reverse(apps, schema_editor): + """Mark watching draft-iesg state as used + + Does not try to re-apply the state to Documents modified by the forward migration. This + could be done in theory, but would either require dangerous history rewriting or add a + lot of history junk. + """ + State = apps.get_model("doc", "State") + StateType = apps.get_model("doc", "StateType") + State.objects.filter( + type=StateType.objects.get(slug="draft-iesg"), slug="watching" + ).update(used=True) + + +class Migration(migrations.Migration): + + dependencies = [ + ("doc", "0023_bofreqspamstate"), + ] + + operations = [migrations.RunPython(forward, reverse)] diff --git a/ietf/doc/migrations/0025_ianaexpertdocevent.py b/ietf/doc/migrations/0025_ianaexpertdocevent.py deleted file mode 100644 index 282d506d9ca..00000000000 --- a/ietf/doc/migrations/0025_ianaexpertdocevent.py +++ /dev/null @@ -1,24 +0,0 @@ -# Copyright The IETF Trust 2019-2020, All Rights Reserved -# -*- coding: utf-8 -*- -# Generated by Django 1.11.23 on 2019-08-07 12:27 - - -from django.db import migrations, models -import django.db.models.deletion - - -class Migration(migrations.Migration): - - dependencies = [ - ('doc', '0024_iana_experts'), - ] - - operations = [ - migrations.CreateModel( - name='IanaExpertDocEvent', - fields=[ - ('docevent_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='doc.DocEvent')), - ], - bases=('doc.docevent',), - ), - ] diff --git a/ietf/doc/migrations/0025_storedobject_storedobject_unique_name_per_store.py b/ietf/doc/migrations/0025_storedobject_storedobject_unique_name_per_store.py new file mode 100644 index 00000000000..e948ca30113 --- /dev/null +++ b/ietf/doc/migrations/0025_storedobject_storedobject_unique_name_per_store.py @@ -0,0 +1,66 @@ +# Copyright The IETF Trust 2025, All Rights Reserved + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("doc", "0024_remove_ad_is_watching_states"), + ] + + operations = [ + migrations.CreateModel( + name="StoredObject", + fields=[ + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("store", models.CharField(max_length=256)), + ("name", models.CharField(max_length=1024)), + ("sha384", models.CharField(max_length=96)), + ("len", models.PositiveBigIntegerField()), + ( + "store_created", + models.DateTimeField( + help_text="The instant the object ws first placed in the store" + ), + ), + ( + "created", + models.DateTimeField( + help_text="Instant object became known. May not be the same as the storage's created value for the instance. It will hold ctime for objects imported from older disk storage" + ), + ), + ( + "modified", + models.DateTimeField( + help_text="Last instant object was modified. May not be the same as the storage's modified value for the instance. It will hold mtime for objects imported from older disk storage unless they've actually been overwritten more recently" + ), + ), + ("doc_name", models.CharField(blank=True, max_length=255, null=True)), + ("doc_rev", models.CharField(blank=True, max_length=16, null=True)), + ("deleted", models.DateTimeField(null=True)), + ], + options={ + "indexes": [ + models.Index( + fields=["doc_name", "doc_rev"], + name="doc_storedo_doc_nam_d04465_idx", + ) + ], + }, + ), + migrations.AddConstraint( + model_name="storedobject", + constraint=models.UniqueConstraint( + fields=("store", "name"), name="unique_name_per_store" + ), + ), + ] diff --git a/ietf/doc/migrations/0026_add_draft_rfceditor_state.py b/ietf/doc/migrations/0026_add_draft_rfceditor_state.py deleted file mode 100644 index 0490f15ba93..00000000000 --- a/ietf/doc/migrations/0026_add_draft_rfceditor_state.py +++ /dev/null @@ -1,24 +0,0 @@ -# Copyright The IETF Trust 2019-2020, All Rights Reserved -# -*- coding: utf-8 -*- - - -from django.db import migrations - -def forward(apps, schema_editor): - State = apps.get_model('doc','State') - State.objects.get_or_create(type_id='draft-rfceditor', slug='tooling-issue', name='TI', - desc='Tooling Issue; an update is needed to one or more of the tools in the publication pipeline before this document can be published') - -def reverse(apps, schema_editor): - State = apps.get_model('doc','State') - State.objects.filter(type_id='draft-rfceditor', slug='tooling-issue').delete() - -class Migration(migrations.Migration): - - dependencies = [ - ('doc', '0025_ianaexpertdocevent'), - ] - - operations = [ - migrations.RunPython(forward,reverse) - ] diff --git a/ietf/doc/migrations/0026_change_wg_state_descriptions.py b/ietf/doc/migrations/0026_change_wg_state_descriptions.py new file mode 100644 index 00000000000..b02b12c97e4 --- /dev/null +++ b/ietf/doc/migrations/0026_change_wg_state_descriptions.py @@ -0,0 +1,117 @@ +# Copyright The IETF Trust 2025, All Rights Reserved + +from django.db import migrations + +def forward(apps, schema_editor): + State = apps.get_model("doc","State") + for name, desc in [ + ("WG Document","The document has been adopted by the Working Group (WG) and is under development. A document can only be adopted by one WG at a time. However, a document may be transferred between WGs."), + ("Parked WG Document","The Working Group (WG) document is in a temporary state where it will not be actively developed. The reason for the pause is explained via a datatracker comments section."), + ("Dead WG Document","The Working Group (WG) document has been abandoned by the WG. No further development is planned in this WG. A decision to resume work on this document and move it out of this state is possible."), + ("In WG Last Call","The Working Group (WG) document is currently subject to an active WG Last Call (WGLC) review per Section 7.4 of RFC2418."), + ("Waiting for Implementation","The progression of this Working Group (WG) document towards publication is paused as it awaits implementation. The process governing the approach to implementations is WG-specific."), + ("Held by WG","Held by Working Group (WG) chairs for administrative reasons. See document history for details."), + ("Waiting for WG Chair Go-Ahead","The Working Group (WG) document has completed Working Group Last Call (WGLC), but the WG chair(s) are not yet ready to call consensus on the document. The reasons for this may include comments from the WGLC need to be responded to, or a revision to the document is needed"), + ("WG Consensus: Waiting for Write-Up","The Working Group (WG) document has consensus to proceed to publication. However, the document is waiting for a document shepherd write-up per RFC4858."), + ("Submitted to IESG for Publication","The Working Group (WG) document has left the WG and been submitted to the Internet Engineering Steering Group (IESG) for evaluation and publication. See the “IESG State” or “RFC Editor State” for further details on the state of the document."), + ("Candidate for WG Adoption","The individual submission document has been marked by the Working Group (WG) chairs as a candidate for adoption by the WG, but no adoption call has been started."), + ("Call For Adoption By WG Issued","A call for adoption of the individual submission document has been issued by the Working Group (WG) chairs. This call is still running but the WG has not yet reached consensus for adoption."), + ("Adopted by a WG","The individual submission document has been adopted by the Working Group (WG), but a WG document replacing this document with the typical naming convention of 'draft- ietf-wgname-topic-nn' has not yet been submitted."), + ("Adopted for WG Info Only","The document is adopted by the Working Group (WG) for its internal use. The WG has decided that it will not pursue publication of it as an RFC."), + ]: + State.objects.filter(name=name).update(desc=desc) + +def reverse(apps, schema_editor): + State = apps.get_model("doc","State") + for name, desc in [ + ("WG Document","""4.2.4. WG Document + + The "WG Document" state describes an I-D that has been adopted by an IETF WG and is being actively developed. + + A WG Chair may transition an I-D into the "WG Document" state at any time as long as the I-D is not being considered or developed in any other WG. + + Alternatively, WG Chairs may rely upon new functionality to be added to the Datatracker to automatically move version-00 drafts into the "WG Document" state as described in Section 4.1. + + Under normal conditions, it should not be possible for an I-D to be in the "WG Document" state in more than one WG at a time. This said, I-Ds may be transferred from one WG to another with the consent of the WG Chairs and the responsible ADs."""), + ("Parked WG Document","""4.2.5. Parked WG Document + + A "Parked WG Document" is an I-D that has lost its author or editor, is waiting for another document to be written or for a review to be completed, or cannot be progressed by the working group for some other reason. + + Some of the annotation tags described in Section 4.3 may be used in conjunction with this state to indicate why an I-D has been parked, and/or what may need to happen for the I-D to be un-parked. + + Parking a WG draft will not prevent it from expiring; however, this state can be used to indicate why the I-D has stopped progressing in the WG. + + A "Parked WG Document" that is not expired may be transferred from one WG to another with the consent of the WG Chairs and the responsible ADs."""), + ("Dead WG Document","""4.2.6. Dead WG Document + + A "Dead WG Document" is an I-D that has been abandoned. Note that 'Dead' is not always a final state for a WG I-D. If consensus is subsequently achieved, a "Dead WG Document" may be resurrected. A "Dead WG Document" that is not resurrected will eventually expire. + + Note that an I-D that is declared to be "Dead" in one WG and that is not expired may be transferred to a non-dead state in another WG with the consent of the WG Chairs and the responsible ADs."""), + ("In WG Last Call","""4.2.7. In WG Last Call + + A document "In WG Last Call" is an I-D for which a WG Last Call (WGLC) has been issued and is in progress. + + Note that conducting a WGLC is an optional part of the IETF WG process, per Section 7.4 of RFC 2418 [RFC2418]. + + If a WG Chair decides to conduct a WGLC on an I-D, the "In WG Last Call" state can be used to track the progress of the WGLC. The Chair may configure the Datatracker to send a WGLC message to one or more mailing lists when the Chair moves the I-D into this state. The WG Chair may also be able to select a different set of mailing lists for a different document undergoing a WGLC; some documents may deserve coordination with other WGs. + + A WG I-D in this state should remain "In WG Last Call" until the WG Chair moves it to another state. The WG Chair may configure the Datatracker to send an e-mail after a specified period of time to remind or 'nudge' the Chair to conclude the WGLC and to determine the next state for the document. + + It is possible for one WGLC to lead into another WGLC for the same document. For example, an I-D that completed a WGLC as an "Informational" document may need another WGLC if a decision is taken to convert the I-D into a Standards Track document."""), + ("Waiting for Implementation","""In some areas, it can be desirable to wait for multiple interoperable implementations before progressing a draft to be an RFC, and in some WGs this is required. This state should be entered after WG Last Call has completed."""), + ("Held by WG","""Held by WG, see document history for details."""), + ("Waiting for WG Chair Go-Ahead","""4.2.8. Waiting for WG Chair Go-Ahead + + A WG Chair may wish to place an I-D that receives a lot of comments during a WGLC into the "Waiting for WG Chair Go-Ahead" state. This state describes an I-D that has undergone a WGLC; however, the Chair is not yet ready to call consensus on the document. + + If comments from the WGLC need to be responded to, or a revision to the I-D is needed, the Chair may place an I-D into this state until all of the WGLC comments are adequately addressed and the (possibly revised) document is in the I-D repository."""), + ("WG Consensus: Waiting for Write-Up","""4.2.9. WG Consensus: Waiting for Writeup + + A document in the "WG Consensus: Waiting for Writeup" state has essentially completed its development within the working group, and is nearly ready to be sent to the IESG for publication. The last thing to be done is the preparation of a protocol writeup by a Document Shepherd. The IESG requires that a document shepherd writeup be completed before publication of the I-D is requested. The IETF document shepherding process and the role of a WG Document Shepherd is described in RFC 4858 [RFC4858] + + A WG Chair may call consensus on an I-D without a formal WGLC and transition an I-D that was in the "WG Document" state directly into this state. + + The name of this state includes the words "Waiting for Writeup" because a good document shepherd writeup takes time to prepare."""), + ("Submitted to IESG for Publication","""4.2.10. Submitted to IESG for Publication + + This state describes a WG document that has been submitted to the IESG for publication and that has not been sent back to the working group for revision. + + An I-D in this state may be under review by the IESG, it may have been approved and be in the RFC Editor's queue, or it may have been published as an RFC. Other possibilities exist too. The document may be "Dead" (in the IESG state machine) or in a "Do Not Publish" state."""), + ("Candidate for WG Adoption","""The document has been marked as a candidate for WG adoption by the WG Chair. This state can be used before a call for adoption is issued (and the document is put in the "Call For Adoption By WG Issued" state), to indicate that the document is in the queue for a call for adoption, even if none has been issued yet."""), + ("Call For Adoption By WG Issued","""4.2.1. Call for Adoption by WG Issued + + The "Call for Adoption by WG Issued" state should be used to indicate when an I-D is being considered for adoption by an IETF WG. An I-D that is in this state is actively being considered for adoption and has not yet achieved consensus, preference, or selection in the WG. + + This state may be used to describe an I-D that someone has asked a WG to consider for adoption, if the WG Chair has agreed with the request. This state may also be used to identify an I-D that a WG Chair asked an author to write specifically for consideration as a candidate WG item [WGDTSPEC], and/or an I-D that is listed as a 'candidate draft' in the WG's charter. + + Under normal conditions, it should not be possible for an I-D to be in the "Call for Adoption by WG Issued" state in more than one working group at the same time. This said, it is not uncommon for authors to "shop" their I-Ds to more than one WG at a time, with the hope of getting their documents adopted somewhere. + + After this state is implemented in the Datatracker, an I-D that is in the "Call for Adoption by WG Issued" state will not be able to be "shopped" to any other WG without the consent of the WG Chairs and the responsible ADs impacted by the shopping. + + Note that Figure 1 includes an arc leading from this state to outside of the WG state machine. This illustrates that some I-Ds that are considered do not get adopted as WG drafts. An I-D that is not adopted as a WG draft will transition out of the WG state machine and revert back to having no stream-specific state; however, the status change history log of the I-D will record that the I-D was previously in the "Call for Adoption by WG Issued" state."""), + ("Adopted by a WG","""4.2.2. Adopted by a WG + + The "Adopted by a WG" state describes an individual submission I-D that an IETF WG has agreed to adopt as one of its WG drafts. + + WG Chairs who use this state will be able to clearly indicate when their WGs adopt individual submission I-Ds. This will facilitate the Datatracker's ability to correctly capture "Replaces" information for WG drafts and correct "Replaced by" information for individual submission I-Ds that have been replaced by WG drafts. + + This state is needed because the Datatracker uses the filename of an I-D as a key to search its database for status information about the I-D, and because the filename of a WG I-D is supposed to be different from the filename of an individual submission I-D. The filename of an individual submission I-D will typically be formatted as 'draft-author-wgname-topic-nn'. + + The filename of a WG document is supposed to be formatted as 'draft- ietf-wgname-topic-nn'. + + An individual I-D that is adopted by a WG may take weeks or months to be resubmitted by the author as a new (version-00) WG draft. If the "Adopted by a WG" state is not used, the Datatracker has no way to determine that an I-D has been adopted until a new version of the I-D is submitted to the WG by the author and until the I-D is approved for posting by a WG Chair."""), + ("Adopted for WG Info Only","""4.2.3. Adopted for WG Info Only + + The "Adopted for WG Info Only" state describes a document that contains useful information for the WG that adopted it, but the document is not intended to be published as an RFC. The WG will not actively develop the contents of the I-D or progress it for publication as an RFC. The only purpose of the I-D is to provide information for internal use by the WG."""), + ]: + State.objects.filter(name=name).update(desc=desc) + +class Migration(migrations.Migration): + + dependencies = [ + ("doc", "0025_storedobject_storedobject_unique_name_per_store"), + ] + + operations = [ + migrations.RunPython(forward, reverse) + ] diff --git a/ietf/doc/migrations/0027_add_irsg_doc_positions.py b/ietf/doc/migrations/0027_add_irsg_doc_positions.py deleted file mode 100644 index e88ac9dda76..00000000000 --- a/ietf/doc/migrations/0027_add_irsg_doc_positions.py +++ /dev/null @@ -1,62 +0,0 @@ -# Copyright The IETF Trust 2019-2020, All Rights Reserved -# -*- coding: utf-8 -*- -# Generated by Django 1.11.22 on 2019-08-03 10:09 - - -from django.db import migrations - -# forward, reverse initially copied from migration 0004 -def forward(apps, schema_editor): - State = apps.get_model('doc','State') - State.objects.create(type_id='draft-stream-irtf', - slug='irsg_review', - name='IRSG Review', - desc='IRSG Review', - used=True, - ) - BallotPositionName = apps.get_model('name','BallotPositionName') - # desc, used, order, and blocking all have suitable defaults - BallotPositionName.objects.create(slug="moretime", - name="Need More Time", - ) - BallotPositionName.objects.create(slug="notready", - name="Not Ready", - ) - - # Create a new ballot type for IRSG ballot - # include positions for the ballot type - BallotType = apps.get_model('doc','BallotType') - bt = BallotType.objects.create(doc_type_id="draft", - slug="irsg-approve", - name="IRSG Approve", - question="Is this draft ready for publication in the IRTF stream?", - ) - bt.positions.set(['yes','noobj','recuse','notready','moretime']) - -def reverse(apps, schema_editor): - State = apps.get_model('doc','State') - State.objects.filter(type_id__in=('draft-stream-irtf',), slug='irsg_review').delete() - - Position = apps.get_model('name','BallotPositionName') - for pos in ("moretime", "notready"): - Position.objects.filter(slug=pos).delete() - - IRSGBallot = apps.get_model('doc','BallotType') - IRSGBallot.objects.filter(slug="irsg-approve").delete() - -class Migration(migrations.Migration): - - dependencies = [ - ('doc', '0026_add_draft_rfceditor_state'), - ('name', '0007_fix_m2m_slug_id_length'), - ] - - operations = [ - migrations.RunPython(forward,reverse), - migrations.RenameField( - model_name='ballotpositiondocevent', - old_name='ad', - new_name='balloter', - ), - - ] diff --git a/ietf/doc/migrations/0027_alter_dochistory_title_alter_document_title.py b/ietf/doc/migrations/0027_alter_dochistory_title_alter_document_title.py new file mode 100644 index 00000000000..e0d8560e6f9 --- /dev/null +++ b/ietf/doc/migrations/0027_alter_dochistory_title_alter_document_title.py @@ -0,0 +1,41 @@ +# Copyright The IETF Trust 2025, All Rights Reserved + +import django.core.validators +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("doc", "0026_change_wg_state_descriptions"), + ] + + operations = [ + migrations.AlterField( + model_name="dochistory", + name="title", + field=models.CharField( + max_length=255, + validators=[ + django.core.validators.ProhibitNullCharactersValidator, # type:ignore + django.core.validators.RegexValidator( + message="Please enter a string without control characters.", + regex="^[^\x01-\x1f]*$", + ), + ], + ), + ), + migrations.AlterField( + model_name="document", + name="title", + field=models.CharField( + max_length=255, + validators=[ + django.core.validators.ProhibitNullCharactersValidator, # type:ignore + django.core.validators.RegexValidator( + message="Please enter a string without control characters.", + regex="^[^\x01-\x1f]*$", + ), + ], + ), + ), + ] diff --git a/ietf/doc/migrations/0028_irsgballotdocevent.py b/ietf/doc/migrations/0028_irsgballotdocevent.py deleted file mode 100644 index 92f4d52d735..00000000000 --- a/ietf/doc/migrations/0028_irsgballotdocevent.py +++ /dev/null @@ -1,25 +0,0 @@ -# Copyright The IETF Trust 2019-2020, All Rights Reserved -# -*- coding: utf-8 -*- -# Generated by Django 1.11.25 on 2019-10-10 10:37 - - -from django.db import migrations, models -import django.db.models.deletion - - -class Migration(migrations.Migration): - - dependencies = [ - ('doc', '0027_add_irsg_doc_positions'), - ] - - operations = [ - migrations.CreateModel( - name='IRSGBallotDocEvent', - fields=[ - ('ballotdocevent_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='doc.BallotDocEvent')), - ('duedate', models.DateTimeField(blank=True, null=True)), - ], - bases=('doc.ballotdocevent',), - ), - ] diff --git a/ietf/doc/migrations/0028_rfcauthor.py b/ietf/doc/migrations/0028_rfcauthor.py new file mode 100644 index 00000000000..776dc22eb10 --- /dev/null +++ b/ietf/doc/migrations/0028_rfcauthor.py @@ -0,0 +1,84 @@ +# Copyright The IETF Trust 2025, All Rights Reserved + +from django.db import migrations, models +import django.db.models.deletion +import ietf.utils.models + + +class Migration(migrations.Migration): + dependencies = [ + ("person", "0005_alter_historicalperson_pronouns_selectable_and_more"), + ("doc", "0027_alter_dochistory_title_alter_document_title"), + ] + + operations = [ + migrations.CreateModel( + name="RfcAuthor", + fields=[ + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("titlepage_name", models.CharField(max_length=128)), + ("is_editor", models.BooleanField(default=False)), + ( + "affiliation", + models.CharField( + blank=True, + help_text="Organization/company used by author for submission", + max_length=100, + ), + ), + ( + "country", + models.CharField( + blank=True, + help_text="Country used by author for submission", + max_length=255, + ), + ), + ("order", models.IntegerField(default=1)), + ( + "document", + ietf.utils.models.ForeignKey( + limit_choices_to={"type_id": "rfc"}, + on_delete=django.db.models.deletion.CASCADE, + to="doc.document", + ), + ), + ( + "email", + ietf.utils.models.ForeignKey( + blank=True, + help_text="Email address used by author for submission", + null=True, + on_delete=django.db.models.deletion.PROTECT, + to="person.email", + ), + ), + ( + "person", + ietf.utils.models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.PROTECT, + to="person.person", + ), + ), + ], + options={ + "ordering": ["document", "order"], + "indexes": [ + models.Index( + fields=["document", "order"], + name="doc_rfcauth_documen_6b5dc4_idx", + ) + ], + }, + ), + ] diff --git a/ietf/doc/migrations/0029_add_ipr_event_types.py b/ietf/doc/migrations/0029_add_ipr_event_types.py deleted file mode 100644 index 08073b16e80..00000000000 --- a/ietf/doc/migrations/0029_add_ipr_event_types.py +++ /dev/null @@ -1,21 +0,0 @@ -# Copyright The IETF Trust 2020, All Rights Reserved -# -*- coding: utf-8 -*- -# Generated by Django 1.11.27 on 2020-01-17 11:54 - - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('doc', '0028_irsgballotdocevent'), - ] - - operations = [ - migrations.AlterField( - model_name='docevent', - name='type', - field=models.CharField(choices=[('new_revision', 'Added new revision'), ('new_submission', 'Uploaded new revision'), ('changed_document', 'Changed document metadata'), ('added_comment', 'Added comment'), ('added_message', 'Added message'), ('edited_authors', 'Edited the documents author list'), ('deleted', 'Deleted document'), ('changed_state', 'Changed state'), ('changed_stream', 'Changed document stream'), ('expired_document', 'Expired document'), ('extended_expiry', 'Extended expiry of document'), ('requested_resurrect', 'Requested resurrect'), ('completed_resurrect', 'Completed resurrect'), ('changed_consensus', 'Changed consensus'), ('published_rfc', 'Published RFC'), ('added_suggested_replaces', 'Added suggested replacement relationships'), ('reviewed_suggested_replaces', 'Reviewed suggested replacement relationships'), ('changed_group', 'Changed group'), ('changed_protocol_writeup', 'Changed protocol writeup'), ('changed_charter_milestone', 'Changed charter milestone'), ('initial_review', 'Set initial review time'), ('changed_review_announcement', 'Changed WG Review text'), ('changed_action_announcement', 'Changed WG Action text'), ('started_iesg_process', 'Started IESG process on document'), ('created_ballot', 'Created ballot'), ('closed_ballot', 'Closed ballot'), ('sent_ballot_announcement', 'Sent ballot announcement'), ('changed_ballot_position', 'Changed ballot position'), ('changed_ballot_approval_text', 'Changed ballot approval text'), ('changed_ballot_writeup_text', 'Changed ballot writeup text'), ('changed_rfc_editor_note_text', 'Changed RFC Editor Note text'), ('changed_last_call_text', 'Changed last call text'), ('requested_last_call', 'Requested last call'), ('sent_last_call', 'Sent last call'), ('scheduled_for_telechat', 'Scheduled for telechat'), ('iesg_approved', 'IESG approved document (no problem)'), ('iesg_disapproved', 'IESG disapproved document (do not publish)'), ('approved_in_minute', 'Approved in minute'), ('iana_review', 'IANA review comment'), ('rfc_in_iana_registry', 'RFC is in IANA registry'), ('rfc_editor_received_announcement', 'Announcement was received by RFC Editor'), ('requested_publication', 'Publication at RFC Editor requested'), ('sync_from_rfc_editor', 'Received updated information from RFC Editor'), ('requested_review', 'Requested review'), ('assigned_review_request', 'Assigned review request'), ('closed_review_request', 'Closed review request'), ('closed_review_assignment', 'Closed review assignment'), ('downref_approved', 'Downref approved'), ('posted_related_ipr', 'Posted related IPR'), ('removed_related_ipr', 'Removed related IPR')], max_length=50), - ), - ] diff --git a/ietf/doc/migrations/0029_editedrfcauthorsdocevent.py b/ietf/doc/migrations/0029_editedrfcauthorsdocevent.py new file mode 100644 index 00000000000..60837c5cb2d --- /dev/null +++ b/ietf/doc/migrations/0029_editedrfcauthorsdocevent.py @@ -0,0 +1,30 @@ +# Copyright The IETF Trust 2025, All Rights Reserved + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + dependencies = [ + ("doc", "0028_rfcauthor"), + ] + + operations = [ + migrations.CreateModel( + name="EditedRfcAuthorsDocEvent", + fields=[ + ( + "docevent_ptr", + models.OneToOneField( + auto_created=True, + on_delete=django.db.models.deletion.CASCADE, + parent_link=True, + primary_key=True, + serialize=False, + to="doc.docevent", + ), + ), + ], + bases=("doc.docevent",), + ), + ] diff --git a/ietf/doc/migrations/0030_alter_dochistory_title_alter_document_title.py b/ietf/doc/migrations/0030_alter_dochistory_title_alter_document_title.py new file mode 100644 index 00000000000..9ee858b2e8d --- /dev/null +++ b/ietf/doc/migrations/0030_alter_dochistory_title_alter_document_title.py @@ -0,0 +1,41 @@ +# Copyright The IETF Trust 2026, All Rights Reserved + +import django.core.validators +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("doc", "0029_editedrfcauthorsdocevent"), + ] + + operations = [ + migrations.AlterField( + model_name="dochistory", + name="title", + field=models.CharField( + max_length=255, + validators=[ + django.core.validators.ProhibitNullCharactersValidator(), + django.core.validators.RegexValidator( + message="Please enter a string without control characters.", + regex="^[^\x01-\x1f]*$", + ), + ], + ), + ), + migrations.AlterField( + model_name="document", + name="title", + field=models.CharField( + max_length=255, + validators=[ + django.core.validators.ProhibitNullCharactersValidator(), + django.core.validators.RegexValidator( + message="Please enter a string without control characters.", + regex="^[^\x01-\x1f]*$", + ), + ], + ), + ), + ] diff --git a/ietf/doc/migrations/0030_fix_bytes_mailarch_url.py b/ietf/doc/migrations/0030_fix_bytes_mailarch_url.py deleted file mode 100644 index 3c3ad2aa6fb..00000000000 --- a/ietf/doc/migrations/0030_fix_bytes_mailarch_url.py +++ /dev/null @@ -1,37 +0,0 @@ -# Copyright The IETF Trust 2020, All Rights Reserved -# -*- coding: utf-8 -*- -# Generated by Django 1.11.20 on 2019-05-21 14:27 - - -from __future__ import absolute_import, print_function, unicode_literals - -import re - -from django.conf import settings -from django.db import migrations - - -def forward(apps, schema_editor): - - Document = apps.get_model('doc', 'Document') - - print('') - for d in Document.objects.filter(external_url__contains="/b'"): - match = re.search("^(%s/arch/msg/[^/]+/)b'([^']+)'$" % settings.MAILING_LIST_ARCHIVE_URL, d.external_url) - if match: - d.external_url = "%s%s" % (match.group(1), match.group(2)) - d.save() - print('Fixed url #%s: %s' % (d.id, d.external_url)) - -def reverse(apps, schema_editor): - pass - -class Migration(migrations.Migration): - - dependencies = [ - ('doc', '0029_add_ipr_event_types'), - ] - - operations = [ - migrations.RunPython(forward, reverse), - ] diff --git a/ietf/doc/migrations/0031_change_draft_stream_ietf_state_descriptions.py b/ietf/doc/migrations/0031_change_draft_stream_ietf_state_descriptions.py new file mode 100644 index 00000000000..c664126da32 --- /dev/null +++ b/ietf/doc/migrations/0031_change_draft_stream_ietf_state_descriptions.py @@ -0,0 +1,57 @@ +# Copyright The IETF Trust 2026, All Rights Reserved + +from django.db import migrations + + +def forward(apps, schema_editor): + State = apps.get_model("doc", "State") + for name, desc in [ + ( + "Adopted by a WG", + "The individual submission document has been adopted by the Working Group (WG), but some administrative matter still needs to be completed (e.g., a WG document replacing this document with the typical naming convention of 'draft-ietf-wgname-topic-nn' has not yet been submitted).", + ), + ( + "WG Document", + "The document has been identified as a Working Group (WG) document and is under development per Section 7.2 of RFC2418.", + ), + ( + "Waiting for WG Chair Go-Ahead", + "The Working Group (WG) document has completed Working Group Last Call (WGLC), but the WG chairs are not yet ready to call consensus on the document. The reasons for this may include comments from the WGLC need to be responded to, or a revision to the document is needed.", + ), + ( + "Submitted to IESG for Publication", + "The Working Group (WG) document has been submitted to the Internet Engineering Steering Group (IESG) for evaluation and publication per Section 7.4 of RFC2418. See the “IESG State” or “RFC Editor State” for further details on the state of the document.", + ), + ]: + State.objects.filter(name=name).update(desc=desc, type="draft-stream-ietf") + + +def reverse(apps, schema_editor): + State = apps.get_model("doc", "State") + for name, desc in [ + ( + "Adopted by a WG", + "The individual submission document has been adopted by the Working Group (WG), but a WG document replacing this document with the typical naming convention of 'draft- ietf-wgname-topic-nn' has not yet been submitted.", + ), + ( + "WG Document", + "The document has been adopted by the Working Group (WG) and is under development. A document can only be adopted by one WG at a time. However, a document may be transferred between WGs.", + ), + ( + "Waiting for WG Chair Go-Ahead", + "The Working Group (WG) document has completed Working Group Last Call (WGLC), but the WG chair(s) are not yet ready to call consensus on the document. The reasons for this may include comments from the WGLC need to be responded to, or a revision to the document is needed", + ), + ( + "Submitted to IESG for Publication", + "The Working Group (WG) document has left the WG and been submitted to the Internet Engineering Steering Group (IESG) for evaluation and publication. See the “IESG State” or “RFC Editor State” for further details on the state of the document.", + ), + ]: + State.objects.filter(name=name).update(desc=desc, type="draft-stream-ietf") + + +class Migration(migrations.Migration): + dependencies = [ + ("doc", "0030_alter_dochistory_title_alter_document_title"), + ] + + operations = [migrations.RunPython(forward, reverse)] diff --git a/ietf/doc/migrations/0031_set_state_for_charters_of_replaced_groups.py b/ietf/doc/migrations/0031_set_state_for_charters_of_replaced_groups.py deleted file mode 100644 index 1bf96f9a4d8..00000000000 --- a/ietf/doc/migrations/0031_set_state_for_charters_of_replaced_groups.py +++ /dev/null @@ -1,42 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright The IETF Trust 2020, All Rights Reserved -# Generated by Django 1.11.28 on 2020-03-03 13:54 -from __future__ import unicode_literals - -from django.db import migrations - -def forward(apps, schema_editor): - - Person = apps.get_model('person', 'Person') - - Document = apps.get_model('doc','Document') - State = apps.get_model('doc','State') - BallotDocEvent = apps.get_model('doc','BallotDocEvent') - - replaced_state = State.objects.create(type_id='charter', slug='replaced', name='Replaced', used=True, desc="This charter's group was replaced.", order = 0) - by = Person.objects.get(name='(System)') - - for doc in Document.objects.filter(type_id='charter',states__type_id='charter',states__slug__in=['intrev','extrev'],group__state='replaced'): - doc.states.remove(*list(doc.states.filter(type_id='charter'))) - doc.states.add(replaced_state) - ballot = BallotDocEvent.objects.filter(doc=doc, type__in=('created_ballot', 'closed_ballot')).order_by('-time', '-id').first() - if ballot and ballot.type == 'created_ballot': - e = BallotDocEvent(type="closed_ballot", doc=doc, rev=doc.rev, by=by) - e.ballot_type = ballot.ballot_type - e.desc = 'Closed "%s" ballot' % e.ballot_type.name - e.save() - - -def reverse(apps, schema_editor): - pass - -class Migration(migrations.Migration): - - dependencies = [ - ('doc', '0030_fix_bytes_mailarch_url'), - ('person', '0009_auto_20190118_0725'), - ] - - operations = [ - migrations.RunPython(forward, reverse), - ] diff --git a/ietf/doc/migrations/0032_auto_20200624_1332.py b/ietf/doc/migrations/0032_auto_20200624_1332.py deleted file mode 100644 index 1dd656a31f8..00000000000 --- a/ietf/doc/migrations/0032_auto_20200624_1332.py +++ /dev/null @@ -1,23 +0,0 @@ -# Generated by Django 2.1.15 on 2020-06-24 13:32 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('doc', '0031_set_state_for_charters_of_replaced_groups'), - ] - - operations = [ - migrations.AlterField( - model_name='ballotpositiondocevent', - name='send_email', - field=models.BooleanField(default=None, null=True), - ), - migrations.AlterField( - model_name='consensusdocevent', - name='consensus', - field=models.BooleanField(default=None, null=True), - ), - ] diff --git a/ietf/doc/migrations/0032_remove_rfcauthor_email.py b/ietf/doc/migrations/0032_remove_rfcauthor_email.py new file mode 100644 index 00000000000..a0e147da591 --- /dev/null +++ b/ietf/doc/migrations/0032_remove_rfcauthor_email.py @@ -0,0 +1,16 @@ +# Copyright The IETF Trust 2026, All Rights Reserved + +from django.db import migrations + + +class Migration(migrations.Migration): + dependencies = [ + ("doc", "0031_change_draft_stream_ietf_state_descriptions"), + ] + + operations = [ + migrations.RemoveField( + model_name="rfcauthor", + name="email", + ), + ] diff --git a/ietf/doc/migrations/0033_dochistory_keywords_document_keywords.py b/ietf/doc/migrations/0033_dochistory_keywords_document_keywords.py new file mode 100644 index 00000000000..5e2513e15a9 --- /dev/null +++ b/ietf/doc/migrations/0033_dochistory_keywords_document_keywords.py @@ -0,0 +1,31 @@ +# Copyright The IETF Trust 2026, All Rights Reserved + +from django.db import migrations, models +import ietf.doc.models + + +class Migration(migrations.Migration): + dependencies = [ + ("doc", "0032_remove_rfcauthor_email"), + ] + + operations = [ + migrations.AddField( + model_name="dochistory", + name="keywords", + field=models.JSONField( + default=list, + max_length=1000, + validators=[ietf.doc.models.validate_doc_keywords], + ), + ), + migrations.AddField( + model_name="document", + name="keywords", + field=models.JSONField( + default=list, + max_length=1000, + validators=[ietf.doc.models.validate_doc_keywords], + ), + ), + ] diff --git a/ietf/doc/migrations/0033_populate_auth48_urls.py b/ietf/doc/migrations/0033_populate_auth48_urls.py deleted file mode 100644 index d6092b630da..00000000000 --- a/ietf/doc/migrations/0033_populate_auth48_urls.py +++ /dev/null @@ -1,67 +0,0 @@ -# Copyright The IETF Trust 2020, All Rights Reserved -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - -from django.db import migrations -from django.db.models import OuterRef, Subquery - -from re import match - - -def forward(apps, schema_editor): - """Add DocumentURLs for docs in the Auth48 state - - Checks the latest StateDocEvent; if it is in the auth48 state and the - event desc has an AUTH48 link, creates an auth48 DocumentURL for that doc. - """ - Document = apps.get_model('doc', 'Document') - StateDocEvent = apps.get_model('doc', 'StateDocEvent') - DocumentURL = apps.get_model('doc', 'DocumentURL') - - # Regex - extracts auth48 URL as first match group - pattern = r'RFC Editor state changed to AUTH48.*.*' - - # To avoid 100k queries, set up a subquery to find the latest StateDocEvent for each doc... - latest_events = StateDocEvent.objects.filter(doc=OuterRef('pk')).order_by('-time', '-id') - # ... then annotate the doc list with that and select only those in the auth48 state... - auth48_docs = Document.objects.annotate( - current_state_slug=Subquery(latest_events.values('state__slug')[:1]) - ).filter(current_state_slug='auth48') - # ... and add an auth48 DocumentURL if one is found. - for doc in auth48_docs: - # Retrieve the full StateDocEvent. Results in a query per doc, but - # only for the few few in the auth48 state. - sde = StateDocEvent.objects.filter(doc=doc).order_by('-time', '-id').first() - urlmatch = match(pattern, sde.desc) # Auth48 URL is usually in the event desc - if urlmatch is not None: - DocumentURL.objects.create(doc=doc, tag_id='auth48', url=urlmatch[1]) - - # Validate the migration using a different approach to find auth48 docs. - # This is slower than above, but still avoids querying for every Document. - auth48_events = StateDocEvent.objects.filter(state__slug='auth48') - for a48_event in auth48_events: - doc = a48_event.doc - latest_sde = StateDocEvent.objects.filter(doc=doc).order_by('-time', '-id').first() - if latest_sde.state and latest_sde.state.slug == 'auth48' and match(pattern, latest_sde.desc) is not None: - # Currently in the auth48 state with a URL - assert doc.documenturl_set.filter(tag_id='auth48').count() == 1 - else: - # Either no longer in auth48 state or had no URL - assert doc.documenturl_set.filter(tag_id='auth48').count() == 0 - - -def reverse(apps, schema_editor): - """Remove any auth48 DocumentURLs - these did not exist before""" - DocumentURL = apps.get_model('doc', 'DocumentURL') - DocumentURL.objects.filter(tag_id='auth48').delete() - - -class Migration(migrations.Migration): - dependencies = [ - ('doc', '0032_auto_20200624_1332'), - ('name', '0013_add_auth48_docurltagname'), - ] - - operations = [ - migrations.RunPython(forward, reverse), - ] diff --git a/ietf/doc/migrations/0034_alter_dochistory_keywords_alter_document_keywords.py b/ietf/doc/migrations/0034_alter_dochistory_keywords_alter_document_keywords.py new file mode 100644 index 00000000000..2b89b67e88c --- /dev/null +++ b/ietf/doc/migrations/0034_alter_dochistory_keywords_alter_document_keywords.py @@ -0,0 +1,33 @@ +# Copyright The IETF Trust 2026, All Rights Reserved + +from django.db import migrations, models +import ietf.doc.models + + +class Migration(migrations.Migration): + dependencies = [ + ("doc", "0033_dochistory_keywords_document_keywords"), + ] + + operations = [ + migrations.AlterField( + model_name="dochistory", + name="keywords", + field=models.JSONField( + blank=True, + default=list, + max_length=1000, + validators=[ietf.doc.models.validate_doc_keywords], + ), + ), + migrations.AlterField( + model_name="document", + name="keywords", + field=models.JSONField( + blank=True, + default=list, + max_length=1000, + validators=[ietf.doc.models.validate_doc_keywords], + ), + ), + ] diff --git a/ietf/doc/migrations/0034_extres.py b/ietf/doc/migrations/0034_extres.py deleted file mode 100644 index 2157d0e8632..00000000000 --- a/ietf/doc/migrations/0034_extres.py +++ /dev/null @@ -1,28 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.11.29 on 2020-04-15 10:20 -from __future__ import unicode_literals - -from django.db import migrations, models -import django.db.models.deletion -import ietf.utils.models - - -class Migration(migrations.Migration): - - dependencies = [ - ('name', '0014_extres'), - ('doc', '0033_populate_auth48_urls'), - ] - - operations = [ - migrations.CreateModel( - name='DocExtResource', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('display_name', models.CharField(blank=True, default='', max_length=255)), - ('value', models.CharField(max_length=2083)), - ('doc', ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='doc.Document')), - ('name', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='name.ExtResourceName')), - ], - ), - ] diff --git a/ietf/doc/migrations/0035_add_rpc_queue_draft_rfceditor_states.py b/ietf/doc/migrations/0035_add_rpc_queue_draft_rfceditor_states.py new file mode 100644 index 00000000000..9805970ef0d --- /dev/null +++ b/ietf/doc/migrations/0035_add_rpc_queue_draft_rfceditor_states.py @@ -0,0 +1,31 @@ +# Copyright The IETF Trust 2026, All Rights Reserved + +from django.db import migrations + + +def forward(apps, schema_editor): + State = apps.get_model("doc", "State") + for slug, name in [("in_progress", "In Progress"), ("blocked", "Blocked")]: + State.objects.get_or_create( + type_id="draft-rfceditor", + slug=slug, + defaults={"name": name, "used": True, "desc": "", "order": 0}, + ) + + +def reverse(apps, schema_editor): + State = apps.get_model("doc", "State") + Document = apps.get_model("doc", "Document") + for slug in ("in_progress", "blocked"): + assert not Document.objects.filter( + states__type="draft-rfceditor", states__slug=slug + ).exists() + State.objects.filter(type_id="draft-rfceditor", slug=slug).delete() + + +class Migration(migrations.Migration): + dependencies = [ + ("doc", "0034_alter_dochistory_keywords_alter_document_keywords"), + ] + + operations = [migrations.RunPython(forward, reverse)] diff --git a/ietf/doc/migrations/0035_populate_docextresources.py b/ietf/doc/migrations/0035_populate_docextresources.py deleted file mode 100644 index 04b396a9636..00000000000 --- a/ietf/doc/migrations/0035_populate_docextresources.py +++ /dev/null @@ -1,125 +0,0 @@ -# Copyright The IETF Trust 2020, All Rights Reserved -# -*- coding: utf-8 -*- -# Generated by Django 1.11.29 on 2020-03-19 13:06 -from __future__ import unicode_literals - -import re - -import debug # pyflakes:ignore - -from collections import OrderedDict, Counter -from io import StringIO - -from django.db import migrations - -from ietf.utils.validators import validate_external_resource_value -from django.core.exceptions import ValidationError - - -name_map = { - "Issue.*": "tracker", - ".*FAQ.*": "faq", - ".*Area Web Page": "webpage", - ".*Wiki": "wiki", - "Home Page": "webpage", - "Slack.*": "slack", - "Additional .* Web Page": "webpage", - "Additional .* Page": "webpage", - "Yang catalog entry.*": "yc_entry", - "Yang impact analysis.*": "yc_impact", - "GitHub": "github_repo", - "Github page": "github_repo", - "GitHub repo.*": "github_repo", - "Github repository.*": "github_repo", - "GitHub org.*": "github_org", - "GitHub User.*": "github_username", - "GitLab User": "gitlab_username", - "GitLab User Name": "gitlab_username", -} - -url_map = OrderedDict({ - "https?://github\\.com": "github_repo", - "https://git.sr.ht/": "repo", - "https://todo.sr.ht/": "tracker", - "https?://trac\\.ietf\\.org/.*/wiki": "wiki", - "ietf\\.org.*/trac/wiki": "wiki", - "trac.*wiki": "wiki", - "www\\.ietf\\.org/mailman" : None, - "www\\.ietf\\.org/mail-archive" : None, - "mailarchive\\.ietf\\.org" : None, - "ietf\\.org/logs": "jabber_log", - "ietf\\.org/jabber/logs": "jabber_log", - "xmpp:.*?join": "jabber_room", - "bell-labs\\.com": None, - "html\\.charters": None, - "datatracker\\.ietf\\.org": None, -}) - -def forward(apps, schema_editor): - DocExtResource = apps.get_model('doc', 'DocExtResource') - ExtResourceName = apps.get_model('name', 'ExtResourceName') - DocumentUrl = apps.get_model('doc', 'DocumentUrl') - - stats = Counter() - stats_file = StringIO() - - for doc_url in DocumentUrl.objects.all(): - doc_url.url = doc_url.url.strip() - match_found = False - for regext,slug in name_map.items(): - if re.fullmatch(regext, doc_url.desc): - match_found = True - stats['mapped'] += 1 - name = ExtResourceName.objects.get(slug=slug) - try: - validate_external_resource_value(name, doc_url.url) - DocExtResource.objects.create(doc=doc_url.doc, name_id=slug, value=doc_url.url, display_name=doc_url.desc) - except ValidationError as e: # pyflakes:ignore - print("Failed validation:", doc_url.url, e, file=stats_file) - stats['failed_validation'] +=1 - break - if not match_found: - for regext, slug in url_map.items(): - if re.search(regext, doc_url.url): - match_found = True - if slug: - stats['mapped'] +=1 - name = ExtResourceName.objects.get(slug=slug) - # Munge the URL if it's the first github repo match - # Remove "/tree/master" substring if it exists - # Remove trailing "/issues" substring if it exists - # Remove "/blob/master/.*" pattern if present - if regext == "https?://github\\.com": - doc_url.url = doc_url.url.replace("/tree/master","") - doc_url.url = re.sub('/issues$', '', doc_url.url) - doc_url.url = re.sub('/blob/master.*$', '', doc_url.url) - try: - validate_external_resource_value(name, doc_url.url) - DocExtResource.objects.create(doc=doc_url.doc, name=name, value=doc_url.url, display_name=doc_url.desc) - except ValidationError as e: # pyflakes:ignore - print("Failed validation:", doc_url.url, e, file=stats_file) - stats['failed_validation'] +=1 - else: - stats['ignored'] +=1 - break - if not match_found: - print("Not Mapped:", doc_url.desc, doc_url.tag.slug, doc_url.doc.name, doc_url.url, file=stats_file) - stats['not_mapped'] += 1 - print('') - print(stats_file.getvalue()) - print (stats) - -def reverse(apps, schema_editor): - DocExtResource = apps.get_model('doc', 'DocExtResource') - DocExtResource.objects.all().delete() - -class Migration(migrations.Migration): - - dependencies = [ - ('doc', '0034_extres'), - ('name', '0015_populate_extres'), - ] - - operations = [ - migrations.RunPython(forward, reverse) - ] diff --git a/ietf/doc/migrations/0036_alter_docevent_type.py b/ietf/doc/migrations/0036_alter_docevent_type.py new file mode 100644 index 00000000000..1cc11d4ee96 --- /dev/null +++ b/ietf/doc/migrations/0036_alter_docevent_type.py @@ -0,0 +1,92 @@ +# Copyright The IETF Trust 2026, All Rights Reserved + +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("doc", "0035_add_rpc_queue_draft_rfceditor_states"), + ] + + operations = [ + migrations.AlterField( + model_name="docevent", + name="type", + field=models.CharField( + choices=[ + ("new_revision", "Added new revision"), + ("new_submission", "Uploaded new revision"), + ("changed_document", "Changed document metadata"), + ("added_comment", "Added comment"), + ("added_message", "Added message"), + ("edited_authors", "Edited the documents author list"), + ("deleted", "Deleted document"), + ("changed_state", "Changed state"), + ("changed_stream", "Changed document stream"), + ("expired_document", "Expired document"), + ("extended_expiry", "Extended expiry of document"), + ("requested_resurrect", "Requested resurrect"), + ("completed_resurrect", "Completed resurrect"), + ("changed_consensus", "Changed consensus"), + ("published_rfc", "Published RFC"), + ( + "added_suggested_replaces", + "Added suggested replacement relationships", + ), + ( + "reviewed_suggested_replaces", + "Reviewed suggested replacement relationships", + ), + ("changed_action_holders", "Changed action holders for document"), + ("changed_group", "Changed group"), + ("changed_protocol_writeup", "Changed protocol writeup"), + ("changed_charter_milestone", "Changed charter milestone"), + ("initial_review", "Set initial review time"), + ("changed_review_announcement", "Changed WG Review text"), + ("changed_action_announcement", "Changed WG Action text"), + ("started_iesg_process", "Started IESG process on document"), + ("created_ballot", "Created ballot"), + ("closed_ballot", "Closed ballot"), + ("sent_ballot_announcement", "Sent ballot announcement"), + ("changed_ballot_position", "Changed ballot position"), + ("changed_ballot_approval_text", "Changed ballot approval text"), + ("changed_ballot_writeup_text", "Changed ballot writeup text"), + ("changed_rfc_editor_note_text", "Changed RFC Editor Note text"), + ("changed_last_call_text", "Changed last call text"), + ("requested_last_call", "Requested last call"), + ("sent_last_call", "Sent last call"), + ("scheduled_for_telechat", "Scheduled for telechat"), + ("iesg_approved", "IESG approved document (no problem)"), + ("iesg_disapproved", "IESG disapproved document (do not publish)"), + ("approved_in_minute", "Approved in minute"), + ("iana_review", "IANA review comment"), + ("rfc_in_iana_registry", "RFC is in IANA registry"), + ( + "rfc_editor_received_announcement", + "Announcement was received by RFC Editor", + ), + ("requested_publication", "Publication at RFC Editor requested"), + ( + "sync_from_rfc_editor", + "Received updated information from RFC Editor", + ), + ("changed_rpc_assignments", "Changed RPC queue assignments"), + ("requested_review", "Requested review"), + ("assigned_review_request", "Assigned review request"), + ("closed_review_request", "Closed review request"), + ("closed_review_assignment", "Closed review assignment"), + ("downref_approved", "Downref approved"), + ("posted_related_ipr", "Posted related IPR"), + ("removed_related_ipr", "Removed related IPR"), + ( + "removed_objfalse_related_ipr", + "Removed Objectively False related IPR", + ), + ("changed_editors", "Changed BOF Request editors"), + ("published_statement", "Published statement"), + ("approved_slides", "Slides approved"), + ], + max_length=50, + ), + ), + ] diff --git a/ietf/doc/migrations/0036_orgs_vs_repos.py b/ietf/doc/migrations/0036_orgs_vs_repos.py deleted file mode 100644 index 37a0db0d26f..00000000000 --- a/ietf/doc/migrations/0036_orgs_vs_repos.py +++ /dev/null @@ -1,34 +0,0 @@ -# Copyright The IETF Trust 2020, All Rights Reserved - -from urllib.parse import urlparse -from django.db import migrations - -def categorize(url): - # This will categorize a few urls pointing into files in a repo as a repo, but that's better than calling them an org - element_count = len(urlparse(url).path.strip('/').split('/')) - if element_count < 1: - print("Bad github resource:",url) - return 'github_org' if element_count == 1 else 'github_repo' - -def forward(apps, schema_editor): - DocExtResource = apps.get_model('doc','DocExtResource') - - for resource in DocExtResource.objects.filter(name__slug__in=('github_org','github_repo')): - category = categorize(resource.value) - if resource.name_id != category: - resource.name_id = category - resource.save() - -def reverse(apps, schema_editor): - # Intentionally don't try to return to former worse state - pass - -class Migration(migrations.Migration): - - dependencies = [ - ('doc', '0035_populate_docextresources'), - ] - - operations = [ - migrations.RunPython(forward, reverse), - ] diff --git a/ietf/doc/migrations/0037_clean_up_missing_docaliases.py b/ietf/doc/migrations/0037_clean_up_missing_docaliases.py deleted file mode 100644 index 6ce350c3f8c..00000000000 --- a/ietf/doc/migrations/0037_clean_up_missing_docaliases.py +++ /dev/null @@ -1,29 +0,0 @@ -# Generated by Django 2.2.16 on 2020-09-22 07:58 - -from django.db import migrations - - -def forward(apps, schema_editor): - Document = apps.get_model('doc', 'Document') - DocAlias = apps.get_model('doc', 'DocAlias') - - docs_without_alias = Document.objects.filter(docalias__isnull=True) - - bad_aliases = DocAlias.objects.filter(name__in=docs_without_alias.values_list('name')) - bad_aliases.delete() - - for doc in docs_without_alias: - DocAlias.objects.create(name=doc.name).docs.add(doc) - -def reverse(apps, schema_editor): - pass - -class Migration(migrations.Migration): - - dependencies = [ - ('doc', '0036_orgs_vs_repos'), - ] - - operations = [ - migrations.RunPython(forward, reverse), - ] diff --git a/ietf/doc/migrations/0037_rpcassignmentdocevent.py b/ietf/doc/migrations/0037_rpcassignmentdocevent.py new file mode 100644 index 00000000000..648376e1188 --- /dev/null +++ b/ietf/doc/migrations/0037_rpcassignmentdocevent.py @@ -0,0 +1,31 @@ +# Copyright The IETF Trust 2026, All Rights Reserved + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + dependencies = [ + ("doc", "0036_alter_docevent_type"), + ] + + operations = [ + migrations.CreateModel( + name="RpcAssignmentDocEvent", + fields=[ + ( + "docevent_ptr", + models.OneToOneField( + auto_created=True, + on_delete=django.db.models.deletion.CASCADE, + parent_link=True, + primary_key=True, + serialize=False, + to="doc.docevent", + ), + ), + ("assignments", models.TextField(blank=True)), + ], + bases=("doc.docevent",), + ), + ] diff --git a/ietf/doc/migrations/0038_auto_20201109_0429.py b/ietf/doc/migrations/0038_auto_20201109_0429.py deleted file mode 100644 index 1335032b283..00000000000 --- a/ietf/doc/migrations/0038_auto_20201109_0429.py +++ /dev/null @@ -1,17 +0,0 @@ -# Generated by Django 2.2.17 on 2020-11-09 04:29 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('doc', '0037_clean_up_missing_docaliases'), - ] - - operations = [ - migrations.AddIndex( - model_name='docevent', - index=models.Index(fields=['-time', '-id'], name='doc_doceven_time_1a258f_idx'), - ), - ] diff --git a/ietf/doc/migrations/0039_auto_20201109_0439.py b/ietf/doc/migrations/0039_auto_20201109_0439.py deleted file mode 100644 index e6e3364568d..00000000000 --- a/ietf/doc/migrations/0039_auto_20201109_0439.py +++ /dev/null @@ -1,21 +0,0 @@ -# Generated by Django 2.2.17 on 2020-11-09 04:39 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('doc', '0038_auto_20201109_0429'), - ] - - operations = [ - migrations.AddIndex( - model_name='dochistoryauthor', - index=models.Index(fields=['document', 'order'], name='doc_dochist_documen_7e2441_idx'), - ), - migrations.AddIndex( - model_name='documentauthor', - index=models.Index(fields=['document', 'order'], name='doc_documen_documen_7fabe2_idx'), - ), - ] diff --git a/ietf/doc/migrations/0040_add_changed_action_holders_docevent_type.py b/ietf/doc/migrations/0040_add_changed_action_holders_docevent_type.py deleted file mode 100644 index 3aa12787129..00000000000 --- a/ietf/doc/migrations/0040_add_changed_action_holders_docevent_type.py +++ /dev/null @@ -1,19 +0,0 @@ -# Generated by Django 2.2.17 on 2021-01-15 12:50 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('group', '0040_lengthen_used_roles_fields'), # only needed for schema vs data ordering - ('doc', '0039_auto_20201109_0439'), - ] - - operations = [ - migrations.AlterField( - model_name='docevent', - name='type', - field=models.CharField(choices=[('new_revision', 'Added new revision'), ('new_submission', 'Uploaded new revision'), ('changed_document', 'Changed document metadata'), ('added_comment', 'Added comment'), ('added_message', 'Added message'), ('edited_authors', 'Edited the documents author list'), ('deleted', 'Deleted document'), ('changed_state', 'Changed state'), ('changed_stream', 'Changed document stream'), ('expired_document', 'Expired document'), ('extended_expiry', 'Extended expiry of document'), ('requested_resurrect', 'Requested resurrect'), ('completed_resurrect', 'Completed resurrect'), ('changed_consensus', 'Changed consensus'), ('published_rfc', 'Published RFC'), ('added_suggested_replaces', 'Added suggested replacement relationships'), ('reviewed_suggested_replaces', 'Reviewed suggested replacement relationships'), ('changed_action_holders', 'Changed action holders for document'), ('changed_group', 'Changed group'), ('changed_protocol_writeup', 'Changed protocol writeup'), ('changed_charter_milestone', 'Changed charter milestone'), ('initial_review', 'Set initial review time'), ('changed_review_announcement', 'Changed WG Review text'), ('changed_action_announcement', 'Changed WG Action text'), ('started_iesg_process', 'Started IESG process on document'), ('created_ballot', 'Created ballot'), ('closed_ballot', 'Closed ballot'), ('sent_ballot_announcement', 'Sent ballot announcement'), ('changed_ballot_position', 'Changed ballot position'), ('changed_ballot_approval_text', 'Changed ballot approval text'), ('changed_ballot_writeup_text', 'Changed ballot writeup text'), ('changed_rfc_editor_note_text', 'Changed RFC Editor Note text'), ('changed_last_call_text', 'Changed last call text'), ('requested_last_call', 'Requested last call'), ('sent_last_call', 'Sent last call'), ('scheduled_for_telechat', 'Scheduled for telechat'), ('iesg_approved', 'IESG approved document (no problem)'), ('iesg_disapproved', 'IESG disapproved document (do not publish)'), ('approved_in_minute', 'Approved in minute'), ('iana_review', 'IANA review comment'), ('rfc_in_iana_registry', 'RFC is in IANA registry'), ('rfc_editor_received_announcement', 'Announcement was received by RFC Editor'), ('requested_publication', 'Publication at RFC Editor requested'), ('sync_from_rfc_editor', 'Received updated information from RFC Editor'), ('requested_review', 'Requested review'), ('assigned_review_request', 'Assigned review request'), ('closed_review_request', 'Closed review request'), ('closed_review_assignment', 'Closed review assignment'), ('downref_approved', 'Downref approved'), ('posted_related_ipr', 'Posted related IPR'), ('removed_related_ipr', 'Removed related IPR')], max_length=50), - ), - ] diff --git a/ietf/doc/migrations/0041_add_documentactionholder.py b/ietf/doc/migrations/0041_add_documentactionholder.py deleted file mode 100644 index 3832a5603f5..00000000000 --- a/ietf/doc/migrations/0041_add_documentactionholder.py +++ /dev/null @@ -1,35 +0,0 @@ -# Generated by Django 2.2.17 on 2021-01-15 12:50 - -import datetime -from django.db import migrations, models -import django.db.models.deletion -import ietf.utils.models - - -class Migration(migrations.Migration): - - dependencies = [ - ('person', '0018_auto_20201109_0439'), - ('doc', '0040_add_changed_action_holders_docevent_type'), - ] - - operations = [ - migrations.CreateModel( - name='DocumentActionHolder', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('time_added', models.DateTimeField(default=datetime.datetime.now)), - ('document', ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='doc.Document')), - ('person', ietf.utils.models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='person.Person')), - ], - ), - migrations.AddField( - model_name='document', - name='action_holders', - field=models.ManyToManyField(blank=True, through='doc.DocumentActionHolder', to='person.Person'), - ), - migrations.AddConstraint( - model_name='documentactionholder', - constraint=models.UniqueConstraint(fields=('document', 'person'), name='unique_action_holder'), - ), - ] diff --git a/ietf/doc/migrations/0042_bofreq_states.py b/ietf/doc/migrations/0042_bofreq_states.py deleted file mode 100644 index 95119f81475..00000000000 --- a/ietf/doc/migrations/0042_bofreq_states.py +++ /dev/null @@ -1,36 +0,0 @@ -# Copyright The IETF Trust 2021 All Rights Reserved - -# Generated by Django 2.2.23 on 2021-05-21 13:29 - -from django.db import migrations - -def forward(apps, schema_editor): - StateType = apps.get_model('doc', 'StateType') - State = apps.get_model('doc', 'State') - - StateType.objects.create(slug='bofreq', label='BOF Request State') - proposed = State.objects.create(type_id='bofreq', slug='proposed', name='Proposed', used=True, desc='The BOF request is proposed', order=0) - approved = State.objects.create(type_id='bofreq', slug='approved', name='Approved', used=True, desc='The BOF request is approved', order=1) - declined = State.objects.create(type_id='bofreq', slug='declined', name='Declined', used=True, desc='The BOF request is declined', order=2) - replaced = State.objects.create(type_id='bofreq', slug='replaced', name='Replaced', used=True, desc='The BOF request is proposed', order=3) - abandoned = State.objects.create(type_id='bofreq', slug='abandoned', name='Abandoned', used=True, desc='The BOF request is abandoned', order=4) - - proposed.next_states.set([approved,declined,replaced,abandoned]) - -def reverse(apps, schema_editor): - StateType = apps.get_model('doc', 'StateType') - State = apps.get_model('doc', 'State') - State.objects.filter(type_id='bofreq').delete() - StateType.objects.filter(slug='bofreq').delete() - - -class Migration(migrations.Migration): - - dependencies = [ - ('doc', '0041_add_documentactionholder'), - ('name', '0027_add_bofrequest'), - ] - - operations = [ - migrations.RunPython(forward, reverse) - ] diff --git a/ietf/doc/migrations/0043_bofreq_docevents.py b/ietf/doc/migrations/0043_bofreq_docevents.py deleted file mode 100644 index 7a300426b32..00000000000 --- a/ietf/doc/migrations/0043_bofreq_docevents.py +++ /dev/null @@ -1,36 +0,0 @@ -# Generated by Django 2.2.24 on 2021-07-06 13:34 - -from django.db import migrations, models -import django.db.models.deletion - - -class Migration(migrations.Migration): - - dependencies = [ - ('person', '0019_auto_20210604_1443'), - ('doc', '0042_bofreq_states'), - ] - - operations = [ - migrations.AlterField( - model_name='docevent', - name='type', - field=models.CharField(choices=[('new_revision', 'Added new revision'), ('new_submission', 'Uploaded new revision'), ('changed_document', 'Changed document metadata'), ('added_comment', 'Added comment'), ('added_message', 'Added message'), ('edited_authors', 'Edited the documents author list'), ('deleted', 'Deleted document'), ('changed_state', 'Changed state'), ('changed_stream', 'Changed document stream'), ('expired_document', 'Expired document'), ('extended_expiry', 'Extended expiry of document'), ('requested_resurrect', 'Requested resurrect'), ('completed_resurrect', 'Completed resurrect'), ('changed_consensus', 'Changed consensus'), ('published_rfc', 'Published RFC'), ('added_suggested_replaces', 'Added suggested replacement relationships'), ('reviewed_suggested_replaces', 'Reviewed suggested replacement relationships'), ('changed_action_holders', 'Changed action holders for document'), ('changed_group', 'Changed group'), ('changed_protocol_writeup', 'Changed protocol writeup'), ('changed_charter_milestone', 'Changed charter milestone'), ('initial_review', 'Set initial review time'), ('changed_review_announcement', 'Changed WG Review text'), ('changed_action_announcement', 'Changed WG Action text'), ('started_iesg_process', 'Started IESG process on document'), ('created_ballot', 'Created ballot'), ('closed_ballot', 'Closed ballot'), ('sent_ballot_announcement', 'Sent ballot announcement'), ('changed_ballot_position', 'Changed ballot position'), ('changed_ballot_approval_text', 'Changed ballot approval text'), ('changed_ballot_writeup_text', 'Changed ballot writeup text'), ('changed_rfc_editor_note_text', 'Changed RFC Editor Note text'), ('changed_last_call_text', 'Changed last call text'), ('requested_last_call', 'Requested last call'), ('sent_last_call', 'Sent last call'), ('scheduled_for_telechat', 'Scheduled for telechat'), ('iesg_approved', 'IESG approved document (no problem)'), ('iesg_disapproved', 'IESG disapproved document (do not publish)'), ('approved_in_minute', 'Approved in minute'), ('iana_review', 'IANA review comment'), ('rfc_in_iana_registry', 'RFC is in IANA registry'), ('rfc_editor_received_announcement', 'Announcement was received by RFC Editor'), ('requested_publication', 'Publication at RFC Editor requested'), ('sync_from_rfc_editor', 'Received updated information from RFC Editor'), ('requested_review', 'Requested review'), ('assigned_review_request', 'Assigned review request'), ('closed_review_request', 'Closed review request'), ('closed_review_assignment', 'Closed review assignment'), ('downref_approved', 'Downref approved'), ('posted_related_ipr', 'Posted related IPR'), ('removed_related_ipr', 'Removed related IPR'), ('changed_editors', 'Changed BOF Request editors')], max_length=50), - ), - migrations.CreateModel( - name='BofreqResponsibleDocEvent', - fields=[ - ('docevent_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='doc.DocEvent')), - ('responsible', models.ManyToManyField(blank=True, to='person.Person')), - ], - bases=('doc.docevent',), - ), - migrations.CreateModel( - name='BofreqEditorDocEvent', - fields=[ - ('docevent_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='doc.DocEvent')), - ('editors', models.ManyToManyField(blank=True, to='person.Person')), - ], - bases=('doc.docevent',), - ), - ] diff --git a/ietf/doc/migrations/0044_procmaterials_states.py b/ietf/doc/migrations/0044_procmaterials_states.py deleted file mode 100644 index 28929358816..00000000000 --- a/ietf/doc/migrations/0044_procmaterials_states.py +++ /dev/null @@ -1,34 +0,0 @@ -# Copyright The IETF Trust 2021 All Rights Reserved - -# Generated by Django 2.2.23 on 2021-05-21 13:29 - -from django.db import migrations - -def forward(apps, schema_editor): - StateType = apps.get_model('doc', 'StateType') - State = apps.get_model('doc', 'State') - - StateType.objects.create(slug='procmaterials', label='Proceedings Materials State') - active = State.objects.create(type_id='procmaterials', slug='active', name='Active', used=True, desc='The material is active', order=0) - removed = State.objects.create(type_id='procmaterials', slug='removed', name='Removed', used=True, desc='The material is removed', order=1) - - active.next_states.set([removed]) - removed.next_states.set([active]) - -def reverse(apps, schema_editor): - StateType = apps.get_model('doc', 'StateType') - State = apps.get_model('doc', 'State') - State.objects.filter(type_id='procmaterials').delete() - StateType.objects.filter(slug='procmaterials').delete() - - -class Migration(migrations.Migration): - - dependencies = [ - ('doc', '0043_bofreq_docevents'), - ('name', '0031_add_procmaterials'), - ] - - operations = [ - migrations.RunPython(forward, reverse) - ] diff --git a/ietf/doc/models.py b/ietf/doc/models.py index 23a2403bfe6..ff879dd71c6 100644 --- a/ietf/doc/models.py +++ b/ietf/doc/models.py @@ -1,40 +1,62 @@ -# Copyright The IETF Trust 2010-2020, All Rights Reserved +# Copyright The IETF Trust 2010-2026, All Rights Reserved # -*- coding: utf-8 -*- +from collections import namedtuple import datetime import logging -import io import os + +import django.db import rfc2html -from typing import Optional, TYPE_CHECKING +from io import BufferedReader +from pathlib import Path + +from django.core.exceptions import ValidationError +from django.db.models import Q +from lxml import etree +from typing import Optional, Protocol, TYPE_CHECKING, Union from weasyprint import HTML as wpHTML +from weasyprint.text.fonts import FontConfiguration from django.db import models from django.core import checks +from django.core.files.base import File from django.core.cache import caches -from django.core.validators import URLValidator, RegexValidator +from django.core.validators import ( + URLValidator, + RegexValidator, + ProhibitNullCharactersValidator, +) from django.urls import reverse as urlreverse from django.contrib.contenttypes.models import ContentType from django.conf import settings -from django.utils.encoding import force_text +from django.utils import timezone +from django.utils.encoding import force_str from django.utils.html import mark_safe # type:ignore +from django.contrib.staticfiles import finders import debug # pyflakes:ignore from ietf.group.models import Group +from ietf.doc.storage_utils import ( + store_str as utils_store_str, + store_bytes as utils_store_bytes, + store_file as utils_store_file +) from ietf.name.models import ( DocTypeName, DocTagName, StreamName, IntendedStdLevelName, StdLevelName, DocRelationshipName, DocReminderTypeName, BallotPositionName, ReviewRequestStateName, ReviewAssignmentStateName, FormalLanguageName, DocUrlTagName, ExtResourceName) from ietf.person.models import Email, Person from ietf.person.utils import get_active_balloters from ietf.utils import log -from ietf.utils.admin import admin_link from ietf.utils.decorators import memoize +from ietf.utils.text import decode_document_content from ietf.utils.validators import validate_no_control_chars from ietf.utils.mail import formataddr from ietf.utils.models import ForeignKey +from ietf.utils.timezone import date_today, RPC_TZINFO, DEADLINE_TZINFO if TYPE_CHECKING: # importing other than for type checking causes errors due to cyclic imports from ietf.meeting.models import ProceedingsMaterial, Session @@ -51,16 +73,22 @@ def __str__(self): @checks.register('db-consistency') def check_statetype_slugs(app_configs, **kwargs): errors = [] - state_type_slugs = [ t.slug for t in StateType.objects.all() ] - for type in DocTypeName.objects.all(): - if not type.slug in state_type_slugs: - errors.append(checks.Error( - "The document type '%s (%s)' does not have a corresponding entry in the doc.StateType table" % (type.name, type.slug), - hint="You should add a doc.StateType entry with a slug '%s' to match the DocTypeName slug."%(type.slug), - obj=type, - id='datatracker.doc.E0015', - )) - return errors + try: + state_type_slugs = [ t.slug for t in StateType.objects.all() ] + except django.db.ProgrammingError: + # When running initial migrations on an empty DB, attempting to retrieve StateType will raise a + # ProgrammingError. Until Django 3, there is no option to skip the checks. + return [] + else: + for type in DocTypeName.objects.all(): + if not type.slug in state_type_slugs: + errors.append(checks.Error( + "The document type '%s (%s)' does not have a corresponding entry in the doc.StateType table" % (type.name, type.slug), + hint="You should add a doc.StateType entry with a slug '%s' to match the DocTypeName slug."%(type.slug), + obj=type, + id='datatracker.doc.E0015', + )) + return errors class State(models.Model): type = ForeignKey(StateType) @@ -70,7 +98,7 @@ class State(models.Model): desc = models.TextField(blank=True) order = models.IntegerField(default=0) - next_states = models.ManyToManyField('State', related_name="previous_states", blank=True) + next_states = models.ManyToManyField('doc.State', related_name="previous_states", blank=True) def __str__(self): return self.name @@ -83,16 +111,31 @@ class Meta: IESG_STATCHG_CONFLREV_ACTIVE_STATES = ("iesgeval", "defer") IESG_SUBSTATE_TAGS = ('ad-f-up', 'need-rev', 'extpty') + +def validate_doc_keywords(value): + if ( + not isinstance(value, list | tuple | set) + or not all(isinstance(elt, str) for elt in value) + ): + raise ValidationError("Value must be an array of strings") + + class DocumentInfo(models.Model): """Any kind of document. Draft, RFC, Charter, IPR Statement, Liaison Statement""" - time = models.DateTimeField(default=datetime.datetime.now) # should probably have auto_now=True + time = models.DateTimeField(default=timezone.now) # should probably have auto_now=True type = ForeignKey(DocTypeName, blank=True, null=True) # Draft, Agenda, Minutes, Charter, Discuss, Guideline, Email, Review, Issue, Wiki, External ... - title = models.CharField(max_length=255, validators=[validate_no_control_chars, ]) + title = models.CharField( + max_length=255, + validators=[ + ProhibitNullCharactersValidator(), + validate_no_control_chars, + ], + ) states = models.ManyToManyField(State, blank=True) # plain state (Active/Expired/...), IESG state, stream state tags = models.ManyToManyField(DocTagName, blank=True) # Revised ID Needed, ExternalParty, AD Followup, ... - stream = ForeignKey(StreamName, blank=True, null=True) # IETF, IAB, IRTF, Independent Submission + stream = ForeignKey(StreamName, blank=True, null=True) # IETF, IAB, IRTF, Independent Submission, Editorial group = ForeignKey(Group, blank=True, null=True) # WG, RG, IAB, IESG, Edu, Tools abstract = models.TextField(blank=True) @@ -100,17 +143,28 @@ class DocumentInfo(models.Model): pages = models.IntegerField(blank=True, null=True) words = models.IntegerField(blank=True, null=True) formal_languages = models.ManyToManyField(FormalLanguageName, blank=True, help_text="Formal languages used in document") - order = models.IntegerField(default=1, blank=True) # This is probably obviated by SessionPresentaion.order intended_std_level = ForeignKey(IntendedStdLevelName, verbose_name="Intended standardization level", blank=True, null=True) std_level = ForeignKey(StdLevelName, verbose_name="Standardization level", blank=True, null=True) ad = ForeignKey(Person, verbose_name="area director", related_name='ad_%(class)s_set', blank=True, null=True) shepherd = ForeignKey(Email, related_name='shepherd_%(class)s_set', blank=True, null=True) expires = models.DateTimeField(blank=True, null=True) - notify = models.CharField(max_length=255, blank=True) + notify = models.TextField(max_length=1023, blank=True) external_url = models.URLField(blank=True) uploaded_filename = models.TextField(blank=True) note = models.TextField(blank=True) - internal_comments = models.TextField(blank=True) + rfc_number = models.PositiveIntegerField(blank=True, null=True) # only valid for type="rfc" + keywords = models.JSONField( + default=list, + max_length=1000, + validators=[validate_doc_keywords], + blank=True, + ) + + @property + def doi(self) -> str | None: + if self.type_id == "rfc" and self.rfc_number is not None: + return f"{settings.IETF_DOI_PREFIX}/RFC{self.rfc_number}" + return None def file_extension(self): if not hasattr(self, '_cached_extension'): @@ -123,20 +177,20 @@ def file_extension(self): def get_file_path(self): if not hasattr(self, '_cached_file_path'): - if self.type_id == "draft": + if self.type_id == "rfc": + self._cached_file_path = settings.RFC_PATH + elif self.type_id == "draft": if self.is_dochistory(): self._cached_file_path = settings.INTERNET_ALL_DRAFTS_ARCHIVE_DIR else: - if self.get_state_slug() == "rfc": - self._cached_file_path = settings.RFC_PATH + # This could be simplified since anything in INTERNET_DRAFT_PATH is also already in INTERNET_ALL_DRAFTS_ARCHIVE_DIR + draft_state = self.get_state('draft') + if draft_state and draft_state.slug == 'active': + self._cached_file_path = settings.INTERNET_DRAFT_PATH else: - draft_state = self.get_state('draft') - if draft_state and draft_state.slug == 'active': - self._cached_file_path = settings.INTERNET_DRAFT_PATH - else: - self._cached_file_path = settings.INTERNET_ALL_DRAFTS_ARCHIVE_DIR + self._cached_file_path = settings.INTERNET_ALL_DRAFTS_ARCHIVE_DIR elif self.meeting_related() and self.type_id in ( - "agenda", "minutes", "slides", "bluesheets", "procmaterials" + "agenda", "minutes", "narrativeminutes", "slides", "bluesheets", "procmaterials", "chatlog", "polls" ): meeting = self.get_related_meeting() if meeting is not None: @@ -149,7 +203,7 @@ def get_file_path(self): self._cached_file_path = settings.CONFLICT_REVIEW_PATH elif self.type_id == "statchg": self._cached_file_path = settings.STATUS_CHANGE_PATH - elif self.type_id == "bofreq": + elif self.type_id == "bofreq": # TODO: This is probably unneeded, as is the separate path setting self._cached_file_path = settings.BOFREQ_PATH else: self._cached_file_path = settings.DOCUMENT_PATH_PATTERN.format(doc=self) @@ -159,27 +213,26 @@ def get_base_name(self): if not hasattr(self, '_cached_base_name'): if self.uploaded_filename: self._cached_base_name = self.uploaded_filename + elif self.type_id == 'rfc': + self._cached_base_name = "%s.txt" % self.name elif self.type_id == 'draft': if self.is_dochistory(): self._cached_base_name = "%s-%s.txt" % (self.doc.name, self.rev) else: - if self.get_state_slug() == 'rfc': - self._cached_base_name = "%s.txt" % self.canonical_name() - else: - self._cached_base_name = "%s-%s.txt" % (self.name, self.rev) + self._cached_base_name = "%s-%s.txt" % (self.name, self.rev) elif self.type_id in ["slides", "agenda", "minutes", "bluesheets", "procmaterials", ] and self.meeting_related(): ext = 'pdf' if self.type_id == 'procmaterials' else 'txt' - self._cached_base_name = f'{self.canonical_name()}-{self.rev}.{ext}' + self._cached_base_name = f'{self.name}-{self.rev}.{ext}' elif self.type_id == 'review': # TODO: This will be wrong if a review is updated on the same day it was created (or updated more than once on the same day) self._cached_base_name = "%s.txt" % self.name - elif self.type_id == 'bofreq': + elif self.type_id in ['bofreq', 'statement']: self._cached_base_name = "%s-%s.md" % (self.name, self.rev) else: if self.rev: - self._cached_base_name = "%s-%s.txt" % (self.canonical_name(), self.rev) + self._cached_base_name = "%s-%s.txt" % (self.name, self.rev) else: - self._cached_base_name = "%s.txt" % (self.canonical_name(), ) + self._cached_base_name = "%s.txt" % (self.name, ) return self._cached_base_name def get_file_name(self): @@ -187,41 +240,56 @@ def get_file_name(self): self._cached_file_name = os.path.join(self.get_file_path(), self.get_base_name()) return self._cached_file_name - def revisions(self): + + def revisions_by_dochistory(self): revisions = [] - doc = self.doc if isinstance(self, DocHistory) else self - for e in doc.docevent_set.filter(type='new_revision').distinct(): - if e.rev and not e.rev in revisions: - revisions.append(e.rev) - if not doc.rev in revisions: - revisions.append(doc.rev) - revisions.sort() + if self.type_id != "rfc": + for h in self.history_set.order_by("time", "id"): + if h.rev and not h.rev in revisions: + revisions.append(h.rev) + if not self.rev in revisions: + revisions.append(self.rev) return revisions + def revisions_by_newrevisionevent(self): + revisions = [] + if self.type_id != "rfc": + doc = self.doc if isinstance(self, DocHistory) else self + for e in doc.docevent_set.filter(type='new_revision').distinct(): + if e.rev and not e.rev in revisions: + revisions.append(e.rev) + if not doc.rev in revisions: + revisions.append(doc.rev) + revisions.sort() + return revisions def get_href(self, meeting=None): - return self._get_ref(meeting=meeting,meeting_doc_refs=settings.MEETING_DOC_HREFS) + return self._get_ref(meeting=meeting, versioned=True) def get_versionless_href(self, meeting=None): - return self._get_ref(meeting=meeting,meeting_doc_refs=settings.MEETING_DOC_GREFS) + return self._get_ref(meeting=meeting, versioned=False) - def _get_ref(self, meeting=None, meeting_doc_refs=settings.MEETING_DOC_HREFS): + def _get_ref(self, meeting=None, versioned=True): """ Returns an url to the document text. This differs from .get_absolute_url(), which returns an url to the datatracker page for the document. """ # If self.external_url truly is an url, use it. This is a change from - # the earlier resulution order, but there's at the moment one single + # the earlier resolution order, but there's at the moment one single # instance which matches this (with correct results), so we won't # break things all over the place. - if not hasattr(self, '_cached_href'): + cache_attr = "_cached_href" if versioned else "_cached_versionless_href" + if not hasattr(self, cache_attr): validator = URLValidator() if self.external_url and self.external_url.split(':')[0] in validator.schemes: validator(self.external_url) return self.external_url + meeting_doc_refs = ( + settings.MEETING_DOC_HREFS if versioned else settings.MEETING_DOC_GREFS + ) if self.type_id in settings.DOC_HREFS and self.type_id in meeting_doc_refs: if self.meeting_related(): self.is_meeting_related = True @@ -231,7 +299,7 @@ def _get_ref(self, meeting=None, meeting_doc_refs=settings.MEETING_DOC_HREFS): format = settings.DOC_HREFS[self.type_id] elif self.type_id in settings.DOC_HREFS: self.is_meeting_related = False - if self.is_rfc(): + if self.type_id == "rfc": format = settings.DOC_HREFS['rfc'] else: format = settings.DOC_HREFS[self.type_id] @@ -258,10 +326,28 @@ def _get_ref(self, meeting=None, meeting_doc_refs=settings.MEETING_DOC_HREFS): info = dict(doc=self) href = format.format(**info) + + # For slides that are not meeting-related, we need to know the file extension. + # Assume we have access to the same files as settings.DOC_HREFS["slides"] and + # see what extension is available + if self.type_id == "slides" and not self.meeting_related() and not href.endswith("/"): + filepath = Path(self.get_file_path()) / self.get_base_name() # start with this + if not filepath.exists(): + # Look for other extensions - grab the first one, sorted for stability + for existing in sorted(filepath.parent.glob(f"{filepath.stem}.*")): + filepath = filepath.with_suffix(existing.suffix) + break + href += filepath.suffix # tack on the extension + if href.startswith('/'): href = settings.IDTRACKER_BASE_URL + href - self._cached_href = href - return self._cached_href + setattr(self, cache_attr, href) + return getattr(self, cache_attr) + + def refresh_from_db(self, using=None, fields=None, **kwargs): + super().refresh_from_db(using=using, fields=fields, **kwargs) + self.state_cache = None + self._cached_state_slug = {} def set_state(self, state): """Switch state type implicit in state to state. This just @@ -321,7 +407,9 @@ def friendly_state(self): if not state: return "Unknown state" - if self.type_id == 'draft': + if self.type_id == "rfc": + return f"RFC {self.rfc_number} ({self.std_level})" + elif self.type_id == 'draft': iesg_state = self.get_state("draft-iesg") iesg_state_summary = None if iesg_state: @@ -330,13 +418,15 @@ def friendly_state(self): iesg_state_summary = iesg_state.name if iesg_substate: iesg_state_summary = iesg_state_summary + "::"+"::".join(tag.name for tag in iesg_substate) - - if state.slug == "rfc": - return "RFC %s (%s)" % (self.rfc_number(), self.std_level) + + rfc = self.became_rfc() + if rfc: + return f"Became RFC {rfc.rfc_number} ({rfc.std_level})" + elif state.slug == "repl": rs = self.related_that("replaces") if rs: - return mark_safe("Replaced by " + ", ".join("%s" % (urlreverse('ietf.doc.views_doc.document_main', kwargs=dict(name=alias.document.name)), alias.document) for alias in rs)) + return mark_safe("Replaced by " + ", ".join("%s" % (urlreverse('ietf.doc.views_doc.document_main', kwargs=dict(name=related.name)), related) for related in rs)) else: return "Replaced" elif state.slug == "active": @@ -349,7 +439,7 @@ def friendly_state(self): elif iesg_state.slug == "lc": e = self.latest_event(LastCallDocEvent, type="sent_last_call") if e: - return iesg_state_summary + " (ends %s)" % e.expires.date().isoformat() + return iesg_state_summary + " (ends %s)" % e.expires.astimezone(DEADLINE_TZINFO).date().isoformat() return iesg_state_summary else: @@ -362,30 +452,56 @@ def friendly_state(self): else: return state.name - def is_rfc(self): - if not hasattr(self, '_cached_is_rfc'): - self._cached_is_rfc = self.pk and self.type_id == 'draft' and self.states.filter(type='draft',slug='rfc').exists() - return self._cached_is_rfc - - def rfc_number(self): - if not hasattr(self, '_cached_rfc_number'): - self._cached_rfc_number = None - if self.is_rfc(): - n = self.canonical_name() - if n.startswith("rfc"): - self._cached_rfc_number = n[3:] + def author_names(self): + """Author names as a list of strings""" + names = [] + if self.type_id == "rfc" and self.rfcauthor_set.exists(): + for author in self.rfcauthor_set.select_related("person"): + if author.person: + names.append(author.person.name) else: - if isinstance(self,Document): - logger.error("Document self.is_rfc() is True but self.canonical_name() is %s" % n) - return self._cached_rfc_number + # titlepage_name cannot be blank + names.append(author.titlepage_name) + else: + names = [ + author.person.name + for author in self.documentauthor_set.select_related("person") + ] + return names + + def author_persons_or_names(self): + """Authors as a list of named tuples with person and/or titlepage_name""" + Author = namedtuple("Author", "person titlepage_name") + persons_or_names = [] + if self.type_id=="rfc" and self.rfcauthor_set.exists(): + for author in self.rfcauthor_set.select_related("person"): + persons_or_names.append(Author(person=author.person, titlepage_name=author.titlepage_name)) + else: + for author in self.documentauthor_set.select_related("person"): + persons_or_names.append(Author(person=author.person, titlepage_name="")) + return persons_or_names - @property - def rfcnum(self): - return self.rfc_number() + def author_persons(self): + """Authors as a list of Persons + + Omits any RfcAuthors with a null person field. + """ + if self.type_id == "rfc" and self.rfcauthor_set.exists(): + authors_qs = self.rfcauthor_set.filter(person__isnull=False) + else: + authors_qs = self.documentauthor_set.all() + return [a.person for a in authors_qs.select_related("person")] def author_list(self): + """List of author emails""" + if self.type_id == "rfc" and self.rfcauthor_set.exists(): + author_qs = self.rfcauthor_set.select_related("person").order_by("order") + else: + author_qs = self.documentauthor_set.select_related("email").order_by( + "order" + ) best_addresses = [] - for author in self.documentauthor_set.all(): + for author in author_qs: if author.email: if author.email.active or not author.email.person: best_addresses.append(author.email.address) @@ -393,9 +509,6 @@ def author_list(self): best_addresses.append(author.email.person.email_address()) return ", ".join(best_addresses) - def authors(self): - return [ a.person for a in self.documentauthor_set.all() ] - # This, and several other ballot related functions here, assume that there is only one active ballot for a document at any point in time. # If that assumption is violated, they will only expose the most recently created ballot def ballot_open(self, ballot_type_slug): @@ -420,7 +533,7 @@ def has_rfc_editor_note(self): return e != None and (e.text != "") def meeting_related(self): - if self.type_id in ("agenda","minutes","bluesheets","slides","recording","procmaterials"): + if self.type_id in ("agenda","minutes", "narrativeminutes", "bluesheets","slides","recording","procmaterials","chatlog","polls"): return self.type_id != "slides" or self.get_state_slug('reuse_policy')=='single' return False @@ -455,9 +568,9 @@ def relations_that(self, relationship): if not isinstance(relationship, tuple): raise TypeError("Expected a string or tuple, received %s" % type(relationship)) if isinstance(self, Document): - return RelatedDocument.objects.filter(target__docs=self, relationship__in=relationship).select_related('source') + return RelatedDocument.objects.filter(target=self, relationship__in=relationship).select_related('source') elif isinstance(self, DocHistory): - return RelatedDocHistory.objects.filter(target__docs=self.doc, relationship__in=relationship).select_related('source') + return RelatedDocHistory.objects.filter(target=self.doc, relationship__in=relationship).select_related('source') else: raise TypeError("Expected method called on Document or DocHistory") @@ -491,15 +604,14 @@ def all_relations_that_doc(self, relationship, related=None): for r in rels: if not r in related: related += ( r, ) - for doc in r.target.docs.all(): - related = doc.all_relations_that_doc(relationship, related) + related = r.target.all_relations_that_doc(relationship, related) return related def related_that(self, relationship): - return list(set([x.source.docalias.get(name=x.source.name) for x in self.relations_that(relationship)])) + return list(set([x.source for x in self.relations_that(relationship)])) def all_related_that(self, relationship, related=None): - return list(set([x.source.docalias.get(name=x.source.name) for x in self.all_relations_that(relationship)])) + return list(set([x.source for x in self.all_relations_that(relationship)])) def related_that_doc(self, relationship): return list(set([x.target for x in self.relations_that_doc(relationship)])) @@ -508,37 +620,81 @@ def all_related_that_doc(self, relationship, related=None): return list(set([x.target for x in self.all_relations_that_doc(relationship)])) def replaces(self): - return set([ d for r in self.related_that_doc("replaces") for d in r.docs.all() ]) - - def replaces_canonical_name(self): - s = set([ r.document for r in self.related_that_doc("replaces")]) - first = list(s)[0] if s else None - return None if first is None else first.filename_with_rev() + return self.related_that_doc("replaces") def replaced_by(self): return set([ r.document for r in self.related_that("replaces") ]) - def text(self): + def _text_path(self): path = self.get_file_name() root, ext = os.path.splitext(path) txtpath = root+'.txt' if ext != '.txt' and os.path.exists(txtpath): path = txtpath - try: - with io.open(path, 'rb') as file: - raw = file.read() - except IOError: + return path + + def text_exists(self): + path = Path(self._text_path()) + return path.exists() + + def text(self, size = -1): + path = Path(self._text_path()) + if not path.exists(): return None try: - text = raw.decode('utf-8') - except UnicodeDecodeError: - text = raw.decode('latin-1') - # - return text + with path.open('rb') as file: + raw = file.read(size) + except IOError as e: + log.log(f"Error reading text for {path}: {e}") + return None + return decode_document_content(raw) def text_or_error(self): return self.text() or "Error; cannot read '%s'"%self.get_base_name() + def html_body(self, classes=""): + if self.type_id == "rfc": + try: + html = Path( + os.path.join(settings.RFC_PATH, self.name + ".html") + ).read_text() + except (IOError, UnicodeDecodeError): + return None + else: + try: + html = Path( + os.path.join( + settings.INTERNET_ALL_DRAFTS_ARCHIVE_DIR, + self.name + "-" + self.rev + ".html", + ) + ).read_text() + except (IOError, UnicodeDecodeError): + return None + + # If HTML was generated by rfc2html, do not return it. Caller + # will use htmlize() to use a more current rfc2html to + # generate an HTMLized version. TODO: There should be a + # better way to determine how an HTML format was generated. + if html.startswith("
"):
+            return None
+
+        # get body
+        etree_html = etree.HTML(html)
+        if etree_html is None:
+            return None
+        body = etree_html.xpath("//body")[0]
+        body.tag = "div"
+        if classes:
+            body.attrib["class"] = classes
+
+        # remove things
+        for tag in ["script"]:
+            for t in body.xpath(f"//{tag}"):
+                t.getparent().remove(t)
+        html = etree.tostring(body, encoding=str, method="html")
+
+        return html
+
     def htmlized(self):
         name = self.get_base_name()
         text = self.text()
@@ -558,25 +714,43 @@ def htmlized(self):
                 # The path here has to match the urlpattern for htmlized
                 # documents in order to produce correct intra-document links
                 html = rfc2html.markup(text, path=settings.HTMLIZER_URL_PREFIX)
+                html = f'
{html}
' if html: cache.set(cache_key, html, settings.HTMLIZER_CACHE_TIME) return html def pdfized(self): name = self.get_base_name() - text = self.text() - cache = caches['pdfized'] - cache_key = name.split('.')[0] + text = self.html_body(classes="rfchtml") + stylesheets = [finders.find("ietf/css/document_html_referenced.css")] + if text: + stylesheets.append(finders.find("ietf/css/document_html_txt.css")) + else: + text = self.htmlized() + stylesheets.append(f'{settings.STATIC_IETF_ORG_INTERNAL}/fonts/noto-sans-mono/import.css') + + cache = caches["pdfized"] + cache_key = name.split(".")[0] try: pdf = cache.get(cache_key) except EOFError: pdf = None if not pdf: - html = rfc2html.markup(text, path=settings.PDFIZER_URL_PREFIX) try: - pdf = wpHTML(string=html.replace('\xad','')).write_pdf(stylesheets=[io.BytesIO(b'html { font-size: 94%;}')]) + font_config = FontConfiguration() + pdf = wpHTML( + string=text, base_url=settings.IDTRACKER_BASE_URL + ).write_pdf( + stylesheets=stylesheets, + font_config=font_config, + presentational_hints=True, + optimize_images=True, + ) except AssertionError: pdf = None + except Exception as e: + log.log('weasyprint failed:'+str(e)) + raise if pdf: cache.set(cache_key, pdf, settings.PDFIZER_CACHE_TIME) return pdf @@ -585,70 +759,224 @@ def references(self): return self.relations_that_doc(('refnorm','refinfo','refunk','refold')) def referenced_by(self): - return self.relations_that(('refnorm','refinfo','refunk','refold')).filter(source__states__type__slug='draft',source__states__slug__in=['rfc','active']) - + return self.relations_that(("refnorm", "refinfo", "refunk", "refold")).filter( + models.Q( + source__type__slug="draft", + source__states__type__slug="draft", + source__states__slug="active", + ) + | models.Q(source__type__slug="rfc") + ).distinct() + def referenced_by_rfcs(self): - return self.relations_that(('refnorm','refinfo','refunk','refold')).filter(source__states__type__slug='draft',source__states__slug='rfc') - + """Get refs to this doc from RFCs""" + return self.relations_that(("refnorm", "refinfo", "refunk", "refold")).filter( + source__type__slug="rfc" + ) + + def became_rfc(self): + if not hasattr(self, "_cached_became_rfc"): + doc = self if isinstance(self, Document) else self.doc + self._cached_became_rfc = next(iter(doc.related_that_doc("became_rfc")), None) + return self._cached_became_rfc + + def came_from_draft(self): + if not hasattr(self, "_cached_came_from_draft"): + doc = self if isinstance(self, Document) else self.doc + self._cached_came_from_draft = next(iter(doc.related_that("became_rfc")), None) + return self._cached_came_from_draft + + def contains(self): + return self.related_that_doc("contains") + + def part_of(self): + return self.related_that("contains") + + def referenced_by_rfcs_as_rfc_or_draft(self): + """Get refs to this doc, or a draft/rfc it came from, from an RFC""" + refs_to = self.referenced_by_rfcs() + if self.type_id == "rfc" and self.came_from_draft(): + refs_to |= self.came_from_draft().referenced_by_rfcs() + return refs_to + + def sent_to_rfc_editor_event(self): + if self.stream_id == "ietf": + return self.docevent_set.filter(type="iesg_approved").order_by("-time").first() + elif self.stream_id in ["editorial", "iab", "irtf", "ise"]: + return self.docevent_set.filter(type="requested_publication").order_by("-time").first() + else: + return None class Meta: abstract = True + +class HasNameRevAndTypeIdProtocol(Protocol): + """Typing Protocol describing a class that has name, rev, and type_id properties""" + @property + def name(self) -> str: ... + @property + def rev(self) -> str: ... + @property + def type_id(self) -> str: ... + + +class StorableMixin: + """Mixin that adds storage helpers to a DocumentInfo subclass""" + def store_str( + self: HasNameRevAndTypeIdProtocol, + name: str, + content: str, + allow_overwrite: bool = False + ) -> None: + return utils_store_str(self.type_id, name, content, allow_overwrite, self.name, self.rev) + + def store_bytes( + self: HasNameRevAndTypeIdProtocol, + name: str, + content: bytes, + allow_overwrite: bool = False, + doc_name: Optional[str] = None, + doc_rev: Optional[str] = None + ) -> None: + return utils_store_bytes(self.type_id, name, content, allow_overwrite, self.name, self.rev) + + def store_file( + self: HasNameRevAndTypeIdProtocol, + name: str, + file: Union[File, BufferedReader], + allow_overwrite: bool = False, + doc_name: Optional[str] = None, + doc_rev: Optional[str] = None + ) -> None: + return utils_store_file(self.type_id, name, file, allow_overwrite, self.name, self.rev) + + STATUSCHANGE_RELATIONS = ('tops','tois','tohist','toinf','tobcp','toexp') class RelatedDocument(models.Model): source = ForeignKey('Document') - target = ForeignKey('DocAlias') + target = ForeignKey('Document', related_name='targets_related') relationship = ForeignKey(DocRelationshipName) + originaltargetaliasname = models.CharField(max_length=255, null=True, blank=True) def action(self): return self.relationship.name def __str__(self): return u"%s %s %s" % (self.source.name, self.relationship.name.lower(), self.target.name) def is_downref(self): - - if self.source.type.slug!='draft' or self.relationship.slug not in ['refnorm','refold','refunk']: + if self.source.type_id not in ["draft","rfc"] or self.relationship.slug not in [ + "refnorm", + "refold", + "refunk", + ]: return None - state = self.source.get_state() - if state and state.slug == 'rfc': - source_lvl = self.source.std_level.slug if self.source.std_level else None - elif self.source.intended_std_level: - source_lvl = self.source.intended_std_level.slug + if self.source.type_id == "rfc": + source_lvl = self.source.std_level_id + elif self.source.type_id in ["bcp","std"]: + source_lvl = self.source.type_id else: - source_lvl = None + source_lvl = self.source.intended_std_level_id - if source_lvl not in ['bcp','ps','ds','std']: + if source_lvl not in ["bcp", "ps", "ds", "std", "unkn"]: return None - if self.target.document.get_state().slug == 'rfc': - if not self.target.document.std_level: + if self.target.type_id == 'rfc': + if not self.target.std_level: target_lvl = 'unkn' else: - target_lvl = self.target.document.std_level.slug + target_lvl = self.target.std_level_id + elif self.target.type_id in ["bcp", "std"]: + target_lvl = self.target.type_id else: - if not self.target.document.intended_std_level: + if not self.target.intended_std_level: target_lvl = 'unkn' else: - target_lvl = self.target.document.intended_std_level.slug + target_lvl = self.target.intended_std_level_id - rank = { 'ps':1, 'ds':2, 'std':3, 'bcp':3 } + if self.relationship.slug not in ["refnorm", "refunk"]: + return None - if ( target_lvl not in rank ) or ( rank[target_lvl] < rank[source_lvl] ): - if self.relationship.slug == 'refnorm' and target_lvl!='unkn': - return "Downref" - else: - return "Possible Downref" + if source_lvl in ["inf", "exp"]: + return None + + pos_downref = ( + "Downref" if self.relationship_id != "refunk" else "Possible Downref" + ) + + if source_lvl in ["bcp", "ps", "ds", "std"] and target_lvl in ["inf", "exp"]: + return pos_downref + + if source_lvl == "ds" and target_lvl == "ps": + return pos_downref + + if source_lvl == "std" and target_lvl in ["ps", "ds"]: + return pos_downref + + if source_lvl not in ["inf", "exp"] and target_lvl == "unkn": + return "Possible Downref" + + if source_lvl == "unkn" and target_lvl in ["ps", "ds"]: + return "Possible Downref" return None def is_approved_downref(self): - if self.target.document.get_state().slug == 'rfc': - if RelatedDocument.objects.filter(relationship_id='downref-approval', target=self.target): + if self.target.type_id == 'rfc': + if RelatedDocument.objects.filter(relationship_id='downref-approval', target=self.target).exists(): return "Approved Downref" return False +class RfcAuthor(models.Model): + """Captures the authors of an RFC as represented on the RFC title page. + + This deviates from DocumentAuthor in that it does not get moved into the DocHistory + hierarchy as documents are saved. It will attempt to preserve email, country, and affiliation + from the DocumentAuthor objects associated with the draft leading to this RFC (which + may be wrong if the author moves or changes affiliation while the document is in the + queue). + + It does not, at this time, attempt to capture the authors from anything _but_ the title + page. The datatracker may know more about such authors based on information from the draft + leading to the RFC, and future work may take that into account. + + Once doc.rfcauthor_set.exists() for a doc of type `rfc`, doc.documentauthor_set should be + ignored. + """ + + document = ForeignKey( + "Document", + on_delete=models.CASCADE, + limit_choices_to={"type_id": "rfc"}, # only affects ModelForms (e.g., admin) + ) + titlepage_name = models.CharField(max_length=128, blank=False) + is_editor = models.BooleanField(default=False) + person = ForeignKey(Person, null=True, blank=True, on_delete=models.PROTECT) + affiliation = models.CharField(max_length=100, blank=True, help_text="Organization/company used by author for submission") + country = models.CharField(max_length=255, blank=True, help_text="Country used by author for submission") + order = models.IntegerField(default=1) + + def __str__(self): + return u"%s %s (%s)" % (self.document.name, self.person, self.order) + + class Meta: + ordering=["document", "order"] + indexes=[ + models.Index(fields=["document", "order"]) + ] + + @property + def email(self) -> Email | None: + return self.person.email() if self.person else None + + def format_for_titlepage(self): + if self.is_editor: + return f"{self.titlepage_name}, Ed." + return self.titlepage_name + + class DocumentAuthorInfo(models.Model): person = ForeignKey(Person) # email should only be null for some historic documents @@ -682,7 +1010,7 @@ class DocumentActionHolder(models.Model): """Action holder for a document""" document = ForeignKey('Document') person = ForeignKey(Person) - time_added = models.DateTimeField(default=datetime.datetime.now) + time_added = models.DateTimeField(default=timezone.now) CLEAR_ACTION_HOLDERS_STATES = ['approved', 'ann', 'rfcqueue', 'pub', 'dead'] # draft-iesg state slugs GROUP_ROLES_OF_INTEREST = ['chair', 'techadv', 'editor', 'secr'] @@ -698,7 +1026,7 @@ class Meta: def role_for_doc(self): """Brief string description of this person's relationship to the doc""" roles = [] - if self.person in self.document.authors(): + if self.person in self.document.author_persons(): roles.append('Author') if self.person == self.document.ad: roles.append('Responsible AD') @@ -717,13 +1045,25 @@ def role_for_doc(self): roles.append('Action Holder') return ', '.join(roles) +# N.B., at least a couple dozen documents exist that do not satisfy this validator validate_docname = RegexValidator( r'^[-a-z0-9]+$', "Provide a valid document name consisting of lowercase letters, numbers and hyphens.", 'invalid' ) -class Document(DocumentInfo): + +SUBSERIES_DOC_TYPE_IDS = ("bcp", "fyi", "std") + + +class DocumentQuerySet(models.QuerySet): + def subseries_docs(self): + return self.filter(type_id__in=SUBSERIES_DOC_TYPE_IDS) + + +class Document(StorableMixin, DocumentInfo): + objects = DocumentQuerySet.as_manager() + name = models.CharField(max_length=255, validators=[validate_docname,], unique=True) # immutable action_holders = models.ManyToManyField(Person, through=DocumentActionHolder, blank=True) @@ -740,7 +1080,7 @@ def get_absolute_url(self): name = self.name url = None if self.type_id == "draft" and self.get_state_slug() == "rfc": - name = self.canonical_name() + name = self.name url = urlreverse('ietf.doc.views_doc.document_main', kwargs={ 'name': name }, urlconf="ietf.urls") elif self.type_id in ('slides','bluesheets','recording'): session = self.session_set.first() @@ -778,28 +1118,8 @@ def latest_event(self, *args, **filter_args): e = model.objects.filter(doc=self).filter(**filter_args).order_by('-time', '-id').first() return e - def canonical_name(self): - if not hasattr(self, '_canonical_name'): - name = self.name - if self.type_id == "draft" and self.get_state_slug() == "rfc": - a = self.docalias.filter(name__startswith="rfc").order_by('-name').first() - if a: - name = a.name - elif self.type_id == "charter": - from ietf.doc.utils_charter import charter_name_for_group # Imported locally to avoid circular imports - try: - name = charter_name_for_group(self.chartered_group) - except Group.DoesNotExist: - pass - self._canonical_name = name - return self._canonical_name - - - def canonical_docalias(self): - return self.docalias.get(name=self.name) - def display_name(self): - name = self.canonical_name() + name = self.name if name.startswith('rfc'): name = name.upper() return name @@ -829,22 +1149,42 @@ def save(self, *args, **kwargs): def telechat_date(self, e=None): if not e: e = self.latest_event(TelechatDocEvent, type="scheduled_for_telechat") - return e.telechat_date if e and e.telechat_date and e.telechat_date >= datetime.date.today() else None + return e.telechat_date if e and e.telechat_date and e.telechat_date >= date_today(settings.TIME_ZONE) else None def past_telechat_date(self): "Return the latest telechat date if it isn't in the future; else None" e = self.latest_event(TelechatDocEvent, type="scheduled_for_telechat") - return e.telechat_date if e and e.telechat_date and e.telechat_date < datetime.date.today() else None + return e.telechat_date if e and e.telechat_date and e.telechat_date < date_today(settings.TIME_ZONE) else None def previous_telechat_date(self): "Return the most recent telechat date in the past, if any (even if there's another in the future)" - e = self.latest_event(TelechatDocEvent, type="scheduled_for_telechat", telechat_date__lt=datetime.datetime.now()) + e = self.latest_event( + TelechatDocEvent, + type="scheduled_for_telechat", + telechat_date__lt=date_today(settings.TIME_ZONE), + ) return e.telechat_date if e else None def request_closed_time(self, review_req): e = self.latest_event(ReviewRequestDocEvent, type="closed_review_request", review_request=review_req) return e.time if e and e.time else None + @property + def area(self) -> Group | None: + """Get area for document, if one exists + + None for non-IETF-stream documents. N.b., this is stricter than Group.area() and + uses different logic from Document.area_acronym(). + """ + if self.stream_id != "ietf": + return None + if self.group is None: + return None + parent = self.group.parent + if parent.type_id == "area": + return parent + return None + def area_acronym(self): g = self.group if g: @@ -888,33 +1228,50 @@ def most_recent_ietflc(self): def displayname_with_link(self): return mark_safe('%s-%s' % (self.get_absolute_url(), self.name , self.rev)) - def ipr(self,states=('posted','removed')): + def ipr(self,states=settings.PUBLISH_IPR_STATES): """Returns the IPR disclosures against this document (as a queryset over IprDocRel).""" - from ietf.ipr.models import IprDocRel - return IprDocRel.objects.filter(document__docs=self, disclosure__state__in=states) + # from ietf.ipr.models import IprDocRel + # return IprDocRel.objects.filter(document__docs=self, disclosure__state__in=states) # TODO - clear these comments away + return self.iprdocrel_set.filter(disclosure__state__in=states) def related_ipr(self): """Returns the IPR disclosures against this document and those documents this document directly or indirectly obsoletes or replaces """ from ietf.ipr.models import IprDocRel - iprs = IprDocRel.objects.filter(document__in=list(self.docalias.all())+self.all_related_that_doc(('obs','replaces'))).filter(disclosure__state__in=('posted','removed')).values_list('disclosure', flat=True).distinct() + iprs = ( + IprDocRel.objects.filter( + document__in=[self] + + self.all_related_that_doc(("obs", "replaces")) + ) + .filter(disclosure__state__in=settings.PUBLISH_IPR_STATES) + .values_list("disclosure", flat=True) + .distinct() + ) return iprs + def future_presentations(self): """ returns related SessionPresentation objects for meetings that have not yet ended. This implementation allows for 2 week meetings """ - candidate_presentations = self.sessionpresentation_set.filter(session__meeting__date__gte=datetime.date.today()-datetime.timedelta(days=15)) - return sorted([pres for pres in candidate_presentations if pres.session.meeting.end_date()>=datetime.date.today()], key=lambda x:x.session.meeting.date) + candidate_presentations = self.presentations.filter( + session__meeting__date__gte=date_today() - datetime.timedelta(days=15) + ) + return sorted( + [pres for pres in candidate_presentations + if pres.session.meeting.end_date() >= date_today()], + key=lambda x:x.session.meeting.date, + ) def last_presented(self): """ returns related SessionPresentation objects for the most recent meeting in the past""" - # Assumes no two meetings have the same start date - if the assumption is violated, one will be chosen arbitrariy - candidate_presentations = self.sessionpresentation_set.filter(session__meeting__date__lte=datetime.date.today()) - candidate_meetings = set([p.session.meeting for p in candidate_presentations if p.session.meeting.end_date()%s" % (self.name, ','.join([force_text(d.name) for d in self.docs.all() if isinstance(d, Document) ])) - document_link = admin_link("document") - class Meta: - verbose_name = "document alias" - verbose_name_plural = "document aliases" class DocReminder(models.Model): event = ForeignKey('DocEvent') @@ -1188,6 +1548,7 @@ class DocReminder(models.Model): ("rfc_editor_received_announcement", "Announcement was received by RFC Editor"), ("requested_publication", "Publication at RFC Editor requested"), ("sync_from_rfc_editor", "Received updated information from RFC Editor"), + ("changed_rpc_assignments", "Changed RPC queue assignments"), # review ("requested_review", "Requested review"), @@ -1201,14 +1562,22 @@ class DocReminder(models.Model): # IPR events ("posted_related_ipr", "Posted related IPR"), ("removed_related_ipr", "Removed related IPR"), + ("removed_objfalse_related_ipr", "Removed Objectively False related IPR"), # Bofreq Editor events - ("changed_editors", "Changed BOF Request editors") + ("changed_editors", "Changed BOF Request editors"), + + # Statement events + ("published_statement", "Published statement"), + + # Slide events + ("approved_slides", "Slides approved"), + ] class DocEvent(models.Model): """An occurrence for a document, used for tracking who, when and what.""" - time = models.DateTimeField(default=datetime.datetime.now, help_text="When the event happened", db_index=True) + time = models.DateTimeField(default=timezone.now, help_text="When the event happened", db_index=True) type = models.CharField(max_length=50, choices=EVENT_TYPES) by = ForeignKey(Person) doc = ForeignKey(Document) @@ -1245,6 +1614,9 @@ class StateDocEvent(DocEvent): class ConsensusDocEvent(DocEvent): consensus = models.BooleanField(null=True, default=None) +class RpcAssignmentDocEvent(DocEvent): + assignments = models.TextField(blank=True) + # IESG events class BallotType(models.Model): doc_type = ForeignKey(DocTypeName, blank=True, null=True) @@ -1265,7 +1637,7 @@ class BallotDocEvent(DocEvent): ballot_type = ForeignKey(BallotType) def active_balloter_positions(self): - """Return dict mapping each active AD or IRSG member to a current ballot position (or None if they haven't voted).""" + """Return dict mapping each active member of the balloting body to a current ballot position (or None if they haven't voted).""" res = {} active_balloters = get_active_balloters(self.ballot_type) @@ -1302,13 +1674,13 @@ def all_positions(self): if e.pos != prev: latest.old_positions.append(e.pos) - # get rid of trailling "No record" positions, some old ballots + # get rid of trailing "No record" positions, some old ballots # have plenty of these for p in positions: while p.old_positions and p.old_positions[-1].slug == "norecord": p.old_positions.pop() - # add any missing ADs/IRSGers through fake No Record events + # add any missing balloters through fake No Record events if self.doc.active_ballot() == self: norecord = BallotPositionName.objects.get(slug="norecord") for balloter in active_balloters: @@ -1388,7 +1760,7 @@ class DeletedEvent(models.Model): content_type = ForeignKey(ContentType) json = models.TextField(help_text="Deleted object in JSON format, with attribute names chosen to be suitable for passing into the relevant create method.") by = ForeignKey(Person) - time = models.DateTimeField(default=datetime.datetime.now) + time = models.DateTimeField(default=timezone.now) def __str__(self): return u"%s by %s %s" % (self.content_type, self.by, self.time) @@ -1400,6 +1772,11 @@ class EditedAuthorsDocEvent(DocEvent): """ basis = models.CharField(help_text="What is the source or reasoning for the changes to the author list",max_length=255) + +class EditedRfcAuthorsDocEvent(DocEvent): + """Change to the RfcAuthor list for a document""" + + class BofreqEditorDocEvent(DocEvent): """ Capture the proponents of a BOF Request.""" editors = models.ManyToManyField('person.Person', blank=True) @@ -1407,3 +1784,42 @@ class BofreqEditorDocEvent(DocEvent): class BofreqResponsibleDocEvent(DocEvent): """ Capture the responsible leadership (IAB and IESG members) for a BOF Request """ responsible = models.ManyToManyField('person.Person', blank=True) + + +class StoredObjectQuerySet(models.QuerySet): + def exclude_deleted(self): + return self.filter(deleted__isnull=True) + + +class StoredObject(models.Model): + """Hold metadata about objects placed in object storage""" + + objects = StoredObjectQuerySet.as_manager() + + store = models.CharField(max_length=256) + name = models.CharField(max_length=1024, null=False, blank=False) # N.B. the 1024 limit on name comes from S3 + sha384 = models.CharField(max_length=96) + len = models.PositiveBigIntegerField() + store_created = models.DateTimeField(help_text="The instant the object ws first placed in the store") + created = models.DateTimeField( + null=False, + help_text="Instant object became known. May not be the same as the storage's created value for the instance. It will hold ctime for objects imported from older disk storage" + ) + modified = models.DateTimeField( + null=False, + help_text="Last instant object was modified. May not be the same as the storage's modified value for the instance. It will hold mtime for objects imported from older disk storage unless they've actually been overwritten more recently" + ) + doc_name = models.CharField(max_length=255, null=True, blank=True) + doc_rev = models.CharField(max_length=16, null=True, blank=True) + deleted = models.DateTimeField(null=True) + + class Meta: + constraints = [ + models.UniqueConstraint(fields=['store', 'name'], name='unique_name_per_store'), + ] + indexes = [ + models.Index(fields=["doc_name", "doc_rev"]), + ] + + def __str__(self): + return f"{self.store}:{self.name}" diff --git a/ietf/doc/resources.py b/ietf/doc/resources.py index 99e26ac33d8..9da7cb57d80 100644 --- a/ietf/doc/resources.py +++ b/ietf/doc/resources.py @@ -12,13 +12,14 @@ from ietf import api from ietf.doc.models import (BallotType, DeletedEvent, StateType, State, Document, - DocumentAuthor, DocEvent, StateDocEvent, DocHistory, ConsensusDocEvent, DocAlias, + DocumentAuthor, DocEvent, StateDocEvent, DocHistory, ConsensusDocEvent, TelechatDocEvent, DocReminder, LastCallDocEvent, NewRevisionDocEvent, WriteupDocEvent, InitialReviewDocEvent, DocHistoryAuthor, BallotDocEvent, RelatedDocument, RelatedDocHistory, BallotPositionDocEvent, AddedMessageEvent, SubmissionDocEvent, ReviewRequestDocEvent, ReviewAssignmentDocEvent, EditedAuthorsDocEvent, DocumentURL, - IanaExpertDocEvent, IRSGBallotDocEvent, DocExtResource, DocumentActionHolder, - BofreqEditorDocEvent,BofreqResponsibleDocEvent) + IanaExpertDocEvent, IRSGBallotDocEvent, DocExtResource, DocumentActionHolder, + BofreqEditorDocEvent, BofreqResponsibleDocEvent, StoredObject, RfcAuthor, + EditedRfcAuthorsDocEvent, RpcAssignmentDocEvent) from ietf.name.resources import BallotPositionNameResource, DocTypeNameResource class BallotTypeResource(ModelResource): @@ -130,7 +131,6 @@ class Meta: "external_url": ALL, "uploaded_filename": ALL, "note": ALL, - "internal_comments": ALL, "name": ALL, "type": ALL_WITH_RELATIONS, "stream": ALL_WITH_RELATIONS, @@ -247,7 +247,6 @@ class Meta: "external_url": ALL, "uploaded_filename": ALL, "note": ALL, - "internal_comments": ALL, "name": ALL, "type": ALL_WITH_RELATIONS, "stream": ALL_WITH_RELATIONS, @@ -286,21 +285,6 @@ class Meta: } api.doc.register(ConsensusDocEventResource()) -class DocAliasResource(ModelResource): - document = ToOneField(DocumentResource, 'document') - class Meta: - cache = SimpleCache() - queryset = DocAlias.objects.all() - serializer = api.Serializer() - detail_uri_name = 'name' - #resource_name = 'docalias' - ordering = ['id', ] - filtering = { - "name": ALL, - "document": ALL_WITH_RELATIONS, - } -api.doc.register(DocAliasResource()) - from ietf.person.resources import PersonResource class TelechatDocEventResource(ModelResource): by = ToOneField(PersonResource, 'by') @@ -490,7 +474,7 @@ class Meta: from ietf.name.resources import DocRelationshipNameResource class RelatedDocumentResource(ModelResource): source = ToOneField(DocumentResource, 'source') - target = ToOneField(DocAliasResource, 'target') + target = ToOneField(DocumentResource, 'target') relationship = ToOneField(DocRelationshipNameResource, 'relationship') class Meta: cache = SimpleCache() @@ -509,7 +493,7 @@ class Meta: from ietf.name.resources import DocRelationshipNameResource class RelatedDocHistoryResource(ModelResource): source = ToOneField(DocHistoryResource, 'source') - target = ToOneField(DocAliasResource, 'target') + target = ToOneField(DocumentResource, 'target') relationship = ToOneField(DocRelationshipNameResource, 'relationship') class Meta: cache = SimpleCache() @@ -667,6 +651,31 @@ class Meta: api.doc.register(EditedAuthorsDocEventResource()) + +from ietf.person.resources import PersonResource +class EditedRfcAuthorsDocEventResource(ModelResource): + by = ToOneField(PersonResource, 'by') + doc = ToOneField(DocumentResource, 'doc') + docevent_ptr = ToOneField(DocEventResource, 'docevent_ptr') + class Meta: + queryset = EditedRfcAuthorsDocEvent.objects.all() + serializer = api.Serializer() + cache = SimpleCache() + #resource_name = 'editedrfcauthorsdocevent' + ordering = ['id', ] + filtering = { + "id": ALL, + "time": ALL, + "type": ALL, + "rev": ALL, + "desc": ALL, + "by": ALL_WITH_RELATIONS, + "doc": ALL_WITH_RELATIONS, + "docevent_ptr": ALL_WITH_RELATIONS, + } +api.doc.register(EditedRfcAuthorsDocEventResource()) + + from ietf.name.resources import DocUrlTagNameResource class DocumentURLResource(ModelResource): doc = ToOneField(DocumentResource, 'doc') @@ -859,3 +868,76 @@ class Meta: "responsible": ALL_WITH_RELATIONS, } api.doc.register(BofreqResponsibleDocEventResource()) + + +class StoredObjectResource(ModelResource): + class Meta: + queryset = StoredObject.objects.all() + serializer = api.Serializer() + cache = SimpleCache() + #resource_name = 'storedobject' + ordering = ['id', ] + filtering = { + "id": ALL, + "store": ALL, + "name": ALL, + "sha384": ALL, + "len": ALL, + "store_created": ALL, + "created": ALL, + "modified": ALL, + "doc_name": ALL, + "doc_rev": ALL, + "deleted": ALL, + } +api.doc.register(StoredObjectResource()) + + +from ietf.person.resources import EmailResource, PersonResource +class RfcAuthorResource(ModelResource): + document = ToOneField(DocumentResource, 'document') + person = ToOneField(PersonResource, 'person', null=True) + email = ToOneField(EmailResource, 'email', null=True, readonly=True) + class Meta: + queryset = RfcAuthor.objects.all() + serializer = api.Serializer() + cache = SimpleCache() + #resource_name = 'rfcauthor' + ordering = ['id', ] + filtering = { + "id": ALL, + "titlepage_name": ALL, + "is_editor": ALL, + "affiliation": ALL, + "country": ALL, + "order": ALL, + "document": ALL_WITH_RELATIONS, + "person": ALL_WITH_RELATIONS, + "email": ALL_WITH_RELATIONS, + } +api.doc.register(RfcAuthorResource()) + + +from ietf.person.resources import PersonResource +class RpcAssignmentDocEventResource(ModelResource): + by = ToOneField(PersonResource, 'by') + doc = ToOneField(DocumentResource, 'doc') + docevent_ptr = ToOneField(DocEventResource, 'docevent_ptr') + class Meta: + queryset = RpcAssignmentDocEvent.objects.all() + serializer = api.Serializer() + cache = SimpleCache() + #resource_name = 'rpcassignmentdocevent' + ordering = ['docevent_ptr', ] + filtering = { + "id": ALL, + "time": ALL, + "type": ALL, + "rev": ALL, + "desc": ALL, + "assignments": ALL, + "by": ALL_WITH_RELATIONS, + "doc": ALL_WITH_RELATIONS, + "docevent_ptr": ALL_WITH_RELATIONS, + } +api.doc.register(RpcAssignmentDocEventResource()) diff --git a/ietf/doc/serializers.py b/ietf/doc/serializers.py new file mode 100644 index 00000000000..3651670962b --- /dev/null +++ b/ietf/doc/serializers.py @@ -0,0 +1,360 @@ +# Copyright The IETF Trust 2024-2026, All Rights Reserved +"""django-rest-framework serializers""" + +from dataclasses import dataclass +from typing import Literal, ClassVar + +from django.db.models.manager import BaseManager +from django.db.models.query import QuerySet +from drf_spectacular.utils import extend_schema_field +from rest_framework import serializers + +from ietf.group.serializers import ( + AreaDirectorSerializer, + AreaSerializer, + GroupSerializer, +) +from ietf.name.serializers import StreamNameSerializer +from ietf.utils import log +from .models import Document, DocumentAuthor, RfcAuthor + + +class RfcAuthorSerializer(serializers.ModelSerializer): + """Serializer for an RfcAuthor / DocumentAuthor in a response""" + + email = serializers.EmailField(source="email.address", read_only=True) + datatracker_person_path = serializers.URLField( + source="person.get_absolute_url", + required=False, + help_text="URL for person link (relative to datatracker base URL)", + read_only=True, + ) + + class Meta: + model = RfcAuthor + fields = [ + "titlepage_name", + "is_editor", + "person", + "email", + "affiliation", + "country", + "datatracker_person_path", + ] + + def to_representation(self, instance): + """instance -> primitive data types + + Translates a DocumentAuthor into an equivalent RfcAuthor we can use the same + serializer for either type. + """ + if isinstance(instance, DocumentAuthor): + # create a non-persisted RfcAuthor as a shim - do not save it! + document_author = instance + instance = RfcAuthor( + titlepage_name=document_author.person.plain_name(), + is_editor=False, + person=document_author.person, + affiliation=document_author.affiliation, + country=document_author.country, + order=document_author.order, + ) + return super().to_representation(instance) + + def validate(self, data): + email = data.get("email") + if email is not None: + person = data.get("person") + if person is None: + raise serializers.ValidationError( + { + "email": "cannot have an email without a person", + }, + code="email-without-person", + ) + if email.person_id != person.pk: + raise serializers.ValidationError( + { + "email": "email must belong to person", + }, + code="email-person-mismatch", + ) + return data + + +@dataclass +class DocIdentifier: + type: Literal["doi", "issn"] + value: str + + +class DocIdentifierSerializer(serializers.Serializer): + type = serializers.ChoiceField(choices=["doi", "issn"]) + value = serializers.CharField() + + +type RfcStatusSlugT = Literal[ + "std", + "ps", + "ds", + "bcp", + "inf", + "exp", + "hist", + "unkn", + "not-issued", +] + + +@dataclass +class RfcStatus: + """Helper to extract the 'Status' from an RFC document for serialization""" + + slug: RfcStatusSlugT + + # Names that aren't just the slug itself. ClassVar annotation prevents dataclass from treating this as a field. + fancy_names: ClassVar[dict[RfcStatusSlugT, str]] = { + "std": "internet standard", + "ps": "proposed standard", + "ds": "draft standard", + "bcp": "best current practice", + "inf": "informational", + "exp": "experimental", + "hist": "historic", + "unkn": "unknown", + } + + # ClassVar annotation prevents dataclass from treating this as a field + stdlevelname_slug_map: ClassVar[dict[str, RfcStatusSlugT]] = { + "bcp": "bcp", + "ds": "ds", + "exp": "exp", + "hist": "hist", + "inf": "inf", + "std": "std", + "ps": "ps", + "unkn": "unkn", + } + + # ClassVar annotation prevents dataclass from treating this as a field + status_slugs: ClassVar[list[RfcStatusSlugT]] = sorted( + # TODO implement "not-issued" RFCs + set(stdlevelname_slug_map.values()) | {"not-issued"} + ) + + @property + def name(self): + return RfcStatus.fancy_names.get(self.slug, self.slug) + + @classmethod + def from_document(cls, doc: Document): + """Decide the status that applies to a document""" + return cls( + slug=(cls.stdlevelname_slug_map.get(doc.std_level.slug, "unkn")), + ) + + @classmethod + def filter(cls, queryset, name, value: list[RfcStatusSlugT]): + """Filter a queryset by status + + This is basically the inverse of the from_document() method. Given a status name, filter + the queryset to those in that status. The queryset should be a Document queryset. + """ + interesting_slugs = [ + stdlevelname_slug + for stdlevelname_slug, status_slug in cls.stdlevelname_slug_map.items() + if status_slug in value + ] + if len(interesting_slugs) == 0: + return queryset.none() + return queryset.filter(std_level__slug__in=interesting_slugs) + + +class RfcStatusSerializer(serializers.Serializer): + """Status serializer for a Document instance""" + + slug = serializers.ChoiceField(choices=RfcStatus.status_slugs) + name = serializers.CharField() + + def to_representation(self, instance: Document): + return super().to_representation(instance=RfcStatus.from_document(instance)) + + +class ShepherdSerializer(serializers.Serializer): + email = serializers.EmailField(source="email_address") + + +class RelatedDraftSerializer(serializers.Serializer): + id = serializers.IntegerField(source="source.id") + name = serializers.CharField(source="source.name") + title = serializers.CharField(source="source.title") + shepherd = ShepherdSerializer(source="source.shepherd", allow_null=True) + ad = AreaDirectorSerializer(source="source.ad", allow_null=True) + + +class RelatedRfcSerializer(serializers.Serializer): + id = serializers.IntegerField(source="target.id") + number = serializers.IntegerField(source="target.rfc_number") + title = serializers.CharField(source="target.title") + + +class ReverseRelatedRfcSerializer(serializers.Serializer): + id = serializers.IntegerField(source="source.id") + number = serializers.IntegerField(source="source.rfc_number") + title = serializers.CharField(source="source.title") + + +class ContainingSubseriesSerializer(serializers.Serializer): + name = serializers.CharField(source="source.name") + type = serializers.CharField(source="source.type_id") + + +class RfcFormatSerializer(serializers.Serializer): + RFC_FORMATS = ("xml", "txt", "html", "pdf", "ps", "json", "notprepped") + + fmt = serializers.ChoiceField(choices=RFC_FORMATS) + name = serializers.CharField(help_text="Name of blob in the blob store") + + +class RfcMetadataSerializer(serializers.ModelSerializer): + """Serialize metadata of an RFC + + This needs to be called with a Document queryset that has been processed with + api.augment_rfc_queryset() or it very likely will not work. Some of the typing + refers to Document, but this should really be WithAnnotations[Document, ...]. + However, have not been able to make that work yet. + """ + + number = serializers.IntegerField(source="rfc_number") + published = serializers.DateField() + status = RfcStatusSerializer(source="*") + authors = serializers.SerializerMethodField() + group = GroupSerializer() + area = AreaSerializer(read_only=True) + stream = StreamNameSerializer() + ad = AreaDirectorSerializer(read_only=True, allow_null=True) + group_list_email = serializers.EmailField(source="group.list_email", read_only=True) + identifiers = serializers.SerializerMethodField() + draft = serializers.SerializerMethodField() + obsoletes = RelatedRfcSerializer(many=True, read_only=True) + obsoleted_by = ReverseRelatedRfcSerializer(many=True, read_only=True) + updates = RelatedRfcSerializer(many=True, read_only=True) + updated_by = ReverseRelatedRfcSerializer(many=True, read_only=True) + subseries = ContainingSubseriesSerializer(many=True, read_only=True) + formats = RfcFormatSerializer( + many=True, read_only=True, help_text="Available formats" + ) + keywords = serializers.ListField(child=serializers.CharField(), read_only=True) + has_errata = serializers.BooleanField(read_only=True) + + class Meta: + model = Document + fields = [ + "number", + "title", + "published", + "status", + "pages", + "authors", + "group", + "area", + "stream", + "ad", + "group_list_email", + "identifiers", + "obsoletes", + "obsoleted_by", + "updates", + "updated_by", + "subseries", + "draft", + "abstract", + "formats", + "keywords", + "has_errata", + ] + + @extend_schema_field(RfcAuthorSerializer(many=True)) + def get_authors(self, doc: Document): + # If doc has any RfcAuthors, use those, otherwise fall back to DocumentAuthors + author_queryset: QuerySet[RfcAuthor] | QuerySet[DocumentAuthor] = ( + doc.rfcauthor_set.all() + if doc.rfcauthor_set.exists() + else doc.documentauthor_set.all() + ) + # RfcAuthorSerializer can deal with DocumentAuthor instances + return RfcAuthorSerializer( + instance=author_queryset, + many=True, + ).data + + @extend_schema_field(DocIdentifierSerializer(many=True)) + def get_identifiers(self, doc: Document): + identifiers = [] + if doc.doi: + identifiers.append( + DocIdentifier(type="doi", value=doc.doi) + ) + return DocIdentifierSerializer(instance=identifiers, many=True).data + + @extend_schema_field(RelatedDraftSerializer) + def get_draft(self, doc: Document): + if hasattr(doc, "drafts"): + # This is the expected case - drafts is added by a Prefetch in + # the augment_rfc_queryset() method. + try: + related_doc = doc.drafts[0] + except IndexError: + return None + else: + # Fallback in case augment_rfc_queryset() was not called + log.log( + f"Warning: {self.__class__}.get_draft() called without prefetched draft" + ) + related_doc = doc.came_from_draft() + return RelatedDraftSerializer(related_doc).data + + +class RfcSerializer(RfcMetadataSerializer): + """Serialize an RFC, including its metadata and text content if available""" + + text = serializers.CharField(allow_null=True) + + class Meta: + model = RfcMetadataSerializer.Meta.model + fields = RfcMetadataSerializer.Meta.fields + ["text"] + + +class SubseriesContentListSerializer(serializers.ListSerializer): + """ListSerializer that gets its object from item.target""" + + def to_representation(self, data): + """ + List of object instances -> List of dicts of primitive datatypes. + """ + # Dealing with nested relationships, data can be a Manager, + # so, first get a queryset from the Manager if needed + iterable = data.all() if isinstance(data, BaseManager) else data + # Serialize item.target instead of item itself + return [self.child.to_representation(item.target) for item in iterable] + + +class SubseriesContentSerializer(RfcMetadataSerializer): + """Serialize RFC contained in a subseries doc""" + + class Meta(RfcMetadataSerializer.Meta): + list_serializer_class = SubseriesContentListSerializer + + +class SubseriesDocSerializer(serializers.ModelSerializer): + """Serialize a subseries document (e.g., a BCP or STD)""" + + contents = SubseriesContentSerializer(many=True) + + class Meta: + model = Document + fields = [ + "name", + "type", + "contents", + ] diff --git a/ietf/doc/storage.py b/ietf/doc/storage.py new file mode 100644 index 00000000000..ee1e76c4fac --- /dev/null +++ b/ietf/doc/storage.py @@ -0,0 +1,181 @@ +# Copyright The IETF Trust 2025, All Rights Reserved +from typing import Optional + +import debug # pyflakes:ignore +import json + +from contextlib import contextmanager +from storages.backends.s3 import S3Storage + +from django.core.files.base import File + +from ietf.blobdb.storage import BlobdbStorage +from ietf.doc.models import StoredObject +from ietf.utils.log import log +from ietf.utils.storage import MetadataFile +from ietf.utils.timezone import timezone + + +class StoredObjectFile(MetadataFile): + """Django storage File object that represents a StoredObject""" + def __init__(self, file, name, mtime=None, content_type="", store=None, doc_name=None, doc_rev=None): + super().__init__( + file=file, + name=name, + mtime=mtime, + content_type=content_type, + ) + self.store = store + self.doc_name = doc_name + self.doc_rev = doc_rev + + @classmethod + def from_storedobject(cls, file, name, store): + """Alternate constructor for objects that already exist in the StoredObject table""" + stored_object = StoredObject.objects.exclude_deleted().filter(store=store, name=name).first() + if stored_object is None: + raise FileNotFoundError(f"StoredObject for {store}:{name} does not exist or was deleted") + file = cls(file, name, store, doc_name=stored_object.doc_name, doc_rev=stored_object.doc_rev) + if int(file.custom_metadata["len"]) != stored_object.len: + raise RuntimeError(f"File length changed unexpectedly for {store}:{name}") + if file.custom_metadata["sha384"] != stored_object.sha384: + raise RuntimeError(f"SHA-384 hash changed unexpectedly for {store}:{name}") + return file + + +@contextmanager +def maybe_log_timing(enabled, op, **kwargs): + """If enabled, log elapsed time and additional data from kwargs + + Emits log even if an exception occurs + """ + before = timezone.now() + exception = None + try: + yield + except Exception as err: + exception = err + raise + finally: + if enabled: + dt = timezone.now() - before + log( + json.dumps( + { + "log": "S3Storage_timing", + "seconds": dt.total_seconds(), + "op": op, + "exception": "" if exception is None else repr(exception), + **kwargs, + } + ) + ) + + +class MetadataS3Storage(S3Storage): + def get_default_settings(self): + # add a default for the ietf_log_blob_timing boolean + return super().get_default_settings() | {"ietf_log_blob_timing": False} + + def _save(self, name, content: File): + with maybe_log_timing( + self.ietf_log_blob_timing, "_save", bucket_name=self.bucket_name, name=name + ): + return super()._save(name, content) + + def _open(self, name, mode="rb"): + with maybe_log_timing( + self.ietf_log_blob_timing, + "_open", + bucket_name=self.bucket_name, + name=name, + mode=mode, + ): + return super()._open(name, mode) + + def delete(self, name): + with maybe_log_timing( + self.ietf_log_blob_timing, "delete", bucket_name=self.bucket_name, name=name + ): + super().delete(name) + + def _get_write_parameters(self, name, content=None): + # debug.show('f"getting write parameters for {name}"') + params = super()._get_write_parameters(name, content) + # If we have a non-empty explicit content type, use it + content_type = getattr(content, "content_type", "").strip() + if content_type != "": + params["ContentType"] = content_type + if "Metadata" not in params: + params["Metadata"] = {} + if hasattr(content, "custom_metadata"): + params["Metadata"].update(content.custom_metadata) + return params + + +class StoredObjectBlobdbStorage(BlobdbStorage): + warn_if_missing = True # TODO-BLOBSTORE make this configurable (or remove it) + + def _save_stored_object(self, name, content) -> StoredObject: + now = timezone.now() + record, created = StoredObject.objects.get_or_create( + store=self.bucket_name, + name=name, + defaults=dict( + sha384=content.custom_metadata["sha384"], + len=int(content.custom_metadata["len"]), + store_created=now, + created=now, + modified=now, + doc_name=getattr( + content, + "doc_name", # Note that these are assumed to be invariant + None, # should be blank? + ), + doc_rev=getattr( + content, + "doc_rev", # for a given name + None, # should be blank? + ), + ), + ) + if not created and ( + record.sha384 != content.custom_metadata["sha384"] + or record.len != int(content.custom_metadata["len"]) + or record.deleted is not None + ): + record.sha384 = content.custom_metadata["sha384"] + record.len = int(content.custom_metadata["len"]) + record.modified = now + record.deleted = None + record.save() + return record + + def _delete_stored_object(self, name) -> Optional[StoredObject]: + existing_record = StoredObject.objects.filter(store=self.bucket_name, name=name) + if not existing_record.exists() and self.warn_if_missing: + complaint = ( + f"WARNING: Asked to delete {name} from {self.bucket_name} storage, " + f"but there was no matching StoredObject" + ) + log(complaint) + debug.show("complaint") + else: + now = timezone.now() + # Note that existing_record is a queryset that will have one matching object + existing_record.exclude_deleted().update(deleted=now) + return existing_record.first() + + def _save(self, name, content): + """Perform the save operation + + In principle the name could change on save to the blob store. As of now, BlobdbStorage + will not change it, but allow for that possibility. Callers should be prepared for this. + """ + saved_name = super()._save(name, content) + self._save_stored_object(saved_name, content) + return saved_name + + def delete(self, name): + self._delete_stored_object(name) + super().delete(name) diff --git a/ietf/doc/storage_utils.py b/ietf/doc/storage_utils.py new file mode 100644 index 00000000000..c7cc6989cd0 --- /dev/null +++ b/ietf/doc/storage_utils.py @@ -0,0 +1,203 @@ +# Copyright The IETF Trust 2025, All Rights Reserved +import datetime +from io import BufferedReader +from typing import Optional, Union + +import debug # pyflakes ignore + +from django.conf import settings +from django.core.files.base import ContentFile, File +from django.core.files.storage import storages, Storage + +from ietf.utils.log import log +from ietf.utils.text import decode_document_content + + +class StorageUtilsError(Exception): + pass + + +class AlreadyExistsError(StorageUtilsError): + pass + + +def _get_storage(kind: str) -> Storage: + if kind in settings.ARTIFACT_STORAGE_NAMES: + return storages[kind] + else: + debug.say(f"Got into not-implemented looking for {kind}") + raise NotImplementedError(f"Don't know how to store {kind}") + + +def exists_in_storage(kind: str, name: str) -> bool: + if settings.ENABLE_BLOBSTORAGE: + try: + store = _get_storage(kind) + with store.open(name): + return True + except FileNotFoundError: + return False + except Exception as err: + log(f"Blobstore Error: Failed to test existence of {kind}:{name}: {repr(err)}") + if settings.SERVER_MODE == "development": + raise + return False + + +def remove_from_storage(kind: str, name: str, warn_if_missing: bool = True) -> None: + if settings.ENABLE_BLOBSTORAGE: + try: + if exists_in_storage(kind, name): + _get_storage(kind).delete(name) + elif warn_if_missing: + complaint = ( + f"WARNING: Asked to delete non-existent {name} from {kind} storage" + ) + debug.show("complaint") + log(complaint) + except Exception as err: + log(f"Blobstore Error: Failed to remove {kind}:{name}: {repr(err)}") + if settings.SERVER_MODE == "development": + raise + return None + + +def store_file( + kind: str, + name: str, + file: Union[File, BufferedReader], + allow_overwrite: bool = False, + doc_name: Optional[str] = None, + doc_rev: Optional[str] = None, + content_type: str="", + mtime: Optional[datetime.datetime]=None, +) -> None: + from .storage import StoredObjectFile # avoid circular import + if settings.ENABLE_BLOBSTORAGE: + try: + is_new = not exists_in_storage(kind, name) + # debug.show('f"Asked to store {name} in {kind}: is_new={is_new}, allow_overwrite={allow_overwrite}"') + if not allow_overwrite and not is_new: + debug.show('f"Failed to save {kind}:{name} - name already exists in store"') + raise AlreadyExistsError(f"Failed to save {kind}:{name} - name already exists in store") + new_name = _get_storage(kind).save( + name, + StoredObjectFile( + file=file, + name=name, + doc_name=doc_name, + doc_rev=doc_rev, + mtime=mtime, + content_type=content_type, + ), + ) + if new_name != name: + complaint = f"Error encountered saving '{name}' - results stored in '{new_name}' instead." + debug.show("complaint") + raise StorageUtilsError(complaint) + except Exception as err: + log(f"Blobstore Error: Failed to store file {kind}:{name}: {repr(err)}") + if settings.SERVER_MODE == "development": + raise # TODO-BLOBSTORE eventually make this an error for all modes + return None + + +def store_bytes( + kind: str, + name: str, + content: bytes, + allow_overwrite: bool = False, + doc_name: Optional[str] = None, + doc_rev: Optional[str] = None, + content_type: str = "", + mtime: Optional[datetime.datetime] = None, +) -> None: + if settings.ENABLE_BLOBSTORAGE: + try: + store_file( + kind, + name, + ContentFile(content), + allow_overwrite, + doc_name, + doc_rev, + content_type, + mtime, + ) + except Exception as err: + # n.b., not likely to get an exception here because store_file or store_bytes will catch it + log(f"Blobstore Error: Failed to store bytes to {kind}:{name}: {repr(err)}") + if settings.SERVER_MODE == "development": + raise # TODO-BLOBSTORE eventually make this an error for all modes + return None + + +def store_str( + kind: str, + name: str, + content: str, + allow_overwrite: bool = False, + doc_name: Optional[str] = None, + doc_rev: Optional[str] = None, + content_type: str = "", + mtime: Optional[datetime.datetime] = None, +) -> None: + if settings.ENABLE_BLOBSTORAGE: + try: + content_bytes = content.encode("utf-8") + store_bytes( + kind, + name, + content_bytes, + allow_overwrite, + doc_name, + doc_rev, + content_type, + mtime, + ) + except Exception as err: + # n.b., not likely to get an exception here because store_file or store_bytes will catch it + log(f"Blobstore Error: Failed to store string to {kind}:{name}: {repr(err)}") + if settings.SERVER_MODE == "development": + raise # TODO-BLOBSTORE eventually make this an error for all modes + return None + + +def retrieve_bytes(kind: str, name: str) -> bytes: + from ietf.doc.storage import maybe_log_timing + if not settings.ENABLE_BLOBSTORAGE: + return b"" + try: + store = _get_storage(kind) + with store.open(name) as f: + with maybe_log_timing( + hasattr(store, "ietf_log_blob_timing") and store.ietf_log_blob_timing, + "read", + bucket_name=store.bucket_name if hasattr(store, "bucket_name") else "", + name=name, + ): + content = f.read() + except Exception as err: + log(f"Blobstore Error: Failed to read bytes from {kind}:{name}: {repr(err)}") + raise + return content + + +def retrieve_str(kind: str, name: str) -> str: + if not settings.ENABLE_BLOBSTORAGE: + return "" + try: + content = decode_document_content(retrieve_bytes(kind, name)) + except Exception as err: + log(f"Blobstore Error: Failed to read string from {kind}:{name}: {repr(err)}") + raise + return content + + +def force_replication(kind: str, name: str): + if not settings.ENABLE_BLOBSTORAGE: + return + storage = _get_storage(kind) + from ietf.blobdb.storage import BlobdbStorage + if isinstance(storage, BlobdbStorage): + storage.force_replication(name) diff --git a/ietf/doc/tasks.py b/ietf/doc/tasks.py new file mode 100644 index 00000000000..37c235b9115 --- /dev/null +++ b/ietf/doc/tasks.py @@ -0,0 +1,226 @@ +# Copyright The IETF Trust 2024-2026, All Rights Reserved +# +# Celery task definitions +# +import datetime + +import debug # pyflakes:ignore + +from celery import shared_task +from celery.exceptions import MaxRetriesExceededError +from pathlib import Path + +from django.conf import settings +from django.utils import timezone + +from ietf.doc.utils_r2 import rfcs_are_in_r2 +from ietf.doc.utils_red import trigger_red_precomputer +from ietf.utils import log, searchindex +from ietf.utils.timezone import datetime_today + +from .expire import ( + in_draft_expire_freeze, + get_expired_drafts, + expirable_drafts, + send_expire_notice_for_draft, + expire_draft, + clean_up_draft_files, + get_soon_to_expire_drafts, + send_expire_warning_for_draft, +) +from .lastcall import get_expired_last_calls, expire_last_call +from .models import Document, NewRevisionDocEvent +from .utils import ( + generate_idnits2_rfc_status, + generate_idnits2_rfcs_obsoleted, + rebuild_reference_relations, + update_or_create_draft_bibxml_file, + ensure_draft_bibxml_path_exists, + investigate_fragment, +) +from .utils_bofreq import fixup_bofreq_timestamps +from .utils_errata import signal_update_rfc_metadata + + +@shared_task +def expire_ids_task(): + try: + if not in_draft_expire_freeze(): + log.log("Expiring drafts ...") + for doc in get_expired_drafts(): + # verify expirability -- it might have changed after get_expired_drafts() was run + # (this whole loop took about 2 minutes on 04 Jan 2018) + # N.B., re-running expirable_drafts() repeatedly is fairly expensive. Where possible, + # it's much faster to run it once on a superset query of the objects you are going + # to test and keep its results. That's not desirable here because it would defeat + # the purpose of double-checking that a document is still expirable when it is actually + # being marked as expired. + if expirable_drafts( + Document.objects.filter(pk=doc.pk) + ).exists() and doc.expires < datetime_today() + datetime.timedelta(1): + send_expire_notice_for_draft(doc) + expire_draft(doc) + log.log(f" Expired draft {doc.name}-{doc.rev}") + + log.log("Cleaning up draft files") + clean_up_draft_files() + except Exception as e: + log.log("Exception in expire-ids: %s" % e) + raise + + +@shared_task +def notify_expirations_task(notify_days=14): + for doc in get_soon_to_expire_drafts(notify_days): + send_expire_warning_for_draft(doc) + + +@shared_task +def expire_last_calls_task(): + for doc in get_expired_last_calls(): + try: + expire_last_call(doc) + except Exception: + log.log( + f"ERROR: Failed to expire last call for {doc.file_tag()} (id={doc.pk})" + ) + else: + log.log(f"Expired last call for {doc.file_tag()} (id={doc.pk})") + + +@shared_task +def generate_idnits2_rfc_status_task(): + outpath = Path(settings.DERIVED_DIR) / "idnits2-rfc-status" + blob = generate_idnits2_rfc_status() + try: + outpath.write_text(blob, encoding="utf8") # TODO-BLOBSTORE + except Exception as e: + log.log(f"failed to write idnits2-rfc-status: {e}") + + +@shared_task +def generate_idnits2_rfcs_obsoleted_task(): + outpath = Path(settings.DERIVED_DIR) / "idnits2-rfcs-obsoleted" + blob = generate_idnits2_rfcs_obsoleted() + try: + outpath.write_text(blob, encoding="utf8") # TODO-BLOBSTORE + except Exception as e: + log.log(f"failed to write idnits2-rfcs-obsoleted: {e}") + + +@shared_task +def generate_draft_bibxml_files_task(days=7, process_all=False): + """Generate bibxml files for recently updated docs + + If process_all is False (the default), processes only docs with new revisions + in the last specified number of days. + """ + if not process_all and days < 1: + raise ValueError("Must call with days >= 1 or process_all=True") + ensure_draft_bibxml_path_exists() + doc_events = NewRevisionDocEvent.objects.filter( + type="new_revision", + doc__type_id="draft", + ).order_by("time") + if not process_all: + doc_events = doc_events.filter( + time__gte=timezone.now() - datetime.timedelta(days=days) + ) + for event in doc_events: + try: + update_or_create_draft_bibxml_file(event.doc, event.rev) + except Exception as err: + log.log(f"Error generating bibxml for {event.doc.name}-{event.rev}: {err}") + + +@shared_task(ignore_result=False) +def investigate_fragment_task(name_fragment: str): + return { + "name_fragment": name_fragment, + "results": investigate_fragment(name_fragment), + } + + +@shared_task +def rebuild_reference_relations_task(doc_names: list[str]): + log.log(f"Task: Rebuilding reference relations for {doc_names}") + for doc in Document.objects.filter(name__in=doc_names, type__in=["rfc", "draft"]): + filenames = dict() + base = ( + settings.RFC_PATH + if doc.type_id == "rfc" + else settings.INTERNET_ALL_DRAFTS_ARCHIVE_DIR + ) + stem = doc.name if doc.type_id == "rfc" else f"{doc.name}-{doc.rev}" + for ext in ["xml", "txt"]: + path = Path(base) / f"{stem}.{ext}" + if path.is_file(): + filenames[ext] = str(path) + if len(filenames) > 0: + rebuild_reference_relations(doc, filenames) + else: + log.log(f"Found no content for {stem}") + + +@shared_task +def fixup_bofreq_timestamps_task(): # pragma: nocover + fixup_bofreq_timestamps() + + +@shared_task +def signal_update_rfc_metadata_task(rfc_number_list=()): + signal_update_rfc_metadata(rfc_number_list) + + +@shared_task(bind=True) +def trigger_red_precomputer_task(self, rfc_number_list=()): + if not rfcs_are_in_r2(rfc_number_list): + log.log(f"Objects are not yet in R2 for RFCs {rfc_number_list}") + try: + countdown = getattr(settings, "RED_PRECOMPUTER_TRIGGER_RETRY_DELAY", 10) + max_retries = getattr(settings, "RED_PRECOMPUTER_TRIGGER_MAX_RETRIES", 12) + self.retry(countdown=countdown, max_retries=max_retries) + except MaxRetriesExceededError: + log.log(f"Gave up waiting for objects in R2 for RFCs {rfc_number_list}") + else: + trigger_red_precomputer(rfc_number_list) + + +@shared_task(bind=True) +def update_rfc_searchindex_task(self, rfc_number: int): + """Update the search index for one RFC""" + if not searchindex.enabled(): + log.log("Search indexing is not enabled, skipping") + return + + rfc = Document.objects.filter(type_id="rfc", rfc_number=rfc_number).first() + if rfc is None: + log.log( + f"ERROR: Document for rfc{rfc_number} not found, not updating search index" + ) + return + try: + searchindex.update_or_create_rfc_entry(rfc) + except Exception as err: + log.log(f"Search index update for {rfc.name} failed ({err})") + if isinstance(err, searchindex.RETRYABLE_ERROR_CLASSES): + searchindex_settings = searchindex.get_settings() + self.retry( + countdown=searchindex_settings["TASK_RETRY_DELAY"], + max_retries=searchindex_settings["TASK_MAX_RETRIES"], + ) + + +@shared_task +def rebuild_searchindex_task( + *, batchsize=40, drop_collection=False, upsert_presets=True +): + if drop_collection: + searchindex.delete_collection() + searchindex.create_collection() + if upsert_presets: + searchindex.upsert_presets() # ok if they already exist + searchindex.update_or_create_rfc_entries( + Document.objects.filter(type_id="rfc").order_by("-rfc_number"), + batchsize=batchsize, + ) diff --git a/ietf/doc/templatetags/active_groups_menu.py b/ietf/doc/templatetags/active_groups_menu.py index dd97c8e45bb..c60d6dcd1af 100644 --- a/ietf/doc/templatetags/active_groups_menu.py +++ b/ietf/doc/templatetags/active_groups_menu.py @@ -8,23 +8,19 @@ register = template.Library() -parents = GroupTypeName.objects.filter( - slug__in=["ag", "area", "rag", "team", "dir", "program"] -) - -others = [] -for group in Group.objects.filter(acronym__in=("rsoc",), state_id="active"): - group.menu_url = reverse("ietf.group.views.group_home", kwargs=dict(acronym=group.acronym)) # type: ignore - # could use group.about_url() instead - others.append(group) - @register.simple_tag def active_groups_menu(flavor): - global parents, others + parents = GroupTypeName.objects.filter(slug__in=["ag", "area", "rag", "team", "dir", "program", "iabworkshop"]) + others = [] + for group in Group.objects.filter(acronym__in=("rsoc",), state_id="active"): + group.menu_url = reverse("ietf.group.views.group_home", kwargs=dict(acronym=group.acronym)) # type: ignore + # could use group.about_url() instead + others.append(group) + for p in parents: p.menu_url = "/%s/" % p.slug return render_to_string( "base/menu_active_groups.html", {"parents": parents, "others": others, "flavor": flavor}, - ) \ No newline at end of file + ) diff --git a/ietf/doc/templatetags/ballot_icon.py b/ietf/doc/templatetags/ballot_icon.py index 6d3ddba44e0..07a6c7f9265 100644 --- a/ietf/doc/templatetags/ballot_icon.py +++ b/ietf/doc/templatetags/ballot_icon.py @@ -38,6 +38,7 @@ from django import template from django.urls import reverse as urlreverse from django.db.models import Q +from django.utils import timezone from django.utils.safestring import mark_safe from ietf.ietfauth.utils import user_is_person, has_role @@ -52,7 +53,9 @@ def showballoticon(doc): if doc.type_id == "draft": if doc.stream_id == 'ietf' and doc.get_state_slug("draft-iesg") not in IESG_BALLOT_ACTIVE_STATES: return False - elif doc.stream_id == 'irtf' and doc.get_state_slug("draft-stream-irtf") not in ['irsgpoll']: + elif doc.stream_id == 'irtf' and doc.get_state_slug("draft-stream-irtf") != "irsgpoll": + return False + elif doc.stream_id == 'editorial' and doc.get_state_slug("draft-stream-rsab") != "rsabpoll": return False elif doc.type_id == "charter": if doc.get_state_slug() not in ("intrev", "extrev", "iesgrev"): @@ -93,9 +96,14 @@ def sort_key(t): positions = list(ballot.active_balloter_positions().items()) positions.sort(key=sort_key) + request = context.get("request") + ballot_edit_return_point_param = f"ballot_edit_return_point={request.path}" + right_click_string = '' if has_role(user, "Area Director"): - right_click_string = 'oncontextmenu="window.location.href=\'%s\';return false;"' % urlreverse('ietf.doc.views_ballot.edit_position', kwargs=dict(name=doc.name, ballot_id=ballot.pk)) + right_click_string = 'oncontextmenu="window.location.href=\'{}?{}\';return false;"'.format( + urlreverse('ietf.doc.views_ballot.edit_position', kwargs=dict(name=doc.name, ballot_id=ballot.pk)), + ballot_edit_return_point_param) my_blocking = False for i, (balloter, pos) in enumerate(positions): @@ -104,14 +112,20 @@ def sort_key(t): break typename = "Unknown" - if ballot.ballot_type.slug=='irsg-approve': + if ballot.ballot_type.slug == "irsg-approve": typename = "IRSG" + elif ballot.ballot_type.slug == "rsab-approve": + typename = "RSAB" else: typename = "IESG" + + modal_url = "{}?{}".format( + urlreverse("ietf.doc.views_doc.ballot_popup", kwargs=dict(name=doc.name, ballot_id=ballot.pk)), + ballot_edit_return_point_param) res = ['
") - res.append('' % ballot.pk) + res.append('' % ballot.pk) return mark_safe("".join(res)) @@ -170,22 +184,21 @@ def state_age_colored(doc): if not iesg_state: return "" - if iesg_state in ["dead", "watching", "pub", "idexists"]: + if iesg_state in ["dead", "pub", "idexists"]: return "" try: - state_date = ( + state_datetime = ( doc.docevent_set.filter( Q(type="started_iesg_process") | Q(type="changed_state", statedocevent__state_type="draft-iesg") ) .order_by("-time")[0] - .time.date() + .time ) except IndexError: - state_date = datetime.date(1990, 1, 1) - days = (datetime.date.today() - state_date).days - # loosely based on - # https://trac.ietf.org/trac/iesg/wiki/PublishPath + state_datetime = datetime.datetime(1990, 1, 1, tzinfo=datetime.UTC) + days = (timezone.now() - state_datetime).days + # loosely based on the Publish Path page at the iesg wiki if iesg_state == "lc": goal1 = 30 goal2 = 30 @@ -208,9 +221,9 @@ def state_age_colored(doc): goal1 = 14 goal2 = 28 if days > goal2: - class_name = "bg-danger" + class_name = "text-bg-danger" elif days > goal1: - class_name = "bg-warning" + class_name = "text-bg-warning" else: # don't show a badge when things are in the green; clutters display # class_name = "text-success" @@ -224,7 +237,7 @@ def state_age_colored(doc): else: title = "" return mark_safe( - ' %d' + ' %d' % (class_name, title, days) ) else: @@ -243,6 +256,6 @@ def auth48_alert_badge(doc): rfced_state = doc.get_state_slug('draft-rfceditor') if rfced_state == 'auth48': - return mark_safe('AUTH48') + return mark_safe('AUTH48') return '' diff --git a/ietf/doc/templatetags/document_type_badge.py b/ietf/doc/templatetags/document_type_badge.py new file mode 100644 index 00000000000..a82c606ff90 --- /dev/null +++ b/ietf/doc/templatetags/document_type_badge.py @@ -0,0 +1,29 @@ +# Copyright The IETF Trust 2015-2020, All Rights Reserved +from django import template +from django.conf import settings +from django.template.loader import render_to_string +from ietf.utils.log import log + +register = template.Library() + + +@register.simple_tag +def document_type_badge(doc, snapshot, submission, resurrected_by): + context = {"doc": doc, "snapshot": snapshot, "submission": submission, "resurrected_by": resurrected_by} + if doc.type_id == "rfc": + return render_to_string( + "doc/badge/doc-badge-rfc.html", + context, + ) + elif doc.type_id == "draft": + return render_to_string( + "doc/badge/doc-badge-draft.html", + context, + ) + else: + error_message = f"Unsupported document type {doc.type_id}." + if settings.SERVER_MODE != 'production': + raise ValueError(error_message) + else: + log(error_message) + return "" diff --git a/ietf/doc/templatetags/ietf_filters.py b/ietf/doc/templatetags/ietf_filters.py index d2450fa62bf..e72cc04ff34 100644 --- a/ietf/doc/templatetags/ietf_filters.py +++ b/ietf/doc/templatetags/ietf_filters.py @@ -1,10 +1,12 @@ -# Copyright The IETF Trust 2007-2020, All Rights Reserved +# Copyright The IETF Trust 2007-2023, All Rights Reserved # -*- coding: utf-8 -*- import datetime import re +from pathlib import Path from urllib.parse import urljoin +from zoneinfo import ZoneInfo from django import template from django.conf import settings @@ -12,21 +14,23 @@ from django.template.defaultfilters import truncatewords_html, linebreaksbr, stringfilter, striptags from django.utils.safestring import mark_safe, SafeData from django.utils.html import strip_tags -from django.utils.encoding import force_text -from django.utils.encoding import force_str # pyflakes:ignore force_str is used in the doctests +from django.utils.encoding import force_str from django.urls import reverse as urlreverse from django.core.cache import cache from django.core.exceptions import ValidationError from django.urls import NoReverseMatch +from django.utils import timezone import debug # pyflakes:ignore -from ietf.doc.models import BallotDocEvent, DocAlias +from ietf.doc.models import BallotDocEvent, Document from ietf.doc.models import ConsensusDocEvent -from ietf.utils.html import sanitize_fragment +from ietf.ietfauth.utils import can_request_rfc_publication as utils_can_request_rfc_publication from ietf.utils import log from ietf.doc.utils import prettify_std_name -from ietf.utils.text import wordwrap, fill, wrap_text_if_unwrapped, bleach_linker, bleach_cleaner, validate_url +from ietf.utils.html import clean_html +from ietf.utils.text import wordwrap, fill, wrap_text_if_unwrapped, linkify +from ietf.utils.validators import validate_url register = template.Library() @@ -95,7 +99,7 @@ def sanitize(value): attributes to those deemed acceptable. See ietf/utils/html.py for the details. """ - return mark_safe(sanitize_fragment(value)) + return mark_safe(clean_html(value)) # For use with ballot view @@ -129,23 +133,24 @@ def bracketpos(pos,posslug): @register.filter def prettystdname(string, space=" "): from ietf.doc.utils import prettify_std_name - return prettify_std_name(force_text(string or ""), space) + return prettify_std_name(force_str(string or ""), space) @register.filter def rfceditor_info_url(rfcnum : str): """Link to the RFC editor info page for an RFC""" - return urljoin(settings.RFC_EDITOR_INFO_BASE_URL, f'rfc{rfcnum}') + return urljoin(settings.RFC_EDITOR_INFO_BASE_URL, f'rfc{rfcnum}/') -def doc_canonical_name(name): +def doc_name(name): """Check whether a given document exists, and return its canonical name""" def find_unique(n): key = hash(n) found = cache.get(key) if not found: - exact = DocAlias.objects.filter(name=n).first() + exact = Document.objects.filter(name=n).first() found = exact.name if exact else "_" + # TODO review this cache policy (and the need for these entire function) cache.set(key, found, timeout=60*60*24) # cache for one day return None if found == "_" else found @@ -171,7 +176,7 @@ def find_unique(n): def link_charter_doc_match(match): - if not doc_canonical_name(match[0]): + if not doc_name(match[0]): return match[0] url = urlreverse( "ietf.doc.views_doc.document_main", @@ -184,7 +189,7 @@ def link_non_charter_doc_match(match): name = match[0] # handle "I-D.*"" reference-style matches name = re.sub(r"^i-d\.(.*)", r"draft-\1", name, flags=re.IGNORECASE) - cname = doc_canonical_name(name) + cname = doc_name(name) if not cname: return match[0] if name == cname: @@ -199,7 +204,7 @@ def link_non_charter_doc_match(match): url = urlreverse("ietf.doc.views_doc.document_main", kwargs=dict(name=cname)) return f'{match[0]}' - cname = doc_canonical_name(name) + cname = doc_name(name) if not cname: return match[0] if name == cname: @@ -219,12 +224,11 @@ def link_non_charter_doc_match(match): def link_other_doc_match(match): doc = match[2].strip().lower() rev = match[3] - if not doc_canonical_name(doc + rev): + if not doc_name(doc + rev): return match[0] url = urlreverse("ietf.doc.views_doc.document_main", kwargs=dict(name=doc + rev)) return f'{match[1]}' - @register.filter(name="urlize_ietf_docs", is_safe=True, needs_autoescape=True) def urlize_ietf_docs(string, autoescape=None): """ @@ -248,58 +252,57 @@ def urlize_ietf_docs(string, autoescape=None): flags=re.IGNORECASE | re.ASCII, ) string = re.sub( - r"\b(?%(name)s' % dict(name=prettify_std_name(name), title=title, url=url) )) return links - -@register.filter(name='urlize_related_target_list', is_safe=True, needs_autoescape=True) -def urlize_related_target_list(related, autoescape=None): + +@register.filter(name='urlize_related_target_list', is_safe=True, document_html=False) +def urlize_related_target_list(related, document_html=False): """Convert a list of RelatedDocuments into list of links using the target document's canonical name""" links = [] for rel in related: - name=rel.target.document.canonical_name() - title = rel.target.document.title - url = urlreverse('ietf.doc.views_doc.document_main', kwargs=dict(name=name)) - if autoescape: - name = escape(name) - title = escape(title) + name=rel.target.name + title = rel.target.title + url = urlreverse('ietf.doc.views_doc.document_main' if document_html is False else 'ietf.doc.views_doc.document_html', kwargs=dict(name=name)) + name = escape(name) + title = escape(title) links.append(mark_safe( '%(name)s' % dict(name=prettify_std_name(name), title=title, url=url) )) return links - + @register.filter(name='dashify') def dashify(string): """ @@ -315,10 +318,19 @@ def underline(string): @register.filter(name='timesince_days') def timesince_days(date): - """Returns the number of days since 'date' (relative to now)""" + """Returns the number of days since 'date' (relative to now) + + >>> timesince_days(timezone.now() - datetime.timedelta(days=2)) + 2 + + >>> tz = ZoneInfo(settings.TIME_ZONE) + >>> timesince_days(timezone.now().astimezone(tz).date() - datetime.timedelta(days=2)) + 2 + + """ if date.__class__ is not datetime.datetime: - date = datetime.datetime(date.year, date.month, date.day) - delta = datetime.datetime.now() - date + date = datetime.datetime(date.year, date.month, date.day, tzinfo=ZoneInfo(settings.TIME_ZONE)) + delta = timezone.now() - date return delta.days @register.filter @@ -400,9 +412,9 @@ def startswith(x, y): return str(x).startswith(y) -@register.filter(name='removesuffix', is_safe=False) -def removesuffix(value, suffix): - """Remove an exact-match suffix +@register.filter(name='removeprefix', is_safe=False) +def removeprefix(value, prefix): + """Remove an exact-match prefix The is_safe flag is False because indiscriminate use of this could result in non-safe output. See https://docs.djangoproject.com/en/2.2/howto/custom-template-tags/#filters-and-auto-escaping @@ -410,8 +422,8 @@ def removesuffix(value, suffix): HTML-unsafe output. """ base = str(value) - if base.endswith(suffix): - return base[:-len(suffix)] + if base.startswith(prefix): + return base[len(prefix):] else: return base @@ -435,16 +447,16 @@ def ad_area(user): @register.filter def format_history_text(text, trunc_words=25): """Run history text through some cleaning and add ellipsis if it's too long.""" - full = mark_safe(bleach_cleaner.clean(text)) - full = bleach_linker.linkify(urlize_ietf_docs(full)) + full = mark_safe(clean_html(text)) + full = linkify(urlize_ietf_docs(full)) return format_snippet(full, trunc_words) @register.filter def format_snippet(text, trunc_words=25): # urlize if there aren't already links present - text = bleach_linker.linkify(text) - full = keep_spacing(collapsebr(linebreaksbr(mark_safe(sanitize_fragment(text))))) + text = linkify(text) + full = keep_spacing(collapsebr(linebreaksbr(mark_safe(clean_html(text))))) snippet = truncatewords_html(full, trunc_words) if snippet != full: return mark_safe('
%s
%s
' % (snippet, full)) @@ -468,6 +480,19 @@ def state(doc, slug): slug = "%s-stream-%s" % (doc.type_id, doc.stream_id) return doc.get_state(slug) + +@register.filter +def is_unexpected_wg_state(doc): + """Returns a flag indicating whether the document has an unexpected wg state.""" + if not doc.type_id == "draft": + return False + + draft_iesg_state = doc.get_state("draft-iesg") + draft_stream_state = doc.get_state("draft-stream-ietf") + + return draft_iesg_state.slug != "idexists" and draft_stream_state is not None and draft_stream_state.slug != "sub-pub" + + @register.filter def statehelp(state): "Output help icon with tooltip for state." @@ -496,10 +521,89 @@ def plural(text, seq, arg='s'): else: return text + pluralize(len(seq), arg) + +# Translation table to escape ICS characters. The {} | {} construction builds up a dict +# mapping characters to arbitrary-length strings or None. Values in later dicts override +# earlier ones prior to conversion to a translation table, so excluding a char and then +# mapping it to an escape sequence results in its being escaped, not dropped. +rfc5545_text_escapes = str.maketrans( + # text = *(TSAFE-CHAR / ":" / DQUOTE / ESCAPED-CHAR) + # TSAFE-CHAR = WSP / %x21 / %x23-2B / %x2D-39 / %x3C-5B / + # %x5D-7E / NON-US-ASCII + {chr(c): None for c in range(0x00, 0x20)} # strip 0x00-0x20 + | { + # ESCAPED-CHAR = ("\\" / "\;" / "\," / "\N" / "\n") + "\n": r"\n", + ";": r"\;", + ",": r"\,", + "\\": r"\\", # rhs is two backslashes! + "\t": "\t", # htab ok (0x09) + " ": " ", # space ok (0x20) + } +) + + @register.filter def ics_esc(text): - text = re.sub(r"([\n,;\\])", r"\\\1", text) - return text + """Escape a string to use in an iCalendar text context + + >>> ics_esc('simple') + 'simple' + + For the next tests, it helps to know: + chr(0x09) = "\t" + chr(0x0a) = "\n" + chr(0x0d) = "\r" + chr(0x5c) = "\\" + + >>> ics_esc(f'strips{chr(0x0d)}out{chr(0x0d)}LFs') + 'stripsoutLFs' + + + >>> ics_esc(f'escapes;and,and{chr(0x5c)}and{chr(0x0a)}') + 'escapes\\\\;and\\\\,and\\\\\\\\and\\\\n' + + >>> ics_esc(f"keeps spaces : and{chr(0x09)}tabs") + 'keeps spaces : and\\ttabs' + """ + return text.translate(rfc5545_text_escapes) + + +@register.simple_tag +def ics_date_time(dt, tzname): + """Render a datetime as an iCalendar date-time + + dt a datetime, localized to the timezone to be displayed + tzname is the name for this timezone + + Caller must arrange for a VTIMEZONE for the tzname to be included in the iCalendar file. + Output includes a ':'. Use like: + DTSTART{% ics_date_time timestamp 'America/Los_Angeles' %} + to get + DTSTART;TZID=America/Los_Angeles:20221021T111200 + + >>> ics_date_time(datetime.datetime(2022,1,2,3,4,5), 'utc') + ':20220102T030405Z' + + >>> ics_date_time(datetime.datetime(2022,1,2,3,4,5), 'UTC') + ':20220102T030405Z' + + >>> ics_date_time(datetime.datetime(2022,1,2,3,4,5), 'GmT') + ':20220102T030405Z' + + >>> ics_date_time(datetime.datetime(2022,1,2,3,4,5), 'America/Los_Angeles') + ';TZID=America/Los_Angeles:20220102T030405' + """ + timestamp = dt.strftime('%Y%m%dT%H%M%S') + if tzname.lower() in ('gmt', 'utc'): + return f':{timestamp}Z' + else: + return f';TZID={ics_esc(tzname)}:{timestamp}' + +@register.filter +def next_day(value): + return value + datetime.timedelta(days=1) + @register.filter def consensus(doc): @@ -513,6 +617,19 @@ def consensus(doc): else: return "Unknown" + +@register.filter +def std_level_to_label_format(doc): + """Returns valid Bootstrap classes to label a status level badge.""" + if doc.type_id == "rfc": + if doc.related_that("obs"): + return "obs" + else: + return doc.std_level_id + else: + return "draft" + + @register.filter def pos_to_label_format(text): """Returns valid Bootstrap classes to label a ballot position.""" @@ -525,6 +642,8 @@ def pos_to_label_format(text): 'Recuse': 'bg-recuse text-light', 'Not Ready': 'bg-discuss text-light', 'Need More Time': 'bg-discuss text-light', + 'Concern': 'bg-discuss text-light', + }.get(str(text), 'bg-norecord text-dark') @register.filter @@ -539,6 +658,7 @@ def pos_to_border_format(text): 'Recuse': 'border-recuse', 'Not Ready': 'border-discuss', 'Need More Time': 'border-discuss', + 'Concern': 'border-discuss', }.get(str(text), 'border-norecord') @register.filter @@ -598,7 +718,7 @@ def rfcbis(s): @stringfilter def urlize(value): raise RuntimeError("Use linkify from textfilters instead of urlize") - + @register.filter @stringfilter def charter_major_rev(rev): @@ -612,17 +732,25 @@ def charter_minor_rev(rev): @register.filter() def can_defer(user,doc): ballot = doc.latest_event(BallotDocEvent, type="created_ballot") - if ballot and (doc.type_id == "draft" or doc.type_id == "conflrev") and doc.stream_id == 'ietf' and has_role(user, 'Area Director,Secretariat'): + if ballot and (doc.type_id == "draft" or doc.type_id == "conflrev" or doc.type_id=="statchg") and doc.stream_id == 'ietf' and has_role(user, 'Area Director,Secretariat'): return True else: return False +@register.filter() +def can_clear_ballot(user, doc): + return can_defer(user, doc) + +@register.filter() +def can_request_rfc_publication(user, doc): + return utils_can_request_rfc_publication(user, doc) + @register.filter() def can_ballot(user,doc): - # Only IRSG memebers (and the secretariat, handled by code separately) can take positions on IRTF documents - # Otherwise, an AD can take a position on anything that has a ballot open - if doc.type_id == 'draft' and doc.stream_id == 'irtf': - return has_role(user,'IRSG Member') + if doc.stream_id == "irtf" and doc.type_id == "draft": + return has_role(user,"IRSG Member") + elif doc.stream_id == "editorial" and doc.type_id == "draft": + return has_role(user,"RSAB Member") else: return user.person.role_set.filter(name="ad", group__type="area", group__state="active") @@ -637,22 +765,22 @@ def action_holder_badge(action_holder): >>> action_holder_badge(DocumentActionHolderFactory()) '' - >>> action_holder_badge(DocumentActionHolderFactory(time_added=datetime.datetime.now() - datetime.timedelta(days=15))) + >>> action_holder_badge(DocumentActionHolderFactory(time_added=timezone.now() - datetime.timedelta(days=15))) '' - >>> action_holder_badge(DocumentActionHolderFactory(time_added=datetime.datetime.now() - datetime.timedelta(days=16))) - ' 16' + >>> action_holder_badge(DocumentActionHolderFactory(time_added=timezone.now() - datetime.timedelta(days=16))) + ' 16' - >>> action_holder_badge(DocumentActionHolderFactory(time_added=datetime.datetime.now() - datetime.timedelta(days=30))) - ' 30' + >>> action_holder_badge(DocumentActionHolderFactory(time_added=timezone.now() - datetime.timedelta(days=30))) + ' 30' >>> settings.DOC_ACTION_HOLDER_AGE_LIMIT_DAYS = old_limit """ age_limit = settings.DOC_ACTION_HOLDER_AGE_LIMIT_DAYS - age = (datetime.datetime.now() - action_holder.time_added).days + age = (timezone.now() - action_holder.time_added).days if age > age_limit: return mark_safe( - ' %d' + ' %d' % (age, "s" if age != 1 else "", age_limit, age) ) else: @@ -779,3 +907,171 @@ def is_valid_url(url): except ValidationError: return False return True + + +@register.filter +def badgeify(blob): + """ + Add an appropriate bootstrap badge around "text", based on its contents. + """ + config = [ + (r"rejected|not ready|serious issues", "danger", "x-lg"), + (r"complete|accepted|ready", "success", ""), + (r"has nits|almost ready", "info", "info-lg"), + (r"has issues|on the right track", "warning", "exclamation-lg"), + (r"assigned", "info", "person-plus-fill"), + (r"will not review|overtaken by events|withdrawn", "secondary", "dash-lg"), + (r"no response", "warning", "question-lg"), + ] + text = str(blob) + + for pattern, color, icon in config: + if re.search(pattern, text, flags=re.IGNORECASE): + # Shorten the badge text + text = re.sub(r"with ", "w/", text, flags=re.IGNORECASE) + text = re.sub(r"document", "doc", text, flags=re.IGNORECASE) + text = re.sub(r"will not", "won't", text, flags=re.IGNORECASE) + + return mark_safe( + f""" + + {text.capitalize()} + + """ + ) + + return text + +@register.filter +def simple_history_delta_changes(history): + """Returns diff between given history and previous entry.""" + prev = history.prev_record + if prev: + delta = history.diff_against(prev) + return delta.changes + return [] + +@register.filter +def simple_history_delta_change_cnt(history): + """Returns number of changes between given history and previous entry.""" + prev = history.prev_record + if prev: + delta = history.diff_against(prev) + return len(delta.changes) + return 0 + +@register.filter +def mtime(path): + """Returns a datetime object representing mtime given a pathlib Path object""" + return datetime.datetime.fromtimestamp(path.stat().st_mtime).astimezone(ZoneInfo(settings.TIME_ZONE)) + +@register.filter +def mtime_is_epoch(path): + return path.stat().st_mtime == 0 + +@register.filter +def url_for_path(path): + """Consructs a 'best' URL for web access to the given pathlib Path object. + + Assumes that the path is into the Internet-Draft archive or the proceedings. + """ + if Path(settings.AGENDA_PATH) in path.parents: + return ( + f"https://www.ietf.org/proceedings/{path.relative_to(settings.AGENDA_PATH)}" + ) + elif any( + [ + pathdir in path.parents + for pathdir in [ + Path(settings.INTERNET_DRAFT_PATH), + Path(settings.INTERNET_DRAFT_ARCHIVE_DIR).parent, + Path(settings.INTERNET_ALL_DRAFTS_ARCHIVE_DIR), + ] + ] + ): + return f"{settings.IETF_ID_ARCHIVE_URL}{path.name}" + else: + return "#" + + +@register.filter +def is_in_stream(doc): + """ + Check if the doc is in one of the states in it stream that + indicate that is actually adopted, i.e., part of the stream. + (There are various "candidate" states that necessitate this + filter.) + """ + if not doc.stream: + return False + stream = doc.stream.slug + state = doc.get_state_slug(f"draft-stream-{doc.stream.slug}") + if not state: + return True + if stream == "ietf": + return state not in ["wg-cand", "c-adopt"] + elif stream == "irtf": + return state != "candidat" + elif stream == "iab": + return state not in ["candidat", "diff-org"] + elif stream == "editorial": + return True + return False + + +@register.filter +def is_doc_ietf_adoptable(doc): + return doc.stream_id is None or all( + [ + doc.stream_id == "ietf", + doc.get_state_slug("draft-stream-ietf") + not in [ + "c-adopt", + "adopt-wg", + "info", + "wg-doc", + "parked", + "dead", + "wg-lc", + "waiting-for-implementation", + "chair-w", + "writeupw", + "sub-pub", + ], + doc.get_state_slug("draft") != "rfc", + doc.became_rfc() is None, + ] + ) + + +@register.filter +def can_issue_ietf_wg_lc(doc): + return all( + [ + doc.stream_id == "ietf", + doc.get_state_slug("draft-stream-ietf") + not in ["wg-cand", "c-adopt", "wg-lc"], + doc.get_state_slug("draft") != "rfc", + doc.became_rfc() is None, + ] + ) + + +@register.filter +def can_submit_to_iesg(doc): + return all( + [ + doc.stream_id == "ietf", + doc.get_state_slug("draft-iesg") == "idexists", + doc.get_state_slug("draft-stream-ietf") not in ["wg-cand", "c-adopt"], + ] + ) + + +@register.filter +def has_had_ietf_wg_lc(doc): + return ( + doc.stream_id == "ietf" + and doc.docevent_set.filter(statedocevent__state__slug="wg-lc").exists() + ) + diff --git a/ietf/doc/templatetags/mail_filters.py b/ietf/doc/templatetags/mail_filters.py index 32e8dd0ca8c..6be6620315b 100644 --- a/ietf/doc/templatetags/mail_filters.py +++ b/ietf/doc/templatetags/mail_filters.py @@ -9,7 +9,7 @@ def std_level_prompt(doc): to the object's intended_std_level (with the word RFC appended in some cases), or a prompt requesting that the intended_std_level be set.""" - prompt = "*** YOU MUST SELECT AN INTENDED STATUS FOR THIS DRAFT AND REGENERATE THIS TEXT ***" + prompt = "*** YOU MUST SELECT AN INTENDED STATUS FOR THIS INTERNET-DRAFT AND REGENERATE THIS TEXT ***" if doc.intended_std_level: prompt = doc.intended_std_level.name diff --git a/ietf/doc/templatetags/tests_ietf_filters.py b/ietf/doc/templatetags/tests_ietf_filters.py index f791d615301..b5130849ea2 100644 --- a/ietf/doc/templatetags/tests_ietf_filters.py +++ b/ietf/doc/templatetags/tests_ietf_filters.py @@ -3,13 +3,26 @@ from django.conf import settings from ietf.doc.factories import ( - WgDraftFactory, + WgRfcFactory, IndividualDraftFactory, CharterFactory, NewRevisionDocEventFactory, + StatusChangeFactory, + RgDraftFactory, + EditorialDraftFactory, + WgDraftFactory, + ConflictReviewFactory, + BofreqFactory, + StatementFactory, + RfcFactory, +) +from ietf.doc.models import DocEvent +from ietf.doc.templatetags.ietf_filters import ( + urlize_ietf_docs, + is_valid_url, + is_in_stream, + is_unexpected_wg_state, ) -from ietf.doc.models import State, DocEvent, DocAlias -from ietf.doc.templatetags.ietf_filters import urlize_ietf_docs, is_valid_url from ietf.person.models import Person from ietf.utils.test_utils import TestCase @@ -19,29 +32,42 @@ class IetfFiltersTests(TestCase): + def test_is_in_stream(self): + for draft in [ + IndividualDraftFactory(), + CharterFactory(), + StatusChangeFactory(), + ConflictReviewFactory(), + StatementFactory(), + BofreqFactory(), + ]: + self.assertFalse(is_in_stream(draft)) + for draft in [RgDraftFactory(), WgDraftFactory(), EditorialDraftFactory()]: + self.assertTrue(is_in_stream(draft)) + for stream in ["iab", "ietf", "irtf", "ise", "editorial"]: + self.assertTrue(is_in_stream(IndividualDraftFactory(stream_id=stream))) + def test_is_valid_url(self): cases = [(settings.IDTRACKER_BASE_URL, True), ("not valid", False)] for url, result in cases: self.assertEqual(is_valid_url(url), result) def test_urlize_ietf_docs(self): - wg_id = WgDraftFactory() - wg_id.set_state(State.objects.get(type="draft", slug="rfc")) - wg_id.std_level_id = "bcp" - wg_id.save_with_history( + rfc = WgRfcFactory(rfc_number=123456, std_level_id="bcp") + rfc.save_with_history( [ DocEvent.objects.create( - doc=wg_id, - rev=wg_id.rev, + doc=rfc, + rev=rfc.rev, type="published_rfc", by=Person.objects.get(name="(System)"), ) ] ) - DocAlias.objects.create(name="rfc123456").docs.add(wg_id) - DocAlias.objects.create(name="bcp123456").docs.add(wg_id) - DocAlias.objects.create(name="std123456").docs.add(wg_id) - DocAlias.objects.create(name="fyi123456").docs.add(wg_id) + # TODO - bring these into existance when subseries are well modeled + # DocAlias.objects.create(name="bcp123456").docs.add(rfc) + # DocAlias.objects.create(name="std123456").docs.add(rfc) + # DocAlias.objects.create(name="fyi123456").docs.add(rfc) id = IndividualDraftFactory(name="draft-me-rfc123456bis") id_num = IndividualDraftFactory(name="draft-rosen-rfcefdp-update-2026") @@ -59,15 +85,16 @@ def test_urlize_ietf_docs(self): cases = [ ("no change", "no change"), - ("bCp123456", 'bCp123456'), - ("Std 00123456", 'Std 00123456'), - ( - "FyI 0123456 changes std 00123456", - 'FyI 0123456 changes std 00123456', - ), + # TODO: rework subseries when we add them + # ("bCp123456", 'bCp123456'), + # ("Std 00123456", 'Std 00123456'), + # ( + # "FyI 0123456 changes std 00123456", + # 'FyI 0123456 changes std 00123456', + # ), ("rfc123456", 'rfc123456'), ("Rfc 0123456", 'Rfc 0123456'), - (wg_id.name, f'{wg_id.name}'), + (rfc.name, f'{rfc.name}'), ( f"{id.name}-{id.rev}.txt", f'{id.name}-{id.rev}.txt', @@ -149,3 +176,17 @@ def test_urlize_ietf_docs(self): for input, output in cases: # debug.show("(input, urlize_ietf_docs(input), output)") self.assertEqual(urlize_ietf_docs(input), output) + + def test_is_unexpected_wg_state(self): + """ + Test that the unexpected_wg_state function works correctly + """ + # test documents with expected wg states + self.assertFalse(is_unexpected_wg_state(RfcFactory())) + self.assertFalse(is_unexpected_wg_state(WgDraftFactory (states=[('draft-stream-ietf', 'sub-pub')]))) + self.assertFalse(is_unexpected_wg_state(WgDraftFactory (states=[('draft-iesg', 'idexists')]))) + self.assertFalse(is_unexpected_wg_state(WgDraftFactory (states=[('draft-stream-ietf', 'wg-cand'), ('draft-iesg','idexists')]))) + + # test documents with unexpected wg states due to invalid combination of states + self.assertTrue(is_unexpected_wg_state(WgDraftFactory (states=[('draft-stream-ietf', 'wg-cand'), ('draft-iesg','lc-req')]))) + self.assertTrue(is_unexpected_wg_state(WgDraftFactory (states=[('draft-stream-ietf', 'chair-w'), ('draft-iesg','pub-req')]))) diff --git a/ietf/doc/templatetags/wg_menu.py b/ietf/doc/templatetags/wg_menu.py index e82f125c076..3e8d209448a 100644 --- a/ietf/doc/templatetags/wg_menu.py +++ b/ietf/doc/templatetags/wg_menu.py @@ -1,4 +1,4 @@ -# Copyright The IETF Trust 2009-2022, All Rights Reserved +# Copyright The IETF Trust 2009-2023, All Rights Reserved # Copyright (C) 2009-2010 Nokia Corporation and/or its subsidiary(-ies). # All rights reserved. Contact: Pasi Eronen @@ -32,6 +32,8 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +import debug # pyflakes: ignore + from django import template from django.template.loader import render_to_string from django.db import models @@ -60,15 +62,13 @@ @register.simple_tag def wg_menu(flavor): - global parents - for p in parents: p.short_name = parent_short_names.get(p.acronym) or p.name if p.short_name.endswith(" Area"): p.short_name = p.short_name[: -len(" Area")] if p.type_id == "area": - p.menu_url = "/wg/#" + p.acronym + p.menu_url = "/wg/#" + p.acronym.upper() elif p.acronym == "irtf": p.menu_url = "/rg/" elif p.acronym == "iab": diff --git a/ietf/doc/tests.py b/ietf/doc/tests.py index e01b5e0bd80..6f15003f92f 100644 --- a/ietf/doc/tests.py +++ b/ietf/doc/tests.py @@ -1,13 +1,16 @@ -# Copyright The IETF Trust 2012-2020, All Rights Reserved +# Copyright The IETF Trust 2012-2024, All Rights Reserved # -*- coding: utf-8 -*- import os import datetime import io +from hashlib import sha384 + +from django.http import HttpRequest import lxml import bibtexparser -import mock +from unittest import mock import json import copy import random @@ -16,32 +19,47 @@ from pathlib import Path from pyquery import PyQuery from urllib.parse import urlparse, parse_qs -from tempfile import NamedTemporaryFile from collections import defaultdict +from zoneinfo import ZoneInfo -from django.core.management import call_command from django.urls import reverse as urlreverse from django.conf import settings from django.forms import Form from django.utils.html import escape from django.test import override_settings +from django.utils import timezone from django.utils.text import slugify from tastypie.test import ResourceTestCaseMixin +from weasyprint.urls import URLFetchingError + import debug # pyflakes:ignore -from ietf.doc.models import ( Document, DocAlias, DocRelationshipName, RelatedDocument, State, - DocEvent, BallotPositionDocEvent, LastCallDocEvent, WriteupDocEvent, NewRevisionDocEvent, BallotType, - EditedAuthorsDocEvent ) -from ietf.doc.factories import ( DocumentFactory, DocEventFactory, CharterFactory, - ConflictReviewFactory, WgDraftFactory, IndividualDraftFactory, WgRfcFactory, - IndividualRfcFactory, StateDocEventFactory, BallotPositionDocEventFactory, - BallotDocEventFactory, DocumentAuthorFactory, NewRevisionDocEventFactory, - StatusChangeFactory, BofreqFactory) +from ietf.doc.models import (Document, DocRelationshipName, RelatedDocument, State, + DocEvent, BallotPositionDocEvent, LastCallDocEvent, WriteupDocEvent, NewRevisionDocEvent, BallotType, + EditedAuthorsDocEvent, StateType, RfcAuthor, RpcAssignmentDocEvent) +from ietf.doc.factories import (DocumentFactory, DocEventFactory, CharterFactory, + ConflictReviewFactory, WgDraftFactory, + IndividualDraftFactory, WgRfcFactory, + IndividualRfcFactory, StateDocEventFactory, + BallotPositionDocEventFactory, + BallotDocEventFactory, DocumentAuthorFactory, + NewRevisionDocEventFactory, + StatusChangeFactory, DocExtResourceFactory, + RgDraftFactory, BcpFactory, RfcAuthorFactory) +from ietf.doc.forms import NotifyForm from ietf.doc.fields import SearchableDocumentsField -from ietf.doc.utils import create_ballot_if_not_open, uppercase_std_abbreviated_name -from ietf.doc.views_search import ad_dashboard_group, ad_dashboard_group_type, shorten_group_name # TODO: red flag that we're importing from views in tests. Move these to utils. +from ietf.doc.utils import ( + create_ballot_if_not_open, + investigate_fragment, + uppercase_std_abbreviated_name, + DraftAliasGenerator, + generate_idnits2_rfc_status, + generate_idnits2_rfcs_obsoleted, + get_doc_email_aliases, +) +from ietf.doc.views_doc import get_diff_revisions from ietf.group.models import Group, Role from ietf.group.factories import GroupFactory, RoleFactory from ietf.ipr.factories import HolderIprDisclosureFactory @@ -49,18 +67,22 @@ from ietf.meeting.factories import ( MeetingFactory, SessionFactory, SessionPresentationFactory, ProceedingsMaterialFactory ) -from ietf.name.models import SessionStatusName, BallotPositionName, DocTypeName +from ietf.name.models import SessionStatusName, BallotPositionName, DocTypeName, RoleName from ietf.person.models import Person from ietf.person.factories import PersonFactory, EmailFactory -from ietf.utils.mail import outbox, empty_outbox -from ietf.utils.test_utils import login_testing_unauthorized, unicontent, reload_db_objects +from ietf.utils.mail import get_payload_text, outbox, empty_outbox +from ietf.utils.test_utils import login_testing_unauthorized, unicontent from ietf.utils.test_utils import TestCase -from ietf.utils.text import normalize_text +from ietf.utils.text import normalize_text, texescape +from ietf.utils.timezone import date_today, datetime_today, DEADLINE_TZINFO, RPC_TZINFO +from ietf.doc.utils_search import AD_WORKLOAD + class SearchTests(TestCase): def test_search(self): draft = WgDraftFactory(name='draft-ietf-mars-test',group=GroupFactory(acronym='mars',parent=Group.objects.get(acronym='farfut')),authors=[PersonFactory()],ad=PersonFactory()) + rfc = WgRfcFactory() draft.set_state(State.objects.get(used=True, type="draft-iesg", slug="pub-req")) old_draft = IndividualDraftFactory(name='draft-foo-mars-test',authors=[PersonFactory()],title="Optimizing Martian Network Topologies") old_draft.set_state(State.objects.get(used=True, type="draft", slug="expired")) @@ -88,11 +110,16 @@ def test_search(self): self.assertEqual(r.status_code, 200) self.assertContains(r, "draft-foo-mars-test") - # find by rfc/active/inactive - draft.set_state(State.objects.get(type="draft", slug="rfc")) - r = self.client.get(base_url + "?rfcs=on&name=%s" % draft.name) + r = self.client.get(base_url + "?olddrafts=on&name=FoO") # mixed case self.assertEqual(r.status_code, 200) - self.assertContains(r, draft.title) + self.assertContains(r, "draft-foo-mars-test") + + # find by RFC + r = self.client.get(base_url + "?rfcs=on&name=%s" % rfc.name) + self.assertEqual(r.status_code, 200) + self.assertContains(r, rfc.title) + + # find by active/inactive draft.set_state(State.objects.get(type="draft", slug="active")) r = self.client.get(base_url + "?activedrafts=on&name=%s" % draft.name) @@ -121,6 +148,10 @@ def test_search(self): self.assertEqual(r.status_code, 200) self.assertContains(r, draft.title) + r = self.client.get(base_url + "?activedrafts=on&by=group&group=%s" % draft.group.acronym.swapcase()) + self.assertEqual(r.status_code, 200) + self.assertContains(r, draft.title) + # find by area r = self.client.get(base_url + "?activedrafts=on&by=area&area=%s" % draft.group.parent_id) self.assertEqual(r.status_code, 200) @@ -141,6 +172,23 @@ def test_search(self): self.assertEqual(r.status_code, 200) self.assertContains(r, draft.title) + def test_search_became_rfc(self): + draft = WgDraftFactory() + rfc = WgRfcFactory() + draft.set_state(State.objects.get(type="draft", slug="rfc")) + draft.relateddocument_set.create(relationship_id="became_rfc", target=rfc) + base_url = urlreverse('ietf.doc.views_search.search') + + # find by RFC + r = self.client.get(base_url + f"?rfcs=on&name={rfc.name}") + self.assertEqual(r.status_code, 200) + self.assertContains(r, rfc.title) + + # find by draft + r = self.client.get(base_url + f"?activedrafts=on&rfcs=on&name={draft.name}") + self.assertEqual(r.status_code, 200) + self.assertContains(r, rfc.title) + def test_search_for_name(self): draft = WgDraftFactory(name='draft-ietf-mars-test',group=GroupFactory(acronym='mars',parent=Group.objects.get(acronym='farfut')),authors=[PersonFactory()],ad=PersonFactory()) draft.set_state(State.objects.get(used=True, type="draft-iesg", slug="pub-req")) @@ -162,16 +210,39 @@ def test_search_for_name(self): self.assertEqual(r.status_code, 302) self.assertEqual(urlparse(r["Location"]).path, urlreverse("ietf.doc.views_doc.document_main", kwargs=dict(name=draft.name))) + # mixed-up case exact match + r = self.client.get(urlreverse('ietf.doc.views_search.search_for_name', kwargs=dict(name=draft.name.swapcase()))) + self.assertEqual(r.status_code, 302) + self.assertEqual(urlparse(r["Location"]).path, urlreverse("ietf.doc.views_doc.document_main", kwargs=dict(name=draft.name))) + # prefix match r = self.client.get(urlreverse('ietf.doc.views_search.search_for_name', kwargs=dict(name="-".join(draft.name.split("-")[:-1])))) self.assertEqual(r.status_code, 302) self.assertEqual(urlparse(r["Location"]).path, urlreverse("ietf.doc.views_doc.document_main", kwargs=dict(name=draft.name))) + # mixed-up case prefix match + r = self.client.get( + urlreverse( + 'ietf.doc.views_search.search_for_name', + kwargs=dict(name="-".join(draft.name.swapcase().split("-")[:-1])), + )) + self.assertEqual(r.status_code, 302) + self.assertEqual(urlparse(r["Location"]).path, urlreverse("ietf.doc.views_doc.document_main", kwargs=dict(name=draft.name))) + # non-prefix match r = self.client.get(urlreverse('ietf.doc.views_search.search_for_name', kwargs=dict(name="-".join(draft.name.split("-")[1:])))) self.assertEqual(r.status_code, 302) self.assertEqual(urlparse(r["Location"]).path, urlreverse("ietf.doc.views_doc.document_main", kwargs=dict(name=draft.name))) + # mixed-up case non-prefix match + r = self.client.get( + urlreverse( + 'ietf.doc.views_search.search_for_name', + kwargs=dict(name="-".join(draft.name.swapcase().split("-")[1:])), + )) + self.assertEqual(r.status_code, 302) + self.assertEqual(urlparse(r["Location"]).path, urlreverse("ietf.doc.views_doc.document_main", kwargs=dict(name=draft.name))) + # other doctypes than drafts doc = Document.objects.get(name='charter-ietf-mars') r = self.client.get(urlreverse('ietf.doc.views_search.search_for_name', kwargs=dict(name='charter-ietf-ma'))) @@ -225,6 +296,17 @@ def test_search_for_name(self): parsed = urlparse(r["Location"]) self.assertEqual(parsed.path, urlreverse('ietf.doc.views_search.search')) self.assertEqual(parse_qs(parsed.query)["name"][0], "draft-ietf-doesnotexist-42") + + def test_search_rfc(self): + rfc = WgRfcFactory(name="rfc0000") + + # search for existing RFC should redirect directly to the RFC page + r = self.client.get(urlreverse('ietf.doc.views_search.search_for_name', kwargs=dict(name=rfc.name))) + self.assertRedirects(r, f'/doc/{rfc.name}/', status_code=302, target_status_code=200) + + # search for existing RFC with revision number should redirect to the RFC page + r = self.client.get(urlreverse('ietf.doc.views_search.search_for_name', kwargs=dict(name=rfc.name + "-99")), follow=True) + self.assertRedirects(r, f'/doc/{rfc.name}/', status_code=302, target_status_code=200) def test_frontpage(self): r = self.client.get("/") @@ -232,52 +314,68 @@ def test_frontpage(self): self.assertContains(r, "Document Search") def test_ad_workload(self): - Role.objects.filter(name_id='ad').delete() - ad = RoleFactory(name_id='ad',group__type_id='area',group__state_id='active',person__name='Example Areadirector').person - doc_type_names = ['bofreq', 'charter', 'conflrev', 'draft', 'statchg'] - expected = defaultdict(lambda :0) - for doc_type_name in doc_type_names: - if doc_type_name=='draft': - states = State.objects.filter(type='draft-iesg', used=True).values_list('slug', flat=True) - else: - states = State.objects.filter(type=doc_type_name, used=True).values_list('slug', flat=True) - - for state in states: - target_num = random.randint(0,2) + Role.objects.filter(name_id="ad").delete() + ad = RoleFactory( + name_id="ad", + group__type_id="area", + group__state_id="active", + person__name="Example Areadirector", + ).person + expected = defaultdict(lambda: 0) + for doc_type_slug in AD_WORKLOAD: + for state in AD_WORKLOAD[doc_type_slug]: + target_num = random.randint(0, 2) for _ in range(target_num): - if doc_type_name == 'draft': - doc = IndividualDraftFactory(ad=ad,states=[('draft-iesg', state),('draft','rfc' if state=='pub' else 'active')]) - elif doc_type_name == 'charter': - doc = CharterFactory(ad=ad, states=[(doc_type_name, state)]) - elif doc_type_name == 'bofreq': - # Note that the view currently doesn't handle bofreqs - doc = BofreqFactory(states=[(doc_type_name, state)], bofreqresponsibledocevent__responsible=[ad]) - elif doc_type_name == 'conflrev': - doc = ConflictReviewFactory(ad=ad, states=State.objects.filter(type_id=doc_type_name, slug=state)) - elif doc_type_name == 'statchg': - doc = StatusChangeFactory(ad=ad, states=State.objects.filter(type_id=doc_type_name, slug=state)) - else: - # Currently unreachable - doc = DocumentFactory(type_id=doc_type_name, ad=ad, states=[(doc_type_name, state)]) - - if not slugify(ad_dashboard_group_type(doc)) in ('document', 'none'): - expected[(slugify(ad_dashboard_group_type(doc)), slugify(ad.full_name_as_key()), slugify(shorten_group_name(ad_dashboard_group(doc))))] += 1 - - url = urlreverse('ietf.doc.views_search.ad_workload') + if ( + doc_type_slug == "draft" + or doc_type_slug == "rfc" + and state == "rfcqueue" + ): + IndividualDraftFactory( + ad=ad, + states=[ + ("draft-iesg", state), + ("draft", "rfc" if state == "pub" else "active"), + ], + ) + elif doc_type_slug == "rfc": + WgRfcFactory.create( + states=[("draft", "rfc"), ("draft-iesg", "pub")] + ) + + elif doc_type_slug == "charter": + CharterFactory(ad=ad, states=[(doc_type_slug, state)]) + elif doc_type_slug == "conflrev": + ConflictReviewFactory( + ad=ad, + states=State.objects.filter( + type_id=doc_type_slug, slug=state + ), + ) + elif doc_type_slug == "statchg": + StatusChangeFactory( + ad=ad, + states=State.objects.filter( + type_id=doc_type_slug, slug=state + ), + ) + self.client.login(username="ad", password="ad+password") + url = urlreverse("ietf.doc.views_search.ad_workload") r = self.client.get(url) self.assertEqual(r.status_code, 200) q = PyQuery(r.content) for group_type, ad, group in expected: - self.assertEqual(int(q(f'#{group_type}-{ad}-{group}').text()),expected[(group_type, ad, group)]) + self.assertEqual( + int(q(f"#{group_type}-{ad}-{group}").text()), + expected[(group_type, ad, group)], + ) def test_docs_for_ad(self): ad = RoleFactory(name_id='ad',group__type_id='area',group__state_id='active').person draft = IndividualDraftFactory(ad=ad) draft.action_holders.set([PersonFactory()]) draft.set_state(State.objects.get(type='draft-iesg', slug='lc')) - rfc = IndividualDraftFactory(ad=ad) - rfc.set_state(State.objects.get(type='draft', slug='rfc')) - DocAlias.objects.create(name='rfc6666').docs.add(rfc) + rfc = IndividualRfcFactory(ad=ad) conflrev = DocumentFactory(type_id='conflrev',ad=ad) conflrev.set_state(State.objects.get(type='conflrev', slug='iesgeval')) statchg = DocumentFactory(type_id='statchg',ad=ad) @@ -301,7 +399,7 @@ def test_docs_for_ad(self): self.assertEqual(r.status_code, 200) self.assertContains(r, draft.name) self.assertContains(r, escape(draft.action_holders.first().name)) - self.assertContains(r, rfc.canonical_name()) + self.assertContains(r, rfc.name) self.assertContains(r, conflrev.name) self.assertContains(r, statchg.name) self.assertContains(r, charter.name) @@ -309,6 +407,30 @@ def test_docs_for_ad(self): self.assertContains(r, discuss_other.doc.name) self.assertContains(r, block_other.doc.name) + def test_docs_for_iesg(self): + ad1 = RoleFactory(name_id='ad',group__type_id='area',group__state_id='active').person + ad2 = RoleFactory(name_id='ad',group__type_id='area',group__state_id='active').person + + draft = IndividualDraftFactory(ad=ad1) + draft.action_holders.set([PersonFactory()]) + draft.set_state(State.objects.get(type='draft-iesg', slug='lc')) + rfc = IndividualRfcFactory(ad=ad2) + conflrev = DocumentFactory(type_id='conflrev',ad=ad1) + conflrev.set_state(State.objects.get(type='conflrev', slug='iesgeval')) + statchg = DocumentFactory(type_id='statchg',ad=ad2) + statchg.set_state(State.objects.get(type='statchg', slug='iesgeval')) + charter = CharterFactory(name='charter-ietf-ames',ad=ad1) + charter.set_state(State.objects.get(type='charter', slug='iesgrev')) + + r = self.client.get(urlreverse('ietf.doc.views_search.docs_for_iesg')) + self.assertEqual(r.status_code, 200) + self.assertContains(r, draft.name) + self.assertContains(r, escape(draft.action_holders.first().name)) + self.assertNotContains(r, rfc.name) + self.assertContains(r, conflrev.name) + self.assertContains(r, statchg.name) + self.assertContains(r, charter.name) + def test_auth48_doc_for_ad(self): """Docs in AUTH48 state should have a decoration""" ad = RoleFactory(name_id='ad', group__type_id='area', group__state_id='active').person @@ -331,17 +453,6 @@ def test_drafts_in_last_call(self): self.assertContains(r, draft.title) self.assertContains(r, escape(draft.action_holders.first().name)) - def test_in_iesg_process(self): - doc_in_process = IndividualDraftFactory() - doc_in_process.action_holders.set([PersonFactory()]) - doc_in_process.set_state(State.objects.get(type='draft-iesg', slug='lc')) - doc_not_in_process = IndividualDraftFactory() - r = self.client.get(urlreverse('ietf.doc.views_search.drafts_in_iesg_process')) - self.assertEqual(r.status_code, 200) - self.assertContains(r, doc_in_process.title) - self.assertContains(r, escape(doc_in_process.action_holders.first().name)) - self.assertNotContains(r, doc_not_in_process.title) - def test_indexes(self): draft = IndividualDraftFactory() rfc = WgRfcFactory() @@ -349,16 +460,17 @@ def test_indexes(self): r = self.client.get(urlreverse('ietf.doc.views_search.index_all_drafts')) self.assertEqual(r.status_code, 200) self.assertContains(r, draft.name) - self.assertContains(r, rfc.canonical_name().upper()) + self.assertContains(r, rfc.name.upper()) r = self.client.get(urlreverse('ietf.doc.views_search.index_active_drafts')) self.assertEqual(r.status_code, 200) self.assertContains(r, draft.title) def test_ajax_search_docs(self): - draft = IndividualDraftFactory() + draft = IndividualDraftFactory(name="draft-ietf-rfc1234bis") + rfc = IndividualRfcFactory(rfc_number=1234) + bcp = IndividualRfcFactory(name="bcp12345", type_id="bcp") - # Document url = urlreverse('ietf.doc.views_search.ajax_select2_search_docs', kwargs={ "model_name": "document", "doc_type": "draft", @@ -368,38 +480,47 @@ def test_ajax_search_docs(self): data = r.json() self.assertEqual(data[0]["id"], draft.pk) - # DocAlias - doc_alias = draft.docalias.first() - url = urlreverse('ietf.doc.views_search.ajax_select2_search_docs', kwargs={ - "model_name": "docalias", - "doc_type": "draft", + "model_name": "document", + "doc_type": "rfc", }) + r = self.client.get(url, dict(q=rfc.name)) + self.assertEqual(r.status_code, 200) + data = r.json() + self.assertEqual(data[0]["id"], rfc.pk) - r = self.client.get(url, dict(q=doc_alias.name)) + url = urlreverse('ietf.doc.views_search.ajax_select2_search_docs', kwargs={ + "model_name": "document", + "doc_type": "all", + }) + r = self.client.get(url, dict(q="1234")) self.assertEqual(r.status_code, 200) data = r.json() - self.assertEqual(data[0]["id"], doc_alias.pk) + self.assertEqual(len(data), 3) + pks = set([data[i]["id"] for i in range(3)]) + self.assertEqual(pks, set([bcp.pk, rfc.pk, draft.pk])) + + def test_recent_drafts(self): # Three drafts to show with various warnings drafts = WgDraftFactory.create_batch(3,states=[('draft','active'),('draft-iesg','ad-eval')]) for index, draft in enumerate(drafts): - StateDocEventFactory(doc=draft, state=('draft-iesg','ad-eval'), time=datetime.datetime.now()-datetime.timedelta(days=[1,15,29][index])) + StateDocEventFactory(doc=draft, state=('draft-iesg','ad-eval'), time=timezone.now()-datetime.timedelta(days=[1,15,29][index])) draft.action_holders.set([PersonFactory()]) # And one draft that should not show (with the default of 7 days to view) old = WgDraftFactory() - old.docevent_set.filter(newrevisiondocevent__isnull=False).update(time=datetime.datetime.now()-datetime.timedelta(days=8)) - StateDocEventFactory(doc=old, time=datetime.datetime.now()-datetime.timedelta(days=8)) + old.docevent_set.filter(newrevisiondocevent__isnull=False).update(time=timezone.now()-datetime.timedelta(days=8)) + StateDocEventFactory(doc=old, time=timezone.now()-datetime.timedelta(days=8)) url = urlreverse('ietf.doc.views_search.recent_drafts') r = self.client.get(url) self.assertEqual(r.status_code, 200) q = PyQuery(r.content) self.assertEqual(len(q('td.doc')),3) - self.assertTrue(q('td.status span.bg-warning[title*="%s"]' % "for 15 days")) - self.assertTrue(q('td.status span.bg-danger[title*="%s"]' % "for 29 days")) + self.assertTrue(q('td.status span.text-bg-warning[title*="%s"]' % "for 15 days")) + self.assertTrue(q('td.status span.text-bg-danger[title*="%s"]' % "for 29 days")) for ah in [draft.action_holders.first() for draft in drafts]: self.assertContains(r, escape(ah.name)) @@ -485,7 +606,7 @@ class DocDraftTestCase(TestCase): 1. Introduction This document describes how to make the Martian networks work. The - methods used in Earth do not directly translate to the efficent + methods used in Earth do not directly translate to the efficient networks on Mars, as the topographical differences caused by planets. For example the avian carriers, cannot be used in the Mars, thus RFC1149 ([RFC1149]) cannot be used in Mars. @@ -581,21 +702,24 @@ def setUp(self): f.write(self.draft_text) def test_document_draft(self): - draft = WgDraftFactory(name='draft-ietf-mars-test',rev='01') + draft = WgDraftFactory(name='draft-ietf-mars-test',rev='01', create_revisions=range(0,2)) + HolderIprDisclosureFactory(docs=[draft]) # Docs for testing relationships. Does not test 'possibly-replaces'. The 'replaced_by' direction # is tested separately below. replaced = IndividualDraftFactory() - draft.relateddocument_set.create(relationship_id='replaces',source=draft,target=replaced.docalias.first()) + draft.relateddocument_set.create(relationship_id='replaces',source=draft,target=replaced) obsoleted = IndividualDraftFactory() - draft.relateddocument_set.create(relationship_id='obs',source=draft,target=obsoleted.docalias.first()) + draft.relateddocument_set.create(relationship_id='obs',source=draft,target=obsoleted) obsoleted_by = IndividualDraftFactory() - obsoleted_by.relateddocument_set.create(relationship_id='obs',source=obsoleted_by,target=draft.docalias.first()) + obsoleted_by.relateddocument_set.create(relationship_id='obs',source=obsoleted_by,target=draft) updated = IndividualDraftFactory() - draft.relateddocument_set.create(relationship_id='updates',source=draft,target=updated.docalias.first()) + draft.relateddocument_set.create(relationship_id='updates',source=draft,target=updated) updated_by = IndividualDraftFactory() - updated_by.relateddocument_set.create(relationship_id='updates',source=obsoleted_by,target=draft.docalias.first()) + updated_by.relateddocument_set.create(relationship_id='updates',source=obsoleted_by,target=draft) + + DocExtResourceFactory(doc=draft) # these tests aren't testing all attributes yet, feel free to # expand them @@ -606,68 +730,32 @@ def test_document_draft(self): if settings.USER_PREFERENCE_DEFAULTS['full_draft'] == 'off': self.assertContains(r, "Show full document") self.assertNotContains(r, "Deimos street") - self.assertContains(r, replaced.canonical_name()) + self.assertContains(r, replaced.name) self.assertContains(r, replaced.title) - # obs/updates not included until draft is RFC - self.assertNotContains(r, obsoleted.canonical_name()) - self.assertNotContains(r, obsoleted.title) - self.assertNotContains(r, obsoleted_by.canonical_name()) - self.assertNotContains(r, obsoleted_by.title) - self.assertNotContains(r, updated.canonical_name()) - self.assertNotContains(r, updated.title) - self.assertNotContains(r, updated_by.canonical_name()) - self.assertNotContains(r, updated_by.title) r = self.client.get(urlreverse("ietf.doc.views_doc.document_main", kwargs=dict(name=draft.name)) + "?include_text=0") self.assertEqual(r.status_code, 200) self.assertContains(r, "Active Internet-Draft") self.assertContains(r, "Show full document") self.assertNotContains(r, "Deimos street") - self.assertContains(r, replaced.canonical_name()) + self.assertContains(r, replaced.name) self.assertContains(r, replaced.title) - # obs/updates not included until draft is RFC - self.assertNotContains(r, obsoleted.canonical_name()) - self.assertNotContains(r, obsoleted.title) - self.assertNotContains(r, obsoleted_by.canonical_name()) - self.assertNotContains(r, obsoleted_by.title) - self.assertNotContains(r, updated.canonical_name()) - self.assertNotContains(r, updated.title) - self.assertNotContains(r, updated_by.canonical_name()) - self.assertNotContains(r, updated_by.title) r = self.client.get(urlreverse("ietf.doc.views_doc.document_main", kwargs=dict(name=draft.name)) + "?include_text=foo") self.assertEqual(r.status_code, 200) self.assertContains(r, "Active Internet-Draft") self.assertNotContains(r, "Show full document") self.assertContains(r, "Deimos street") - self.assertContains(r, replaced.canonical_name()) + self.assertContains(r, replaced.name) self.assertContains(r, replaced.title) - # obs/updates not included until draft is RFC - self.assertNotContains(r, obsoleted.canonical_name()) - self.assertNotContains(r, obsoleted.title) - self.assertNotContains(r, obsoleted_by.canonical_name()) - self.assertNotContains(r, obsoleted_by.title) - self.assertNotContains(r, updated.canonical_name()) - self.assertNotContains(r, updated.title) - self.assertNotContains(r, updated_by.canonical_name()) - self.assertNotContains(r, updated_by.title) r = self.client.get(urlreverse("ietf.doc.views_doc.document_main", kwargs=dict(name=draft.name)) + "?include_text=1") self.assertEqual(r.status_code, 200) self.assertContains(r, "Active Internet-Draft") self.assertNotContains(r, "Show full document") self.assertContains(r, "Deimos street") - self.assertContains(r, replaced.canonical_name()) + self.assertContains(r, replaced.name) self.assertContains(r, replaced.title) - # obs/updates not included until draft is RFC - self.assertNotContains(r, obsoleted.canonical_name()) - self.assertNotContains(r, obsoleted.title) - self.assertNotContains(r, obsoleted_by.canonical_name()) - self.assertNotContains(r, obsoleted_by.title) - self.assertNotContains(r, updated.canonical_name()) - self.assertNotContains(r, updated.title) - self.assertNotContains(r, updated_by.canonical_name()) - self.assertNotContains(r, updated_by.title) self.client.cookies = SimpleCookie({str('full_draft'): str('on')}) r = self.client.get(urlreverse("ietf.doc.views_doc.document_main", kwargs=dict(name=draft.name))) @@ -675,17 +763,8 @@ def test_document_draft(self): self.assertContains(r, "Active Internet-Draft") self.assertNotContains(r, "Show full document") self.assertContains(r, "Deimos street") - self.assertContains(r, replaced.canonical_name()) + self.assertContains(r, replaced.name) self.assertContains(r, replaced.title) - # obs/updates not included until draft is RFC - self.assertNotContains(r, obsoleted.canonical_name()) - self.assertNotContains(r, obsoleted.title) - self.assertNotContains(r, obsoleted_by.canonical_name()) - self.assertNotContains(r, obsoleted_by.title) - self.assertNotContains(r, updated.canonical_name()) - self.assertNotContains(r, updated.title) - self.assertNotContains(r, updated_by.canonical_name()) - self.assertNotContains(r, updated_by.title) self.client.cookies = SimpleCookie({str('full_draft'): str('off')}) r = self.client.get(urlreverse("ietf.doc.views_doc.document_main", kwargs=dict(name=draft.name))) @@ -693,17 +772,8 @@ def test_document_draft(self): self.assertContains(r, "Active Internet-Draft") self.assertContains(r, "Show full document") self.assertNotContains(r, "Deimos street") - self.assertContains(r, replaced.canonical_name()) + self.assertContains(r, replaced.name) self.assertContains(r, replaced.title) - # obs/updates not included until draft is RFC - self.assertNotContains(r, obsoleted.canonical_name()) - self.assertNotContains(r, obsoleted.title) - self.assertNotContains(r, obsoleted_by.canonical_name()) - self.assertNotContains(r, obsoleted_by.title) - self.assertNotContains(r, updated.canonical_name()) - self.assertNotContains(r, updated.title) - self.assertNotContains(r, updated_by.canonical_name()) - self.assertNotContains(r, updated_by.title) self.client.cookies = SimpleCookie({str('full_draft'): str('foo')}) r = self.client.get(urlreverse("ietf.doc.views_doc.document_main", kwargs=dict(name=draft.name))) @@ -712,45 +782,43 @@ def test_document_draft(self): if settings.USER_PREFERENCE_DEFAULTS['full_draft'] == 'off': self.assertContains(r, "Show full document") self.assertNotContains(r, "Deimos street") - self.assertContains(r, replaced.canonical_name()) + self.assertContains(r, replaced.name) self.assertContains(r, replaced.title) - # obs/updates not included until draft is RFC - self.assertNotContains(r, obsoleted.canonical_name()) - self.assertNotContains(r, obsoleted.title) - self.assertNotContains(r, obsoleted_by.canonical_name()) - self.assertNotContains(r, obsoleted_by.title) - self.assertNotContains(r, updated.canonical_name()) - self.assertNotContains(r, updated.title) - self.assertNotContains(r, updated_by.canonical_name()) - self.assertNotContains(r, updated_by.title) r = self.client.get(urlreverse("ietf.doc.views_doc.document_html", kwargs=dict(name=draft.name))) self.assertEqual(r.status_code, 200) - self.assertContains(r, "Versions:") + self.assertContains(r, "Select version") self.assertContains(r, "Deimos street") q = PyQuery(r.content) self.assertEqual(q('title').text(), 'draft-ietf-mars-test-01') - self.assertEqual(len(q('.rfcmarkup pre')), 4) - self.assertEqual(len(q('.rfcmarkup span.h1')), 2) - self.assertEqual(len(q('.rfcmarkup a[href]')), 41) + self.assertEqual(len(q('.rfcmarkup pre')), 3) + self.assertEqual(len(q('.rfcmarkup span.h1, .rfcmarkup h1')), 2) + self.assertEqual(len(q('.rfcmarkup a[href]')), 27) r = self.client.get(urlreverse("ietf.doc.views_doc.document_html", kwargs=dict(name=draft.name, rev=draft.rev))) self.assertEqual(r.status_code, 200) q = PyQuery(r.content) self.assertEqual(q('title').text(), 'draft-ietf-mars-test-01') + # check that revision list has expected versions + self.assertEqual(len(q('#sidebar .revision-list .page-item.active a.page-link[href$="draft-ietf-mars-test-01"]')), 1) + + # check that diff dropdowns have expected versions + self.assertEqual(len(q('#sidebar option[value="draft-ietf-mars-test-00"][selected="selected"]')), 1) + rfc = WgRfcFactory() + rfc.save_with_history([DocEventFactory(doc=rfc)]) (Path(settings.RFC_PATH) / rfc.get_base_name()).touch() - r = self.client.get(urlreverse("ietf.doc.views_doc.document_html", kwargs=dict(name=rfc.canonical_name()))) + r = self.client.get(urlreverse("ietf.doc.views_doc.document_html", kwargs=dict(name=rfc.name))) self.assertEqual(r.status_code, 200) q = PyQuery(r.content) - self.assertEqual(q('title').text(), f'RFC {rfc.rfc_number()} - {rfc.title}') + self.assertEqual(q('title').text(), f'RFC {rfc.rfc_number} - {rfc.title}') # synonyms for the rfc should be redirected to its canonical view - r = self.client.get(urlreverse("ietf.doc.views_doc.document_html", kwargs=dict(name=rfc.rfc_number()))) - self.assertRedirects(r, urlreverse("ietf.doc.views_doc.document_html", kwargs=dict(name=rfc.canonical_name()))) - r = self.client.get(urlreverse("ietf.doc.views_doc.document_html", kwargs=dict(name=f'RFC {rfc.rfc_number()}'))) - self.assertRedirects(r, urlreverse("ietf.doc.views_doc.document_html", kwargs=dict(name=rfc.canonical_name()))) + r = self.client.get(urlreverse("ietf.doc.views_doc.document_html", kwargs=dict(name=rfc.rfc_number))) + self.assertRedirects(r, urlreverse("ietf.doc.views_doc.document_html", kwargs=dict(name=rfc.name))) + r = self.client.get(urlreverse("ietf.doc.views_doc.document_html", kwargs=dict(name=f'RFC {rfc.rfc_number}'))) + self.assertRedirects(r, urlreverse("ietf.doc.views_doc.document_html", kwargs=dict(name=rfc.name))) # expired draft draft.set_state(State.objects.get(type="draft", slug="expired")) @@ -764,56 +832,63 @@ def test_document_draft(self): replacement = WgDraftFactory( name="draft-ietf-replacement", - time=datetime.datetime.now(), + time=timezone.now(), title="Replacement Draft", stream_id=draft.stream_id, group_id=draft.group_id, abstract=draft.abstract,stream=draft.stream, rev=draft.rev, pages=draft.pages, intended_std_level_id=draft.intended_std_level_id, shepherd_id=draft.shepherd_id, ad_id=draft.ad_id, expires=draft.expires, - notify=draft.notify, note=draft.note) + notify=draft.notify) rel = RelatedDocument.objects.create(source=replacement, - target=draft.docalias.get(name__startswith="draft"), + target=draft, relationship_id="replaces") r = self.client.get(urlreverse("ietf.doc.views_doc.document_main", kwargs=dict(name=draft.name))) self.assertEqual(r.status_code, 200) self.assertContains(r, "Replaced Internet-Draft") - self.assertContains(r, replacement.canonical_name()) + self.assertContains(r, replacement.name) self.assertContains(r, replacement.title) rel.delete() # draft published as RFC draft.set_state(State.objects.get(type="draft", slug="rfc")) - draft.std_level_id = "bcp" - draft.save_with_history([DocEvent.objects.create(doc=draft, rev=draft.rev, type="published_rfc", by=Person.objects.get(name="(System)"))]) + draft.std_level_id = "ps" + + rfc = WgRfcFactory(group=draft.group, name="rfc123456") + rfc.save_with_history([DocEvent.objects.create(doc=rfc, rev=None, type="published_rfc", by=Person.objects.get(name="(System)"))]) + draft.relateddocument_set.create(relationship_id="became_rfc", target=rfc) - rfc_alias = DocAlias.objects.create(name="rfc123456") - rfc_alias.docs.add(draft) - bcp_alias = DocAlias.objects.create(name="bcp123456") - bcp_alias.docs.add(draft) + obsoleted = IndividualRfcFactory() + rfc.relateddocument_set.create(relationship_id='obs',target=obsoleted) + obsoleted_by = IndividualRfcFactory() + obsoleted_by.relateddocument_set.create(relationship_id='obs',target=rfc) + updated = IndividualRfcFactory() + rfc.relateddocument_set.create(relationship_id='updates',target=updated) + updated_by = IndividualRfcFactory() + updated_by.relateddocument_set.create(relationship_id='updates',target=rfc) + + r = self.client.get(urlreverse("ietf.doc.views_doc.document_main", kwargs=dict(name=draft.name, rev=draft.rev))) + self.assertEqual(r.status_code, 200) + self.assertContains(r, "This is an older version of an Internet-Draft that was ultimately published as") r = self.client.get(urlreverse("ietf.doc.views_doc.document_main", kwargs=dict(name=draft.name))) self.assertEqual(r.status_code, 302) - r = self.client.get(urlreverse("ietf.doc.views_doc.document_main", kwargs=dict(name=bcp_alias.name))) - self.assertEqual(r.status_code, 302) - r = self.client.get(urlreverse("ietf.doc.views_doc.document_main", kwargs=dict(name=rfc_alias.name))) + r = self.client.get(urlreverse("ietf.doc.views_doc.document_main", kwargs=dict(name=rfc.name))) self.assertEqual(r.status_code, 200) self.assertContains(r, "RFC 123456") self.assertContains(r, draft.name) - self.assertContains(r, replaced.canonical_name()) - self.assertContains(r, replaced.title) # obs/updates included with RFC - self.assertContains(r, obsoleted.canonical_name()) + self.assertContains(r, obsoleted.name) self.assertContains(r, obsoleted.title) - self.assertContains(r, obsoleted_by.canonical_name()) + self.assertContains(r, obsoleted_by.name) self.assertContains(r, obsoleted_by.title) - self.assertContains(r, updated.canonical_name()) + self.assertContains(r, updated.name) self.assertContains(r, updated.title) - self.assertContains(r, updated_by.canonical_name()) + self.assertContains(r, updated_by.name) self.assertContains(r, updated_by.title) - # naked RFC - also wierd that we test a PS from the ISE + # naked RFC - also weird that we test a PS from the ISE rfc = IndividualDraftFactory( name="rfc1234567", title="RFC without a Draft", @@ -843,7 +918,7 @@ def test_draft_status_changes(self): draft = WgRfcFactory() status_change_doc = StatusChangeFactory( group=draft.group, - changes_status_of=[('tops', draft.docalias.first())], + changes_status_of=[('tops', draft)], ) status_change_url = urlreverse( 'ietf.doc.views_doc.document_main', @@ -851,7 +926,7 @@ def test_draft_status_changes(self): ) proposed_status_change_doc = StatusChangeFactory( group=draft.group, - changes_status_of=[('tobcp', draft.docalias.first())], + changes_status_of=[('tobcp', draft)], states=[State.objects.get(slug='needshep', type='statchg')], ) proposed_status_change_url = urlreverse( @@ -862,7 +937,7 @@ def test_draft_status_changes(self): r = self.client.get( urlreverse( 'ietf.doc.views_doc.document_main', - kwargs={'name': draft.canonical_name()}, + kwargs={'name': draft.name}, ) ) self.assertEqual(r.status_code, 200) @@ -908,7 +983,7 @@ def test_edit_authors_permissions(self): # Relevant users not authorized to edit authors unauthorized_usernames = [ 'plain', - *[author.user.username for author in draft.authors()], + *[author.user.username for author in draft.author_persons()], draft.group.get_chair().person.user.username, 'ad' ] @@ -923,7 +998,7 @@ def test_edit_authors_permissions(self): self.client.logout() # Try to add an author via POST - still only the secretary should be able to do this. - orig_authors = draft.authors() + orig_authors = draft.author_persons() post_data = self.make_edit_authors_post_data( basis='permission test', authors=draft.documentauthor_set.all(), @@ -941,12 +1016,40 @@ def test_edit_authors_permissions(self): for username in unauthorized_usernames: login_testing_unauthorized(self, username, url, method='post', request_kwargs=dict(data=post_data)) draft = Document.objects.get(pk=draft.pk) - self.assertEqual(draft.authors(), orig_authors) # ensure draft author list was not modified + self.assertEqual(draft.author_persons(), orig_authors) # ensure draft author list was not modified login_testing_unauthorized(self, 'secretary', url, method='post', request_kwargs=dict(data=post_data)) r = self.client.post(url, post_data) self.assertEqual(r.status_code, 302) draft = Document.objects.get(pk=draft.pk) - self.assertEqual(draft.authors(), orig_authors + [new_auth_person]) + self.assertEqual(draft.author_persons(), orig_authors + [new_auth_person]) + + def test_edit_authors_blocked_when_rfcauthors_exist(self): + """edit_authors returns 403 for all users when RfcAuthors exist""" + rfc = WgRfcFactory() + RfcAuthorFactory(document=rfc) + url = urlreverse('ietf.doc.views_doc.edit_authors', kwargs=dict(name=rfc.name)) + + self.client.login(username='secretary', password='secretary+password') + r = self.client.get(url) + self.assertEqual(r.status_code, 403) + r = self.client.post(url, {}) + self.assertEqual(r.status_code, 403) + + def test_document_main_hides_edit_authors_when_rfcauthors_exist(self): + """document_main does not offer edit link for authors when RfcAuthors exist""" + rfc = WgRfcFactory() + edit_authors_url = urlreverse('ietf.doc.views_doc.edit_authors', kwargs=dict(name=rfc.name)) + + self.client.login(username='secretary', password='secretary+password') + + r = self.client.get(urlreverse('ietf.doc.views_doc.document_main', kwargs=dict(name=rfc.name))) + self.assertEqual(r.status_code, 200) + self.assertContains(r, edit_authors_url) + + RfcAuthorFactory(document=rfc) + r = self.client.get(urlreverse('ietf.doc.views_doc.document_main', kwargs=dict(name=rfc.name))) + self.assertEqual(r.status_code, 200) + self.assertNotContains(r, edit_authors_url) def make_edit_authors_post_data(self, basis, authors): """Helper to generate edit_authors POST data for a set of authors""" @@ -1276,7 +1379,12 @@ def test_edit_authors_reorder_authors(self): def test_edit_authors_edit_fields(self): draft = WgDraftFactory() - DocumentAuthorFactory.create_batch(3, document=draft) + DocumentAuthorFactory.create_batch( + 3, + document=draft, + affiliation='Somewhere, Inc.', + country='Bolivia', + ) url = urlreverse('ietf.doc.views_doc.edit_authors', kwargs=dict(name=draft.name)) change_reason = 'reorder the authors' @@ -1288,8 +1396,9 @@ def test_edit_authors_edit_fields(self): authors = draft.documentauthor_set.all(), basis=change_reason ) - - new_email = EmailFactory(person=draft.authors()[0]) + + old_address = draft.author_persons()[0].email() + new_email = EmailFactory(person=draft.author_persons()[0], address=f'changed-{old_address}') post_data['author-0-email'] = new_email.address post_data['author-1-affiliation'] = 'University of Nowhere' post_data['author-2-country'] = 'Chile' @@ -1322,17 +1431,17 @@ def test_edit_authors_edit_fields(self): country_event = change_events.filter(desc__icontains='changed country').first() self.assertIsNotNone(email_event) - self.assertIn(draft.authors()[0].name, email_event.desc) + self.assertIn(draft.author_persons()[0].name, email_event.desc) self.assertIn(before[0]['email'], email_event.desc) self.assertIn(after[0]['email'], email_event.desc) self.assertIsNotNone(affiliation_event) - self.assertIn(draft.authors()[1].name, affiliation_event.desc) + self.assertIn(draft.author_persons()[1].name, affiliation_event.desc) self.assertIn(before[1]['affiliation'], affiliation_event.desc) self.assertIn(after[1]['affiliation'], affiliation_event.desc) self.assertIsNotNone(country_event) - self.assertIn(draft.authors()[2].name, country_event.desc) + self.assertIn(draft.author_persons()[2].name, country_event.desc) self.assertIn(before[2]['country'], country_event.desc) self.assertIn(after[2]['country'], country_event.desc) @@ -1390,6 +1499,14 @@ def test_document_draft_action_holders_buttons(self, mock_method): """Buttons for action holders should be shown when AD or secretary""" draft = WgDraftFactory() draft.action_holders.set([PersonFactory()]) + other_group = GroupFactory(type_id=draft.group.type_id) + + # create a test RoleName and put it in the docman_roles for the document group + RoleName.objects.create(slug="wrangler", name="Wrangler", used=True) + draft.group.features.docman_roles.append("wrangler") + draft.group.features.save() + wrangler = RoleFactory(group=draft.group, name_id="wrangler").person + wrangler_of_other_group = RoleFactory(group=other_group, name_id="wrangler").person url = urlreverse('ietf.doc.views_doc.document_main', kwargs=dict(name=draft.name)) edit_ah_url = urlreverse('ietf.doc.views_doc.edit_action_holders', kwargs=dict(name=draft.name)) @@ -1422,11 +1539,15 @@ def _run_test(username=None, expect_buttons=False): _run_test(None, False) _run_test('plain', False) + _run_test(wrangler_of_other_group.user.username, False) + _run_test(wrangler.user.username, True) _run_test('ad', True) _run_test('secretary', True) def test_draft_group_link(self): """Link to group 'about' page should have correct format""" + event_datetime = datetime.datetime(2010, 10, 10, tzinfo=RPC_TZINFO) + for group_type_id in ['wg', 'rg', 'ag']: group = GroupFactory(type_id=group_type_id) draft = WgDraftFactory(name='draft-document-%s' % group_type_id, group=group) @@ -1434,11 +1555,11 @@ def test_draft_group_link(self): self.assertEqual(r.status_code, 200) self.assert_correct_wg_group_link(r, group) - rfc = WgRfcFactory(name='draft-rfc-document-%s' % group_type_id, group=group) - DocEventFactory.create(doc=rfc, type='published_rfc', time = '2010-10-10') - # get the rfc name to avoid a redirect - rfc_name = rfc.docalias.filter(name__startswith='rfc').first().name - r = self.client.get(urlreverse("ietf.doc.views_doc.document_main", kwargs=dict(name=rfc_name))) + rfc = WgRfcFactory(group=group) + draft = WgDraftFactory(group=group) + draft.relateddocument_set.create(relationship_id="became_rfc", target=rfc) + DocEventFactory.create(doc=rfc, type='published_rfc', time=event_datetime) + r = self.client.get(urlreverse("ietf.doc.views_doc.document_main", kwargs=dict(name=rfc.name))) self.assertEqual(r.status_code, 200) self.assert_correct_wg_group_link(r, group) @@ -1449,14 +1570,33 @@ def test_draft_group_link(self): self.assertEqual(r.status_code, 200) self.assert_correct_non_wg_group_link(r, group) - rfc = WgRfcFactory(name='draft-rfc-document-%s' % group_type_id, group=group) - DocEventFactory.create(doc=rfc, type='published_rfc', time = '2010-10-10') - # get the rfc name to avoid a redirect - rfc_name = rfc.docalias.filter(name__startswith='rfc').first().name - r = self.client.get(urlreverse("ietf.doc.views_doc.document_main", kwargs=dict(name=rfc_name))) + rfc = WgRfcFactory(group=group) + draft = WgDraftFactory(name='draft-rfc-document-%s'% group_type_id, group=group) + draft.relateddocument_set.create(relationship_id="became_rfc", target=rfc) + DocEventFactory.create(doc=rfc, type='published_rfc', time=event_datetime) + r = self.client.get(urlreverse("ietf.doc.views_doc.document_main", kwargs=dict(name=rfc.name))) self.assertEqual(r.status_code, 200) self.assert_correct_non_wg_group_link(r, group) + def test_document_email_authors_button(self): + # rfc not from draft + rfc = WgRfcFactory() + DocEventFactory.create(doc=rfc, type='published_rfc') + url = urlreverse("ietf.doc.views_doc.document_main", kwargs=dict(name=rfc.name)) + r = self.client.get(url) + self.assertEqual(r.status_code, 200) + q = PyQuery(r.content) + self.assertEqual(len(q('a:contains("Email authors")')), 0, 'Did not expect "Email authors" button') + + # rfc from draft + draft = WgDraftFactory(group=rfc.group) + draft.relateddocument_set.create(relationship_id="became_rfc", target=rfc) + draft.set_state(State.objects.get(used=True, type="draft", slug="rfc")) + r = self.client.get(url) + self.assertEqual(r.status_code, 200) + q = PyQuery(r.content) + self.assertEqual(len(q('a:contains("Email authors")')), 1, 'Expected "Email authors" button') + def test_document_primary_and_history_views(self): IndividualDraftFactory(name='draft-imaginary-independent-submission') ConflictReviewFactory(name='conflict-review-imaginary-irtf-submission') @@ -1464,6 +1604,10 @@ def test_document_primary_and_history_views(self): DocumentFactory(type_id='agenda',name='agenda-72-mars') DocumentFactory(type_id='minutes',name='minutes-72-mars') DocumentFactory(type_id='slides',name='slides-72-mars-1-active') + chatlog = DocumentFactory(type_id="chatlog",name='chatlog-72-mars-197001010000') + polls = DocumentFactory(type_id="polls",name='polls-72-mars-197001010000') + SessionPresentationFactory(document=chatlog) + SessionPresentationFactory(document=polls) statchg = DocumentFactory(type_id='statchg',name='status-change-imaginary-mid-review') statchg.set_state(State.objects.get(type_id='statchg',slug='adrev')) @@ -1475,6 +1619,8 @@ def test_document_primary_and_history_views(self): "agenda-72-mars", "minutes-72-mars", "slides-72-mars-1-active", + "chatlog-72-mars-197001010000", + "polls-72-mars-197001010000", # TODO: add #"bluesheets-72-mars-1", #"recording-72-mars-1-00", @@ -1542,19 +1688,45 @@ def _change_state(doc, state): self.assertEqual(r.status_code, 200) self.assertNotContains(r, 'Auth48 status') + def test_rfceditor_queue_status_shown(self): + """A queued draft shows its publication-queue Status in place of the state name.""" + draft = IndividualDraftFactory() + event = StateDocEventFactory(doc=draft, state=('draft-rfceditor', 'in_progress')) + draft.set_state(event.state) + draft.save_with_history([event]) + RpcAssignmentDocEvent.objects.create( + doc=draft, + rev=draft.rev, + by=Person.objects.get(name="(System)"), + type="changed_rpc_assignments", + assignments="In Progress (First Edit)", + desc="RPC status changed to In Progress (First Edit)", + ) + + r = self.client.get(urlreverse("ietf.doc.views_doc.document_main", kwargs=dict(name=draft.name))) + self.assertEqual(r.status_code, 200) + # The composite queue Status (which only comes from the RpcAssignmentDocEvent, + # not from the state name) is shown, confirming it replaces the raw state name. + self.assertContains(r, "In Progress (First Edit)") + self.assertContains(r, "Publication queue entry") + class DocTestCase(TestCase): def test_status_change(self): statchg = StatusChangeFactory() r = self.client.get(urlreverse("ietf.doc.views_doc.document_main", kwargs=dict(name=statchg.name))) self.assertEqual(r.status_code, 200) - r = self.client.get(urlreverse("ietf.doc.views_doc.document_main", kwargs=dict(name=statchg.relateddocument_set.first().target.document))) - self.assertEqual(r.status_code, 302) + r = self.client.get(urlreverse("ietf.doc.views_doc.document_main", kwargs=dict(name=statchg.relateddocument_set.first().target))) + self.assertEqual(r.status_code, 200) def test_document_charter(self): CharterFactory(name='charter-ietf-mars') r = self.client.get(urlreverse("ietf.doc.views_doc.document_main", kwargs=dict(name="charter-ietf-mars"))) self.assertEqual(r.status_code, 200) + + def test_incorrect_rfc_url(self): + r = self.client.get(urlreverse("ietf.doc.views_doc.document_main", kwargs=dict(name="rfc8989", rev="00"))) + self.assertEqual(r.status_code, 404) def test_document_conflict_review(self): ConflictReviewFactory(name='conflict-review-imaginary-irtf-submission') @@ -1580,7 +1752,7 @@ def test_document_material(self): name = "session-72-mars-1", meeting = Meeting.objects.get(number='72'), group = Group.objects.get(acronym='mars'), - modified = datetime.datetime.now(), + modified = timezone.now(), add_to_schedule=False, ) SchedulingEvent.objects.create( @@ -1592,6 +1764,17 @@ def test_document_material(self): r = self.client.get(urlreverse("ietf.doc.views_doc.document_main", kwargs=dict(name=doc.name))) self.assertEqual(r.status_code, 200) + self.assertNotContains(r, "The session for this document was cancelled.") + + SchedulingEvent.objects.create( + session=session, + status_id='canceled', + by = Person.objects.get(user__username="marschairman"), + ) + + r = self.client.get(urlreverse("ietf.doc.views_doc.document_main", kwargs=dict(name=doc.name))) + self.assertEqual(r.status_code, 200) + self.assertContains(r, "The session for this document was cancelled.") def test_document_ballot(self): doc = IndividualDraftFactory() @@ -1610,7 +1793,7 @@ def test_document_ballot(self): type="changed_ballot_position", pos_id="yes", comment="Looks fine to me", - comment_time=datetime.datetime.now(), + comment_time=timezone.now(), balloter=Person.objects.get(user__username="ad"), by=Person.objects.get(name="(System)")) @@ -1634,7 +1817,13 @@ def test_document_ballot(self): doc.save_with_history([e]) r = self.client.get(urlreverse("ietf.doc.views_doc.document_ballot", kwargs=dict(name=doc.name))) self.assertEqual(r.status_code, 200) - self.assertRegex(r.content.decode(), r'\(\s*%s\s+for\s+-%s\s*\)' % (pos.comment_time.strftime('%Y-%m-%d'), oldrev)) + self.assertRegex( + r.content.decode(), + r'\(\s*%s\s+for\s+-%s\s*\)' % ( + pos.comment_time.astimezone(ZoneInfo(settings.TIME_ZONE)).strftime('%Y-%m-%d'), + oldrev, + ) + ) # Now simulate a new ballot against the new revision and make sure the "was" position is included pos2 = BallotPositionDocEvent.objects.create( @@ -1644,7 +1833,7 @@ def test_document_ballot(self): type="changed_ballot_position", pos_id="noobj", comment="Still looks okay to me", - comment_time=datetime.datetime.now(), + comment_time=timezone.now(), balloter=Person.objects.get(user__username="ad"), by=Person.objects.get(name="(System)")) @@ -1666,7 +1855,7 @@ def test_document_ballot_popup_unique_anchors_per_doc(self): type="changed_ballot_position", pos_id="yes", comment="Looks fine to me", - comment_time=datetime.datetime.now(), + comment_time=timezone.now(), balloter=Person.objects.get(user__username="ad"), by=Person.objects.get(name="(System)")) @@ -1682,7 +1871,7 @@ def test_document_ballot_popup_unique_anchors_per_doc(self): href = q(f'div.balloter-name a[href$="{author_slug}"]').attr('href') ids = [ target.attr('id') - for target in q(f'p.h5[id$="{author_slug}"]').items() + for target in q(f'div.h5[id$="{author_slug}"]').items() ] self.assertEqual(len(ids), 1, 'Should be exactly one link for the balloter') self.assertEqual(href, f'#{ids[0]}', 'Anchor href should match ID') @@ -1703,38 +1892,88 @@ def test_document_ballot_needed_positions(self): self.assertNotContains(r, 'more YES or NO') # status change - DocAlias.objects.create(name='rfc9998').docs.add(IndividualDraftFactory()) - DocAlias.objects.create(name='rfc9999').docs.add(IndividualDraftFactory()) + Document.objects.create(name='rfc9998') + Document.objects.create(name='rfc9999') doc = DocumentFactory(type_id='statchg',name='status-change-imaginary-mid-review') iesgeval_pk = str(State.objects.get(slug='iesgeval',type__slug='statchg').pk) empty_outbox() self.client.login(username='ad', password='ad+password') r = self.client.post(urlreverse('ietf.doc.views_status_change.change_state',kwargs=dict(name=doc.name)),dict(new_state=iesgeval_pk)) self.assertEqual(r.status_code, 302) - r = self.client.get(r._headers["location"][1]) + r = self.client.get(r.headers["location"]) self.assertContains(r, ">IESG Evaluation<") self.assertEqual(len(outbox), 2) self.assertIn('iesg-secretary',outbox[0]['To']) self.assertIn('drafts-eval',outbox[1]['To']) - doc.relateddocument_set.create(target=DocAlias.objects.get(name='rfc9998'),relationship_id='tohist') + doc.relateddocument_set.create(target=Document.objects.get(name='rfc9998'),relationship_id='tohist') r = self.client.get(urlreverse("ietf.doc.views_doc.document_ballot", kwargs=dict(name=doc.name))) self.assertNotContains(r, 'Needs a YES') self.assertNotContains(r, 'more YES or NO') - doc.relateddocument_set.create(target=DocAlias.objects.get(name='rfc9999'),relationship_id='tois') + doc.relateddocument_set.create(target=Document.objects.get(name='rfc9999'),relationship_id='tois') r = self.client.get(urlreverse("ietf.doc.views_doc.document_ballot", kwargs=dict(name=doc.name))) self.assertContains(r, 'more YES or NO') def test_document_json(self): doc = IndividualDraftFactory() - + author = DocumentAuthorFactory(document=doc) + r = self.client.get(urlreverse("ietf.doc.views_doc.document_json", kwargs=dict(name=doc.name))) self.assertEqual(r.status_code, 200) data = r.json() - self.assertEqual(doc.name, data['name']) - self.assertEqual(doc.pages,data['pages']) + self.assertEqual(data["name"], doc.name) + self.assertEqual(data["pages"], doc.pages) + self.assertEqual( + data["authors"], + [ + { + "name": author.person.name, + "email": author.email.address, + "affiliation": author.affiliation, + } + ] + ) + + def test_document_json_rfc(self): + doc = IndividualRfcFactory() + old_style_author = DocumentAuthorFactory(document=doc) + url = urlreverse("ietf.doc.views_doc.document_json", kwargs=dict(name=doc.name)) + + r = self.client.get(url) + self.assertEqual(r.status_code, 200) + data = r.json() + self.assertEqual(data["name"], doc.name) + self.assertEqual(data["pages"], doc.pages) + self.assertEqual( + data["authors"], + [ + { + "name": old_style_author.person.name, + "email": old_style_author.email.address, + "affiliation": old_style_author.affiliation, + } + ] + ) + + new_style_author = RfcAuthorFactory(document=doc) + r = self.client.get(url) + self.assertEqual(r.status_code, 200) + data = r.json() + self.assertEqual(data["name"], doc.name) + self.assertEqual(data["pages"], doc.pages) + self.assertEqual( + data["authors"], + [ + { + "name": new_style_author.titlepage_name, + "email": new_style_author.email.address, + "affiliation": new_style_author.affiliation, + } + ] + ) + def test_writeup(self): doc = IndividualDraftFactory(states = [('draft','active'),('draft-iesg','iesg-eva')],) @@ -1769,6 +2008,18 @@ def test_writeup(self): self.assertContains(r, notes.text) self.assertContains(r, rfced_note.text) + def test_diff_revisions(self): + ind_doc = IndividualDraftFactory(create_revisions=range(2)) + wg_doc = WgDraftFactory( + relations=[("replaces", ind_doc)], create_revisions=range(2) + ) + diff_revisions = get_diff_revisions(HttpRequest(), wg_doc.name, wg_doc) + self.assertEqual(len(diff_revisions), 4) + self.assertEqual( + [t[3] for t in diff_revisions], + [f"{n}-{v:02d}" for n in [wg_doc.name, ind_doc.name] for v in [1, 0]], + ) + def test_history(self): doc = IndividualDraftFactory() @@ -1785,15 +2036,14 @@ def test_history(self): self.assertContains(r, e.desc) def test_history_bis_00(self): - rfcname='rfc9090' - rfc = WgRfcFactory(alias2=rfcname) - bis_draft = WgDraftFactory(name='draft-ietf-{}-{}bis'.format(rfc.group.acronym,rfcname)) + rfc = WgRfcFactory(rfc_number=9090) + bis_draft = WgDraftFactory(name='draft-ietf-{}-{}bis'.format(rfc.group.acronym,rfc.name)) url = urlreverse('ietf.doc.views_doc.document_history', kwargs=dict(name=bis_draft.name)) r = self.client.get(url) self.assertEqual(r.status_code, 200) q = PyQuery(unicontent(r)) - attr1='value="{}"'.format(rfcname) + attr1='value="{}"'.format(rfc.name) self.assertEqual(len(q('option['+attr1+'][selected="selected"]')), 1) @@ -1836,18 +2086,38 @@ def test_last_call_feed(self): desc="Last call\x0b", # include a control character to be sure it does not break anything type="sent_last_call", by=Person.objects.get(user__username="secretary"), - expires=datetime.date.today() + datetime.timedelta(days=7)) + expires=datetime_today(DEADLINE_TZINFO) + datetime.timedelta(days=7)) r = self.client.get("/feed/last-call/") self.assertEqual(r.status_code, 200) self.assertContains(r, doc.name) def test_rfc_feed(self): - WgRfcFactory() + rfc = WgRfcFactory(rfc_number=9000) + DocEventFactory(doc=rfc, type="published_rfc") r = self.client.get("/feed/rfc/") self.assertTrue(r.status_code, 200) + q = PyQuery(r.content[39:]) # Strip off the xml declaration + self.assertEqual(len(q("item")), 1) + item = q("item")[0] + media_content = item.findall("{http://search.yahoo.com/mrss/}content") + self.assertEqual(len(media_content),4) + types = set([m.attrib["type"] for m in media_content]) + self.assertEqual(types, set(["application/rfc+xml", "text/plain", "text/html", "application/pdf"])) + rfcs_2016 = WgRfcFactory.create_batch(3) # rfc numbers will be well below v3 + for rfc in rfcs_2016: + e = DocEventFactory(doc=rfc, type="published_rfc") + e.time = e.time.replace(year=2016) + e.save() r = self.client.get("/feed/rfc/2016") self.assertTrue(r.status_code, 200) + q = PyQuery(r.content[39:]) + self.assertEqual(len(q("item")), 3) + item = q("item")[0] + media_content = item.findall("{http://search.yahoo.com/mrss/}content") + self.assertEqual(len(media_content), 2) + types = set([m.attrib["type"] for m in media_content]) + self.assertEqual(types, set(["text/plain", "text/html"])) def test_state_help(self): url = urlreverse('ietf.doc.views_help.state_help', kwargs=dict(type="draft-iesg")) @@ -1855,6 +2125,23 @@ def test_state_help(self): self.assertEqual(r.status_code, 200) self.assertContains(r, State.objects.get(type="draft-iesg", slug="lc").name) + def test_rfceditor_state_help_has_queue_status_and_legacy_sections(self): + url = urlreverse('ietf.doc.views_help.state_help', kwargs=dict(type="draft-rfceditor")) + r = self.client.get(url) + self.assertEqual(r.status_code, 200) + # New "Queue status" section describing the queue Status values. + self.assertContains(r, "Queue status") + self.assertContains(r, "In Progress (First Edit)") + # Legacy states are moved to their own section with the history note. + self.assertContains(r, "Legacy states") + self.assertContains(r, "appear in the change history") + self.assertContains(r, State.objects.get(type="draft-rfceditor", slug="auth48").name) + # The queue-backing states are not listed among the legacy states. + q = PyQuery(r.content) + legacy_ids = [row.get("id") for row in q("tbody tr")] + self.assertNotIn("in_progress", legacy_ids) + self.assertNotIn("blocked", legacy_ids) + def test_document_nonietf_pubreq_button(self): doc = IndividualDraftFactory() @@ -1880,62 +2167,98 @@ def _parse_bibtex_response(self, response) -> dict: @override_settings(RFC_EDITOR_INFO_BASE_URL='https://www.rfc-editor.ietf.org/info/') def test_document_bibtex(self): + + for factory in [CharterFactory, BcpFactory, StatusChangeFactory, ConflictReviewFactory]: # Should be extended to all other doc types + doc = factory() + url = urlreverse("ietf.doc.views_doc.document_bibtex", kwargs=dict(name=doc.name)) + r = self.client.get(url) + self.assertEqual(r.status_code, 404) + authors = PersonFactory.create_batch(2) rfc = WgRfcFactory.create( - #other_aliases = ['rfc6020',], - states = [('draft','rfc'),('draft-iesg','pub')], - std_level_id = 'ps', - time = datetime.datetime(2010,10,10), - ) - num = rfc.rfc_number() - DocEventFactory.create(doc=rfc, type='published_rfc', time = '2010-10-10') + time=datetime.datetime(2010, 10, 10, tzinfo=ZoneInfo(settings.TIME_ZONE)), + authors=authors, + ) + num = rfc.rfc_number + DocEventFactory.create( + doc=rfc, + type="published_rfc", + time=datetime.datetime(2010, 10, 10, tzinfo=RPC_TZINFO), + ) # - url = urlreverse('ietf.doc.views_doc.document_bibtex', kwargs=dict(name=rfc.name)) + url = urlreverse("ietf.doc.views_doc.document_bibtex", kwargs=dict(name=rfc.name)) r = self.client.get(url) - entry = self._parse_bibtex_response(r)["rfc%s"%num] - self.assertEqual(entry['series'], 'Request for Comments') - self.assertEqual(entry['number'], num) - self.assertEqual(entry['doi'], '10.17487/RFC%s'%num) - self.assertEqual(entry['year'], '2010') - self.assertEqual(entry['month'].lower()[0:3], 'oct') - self.assertEqual(entry['url'], f'https://www.rfc-editor.ietf.org/info/rfc{num}') + entry = self._parse_bibtex_response(r)["rfc%s" % num] + self.assertEqual(entry["series"], "Request for Comments") + self.assertEqual(int(entry["number"]), num) + self.assertEqual(entry["doi"], "10.17487/RFC%s" % num) + self.assertEqual(entry["year"], "2010") + self.assertEqual(entry["month"].lower()[0:3], "oct") + self.assertEqual(entry["url"], f"https://www.rfc-editor.ietf.org/info/rfc{num}/") + escaped_author_names = [ + texescape(ra.titlepage_name) + for ra in RfcAuthor.objects.filter(document=rfc) + ] + self.assertEqual(entry["author"], " and ".join(escaped_author_names)) # - self.assertNotIn('day', entry) - + self.assertNotIn("day", entry) + + # test for incorrect case - revision for RFC + rfc = WgRfcFactory(name="rfc0000") + url = urlreverse( + "ietf.doc.views_doc.document_bibtex", kwargs=dict(name=rfc.name, rev="00") + ) + r = self.client.get(url) + self.assertEqual(r.status_code, 404) + april1 = IndividualRfcFactory.create( - stream_id = 'ise', - states = [('draft','rfc'),('draft-iesg','pub')], - std_level_id = 'inf', - time = datetime.datetime(1990,0o4,0o1), - ) - num = april1.rfc_number() - DocEventFactory.create(doc=april1, type='published_rfc', time = '1990-04-01') + stream_id="ise", + std_level_id="inf", + time=datetime.datetime(1990, 4, 1, tzinfo=ZoneInfo(settings.TIME_ZONE)), + ) + num = april1.rfc_number + DocEventFactory.create( + doc=april1, + type="published_rfc", + time=datetime.datetime(1990, 4, 1, tzinfo=RPC_TZINFO), + ) # - url = urlreverse('ietf.doc.views_doc.document_bibtex', kwargs=dict(name=april1.name)) + url = urlreverse( + "ietf.doc.views_doc.document_bibtex", kwargs=dict(name=april1.name) + ) r = self.client.get(url) - self.assertEqual(r.get('Content-Type'), 'text/plain; charset=utf-8') - entry = self._parse_bibtex_response(r)["rfc%s"%num] - self.assertEqual(entry['series'], 'Request for Comments') - self.assertEqual(entry['number'], num) - self.assertEqual(entry['doi'], '10.17487/RFC%s'%num) - self.assertEqual(entry['year'], '1990') - self.assertEqual(entry['month'].lower()[0:3], 'apr') - self.assertEqual(entry['day'], '1') - self.assertEqual(entry['url'], f'https://www.rfc-editor.ietf.org/info/rfc{num}') - + self.assertEqual(r.get("Content-Type"), "text/plain; charset=utf-8") + entry = self._parse_bibtex_response(r)["rfc%s" % num] + self.assertEqual(entry["series"], "Request for Comments") + self.assertEqual(int(entry["number"]), num) + self.assertEqual(entry["doi"], "10.17487/RFC%s" % num) + self.assertEqual(entry["year"], "1990") + self.assertEqual(entry["month"].lower()[0:3], "apr") + self.assertEqual(entry["day"], "1") + self.assertEqual(entry["url"], f"https://www.rfc-editor.ietf.org/info/rfc{num}/") + draft = IndividualDraftFactory.create() - docname = '%s-%s' % (draft.name, draft.rev) - bibname = docname[6:] # drop the 'draft-' prefix - url = urlreverse('ietf.doc.views_doc.document_bibtex', kwargs=dict(name=draft.name)) + docname = "%s-%s" % (draft.name, draft.rev) + bibname = docname[6:] # drop the 'draft-' prefix + url = urlreverse("ietf.doc.views_doc.document_bibtex", kwargs=dict(name=draft.name)) r = self.client.get(url) entry = self._parse_bibtex_response(r)[bibname] - self.assertEqual(entry['note'], 'Work in Progress') - self.assertEqual(entry['number'], docname) - self.assertEqual(entry['year'], str(draft.pub_date().year)) - self.assertEqual(entry['month'].lower()[0:3], draft.pub_date().strftime('%b').lower()) - self.assertEqual(entry['day'], str(draft.pub_date().day)) - self.assertEqual(entry['url'], settings.IDTRACKER_BASE_URL + urlreverse("ietf.doc.views_doc.document_main", kwargs=dict(name=draft.name, rev=draft.rev))) + self.assertEqual(entry["note"], "Work in Progress") + self.assertEqual(entry["number"], docname) + self.assertEqual(entry["year"], str(draft.pub_date().year)) + self.assertEqual( + entry["month"].lower()[0:3], draft.pub_date().strftime("%b").lower() + ) + self.assertEqual(entry["day"], str(draft.pub_date().day)) + self.assertEqual( + entry["url"], + settings.IDTRACKER_BASE_URL + + urlreverse( + "ietf.doc.views_doc.document_main", + kwargs=dict(name=draft.name, rev=draft.rev), + ), + ) # - self.assertNotIn('doi', entry) + self.assertNotIn("doi", entry) def test_document_bibxml(self): draft = IndividualDraftFactory.create() @@ -1966,20 +2289,19 @@ def test_trailing_hypen_digit_name_bibxml(self): class AddCommentTestCase(TestCase): def test_add_comment(self): - draft = WgDraftFactory(name='draft-ietf-mars-test',group__acronym='mars') - url = urlreverse('ietf.doc.views_doc.add_comment', kwargs=dict(name=draft.name)) + draft = WgDraftFactory(name="draft-ietf-mars-test", group__acronym="mars") + url = urlreverse("ietf.doc.views_doc.add_comment", kwargs=dict(name=draft.name)) login_testing_unauthorized(self, "secretary", url) # normal get r = self.client.get(url) self.assertEqual(r.status_code, 200) q = PyQuery(unicontent(r)) - self.assertEqual(len(q('form textarea[name=comment]')), 1) + self.assertEqual(len(q("form textarea[name=comment]")), 1) - # request resurrect events_before = draft.docevent_set.count() mailbox_before = len(outbox) - + r = self.client.post(url, dict(comment="This is a test.")) self.assertEqual(r.status_code, 302) @@ -1987,9 +2309,9 @@ def test_add_comment(self): self.assertEqual("This is a test.", draft.latest_event().desc) self.assertEqual("added_comment", draft.latest_event().type) self.assertEqual(len(outbox), mailbox_before + 1) - self.assertIn("Comment added", outbox[-1]['Subject']) - self.assertIn(draft.name, outbox[-1]['Subject']) - self.assertIn('draft-ietf-mars-test@', outbox[-1]['To']) + self.assertIn("Comment added", outbox[-1]["Subject"]) + self.assertIn(draft.name, outbox[-1]["Subject"]) + self.assertIn("draft-ietf-mars-test@", outbox[-1]["To"]) # Make sure we can also do it as IANA self.client.login(username="iana", password="iana+password") @@ -1998,7 +2320,22 @@ def test_add_comment(self): r = self.client.get(url) self.assertEqual(r.status_code, 200) q = PyQuery(unicontent(r)) - self.assertEqual(len(q('form textarea[name=comment]')), 1) + self.assertEqual(len(q("form textarea[name=comment]")), 1) + + empty_outbox() + rfc = WgRfcFactory() + self.client.login(username="rfc", password="rfc+password") + url = urlreverse("ietf.doc.views_doc.add_comment", kwargs=dict(name=rfc.name)) + r = self.client.post( + url, dict(comment="This is an RFC Editor comment on an RFC.") + ) + self.assertEqual(r.status_code, 302) + + self.assertEqual( + "This is an RFC Editor comment on an RFC.", rfc.latest_event().desc + ) + self.assertEqual(len(outbox), 1) + self.assertIn("This is an RFC Editor comment on an RFC.", get_payload_text(outbox[0])) class TemplateTagTest(TestCase): @@ -2012,7 +2349,7 @@ class ReferencesTest(TestCase): def test_references(self): doc1 = WgDraftFactory(name='draft-ietf-mars-test') - doc2 = IndividualDraftFactory(name='draft-imaginary-independent-submission').docalias.first() + doc2 = IndividualDraftFactory(name='draft-imaginary-independent-submission') RelatedDocument.objects.get_or_create(source=doc1,target=doc2,relationship=DocRelationshipName.objects.get(slug='refnorm')) url = urlreverse('ietf.doc.views_doc.document_references', kwargs=dict(name=doc1.name)) r = self.client.get(url) @@ -2024,123 +2361,169 @@ def test_references(self): self.assertContains(r, doc1.name) class GenerateDraftAliasesTests(TestCase): - def setUp(self): - super().setUp() - self.doc_aliases_file = NamedTemporaryFile(delete=False, mode='w+') - self.doc_aliases_file.close() - self.doc_virtual_file = NamedTemporaryFile(delete=False, mode='w+') - self.doc_virtual_file.close() - self.saved_draft_aliases_path = settings.DRAFT_ALIASES_PATH - self.saved_draft_virtual_path = settings.DRAFT_VIRTUAL_PATH - settings.DRAFT_ALIASES_PATH = self.doc_aliases_file.name - settings.DRAFT_VIRTUAL_PATH = self.doc_virtual_file.name - - def tearDown(self): - settings.DRAFT_ALIASES_PATH = self.saved_draft_aliases_path - settings.DRAFT_VIRTUAL_PATH = self.saved_draft_virtual_path - os.unlink(self.doc_aliases_file.name) - os.unlink(self.doc_virtual_file.name) - super().tearDown() - - def testManagementCommand(self): - a_month_ago = datetime.datetime.now() - datetime.timedelta(30) - ad = RoleFactory(name_id='ad', group__type_id='area', group__state_id='active').person - shepherd = PersonFactory() - author1 = PersonFactory() - author2 = PersonFactory() - author3 = PersonFactory() - author4 = PersonFactory() - author5 = PersonFactory() - author6 = PersonFactory() - mars = GroupFactory(type_id='wg', acronym='mars') - marschairman = PersonFactory(user__username='marschairman') - mars.role_set.create(name_id='chair', person=marschairman, email=marschairman.email()) - doc1 = IndividualDraftFactory(authors=[author1], shepherd=shepherd.email(), ad=ad) - doc2 = WgDraftFactory(name='draft-ietf-mars-test', group__acronym='mars', authors=[author2], ad=ad) - doc3 = WgRfcFactory.create(name='draft-ietf-mars-finished', group__acronym='mars', authors=[author3], ad=ad, std_level_id='ps', states=[('draft','rfc'),('draft-iesg','pub')], time=a_month_ago) - DocEventFactory.create(doc=doc3, type='published_rfc', time=a_month_ago.strftime("%Y-%m-%d")) - doc4 = WgRfcFactory.create(authors=[author4,author5], ad=ad, std_level_id='ps', states=[('draft','rfc'),('draft-iesg','pub')], time=datetime.datetime(2010,10,10)) - DocEventFactory.create(doc=doc4, type='published_rfc', time = '2010-10-10') - doc5 = IndividualDraftFactory(authors=[author6]) - - args = [ ] - kwargs = { } - out = io.StringIO() - call_command("generate_draft_aliases", *args, **kwargs, stdout=out, stderr=out) - self.assertFalse(out.getvalue()) - - with open(settings.DRAFT_ALIASES_PATH) as afile: - acontent = afile.read() - self.assertTrue(all([x in acontent for x in [ - 'xfilter-' + doc1.name, - 'xfilter-' + doc1.name + '.ad', - 'xfilter-' + doc1.name + '.authors', - 'xfilter-' + doc1.name + '.shepherd', - 'xfilter-' + doc1.name + '.all', - 'xfilter-' + doc2.name, - 'xfilter-' + doc2.name + '.ad', - 'xfilter-' + doc2.name + '.authors', - 'xfilter-' + doc2.name + '.chairs', - 'xfilter-' + doc2.name + '.all', - 'xfilter-' + doc3.name, - 'xfilter-' + doc3.name + '.ad', - 'xfilter-' + doc3.name + '.authors', - 'xfilter-' + doc3.name + '.chairs', - 'xfilter-' + doc5.name, - 'xfilter-' + doc5.name + '.authors', - 'xfilter-' + doc5.name + '.all', - ]])) - self.assertFalse(all([x in acontent for x in [ - 'xfilter-' + doc1.name + '.chairs', - 'xfilter-' + doc2.name + '.shepherd', - 'xfilter-' + doc3.name + '.shepherd', - 'xfilter-' + doc4.name, - 'xfilter-' + doc5.name + '.shepherd', - 'xfilter-' + doc5.name + '.ad', - ]])) - - with open(settings.DRAFT_VIRTUAL_PATH) as vfile: - vcontent = vfile.read() - self.assertTrue(all([x in vcontent for x in [ - ad.email_address(), - shepherd.email_address(), - marschairman.email_address(), - author1.email_address(), - author2.email_address(), - author3.email_address(), - author6.email_address(), - ]])) - self.assertFalse(all([x in vcontent for x in [ - author4.email_address(), - author5.email_address(), - ]])) - self.assertTrue(all([x in vcontent for x in [ - 'xfilter-' + doc1.name, - 'xfilter-' + doc1.name + '.ad', - 'xfilter-' + doc1.name + '.authors', - 'xfilter-' + doc1.name + '.shepherd', - 'xfilter-' + doc1.name + '.all', - 'xfilter-' + doc2.name, - 'xfilter-' + doc2.name + '.ad', - 'xfilter-' + doc2.name + '.authors', - 'xfilter-' + doc2.name + '.chairs', - 'xfilter-' + doc2.name + '.all', - 'xfilter-' + doc3.name, - 'xfilter-' + doc3.name + '.ad', - 'xfilter-' + doc3.name + '.authors', - 'xfilter-' + doc3.name + '.chairs', - 'xfilter-' + doc5.name, - 'xfilter-' + doc5.name + '.authors', - 'xfilter-' + doc5.name + '.all', - ]])) - self.assertFalse(all([x in vcontent for x in [ - 'xfilter-' + doc1.name + '.chairs', - 'xfilter-' + doc2.name + '.shepherd', - 'xfilter-' + doc3.name + '.shepherd', - 'xfilter-' + doc4.name, - 'xfilter-' + doc5.name + '.shepherd', - 'xfilter-' + doc5.name + '.ad', - ]])) + @override_settings(TOOLS_SERVER="tools.example.org", DRAFT_ALIAS_DOMAIN="draft.example.org") + def test_generator_class(self): + """The DraftAliasGenerator should generate the same lists as the old mgmt cmd""" + a_month_ago = (timezone.now() - datetime.timedelta(30)).astimezone(RPC_TZINFO) + a_month_ago = a_month_ago.replace(hour=0, minute=0, second=0, microsecond=0) + ad = RoleFactory( + name_id="ad", group__type_id="area", group__state_id="active" + ).person + shepherd = PersonFactory() + author1 = PersonFactory() + author2 = PersonFactory() + author3 = PersonFactory() + author4 = PersonFactory() + author5 = PersonFactory() + author6 = PersonFactory() + mars = GroupFactory(type_id="wg", acronym="mars") + marschairman = PersonFactory(user__username="marschairman") + mars.role_set.create( + name_id="chair", person=marschairman, email=marschairman.email() + ) + doc1 = IndividualDraftFactory(authors=[author1], shepherd=shepherd.email(), ad=ad) + doc2 = WgDraftFactory( + name="draft-ietf-mars-test", group__acronym="mars", authors=[author2], ad=ad + ) + doc2.notify = f"{doc2.name}.ad@draft.example.org" + doc2.save() + doc3 = WgDraftFactory.create( + name="draft-ietf-mars-finished", + group__acronym="mars", + authors=[author3], + ad=ad, + std_level_id="ps", + states=[("draft", "rfc"), ("draft-iesg", "pub")], + time=a_month_ago, + ) + rfc3 = WgRfcFactory() + DocEventFactory.create(doc=rfc3, type="published_rfc", time=a_month_ago) + doc3.relateddocument_set.create(relationship_id="became_rfc", target=rfc3) + doc4 = WgDraftFactory.create( + authors=[author4, author5], + ad=ad, + std_level_id="ps", + states=[("draft", "rfc"), ("draft-iesg", "pub")], + time=datetime.datetime(2010, 10, 10, tzinfo=ZoneInfo(settings.TIME_ZONE)), + ) + rfc4 = WgRfcFactory() + DocEventFactory.create( + doc=rfc4, + type="published_rfc", + time=datetime.datetime(2010, 10, 10, tzinfo=RPC_TZINFO), + ) + doc4.relateddocument_set.create(relationship_id="became_rfc", target=rfc4) + doc5 = IndividualDraftFactory(authors=[author6]) + + output = [(alias, alist) for alias, alist in DraftAliasGenerator()] + alias_dict = dict(output) + self.assertEqual(len(alias_dict), len(output)) # no duplicate aliases + expected_dict = { + doc1.name: [author1.email_address()], + doc1.name + ".ad": [ad.email_address()], + doc1.name + ".authors": [author1.email_address()], + doc1.name + ".shepherd": [shepherd.email_address()], + doc1.name + + ".all": [ + author1.email_address(), + ad.email_address(), + shepherd.email_address(), + ], + doc2.name: [author2.email_address()], + doc2.name + ".ad": [ad.email_address()], + doc2.name + ".authors": [author2.email_address()], + doc2.name + ".chairs": [marschairman.email_address()], + doc2.name + ".notify": [ad.email_address()], + doc2.name + + ".all": [ + author2.email_address(), + ad.email_address(), + marschairman.email_address(), + ], + doc3.name: [author3.email_address()], + doc3.name + ".ad": [ad.email_address()], + doc3.name + ".authors": [author3.email_address()], + doc3.name + ".chairs": [marschairman.email_address()], + doc3.name + + ".all": [ + author3.email_address(), + ad.email_address(), + marschairman.email_address(), + ], + doc5.name: [author6.email_address()], + doc5.name + ".authors": [author6.email_address()], + doc5.name + ".all": [author6.email_address()], + } + # Sort lists for comparison + self.assertEqual( + {k: sorted(v) for k, v in alias_dict.items()}, + {k: sorted(v) for k, v in expected_dict.items()}, + ) + + # check single name + output = [(alias, alist) for alias, alist in DraftAliasGenerator(Document.objects.filter(name=doc1.name))] + alias_dict = dict(output) + self.assertEqual(len(alias_dict), len(output)) # no duplicate aliases + expected_dict = { + doc1.name: [author1.email_address()], + doc1.name + ".ad": [ad.email_address()], + doc1.name + ".authors": [author1.email_address()], + doc1.name + ".shepherd": [shepherd.email_address()], + doc1.name + + ".all": [ + author1.email_address(), + ad.email_address(), + shepherd.email_address(), + ], + } + # Sort lists for comparison + self.assertEqual( + {k: sorted(v) for k, v in alias_dict.items()}, + {k: sorted(v) for k, v in expected_dict.items()}, + ) + + @override_settings(TOOLS_SERVER="tools.example.org", DRAFT_ALIAS_DOMAIN="draft.example.org") + def test_get_draft_notify_emails(self): + ad = PersonFactory() + shepherd = PersonFactory() + author = PersonFactory() + doc = DocumentFactory(authors=[author], shepherd=shepherd.email(), ad=ad) + generator = DraftAliasGenerator() + + doc.notify = f"{doc.name}@draft.example.org" + doc.save() + self.assertCountEqual(generator.get_draft_notify_emails(doc), [author.email_address()]) + + doc.notify = f"{doc.name}.ad@draft.example.org" + doc.save() + self.assertCountEqual(generator.get_draft_notify_emails(doc), [ad.email_address()]) + + doc.notify = f"{doc.name}.shepherd@draft.example.org" + doc.save() + self.assertCountEqual(generator.get_draft_notify_emails(doc), [shepherd.email_address()]) + + doc.notify = f"{doc.name}.all@draft.example.org" + doc.save() + self.assertCountEqual( + generator.get_draft_notify_emails(doc), + [ad.email_address(), author.email_address(), shepherd.email_address()] + ) + + doc.notify = f"{doc.name}.notify@draft.example.org" + doc.save() + self.assertCountEqual(generator.get_draft_notify_emails(doc), []) + + doc.notify = f"{doc.name}.ad@somewhere.example.com" + doc.save() + self.assertCountEqual(generator.get_draft_notify_emails(doc), [f"{doc.name}.ad@somewhere.example.com"]) + + doc.notify = f"somebody@example.com, nobody@example.com, {doc.name}.ad@tools.example.org" + doc.save() + self.assertCountEqual( + generator.get_draft_notify_emails(doc), + ["somebody@example.com", "nobody@example.com", ad.email_address()] + ) + class EmailAliasesTests(TestCase): @@ -2149,37 +2532,20 @@ def setUp(self): WgDraftFactory(name='draft-ietf-mars-test',group__acronym='mars') WgDraftFactory(name='draft-ietf-ames-test',group__acronym='ames') RoleFactory(group__type_id='review', group__acronym='yangdoctors', name_id='secr') - self.doc_alias_file = NamedTemporaryFile(delete=False, mode='w+') - self.doc_alias_file.write("""# Generated by hand at 2015-02-12_16:26:45 -virtual.ietf.org anything -draft-ietf-mars-test@ietf.org xfilter-draft-ietf-mars-test -expand-draft-ietf-mars-test@virtual.ietf.org mars-author@example.com, mars-collaborator@example.com -draft-ietf-mars-test.authors@ietf.org xfilter-draft-ietf-mars-test.authors -expand-draft-ietf-mars-test.authors@virtual.ietf.org mars-author@example.mars, mars-collaborator@example.mars -draft-ietf-mars-test.chairs@ietf.org xfilter-draft-ietf-mars-test.chairs -expand-draft-ietf-mars-test.chairs@virtual.ietf.org mars-chair@example.mars -draft-ietf-mars-test.all@ietf.org xfilter-draft-ietf-mars-test.all -expand-draft-ietf-mars-test.all@virtual.ietf.org mars-author@example.mars, mars-collaborator@example.mars, mars-chair@example.mars -draft-ietf-ames-test@ietf.org xfilter-draft-ietf-ames-test -expand-draft-ietf-ames-test@virtual.ietf.org ames-author@example.com, ames-collaborator@example.com -draft-ietf-ames-test.authors@ietf.org xfilter-draft-ietf-ames-test.authors -expand-draft-ietf-ames-test.authors@virtual.ietf.org ames-author@example.ames, ames-collaborator@example.ames -draft-ietf-ames-test.chairs@ietf.org xfilter-draft-ietf-ames-test.chairs -expand-draft-ietf-ames-test.chairs@virtual.ietf.org ames-chair@example.ames -draft-ietf-ames-test.all@ietf.org xfilter-draft-ietf-ames-test.all -expand-draft-ietf-ames-test.all@virtual.ietf.org ames-author@example.ames, ames-collaborator@example.ames, ames-chair@example.ames - -""") - self.doc_alias_file.close() - self.saved_draft_virtual_path = settings.DRAFT_VIRTUAL_PATH - settings.DRAFT_VIRTUAL_PATH = self.doc_alias_file.name - - def tearDown(self): - settings.DRAFT_VIRTUAL_PATH = self.saved_draft_virtual_path - os.unlink(self.doc_alias_file.name) - super().tearDown() - - def testAliases(self): + + + @mock.patch("ietf.doc.views_doc.get_doc_email_aliases") + def testAliases(self, mock_get_aliases): + mock_get_aliases.return_value = [ + {"doc_name": "draft-ietf-mars-test", "alias_type": "", "expansion": "mars-author@example.mars, mars-collaborator@example.mars"}, + {"doc_name": "draft-ietf-mars-test", "alias_type": ".authors", "expansion": "mars-author@example.mars, mars-collaborator@example.mars"}, + {"doc_name": "draft-ietf-mars-test", "alias_type": ".chairs", "expansion": "mars-chair@example.mars"}, + {"doc_name": "draft-ietf-mars-test", "alias_type": ".all", "expansion": "mars-author@example.mars, mars-collaborator@example.mars, mars-chair@example.mars"}, + {"doc_name": "draft-ietf-ames-test", "alias_type": "", "expansion": "ames-author@example.ames, ames-collaborator@example.ames"}, + {"doc_name": "draft-ietf-ames-test", "alias_type": ".authors", "expansion": "ames-author@example.ames, ames-collaborator@example.ames"}, + {"doc_name": "draft-ietf-ames-test", "alias_type": ".chairs", "expansion": "ames-chair@example.ames"}, + {"doc_name": "draft-ietf-ames-test", "alias_type": ".all", "expansion": "ames-author@example.ames, ames-collaborator@example.ames, ames-chair@example.ames"}, + ] PersonFactory(user__username='plain') url = urlreverse('ietf.doc.urls.redirect.document_email', kwargs=dict(name="draft-ietf-mars-test")) r = self.client.get(url) @@ -2189,16 +2555,70 @@ def testAliases(self): login_testing_unauthorized(self, "plain", url) r = self.client.get(url) self.assertEqual(r.status_code, 200) + self.assertEqual(mock_get_aliases.call_args, mock.call()) self.assertTrue(all([x in unicontent(r) for x in ['mars-test@','mars-test.authors@','mars-test.chairs@']])) self.assertTrue(all([x in unicontent(r) for x in ['ames-test@','ames-test.authors@','ames-test.chairs@']])) - def testExpansions(self): + + @mock.patch("ietf.doc.views_doc.get_doc_email_aliases") + def testExpansions(self, mock_get_aliases): + mock_get_aliases.return_value = [ + {"doc_name": "draft-ietf-mars-test", "alias_type": "", "expansion": "mars-author@example.mars, mars-collaborator@example.mars"}, + {"doc_name": "draft-ietf-mars-test", "alias_type": ".authors", "expansion": "mars-author@example.mars, mars-collaborator@example.mars"}, + {"doc_name": "draft-ietf-mars-test", "alias_type": ".chairs", "expansion": "mars-chair@example.mars"}, + {"doc_name": "draft-ietf-mars-test", "alias_type": ".all", "expansion": "mars-author@example.mars, mars-collaborator@example.mars, mars-chair@example.mars"}, + ] url = urlreverse('ietf.doc.views_doc.document_email', kwargs=dict(name="draft-ietf-mars-test")) r = self.client.get(url) + self.assertEqual(mock_get_aliases.call_args, mock.call("draft-ietf-mars-test")) self.assertEqual(r.status_code, 200) self.assertContains(r, 'draft-ietf-mars-test.all@ietf.org') self.assertContains(r, 'iesg_ballot_saved') + + @mock.patch("ietf.doc.utils.DraftAliasGenerator") + def test_get_doc_email_aliases(self, mock_alias_gen_cls): + mock_alias_gen_cls.return_value = [ + ("draft-something-or-other.some-type", ["somebody@example.com"]), + ("draft-something-or-other", ["somebody@example.com"]), + ("draft-nothing-at-all", ["nobody@example.com"]), + ("draft-nothing-at-all.some-type", ["nobody@example.com"]), + ] + # order is important in the response - should be sorted by doc name and otherwise left + # in order + self.assertEqual( + get_doc_email_aliases(), + [ + { + "doc_name": "draft-nothing-at-all", + "alias_type": "", + "expansion": "nobody@example.com", + }, + { + "doc_name": "draft-nothing-at-all", + "alias_type": ".some-type", + "expansion": "nobody@example.com", + }, + { + "doc_name": "draft-something-or-other", + "alias_type": ".some-type", + "expansion": "somebody@example.com", + }, + { + "doc_name": "draft-something-or-other", + "alias_type": "", + "expansion": "somebody@example.com", + }, + ], + ) + self.assertEqual(mock_alias_gen_cls.call_args, mock.call(None)) + # Repeat with a name, no need to re-test that the alias list is actually passed through, just + # check that the DraftAliasGenerator is called correctly + draft = WgDraftFactory() + get_doc_email_aliases(draft.name) + self.assertQuerySetEqual(mock_alias_gen_cls.call_args[0][0], Document.objects.filter(pk=draft.pk)) + + class DocumentMeetingTests(TestCase): def setUp(self): @@ -2211,7 +2631,7 @@ def setUp(self): self.other_chair = PersonFactory() self.other_group.role_set.create(name_id='chair',person=self.other_chair,email=self.other_chair.email()) - today = datetime.date.today() + today = date_today() cut_days = settings.MEETING_MATERIALS_DEFAULT_SUBMISSION_CORRECTION_DAYS self.past_cutoff = SessionFactory.create(meeting__type_id='ietf',group=self.group,meeting__date=today-datetime.timedelta(days=1+cut_days)) self.past = SessionFactory.create(meeting__type_id='ietf',group=self.group,meeting__date=today-datetime.timedelta(days=cut_days/2)) @@ -2221,8 +2641,8 @@ def setUp(self): def test_view_document_meetings(self): doc = IndividualDraftFactory.create() - doc.sessionpresentation_set.create(session=self.inprog,rev=None) - doc.sessionpresentation_set.create(session=self.interim,rev=None) + doc.presentations.create(session=self.inprog,rev=None) + doc.presentations.create(session=self.interim,rev=None) url = urlreverse('ietf.doc.views_doc.all_presentations', kwargs=dict(name=doc.name)) response = self.client.get(url) @@ -2233,8 +2653,8 @@ def test_view_document_meetings(self): self.assertFalse(q('#addsessionsbutton')) self.assertFalse(q("a.btn:contains('Remove document')")) - doc.sessionpresentation_set.create(session=self.past_cutoff,rev=None) - doc.sessionpresentation_set.create(session=self.past,rev=None) + doc.presentations.create(session=self.past_cutoff,rev=None) + doc.presentations.create(session=self.past,rev=None) self.client.login(username="secretary", password="secretary+password") response = self.client.get(url) @@ -2267,41 +2687,72 @@ def test_view_document_meetings(self): self.assertFalse(q("#futuremeets a.btn:contains('Remove document')")) self.assertFalse(q("#pastmeets a.btn:contains('Remove document')")) - def test_edit_document_session(self): + @override_settings(MEETECHO_API_CONFIG="fake settings") + @mock.patch("ietf.doc.views_doc.SlidesManager") + def test_edit_document_session(self, mock_slides_manager_cls): doc = IndividualDraftFactory.create() - sp = doc.sessionpresentation_set.create(session=self.future,rev=None) + sp = doc.presentations.create(session=self.future,rev=None) url = urlreverse('ietf.doc.views_doc.edit_sessionpresentation',kwargs=dict(name='no-such-doc',session_id=sp.session_id)) response = self.client.get(url) self.assertEqual(response.status_code, 404) + self.assertFalse(mock_slides_manager_cls.called) url = urlreverse('ietf.doc.views_doc.edit_sessionpresentation',kwargs=dict(name=doc.name,session_id=0)) response = self.client.get(url) self.assertEqual(response.status_code, 404) + self.assertFalse(mock_slides_manager_cls.called) url = urlreverse('ietf.doc.views_doc.edit_sessionpresentation',kwargs=dict(name=doc.name,session_id=sp.session_id)) response = self.client.get(url) self.assertEqual(response.status_code, 404) + self.assertFalse(mock_slides_manager_cls.called) self.client.login(username=self.other_chair.user.username,password='%s+password'%self.other_chair.user.username) response = self.client.get(url) self.assertEqual(response.status_code, 404) - + self.assertFalse(mock_slides_manager_cls.called) + self.client.login(username=self.group_chair.user.username,password='%s+password'%self.group_chair.user.username) response = self.client.get(url) self.assertEqual(response.status_code, 200) q = PyQuery(response.content) self.assertEqual(2,len(q('select#id_version option'))) + self.assertFalse(mock_slides_manager_cls.called) + # edit draft self.assertEqual(1,doc.docevent_set.count()) response = self.client.post(url,{'version':'00','save':''}) self.assertEqual(response.status_code, 302) - self.assertEqual(doc.sessionpresentation_set.get(pk=sp.pk).rev,'00') + self.assertEqual(doc.presentations.get(pk=sp.pk).rev,'00') self.assertEqual(2,doc.docevent_set.count()) + self.assertFalse(mock_slides_manager_cls.called) + + # editing slides should call Meetecho API + slides = SessionPresentationFactory( + session=self.future, + document__type_id="slides", + document__rev="00", + rev=None, + order=1, + ).document + url = urlreverse( + "ietf.doc.views_doc.edit_sessionpresentation", + kwargs={"name": slides.name, "session_id": self.future.pk}, + ) + response = self.client.post(url, {"version": "00", "save": ""}) + self.assertEqual(response.status_code, 302) + self.assertEqual(mock_slides_manager_cls.call_count, 1) + self.assertEqual(mock_slides_manager_cls.call_args, mock.call(api_config="fake settings")) + self.assertEqual(mock_slides_manager_cls.return_value.send_update.call_count, 1) + self.assertEqual( + mock_slides_manager_cls.return_value.send_update.call_args, + mock.call(self.future), + ) def test_edit_document_session_after_proceedings_closed(self): doc = IndividualDraftFactory.create() - sp = doc.sessionpresentation_set.create(session=self.past_cutoff,rev=None) + sp = doc.presentations.create(session=self.past_cutoff,rev=None) url = urlreverse('ietf.doc.views_doc.edit_sessionpresentation',kwargs=dict(name=doc.name,session_id=sp.session_id)) self.client.login(username=self.group_chair.user.username,password='%s+password'%self.group_chair.user.username) @@ -2314,39 +2765,64 @@ def test_edit_document_session_after_proceedings_closed(self): q=PyQuery(response.content) self.assertEqual(1,len(q(".alert-warning:contains('may affect published proceedings')"))) - def test_remove_document_session(self): + @override_settings(MEETECHO_API_CONFIG="fake settings") + @mock.patch("ietf.doc.views_doc.SlidesManager") + def test_remove_document_session(self, mock_slides_manager_cls): doc = IndividualDraftFactory.create() - sp = doc.sessionpresentation_set.create(session=self.future,rev=None) + sp = doc.presentations.create(session=self.future,rev=None) url = urlreverse('ietf.doc.views_doc.remove_sessionpresentation',kwargs=dict(name='no-such-doc',session_id=sp.session_id)) response = self.client.get(url) self.assertEqual(response.status_code, 404) + self.assertFalse(mock_slides_manager_cls.called) url = urlreverse('ietf.doc.views_doc.remove_sessionpresentation',kwargs=dict(name=doc.name,session_id=0)) response = self.client.get(url) self.assertEqual(response.status_code, 404) + self.assertFalse(mock_slides_manager_cls.called) url = urlreverse('ietf.doc.views_doc.remove_sessionpresentation',kwargs=dict(name=doc.name,session_id=sp.session_id)) response = self.client.get(url) self.assertEqual(response.status_code, 404) + self.assertFalse(mock_slides_manager_cls.called) self.client.login(username=self.other_chair.user.username,password='%s+password'%self.other_chair.user.username) response = self.client.get(url) self.assertEqual(response.status_code, 404) - + self.assertFalse(mock_slides_manager_cls.called) + self.client.login(username=self.group_chair.user.username,password='%s+password'%self.group_chair.user.username) response = self.client.get(url) self.assertEqual(response.status_code, 200) + self.assertFalse(mock_slides_manager_cls.called) + # removing a draft self.assertEqual(1,doc.docevent_set.count()) response = self.client.post(url,{'remove_session':''}) self.assertEqual(response.status_code, 302) - self.assertFalse(doc.sessionpresentation_set.filter(pk=sp.pk).exists()) + self.assertFalse(doc.presentations.filter(pk=sp.pk).exists()) self.assertEqual(2,doc.docevent_set.count()) + self.assertFalse(mock_slides_manager_cls.called) + + # removing slides should call Meetecho API + slides = SessionPresentationFactory(session=self.future, document__type_id="slides", order=1).document + url = urlreverse( + "ietf.doc.views_doc.remove_sessionpresentation", + kwargs={"name": slides.name, "session_id": self.future.pk}, + ) + response = self.client.post(url, {"remove_session": ""}) + self.assertEqual(response.status_code, 302) + self.assertEqual(mock_slides_manager_cls.call_count, 1) + self.assertEqual(mock_slides_manager_cls.call_args, mock.call(api_config="fake settings")) + self.assertEqual(mock_slides_manager_cls.return_value.delete.call_count, 1) + self.assertEqual( + mock_slides_manager_cls.return_value.delete.call_args, + mock.call(self.future, slides), + ) def test_remove_document_session_after_proceedings_closed(self): doc = IndividualDraftFactory.create() - sp = doc.sessionpresentation_set.create(session=self.past_cutoff,rev=None) + sp = doc.presentations.create(session=self.past_cutoff,rev=None) url = urlreverse('ietf.doc.views_doc.remove_sessionpresentation',kwargs=dict(name=doc.name,session_id=sp.session_id)) self.client.login(username=self.group_chair.user.username,password='%s+password'%self.group_chair.user.username) @@ -2359,28 +2835,49 @@ def test_remove_document_session_after_proceedings_closed(self): q=PyQuery(response.content) self.assertEqual(1,len(q(".alert-warning:contains('may affect published proceedings')"))) - def test_add_document_session(self): + @override_settings(MEETECHO_API_CONFIG="fake settings") + @mock.patch("ietf.doc.views_doc.SlidesManager") + def test_add_document_session(self, mock_slides_manager_cls): doc = IndividualDraftFactory.create() url = urlreverse('ietf.doc.views_doc.add_sessionpresentation',kwargs=dict(name=doc.name)) login_testing_unauthorized(self,self.group_chair.user.username,url) response = self.client.get(url) self.assertEqual(response.status_code,200) - + self.assertFalse(mock_slides_manager_cls.called) + response = self.client.post(url,{'session':0,'version':'current'}) self.assertEqual(response.status_code,200) q=PyQuery(response.content) self.assertTrue(q('.form-select.is-invalid')) + self.assertFalse(mock_slides_manager_cls.called) response = self.client.post(url,{'session':self.future.pk,'version':'bogus version'}) self.assertEqual(response.status_code,200) q=PyQuery(response.content) self.assertTrue(q('.form-select.is-invalid')) + self.assertFalse(mock_slides_manager_cls.called) + # adding a draft self.assertEqual(1,doc.docevent_set.count()) response = self.client.post(url,{'session':self.future.pk,'version':'current'}) self.assertEqual(response.status_code,302) self.assertEqual(2,doc.docevent_set.count()) + self.assertEqual(doc.presentations.get(session__pk=self.future.pk).order, 0) + self.assertFalse(mock_slides_manager_cls.called) + + # adding slides should set order / call Meetecho API + slides = DocumentFactory(type_id="slides") + url = urlreverse("ietf.doc.views_doc.add_sessionpresentation", kwargs=dict(name=slides.name)) + response = self.client.post(url, {"session": self.future.pk, "version": "current"}) + self.assertEqual(response.status_code,302) + self.assertEqual(slides.presentations.get(session__pk=self.future.pk).order, 1) + self.assertEqual(mock_slides_manager_cls.call_args, mock.call(api_config="fake settings")) + self.assertEqual(mock_slides_manager_cls.return_value.add.call_count, 1) + self.assertEqual( + mock_slides_manager_cls.return_value.add.call_args, + mock.call(self.future, slides, order=1), + ) def test_get_related_meeting(self): """Should be able to retrieve related meeting""" @@ -2413,60 +2910,6 @@ def test_get_related_meeting(self): self.assertIsNone(doc.get_related_meeting(), f'{doc.type.slug} should not be related to meeting') class ChartTests(ResourceTestCaseMixin, TestCase): - def test_search_chart_conf(self): - doc = IndividualDraftFactory() - - conf_url = urlreverse('ietf.doc.views_stats.chart_conf_newrevisiondocevent') - - # No qurey arguments; expect an empty json object - r = self.client.get(conf_url) - self.assertValidJSONResponse(r) - self.assertEqual(unicontent(r), '{}') - - # No match - r = self.client.get(conf_url + '?activedrafts=on&name=thisisnotadocumentname') - self.assertValidJSONResponse(r) - d = r.json() - self.assertEqual(d['chart']['type'], settings.CHART_TYPE_COLUMN_OPTIONS['chart']['type']) - - r = self.client.get(conf_url + '?activedrafts=on&name=%s'%doc.name[6:12]) - self.assertValidJSONResponse(r) - d = r.json() - self.assertEqual(d['chart']['type'], settings.CHART_TYPE_COLUMN_OPTIONS['chart']['type']) - self.assertEqual(len(d['series'][0]['data']), 0) - - def test_search_chart_data(self): - doc = IndividualDraftFactory() - - data_url = urlreverse('ietf.doc.views_stats.chart_data_newrevisiondocevent') - - # No qurey arguments; expect an empty json list - r = self.client.get(data_url) - self.assertValidJSONResponse(r) - self.assertEqual(unicontent(r), '[]') - - # No match - r = self.client.get(data_url + '?activedrafts=on&name=thisisnotadocumentname') - self.assertValidJSONResponse(r) - d = r.json() - self.assertEqual(unicontent(r), '[]') - - r = self.client.get(data_url + '?activedrafts=on&name=%s'%doc.name[6:12]) - self.assertValidJSONResponse(r) - d = r.json() - self.assertEqual(len(d), 1) - self.assertEqual(len(d[0]), 2) - - def test_search_chart(self): - doc = IndividualDraftFactory() - - chart_url = urlreverse('ietf.doc.views_stats.chart_newrevisiondocevent') - r = self.client.get(chart_url) - self.assertEqual(r.status_code, 200) - - r = self.client.get(chart_url + '?activedrafts=on&name=%s'%doc.name[6:12]) - self.assertEqual(r.status_code, 200) - def test_personal_chart(self): person = PersonFactory.create() IndividualDraftFactory.create( @@ -2479,7 +2922,7 @@ def test_personal_chart(self): self.assertValidJSONResponse(r) d = r.json() self.assertEqual(d['chart']['type'], settings.CHART_TYPE_COLUMN_OPTIONS['chart']['type']) - self.assertEqual("New draft revisions over time for %s" % person.name, d['title']['text']) + self.assertEqual("New Internet-Draft revisions over time for %s" % person.name, d['title']['text']) data_url = urlreverse('ietf.doc.views_stats.chart_data_person_drafts', kwargs=dict(id=person.id)) @@ -2488,6 +2931,7 @@ def test_personal_chart(self): d = r.json() self.assertEqual(len(d), 1) self.assertEqual(len(d[0]), 2) + self.assertEqual(d[0][1], 1) page_url = urlreverse('ietf.person.views.profile', kwargs=dict(email_or_name=person.name)) r = self.client.get(page_url) @@ -2553,7 +2997,7 @@ def setUp(self): self.doc.save_with_history([e]) # This is necessary for the view to be able to find the document - # which hints that the view has an issue : if a materials document is taken out of all SessionPresentations, it is no longer accessable by this view + # which hints that the view has an issue : if a materials document is taken out of all SessionPresentations, it is no longer accessible by this view SessionPresentationFactory(session__meeting__number=meeting_number, session__group=self.doc.group, document=self.doc) def test_markdown_and_text(self): @@ -2572,247 +3016,63 @@ def test_markdown_and_text(self): class Idnits2SupportTests(TestCase): settings_temp_path_overrides = TestCase.settings_temp_path_overrides + ['DERIVED_DIR'] - def test_obsoleted(self): - rfc = WgRfcFactory(alias2__name='rfc1001') - WgRfcFactory(alias2__name='rfc1003',relations=[('obs',rfc)]) - rfc = WgRfcFactory(alias2__name='rfc1005') - WgRfcFactory(alias2__name='rfc1007',relations=[('obs',rfc)]) + def test_generate_idnits2_rfcs_obsoleted(self): + rfc = WgRfcFactory(rfc_number=1001) + WgRfcFactory(rfc_number=1003,relations=[('obs',rfc)]) + rfc = WgRfcFactory(rfc_number=1005) + WgRfcFactory(rfc_number=1007,relations=[('obs',rfc)]) + blob = generate_idnits2_rfcs_obsoleted() + self.assertEqual(blob, b'1001 1003\n1005 1007\n'.decode("utf8")) + def test_obsoleted(self): url = urlreverse('ietf.doc.views_doc.idnits2_rfcs_obsoleted') r = self.client.get(url) self.assertEqual(r.status_code, 404) - call_command('generate_idnits2_rfcs_obsoleted') + # value written is arbitrary, expect it to be passed through + (Path(settings.DERIVED_DIR) / "idnits2-rfcs-obsoleted").write_bytes(b'1001 1003\n1005 1007\n') url = urlreverse('ietf.doc.views_doc.idnits2_rfcs_obsoleted') r = self.client.get(url) self.assertEqual(r.status_code, 200) self.assertEqual(r.content, b'1001 1003\n1005 1007\n') - def test_rfc_status(self): + def test_generate_idnits2_rfc_status(self): for slug in ('bcp', 'ds', 'exp', 'hist', 'inf', 'std', 'ps', 'unkn'): WgRfcFactory(std_level_id=slug) + blob = generate_idnits2_rfc_status().replace("\n", "") + self.assertEqual(blob[6312-1], "O") + + def test_rfc_status(self): url = urlreverse('ietf.doc.views_doc.idnits2_rfc_status') r = self.client.get(url) self.assertEqual(r.status_code,404) - call_command('generate_idnits2_rfc_status') + # value written is arbitrary, expect it to be passed through + (Path(settings.DERIVED_DIR) / "idnits2-rfc-status").write_bytes(b'1001 1003\n1005 1007\n') r = self.client.get(url) self.assertEqual(r.status_code,200) - blob = unicontent(r).replace('\n','') - self.assertEqual(blob[6312-1],'O') + self.assertEqual(r.content, b'1001 1003\n1005 1007\n') def test_idnits2_state(self): rfc = WgRfcFactory() - url = urlreverse('ietf.doc.views_doc.idnits2_state', kwargs=dict(name=rfc.canonical_name())) + draft = WgDraftFactory() + draft.relateddocument_set.create(relationship_id="became_rfc", target=rfc) + url = urlreverse('ietf.doc.views_doc.idnits2_state', kwargs=dict(name=rfc.name)) r = self.client.get(url) self.assertEqual(r.status_code, 200) self.assertContains(r,'rfcnum') draft = WgDraftFactory() - url = urlreverse('ietf.doc.views_doc.idnits2_state', kwargs=dict(name=draft.canonical_name())) + url = urlreverse('ietf.doc.views_doc.idnits2_state', kwargs=dict(name=draft.name)) r = self.client.get(url) self.assertEqual(r.status_code, 200) self.assertNotContains(r,'rfcnum') self.assertContains(r,'Unknown') draft = WgDraftFactory(intended_std_level_id='ps') - url = urlreverse('ietf.doc.views_doc.idnits2_state', kwargs=dict(name=draft.canonical_name())) + url = urlreverse('ietf.doc.views_doc.idnits2_state', kwargs=dict(name=draft.name)) r = self.client.get(url) self.assertEqual(r.status_code, 200) self.assertContains(r,'Proposed') -class RfcdiffSupportTests(TestCase): - - def setUp(self): - super().setUp() - self.target_view = 'ietf.doc.views_doc.rfcdiff_latest_json' - self._last_rfc_num = 8000 - - def getJson(self, view_args): - url = urlreverse(self.target_view, kwargs=view_args) - r = self.client.get(url) - self.assertEqual(r.status_code, 200) - return r.json() - - def next_rfc_number(self): - self._last_rfc_num += 1 - return self._last_rfc_num - - def do_draft_test(self, name): - draft = IndividualDraftFactory(name=name, rev='00', create_revisions=range(0,13)) - draft = reload_db_objects(draft) - - received = self.getJson(dict(name=draft.name)) - self.assertEqual( - received, - dict( - name=draft.name, - rev=draft.rev, - content_url=draft.get_href(), - previous=f'{draft.name}-{(int(draft.rev)-1):02d}' - ), - 'Incorrect JSON when draft revision not specified', - ) - - received = self.getJson(dict(name=draft.name, rev=draft.rev)) - self.assertEqual( - received, - dict( - name=draft.name, - rev=draft.rev, - content_url=draft.get_href(), - previous=f'{draft.name}-{(int(draft.rev)-1):02d}' - ), - 'Incorrect JSON when latest revision specified', - ) - - received = self.getJson(dict(name=draft.name, rev='10')) - self.assertEqual( - received, - dict( - name=draft.name, - rev='10', - content_url=draft.history_set.get(rev='10').get_href(), - previous=f'{draft.name}-09' - ), - 'Incorrect JSON when historical revision specified', - ) - - received = self.getJson(dict(name=draft.name, rev='00')) - self.assertNotIn('previous', received, 'Rev 00 has no previous name when not replacing a draft') - - replaced = IndividualDraftFactory() - RelatedDocument.objects.create(relationship_id='replaces',source=draft,target=replaced.docalias.first()) - received = self.getJson(dict(name=draft.name, rev='00')) - self.assertEqual(received['previous'], f'{replaced.name}-{replaced.rev}', - 'Rev 00 has a previous name when replacing a draft') - - def test_draft(self): - # test with typical, straightforward names - self.do_draft_test(name='draft-somebody-did-a-thing') - # try with different potentially problematic names - self.do_draft_test(name='draft-someone-did-something-01-02') - self.do_draft_test(name='draft-someone-did-something-else-02') - self.do_draft_test(name='draft-someone-did-something-02-weird-01') - - def do_draft_with_broken_history_test(self, name): - draft = IndividualDraftFactory(name=name, rev='10') - received = self.getJson(dict(name=draft.name,rev='09')) - self.assertEqual(received['rev'],'09') - self.assertEqual(received['previous'], f'{draft.name}-08') - self.assertTrue('warning' in received) - - def test_draft_with_broken_history(self): - # test with typical, straightforward names - self.do_draft_with_broken_history_test(name='draft-somebody-did-something') - # try with different potentially problematic names - self.do_draft_with_broken_history_test(name='draft-someone-did-something-01-02') - self.do_draft_with_broken_history_test(name='draft-someone-did-something-else-02') - self.do_draft_with_broken_history_test(name='draft-someone-did-something-02-weird-03') - - def do_rfc_test(self, draft_name): - draft = WgDraftFactory(name=draft_name, create_revisions=range(0,2)) - draft.docalias.create(name=f'rfc{self.next_rfc_number():04}') - draft.set_state(State.objects.get(type_id='draft',slug='rfc')) - draft.set_state(State.objects.get(type_id='draft-iesg', slug='pub')) - draft = reload_db_objects(draft) - rfc = draft - - number = rfc.rfc_number() - received = self.getJson(dict(name=number)) - self.assertEqual( - received, - dict( - content_url=rfc.get_href(), - name=rfc.canonical_name(), - previous=f'{draft.name}-{draft.rev}', - ), - 'Can look up an RFC by number', - ) - - num_received = received - received = self.getJson(dict(name=rfc.canonical_name())) - self.assertEqual(num_received, received, 'RFC by canonical name gives same result as by number') - - received = self.getJson(dict(name=f'RfC {number}')) - self.assertEqual(num_received, received, 'RFC with unusual spacing/caps gives same result as by number') - - received = self.getJson(dict(name=draft.name)) - self.assertEqual(num_received, received, 'RFC by draft name and no rev gives same result as by number') - - received = self.getJson(dict(name=draft.name, rev='01')) - self.assertEqual( - received, - dict( - content_url=draft.history_set.get(rev='01').get_href(), - name=draft.name, - rev='01', - previous=f'{draft.name}-00', - ), - 'RFC by draft name with rev should give draft name, not canonical name' - ) - - def test_rfc(self): - # simple draft name - self.do_rfc_test(draft_name='draft-test-ar-ef-see') - # tricky draft names - self.do_rfc_test(draft_name='draft-whatever-02') - self.do_rfc_test(draft_name='draft-test-me-03-04') - - def test_rfc_with_tombstone(self): - draft = WgDraftFactory(create_revisions=range(0,2)) - draft.docalias.create(name='rfc3261') # See views_doc.HAS_TOMBSTONE - draft.set_state(State.objects.get(type_id='draft',slug='rfc')) - draft.set_state(State.objects.get(type_id='draft-iesg', slug='pub')) - draft = reload_db_objects(draft) - rfc = draft - - # Some old rfcs had tombstones that shouldn't be used for comparisons - received = self.getJson(dict(name=rfc.canonical_name())) - self.assertTrue(received['previous'].endswith('00')) - - def do_rfc_with_broken_history_test(self, draft_name): - draft = WgDraftFactory(rev='10', name=draft_name) - draft.docalias.create(name=f'rfc{self.next_rfc_number():04}') - draft.set_state(State.objects.get(type_id='draft',slug='rfc')) - draft.set_state(State.objects.get(type_id='draft-iesg', slug='pub')) - draft = reload_db_objects(draft) - rfc = draft - - received = self.getJson(dict(name=draft.name)) - self.assertEqual( - received, - dict( - content_url=rfc.get_href(), - name=rfc.canonical_name(), - previous=f'{draft.name}-10', - ), - 'RFC by draft name without rev should return canonical RFC name and no rev', - ) - - received = self.getJson(dict(name=draft.name, rev='10')) - self.assertEqual(received['name'], draft.name, 'RFC by draft name with rev should return draft name') - self.assertEqual(received['rev'], '10', 'Requested rev should be returned') - self.assertEqual(received['previous'], f'{draft.name}-09', 'Previous rev is one less than requested') - self.assertIn(f'{draft.name}-10', received['content_url'], 'Returned URL should include requested rev') - self.assertNotIn('warning', received, 'No warning when we have the rev requested') - - received = self.getJson(dict(name=f'{draft.name}-09')) - self.assertEqual(received['name'], draft.name, 'RFC by draft name with rev should return draft name') - self.assertEqual(received['rev'], '09', 'Requested rev should be returned') - self.assertEqual(received['previous'], f'{draft.name}-08', 'Previous rev is one less than requested') - self.assertIn(f'{draft.name}-09', received['content_url'], 'Returned URL should include requested rev') - self.assertEqual( - received['warning'], - 'History for this version not found - these results are speculation', - 'Warning should be issued when requested rev is not found' - ) - - def test_rfc_with_broken_history(self): - # simple draft name - self.do_rfc_with_broken_history_test(draft_name='draft-some-draft') - # tricky draft names - self.do_rfc_with_broken_history_test(draft_name='draft-gizmo-01') - self.do_rfc_with_broken_history_test(draft_name='draft-oh-boy-what-a-draft-02-03') - class RawIdTests(TestCase): @@ -2853,16 +3113,12 @@ def test_raw_id(self): self.should_succeed(dict(name=draft.name, rev='00',ext='txt')) self.should_404(dict(name=draft.name, rev='00',ext='html')) - def test_raw_id_rfc(self): - rfc = WgRfcFactory() - dir = settings.INTERNET_ALL_DRAFTS_ARCHIVE_DIR - (Path(dir) / f'{rfc.name}-{rfc.rev}.txt').touch() - self.should_succeed(dict(name=rfc.name)) - self.should_404(dict(name=rfc.canonical_name())) + # test_raw_id_rfc intentionally removed + # an rfc is no longer a pseudo-version of a draft. def test_non_draft(self): - charter = CharterFactory() - self.should_404(dict(name=charter.name)) + for doc in [CharterFactory(), WgRfcFactory()]: + self.should_404(dict(name=doc.name)) class PdfizedTests(TestCase): @@ -2874,28 +3130,506 @@ def should_succeed(self, argdict): url = urlreverse(self.view, kwargs=argdict) r = self.client.get(url) self.assertEqual(r.status_code,200) - self.assertEqual(r.get('Content-Type'),'application/pdf;charset=utf-8') + self.assertEqual(r.get('Content-Type'),'application/pdf') def should_404(self, argdict): url = urlreverse(self.view, kwargs=argdict) r = self.client.get(url) self.assertEqual(r.status_code, 404) + # This takes a _long_ time (32s on a 2022 m1 macbook pro) - is it worth what it covers? def test_pdfized(self): - rfc = WgRfcFactory(create_revisions=range(0,2)) + rfc = WgRfcFactory() + draft = WgDraftFactory(create_revisions=range(0,2)) + draft.relateddocument_set.create(relationship_id="became_rfc", target=rfc) dir = settings.RFC_PATH - with (Path(dir) / f'{rfc.canonical_name()}.txt').open('w') as f: + with (Path(dir) / f'{rfc.name}.txt').open('w') as f: f.write('text content') dir = settings.INTERNET_ALL_DRAFTS_ARCHIVE_DIR for r in range(0,2): - with (Path(dir) / f'{rfc.name}-{r:02d}.txt').open('w') as f: + with (Path(dir) / f'{draft.name}-{r:02d}.txt').open('w') as f: f.write('text content') - self.should_succeed(dict(name=rfc.canonical_name())) + self.assertTrue( + login_testing_unauthorized( + self, + PersonFactory().user.username, + urlreverse(self.view, kwargs={"name": draft.name}), + ) + ) self.should_succeed(dict(name=rfc.name)) + self.should_succeed(dict(name=draft.name)) for r in range(0,2): - self.should_succeed(dict(name=rfc.name,rev=f'{r:02d}')) + self.should_succeed(dict(name=draft.name,rev=f'{r:02d}')) for ext in ('pdf','txt','html','anythingatall'): - self.should_succeed(dict(name=rfc.name,rev=f'{r:02d}',ext=ext)) - self.should_404(dict(name=rfc.name,rev='02')) + self.should_succeed(dict(name=draft.name,rev=f'{r:02d}',ext=ext)) + self.should_404(dict(name=draft.name,rev='02')) + + with mock.patch('ietf.doc.models.DocumentInfo.pdfized', side_effect=URLFetchingError): + url = urlreverse(self.view, kwargs=dict(name=rfc.name)) + r = self.client.get(url) + self.assertEqual(r.status_code, 200) + self.assertContains(r, "Error while rendering PDF") + +class NotifyValidationTests(TestCase): + def test_notify_validation(self): + valid_values = [ + "foo@example.com, bar@example.com", + "Foo Bar , baz@example.com", + "foo@example.com, ,bar@example.com,", # We're ignoring extra commas + "foo@example.com\nbar@example.com", # Yes, we're quietly accepting a newline as a comma + ] + bad_nameaddr_values = [ + "@example.com", + "foo", + "foo@", + "foo bar foobar@example.com", + ] + duplicate_values = [ + "foo@bar.com, bar@baz.com, foo@bar.com", + "Foo , foobar ", + ] + both_duplicate_and_bad_values = [ + "foo@example.com, bar@, Foo ", + "Foo <@example.com>, Bar <@example.com>", + ] + for v in valid_values: + self.assertTrue(NotifyForm({"notify": v}).is_valid()) + for v in bad_nameaddr_values: + f = NotifyForm({"notify": v}) + self.assertFalse(f.is_valid()) + self.assertTrue("Invalid addresses" in f.errors["notify"][0]) + self.assertFalse("Duplicate addresses" in f.errors["notify"][0]) + for v in duplicate_values: + f = NotifyForm({"notify": v}) + self.assertFalse(f.is_valid()) + self.assertFalse("Invalid addresses" in f.errors["notify"][0]) + self.assertTrue("Duplicate addresses" in f.errors["notify"][0]) + for v in both_duplicate_and_bad_values: + f = NotifyForm({"notify": v}) + self.assertFalse(f.is_valid()) + self.assertTrue("Invalid addresses" in f.errors["notify"][0]) + self.assertTrue("Duplicate addresses" in f.errors["notify"][0]) + +class CanRequestConflictReviewTests(TestCase): + def test_gets_request_conflict_review_action_button(self): + ise_draft = IndividualDraftFactory(stream_id="ise") + irtf_draft = RgDraftFactory() + + # This is blunt, trading off precision for time. A more thorough test would ensure + # that the text is in a button and that the correct link is absent/present as well. + + target_string = "Begin IETF conflict review" + + url = urlreverse("ietf.doc.views_doc.document_main", kwargs=dict(name=irtf_draft.name)) + r = self.client.get(url) + self.assertNotContains(r, target_string) + self.client.login(username="secretary", password="secretary+password") + r = self.client.get(url) + self.assertContains(r, target_string) + self.client.logout() + self.client.login(username="irtf-chair", password="irtf-chair+password") + r = self.client.get(url) + self.assertContains(r, target_string) + self.client.logout() + self.client.login(username="ise-chair", password="ise-chair+password") + r = self.client.get(url) + self.assertNotContains(r, target_string) + self.client.logout() + + url = urlreverse("ietf.doc.views_doc.document_main", kwargs=dict(name=ise_draft.name)) + r = self.client.get(url) + self.assertNotContains(r, target_string) + self.client.login(username="secretary", password="secretary+password") + r = self.client.get(url) + self.assertContains(r, target_string) + self.client.logout() + self.client.login(username="irtf-chair", password="irtf-chair+password") + r = self.client.get(url) + self.assertNotContains(r, target_string) + self.client.logout() + self.client.login(username="ise-chair", password="ise-chair+password") + r = self.client.get(url) + self.assertContains(r, target_string) + +class DocInfoMethodsTests(TestCase): + + def test_became_rfc(self): + draft = WgDraftFactory() + rfc = WgRfcFactory() + draft.relateddocument_set.create(relationship_id="became_rfc",target=rfc) + self.assertEqual(draft.became_rfc(), rfc) + self.assertEqual(rfc.came_from_draft(), draft) + + charter = CharterFactory() + self.assertIsNone(charter.became_rfc()) + self.assertIsNone(charter.came_from_draft()) + + def test_revisions(self): + draft = WgDraftFactory(rev="09",create_revisions=range(0,10)) + self.assertEqual(draft.revisions_by_dochistory(),[f"{i:02d}" for i in range(0,10)]) + self.assertEqual(draft.revisions_by_newrevisionevent(),[f"{i:02d}" for i in range(0,10)]) + rfc = WgRfcFactory() + self.assertEqual(rfc.revisions_by_newrevisionevent(),[]) + self.assertEqual(rfc.revisions_by_dochistory(),[]) + + draft.history_set.filter(rev__lt="08").delete() + draft.docevent_set.filter(newrevisiondocevent__rev="05").delete() + self.assertEqual(draft.revisions_by_dochistory(),[f"{i:02d}" for i in range(8,10)]) + self.assertEqual(draft.revisions_by_newrevisionevent(),[f"{i:02d}" for i in [*range(0,5), *range(6,10)]]) + + def test_referenced_by_rfcs(self): + # n.b., no significance to the ref* values in this test + referring_draft = WgDraftFactory() + (rfc, referring_rfc) = WgRfcFactory.create_batch(2) + rfc.targets_related.create(relationship_id="refnorm", source=referring_draft) + rfc.targets_related.create(relationship_id="refnorm", source=referring_rfc) + self.assertCountEqual( + rfc.referenced_by_rfcs(), + rfc.targets_related.filter(source=referring_rfc), + ) + + def test_referenced_by_rfcs_as_rfc_or_draft(self): + # n.b., no significance to the ref* values in this test + draft = WgDraftFactory() + rfc = WgRfcFactory() + draft.relateddocument_set.create(relationship_id="became_rfc", target=rfc) + + # Draft referring to the rfc and the draft - should not be reported at all + draft_referring_to_both = WgDraftFactory() + draft_referring_to_both.relateddocument_set.create(relationship_id="refnorm", target=draft) + draft_referring_to_both.relateddocument_set.create(relationship_id="refnorm", target=rfc) + + # RFC referring only to the draft - should be reported for either the draft or the rfc + rfc_referring_to_draft = WgRfcFactory() + rfc_referring_to_draft.relateddocument_set.create(relationship_id="refinfo", target=draft) + + # RFC referring only to the rfc - should be reported only for the rfc + rfc_referring_to_rfc = WgRfcFactory() + rfc_referring_to_rfc.relateddocument_set.create(relationship_id="refinfo", target=rfc) + + # RFC referring only to the rfc - should be reported only for the rfc + rfc_referring_to_rfc = WgRfcFactory() + rfc_referring_to_rfc.relateddocument_set.create(relationship_id="refinfo", target=rfc) + + # RFC referring to the rfc and the draft - should be reported for both + rfc_referring_to_both = WgRfcFactory() + rfc_referring_to_both.relateddocument_set.create(relationship_id="refnorm", target=draft) + rfc_referring_to_both.relateddocument_set.create(relationship_id="refnorm", target=rfc) + + self.assertCountEqual( + draft.referenced_by_rfcs_as_rfc_or_draft(), + draft.targets_related.filter(source__type="rfc"), + ) + + self.assertCountEqual( + rfc.referenced_by_rfcs_as_rfc_or_draft(), + draft.targets_related.filter(source__type="rfc") | rfc.targets_related.filter(source__type="rfc"), + ) + +class StateIndexTests(TestCase): + + def test_state_index(self): + url = urlreverse('ietf.doc.views_help.state_index') + r = self.client.get(url) + q = PyQuery(r.content) + content = [ e.text for e in q('#content table td a ') ] + names = StateType.objects.values_list('slug', flat=True) + # The following doesn't cover all doc types, only a selection + for name in names: + if not '-' in name: + self.assertIn(name, content) + +class InvestigateTests(TestCase): + settings_temp_path_overrides = TestCase.settings_temp_path_overrides + [ + "AGENDA_PATH", + # "INTERNET_DRAFT_PATH", + # "INTERNET_DRAFT_ARCHIVE_DIR", + # "INTERNET_ALL_DRAFTS_ARCHIVE_DIR", + ] + + def setUp(self): + super().setUp() + # Contort the draft archive dir temporary replacement + # to match the "collections" concept + archive_tmp_dir = Path(settings.INTERNET_DRAFT_ARCHIVE_DIR) + new_archive_dir = archive_tmp_dir / "draft-archive" + new_archive_dir.mkdir() + settings.INTERNET_DRAFT_ARCHIVE_DIR = str(new_archive_dir) + donated_personal_copy_dir = archive_tmp_dir / "donated-personal-copy" + donated_personal_copy_dir.mkdir() + meeting_dir = Path(settings.AGENDA_PATH) / "666" + meeting_dir.mkdir() + all_archive_dir = Path(settings.INTERNET_ALL_DRAFTS_ARCHIVE_DIR) + repository_dir = Path(settings.INTERNET_DRAFT_PATH) + + for path in [repository_dir, all_archive_dir]: + (path / "draft-this-is-active-00.txt").touch() + for path in [new_archive_dir, all_archive_dir]: + (path / "draft-old-but-can-authenticate-00.txt").touch() + (path / "draft-has-mixed-provenance-01.txt").touch() + for path in [donated_personal_copy_dir, all_archive_dir]: + (path / "draft-donated-from-a-personal-collection-00.txt").touch() + (path / "draft-has-mixed-provenance-00.txt").touch() + (path / "draft-has-mixed-provenance-00.txt.Z").touch() + (all_archive_dir / "draft-this-should-not-be-possible-00.txt").touch() + (meeting_dir / "draft-this-predates-the-archive-00.txt").touch() + + def test_investigate_fragment(self): + + result = investigate_fragment("this-is-active") + self.assertEqual(len(result["can_verify"]), 1) + self.assertEqual(len(result["unverifiable_collections"]), 0) + self.assertEqual(len(result["unexpected"]), 0) + self.assertEqual( + list(result["can_verify"])[0].name, "draft-this-is-active-00.txt" + ) + + result = investigate_fragment("old-but-can") + self.assertEqual(len(result["can_verify"]), 1) + self.assertEqual(len(result["unverifiable_collections"]), 0) + self.assertEqual(len(result["unexpected"]), 0) + self.assertEqual( + list(result["can_verify"])[0].name, "draft-old-but-can-authenticate-00.txt" + ) + + result = investigate_fragment("predates") + self.assertEqual(len(result["can_verify"]), 1) + self.assertEqual(len(result["unverifiable_collections"]), 0) + self.assertEqual(len(result["unexpected"]), 0) + self.assertEqual( + list(result["can_verify"])[0].name, "draft-this-predates-the-archive-00.txt" + ) + + result = investigate_fragment("personal-collection") + self.assertEqual(len(result["can_verify"]), 0) + self.assertEqual(len(result["unverifiable_collections"]), 1) + self.assertEqual(len(result["unexpected"]), 0) + self.assertEqual( + list(result["unverifiable_collections"])[0].name, + "draft-donated-from-a-personal-collection-00.txt", + ) + + result = investigate_fragment("mixed-provenance") + self.assertEqual(len(result["can_verify"]), 1) + self.assertEqual(len(result["unverifiable_collections"]), 2) + self.assertEqual(len(result["unexpected"]), 0) + self.assertEqual( + list(result["can_verify"])[0].name, "draft-has-mixed-provenance-01.txt" + ) + self.assertEqual( + set([p.name for p in result["unverifiable_collections"]]), + set( + [ + "draft-has-mixed-provenance-00.txt", + "draft-has-mixed-provenance-00.txt.Z", + ] + ), + ) + + result = investigate_fragment("not-be-possible") + self.assertEqual(len(result["can_verify"]), 0) + self.assertEqual(len(result["unverifiable_collections"]), 0) + self.assertEqual(len(result["unexpected"]), 1) + self.assertEqual( + list(result["unexpected"])[0].name, + "draft-this-should-not-be-possible-00.txt", + ) + + @mock.patch("ietf.doc.utils.caches") + def test_investigate_fragment_cache(self, mock_caches): + """investigate_fragment should cache its result""" + mock_default_cache = mock_caches["default"] + mock_default_cache.get.return_value = None # disable cache + result = investigate_fragment("this-is-active") + self.assertEqual(len(result["can_verify"]), 1) + self.assertEqual(len(result["unverifiable_collections"]), 0) + self.assertEqual(len(result["unexpected"]), 0) + self.assertEqual( + list(result["can_verify"])[0].name, "draft-this-is-active-00.txt" + ) + self.assertTrue(mock_default_cache.get.called) + self.assertTrue(mock_default_cache.set.called) + expected_key = f"investigate_fragment:{sha384(b'this-is-active').hexdigest()}" + self.assertEqual(mock_default_cache.set.call_args.kwargs["key"], expected_key) + cached_value = mock_default_cache.set.call_args.kwargs["value"] # hang on to this + mock_default_cache.reset_mock() + + # Check that a cached value is used + mock_default_cache.get.return_value = cached_value + with mock.patch("ietf.doc.utils.Path") as mock_path: + result = investigate_fragment("this-is-active") + # Check that we got the same results + self.assertEqual(len(result["can_verify"]), 1) + self.assertEqual(len(result["unverifiable_collections"]), 0) + self.assertEqual(len(result["unexpected"]), 0) + self.assertEqual( + list(result["can_verify"])[0].name, "draft-this-is-active-00.txt" + ) + # And that we used the cache + self.assertFalse(mock_path.called) # a proxy for "did the method do any real work" + self.assertTrue(mock_default_cache.get.called) + self.assertEqual(mock_default_cache.get.call_args, mock.call(expected_key)) + + def test_investigate_get(self): + """GET with no querystring should retrieve the investigate UI""" + url = urlreverse("ietf.doc.views_doc.investigate") + login_testing_unauthorized(self, "secretary", url) + r = self.client.get(url) + self.assertEqual(r.status_code, 200) + q = PyQuery(r.content) + self.assertEqual(len(q("form#investigate")), 1) + self.assertEqual(len(q("div#results")), 0) + + @mock.patch("ietf.doc.views_doc.AsyncResult") + def test_investgate_get_task_id(self, mock_asyncresult): + """GET with querystring should lookup task status""" + url = urlreverse("ietf.doc.views_doc.investigate") + login_testing_unauthorized(self, "secretary", url) + mock_asyncresult.return_value.ready.return_value = True + r = self.client.get(url + "?id=a-task-id") + self.assertEqual(r.status_code, 200) + self.assertEqual(r.json(), {"status": "ready"}) + self.assertTrue(mock_asyncresult.called) + self.assertEqual(mock_asyncresult.call_args, mock.call("a-task-id")) + mock_asyncresult.reset_mock() + + mock_asyncresult.return_value.ready.return_value = False + r = self.client.get(url + "?id=a-task-id") + self.assertEqual(r.status_code, 200) + self.assertEqual(r.json(), {"status": "notready"}) + self.assertTrue(mock_asyncresult.called) + self.assertEqual(mock_asyncresult.call_args, mock.call("a-task-id")) + + @mock.patch("ietf.doc.views_doc.investigate_fragment_task") + def test_investigate_post(self, mock_investigate_fragment_task): + """POST with a name_fragment and no task_id should start a celery task""" + url = urlreverse("ietf.doc.views_doc.investigate") + login_testing_unauthorized(self, "secretary", url) + + # test some invalid cases + r = self.client.post(url, {"name_fragment": "short"}) # limit is >= 8 characters + self.assertEqual(r.status_code, 200) + q = PyQuery(r.content) + self.assertEqual(len(q("#id_name_fragment.is-invalid")), 1) + self.assertFalse(mock_investigate_fragment_task.delay.called) + for char in ["*", "%", "/", "\\"]: + r = self.client.post(url, {"name_fragment": f"bad{char}character"}) + self.assertEqual(r.status_code, 200) + q = PyQuery(r.content) + self.assertEqual(len(q("#id_name_fragment.is-invalid")), 1) + self.assertFalse(mock_investigate_fragment_task.delay.called) + + # now a valid one + mock_investigate_fragment_task.delay.return_value.id = "a-task-id" + r = self.client.post(url, {"name_fragment": "this-is-a-valid-fragment"}) + self.assertEqual(r.status_code, 200) + self.assertTrue(mock_investigate_fragment_task.delay.called) + self.assertEqual(mock_investigate_fragment_task.delay.call_args, mock.call("this-is-a-valid-fragment")) + self.assertEqual(r.json(), {"id": "a-task-id"}) + + @mock.patch("ietf.doc.views_doc.AsyncResult") + def test_investigate_post_task_id(self, mock_asyncresult): + """POST with name_fragment and task_id should retrieve results""" + url = urlreverse("ietf.doc.views_doc.investigate") + login_testing_unauthorized(self, "secretary", url) + + # First, test a non-successful result - this could be a failure or non-existent task id + mock_result = mock_asyncresult.return_value + mock_result.successful.return_value = False + r = self.client.post(url, {"name_fragment": "some-fragment", "task_id": "a-task-id"}) + self.assertContains(r, "The investigation task failed.", status_code=200) + self.assertTrue(mock_asyncresult.called) + self.assertEqual(mock_asyncresult.call_args, mock.call("a-task-id")) + self.assertFalse(mock_result.get.called) + mock_asyncresult.reset_mock() + q = PyQuery(r.content) + self.assertEqual(q("#id_name_fragment").val(), "some-fragment") + self.assertEqual(q("#id_task_id").val(), "a-task-id") + + # now the various successful result mixes + mock_result = mock_asyncresult.return_value + mock_result.successful.return_value = True + mock_result.get.return_value = { + "name_fragment": "different-fragment", + "results": { + "can_verify": set(), + "unverifiable_collections": set(), + "unexpected": set(), + } + } + r = self.client.post(url, {"name_fragment": "some-fragment", "task_id": "a-task-id"}) + self.assertEqual(r.status_code, 200) + self.assertTrue(mock_asyncresult.called) + self.assertEqual(mock_asyncresult.call_args, mock.call("a-task-id")) + mock_asyncresult.reset_mock() + q = PyQuery(r.content) + self.assertEqual(q("#id_name_fragment").val(), "different-fragment", "name_fragment should be reset") + self.assertEqual(q("#id_task_id").val(), "", "task_id should be cleared") + self.assertEqual(len(q("div#results")), 1) + self.assertEqual(len(q("table#authenticated")), 0) + self.assertEqual(len(q("table#unverifiable")), 0) + self.assertEqual(len(q("table#unexpected")), 0) + + # This file was created in setUp. It allows the view to render properly + # but its location / content don't matter for this test otherwise. + a_file_that_exists = Path(settings.INTERNET_DRAFT_PATH) / "draft-this-is-active-00.txt" + + mock_result.get.return_value = { + "name_fragment": "different-fragment", + "results": { + "can_verify": {a_file_that_exists}, + "unverifiable_collections": {a_file_that_exists}, + "unexpected": set(), + } + } + r = self.client.post(url, {"name_fragment": "some-fragment", "task_id": "a-task-id"}) + self.assertEqual(r.status_code, 200) + self.assertTrue(mock_asyncresult.called) + self.assertEqual(mock_asyncresult.call_args, mock.call("a-task-id")) + mock_asyncresult.reset_mock() + q = PyQuery(r.content) + self.assertEqual(q("#id_name_fragment").val(), "different-fragment", "name_fragment should be reset") + self.assertEqual(q("#id_task_id").val(), "", "task_id should be cleared") + self.assertEqual(len(q("div#results")), 1) + self.assertEqual(len(q("table#authenticated")), 1) + self.assertEqual(len(q("table#unverifiable")), 1) + self.assertEqual(len(q("table#unexpected")), 0) + + mock_result.get.return_value = { + "name_fragment": "different-fragment", + "results": { + "can_verify": set(), + "unverifiable_collections": set(), + "unexpected": {a_file_that_exists}, + } + } + r = self.client.post(url, {"name_fragment": "some-fragment", "task_id": "a-task-id"}) + self.assertEqual(r.status_code, 200) + self.assertTrue(mock_asyncresult.called) + self.assertEqual(mock_asyncresult.call_args, mock.call("a-task-id")) + mock_asyncresult.reset_mock() + q = PyQuery(r.content) + self.assertEqual(q("#id_name_fragment").val(), "different-fragment", "name_fragment should be reset") + self.assertEqual(q("#id_task_id").val(), "", "task_id should be cleared") + self.assertEqual(len(q("div#results")), 1) + self.assertEqual(len(q("table#authenticated")), 0) + self.assertEqual(len(q("table#unverifiable")), 0) + self.assertEqual(len(q("table#unexpected")), 1) + + +class LogIOErrorTests(TestCase): + + def test_doc_text_io_error(self): + + d = IndividualDraftFactory() + + with mock.patch("ietf.doc.models.Path") as path_cls_mock: + with mock.patch("ietf.doc.models.log.log") as log_mock: + path_cls_mock.return_value.exists.return_value = True + path_cls_mock.return_value.open.return_value.__enter__.return_value.read.side_effect = IOError("Bad things happened") + text = d.text() + self.assertIsNone(text) + self.assertTrue(log_mock.called) + self.assertIn("Bad things happened", log_mock.call_args[0][0]) diff --git a/ietf/doc/tests_ballot.py b/ietf/doc/tests_ballot.py index 317e4e3a1d0..517a2ce0563 100644 --- a/ietf/doc/tests_ballot.py +++ b/ietf/doc/tests_ballot.py @@ -3,7 +3,6 @@ import datetime -import mock from pyquery import PyQuery @@ -12,30 +11,42 @@ from django.test import RequestFactory from django.utils.text import slugify from django.urls import reverse as urlreverse +from django.utils import timezone from ietf.doc.models import (Document, State, DocEvent, BallotPositionDocEvent, LastCallDocEvent, WriteupDocEvent, TelechatDocEvent) from ietf.doc.factories import (DocumentFactory, IndividualDraftFactory, IndividualRfcFactory, WgDraftFactory, - BallotPositionDocEventFactory, BallotDocEventFactory) + BallotPositionDocEventFactory, BallotDocEventFactory, IRSGBallotDocEventFactory, RgDraftFactory) +from ietf.doc.templatetags.ietf_filters import can_defer from ietf.doc.utils import create_ballot_if_not_open +from ietf.doc.views_ballot import parse_ballot_edit_return_point from ietf.doc.views_doc import document_ballot_content from ietf.group.models import Group, Role from ietf.group.factories import GroupFactory, RoleFactory, ReviewTeamFactory from ietf.ipr.factories import HolderIprDisclosureFactory -from ietf.name.models import BallotPositionName from ietf.iesg.models import TelechatDate -from ietf.person.models import Person, PersonalApiKey -from ietf.person.factories import PersonFactory +from ietf.person.models import Person +from ietf.person.factories import PersonFactory, PersonalApiKeyFactory from ietf.person.utils import get_active_ads from ietf.utils.test_utils import TestCase, login_testing_unauthorized from ietf.utils.mail import outbox, empty_outbox, get_payload_text from ietf.utils.text import unwrap +from ietf.utils.timezone import date_today, datetime_today class EditPositionTests(TestCase): + + # N.B. This test needs to be rewritten to exercise all types of ballots (iesg, irsg, rsab) + # and test against the output of the mailtriggers instead of looking for hardcoded values + # in the To and CC results. See #7864 def test_edit_position(self): ad = Person.objects.get(user__username="ad") - draft = IndividualDraftFactory(ad=ad,stream_id='ietf') + draft = WgDraftFactory( + ad=ad, + stream_id="ietf", + notify="somebody@example.com", + group__acronym="mars", + ) ballot = create_ballot_if_not_open(None, draft, ad, 'approve') url = urlreverse('ietf.doc.views_ballot.edit_position', kwargs=dict(name=draft.name, ballot_id=ballot.pk)) @@ -51,11 +62,20 @@ def test_edit_position(self): self.assertEqual(len(q('form textarea[name=comment]')), 1) # vote + empty_outbox() events_before = draft.docevent_set.count() - - r = self.client.post(url, dict(position="discuss", - discuss=" This is a discussion test. \n ", - comment=" This is a test. \n ")) + + r = self.client.post( + url, + dict( + position="discuss", + discuss=" This is a discussion test. \n ", + comment=" This is a test. \n ", + additional_cc="test298347@example.com", + cc_choices=["doc_notify", "doc_group_chairs"], + send_mail=1, + ), + ) self.assertEqual(r.status_code, 302) pos = draft.latest_event(BallotPositionDocEvent, balloter=ad) @@ -66,6 +86,22 @@ def test_edit_position(self): self.assertTrue(pos.comment_time != None) self.assertTrue("New position" in pos.desc) self.assertEqual(draft.docevent_set.count(), events_before + 3) + self.assertEqual(len(outbox),1) + m = outbox[0] + self.assertTrue("COMMENT" in m['Subject']) + self.assertTrue("DISCUSS" in m['Subject']) + self.assertTrue(draft.name in m['Subject']) + self.assertTrue("This is a discussion test." in str(m)) + self.assertTrue("This is a test" in str(m)) + self.assertTrue("iesg@" in m['To']) + # cc_choice doc_group_chairs + self.assertTrue("mars-chairs@" in m['Cc']) + # cc_choice doc_notify + self.assertTrue("somebody@example.com" in m['Cc']) + # cc_choice doc_group_email_list was not selected + self.assertFalse(draft.group.list_email in m['Cc']) + # extra-cc + self.assertTrue("test298347@example.com" in m['Cc']) # recast vote events_before = draft.docevent_set.count() @@ -105,9 +141,9 @@ def test_api_set_position(self): draft = WgDraftFactory(ad=ad) url = urlreverse('ietf.doc.views_ballot.api_set_position') create_ballot_if_not_open(None, draft, ad, 'approve') - ad.user.last_login = datetime.datetime.now() + ad.user.last_login = timezone.now() ad.user.save() - apikey = PersonalApiKey.objects.create(endpoint=url, person=ad) + apikey = PersonalApiKeyFactory(endpoint=url, person=ad) # vote events_before = draft.docevent_set.count() @@ -226,61 +262,6 @@ def test_cannot_edit_position_as_pre_ad(self): r = self.client.post(url, dict(position="discuss", discuss="Test discuss text")) self.assertEqual(r.status_code, 403) - def test_send_ballot_comment(self): - ad = Person.objects.get(user__username="ad") - draft = WgDraftFactory(ad=ad,group__acronym='mars') - draft.notify = "somebody@example.com" - draft.save_with_history([DocEvent.objects.create(doc=draft, rev=draft.rev, type="changed_document", by=Person.objects.get(user__username="secretary"), desc="Test")]) - - ballot = create_ballot_if_not_open(None, draft, ad, 'approve') - - BallotPositionDocEvent.objects.create( - doc=draft, rev=draft.rev, type="changed_ballot_position", - by=ad, balloter=ad, ballot=ballot, pos=BallotPositionName.objects.get(slug="discuss"), - discuss="This draft seems to be lacking a clearer title?", - discuss_time=datetime.datetime.now(), - comment="Test!", - comment_time=datetime.datetime.now()) - - url = urlreverse('ietf.doc.views_ballot.send_ballot_comment', kwargs=dict(name=draft.name, - ballot_id=ballot.pk)) - login_testing_unauthorized(self, "ad", url) - - # normal get - r = self.client.get(url) - self.assertEqual(r.status_code, 200) - q = PyQuery(r.content) - self.assertTrue(len(q('form input[name="extra_cc"]')) > 0) - - # send - mailbox_before = len(outbox) - - r = self.client.post(url, dict(extra_cc="test298347@example.com", cc_choices=['doc_notify','doc_group_chairs'])) - self.assertEqual(r.status_code, 302) - - self.assertEqual(len(outbox), mailbox_before + 1) - m = outbox[-1] - self.assertTrue("COMMENT" in m['Subject']) - self.assertTrue("DISCUSS" in m['Subject']) - self.assertTrue(draft.name in m['Subject']) - self.assertTrue("clearer title" in str(m)) - self.assertTrue("Test!" in str(m)) - self.assertTrue("iesg@" in m['To']) - # cc_choice doc_group_chairs - self.assertTrue("mars-chairs@" in m['Cc']) - # cc_choice doc_notify - self.assertTrue("somebody@example.com" in m['Cc']) - # cc_choice doc_group_email_list was not selected - self.assertFalse(draft.group.list_email in m['Cc']) - # extra-cc - self.assertTrue("test298347@example.com" in m['Cc']) - - r = self.client.post(url, dict(cc="")) - self.assertEqual(r.status_code, 302) - self.assertEqual(len(outbox), mailbox_before + 2) - m = outbox[-1] - self.assertTrue("iesg@" in m['To']) - self.assertFalse(m['Cc'] and draft.group.list_email in m['Cc']) class BallotWriteupsTests(TestCase): @@ -353,7 +334,7 @@ def test_request_last_call(self): self.assertTrue('aread@' in outbox[-1]['Cc']) def test_edit_ballot_writeup(self): - draft = IndividualDraftFactory(states=[('draft','active'),('draft-iesg','iesg-eva')]) + draft = IndividualDraftFactory(states=[('draft','active'),('draft-iesg','iesg-eva')], stream_id='ietf') url = urlreverse('ietf.doc.views_ballot.ballot_writeupnotes', kwargs=dict(name=draft.name)) login_testing_unauthorized(self, "secretary", url) @@ -383,8 +364,25 @@ def test_edit_ballot_writeup(self): self.assertTrue("This is a simple test" in d.latest_event(WriteupDocEvent, type="changed_ballot_writeup_text").text) self.assertTrue('iesg-eva' == d.get_state_slug('draft-iesg')) + def test_edit_ballot_writeup_unauthorized_stream(self): + # Test that accessing a document from unauthorized (irtf) stream returns a 404 error + draft = RgDraftFactory() + url = urlreverse('ietf.doc.views_ballot.ballot_writeupnotes', kwargs=dict(name=draft.name)) + login_testing_unauthorized(self, "ad", url) + + r = self.client.get(url) + self.assertEqual(r.status_code, 404) + + def test_edit_ballot_writeup_invalid_name(self): + # Test that accessing a non-existent document returns a 404 error + url = urlreverse('ietf.doc.views_ballot.ballot_writeupnotes', kwargs=dict(name="invalid_name")) + login_testing_unauthorized(self, "ad", url) + + r = self.client.get(url) + self.assertEqual(r.status_code, 404) + def test_edit_ballot_writeup_already_approved(self): - draft = IndividualDraftFactory(states=[('draft','active'),('draft-iesg','approved')]) + draft = IndividualDraftFactory(states=[('draft','active'),('draft-iesg','approved')], stream_id='ietf') url = urlreverse('ietf.doc.views_ballot.ballot_writeupnotes', kwargs=dict(name=draft.name)) login_testing_unauthorized(self, "secretary", url) @@ -458,7 +456,7 @@ def test_edit_ballot_rfceditornote(self): def test_issue_ballot(self): ad = Person.objects.get(user__username="ad") for case in ('none','past','future'): - draft = IndividualDraftFactory(ad=ad) + draft = IndividualDraftFactory(ad=ad, stream_id='ietf') if case in ('past','future'): LastCallDocEvent.objects.create( by=Person.objects.get(name='(System)'), @@ -466,7 +464,7 @@ def test_issue_ballot(self): doc=draft, rev=draft.rev, desc='issued last call', - expires = datetime.datetime.now()+datetime.timedelta(days = 1 if case=='future' else -1) + expires = timezone.now()+datetime.timedelta(days = 1 if case=='future' else -1) ) url = urlreverse('ietf.doc.views_ballot.ballot_writeupnotes', kwargs=dict(name=draft.name)) login_testing_unauthorized(self, "ad", url) @@ -497,7 +495,7 @@ def test_issue_ballot(self): def test_issue_ballot_auto_state_change(self): ad = Person.objects.get(user__username="ad") - draft = IndividualDraftFactory(ad=ad, states=[('draft','active'),('draft-iesg','writeupw')]) + draft = IndividualDraftFactory(ad=ad, states=[('draft','active'),('draft-iesg','writeupw')], stream_id='ietf') url = urlreverse('ietf.doc.views_ballot.ballot_writeupnotes', kwargs=dict(name=draft.name)) login_testing_unauthorized(self, "secretary", url) @@ -521,11 +519,12 @@ def test_issue_ballot_auto_state_change(self): def test_issue_ballot_warn_if_early(self): ad = Person.objects.get(user__username="ad") - draft = IndividualDraftFactory(ad=ad, states=[('draft','active'),('draft-iesg','lc')]) + draft = IndividualDraftFactory(ad=ad, states=[('draft','active'),('draft-iesg','lc')], stream_id='ietf') url = urlreverse('ietf.doc.views_ballot.ballot_writeupnotes', kwargs=dict(name=draft.name)) login_testing_unauthorized(self, "secretary", url) # expect warning about issuing a ballot before IETF Last Call is done + # No last call has yet been issued r = self.client.get(url) self.assertEqual(r.status_code, 200) q = PyQuery(r.content) @@ -533,6 +532,38 @@ def test_issue_ballot_warn_if_early(self): self.assertTrue(q('[class=text-danger]:contains("not completed IETF Last Call")')) self.assertTrue(q('[type=submit]:contains("Save")')) + # Last call exists but hasn't expired + LastCallDocEvent.objects.create( + doc=draft, + expires=datetime_today()+datetime.timedelta(days=14), + by=Person.objects.get(name="(System)") + ) + r = self.client.get(url) + self.assertEqual(r.status_code, 200) + q = PyQuery(r.content) + self.assertTrue(q('[class=text-danger]:contains("not completed IETF Last Call")')) + + # Last call exists and has expired + LastCallDocEvent.objects.filter(doc=draft).update(expires=datetime_today()-datetime.timedelta(days=2)) + r = self.client.get(url) + self.assertEqual(r.status_code, 200) + q = PyQuery(r.content) + self.assertFalse(q('[class=text-danger]:contains("not completed IETF Last Call")')) + + for state_slug in ["lc", "ad-eval"]: + draft.set_state(State.objects.get(type="draft-iesg",slug=state_slug)) + r = self.client.get(url) + self.assertEqual(r.status_code, 200) + q = PyQuery(r.content) + self.assertTrue(q('[class=text-danger]:contains("It would be unexpected to issue a ballot while in this state.")')) + + draft.set_state(State.objects.get(type="draft-iesg",slug="writeupw")) + r = self.client.get(url) + self.assertEqual(r.status_code, 200) + q = PyQuery(r.content) + self.assertFalse(q('[class=text-danger]:contains("It would be unexpected to issue a ballot while in this state.")')) + + def test_edit_approval_text(self): ad = Person.objects.get(user__username="ad") draft = WgDraftFactory(ad=ad,states=[('draft','active'),('draft-iesg','iesg-eva')],intended_std_level_id='ps',group__parent=Group.objects.get(acronym='farfut')) @@ -684,11 +715,8 @@ def verify_can_see(username, url): verify_can_see(username, url) class ApproveBallotTests(TestCase): - @mock.patch('ietf.sync.rfceditor.requests.post', autospec=True) - def test_approve_ballot(self, mock_urlopen): - mock_urlopen.return_value.text = b'OK' - mock_urlopen.return_value.status_code = 200 - # + def test_approve_ballot(self): + ad = Person.objects.get(name="Areað Irector") draft = IndividualDraftFactory(ad=ad, intended_std_level_id='ps') draft.set_state(State.objects.get(used=True, type="draft-iesg", slug="iesg-eva")) # make sure it's approvable @@ -770,7 +798,7 @@ def test_clear_ballot(self): ballot = create_ballot_if_not_open(None, draft, ad, 'approve') old_ballot_id = ballot.id draft.set_state(State.objects.get(used=True, type="draft-iesg", slug="iesg-eva")) - url = urlreverse('ietf.doc.views_ballot.clear_ballot', kwargs=dict(name=draft.name,ballot_type_slug=draft.ballot_open('approve').ballot_type.slug)) + url = urlreverse('ietf.doc.views_ballot.clear_ballot', kwargs=dict(name=draft.name,ballot_type_slug="approve")) login_testing_unauthorized(self, "secretary", url) r = self.client.get(url) self.assertEqual(r.status_code, 200) @@ -780,6 +808,11 @@ def test_clear_ballot(self): self.assertIsNotNone(ballot) self.assertEqual(ballot.ballotpositiondocevent_set.count(),0) self.assertNotEqual(old_ballot_id, ballot.id) + # It's not valid to clear a ballot of a type where there's no matching state + url = urlreverse('ietf.doc.views_ballot.clear_ballot', kwargs=dict(name=draft.name,ballot_type_slug="statchg")) + r = self.client.post(url,{}) + self.assertEqual(r.status_code, 404) + def test_ballot_downref_approve(self): ad = Person.objects.get(name="Areað Irector") @@ -791,7 +824,7 @@ def test_ballot_downref_approve(self): doc=draft, rev=draft.rev, desc='issued last call', - expires = datetime.datetime.now()-datetime.timedelta(days=14) ) + expires = timezone.now()-datetime.timedelta(days=14) ) WriteupDocEvent.objects.create( by=Person.objects.get(name='(System)'), doc=draft, @@ -800,8 +833,8 @@ def test_ballot_downref_approve(self): desc='Last call announcement was changed', text='this is simple last call text.' ) rfc = IndividualRfcFactory.create( + name = "rfc6666", stream_id='ise', - other_aliases=['rfc6666',], states=[('draft','rfc'),('draft-iesg','pub')], std_level_id='inf', ) @@ -818,7 +851,7 @@ def test_ballot_downref_approve(self): self.assertContains(r, "No downward references for") # Add a downref, the page should ask if it should be added to the registry - rel = draft.relateddocument_set.create(target=rfc.docalias.get(name='rfc6666'),relationship_id='refnorm') + rel = draft.relateddocument_set.create(target=rfc, relationship_id='refnorm') d = [rdoc for rdoc in draft.relateddocument_set.all() if rel.is_approved_downref()] original_len = len(d) r = self.client.get(url) @@ -898,7 +931,7 @@ def test_make_last_call_yang_document(self): mailbox_before = len(outbox) - last_call_sent_date = datetime.date.today() + last_call_sent_date = date_today() expire_date = last_call_sent_date+datetime.timedelta(days=14) r = self.client.post(url, @@ -1067,6 +1100,35 @@ def setUp(self): DocumentFactory(type_id='statchg',name='status-change-imaginary-mid-review',states=[('statchg','iesgeval')]) DocumentFactory(type_id='conflrev',name='conflict-review-imaginary-irtf-submission',states=[('conflrev','iesgeval')]) +class IetfFiltersTests(TestCase): + def test_can_defer(self): + secretariat = Person.objects.get(user__username="secretary").user + ad = Person.objects.get(user__username="ad").user + irtf_chair = Person.objects.get(user__username="irtf-chair").user + rsab_chair = Person.objects.get(user__username="rsab-chair").user + irsg_member = RoleFactory(group__type_id="rg", name_id="chair").person.user + rsab_member = RoleFactory(group=Group.objects.get(acronym="rsab"), name_id="member").person.user + nobody = PersonFactory().user + + users = set([secretariat, ad, irtf_chair, rsab_chair, irsg_member, rsab_member, nobody]) + + iesg_ballot = BallotDocEventFactory(doc__stream_id='ietf') + self.assertTrue(can_defer(secretariat, iesg_ballot.doc)) + self.assertTrue(can_defer(ad, iesg_ballot.doc)) + for user in users - set([secretariat, ad]): + self.assertFalse(can_defer(user, iesg_ballot.doc)) + + irsg_ballot = IRSGBallotDocEventFactory(doc__stream_id='irtf') + for user in users: + self.assertFalse(can_defer(user, irsg_ballot.doc)) + + rsab_ballot = BallotDocEventFactory(ballot_type__slug='rsab-approve', doc__stream_id='editorial') + for user in users: + self.assertFalse(can_defer(user, rsab_ballot.doc)) + + def test_can_clear_ballot(self): + pass # Right now, can_clear_ballot is implemented by can_defer + class RegenerateLastCallTestCase(TestCase): def test_regenerate_last_call(self): @@ -1089,13 +1151,13 @@ def test_regenerate_last_call(self): self.assertFalse("contains these normative down" in lc_text) rfc = IndividualRfcFactory.create( + rfc_number=6666, stream_id='ise', - other_aliases=['rfc6666',], states=[('draft','rfc'),('draft-iesg','pub')], std_level_id='inf', ) - draft.relateddocument_set.create(target=rfc.docalias.get(name='rfc6666'),relationship_id='refnorm') + draft.relateddocument_set.create(target=rfc,relationship_id='refnorm') r = self.client.post(url, dict(regenerate_last_call_text="1")) self.assertEqual(r.status_code, 200) @@ -1105,7 +1167,7 @@ def test_regenerate_last_call(self): self.assertTrue("rfc6666" in lc_text) self.assertTrue("Independent Submission" in lc_text) - draft.relateddocument_set.create(target=rfc.docalias.get(name='rfc6666'), relationship_id='downref-approval') + draft.relateddocument_set.create(target=rfc, relationship_id='downref-approval') r = self.client.post(url, dict(regenerate_last_call_text="1")) self.assertEqual(r.status_code, 200) @@ -1117,7 +1179,7 @@ def test_regenerate_last_call(self): class BallotContentTests(TestCase): def test_ballotpositiondocevent_any_email_sent(self): - now = datetime.datetime.now() # be sure event timestamps are at distinct times + now = timezone.now() # be sure event timestamps are at distinct times bpde_with_null_send_email = BallotPositionDocEventFactory( time=now - datetime.timedelta(minutes=30), send_email=None, @@ -1196,11 +1258,12 @@ def test_ballotpositiondocevent_any_email_sent(self): ) def _assertBallotMessage(self, q, balloter, expected): - heading = q(f'p.h5[id$="_{slugify(balloter.plain_name())}"]') + heading = q(f'div.h5[id$="_{slugify(balloter.plain_name())}"]') self.assertEqual(len(heading), 1) - # is followed by a panel with the message of interest, so use next() + # is followed by a panel with the message of interest, so use next() + next = heading.next() self.assertEqual( - len(heading.next().find( + len(next.find( f'*[title="{expected}"]' )), 1, @@ -1219,7 +1282,7 @@ def test_document_ballot_content_email_sent(self): balloter=balloters[0], pos_id='discuss', discuss='Discussion text', - discuss_time=datetime.datetime.now(), + discuss_time=timezone.now(), send_email=True, ) BallotPositionDocEventFactory( @@ -1227,7 +1290,7 @@ def test_document_ballot_content_email_sent(self): balloter=balloters[1], pos_id='noobj', comment='Commentary', - comment_time=datetime.datetime.now(), + comment_time=timezone.now(), send_email=True, ) @@ -1237,7 +1300,7 @@ def test_document_ballot_content_email_sent(self): balloter=balloters[2], pos_id='discuss', discuss='Discussion text', - discuss_time=datetime.datetime.now(), + discuss_time=timezone.now(), send_email=False, ) BallotPositionDocEventFactory( @@ -1245,7 +1308,7 @@ def test_document_ballot_content_email_sent(self): balloter=balloters[3], pos_id='noobj', comment='Commentary', - comment_time=datetime.datetime.now(), + comment_time=timezone.now(), send_email=False, ) @@ -1255,7 +1318,7 @@ def test_document_ballot_content_email_sent(self): balloter=balloters[4], pos_id='discuss', discuss='Discussion text', - discuss_time=datetime.datetime.now() - datetime.timedelta(days=1), + discuss_time=timezone.now() - datetime.timedelta(days=1), send_email=True, ) BallotPositionDocEventFactory( @@ -1263,7 +1326,7 @@ def test_document_ballot_content_email_sent(self): balloter=balloters[4], pos_id='discuss', discuss='Discussion text', - discuss_time=datetime.datetime.now(), + discuss_time=timezone.now(), send_email=False, ) BallotPositionDocEventFactory( @@ -1271,7 +1334,7 @@ def test_document_ballot_content_email_sent(self): balloter=balloters[5], pos_id='noobj', comment='Commentary', - comment_time=datetime.datetime.now() - datetime.timedelta(days=1), + comment_time=timezone.now() - datetime.timedelta(days=1), send_email=True, ) BallotPositionDocEventFactory( @@ -1279,7 +1342,7 @@ def test_document_ballot_content_email_sent(self): balloter=balloters[5], pos_id='noobj', comment='Commentary', - comment_time=datetime.datetime.now(), + comment_time=timezone.now(), send_email=False, ) @@ -1296,7 +1359,7 @@ def test_document_ballot_content_email_sent(self): balloter__plain='plain name1', pos_id='discuss', discuss='Discussion text', - discuss_time=datetime.datetime.now(), + discuss_time=timezone.now(), send_email=False, ).balloter send_email_balloter = BallotPositionDocEventFactory( @@ -1304,7 +1367,7 @@ def test_document_ballot_content_email_sent(self): balloter__plain='plain name2', pos_id='discuss', discuss='Discussion text', - discuss_time=datetime.datetime.now(), + discuss_time=timezone.now(), send_email=True, ).balloter prev_send_email_balloter = BallotPositionDocEventFactory( @@ -1312,7 +1375,7 @@ def test_document_ballot_content_email_sent(self): balloter__plain='plain name3', pos_id='discuss', discuss='Discussion text', - discuss_time=datetime.datetime.now() - datetime.timedelta(days=1), + discuss_time=timezone.now() - datetime.timedelta(days=1), send_email=True, ).balloter BallotPositionDocEventFactory( @@ -1320,7 +1383,7 @@ def test_document_ballot_content_email_sent(self): balloter=prev_send_email_balloter, pos_id='discuss', discuss='Discussion text', - discuss_time=datetime.datetime.now(), + discuss_time=timezone.now(), send_email=False, ) @@ -1351,7 +1414,7 @@ def test_document_ballot_content_without_send_email_values(self): balloter=balloters[0], pos_id='discuss', discuss='Discussion text', - discuss_time=datetime.datetime.now(), + discuss_time=timezone.now(), send_email=None, ) BallotPositionDocEventFactory( @@ -1359,7 +1422,7 @@ def test_document_ballot_content_without_send_email_values(self): balloter=balloters[1], pos_id='noobj', comment='Commentary', - comment_time=datetime.datetime.now(), + comment_time=timezone.now(), send_email=None, ) old_balloter = BallotPositionDocEventFactory( @@ -1367,7 +1430,7 @@ def test_document_ballot_content_without_send_email_values(self): balloter__plain='plain name', # ensure plain name is slugifiable pos_id='discuss', discuss='Discussion text', - discuss_time=datetime.datetime.now(), + discuss_time=timezone.now(), send_email=None, ).balloter @@ -1377,6 +1440,31 @@ def test_document_ballot_content_without_send_email_values(self): ballot_id=ballot.pk, ) q = PyQuery(content) - self._assertBallotMessage(q, balloters[0], 'No email send requests for this discuss') - self._assertBallotMessage(q, balloters[1], 'No ballot position send log available') - self._assertBallotMessage(q, old_balloter, 'No ballot position send log available') \ No newline at end of file + self._assertBallotMessage(q, balloters[0], 'No discuss send log available') + self._assertBallotMessage(q, balloters[1], 'No comment send log available') + self._assertBallotMessage(q, old_balloter, 'No ballot position send log available') + +class ReturnToUrlTests(TestCase): + def test_invalid_return_to_url(self): + with self.assertRaises(ValueError): + parse_ballot_edit_return_point('/', 'draft-ietf-opsawg-ipfix-tcpo-v6eh', '998718') + + with self.assertRaises(ValueError): + parse_ballot_edit_return_point('/a-route-that-does-not-exist/', 'draft-ietf-opsawg-ipfix-tcpo-v6eh', '998718') + + with self.assertRaises(ValueError): + parse_ballot_edit_return_point('https://example.com/phishing', 'draft-ietf-opsawg-ipfix-tcpo-v6eh', '998718') + + def test_valid_default_return_to_url(self): + self.assertEqual(parse_ballot_edit_return_point( + None, + 'draft-ietf-opsawg-ipfix-tcpo-v6eh', + '998718' + ), '/doc/draft-ietf-opsawg-ipfix-tcpo-v6eh/ballot/998718/') + + def test_valid_return_to_url(self): + self.assertEqual(parse_ballot_edit_return_point( + '/doc/draft-ietf-opsawg-ipfix-tcpo-v6eh/ballot/998718/', + 'draft-ietf-opsawg-ipfix-tcpo-v6eh', + '998718' + ), '/doc/draft-ietf-opsawg-ipfix-tcpo-v6eh/ballot/998718/') diff --git a/ietf/doc/tests_bofreq.py b/ietf/doc/tests_bofreq.py index 4d02108d01d..6b142149be0 100644 --- a/ietf/doc/tests_bofreq.py +++ b/ietf/doc/tests_bofreq.py @@ -14,10 +14,12 @@ from django.conf import settings from django.urls import reverse as urlreverse from django.template.loader import render_to_string +from django.utils import timezone +from ietf.doc.storage_utils import retrieve_str from ietf.group.factories import RoleFactory from ietf.doc.factories import BofreqFactory, NewRevisionDocEventFactory -from ietf.doc.models import State, Document, DocAlias, NewRevisionDocEvent +from ietf.doc.models import State, Document, NewRevisionDocEvent from ietf.doc.utils_bofreq import bofreq_editors, bofreq_responsible from ietf.ietfauth.utils import has_role from ietf.person.factories import PersonFactory @@ -31,7 +33,7 @@ class BofreqTests(TestCase): settings_temp_path_overrides = TestCase.settings_temp_path_overrides + ['BOFREQ_PATH'] def write_bofreq_file(self, bofreq): - fname = Path(settings.BOFREQ_PATH) / ("%s-%s.md" % (bofreq.canonical_name(), bofreq.rev)) + fname = Path(settings.BOFREQ_PATH) / ("%s-%s.md" % (bofreq.name, bofreq.rev)) with fname.open("w") as f: f.write(f"""# This is a test bofreq. Version: {bofreq.rev} @@ -48,13 +50,13 @@ def test_show_bof_requests(self): states = State.objects.filter(type_id='bofreq') self.assertTrue(states.count()>0) for i in range(3*len(states)): - BofreqFactory(states=[('bofreq',states[i%len(states)].slug)],newrevisiondocevent__time=datetime.datetime.today()-datetime.timedelta(days=randint(0,20))) + BofreqFactory(states=[('bofreq',states[i%len(states)].slug)],newrevisiondocevent__time=timezone.now()-datetime.timedelta(days=randint(0,20))) r = self.client.get(url) self.assertEqual(r.status_code, 200) q = PyQuery(r.content) for state in states: - self.assertEqual(len(q(f'#bofreqs-{state.slug}')), 1) - self.assertEqual(len(q(f'#bofreqs-{state.slug} tbody tr')), 3) + self.assertEqual(len(q(f'#bofreqs-{state.slug}')), 1 if state.slug!="spam" else 0) + self.assertEqual(len(q(f'#bofreqs-{state.slug} tbody tr')), 3 if state.slug!="spam" else 0) self.assertFalse(q('#start_button')) PersonFactory(user__username='nobody') self.client.login(username='nobody', password='nobody+password') @@ -62,6 +64,13 @@ def test_show_bof_requests(self): self.assertEqual(r.status_code, 200) q = PyQuery(r.content) self.assertTrue(q('#start_button')) + self.client.logout() + self.client.login(username='secretary', password='secretary+password') + r = self.client.get(url) + q = PyQuery(r.content) + for state in states: + self.assertEqual(len(q(f'#bofreqs-{state.slug}')), 1) + self.assertEqual(len(q(f'#bofreqs-{state.slug} tbody tr')), 3) def test_bofreq_main_page(self): @@ -298,17 +307,20 @@ def test_submit(self): url = urlreverse('ietf.doc.views_bofreq.submit', kwargs=dict(name=doc.name)) rev = doc.rev + doc_time = doc.time r = self.client.post(url,{'bofreq_submission':'enter','bofreq_content':'# oiwefrase'}) self.assertEqual(r.status_code, 302) doc = reload_db_objects(doc) - self.assertEqual(rev, doc.rev) + self.assertEqual(doc.rev, rev) + self.assertEqual(doc.time, doc_time) nobody = PersonFactory() self.client.login(username=nobody.user.username, password=nobody.user.username+'+password') r = self.client.post(url,{'bofreq_submission':'enter','bofreq_content':'# oiwefrase'}) self.assertEqual(r.status_code, 403) doc = reload_db_objects(doc) - self.assertEqual(rev, doc.rev) + self.assertEqual(doc.rev, rev) + self.assertEqual(doc.time, doc_time) self.client.logout() editor = bofreq_editors(doc).first() @@ -319,22 +331,29 @@ def test_submit(self): file = NamedTemporaryFile(delete=False,mode="w+",encoding='utf-8') file.write(f'# {username}') file.close() - for postdict in [ - {'bofreq_submission':'enter','bofreq_content':f'# {username}'}, - {'bofreq_submission':'upload','bofreq_file':open(file.name,'rb')}, - ]: - docevent_count = doc.docevent_set.count() - empty_outbox() - r = self.client.post(url, postdict) - self.assertEqual(r.status_code, 302) - doc = reload_db_objects(doc) - self.assertEqual('%02d'%(int(rev)+1) ,doc.rev) - self.assertEqual(f'# {username}', doc.text()) - self.assertEqual(docevent_count+1, doc.docevent_set.count()) - self.assertEqual(1, len(outbox)) - rev = doc.rev + try: + with open(file.name, 'rb') as bofreq_fd: + for postdict in [ + {'bofreq_submission':'enter','bofreq_content':f'# {username}'}, + {'bofreq_submission':'upload','bofreq_file':bofreq_fd}, + ]: + docevent_count = doc.docevent_set.count() + empty_outbox() + r = self.client.post(url, postdict) + self.assertEqual(r.status_code, 302) + doc = reload_db_objects(doc) + self.assertEqual(doc.rev, '%02d'%(int(rev)+1)) + self.assertGreater(doc.time, doc_time) + self.assertEqual(doc.text(), f'# {username}') + self.assertEqual(retrieve_str('bofreq', doc.get_base_name()), f'# {username}') + self.assertEqual(doc.docevent_set.count(), docevent_count+1) + self.assertEqual(len(outbox), 1) + rev = doc.rev + doc_time = doc.time + finally: + os.unlink(file.name) + self.client.logout() - os.unlink(file.name) def test_start_new_bofreq(self): url = urlreverse('ietf.doc.views_bofreq.new_bof_request') @@ -349,25 +368,28 @@ def test_start_new_bofreq(self): file = NamedTemporaryFile(delete=False,mode="w+",encoding='utf-8') file.write('some stuff') file.close() - for postdict in [ - dict(title='title one', bofreq_submission='enter', bofreq_content='some stuff'), - dict(title='title two', bofreq_submission='upload', bofreq_file=open(file.name,'rb')), - ]: - empty_outbox() - r = self.client.post(url, postdict) - self.assertEqual(r.status_code,302) - name = f"bofreq-{xslugify(nobody.last_name())[:64]}-{postdict['title']}".replace(' ','-') - bofreq = Document.objects.filter(name=name,type_id='bofreq').first() - self.assertIsNotNone(bofreq) - self.assertIsNotNone(DocAlias.objects.filter(name=name).first()) - self.assertEqual(bofreq.title, postdict['title']) - self.assertEqual(bofreq.rev, '00') - self.assertEqual(bofreq.get_state_slug(), 'proposed') - self.assertEqual(list(bofreq_editors(bofreq)), [nobody]) - self.assertEqual(bofreq.latest_event(NewRevisionDocEvent).rev, '00') - self.assertEqual(bofreq.text_or_error(), 'some stuff') - self.assertEqual(len(outbox),1) - os.unlink(file.name) + try: + with open(file.name,'rb') as bofreq_fd: + for postdict in [ + dict(title='title one', bofreq_submission='enter', bofreq_content='some stuff'), + dict(title='title two', bofreq_submission='upload', bofreq_file=bofreq_fd), + ]: + empty_outbox() + r = self.client.post(url, postdict) + self.assertEqual(r.status_code,302) + name = f"bofreq-{xslugify(nobody.last_name())[:64]}-{postdict['title']}".replace(' ','-') + bofreq = Document.objects.filter(name=name,type_id='bofreq').first() + self.assertIsNotNone(bofreq) + self.assertEqual(bofreq.title, postdict['title']) + self.assertEqual(bofreq.rev, '00') + self.assertEqual(bofreq.get_state_slug(), 'proposed') + self.assertEqual(list(bofreq_editors(bofreq)), [nobody]) + self.assertEqual(bofreq.latest_event(NewRevisionDocEvent).rev, '00') + self.assertEqual(bofreq.text_or_error(), 'some stuff') + self.assertEqual(retrieve_str('bofreq',bofreq.get_base_name()), 'some stuff') + self.assertEqual(len(outbox),1) + finally: + os.unlink(file.name) existing_bofreq = BofreqFactory(requester_lastname=nobody.last_name()) for postdict in [ dict(title='', bofreq_submission='enter', bofreq_content='some stuff'), diff --git a/ietf/doc/tests_charter.py b/ietf/doc/tests_charter.py index 8732b7701d9..62e49559e28 100644 --- a/ietf/doc/tests_charter.py +++ b/ietf/doc/tests_charter.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright The IETF Trust 2011-2020, All Rights Reserved +# Copyright The IETF Trust 2011-2023, All Rights Reserved import datetime @@ -16,6 +16,7 @@ from ietf.doc.factories import CharterFactory, NewRevisionDocEventFactory, TelechatDocEventFactory from ietf.doc.models import ( Document, State, BallotDocEvent, BallotType, NewRevisionDocEvent, TelechatDocEvent, WriteupDocEvent ) +from ietf.doc.storage_utils import retrieve_str from ietf.doc.utils_charter import ( next_revision, default_review_text, default_action_text, charter_name_for_group ) from ietf.doc.utils import close_open_ballots @@ -26,6 +27,8 @@ from ietf.utils.test_utils import TestCase from ietf.utils.mail import outbox, empty_outbox, get_payload_text from ietf.utils.test_utils import login_testing_unauthorized +from ietf.utils.timezone import datetime_today, date_today, DEADLINE_TZINFO + class ViewCharterTests(TestCase): def test_view_revisions(self): @@ -85,11 +88,12 @@ def test_view_revisions(self): class EditCharterTests(TestCase): settings_temp_path_overrides = TestCase.settings_temp_path_overrides + ['CHARTER_PATH'] + def setUp(self): + super().setUp() + (Path(settings.FTP_DIR)/"charter").mkdir() + def write_charter_file(self, charter): - with (Path(settings.CHARTER_PATH) / - ("%s-%s.txt" % (charter.canonical_name(), charter.rev)) - ).open("w") as f: - f.write("This is a charter.") + (Path(settings.CHARTER_PATH) / f"{charter.name}-{charter.rev}.txt").write_text("This is a charter.") def test_startstop_process(self): CharterFactory(group__acronym='mars') @@ -402,7 +406,7 @@ def test_no_returning_item_for_different_ballot(self): # Make it so that the charter has been through internal review, and passed its external review # ballot on a previous telechat - last_week = datetime.date.today()-datetime.timedelta(days=7) + last_week = datetime_today(DEADLINE_TZINFO) - datetime.timedelta(days=7) BallotDocEvent.objects.create(type='created_ballot',by=login,doc=charter, rev=charter.rev, ballot_type=BallotType.objects.get(doc_type=charter.type,slug='r-extrev'), time=last_week) @@ -446,8 +450,8 @@ def test_edit_notify(self): # Regenerate does not save! self.assertEqual(charter.notify,newlist) q = PyQuery(r.content) - formlist = q('form input[name=notify]')[0].value - self.assertEqual(formlist, None) + formlist = q('form textarea[name=notify]')[0].value.strip() + self.assertEqual(formlist, "") def test_edit_ad(self): @@ -507,8 +511,21 @@ def test_submit_charter(self): self.assertEqual(charter.rev, next_revision(prev_rev)) self.assertTrue("new_revision" in charter.latest_event().type) - with (Path(settings.CHARTER_PATH) / (charter.canonical_name() + "-" + charter.rev + ".txt")).open(encoding='utf-8') as f: - self.assertEqual(f.read(), "Windows line\nMac line\nUnix line\n" + utf_8_snippet.decode('utf-8')) + charter_path = Path(settings.CHARTER_PATH) / (charter.name + "-" + charter.rev + ".txt") + file_contents = (charter_path).read_text("utf-8") + self.assertEqual( + file_contents, + "Windows line\nMac line\nUnix line\n" + utf_8_snippet.decode("utf-8"), + ) + ftp_charter_path = Path(settings.FTP_DIR) / "charter" / charter_path.name + self.assertTrue(ftp_charter_path.exists()) + self.assertTrue(charter_path.samefile(ftp_charter_path)) + blobstore_contents = retrieve_str("charter", charter.get_base_name()) + self.assertEqual( + blobstore_contents, + "Windows line\nMac line\nUnix line\n" + utf_8_snippet.decode("utf-8"), + ) + def test_submit_initial_charter(self): group = GroupFactory(type_id='wg',acronym='mars',list_email='mars-wg@ietf.org') @@ -536,6 +553,24 @@ def test_submit_initial_charter(self): group = Group.objects.get(pk=group.pk) self.assertEqual(group.charter, charter) + def test_submit_charter_with_invalid_name(self): + self.client.login(username="secretary", password="secretary+password") + ietf_group = GroupFactory(type_id="wg") + for bad_name in ("charter-irtf-{}", "charter-randomjunk-{}", "charter-ietf-thisisnotagroup"): + url = urlreverse("ietf.doc.views_charter.submit", kwargs={"name": bad_name.format(ietf_group.acronym)}) + r = self.client.get(url) + self.assertEqual(r.status_code, 404, f"GET of charter named {bad_name} should 404") + r = self.client.post(url, {}) + self.assertEqual(r.status_code, 404, f"POST of charter named {bad_name} should 404") + + irtf_group = GroupFactory(type_id="rg") + for bad_name in ("charter-ietf-{}", "charter-whatisthis-{}", "charter-irtf-thisisnotagroup"): + url = urlreverse("ietf.doc.views_charter.submit", kwargs={"name": bad_name.format(irtf_group.acronym)}) + r = self.client.get(url) + self.assertEqual(r.status_code, 404, f"GET of charter named {bad_name} should 404") + r = self.client.post(url, {}) + self.assertEqual(r.status_code, 404, f"POST of charter named {bad_name} should 404") + def test_edit_review_announcement_text(self): area = GroupFactory(type_id='area') RoleFactory(name_id='ad',group=area,person=Person.objects.get(user__username='ad')) @@ -746,7 +781,7 @@ def test_approve(self): charter.set_state(State.objects.get(used=True, type="charter", slug="iesgrev")) - due_date = datetime.date.today() + datetime.timedelta(days=180) + due_date = date_today(DEADLINE_TZINFO) + datetime.timedelta(days=180) m1 = GroupMilestone.objects.create(group=group, state_id="active", desc="Has been copied", @@ -786,9 +821,11 @@ def test_approve(self): self.assertTrue(not charter.ballot_open("approve")) self.assertEqual(charter.rev, "01") - self.assertTrue( - (Path(settings.CHARTER_PATH) / ("charter-ietf-%s-%s.txt" % (group.acronym, charter.rev))).exists() - ) + charter_path = Path(settings.CHARTER_PATH) / ("charter-ietf-%s-%s.txt" % (group.acronym, charter.rev)) + charter_ftp_path = Path(settings.FTP_DIR) / "charter" / charter_path.name + self.assertTrue(charter_path.exists()) + self.assertTrue(charter_ftp_path.exists()) + self.assertTrue(charter_path.samefile(charter_ftp_path)) self.assertEqual(len(outbox), 2) # @@ -815,6 +852,19 @@ def test_approve(self): self.assertEqual(group.groupmilestone_set.filter(state="active", desc=m1.desc).count(), 1) self.assertEqual(group.groupmilestone_set.filter(state="active", desc=m4.desc).count(), 1) + def test_approve_irtf(self): + charter = CharterFactory(group__type_id='rg') + url = urlreverse('ietf.doc.views_charter.approve', kwargs=dict(name=charter.name)) + login_testing_unauthorized(self, "secretary", url) + empty_outbox() + r = self.client.post(url, dict()) + self.assertEqual(r.status_code, 302) + self.assertEqual(len(outbox), 2) + self.assertTrue("IRTF" in outbox[1]['From']) + self.assertTrue("irtf-announce" in outbox[1]['To']) + self.assertTrue(charter.group.acronym in outbox[1]['Cc']) + self.assertTrue("RG Action" in outbox[1]['Subject']) + def test_charter_with_milestones(self): charter = CharterFactory() @@ -826,7 +876,7 @@ def test_charter_with_milestones(self): m = GroupMilestone.objects.create(group=charter.group, state_id="active", desc="Test milestone", - due=datetime.date.today(), + due=date_today(DEADLINE_TZINFO), resolved="") url = urlreverse('ietf.doc.views_charter.charter_with_milestones_txt', kwargs=dict(name=charter.name, rev=charter.rev)) @@ -838,4 +888,4 @@ def test_chartering_from_bof(self): ad_role = RoleFactory(group__type_id='area',name_id='ad') charter = CharterFactory(group__type_id='wg',group__state_id='bof',group__parent=ad_role.group) e1,_ = default_review_text(charter.group, charter, Person.objects.get(name="(System)")) - self.assertTrue('A new IETF WG has been proposed' in e1.text) \ No newline at end of file + self.assertTrue('A new IETF WG has been proposed' in e1.text) diff --git a/ietf/doc/tests_conflict_review.py b/ietf/doc/tests_conflict_review.py index 4cc501ec0ca..791db17f5a2 100644 --- a/ietf/doc/tests_conflict_review.py +++ b/ietf/doc/tests_conflict_review.py @@ -1,9 +1,10 @@ -# Copyright The IETF Trust 2012-2020, All Rights Reserved +# Copyright The IETF Trust 2012-2023, All Rights Reserved # -*- coding: utf-8 -*- import io import os +from pathlib import Path from pyquery import PyQuery from textwrap import wrap @@ -13,8 +14,9 @@ import debug # pyflakes:ignore -from ietf.doc.factories import IndividualDraftFactory, ConflictReviewFactory -from ietf.doc.models import Document, DocEvent, NewRevisionDocEvent, BallotPositionDocEvent, TelechatDocEvent, State +from ietf.doc.factories import IndividualDraftFactory, ConflictReviewFactory, RgDraftFactory +from ietf.doc.models import Document, DocEvent, NewRevisionDocEvent, BallotPositionDocEvent, TelechatDocEvent, State, DocTagName +from ietf.doc.storage_utils import retrieve_str from ietf.doc.utils import create_ballot_if_not_open from ietf.doc.views_conflict_review import default_approval_text from ietf.group.models import Person @@ -70,12 +72,12 @@ def test_start_review_as_secretary(self): self.assertEqual(review_doc.ad.name,'Areað Irector') self.assertEqual(review_doc.notify,'ipu@ietf.org') doc = Document.objects.get(name='draft-imaginary-independent-submission') - self.assertTrue(doc in [x.target.document for x in review_doc.relateddocument_set.filter(relationship__slug='conflrev')]) + self.assertTrue(doc in [x.target for x in review_doc.relateddocument_set.filter(relationship__slug='conflrev')]) self.assertTrue(review_doc.latest_event(DocEvent,type="added_comment").desc.startswith("IETF conflict review requested")) self.assertTrue(doc.latest_event(DocEvent,type="added_comment").desc.startswith("IETF conflict review initiated")) self.assertTrue('Conflict Review requested' in outbox[-1]['Subject']) - + # verify you can't start a review when a review is already in progress r = self.client.post(url,dict(ad="Areað Irector",create_in_state="Needs Shepherd",notify='ipu@ietf.org')) self.assertEqual(r.status_code, 404) @@ -105,7 +107,7 @@ def test_start_review_as_stream_owner(self): r = self.client.get(url) self.assertEqual(r.status_code, 200) q = PyQuery(r.content) - self.assertEqual(len(q('form input[name=notify]')),1) + self.assertEqual(len(q('form textarea[name=notify]')), 1) self.assertEqual(len(q('form select[name=ad]')),0) # successfully starts a review, and notifies the secretariat @@ -119,7 +121,7 @@ def test_start_review_as_stream_owner(self): self.assertEqual(review_doc.ad.name,'Ietf Chair') self.assertEqual(review_doc.notify,'ipu@ietf.org') doc = Document.objects.get(name='draft-imaginary-independent-submission') - self.assertTrue(doc in [x.target.document for x in review_doc.relateddocument_set.filter(relationship__slug='conflrev')]) + self.assertTrue(doc in [x.target for x in review_doc.relateddocument_set.filter(relationship__slug='conflrev')]) self.assertEqual(len(outbox), messages_before + 2) @@ -168,6 +170,21 @@ def test_change_state(self): self.assertTrue(review_doc.active_ballot()) self.assertEqual(review_doc.latest_event(BallotPositionDocEvent, type="changed_ballot_position").pos_id,'yes') + # try to change to an AD-forbidden state + appr_noprob_sent_pk = str(State.objects.get(used=True, slug='appr-noprob-sent',type__slug='conflrev').pk) + r = self.client.post(url,dict(review_state=appr_noprob_sent_pk,comment='xyzzy')) + self.assertEqual(r.status_code, 200) + q = PyQuery(r.content) + self.assertTrue(q('form .invalid-feedback')) + + # try again as secretariat + self.client.logout() + login_testing_unauthorized(self, 'secretary', url) + r = self.client.post(url,dict(review_state=appr_noprob_sent_pk,comment='xyzzy')) + self.assertEqual(r.status_code, 302) + review_doc = Document.objects.get(name='conflict-review-imaginary-irtf-submission') + self.assertEqual(review_doc.get_state('conflrev').slug, 'appr-noprob-sent') + def test_edit_notices(self): doc = Document.objects.get(name='conflict-review-imaginary-irtf-submission') @@ -179,8 +196,8 @@ def test_edit_notices(self): r = self.client.get(url) self.assertEqual(r.status_code, 200) q = PyQuery(r.content) - self.assertEqual(len(q('form input[name=notify]')),1) - self.assertEqual(doc.notify,q('form input[name=notify]')[0].value) + self.assertEqual(len(q('form textarea[name=notify]')), 1) + self.assertEqual(doc.notify, q('form textarea[name=notify]')[0].value.strip()) # change notice list newlist = '"Foo Bar" ' @@ -197,7 +214,7 @@ def test_edit_notices(self): # Regenerate does not save! self.assertEqual(doc.notify,newlist) q = PyQuery(r.content) - self.assertEqual(None,q('form input[name=notify]')[0].value) + self.assertEqual("", q('form textarea[name=notify]')[0].value.strip()) def test_edit_ad(self): doc = Document.objects.get(name='conflict-review-imaginary-irtf-submission') @@ -372,7 +389,7 @@ def setUp(self): class ConflictReviewSubmitTests(TestCase): - settings_temp_path_overrides = TestCase.settings_temp_path_overrides + ['CONFLICT_REVIEW_PATH'] + settings_temp_path_overrides = TestCase.settings_temp_path_overrides + ['CONFLICT_REVIEW_PATH','FTP_PATH'] def test_initial_submission(self): doc = Document.objects.get(name='conflict-review-imaginary-irtf-submission') url = urlreverse('ietf.doc.views_conflict_review.submit',kwargs=dict(name=doc.name)) @@ -388,9 +405,15 @@ def test_initial_submission(self): # Right now, nothing to test - we let people put whatever the web browser will let them put into that textbox # sane post using textbox - path = os.path.join(settings.CONFLICT_REVIEW_PATH, '%s-%s.txt' % (doc.canonical_name(), doc.rev)) + basename = f"{doc.name}-{doc.rev}.txt" + path = Path(settings.CONFLICT_REVIEW_PATH) / basename + ftp_dir = Path(settings.FTP_DIR) / "conflict-reviews" + if not ftp_dir.exists(): + ftp_dir.mkdir() + ftp_path = ftp_dir / basename self.assertEqual(doc.rev,'00') - self.assertFalse(os.path.exists(path)) + self.assertFalse(path.exists()) + self.assertFalse(ftp_path.exists()) r = self.client.post(url,dict(content="Some initial review text\n",submit_response="1")) self.assertEqual(r.status_code,302) doc = Document.objects.get(name='conflict-review-imaginary-irtf-submission') @@ -398,7 +421,9 @@ def test_initial_submission(self): with io.open(path) as f: self.assertEqual(f.read(),"Some initial review text\n") f.close() + self.assertTrue(ftp_path.exists()) self.assertTrue( "submission-00" in doc.latest_event(NewRevisionDocEvent).desc) + self.assertEqual(retrieve_str("conflrev",basename), "Some initial review text\n") def test_subsequent_submission(self): doc = Document.objects.get(name='conflict-review-imaginary-irtf-submission') @@ -408,7 +433,7 @@ def test_subsequent_submission(self): # A little additional setup # doc.rev is u'00' per the test setup - double-checking that here - if it fails, the breakage is in setUp self.assertEqual(doc.rev,'00') - path = os.path.join(settings.CONFLICT_REVIEW_PATH, '%s-%s.txt' % (doc.canonical_name(), doc.rev)) + path = os.path.join(settings.CONFLICT_REVIEW_PATH, '%s-%s.txt' % (doc.name, doc.rev)) with io.open(path,'w') as f: f.write('This is the old proposal.') f.close() @@ -435,7 +460,7 @@ def test_subsequent_submission(self): self.assertEqual(r.status_code, 302) doc = Document.objects.get(name='conflict-review-imaginary-irtf-submission') self.assertEqual(doc.rev,'01') - path = os.path.join(settings.CONFLICT_REVIEW_PATH, '%s-%s.txt' % (doc.canonical_name(), doc.rev)) + path = os.path.join(settings.CONFLICT_REVIEW_PATH, '%s-%s.txt' % (doc.name, doc.rev)) with io.open(path) as f: self.assertEqual(f.read(),"This is a new proposal.") f.close() @@ -450,3 +475,89 @@ def test_subsequent_submission(self): def setUp(self): super().setUp() ConflictReviewFactory(name='conflict-review-imaginary-irtf-submission',review_of=IndividualDraftFactory(name='draft-imaginary-irtf-submission',stream_id='irtf'),notify='notifyme@example.net') + +class ConflictReviewStreamStateTests(TestCase): + + def start_review(self, stream, role, kwargs=None): + doc = RgDraftFactory() if stream=='irtf' else IndividualDraftFactory(stream=StreamName.objects.get(slug='ise')) + url = urlreverse('ietf.doc.views_conflict_review.start_review', kwargs=dict(name=doc.name)) + login_testing_unauthorized(self, role, url) + r = self.client.post(url, kwargs) + self.assertEqual(r.status_code, 302) + self.assertEqual(doc.get_state('draft-stream-'+stream).slug, 'iesg-rev') + + def test_start_irtf_review_as_secretary(self): + ad_strpk = str(Person.objects.get(name='Areað Irector').pk) + state_strpk = str(State.objects.get(used=True, slug='needshep', type__slug='conflrev').pk) + self.start_review('irtf', 'secretary', kwargs=dict(ad=ad_strpk, create_in_state=state_strpk)) + + def test_start_ise_review_as_secretary(self): + ad_strpk = str(Person.objects.get(name='Areað Irector').pk) + state_strpk = str(State.objects.get(used=True, slug='needshep', type__slug='conflrev').pk) + self.start_review('ise', 'secretary', kwargs=dict(ad=ad_strpk, create_in_state=state_strpk)) + + def test_start_irtf_review_as_stream_owner(self): + self.start_review('irtf', 'irtf-chair') + + def test_start_ise_review_as_stream_owner(self): + self.start_review('ise', 'ise-chair') + + def close_review(self, close_type, stream, role): + doc = RgDraftFactory() if stream=='irtf' else IndividualDraftFactory(stream=StreamName.objects.get(slug='ise')) + review = ConflictReviewFactory(review_of=doc) + url = urlreverse('ietf.doc.views_conflict_review.change_state', kwargs=dict(name=review.name)) + login_testing_unauthorized(self, role, url) + strpk = str(State.objects.get(used=True, slug=close_type, type__slug='conflrev').pk) + r = self.client.post(url, dict(review_state=strpk)) + self.assertEqual(r.status_code, 302) + self.assertEqual(doc.get_state('draft-stream-'+stream).slug, 'chair-w' if stream=='irtf' else 'ise-rev') + self.assertIn(DocTagName.objects.get(pk='iesg-com'), doc.tags.all()) + + def test_close_irtf_review_reqnopub_as_secretary(self): + self.close_review('appr-reqnopub-sent', 'irtf', 'secretary') + + def test_close_ise_review_reqnopub_as_secretary(self): + self.close_review('appr-reqnopub-sent', 'ise', 'secretary') + + def test_close_irtf_review_noprob_as_secretary(self): + self.close_review('appr-noprob-sent', 'irtf', 'secretary') + + def test_close_ise_review_noprob_as_secretary(self): + self.close_review('appr-noprob-sent', 'ise', 'secretary') + + def test_close_irtf_review_withdraw_as_secretary(self): + self.close_review('withdraw', 'irtf', 'secretary') + + def test_close_ise_review_withdraw_as_secretary(self): + self.close_review('withdraw', 'ise', 'secretary') + + def test_close_irtf_review_dead_as_secretary(self): + self.close_review('dead', 'irtf', 'secretary') + + def test_close_ise_review_dead_as_secretary(self): + self.close_review('dead', 'ise', 'secretary') + + def test_close_irtf_review_withdraw_as_ad(self): + self.close_review('withdraw', 'irtf', 'ad') + + def test_close_ise_review_withdraw_as_ad(self): + self.close_review('withdraw', 'ise', 'ad') + + def test_close_irtf_review_dead_as_ad(self): + self.close_review('dead', 'irtf', 'ad') + + def test_close_ise_review_dead_as_ad(self): + self.close_review('dead', 'ise', 'ad') + + def test_approve_review(self): + doc = RgDraftFactory() + review = ConflictReviewFactory(review_of=doc) + review.set_state(State.objects.get(used=True, slug='appr-noprob-pend', type='conflrev')) + + url = urlreverse('ietf.doc.views_conflict_review.approve_conflict_review', kwargs=dict(name=review.name)) + login_testing_unauthorized(self, 'secretary', url) + + r = self.client.post(url, dict(announcement_text=default_approval_text(review))) + self.assertEqual(r.status_code, 302) + self.assertEqual(doc.get_state('draft-stream-irtf').slug, 'chair-w') + self.assertIn(DocTagName.objects.get(pk='iesg-com'), doc.tags.all()) diff --git a/ietf/doc/tests_downref.py b/ietf/doc/tests_downref.py index dae65cb07d2..0222ad79423 100644 --- a/ietf/doc/tests_downref.py +++ b/ietf/doc/tests_downref.py @@ -19,12 +19,9 @@ def setUp(self): super().setUp() PersonFactory(name='Plain Man',user__username='plain') self.draft = WgDraftFactory(name='draft-ietf-mars-test') - self.draftalias = self.draft.docalias.get(name='draft-ietf-mars-test') self.doc = WgDraftFactory(name='draft-ietf-mars-approved-document',states=[('draft-iesg','rfcqueue')]) - self.docalias = self.doc.docalias.get(name='draft-ietf-mars-approved-document') - self.rfc = WgRfcFactory(alias2__name='rfc9998') - self.rfcalias = self.rfc.docalias.get(name='rfc9998') - RelatedDocument.objects.create(source=self.doc, target=self.rfcalias, relationship_id='downref-approval') + self.rfc = WgRfcFactory(rfc_number=9998) + RelatedDocument.objects.create(source=self.doc, target=self.rfc, relationship_id='downref-approval') def test_downref_registry(self): url = urlreverse('ietf.doc.views_downref.downref_registry') @@ -64,44 +61,44 @@ def test_downref_registry_add(self): self.assertContains(r, 'Save downref') # error - already in the downref registry - r = self.client.post(url, dict(rfc=self.rfcalias.pk, drafts=(self.doc.pk, ))) + r = self.client.post(url, dict(rfc=self.rfc.pk, drafts=(self.doc.pk, ))) self.assertContains(r, 'Downref is already in the registry') # error - source is not in an approved state r = self.client.get(url) self.assertEqual(r.status_code, 200) - r = self.client.post(url, dict(rfc=self.rfcalias.pk, drafts=(self.draft.pk, ))) + r = self.client.post(url, dict(rfc=self.rfc.pk, drafts=(self.draft.pk, ))) self.assertContains(r, 'Draft is not yet approved') # error - the target is not a normative reference of the source self.draft.set_state(State.objects.get(used=True, type="draft-iesg", slug="pub")) r = self.client.get(url) self.assertEqual(r.status_code, 200) - r = self.client.post(url, dict(rfc=self.rfcalias.pk, drafts=(self.draft.pk, ))) + r = self.client.post(url, dict(rfc=self.rfc.pk, drafts=(self.draft.pk, ))) self.assertContains(r, 'There does not seem to be a normative reference to RFC') self.assertContains(r, 'Save downref anyway') # normal - approve the document so the downref is now okay - RelatedDocument.objects.create(source=self.draft, target=self.rfcalias, relationship_id='refnorm') + RelatedDocument.objects.create(source=self.draft, target=self.rfc, relationship_id='refnorm') draft_de_count_before = self.draft.docevent_set.count() rfc_de_count_before = self.rfc.docevent_set.count() r = self.client.get(url) self.assertEqual(r.status_code, 200) - r = self.client.post(url, dict(rfc=self.rfcalias.pk, drafts=(self.draft.pk, ))) + r = self.client.post(url, dict(rfc=self.rfc.pk, drafts=(self.draft.pk, ))) self.assertEqual(r.status_code, 302) newurl = urlreverse('ietf.doc.views_downref.downref_registry') r = self.client.get(newurl) self.assertContains(r, '= datetime.datetime.now() + datetime.timedelta(days=settings.INTERNET_DRAFT_DAYS_TO_EXPIRE - 1)) + self.assertTrue(draft.expires >= timezone.now() + datetime.timedelta(days=settings.INTERNET_DRAFT_DAYS_TO_EXPIRE - 1)) self.assertEqual(len(outbox), mailbox_before + 1) self.assertTrue('Resurrection Completed' in outbox[-1]['Subject']) self.assertTrue('iesg-secretary' in outbox[-1]['To']) @@ -627,26 +656,35 @@ def test_resurrect(self): # ensure file restored from archive directory self.assertTrue(os.path.exists(os.path.join(settings.INTERNET_DRAFT_PATH, txt))) self.assertTrue(not os.path.exists(os.path.join(settings.INTERNET_DRAFT_ARCHIVE_DIR, txt))) + self.assertTrue(exists_in_storage("active-draft",f"txt/{txt}")) class ExpireIDsTests(DraftFileMixin, TestCase): def test_in_draft_expire_freeze(self): from ietf.doc.expire import in_draft_expire_freeze - # If there is no "next" meeting, we musn't be in a freeze + # If there is no "next" meeting, we mustn't be in a freeze self.assertTrue(not in_draft_expire_freeze()) meeting = Meeting.objects.create(number="123", type=MeetingTypeName.objects.get(slug="ietf"), - date=datetime.date.today()) + date=date_today()) second_cut_off = meeting.get_second_cut_off() ietf_monday = meeting.get_ietf_monday() - self.assertTrue(not in_draft_expire_freeze(datetime.datetime.combine(second_cut_off - datetime.timedelta(days=7), datetime.time(0, 0, 0)))) - self.assertTrue(not in_draft_expire_freeze(datetime.datetime.combine(second_cut_off, datetime.time(0, 0, 0)))) - self.assertTrue(in_draft_expire_freeze(datetime.datetime.combine(second_cut_off + datetime.timedelta(days=7), datetime.time(0, 0, 0)))) - self.assertTrue(in_draft_expire_freeze(datetime.datetime.combine(ietf_monday - datetime.timedelta(days=1), datetime.time(0, 0, 0)))) - self.assertTrue(not in_draft_expire_freeze(datetime.datetime.combine(ietf_monday, datetime.time(0, 0, 0)))) + self.assertFalse(in_draft_expire_freeze((second_cut_off - datetime.timedelta(days=7)).replace(hour=0, minute=0, second=0))) + self.assertFalse(in_draft_expire_freeze(second_cut_off.replace(hour=0, minute=0, second=0))) + self.assertTrue(in_draft_expire_freeze((second_cut_off + datetime.timedelta(days=7)).replace(hour=0, minute=0, second=0))) + self.assertTrue(in_draft_expire_freeze( + datetime.datetime.combine( + ietf_monday - datetime.timedelta(days=1), + datetime.time(0, 0, 0), + tzinfo=datetime.UTC, + ) + )) + self.assertFalse(in_draft_expire_freeze( + datetime.datetime.combine(ietf_monday, datetime.time(0, 0, 0), tzinfo=datetime.UTC) + )) def test_warn_expirable_drafts(self): from ietf.doc.expire import get_soon_to_expire_drafts, send_expire_warning_for_draft @@ -657,9 +695,9 @@ def test_warn_expirable_drafts(self): self.assertEqual(len(list(get_soon_to_expire_drafts(14))), 0) - # hack into expirable state + # hack into expirable state to expire in 10 days draft.set_state(State.objects.get(type_id='draft-iesg',slug='idexists')) - draft.expires = datetime.datetime.now() + datetime.timedelta(days=10) + draft.expires = timezone.now() + datetime.timedelta(days=10) draft.save_with_history([DocEvent.objects.create(doc=draft, rev=draft.rev, type="changed_document", by=Person.objects.get(user__username="secretary"), desc="Test")]) self.assertEqual(len(list(get_soon_to_expire_drafts(14))), 1) @@ -673,8 +711,17 @@ def test_warn_expirable_drafts(self): self.assertTrue('draft-ietf-mars-test@' in outbox[-1]['To']) # Gets the authors self.assertTrue('mars-chairs@ietf.org' in outbox[-1]['Cc']) self.assertTrue('aread@' in outbox[-1]['Cc']) + + # hack into expirable state to expire in 10 hours + draft.expires = timezone.now() + datetime.timedelta(hours=10) + draft.save_with_history([DocEvent.objects.create(doc=draft, rev=draft.rev, type="changed_document", by=Person.objects.get(user__username="secretary"), desc="Test")]) + + # test send warning is not sent for a document so close to expiration + mailbox_before = len(outbox) + send_expire_warning_for_draft(draft) + self.assertEqual(len(outbox), mailbox_before) - #Check that we don't sent expiration warnings for dead or replaced drafts + # Check that we don't sent expiration warnings for dead or replaced drafts old_state = draft.get_state_slug("draft-iesg") mailbox_before = len(outbox) draft.set_state(State.objects.get(type_id="draft-iesg",slug="dead")) @@ -698,15 +745,11 @@ def test_expire_drafts(self): # hack into expirable state draft.set_state(State.objects.get(type_id='draft-iesg',slug='idexists')) - draft.expires = datetime.datetime.now() + draft.expires = timezone.now() draft.save_with_history([DocEvent.objects.create(doc=draft, rev=draft.rev, type="changed_document", by=Person.objects.get(user__username="secretary"), desc="Test")]) self.assertEqual(len(list(get_expired_drafts())), 1) - draft.set_state(State.objects.get(used=True, type="draft-iesg", slug="watching")) - - self.assertEqual(len(list(get_expired_drafts())), 1) - draft.set_state(State.objects.get(used=True, type="draft-iesg", slug="iesg-eva")) self.assertEqual(len(list(get_expired_drafts())), 0) @@ -728,20 +771,24 @@ def test_expire_drafts(self): txt = "%s-%s.txt" % (draft.name, draft.rev) self.write_draft_file(txt, 5000) + self.assertFalse(expirable_drafts(Document.objects.filter(pk=draft.pk)).exists()) + draft.set_state(State.objects.get(used=True, type="draft-iesg", slug="idexists")) + self.assertTrue(expirable_drafts(Document.objects.filter(pk=draft.pk)).exists()) expire_draft(draft) draft = Document.objects.get(name=draft.name) self.assertEqual(draft.get_state_slug(), "expired") - self.assertEqual(draft.get_state_slug("draft-iesg"), "dead") + self.assertEqual(draft.get_state_slug("draft-iesg"), "idexists") self.assertTrue(draft.latest_event(type="expired_document")) - self.assertCountEqual(draft.action_holders.all(), []) + self.assertEqual(draft.action_holders.count(), 0) self.assertIn('Removed all action holders', draft.latest_event(type='changed_action_holders').desc) self.assertTrue(not os.path.exists(os.path.join(settings.INTERNET_DRAFT_PATH, txt))) + self.assertFalse(exists_in_storage("active-draft", f"txt/{txt}")) self.assertTrue(os.path.exists(os.path.join(settings.INTERNET_DRAFT_ARCHIVE_DIR, txt))) draft.delete() - rgdraft = RgDraftFactory(expires=datetime.datetime.now()) + rgdraft = RgDraftFactory(expires=timezone.now()) self.assertEqual(len(list(get_expired_drafts())), 1) for slug in ('iesg-rev','irsgpoll'): rgdraft.set_state(State.objects.get(type_id='draft-stream-irtf',slug=slug)) @@ -760,6 +807,7 @@ def test_clean_up_draft_files(self): clean_up_draft_files() self.assertTrue(not os.path.exists(os.path.join(settings.INTERNET_DRAFT_PATH, unknown))) + self.assertFalse(exists_in_storage("active-draft", f"txt/{unknown}")) self.assertTrue(os.path.exists(os.path.join(settings.INTERNET_DRAFT_ARCHIVE_DIR, "unknown_ids", unknown))) @@ -770,6 +818,7 @@ def test_clean_up_draft_files(self): clean_up_draft_files() self.assertTrue(not os.path.exists(os.path.join(settings.INTERNET_DRAFT_PATH, malformed))) + self.assertFalse(exists_in_storage("active-draft", f"txt/{malformed}")) self.assertTrue(os.path.exists(os.path.join(settings.INTERNET_DRAFT_ARCHIVE_DIR, "unknown_ids", malformed))) @@ -784,14 +833,16 @@ def test_clean_up_draft_files(self): clean_up_draft_files() self.assertTrue(not os.path.exists(os.path.join(settings.INTERNET_DRAFT_PATH, txt))) + self.assertFalse(exists_in_storage("active-draft", f"txt/{txt}")) self.assertTrue(os.path.exists(os.path.join(settings.INTERNET_DRAFT_ARCHIVE_DIR, txt))) self.assertTrue(not os.path.exists(os.path.join(settings.INTERNET_DRAFT_PATH, pdf))) + self.assertFalse(exists_in_storage("active-draft", f"pdf/{pdf}")) self.assertTrue(os.path.exists(os.path.join(settings.INTERNET_DRAFT_ARCHIVE_DIR, pdf))) # expire draft draft.set_state(State.objects.get(used=True, type="draft", slug="expired")) - draft.expires = datetime.datetime.now() - datetime.timedelta(days=1) + draft.expires = timezone.now() - datetime.timedelta(days=1) draft.save_with_history([DocEvent.objects.create(doc=draft, rev=draft.rev, type="changed_document", by=Person.objects.get(user__username="secretary"), desc="Test")]) e = DocEvent(doc=draft, rev=draft.rev, type= "expired_document", time=draft.expires, @@ -805,6 +856,7 @@ def test_clean_up_draft_files(self): clean_up_draft_files() self.assertTrue(not os.path.exists(os.path.join(settings.INTERNET_DRAFT_PATH, txt))) + self.assertFalse(exists_in_storage("active-draft", f"txt/{txt}")) self.assertTrue(os.path.exists(os.path.join(settings.INTERNET_DRAFT_ARCHIVE_DIR, txt))) @@ -824,7 +876,7 @@ def test_expire_last_call(self): e = LastCallDocEvent(doc=draft, rev=draft.rev, type="sent_last_call", by=secretary) e.text = "Last call sent" - e.expires = datetime.datetime.now() + datetime.timedelta(days=14) + e.expires = timezone.now() + datetime.timedelta(days=14) e.save() self.assertEqual(len(list(get_expired_last_calls())), 0) @@ -832,7 +884,7 @@ def test_expire_last_call(self): # test expired e = LastCallDocEvent(doc=draft, rev=draft.rev, type="sent_last_call", by=secretary) e.text = "Last call sent" - e.expires = datetime.datetime.now() + e.expires = timezone.now() e.save() drafts = list(get_expired_last_calls()) @@ -866,7 +918,7 @@ def test_expire_last_call_with_downref(self): e = LastCallDocEvent(doc=draft, rev=draft.rev, type="sent_last_call", by=secretary) e.text = "Last call sent" e.desc = "Blah, blah, blah.\n\nThis document makes the following downward references (downrefs):\n ** Downref: Normative reference to an Experimental RFC: RFC 4764" - e.expires = datetime.datetime.now() + e.expires = timezone.now() e.save() drafts = list(get_expired_last_calls()) @@ -888,6 +940,7 @@ def setUp(self): super().setUp() doc = WgDraftFactory(group__acronym='mars',shepherd=PersonFactory(user__username='plain',name='Plain Man').email_set.first()) self.docname = doc.name + self.doc_group = doc.group def test_doc_change_stream(self): url = urlreverse('ietf.doc.views_draft.change_stream', kwargs=dict(name=self.docname)) @@ -928,7 +981,7 @@ def test_doc_change_notify(self): r = self.client.get(url) self.assertEqual(r.status_code,200) q = PyQuery(r.content) - self.assertEqual(len(q('form input[name=notify]')),1) + self.assertEqual(len(q('form textarea[name=notify]')), 1) # Provide a list r = self.client.post(url,dict(notify="TJ2APh2P@ietf.org",save_addresses="1")) @@ -943,7 +996,7 @@ def test_doc_change_notify(self): # Regenerate does not save! self.assertEqual(doc.notify,'TJ2APh2P@ietf.org') q = PyQuery(r.content) - self.assertEqual(None,q('form input[name=notify]')[0].value) + self.assertEqual("", q('form textarea[name=notify]')[0].value.strip()) def test_doc_change_intended_status(self): url = urlreverse('ietf.doc.views_draft.change_intention', kwargs=dict(name=self.docname)) @@ -1004,23 +1057,6 @@ def test_doc_change_telechat_date(self): doc = Document.objects.get(name=self.docname) self.assertEqual(doc.latest_event(TelechatDocEvent, "scheduled_for_telechat").telechat_date,None) - def test_doc_change_iesg_note(self): - url = urlreverse('ietf.doc.views_draft.edit_iesg_note', kwargs=dict(name=self.docname)) - login_testing_unauthorized(self, "secretary", url) - - # get - r = self.client.get(url) - self.assertEqual(r.status_code,200) - q = PyQuery(r.content) - self.assertEqual(len(q('[type=submit]:contains("Save")')),1) - - # post - r = self.client.post(url,dict(note='ZpyQFGmA\r\nZpyQFGmA')) - self.assertEqual(r.status_code,302) - doc = Document.objects.get(name=self.docname) - self.assertEqual(doc.note,'ZpyQFGmA\nZpyQFGmA') - self.assertTrue('ZpyQFGmA' in doc.latest_event(DocEvent,type='added_comment').desc) - def test_doc_change_ad(self): url = urlreverse('ietf.doc.views_draft.edit_ad', kwargs=dict(name=self.docname)) login_testing_unauthorized(self, "secretary", url) @@ -1289,8 +1325,10 @@ def do_doc_change_action_holders_test(self, username): RoleFactory(name_id='techadv', person=PersonFactory(), group=doc.group) RoleFactory(name_id='editor', person=PersonFactory(), group=doc.group) RoleFactory(name_id='secr', person=PersonFactory(), group=doc.group) - + some_other_chair = RoleFactory(name_id="chair").person + url = urlreverse('ietf.doc.views_doc.edit_action_holders', kwargs=dict(name=doc.name)) + login_testing_unauthorized(self, some_other_chair.user.username, url) # other chair can't edit action holders login_testing_unauthorized(self, username, url) r = self.client.get(url) @@ -1330,9 +1368,17 @@ def _test_changing_ah(action_holders, reason): _test_changing_ah([doc.ad, doc.shepherd.person], 'this is a first test') _test_changing_ah([doc.ad], 'this is a second test') - _test_changing_ah(doc.authors(), 'authors can do it, too') + _test_changing_ah(doc.author_persons(), 'authors can do it, too') _test_changing_ah([], 'clear it back out') + def test_doc_change_action_holders_as_doc_manager(self): + # create a test RoleName and put it in the docman_roles for the document group + RoleName.objects.create(slug="wrangler", name="Wrangler", used=True) + self.doc_group.features.docman_roles.append("wrangler") + self.doc_group.features.save() + wrangler = RoleFactory(group=self.doc_group, name_id="wrangler").person + self.do_doc_change_action_holders_test(wrangler.user.username) + def test_doc_change_action_holders_as_secretary(self): self.do_doc_change_action_holders_test('secretary') @@ -1342,9 +1388,11 @@ def test_doc_change_action_holders_as_ad(self): def do_doc_remind_action_holders_test(self, username): doc = Document.objects.get(name=self.docname) doc.action_holders.set(PersonFactory.create_batch(3)) - + some_other_chair = RoleFactory(name_id="chair").person + url = urlreverse('ietf.doc.views_doc.remind_action_holders', kwargs=dict(name=doc.name)) + login_testing_unauthorized(self, some_other_chair.user.username, url) # other chair can't send reminder login_testing_unauthorized(self, username, url) r = self.client.get(url) self.assertEqual(r.status_code, 200) @@ -1371,6 +1419,14 @@ def do_doc_remind_action_holders_test(self, username): self.client.post(url) self.assertEqual(len(outbox), 1) # still 1 + def test_doc_remind_action_holders_as_doc_manager(self): + # create a test RoleName and put it in the docman_roles for the document group + RoleName.objects.create(slug="wrangler", name="Wrangler", used=True) + self.doc_group.features.docman_roles.append("wrangler") + self.doc_group.features.save() + wrangler = RoleFactory(group=self.doc_group, name_id="wrangler").person + self.do_doc_remind_action_holders_test(wrangler.user.username) + def test_doc_remind_action_holders_as_ad(self): self.do_doc_remind_action_holders_test('ad') @@ -1453,14 +1509,47 @@ def test_confirm_submission(self): self.assertTrue("aread@" in outbox[-1]['To']) self.assertTrue("iesg-secretary@" in outbox[-1]['Cc']) + def test_confirm_submission_no_doc_ad(self): + url = urlreverse('ietf.doc.views_draft.to_iesg', kwargs=dict(name=self.docname)) + self.client.login(username="marschairman", password="marschairman+password") + + doc = Document.objects.get(name=self.docname) + RoleFactory(name_id='ad', group=doc.group, person=doc.ad) + e = DocEvent(type="changed_document", by=doc.ad, doc=doc, rev=doc.rev, desc="Remove doc AD") + e.save() + doc.ad = None + doc.save_with_history([e]) + + docevents_pre = set(doc.docevent_set.all()) + mailbox_before = len(outbox) + + r = self.client.post(url, dict(confirm="1")) + self.assertEqual(r.status_code, 302) + + doc = Document.objects.get(name=self.docname) + self.assertTrue(doc.get_state('draft-iesg').slug=='pub-req') + self.assertTrue(doc.get_state('draft-stream-ietf').slug=='sub-pub') + + self.assertCountEqual(doc.action_holders.all(), [doc.ad]) + + new_docevents = set(doc.docevent_set.all()) - docevents_pre + self.assertEqual(len(new_docevents), 5) + new_docevent_type_count = Counter([e.type for e in new_docevents]) + self.assertEqual(new_docevent_type_count['changed_state'],2) + self.assertEqual(new_docevent_type_count['started_iesg_process'],1) + self.assertEqual(new_docevent_type_count['changed_action_holders'], 1) + self.assertEqual(new_docevent_type_count['changed_document'], 1) + + self.assertEqual(len(outbox), mailbox_before + 1) + self.assertTrue("Publication has been requested" in outbox[-1]['Subject']) + self.assertTrue("aread@" in outbox[-1]['To']) + self.assertTrue("iesg-secretary@" in outbox[-1]['Cc']) + class RequestPublicationTests(TestCase): - @mock.patch('ietf.sync.rfceditor.requests.post', autospec=True) - def test_request_publication(self, mockobj): - mockobj.return_value.text = b'OK' - mockobj.return_value.status_code = 200 - # + def test_request_publication(self): + draft = IndividualDraftFactory(stream_id='iab',group__acronym='iab',intended_std_level_id='inf',states=[('draft-stream-iab','approved')]) url = urlreverse('ietf.doc.views_draft.request_publication', kwargs=dict(name=draft.name)) @@ -1579,84 +1668,203 @@ def test_release_ise_draft(self): class AdoptDraftTests(TestCase): def test_adopt_document(self): - RoleFactory(group__acronym='mars',group__list_email='mars-wg@ietf.org',person__user__username='marschairman',name_id='chair') - draft = IndividualDraftFactory(name='draft-ietf-mars-test',notify='aliens@example.mars') - - url = urlreverse('ietf.doc.views_draft.adopt_draft', kwargs=dict(name=draft.name)) - login_testing_unauthorized(self, "marschairman", url) - - # get - r = self.client.get(url) - self.assertEqual(r.status_code, 200) - q = PyQuery(r.content) - self.assertEqual(len(q('form select[name="group"] option')), 1) # we can only select "mars" - - # adopt in mars WG - mailbox_before = len(outbox) - events_before = draft.docevent_set.count() - mars = Group.objects.get(acronym="mars") - call_issued = State.objects.get(type='draft-stream-ietf',slug='c-adopt') - r = self.client.post(url, - dict(comment="some comment", - group=mars.pk, - newstate=call_issued.pk, - weeks="10")) - self.assertEqual(r.status_code, 302) - - draft = Document.objects.get(pk=draft.pk) - self.assertEqual(draft.group.acronym, "mars") - self.assertEqual(draft.stream_id, "ietf") - self.assertEqual(draft.docevent_set.count() - events_before, 5) - self.assertEqual(draft.notify,"aliens@example.mars") - self.assertEqual(len(outbox), mailbox_before + 1) - self.assertTrue("Call For Adoption" in outbox[-1]["Subject"]) - self.assertTrue("mars-chairs@ietf.org" in outbox[-1]['To']) - self.assertTrue("draft-ietf-mars-test@" in outbox[-1]['To']) - self.assertTrue("mars-wg@" in outbox[-1]['To']) - - self.assertFalse(mars.list_email in draft.notify) - - def test_right_state_choices_offered(self): - draft = IndividualDraftFactory() - wg = GroupFactory(type_id='wg',state_id='active') - rg = GroupFactory(type_id='rg',state_id='active') - person = PersonFactory(user__username='person') + stream_state_type_slug = { + "wg": "draft-stream-ietf", + "ag": "draft-stream-ietf", + "rg": "draft-stream-irtf", + "rag": "draft-stream-irtf", + "edwg": "draft-stream-editorial", + } + for type_id in ("wg", "ag", "rg", "rag", "edwg"): + chair_role = RoleFactory(group__type_id=type_id,name_id='chair') + draft = IndividualDraftFactory(notify=f'{type_id}group@example.mars') + + url = urlreverse('ietf.doc.views_draft.adopt_draft', kwargs=dict(name=draft.name)) + self.client.logout() + login_testing_unauthorized(self, chair_role.person.user.username, url) + + # get + r = self.client.get(url) + self.assertEqual(r.status_code, 200) - self.client.login(username='person',password='person+password') - url = urlreverse('ietf.doc.views_draft.adopt_draft', kwargs=dict(name=draft.name)) + # call for adoption + group_type_can_call_for_adoption = State.objects.filter(type_id=stream_state_type_slug[type_id],slug="c-adopt").exists() + if group_type_can_call_for_adoption: + empty_outbox() + events_before = draft.docevent_set.count() + call_issued = State.objects.get(type=stream_state_type_slug[type_id],slug='c-adopt') + r = self.client.post(url, + dict(comment="some comment", + group=chair_role.group.pk, + newstate=call_issued.pk, + weeks="10")) + self.assertEqual(r.status_code, 302) + + draft = Document.objects.get(pk=draft.pk) + self.assertEqual(draft.get_state_slug(stream_state_type_slug[type_id]), "c-adopt") + self.assertEqual(draft.group, chair_role.group) + self.assertEqual(draft.stream_id, stream_state_type_slug[type_id][13:]) # trim off "draft-stream-" + self.assertEqual(draft.docevent_set.count() - events_before, 5) + self.assertEqual(len(outbox), 1) + # contents of outbox[1] are tested elsewhere + + # adopt + empty_outbox() + events_before = draft.docevent_set.count() + # There are several possible states that a stream can adopt into - we will only test one per stream + stream_adopt_state_slug = "wg-doc" if type_id in ("wg", "ag") else "active" + stream_adopt_state = State.objects.get(type=stream_state_type_slug[type_id],slug=stream_adopt_state_slug) + r = self.client.post(url, + dict(comment="some comment", + group=chair_role.group.pk, + newstate=stream_adopt_state.pk, + weeks="10")) + self.assertEqual(r.status_code, 302) - person.role_set.create(name_id='chair',group=wg,email=person.email()) - r = self.client.get(url) - q = PyQuery(r.content) - self.assertTrue('(IETF)' in q('#id_newstate option').text()) - self.assertFalse('(IRTF)' in q('#id_newstate option').text()) + draft = Document.objects.get(pk=draft.pk) + self.assertEqual(draft.get_state_slug(stream_state_type_slug[type_id]), stream_adopt_state_slug) + self.assertEqual(draft.group, chair_role.group) + self.assertEqual(draft.stream_id, stream_state_type_slug[type_id][13:]) # trim off "draft-stream-" + if type_id in ("wg", "ag"): + self.assertEqual( + Counter(list(draft.docevent_set.values_list('type',flat=True))[events_before:]), + Counter({'changed_group': 1, 'changed_stream': 1, 'new_revision': 1}) + ) + else: + self.assertEqual( + Counter(list(draft.docevent_set.values_list('type',flat=True))[events_before:]), + Counter({'changed_state': 1, 'added_comment': 1, 'changed_group': 1, 'changed_document': 1, 'changed_stream': 1, 'new_revision': 1}) + ) + self.assertEqual(len(outbox), 1 if type_id in ["wg", "ag"] else 2) + self.assertTrue(stream_adopt_state.name in outbox[-1]["Subject"]) + self.assertTrue(f"{chair_role.group.acronym}-chairs@" in outbox[-1]['To']) + self.assertTrue(f"{draft.name}@" in outbox[-1]['To']) + self.assertTrue(f"{chair_role.group.acronym}@" in outbox[-1]['To']) + if type_id not in ["wg", "ag"]: + self.assertTrue(outbox[-2]["Subject"].endswith("to Informational")) + # recipient fields tested elsewhere + + +class AdoptDraftFormTests(TestCase): + def setUp(self): + super().setUp() + # test_data.py made a WG already, and made all the GroupFeatures + # This will detect changes in that assumption + self.chair_roles = { + "wg": Group.objects.filter( + type__features__acts_like_wg=True, state="active" + ) + .get() + .role_set.get(name_id="chair") + } + # This set of tests currently assumes all document adopting group types have "chair" in thier docman roles, + # and only tests that the form acts correctly for chairs. It should be expanded to use all the roles it finds + # in the group of docman roles (which comes from the production database by way of ietf/name/fixtures/names.json) + for type_id in ["ag", "rg", "rag", "edwg"]: + self.chair_roles[type_id] = RoleFactory( + group__type_id=type_id, name_id="chair" + ) - person.role_set.create(name_id='chair',group=Group.objects.get(acronym='irtf'),email=person.email()) - r = self.client.get(url) - q = PyQuery(r.content) - self.assertTrue('(IETF)' in q('#id_newstate option').text()) - self.assertTrue('(IRTF)' in q('#id_newstate option').text()) + def test_form_init(self): + secretariat = Person.objects.get(user__username="secretary") + f = AdoptDraftForm(user=secretariat.user) + form_offers_groups = f.fields["group"].queryset + self.assertEqual( + set(form_offers_groups.all()), + set( + Group.objects.filter(type__features__acts_like_wg=True, state="active") + ), + ) + self.assertEqual(form_offers_groups.count(), 5) + form_offers_states = State.objects.filter( + pk__in=[t[0] for t in f.fields["newstate"].choices[1:]] + ) + self.assertEqual( + Counter(form_offers_states.values_list("type_id", flat=True)), + Counter( + { + "draft-stream-irtf": 14, + "draft-stream-ietf": 12, + "draft-stream-editorial": 5, + } + ), + ) - person.role_set.filter(group__acronym='irtf').delete() - person.role_set.create(name_id='chair',group=rg,email=person.email()) - r = self.client.get(url) - q = PyQuery(r.content) - self.assertTrue('(IETF)' in q('#id_newstate option').text()) - self.assertTrue('(IRTF)' in q('#id_newstate option').text()) + irtf_chair = Person.objects.get(user__username="irtf-chair") + f = AdoptDraftForm(user=irtf_chair.user) + form_offers_groups = f.fields["group"].queryset + self.assertEqual( + set(form_offers_groups.all()), + set(Group.objects.filter(type_id__in=("rag", "rg"), state="active")), + ) + self.assertEqual(form_offers_groups.count(), 2) + form_offers_states = State.objects.filter( + pk__in=[t[0] for t in f.fields["newstate"].choices[1:]] + ) + self.assertEqual( + set(form_offers_states.values_list("type_id", flat=True)), + set(["draft-stream-irtf"]), + ) - person.role_set.filter(group=wg).delete() - r = self.client.get(url) - q = PyQuery(r.content) - self.assertFalse('(IETF)' in q('#id_newstate option').text()) - self.assertTrue('(IRTF)' in q('#id_newstate option').text()) + stream_state_type_slug = { + "wg": "draft-stream-ietf", + "ag": "draft-stream-ietf", + "rg": "draft-stream-irtf", + "rag": "draft-stream-irtf", + "edwg": "draft-stream-editorial", + } + for type_id in self.chair_roles: + f = AdoptDraftForm(user=self.chair_roles[type_id].person.user) + form_offers_groups = f.fields["group"].queryset + self.assertEqual(form_offers_groups.get(), self.chair_roles[type_id].group) + form_offers_states = State.objects.filter( + pk__in=[t[0] for t in f.fields["newstate"].choices[1:]] + ) + self.assertEqual( + set(form_offers_states.values_list("type_id", flat=True)), + set([stream_state_type_slug[type_id]]), + ) - person.role_set.all().delete() - person.role_set.create(name_id='secr',group=Group.objects.get(acronym='secretariat'),email=person.email()) - r = self.client.get(url) - q = PyQuery(r.content) - self.assertTrue('(IETF)' in q('#id_newstate option').text()) - self.assertTrue('(IRTF)' in q('#id_newstate option').text()) + edwgchair_role = self.chair_roles["edwg"] + RoleFactory(group__type_id="wg", person=edwgchair_role.person, name_id="chair") + RoleFactory(group__type_id="rg", person=edwgchair_role.person, name_id="chair") + f = AdoptDraftForm(user=edwgchair_role.person.user) + form_offers_groups = f.fields["group"].queryset + self.assertEqual( + set(form_offers_groups.values_list("type_id", flat=True)), + set(["edwg", "wg", "rg"]), + ) + self.assertEqual(form_offers_groups.count(), 3) + form_offers_states = State.objects.filter( + pk__in=[t[0] for t in f.fields["newstate"].choices[1:]] + ) + self.assertEqual( + set(form_offers_states.values_list("type_id", flat=True)), + set(["draft-stream-irtf", "draft-stream-ietf", "draft-stream-editorial"]), + ) + also_chairs_wg = RoleFactory( + group__type_id="wg", person=irtf_chair, name_id="chair" + ) + f = AdoptDraftForm(user=irtf_chair.user) + form_offers_groups = f.fields["group"].queryset + self.assertEqual( + set(form_offers_groups.all()), + set( + Group.objects.filter( + Q(type_id__in=("rag", "rg")) | Q(pk=also_chairs_wg.group.pk), + state="active", + ) + ), + ) + self.assertEqual(form_offers_groups.count(), 4) + form_offers_states = State.objects.filter( + pk__in=[t[0] for t in f.fields["newstate"].choices[1:]] + ) + self.assertEqual( + set(form_offers_states.values_list("type_id", flat=True)), + set(["draft-stream-irtf", "draft-stream-ietf"]), + ) class ChangeStreamStateTests(TestCase): def test_set_tags(self): @@ -1730,8 +1938,11 @@ def test_set_initial_state(self): self.assertEqual(draft.docevent_set.count() - events_before, 2) reminder = DocReminder.objects.filter(event__doc=draft, type="stream-s") self.assertEqual(len(reminder), 1) - due = datetime.datetime.now() + datetime.timedelta(weeks=10) - self.assertTrue(due - datetime.timedelta(days=1) <= reminder[0].due <= due + datetime.timedelta(days=1)) + due = timezone.now().astimezone(DEADLINE_TZINFO) + datetime.timedelta(weeks=10) + self.assertTrue( + due - datetime.timedelta(days=1) <= reminder[0].due <= due + datetime.timedelta(days=1), + f'Due date {reminder[0].due} should be {due} +/- 1 day' + ) self.assertEqual(len(outbox), 1) self.assertTrue("state changed" in outbox[0]["Subject"].lower()) self.assertTrue("mars-chairs@ietf.org" in outbox[0].as_string()) @@ -1775,13 +1986,405 @@ def test_set_state(self): self.assertEqual(draft.docevent_set.count() - events_before, 2) reminder = DocReminder.objects.filter(event__doc=draft, type="stream-s") self.assertEqual(len(reminder), 1) - due = datetime.datetime.now() + datetime.timedelta(weeks=10) - self.assertTrue(due - datetime.timedelta(days=1) <= reminder[0].due <= due + datetime.timedelta(days=1)) + due = timezone.now().astimezone(DEADLINE_TZINFO) + datetime.timedelta(weeks=10) + self.assertTrue( + due - datetime.timedelta(days=1) <= reminder[0].due <= due + datetime.timedelta(days=1), + f'Due date {reminder[0].due} should be {due} +/- 1 day' + ) self.assertEqual(len(outbox), 1) self.assertTrue("state changed" in outbox[0]["Subject"].lower()) self.assertTrue("mars-chairs@ietf.org" in outbox[0].as_string()) self.assertTrue("marsdelegate@ietf.org" in outbox[0].as_string()) + def test_set_stream_state_to_wglc(self): + def _form_presents_state_option(response, state): + q = PyQuery(response.content) + option = q(f"select#id_new_state option[value='{state.pk}']") + return len(option) != 0 + + doc = WgDraftFactory() + chair = RoleFactory(name_id="chair", group=doc.group).person + url = urlreverse( + "ietf.doc.views_draft.change_stream_state", + kwargs=dict(name=doc.name, state_type="draft-stream-ietf"), + ) + login_testing_unauthorized(self, chair.user.username, url) + r = self.client.get(url) + wglc_state = State.objects.get(type="draft-stream-ietf", slug="wg-lc") + doc.set_state(wglc_state) + StateDocEventFactory( + doc=doc, + state_type_id="draft-stream-ietf", + state=("draft-stream-ietf", "wg-lc"), + ) + self.assertEqual(doc.docevent_set.count(), 2) + r = self.client.get(url) + self.assertTrue(_form_presents_state_option(r, wglc_state)) + other_doc = WgDraftFactory() + self.client.logout() + url = urlreverse( + "ietf.doc.views_draft.change_stream_state", + kwargs=dict(name=other_doc.name, state_type="draft-stream-ietf"), + ) + login_testing_unauthorized(self, "secretary", url) + r = self.client.get(url) + self.assertTrue(_form_presents_state_option(r, wglc_state)) + + def test_wg_call_for_adoption_issued(self): + role = RoleFactory( + name_id="chair", + group__acronym="mars", + group__list_email="mars-wg@ietf.org", + person__user__username="marschairman", + person__name="WG Cháir Man", + ) + # First test the usual workflow through the manage adoption view + draft = IndividualDraftFactory() + url = urlreverse( + "ietf.doc.views_draft.adopt_draft", kwargs=dict(name=draft.name) + ) + login_testing_unauthorized(self, "marschairman", url) + empty_outbox() + call_issued = State.objects.get(type="draft-stream-ietf", slug="c-adopt") + r = self.client.post( + url, + dict( + comment="some comment", + group=role.group.pk, + newstate=call_issued.pk, + weeks="10", + ), + ) + self.assertEqual(r.status_code, 302) + self.assertEqual(len(outbox), 1) + # Test not entering a duration on the form + draft = IndividualDraftFactory() + url = urlreverse( + "ietf.doc.views_draft.adopt_draft", kwargs=dict(name=draft.name) + ) + empty_outbox() + call_issued = State.objects.get(type="draft-stream-ietf", slug="c-adopt") + r = self.client.post( + url, + dict( + comment="some comment", + group=role.group.pk, + newstate=call_issued.pk, + ), + ) + self.assertEqual(r.status_code, 302) + self.assertEqual(len(outbox), 1) + + # Test the less usual workflow of issuing a call for adoption + # of a document that's already in the ietf stream + draft = WgDraftFactory(group=role.group) + url = urlreverse( + "ietf.doc.views_draft.change_stream_state", + kwargs=dict(name=draft.name, state_type="draft-stream-ietf"), + ) + old_state = draft.get_state("draft-stream-%s" % draft.stream_id) + new_state = State.objects.get( + used=True, type="draft-stream-%s" % draft.stream_id, slug="c-adopt" + ) + self.assertNotEqual(old_state, new_state) + empty_outbox() + r = self.client.post( + url, + dict( + new_state=new_state.pk, + comment="some comment", + weeks="10", + tags=[ + t.pk + for t in draft.tags.filter( + slug__in=get_tags_for_stream_id(draft.stream_id) + ) + ], + ), + ) + self.assertEqual(r.status_code, 302) + self.assertEqual(len(outbox), 1) + draft = WgDraftFactory(group=role.group) + url = urlreverse( + "ietf.doc.views_draft.change_stream_state", + kwargs=dict(name=draft.name, state_type="draft-stream-ietf"), + ) + old_state = draft.get_state("draft-stream-%s" % draft.stream_id) + new_state = State.objects.get( + used=True, type="draft-stream-%s" % draft.stream_id, slug="c-adopt" + ) + self.assertNotEqual(old_state, new_state) + empty_outbox() + r = self.client.post( + url, + dict( + new_state=new_state.pk, + comment="some comment", + tags=[ + t.pk + for t in draft.tags.filter( + slug__in=get_tags_for_stream_id(draft.stream_id) + ) + ], + ), + ) + self.assertEqual(r.status_code, 302) + self.assertEqual(len(outbox), 1) + + def test_issue_wg_lc_form(self): + end_date = date_today(DEADLINE_TZINFO) + datetime.timedelta(days=1) + post = dict( + end_date=end_date, + to="foo@example.net, bar@example.com", + # Intentionally not passing cc + subject=f"garbage {end_date.isoformat()}", + body=f"garbage {end_date.isoformat()}", + ) + form = IssueWorkingGroupLastCallForm(post) + self.assertTrue(form.is_valid()) + post["end_date"] = date_today(DEADLINE_TZINFO) + form = IssueWorkingGroupLastCallForm(post) + self.assertFalse(form.is_valid()) + self.assertIn( + "End date must be later than today", + form.errors["end_date"], + "Form accepted a too-early date", + ) + post["end_date"] = end_date + datetime.timedelta(days=2) + form = IssueWorkingGroupLastCallForm(post) + self.assertFalse(form.is_valid()) + self.assertIn( + f"Last call end date ({post['end_date'].isoformat()}) not found in subject", + form.errors["subject"], + "form allowed subject without end_date", + ) + self.assertIn( + f"Last call end date ({post['end_date'].isoformat()}) not found in body", + form.errors["body"], + "form allowed body without end_date", + ) + + def test_issue_wg_lc(self): + def _assert_rejected(testcase, doc, person): + url = urlreverse( + "ietf.doc.views_draft.issue_wg_lc", kwargs=dict(name=doc.name) + ) + login_testing_unauthorized(testcase, person.user.username, url) + r = testcase.client.get(url) + testcase.assertEqual(r.status_code, 404) + testcase.client.logout() + + already_rfc = WgDraftFactory(states=[("draft", "rfc")]) + rfc_chair = RoleFactory(name_id="chair", group=already_rfc.group).person + _assert_rejected(self, already_rfc, rfc_chair) + rg_doc = RgDraftFactory() + rg_chair = RoleFactory(name_id="chair", group=rg_doc.group).person + _assert_rejected(self, rg_doc, rg_chair) + inwglc_doc = WgDraftFactory(states=[("draft-stream-ietf", "wg-lc")]) + inwglc_chair = RoleFactory(name_id="chair", group=inwglc_doc.group).person + _assert_rejected(self, inwglc_doc, inwglc_chair) + doc = WgDraftFactory() + chair = RoleFactory(name_id="chair", group=doc.group).person + url = urlreverse("ietf.doc.views_draft.issue_wg_lc", kwargs=dict(name=doc.name)) + login_testing_unauthorized(self, chair.user.username, url) + + # GET: check 200 and that the pre-populated body contains the archive URL + r = self.client.get(url) + self.assertEqual(r.status_code, 200) + q = PyQuery(r.content) + prefilled_body = q("textarea#id_body").text() + expected_archive_url = f"{settings.IETF_ID_ARCHIVE_URL}{doc.name}-{doc.rev}.txt" + self.assertIn( + expected_archive_url, + prefilled_body, + "Pre-populated body must contain the I-D archive .txt URL", + ) + + # Invalid POST: end_date in the past must not change state + bad_postdict = dict( + end_date=date_today(DEADLINE_TZINFO), + to=q("input#id_to").attr("value"), + subject=q("input#id_subject").attr("value"), + body=prefilled_body, + ) + r = self.client.post(url, bad_postdict) + self.assertEqual(r.status_code, 200, "Invalid POST should re-render the form") + self.assertNotEqual( + doc.get_state_slug("draft-stream-ietf"), + "wg-lc", + "State must not change on invalid POST", + ) + + postdict = dict() + postdict["end_date"] = q("input#id_end_date").attr("value") + postdict["to"] = q("input#id_to").attr("value") + ", extrato@example.org" + cc = q("input#id_cc").attr("value") + if cc is not None: + postdict["cc"] = cc + ", extracc@example.org" + else: + postdict["cc"] = "extracc@example.org" + postdict["subject"] = q("input#id_subject").attr("value") + " Extra Subject Words" + postdict["body"] = prefilled_body + "FGgqbQ$UNeXs" + empty_outbox() + r = self.client.post( + url, + postdict, + ) + self.assertEqual(r.status_code, 302) + doc.refresh_from_db() + self.assertEqual(doc.get_state_slug("draft-stream-ietf"), "wg-lc") + + # A StateDocEvent recording the transition must exist + self.assertTrue( + doc.docevent_set.filter(type="changed_state").exists(), + "Expected a changed_state event after issuing WG LC", + ) + + # A stream-s reminder must be active for the doc + self.assertTrue( + DocReminder.objects.filter( + event__doc=doc, type_id="stream-s", active=True + ).exists(), + "Expected an active stream-s reminder after issuing WG LC", + ) + + self.assertEqual(len(outbox), 2) + + # outbox[0] is the stream-state-changed notification + self.assertIn(doc.name, outbox[0]["Subject"]) + + # outbox[1] is the WGLC announcement sent to the WG list + self.assertIn(f"{doc.group.acronym}@ietf.org", outbox[1]["To"]) + self.assertIn("extrato@example.org", outbox[1]["To"]) + self.assertIn("extracc@example.org", outbox[1]["Cc"]) + self.assertIn("Extra Subject Words", outbox[1]["Subject"]) + self.assertIn("WG Last Call", outbox[1]["Subject"]) + body = get_payload_text(outbox[1]) + self.assertIn("disclosure obligations", body) + self.assertIn("FGgqbQ$UNeXs", body) + self.assertIn( + expected_archive_url, + body, + "WGLC email body must contain the I-D archive .txt URL", + ) + + def test_issue_wg_call_for_adoption_form(self): + end_date = date_today(DEADLINE_TZINFO) + datetime.timedelta(days=1) + post = dict( + end_date=end_date, + to="foo@example.net, bar@example.com", + # Intentionally not passing cc + subject=f"garbage {end_date.isoformat()}", + body=f"garbage {end_date.isoformat()}", + ) + form = IssueCallForAdoptionForm(post) + self.assertTrue(form.is_valid()) + post["end_date"] = date_today(DEADLINE_TZINFO) + form = IssueCallForAdoptionForm(post) + self.assertFalse(form.is_valid()) + self.assertIn( + "End date must be later than today", + form.errors["end_date"], + "Form accepted a too-early date", + ) + post["end_date"] = end_date + datetime.timedelta(days=2) + form = IssueCallForAdoptionForm(post) + self.assertFalse(form.is_valid()) + self.assertIn( + f"Call for adoption end date ({post['end_date'].isoformat()}) not found in subject", + form.errors["subject"], + "form allowed subject without end_date", + ) + self.assertIn( + f"Call for adoption end date ({post['end_date'].isoformat()}) not found in body", + form.errors["body"], + "form allowed body without end_date", + ) + + def test_issue_wg_call_for_adoption(self): + def _assert_rejected(testcase, doc, person, group=None): + target_acronym = group.acronym if group is not None else doc.group.acronym + url = urlreverse( + "ietf.doc.views_draft.issue_wg_call_for_adoption", + kwargs=dict(name=doc.name, acronym=target_acronym), + ) + login_testing_unauthorized(testcase, person.user.username, url) + r = testcase.client.get(url) + testcase.assertEqual(r.status_code, 403) + testcase.client.logout() + + def _verify_call_issued(testcase, doc, chair_role): + url = urlreverse( + "ietf.doc.views_draft.issue_wg_call_for_adoption", + kwargs=dict(name=doc.name, acronym=chair_role.group.acronym), + ) + login_testing_unauthorized(testcase, chair_role.person.user.username, url) + r = testcase.client.get(url) + testcase.assertEqual(r.status_code, 200) + q = PyQuery(r.content) + postdict = dict() + postdict["end_date"] = q("input#id_end_date").attr("value") + postdict["to"] = q("input#id_to").attr("value") + ", extrato@example.com" + self.assertIn(chair_role.group.list_email, postdict["to"]) + cc = q("input#id_cc").attr("value") + if cc is not None: + postdict["cc"] = cc + ", extracc@example.com" + else: + postdict["cc"] = "extracc@example.com" + postdict["subject"] = q("input#id_subject").attr("value") + " Extra Subject Words" + postdict["body"] = q("textarea#id_body").text() + "FGgqbQ$UNeXs" + empty_outbox() + r = testcase.client.post( + url, + postdict, + ) + testcase.assertEqual(r.status_code, 302) + doc.refresh_from_db() + self.assertEqual(doc.group, chair_role.group) + self.assertEqual(doc.get_state_slug("draft-stream-ietf"), "c-adopt") + self.assertEqual(len(outbox), 2) + self.assertIn(f"{doc.group.acronym}@ietf.org", outbox[1]["To"]) + self.assertIn("extrato@example.com", outbox[1]["To"]) + self.assertIn("extracc@example.com", outbox[1]["Cc"]) + self.assertIn("Call for adoption", outbox[1]["Subject"]) + self.assertIn("Extra Subject Words", outbox[1]["Subject"]) + body = get_payload_text(outbox[1]) + self.assertIn("disclosure obligations", body) + self.assertIn("FGgqbQ$UNeXs", body) + self.client.logout() + return doc + + already_rfc = WgDraftFactory(states=[("draft", "rfc")]) + rfc = WgRfcFactory(group=already_rfc.group) + already_rfc.relateddocument_set.create(relationship_id="became_rfc",target=rfc) + rfc_chair = RoleFactory(name_id="chair", group=already_rfc.group).person + _assert_rejected(self, already_rfc, rfc_chair) + rg_doc = RgDraftFactory() + rg_chair = RoleFactory(name_id="chair", group=rg_doc.group).person + _assert_rejected(self, rg_doc, rg_chair) + inwglc_doc = WgDraftFactory(states=[("draft-stream-ietf", "wg-lc")]) + inwglc_chair = RoleFactory(name_id="chair", group=inwglc_doc.group).person + _assert_rejected(self, inwglc_doc, inwglc_chair) + ind_doc = IndividualDraftFactory() + _assert_rejected(self, ind_doc, rg_chair, rg_doc.group) + + # Successful call issued for doc already in WG + doc = WgDraftFactory(states=[("draft-stream-ietf","wg-cand")]) + chair_role = RoleFactory(name_id="chair",group=doc.group) + _ = _verify_call_issued(self, doc, chair_role) + + # Successful call issued for doc not yet in WG + doc = IndividualDraftFactory() + chair_role = RoleFactory(name_id="chair",group__type_id="wg") + doc = _verify_call_issued(self, doc, chair_role) + self.assertEqual(doc.group, chair_role.group) + self.assertEqual(doc.stream_id, "ietf") + self.assertEqual(doc.get_state_slug("draft-stream-ietf"), "c-adopt") + self.assertCountEqual( + doc.docevent_set.values_list("type", flat=True), + ["changed_state", "changed_group", "changed_stream", "new_revision"] + ) + def test_pubreq_validation(self): role = RoleFactory(name_id='chair',group__acronym='mars',group__list_email='mars-wg@ietf.org',person__user__username='marschairman',person__name='WG Cháir Man') RoleFactory(name_id='delegate',group=role.group,person__user__email='marsdelegate@ietf.org') @@ -1826,7 +2429,7 @@ def setUp(self): name="draft-test-base-b", title="Base B", group=mars_wg, - expires = datetime.datetime.now() - datetime.timedelta(days = 365 - settings.INTERNET_DRAFT_DAYS_TO_EXPIRE), + expires = timezone.now() - datetime.timedelta(days = 365 - settings.INTERNET_DRAFT_DAYS_TO_EXPIRE), ) p = PersonFactory(name="baseb_author") e = Email.objects.create(address="baseb_author@example.com", person=p, origin=p.user.username) @@ -1868,7 +2471,7 @@ def test_change_replaces(self): # Post that says replacea replaces base a empty_outbox() - RelatedDocument.objects.create(source=self.replacea, target=self.basea.docalias.first(), + RelatedDocument.objects.create(source=self.replacea, target=self.basea, relationship=DocRelationshipName.objects.get(slug="possibly-replaces")) self.assertEqual(self.basea.get_state().slug,'active') r = self.client.post(url, dict(replaces=self.basea.pk)) @@ -1916,7 +2519,7 @@ def test_change_replaces(self): def test_review_possibly_replaces(self): - replaced = self.basea.docalias.first() + replaced = self.basea RelatedDocument.objects.create(source=self.replacea, target=replaced, relationship=DocRelationshipName.objects.get(slug="possibly-replaces")) @@ -1960,6 +2563,316 @@ def test_shepherd_writeup_generation(self): login_testing_unauthorized(self, "secretary", url) r = self.client.get(url) self.assertContains(r, "for Individual Documents", status_code=200) + r = self.client.post(url,dict(reset_text='')) + self.assertContains(r, "for Individual Documents", status_code=200) url = urlreverse('ietf.doc.views_draft.edit_shepherd_writeup', kwargs=dict(name=wg_draft.name)) r = self.client.get(url) self.assertContains(r, "for Group Documents", status_code=200) + r = self.client.post(url,dict(reset_text='')) + self.assertContains(r, "for Group Documents", status_code=200) + +class EditorialDraftMetadataTests(TestCase): + def test_editorial_metadata(self): + draft = EditorialDraftFactory() + url = urlreverse("ietf.doc.views_doc.document_main", kwargs=dict(name=draft.name)) + r = self.client.get(url) + q = PyQuery(r.content) + top_level_metadata_headings = q("tbody>tr>th:first-child").text() + self.assertNotIn("IESG", top_level_metadata_headings) + self.assertNotIn("IANA", top_level_metadata_headings) + +class IetfGroupActionHelperTests(TestCase): + def test_manage_adoption_routing(self): + draft = IndividualDraftFactory() + nobody = PersonFactory() + rgchair = RoleFactory(group__type_id="rg", name_id="chair").person + wgchair = RoleFactory(group__type_id="wg", name_id="chair").person + multichair = RoleFactory(group__type_id="rg", name_id="chair").person + RoleFactory(group__type_id="wg", person=multichair, name_id="chair") + ad = RoleFactory(group__type_id="area", name_id="ad").person + secretary = Role.objects.filter( + name_id="secr", group__acronym="secretariat" + ).first() + self.assertIsNotNone(secretary) + secretary = secretary.person + self.assertFalse( + has_role(rgchair.user, ["Secretariat", "Area Director", "WG Chair"]) + ) + url = urlreverse( + "ietf.doc.views_doc.document_main", kwargs={"name": draft.name} + ) + ask_about_ietf_link = urlreverse( + "ietf.doc.views_draft.ask_about_ietf_adoption_call", + kwargs={"name": draft.name}, + ) + non_ietf_adoption_link = urlreverse( + "ietf.doc.views_draft.adopt_draft", kwargs={"name": draft.name} + ) + for person in (None, nobody, rgchair, wgchair, multichair, ad, secretary): + if person is not None: + self.client.login( + username=person.user.username, + password=f"{person.user.username}+password", + ) + r = self.client.get(url) + self.assertEqual(r.status_code, 200) + q = PyQuery(r.content) + has_ask_about_ietf_link = len(q(f'a[href="{ask_about_ietf_link}"]')) != 0 + has_non_ietf_adoption_link = ( + len(q(f'a[href="{non_ietf_adoption_link}"]')) != 0 + ) + ask_about_r = self.client.get(ask_about_ietf_link) + ask_about_link_return_code = ask_about_r.status_code + if person == rgchair: + self.assertFalse(has_ask_about_ietf_link) + self.assertTrue(has_non_ietf_adoption_link) + self.assertEqual(ask_about_link_return_code, 403) + elif person in (ad, nobody, None): + self.assertFalse(has_ask_about_ietf_link) + self.assertFalse(has_non_ietf_adoption_link) + self.assertEqual( + ask_about_link_return_code, 302 if person is None else 403 + ) + else: + self.assertTrue(has_ask_about_ietf_link) + self.assertFalse(has_non_ietf_adoption_link) + self.assertEqual(ask_about_link_return_code, 200) + self.client.logout() + + def test_ask_about_ietf_adoption_call(self): + # Basic permission tests above + doc = IndividualDraftFactory() + self.assertEqual(doc.docevent_set.count(), 1) + chair_role = RoleFactory(group__type_id="wg", name_id="chair") + chair = chair_role.person + group = chair_role.group + othergroup = GroupFactory(type_id="wg") + url = urlreverse( + "ietf.doc.views_draft.ask_about_ietf_adoption_call", + kwargs={"name": doc.name}, + ) + login_testing_unauthorized(self, chair.user.username, url) + r = self.client.post(url, {"group": othergroup.pk}) + self.assertEqual(r.status_code, 200) + r = self.client.post(url, {"group": group.pk}) + self.assertEqual(r.status_code, 302) + + def test_offer_wg_action_helpers(self): + def _assert_view_presents_buttons(testcase, response, expected): + q = PyQuery(response.content) + for id, expect in expected: + button = q(f"#{id}") + testcase.assertEqual( + len(button) != 0, + expect + ) + + # View rejects access + came_from_draft = WgDraftFactory(states=[("draft","rfc")]) + rfc = WgRfcFactory(group=came_from_draft.group) + came_from_draft.relateddocument_set.create(relationship_id="became_rfc",target=rfc) + rfc_chair = RoleFactory(name_id="chair", group=rfc.group).person + url = urlreverse("ietf.doc.views_draft.offer_wg_action_helpers", kwargs=dict(name=came_from_draft.name)) + login_testing_unauthorized(self, rfc_chair.user.username, url) + r = self.client.get(url) + self.assertEqual(r.status_code, 404) + self.client.logout() + rg_draft = RgDraftFactory() + rg_chair = RoleFactory(group=rg_draft.group, name_id="chair").person + url = urlreverse("ietf.doc.views_draft.offer_wg_action_helpers", kwargs=dict(name=rg_draft.name)) + login_testing_unauthorized(self, rg_chair.user.username, url) + r = self.client.get(url) + self.assertEqual(r.status_code,404) + self.client.logout() + + # View offers access + draft = WgDraftFactory() + chair = RoleFactory(group=draft.group, name_id="chair").person + url = urlreverse("ietf.doc.views_draft.offer_wg_action_helpers", kwargs=dict(name=draft.name)) + login_testing_unauthorized(self, chair.user.username, url) + r = self.client.get(url) + self.assertEqual(r.status_code,200) + _assert_view_presents_buttons( + self, + r, + [ + ("id_wgadopt_button", False), + ("id_wglc_button", True), + ("id_pubreq_button", True), + ], + ) + draft.set_state(State.objects.get(type_id="draft-stream-ietf", slug="wg-cand")) + r = self.client.get(url) + self.assertEqual(r.status_code,200) + _assert_view_presents_buttons( + self, + r, + [ + ("id_wgadopt_button", True), + ("id_wglc_button", False), + ("id_pubreq_button", False), + ], + ) + draft.set_state(State.objects.get(type_id="draft-stream-ietf", slug="wg-lc")) + StateDocEventFactory( + doc=draft, + state_type_id="draft-stream-ietf", + state=("draft-stream-ietf", "wg-lc"), + ) + self.assertEqual(draft.docevent_set.count(), 2) + r = self.client.get(url) + self.assertEqual(r.status_code,200) + _assert_view_presents_buttons( + self, + r, + [ + ("id_wgadopt_button", False), + ("id_wglc_button", False), + ("id_pubreq_button", True), + ], + ) + draft.set_state(State.objects.get(type_id="draft-stream-ietf",slug="chair-w")) + r = self.client.get(url) + self.assertEqual(r.status_code, 200) + _assert_view_presents_buttons( + self, + r, + [ + ("id_wgadopt_button", False), + ("id_wglc_button", True), + ("id_pubreq_button", True), + ], + ) + self.assertContains(response=r,text="Issue Another Working Group Last Call", status_code=200) + other_draft = WgDraftFactory() + self.client.logout() + url = urlreverse("ietf.doc.views_draft.offer_wg_action_helpers", kwargs=dict(name=other_draft.name)) + login_testing_unauthorized(self, "secretary", url) + r = self.client.get(url) + self.assertEqual(r.status_code, 200) + _assert_view_presents_buttons( + self, + r, + [ + ("id_wgadopt_button", False), + ("id_wglc_button", True), + ("id_pubreq_button", True), + ], + ) + self.assertContains( + response=r, text="Issue Working Group Last Call", status_code=200 + ) + +class BallotEmailAjaxTests(TestCase): + def test_ajax_build_position_email(self): + def _post_json(self, url, json_to_post): + r = self.client.post( + url, json.dumps(json_to_post), content_type="application/json" + ) + self.assertEqual(r.status_code, 200) + return json.loads(r.content) + + doc = WgDraftFactory() + ad = RoleFactory( + name_id="ad", group=doc.group, person__name="Some Areadirector" + ).person + url = urlreverse("ietf.doc.views_ballot.ajax_build_position_email") + login_testing_unauthorized(self, "secretary", url) + r = self.client.get(url) + self.assertEqual(r.status_code, 405) + response = _post_json(self, url, {}) + self.assertFalse(response["success"]) + self.assertEqual(response["errors"], ["post_data not provided"]) + response = _post_json(self, url, {"dictis": "not empty"}) + self.assertFalse(response["success"]) + self.assertEqual(response["errors"], ["post_data not provided"]) + response = _post_json(self, url, {"post_data": {}}) + self.assertFalse(response["success"]) + self.assertEqual(len(response["errors"]), 7) + response = _post_json( + self, + url, + { + "post_data": { + "discuss": "aaaaaa", + "comment": "bbbbbb", + "position": "discuss", + "balloter": Person.objects.aggregate(maxpk=Max("pk") + 1)["maxpk"], + "docname": "this-draft-does-not-exist", + "cc_choices": ["doc_group_mail_list"], + "additional_cc": "foo@example.com", + } + }, + ) + self.assertFalse(response["success"]) + self.assertEqual( + response["errors"], + ["No person found matching balloter", "No document found matching docname"], + ) + response = _post_json( + self, + url, + { + "post_data": { + "discuss": "aaaaaa", + "comment": "bbbbbb", + "position": "discuss", + "balloter": ad.pk, + "docname": doc.name, + "cc_choices": ["doc_group_mail_list"], + "additional_cc": "foo@example.com", + } + }, + ) + self.assertTrue(response["success"]) + for snippet in [ + "aaaaaa", + "bbbbbb", + "DISCUSS", + ad.plain_name(), + doc.name, + doc.group.list_email, + "foo@example.com", + ]: + self.assertIn(snippet, response["text"]) + + # Non-IETF stream: from address uses balloter.formatted_email(), not role_email("ad"). + # Give the balloter a chair role (in a different RG) with a distinct email to prove + # that chair role address is not used; formatted_email() uses the primary email. + irtf_doc = RgDraftFactory() + non_ad_balloter = PersonFactory(name="Some Irsgmember") + other_rg = GroupFactory(type_id="rg") + chair_role_email = EmailFactory( + person=non_ad_balloter, address="chair-role@example.com" + ) + RoleFactory( + name_id="chair", + group=other_rg, + person=non_ad_balloter, + email=chair_role_email, + ) + response = _post_json( + self, + url, + { + "post_data": { + "discuss": "", + "comment": "cccccc", + "position": "yes", + "balloter": non_ad_balloter.pk, + "docname": irtf_doc.name, + "cc_choices": [], + "additional_cc": "", + } + }, + ) + self.assertTrue(response["success"]) + from_line = next( + line for line in response["text"].split("\n") if line.startswith("From: ") + ) + # formatted_email() uses the primary email, not the chair role email + self.assertIn(non_ad_balloter.email().address, from_line) + self.assertNotIn(chair_role_email.address, from_line) + for snippet in ["cccccc", non_ad_balloter.plain_name(), irtf_doc.name]: + self.assertIn(snippet, response["text"]) + diff --git a/ietf/doc/tests_irsg_ballot.py b/ietf/doc/tests_irsg_ballot.py index f178bb4e56c..d96cf9dbefe 100644 --- a/ietf/doc/tests_irsg_ballot.py +++ b/ietf/doc/tests_irsg_ballot.py @@ -19,6 +19,7 @@ from ietf.person.utils import get_active_irsg, get_active_ads from ietf.group.factories import RoleFactory from ietf.person.models import Person +from ietf.utils.timezone import date_today, datetime_today, DEADLINE_TZINFO class IssueIRSGBallotTests(TestCase): @@ -254,7 +255,7 @@ def test_edit_ballot_position_permissions(self): irsgmember = get_active_irsg()[0] secr = RoleFactory(group__acronym='secretariat',name_id='secr') wg_ballot = create_ballot_if_not_open(None, wg_draft, ad.person, 'approve') - due = datetime.date.today()+datetime.timedelta(days=14) + due = datetime_today(DEADLINE_TZINFO) + datetime.timedelta(days=14) rg_ballot = create_ballot_if_not_open(None, rg_draft, secr.person, 'irsg-approve', due) url = urlreverse('ietf.doc.views_ballot.edit_position', kwargs=dict(name=wg_draft.name, ballot_id=wg_ballot.pk)) @@ -287,7 +288,7 @@ def test_edit_ballot_position_permissions(self): def test_iesg_ballot_no_irsg_actions(self): ad = Person.objects.get(user__username="ad") - wg_draft = IndividualDraftFactory(ad=ad) + wg_draft = IndividualDraftFactory(ad=ad, stream_id='ietf') irsgmember = get_active_irsg()[0] url = urlreverse('ietf.doc.views_ballot.ballot_writeupnotes', kwargs=dict(name=wg_draft.name)) @@ -323,7 +324,7 @@ class BaseManipulationTests(): def test_issue_ballot(self): draft = RgDraftFactory() url = urlreverse('ietf.doc.views_ballot.issue_irsg_ballot',kwargs=dict(name=draft.name)) - due = datetime.date.today()+datetime.timedelta(days=14) + due = date_today(DEADLINE_TZINFO)+datetime.timedelta(days=14) empty_outbox() login_testing_unauthorized(self, self.username , url) @@ -354,28 +355,35 @@ def test_issue_ballot(self): def test_take_and_email_position(self): draft = RgDraftFactory() ballot = IRSGBallotDocEventFactory(doc=draft) - url = urlreverse('ietf.doc.views_ballot.edit_position', kwargs=dict(name=draft.name, ballot_id=ballot.pk)) + self.balloter + url = ( + urlreverse( + "ietf.doc.views_ballot.edit_position", + kwargs=dict(name=draft.name, ballot_id=ballot.pk), + ) + + self.balloter + ) empty_outbox() login_testing_unauthorized(self, self.username, url) r = self.client.get(url) self.assertEqual(r.status_code, 200) - r = self.client.post(url, dict(position='yes', comment='oib239sb', send_mail='Save and send email')) + empty_outbox() + r = self.client.post( + url, + dict( + position="yes", + comment="oib239sb", + send_mail="Save and send email", + cc_choices=["doc_authors", "doc_group_chairs", "doc_group_mail_list"], + ), + ) self.assertEqual(r.status_code, 302) e = draft.latest_event(BallotPositionDocEvent) - self.assertEqual(e.pos.slug,'yes') - self.assertEqual(e.comment, 'oib239sb') - - url = urlreverse('ietf.doc.views_ballot.send_ballot_comment', kwargs=dict(name=draft.name, ballot_id=ballot.pk)) + self.balloter - - r = self.client.get(url) - self.assertEqual(r.status_code, 200) - - r = self.client.post(url, dict(cc_choices=['doc_authors','doc_group_chairs','doc_group_mail_list'], body="Stuff")) - self.assertEqual(r.status_code, 302) - self.assertEqual(len(outbox),1) - self.assertNotIn('discuss-criteria', get_payload_text(outbox[0])) + self.assertEqual(e.pos.slug, "yes") + self.assertEqual(e.comment, "oib239sb") + self.assertEqual(len(outbox), 1) + self.assertNotIn("discuss-criteria", get_payload_text(outbox[0])) def test_close_ballot(self): draft = RgDraftFactory() @@ -444,8 +452,8 @@ def setUp(self): def test_cant_issue_irsg_ballot(self): draft = RgDraftFactory() - due = datetime.date.today()+datetime.timedelta(days=14) - url = urlreverse('ietf.doc.views_ballot.close_irsg_ballot', kwargs=dict(name=draft.name)) + due = datetime_today(DEADLINE_TZINFO) + datetime.timedelta(days=14) + url = urlreverse('ietf.doc.views_ballot.issue_irsg_ballot', kwargs=dict(name=draft.name)) self.client.login(username = self.username, password = self.username+'+password') r = self.client.get(url) @@ -481,27 +489,31 @@ def test_cant_take_position_on_iesg_ballot(self): def test_take_and_email_position(self): draft = RgDraftFactory() ballot = IRSGBallotDocEventFactory(doc=draft) - url = urlreverse('ietf.doc.views_ballot.edit_position', kwargs=dict(name=draft.name, ballot_id=ballot.pk)) + url = urlreverse( + "ietf.doc.views_ballot.edit_position", + kwargs=dict(name=draft.name, ballot_id=ballot.pk), + ) empty_outbox() login_testing_unauthorized(self, self.username, url) r = self.client.get(url) self.assertEqual(r.status_code, 200) - r = self.client.post(url, dict(position='yes', comment='oib239sb', send_mail='Save and send email')) + r = self.client.post( + url, + dict( + position="yes", + comment="oib239sb", + send_mail="Save and send email", + cc_choices=["doc_authors", "doc_group_chairs", "doc_group_mail_list"], + ), + ) self.assertEqual(r.status_code, 302) e = draft.latest_event(BallotPositionDocEvent) - self.assertEqual(e.pos.slug,'yes') - self.assertEqual(e.comment, 'oib239sb') - - url = urlreverse('ietf.doc.views_ballot.send_ballot_comment', kwargs=dict(name=draft.name, ballot_id=ballot.pk)) - - r = self.client.get(url) - self.assertEqual(r.status_code, 200) - - r = self.client.post(url, dict(cc_choices=['doc_authors','doc_group_chairs','doc_group_mail_list'], body="Stuff")) + self.assertEqual(e.pos.slug, "yes") + self.assertEqual(e.comment, "oib239sb") self.assertEqual(r.status_code, 302) - self.assertEqual(len(outbox),1) + self.assertEqual(len(outbox), 1) class IESGMemberTests(TestCase): diff --git a/ietf/doc/tests_js.py b/ietf/doc/tests_js.py index 02daaae9048..9a5aad13b9c 100644 --- a/ietf/doc/tests_js.py +++ b/ietf/doc/tests_js.py @@ -41,7 +41,7 @@ def _fill_in_author_form(form_elt, name, email, affiliation, country): (By.CSS_SELECTOR, result_selector), name )) - input.send_keys('\n') # select the object + self.driver.find_element(By.CSS_SELECTOR, result_selector).click() # After the author is selected, the email select options will be populated. # Wait for that, then click on the option corresponding to the requested email. @@ -92,12 +92,8 @@ def _read_author_form(form_elt): self.assertEqual(len(author_forms), 1) # get the "add author" button so we can add blank author forms - add_author_button = self.driver.find_element(By.ID, 'add-author-button') for index, auth in enumerate(authors): - self.driver.execute_script("arguments[0].scrollIntoView();", add_author_button) # FIXME: no idea why this fails: - # self.scroll_to_element(add_author_button) # Can only click if it's in view! - self.driver.execute_script("arguments[0].click();", add_author_button) # FIXME: no idea why this fails: - # add_author_button.click() # Create a new form. Automatically scrolls to it. + self.scroll_and_click((By.ID, 'add-author-button')) # Create new form. Automatically scrolls to it. author_forms = authors_list.find_elements(By.CLASS_NAME, 'author-panel') authors_added = index + 1 self.assertEqual(len(author_forms), authors_added + 1) # Started with 1 author, hence +1 @@ -118,10 +114,9 @@ def _read_author_form(form_elt): # Must provide a "basis" (change reason) self.driver.find_element(By.ID, 'id_basis').send_keys('change testing') # Now click the 'submit' button and check that the update was accepted. - submit_button = self.driver.find_element(By.CSS_SELECTOR, 'button[type="submit"]') - self.driver.execute_script("arguments[0].click();", submit_button) # FIXME: no idea why this fails: - # self.scroll_to_element(submit_button) - # submit_button.click() + submit_button = self.driver.find_element(By.CSS_SELECTOR, '#content button[type="submit"]') + self.scroll_to_element(submit_button) + submit_button.click() # Wait for redirect to the document_main view self.wait.until( expected_conditions.url_to_be( @@ -132,4 +127,4 @@ def _read_author_form(form_elt): self.assertEqual( list(draft.documentauthor_set.values_list('person', flat=True)), [first_auth.person.pk] + [auth.pk for auth in authors] - ) \ No newline at end of file + ) diff --git a/ietf/doc/tests_material.py b/ietf/doc/tests_material.py index 1e922197d52..04779bdaf14 100644 --- a/ietf/doc/tests_material.py +++ b/ietf/doc/tests_material.py @@ -4,21 +4,24 @@ import os import shutil -import datetime import io +from unittest.mock import call, patch from pathlib import Path from pyquery import PyQuery import debug # pyflakes:ignore from django.conf import settings +from django.test import override_settings from django.urls import reverse as urlreverse +from django.utils import timezone -from ietf.doc.models import Document, State, DocAlias, NewRevisionDocEvent +from ietf.doc.models import Document, State, NewRevisionDocEvent +from ietf.doc.storage_utils import retrieve_str from ietf.group.factories import RoleFactory from ietf.group.models import Group -from ietf.meeting.factories import MeetingFactory, SessionFactory +from ietf.meeting.factories import MeetingFactory, SessionFactory, SessionPresentationFactory from ietf.meeting.models import Meeting, SessionPresentation, SchedulingEvent from ietf.name.models import SessionStatusName from ietf.person.models import Person @@ -26,7 +29,7 @@ class GroupMaterialTests(TestCase): - settings_temp_path_overrides = TestCase.settings_temp_path_overrides + ['AGENDA_PATH'] + settings_temp_path_overrides = TestCase.settings_temp_path_overrides + ['AGENDA_PATH', 'FTP_DIR'] def setUp(self): super().setUp() self.materials_dir = self.tempdir("materials") @@ -35,6 +38,10 @@ def setUp(self): self.slides_dir.mkdir() self.saved_document_path_pattern = settings.DOCUMENT_PATH_PATTERN settings.DOCUMENT_PATH_PATTERN = self.materials_dir + "/{doc.type_id}/" + self.assertTrue(Path(settings.FTP_DIR).exists()) + ftp_slides_dir = Path(settings.FTP_DIR) / "slides" + if not ftp_slides_dir.exists(): + ftp_slides_dir.mkdir() self.meeting_slides_dir = Path(settings.AGENDA_PATH) / "42" / "slides" if not self.meeting_slides_dir.exists(): @@ -54,7 +61,6 @@ def create_slides(self): doc = Document.objects.create(name="slides-testteam-test-file", rev="01", type_id="slides", group=group) doc.set_state(State.objects.get(type="slides", slug="active")) doc.set_state(State.objects.get(type="reuse_policy", slug="multiple")) - DocAlias.objects.create(name=doc.name).docs.add(doc) NewRevisionDocEvent.objects.create(doc=doc,by=Person.objects.get(name="(System)"),rev='00',type='new_revision',desc='New revision available') NewRevisionDocEvent.objects.create(doc=doc,by=Person.objects.get(name="(System)"),rev='01',type='new_revision',desc='New revision available') @@ -111,8 +117,16 @@ def test_upload_slides(self): self.assertEqual(doc.title, "Test File - with fancy title") self.assertEqual(doc.get_state_slug(), "active") - with io.open(os.path.join(self.materials_dir, "slides", doc.name + "-" + doc.rev + ".pdf")) as f: + basename=f"{doc.name}-{doc.rev}.pdf" + filepath=Path(self.materials_dir) / "slides" / basename + with filepath.open() as f: self.assertEqual(f.read(), content) + ftp_filepath=Path(settings.FTP_DIR) / "slides" / basename + with ftp_filepath.open() as f: + self.assertEqual(f.read(), content) + # This test is very sloppy wrt the actual file content. + # Working with/around that for the moment. + self.assertEqual(retrieve_str("slides", basename), content) # check that posting same name is prevented test_file.seek(0) @@ -136,26 +150,54 @@ def test_change_state(self): doc = Document.objects.get(name=doc.name) self.assertEqual(doc.get_state_slug(), "deleted") - def test_edit_title(self): + @override_settings(MEETECHO_API_CONFIG="fake settings") + @patch("ietf.doc.views_material.SlidesManager") + def test_edit_title(self, mock_slides_manager_cls): doc = self.create_slides() url = urlreverse('ietf.doc.views_material.edit_material', kwargs=dict(name=doc.name, action="title")) login_testing_unauthorized(self, "secretary", url) + self.assertFalse(mock_slides_manager_cls.called) # post r = self.client.post(url, dict(title="New title")) self.assertEqual(r.status_code, 302) doc = Document.objects.get(name=doc.name) self.assertEqual(doc.title, "New title") + self.assertFalse(mock_slides_manager_cls.return_value.send_update.called) + + # assign to a session to see that it now sends updates to Meetecho + session = SessionPresentationFactory(session__group=doc.group, document=doc).session + + # Grab the title on the slides when the API call was made (to be sure it's not before it was updated) + titles_sent = [] + mock_slides_manager_cls.return_value.send_update.side_effect = lambda sess: titles_sent.extend( + list(sess.presentations.values_list("document__title", flat=True)) + ) + + r = self.client.post(url, dict(title="Newer title")) + self.assertEqual(r.status_code, 302) + doc = Document.objects.get(name=doc.name) + self.assertEqual(doc.title, "Newer title") + self.assertTrue(mock_slides_manager_cls.called) + self.assertEqual(mock_slides_manager_cls.call_args, call(api_config="fake settings")) + self.assertEqual(mock_slides_manager_cls.return_value.send_update.call_count, 1) + self.assertEqual( + mock_slides_manager_cls.return_value.send_update.call_args, + call(session), + ) + self.assertEqual(titles_sent, ["Newer title"]) - def test_revise(self): + @override_settings(MEETECHO_API_CONFIG="fake settings") + @patch("ietf.doc.views_material.SlidesManager") + def test_revise(self, mock_slides_manager_cls): doc = self.create_slides() session = SessionFactory( name = "session-42-mars-1", meeting = Meeting.objects.get(number='42'), group = Group.objects.get(acronym='mars'), - modified = datetime.datetime.now(), + modified = timezone.now(), ) SchedulingEvent.objects.create( session=session, @@ -166,11 +208,18 @@ def test_revise(self): url = urlreverse('ietf.doc.views_material.edit_material', kwargs=dict(name=doc.name, action="revise")) login_testing_unauthorized(self, "secretary", url) + self.assertFalse(mock_slides_manager_cls.called) content = "some text" test_file = io.StringIO(content) test_file.name = "unnamed.txt" + # Grab the title on the slides when the API call was made (to be sure it's not before it was updated) + titles_sent = [] + mock_slides_manager_cls.return_value.send_update.side_effect = lambda sess: titles_sent.extend( + list(sess.presentations.values_list("document__title", flat=True)) + ) + # post r = self.client.post(url, dict(title="New title", abstract="New abstract", @@ -181,7 +230,17 @@ def test_revise(self): self.assertEqual(doc.rev, "02") self.assertEqual(doc.title, "New title") self.assertEqual(doc.get_state_slug(), "active") + self.assertTrue(mock_slides_manager_cls.called) + self.assertEqual(mock_slides_manager_cls.call_args, call(api_config="fake settings")) + self.assertEqual(mock_slides_manager_cls.return_value.send_update.call_count, 1) + self.assertEqual( + mock_slides_manager_cls.return_value.send_update.call_args, + call(session), + ) + self.assertEqual(titles_sent, ["New title"]) with io.open(os.path.join(doc.get_file_path(), doc.name + "-" + doc.rev + ".txt")) as f: self.assertEqual(f.read(), content) + self.assertEqual(retrieve_str("slides", f"{doc.name}-{doc.rev}.txt"), content) + diff --git a/ietf/doc/tests_models.py b/ietf/doc/tests_models.py new file mode 100644 index 00000000000..d835f646fb6 --- /dev/null +++ b/ietf/doc/tests_models.py @@ -0,0 +1,113 @@ +# Copyright The IETF Trust 2016-2023, All Rights Reserved +# -*- coding: utf-8 -*- + +import itertools + +from ietf.doc.factories import WgRfcFactory +from ietf.doc.models import RelatedDocument +from ietf.utils.test_utils import TestCase + + +class RelatedDocumentTests(TestCase): + def test_is_downref(self): + rfcs = [ + WgRfcFactory(std_level_id=lvl) + for lvl in ["inf", "exp", "bcp", "ps", "ds", "std", "unkn"] + ] + + result_matrix = { + # source + "inf": { + "inf": None, # target + "exp": None, # target + "bcp": None, # target + "ps": None, # target + "ds": None, # target + "std": None, # target + "unkn": None, # target + }, + # source + "exp": { + "inf": None, # target + "exp": None, # target + "bcp": None, # target + "ps": None, # target + "ds": None, # target + "std": None, # target + "unkn": None, # target + }, + # source + "bcp": { + "inf": "Downref", # target + "exp": "Downref", # target + "bcp": None, # target + "ps": None, # target + "ds": None, # target + "std": None, # target + "unkn": "Possible Downref", # target + }, + # source + "ps": { + "inf": "Downref", # target + "exp": "Downref", # target + "bcp": None, # target + "ps": None, # target + "ds": None, # target + "std": None, # target + "unkn": "Possible Downref", # target + }, + # source + "ds": { + "inf": "Downref", # target + "exp": "Downref", # target + "bcp": None, # target + "ps": "Downref", # target + "ds": None, # target + "std": None, # target + "unkn": "Possible Downref", # target + }, + # source + "std": { + "inf": "Downref", # target + "exp": "Downref", # target + "bcp": None, # target + "ps": "Downref", # target + "ds": "Downref", # target + "std": None, # target + "unkn": "Possible Downref", # target + }, + # source + "unkn": { + "inf": None, # target + "exp": None, # target + "bcp": None, # target + "ps": "Possible Downref", # target + "ds": "Possible Downref", # target + "std": None, # target + "unkn": "Possible Downref", # target + }, + } + + for rel in ["refnorm", "refinfo", "refunk", "refold"]: + for source, target in itertools.product(rfcs, rfcs): + ref = RelatedDocument.objects.create( + source=source, + target=target, + relationship_id=rel, + ) + + result = ref.is_downref() + + desired_result = ( + result_matrix[source.std_level_id][target.std_level_id] + if ref.relationship.slug in ["refnorm", "refunk"] + else None + ) + if ( + ref.relationship.slug == "refunk" + and desired_result is not None + and not desired_result.startswith("Possible") + ): + desired_result = f"Possible {desired_result}" + + self.assertEqual(desired_result, result) diff --git a/ietf/doc/tests_notprepped.py b/ietf/doc/tests_notprepped.py new file mode 100644 index 00000000000..f417aa79310 --- /dev/null +++ b/ietf/doc/tests_notprepped.py @@ -0,0 +1,122 @@ +# Copyright The IETF Trust 2026, All Rights Reserved + +from django.conf import settings +from django.utils import timezone +from django.urls import reverse as urlreverse + +from pyquery import PyQuery + +from ietf.doc.factories import WgRfcFactory +from ietf.doc.models import StoredObject +from ietf.doc.storage_utils import store_bytes +from ietf.utils.test_utils import TestCase + + +class NotpreppedRfcXmlTests(TestCase): + def test_editor_source_button_visibility(self): + pre_v3 = WgRfcFactory(rfc_number=settings.FIRST_V3_RFC - 1) + first_v3 = WgRfcFactory(rfc_number=settings.FIRST_V3_RFC) + post_v3 = WgRfcFactory(rfc_number=settings.FIRST_V3_RFC + 1) + + for rfc, expect_button in [(pre_v3, False), (first_v3, True), (post_v3, True)]: + r = self.client.get( + urlreverse( + "ietf.doc.views_doc.document_main", kwargs=dict(name=rfc.name) + ) + ) + self.assertEqual(r.status_code, 200) + buttons = PyQuery(r.content)('a.btn:contains("Get editor source")') + if expect_button: + self.assertEqual(len(buttons), 1, msg=f"rfc_number={rfc.rfc_number}") + expected_href = urlreverse( + "ietf.doc.views_doc.rfcxml_notprepped_wrapper", + kwargs=dict(number=rfc.rfc_number), + ) + self.assertEqual( + buttons.attr("href"), + expected_href, + msg=f"rfc_number={rfc.rfc_number}", + ) + else: + self.assertEqual(len(buttons), 0, msg=f"rfc_number={rfc.rfc_number}") + + def test_rfcxml_notprepped(self): + number = settings.FIRST_V3_RFC + stored_name = f"notprepped/rfc{number}.notprepped.xml" + url = f"/doc/rfc{number}/notprepped/" + + # 404 for pre-v3 RFC numbers (no document needed) + r = self.client.get(f"/doc/rfc{number - 1}/notprepped/") + self.assertEqual(r.status_code, 404) + + # 404 when no RFC document exists in the database + r = self.client.get(url) + self.assertEqual(r.status_code, 404) + + # 404 when RFC document exists but has no StoredObject + WgRfcFactory(rfc_number=number) + r = self.client.get(url) + self.assertEqual(r.status_code, 404) + + # 404 when StoredObject exists but backing storage is missing (FileNotFoundError) + now = timezone.now() + StoredObject.objects.create( + store="rfc", + name=stored_name, + sha384="a" * 96, + len=0, + store_created=now, + created=now, + modified=now, + ) + r = self.client.get(url) + self.assertEqual(r.status_code, 404) + + # 200 with correct content-type, attachment disposition, and body when object is fully stored + xml_content = b"test" + store_bytes("rfc", stored_name, xml_content, allow_overwrite=True) + r = self.client.get(url) + self.assertEqual(r.status_code, 200) + self.assertEqual(r["Content-Type"], "application/xml") + self.assertEqual( + r["Content-Disposition"], + f'attachment; filename="rfc{number}.notprepped.xml"', + ) + self.assertEqual(b"".join(r.streaming_content), xml_content) + + def test_rfcxml_notprepped_wrapper(self): + number = settings.FIRST_V3_RFC + + # 404 for pre-v3 RFC numbers (no document needed) + r = self.client.get( + urlreverse( + "ietf.doc.views_doc.rfcxml_notprepped_wrapper", + kwargs=dict(number=number - 1), + ) + ) + self.assertEqual(r.status_code, 404) + + # 404 when no RFC document exists in the database + r = self.client.get( + urlreverse( + "ietf.doc.views_doc.rfcxml_notprepped_wrapper", + kwargs=dict(number=number), + ) + ) + self.assertEqual(r.status_code, 404) + + # 200 with rendered template when RFC document exists + rfc = WgRfcFactory(rfc_number=number) + r = self.client.get( + urlreverse( + "ietf.doc.views_doc.rfcxml_notprepped_wrapper", + kwargs=dict(number=number), + ) + ) + self.assertEqual(r.status_code, 200) + q = PyQuery(r.content) + self.assertIn(str(rfc.rfc_number), q("h1").text()) + download_url = urlreverse( + "ietf.doc.views_doc.rfcxml_notprepped", kwargs=dict(number=number) + ) + self.assertEqual(len(q(f'a.btn[href="{download_url}"]')), 1) diff --git a/ietf/doc/tests_review.py b/ietf/doc/tests_review.py index 7e902514d57..82d1b5c232b 100644 --- a/ietf/doc/tests_review.py +++ b/ietf/doc/tests_review.py @@ -1,29 +1,31 @@ -# Copyright The IETF Trust 2016-2020, All Rights Reserved +# Copyright The IETF Trust 2016-2023, All Rights Reserved # -*- coding: utf-8 -*- -import datetime, os, shutil +from pathlib import Path +import datetime import io -import tarfile, tempfile, mailbox -import email.mime.multipart, email.mime.text, email.utils +import os +import shutil -from mock import patch +from unittest.mock import patch, Mock from requests import Response - from django.apps import apps from django.urls import reverse as urlreverse from django.conf import settings +from django.utils import timezone from pyquery import PyQuery import debug # pyflakes:ignore +from ietf.doc.storage_utils import retrieve_str import ietf.review.mailarch from ietf.doc.factories import ( NewRevisionDocEventFactory, IndividualDraftFactory, WgDraftFactory, WgRfcFactory, ReviewFactory, DocumentFactory) -from ietf.doc.models import ( Document, DocumentAuthor, RelatedDocument, DocEvent, ReviewRequestDocEvent, +from ietf.doc.models import ( DocumentAuthor, RelatedDocument, DocEvent, ReviewRequestDocEvent, ReviewAssignmentDocEvent, ) from ietf.group.factories import RoleFactory, ReviewTeamFactory from ietf.group.models import Group @@ -38,6 +40,7 @@ from ietf.utils.test_utils import login_testing_unauthorized, reload_db_objects from ietf.utils.test_utils import TestCase from ietf.utils.text import strip_prefix, xslugify +from ietf.utils.timezone import date_today, DEADLINE_TZINFO from django.utils.html import escape class ReviewTests(TestCase): @@ -46,6 +49,7 @@ def setUp(self): self.review_dir = self.tempdir('review') self.old_document_path_pattern = settings.DOCUMENT_PATH_PATTERN settings.DOCUMENT_PATH_PATTERN = self.review_dir + "/{doc.type_id}/" + (Path(settings.FTP_DIR) / "review").mkdir() self.review_subdir = os.path.join(self.review_dir, "review") if not os.path.exists(self.review_subdir): @@ -56,6 +60,17 @@ def tearDown(self): settings.DOCUMENT_PATH_PATTERN = self.old_document_path_pattern super().tearDown() + def verify_review_files_were_written(self, assignment, expected_content = "This is a review\nwith two lines"): + review_file = Path(self.review_subdir) / f"{assignment.review.name}.txt" + content = review_file.read_text() + self.assertEqual(content, expected_content) + self.assertEqual( + retrieve_str("review", review_file.name), + expected_content + ) + review_ftp_file = Path(settings.FTP_DIR) / "review" / review_file.name + self.assertTrue(review_file.samefile(review_ftp_file)) + def test_request_review(self): doc = WgDraftFactory(group__acronym='mars',rev='01') NewRevisionDocEventFactory(doc=doc,rev='01') @@ -67,7 +82,7 @@ def test_request_review(self): RoleFactory(group=review_team,person__user__username='reviewsecretary',person__user__email='reviewsecretary@example.com',name_id='secr') RoleFactory(group=review_team3,person__user__username='reviewsecretary3',person__user__email='reviewsecretary3@example.com',name_id='secr') - req = ReviewRequestFactory(doc=doc,team=review_team,type_id='early',state_id='assigned',requested_by=rev_role.person,deadline=datetime.datetime.now()+datetime.timedelta(days=20)) + req = ReviewRequestFactory(doc=doc,team=review_team,type_id='early',state_id='assigned',requested_by=rev_role.person,deadline=timezone.now()+datetime.timedelta(days=20)) ReviewAssignmentFactory(review_request = req, reviewer = rev_role.person.email_set.first(), state_id='accepted') url = urlreverse('ietf.doc.views_review.request_review', kwargs={ "name": doc.name }) @@ -77,7 +92,7 @@ def test_request_review(self): r = self.client.get(url) self.assertEqual(r.status_code, 200) - deadline = datetime.date.today() + datetime.timedelta(days=10) + deadline = date_today() + datetime.timedelta(days=10) empty_outbox() @@ -136,24 +151,32 @@ def test_request_review_of_rfc(self): url = urlreverse('ietf.doc.views_review.request_review', kwargs={ "name": doc.name }) login_testing_unauthorized(self, "ad", url) - # get should fail + # get should fail - all non draft types 404 + r = self.client.get(url) + self.assertEqual(r.status_code, 404) + + # Can only request reviews on active draft documents + doc = WgDraftFactory(states=[("draft","rfc")]) + url = urlreverse('ietf.doc.views_review.request_review', kwargs={ "name": doc.name }) r = self.client.get(url) self.assertEqual(r.status_code, 403) + + def test_doc_page(self): doc = WgDraftFactory(group__acronym='mars',rev='01') review_team = ReviewTeamFactory(acronym="reviewteam", name="Review Team", type_id="review", list_email="reviewteam@ietf.org", parent=Group.objects.get(acronym="farfut")) rev_role = RoleFactory(group=review_team,person__user__username='reviewer',person__user__email='reviewer@example.com',name_id='reviewer') - review_req = ReviewRequestFactory(doc=doc,team=review_team,type_id='early',state_id='assigned',requested_by=rev_role.person,deadline=datetime.datetime.now()+datetime.timedelta(days=20)) + review_req = ReviewRequestFactory(doc=doc,team=review_team,type_id='early',state_id='assigned',requested_by=rev_role.person,deadline=timezone.now()+datetime.timedelta(days=20)) ReviewAssignmentFactory(review_request=review_req, reviewer=rev_role.person.email_set.first(), state_id='accepted') # move the review request to a doubly-replaced document to # check we can fish it out old_doc = WgDraftFactory(name="draft-foo-mars-test") older_doc = WgDraftFactory(name="draft-older") - RelatedDocument.objects.create(source=old_doc, target=older_doc.docalias.first(), relationship_id='replaces') - RelatedDocument.objects.create(source=doc, target=old_doc.docalias.first(), relationship_id='replaces') + RelatedDocument.objects.create(source=old_doc, target=older_doc, relationship_id='replaces') + RelatedDocument.objects.create(source=doc, target=old_doc, relationship_id='replaces') review_req.doc = older_doc review_req.save() @@ -166,7 +189,7 @@ def test_review_request(self): doc = WgDraftFactory(group__acronym='mars',rev='01', authors=[author]) review_team = ReviewTeamFactory(acronym="reviewteam", name="Review Team", type_id="review", list_email="reviewteam@ietf.org", parent=Group.objects.get(acronym="farfut")) rev_role = RoleFactory(group=review_team,person__user__username='reviewer',person__user__email='reviewer@example.com',name_id='reviewer') - review_req = ReviewRequestFactory(doc=doc,team=review_team,type_id='early',state_id='assigned',requested_by=rev_role.person,deadline=datetime.datetime.now()+datetime.timedelta(days=20)) + review_req = ReviewRequestFactory(doc=doc,team=review_team,type_id='early',state_id='assigned',requested_by=rev_role.person,deadline=timezone.now()+datetime.timedelta(days=20)) ReviewAssignmentFactory(review_request = review_req, reviewer = rev_role.person.email_set.first(), state_id='accepted') url = urlreverse('ietf.doc.views_review.review_request', kwargs={ "name": doc.name, "request_id": review_req.pk }) @@ -195,7 +218,7 @@ def test_close_request(self): rev_role = RoleFactory(group=review_team,person__user__username='reviewer',person__user__email='reviewer@example.com',name_id='reviewer') RoleFactory(group=review_team,person__user__username='reviewsecretary',person__user__email='reviewsecretary@example.com',name_id='secr') RoleFactory(group=review_team,person__user__username='reviewsecretary2',person__user__email='reviewsecretary2@example.com',name_id='secr') - review_req = ReviewRequestFactory(doc=doc,team=review_team,type_id='early',state_id='assigned',requested_by=rev_role.person,deadline=datetime.datetime.now()+datetime.timedelta(days=20)) + review_req = ReviewRequestFactory(doc=doc,team=review_team,type_id='early',state_id='assigned',requested_by=rev_role.person,deadline=timezone.now()+datetime.timedelta(days=20)) ReviewAssignmentFactory(review_request=review_req, state_id='accepted', reviewer=rev_role.person.email_set.first()) close_url = urlreverse('ietf.doc.views_review.close_request', kwargs={ "name": doc.name, "request_id": review_req.pk }) @@ -260,14 +283,14 @@ def test_assign_reviewer(self): # previous review req = ReviewRequestFactory( - time=datetime.datetime.now() - datetime.timedelta(days=100), + time=timezone.now() - datetime.timedelta(days=100), requested_by=Person.objects.get(name="(System)"), doc=doc, type_id='early', team=review_req.team, state_id='assigned', requested_rev="01", - deadline=datetime.date.today() - datetime.timedelta(days=80), + deadline=date_today() - datetime.timedelta(days=80), ) ReviewAssignmentFactory( review_request = req, @@ -344,6 +367,52 @@ def test_assign_reviewer(self): self.assertIn("This team has completed other reviews", message) self.assertIn("{} -01 Serious Issues".format(reviewer_email.person.ascii), message) + # check events + assignment_events = assignment.reviewassignmentdocevent_set.all() + self.assertEqual(assignment_events.count(), 1) + e = assignment_events.first() + self.assertEqual(e.type, 'assigned_review_request') + self.assertIn('is assigned', e.desc) + self.assertEqual(e.doc, doc) + request_events = review_req.reviewrequestdocevent_set.all() + self.assertEqual(request_events.count(), 0) + + def test_assign_reviewer_after_reject(self): + doc = WgDraftFactory() + review_team = ReviewTeamFactory() + rev_role = RoleFactory(group=review_team,person__user__username='reviewer',person__user__email='reviewer@example.com',name_id='reviewer') + reviewer_email = Email.objects.get(person__user__username="reviewer") + RoleFactory(group=review_team,person__user__username='reviewsecretary',name_id='secr') + review_req = ReviewRequestFactory(team=review_team,doc=doc) + ReviewAssignmentFactory(review_request=review_req, state_id='rejected', reviewer=rev_role.person.email_set.first()) + + url = urlreverse('ietf.doc.views_review.assign_reviewer', kwargs={ "name": doc.name, "request_id": review_req.pk }) + login_testing_unauthorized(self, "reviewsecretary", url) + r = self.client.get(url) + self.assertEqual(r.status_code, 200) + q = PyQuery(r.content) + reviewer_label = q("option[value=\"{}\"]".format(reviewer_email.address)).text().lower() + self.assertIn("rejected review of document before", reviewer_label) + + def test_assign_reviewer_after_withdraw(self): + doc = WgDraftFactory() + review_team = ReviewTeamFactory() + rev_role = RoleFactory(group=review_team,person__user__username='reviewer',person__user__email='reviewer@example.com',name_id='reviewer') + RoleFactory(group=review_team,person__user__username='reviewsecretary',name_id='secr') + review_req = ReviewRequestFactory(team=review_team,doc=doc) + reviewer = rev_role.person.email_set.first() + ReviewAssignmentFactory(review_request=review_req, state_id='withdrawn', reviewer=reviewer) + req_url = urlreverse('ietf.doc.views_review.review_request', kwargs={ "name": doc.name, "request_id": review_req.pk }) + assign_url = urlreverse('ietf.doc.views_review.assign_reviewer', kwargs={ "name": doc.name, "request_id": review_req.pk }) + + login_testing_unauthorized(self, "reviewsecretary", assign_url) + r = self.client.post(assign_url, { "action": "assign", "reviewer": reviewer.pk }) + self.assertRedirects(r, req_url) + review_req = reload_db_objects(review_req) + assignment = review_req.reviewassignment_set.last() + self.assertEqual(assignment.state, ReviewAssignmentStateName.objects.get(slug='assigned')) + self.assertEqual(review_req.state, ReviewRequestStateName.objects.get(slug='assigned')) + def test_previously_reviewed_replaced_doc(self): review_team = ReviewTeamFactory(acronym="reviewteam", name="Review Team", type_id="review", list_email="reviewteam@ietf.org", parent=Group.objects.get(acronym="farfut")) rev_role = RoleFactory(group=review_team,person__user__username='reviewer',person__user__email='reviewer@example.com',person__name='Some Reviewer',name_id='reviewer') @@ -372,7 +441,7 @@ def test_accept_reviewer_assignment(self): doc = WgDraftFactory(group__acronym='mars',rev='01') review_team = ReviewTeamFactory(acronym="reviewteam", name="Review Team", type_id="review", list_email="reviewteam@ietf.org", parent=Group.objects.get(acronym="farfut")) rev_role = RoleFactory(group=review_team,person__user__username='reviewer',person__user__email='reviewer@example.com',name_id='reviewer') - review_req = ReviewRequestFactory(doc=doc,team=review_team,type_id='early',state_id='assigned',requested_by=rev_role.person,deadline=datetime.datetime.now()+datetime.timedelta(days=20)) + review_req = ReviewRequestFactory(doc=doc,team=review_team,type_id='early',state_id='assigned',requested_by=rev_role.person,deadline=timezone.now()+datetime.timedelta(days=20)) assignment = ReviewAssignmentFactory(review_request=review_req, state_id='assigned', reviewer=rev_role.person.email_set.first()) url = urlreverse('ietf.doc.views_review.review_request', kwargs={ "name": doc.name, "request_id": review_req.pk }) @@ -395,7 +464,7 @@ def test_reject_reviewer_assignment(self): review_team = ReviewTeamFactory(acronym="reviewteam", name="Review Team", type_id="review", list_email="reviewteam@ietf.org", parent=Group.objects.get(acronym="farfut")) rev_role = RoleFactory(group=review_team,person__user__username='reviewer',person__user__email='reviewer@example.com',name_id='reviewer') RoleFactory(group=review_team,person__user__username='reviewsecretary',person__user__email='reviewsecretary@example.com',name_id='secr') - review_req = ReviewRequestFactory(doc=doc,team=review_team,type_id='early',state_id='assigned',requested_by=rev_role.person,deadline=datetime.datetime.now()+datetime.timedelta(days=20)) + review_req = ReviewRequestFactory(doc=doc,team=review_team,type_id='early',state_id='assigned',requested_by=rev_role.person,deadline=timezone.now()+datetime.timedelta(days=20)) assignment = ReviewAssignmentFactory(review_request = review_req, reviewer=rev_role.person.email_set.first(), state_id='accepted') reject_url = urlreverse('ietf.doc.views_review.reject_reviewer_assignment', kwargs={ "name": doc.name, "assignment_id": assignment.pk }) @@ -407,13 +476,54 @@ def test_reject_reviewer_assignment(self): r = self.client.get(req_url) self.assertEqual(r.status_code, 200) self.assertContains(r, reject_url) + + # anonymous user should not be able to reject self.client.logout() + r = self.client.post(reject_url, { "action": "reject", "message_to_secretary": "Test message" }) + self.assertEqual(r.status_code, 302) # forwards to login page + assignment = reload_db_objects(assignment) + self.assertEqual(assignment.state_id, "accepted") + + # unrelated person should not be able to reject + other_person = PersonFactory() + login_testing_unauthorized(self, other_person.user.username, reject_url) + r = self.client.post(reject_url, { "action": "reject", "message_to_secretary": "Test message" }) + self.assertEqual(r.status_code, 403) + assignment = reload_db_objects(assignment) + self.assertEqual(assignment.state_id, "accepted") - # get reject page + # Check that user can reject it + login_testing_unauthorized(self, assignment.reviewer.person.user.username, reject_url) + r = self.client.get(reject_url) + self.assertEqual(r.status_code, 200) + self.assertContains(r, escape(assignment.reviewer.person.name)) + self.assertNotContains(r, 'can not be rejected') + self.assertContains(r, ' -
  • - - - - - - -{% endblock %} diff --git a/ietf/secr/templates/areas/list.html b/ietf/secr/templates/areas/list.html deleted file mode 100644 index a0ed1ae4a37..00000000000 --- a/ietf/secr/templates/areas/list.html +++ /dev/null @@ -1,42 +0,0 @@ -{% extends "base_site.html" %} -{% load staticfiles %} -{% block title %}Areas{% endblock %} - -{% block extrahead %}{{ block.super }} - -{% endblock %} - -{% block breadcrumbs %}{{ block.super }} - » Areas -{% endblock %} - -{% block content %} - -
    -

    Areas

    - - - - - - - - - - {% for item in results %} - - - - - - {% endfor %} - -
    NameAcronymStatus
    {{ item.name }}{{ item.acronym }}{{ item.state }}
    - -
    -
      -
    -
    -
    - -{% endblock %} diff --git a/ietf/secr/templates/areas/people.html b/ietf/secr/templates/areas/people.html deleted file mode 100644 index c5598f911d5..00000000000 --- a/ietf/secr/templates/areas/people.html +++ /dev/null @@ -1,62 +0,0 @@ -{% extends "base_site.html" %} -{% load staticfiles %} -{% block title %}Areas - People{% endblock %} - -{% block extrahead %}{{ block.super }} - - - -{% endblock %} - -{% block breadcrumbs %}{{ block.super }} - » Areas - » {{ area.acronym }} - » People -{% endblock %} - -{% block content %} - -
    -

    Area Directors ({{ area.acronym }})

    - - {% for director in directors %} - {% csrf_token %} - - - - - {% endif %} - - - - {% endfor %} -
    {{ director.person.name }}{% if director.name.slug == "ad" %} - Voting Enabled - {% else %} -
    - - - -
    -
      -
    • -
    -
    -
    - -{% endblock %} \ No newline at end of file diff --git a/ietf/secr/templates/areas/view.html b/ietf/secr/templates/areas/view.html deleted file mode 100644 index 3b95988682b..00000000000 --- a/ietf/secr/templates/areas/view.html +++ /dev/null @@ -1,51 +0,0 @@ -{% extends "base_site.html" %} -{% load staticfiles %} -{% block title %}Areas - View{% endblock %} - -{% block extrahead %}{{ block.super }} - -{% endblock %} - -{% block breadcrumbs %}{{ block.super }} - » Areas - » {{ area.acronym }} -{% endblock %} - -{% block content %} - -
    -

    Area - View

    - - - - - - - - - - -
    Area Acronym:{{ area.acronym }}
    Area Name:{{ area.name }}
    Status:{{ area.state }}
    Start Date:{{ area.start_date|date:"Y-m-d" }}
    Concluded Date:{{ area.concluded_date|date:"Y-m-d" }}
    Last Modified Date:{{ area.time|date:"Y-m-d" }}
    Comments:{{ area.comments}}
    - - - -
    -
      - -
    • -
    • -
    • -
    -
    -
    - -{% endblock %} diff --git a/ietf/secr/templates/base_secr.html b/ietf/secr/templates/base_secr.html index 47b893f0439..18d77e47bae 100644 --- a/ietf/secr/templates/base_secr.html +++ b/ietf/secr/templates/base_secr.html @@ -1,5 +1,5 @@ -{% load staticfiles %} +{% load static %} diff --git a/ietf/secr/templates/base_secr_bootstrap.html b/ietf/secr/templates/base_secr_bootstrap.html index 2eee566a121..a326346847b 100644 --- a/ietf/secr/templates/base_secr_bootstrap.html +++ b/ietf/secr/templates/base_secr_bootstrap.html @@ -1,5 +1,5 @@ -{% load staticfiles %} +{% load static %} diff --git a/ietf/secr/templates/base_site.html b/ietf/secr/templates/base_site.html index d369a40ec17..5e3ddc62d86 100644 --- a/ietf/secr/templates/base_site.html +++ b/ietf/secr/templates/base_site.html @@ -1,7 +1,7 @@ {% extends "base_secr.html" %} {% load i18n %} {% load ietf_filters %} -{% load staticfiles %} +{% load static %} {% block title %}{{ title }}{% if user|has_role:"Secretariat" %} Secretariat Dashboard {% else %} IETF Dashboard {% endif %}{% endblock %} diff --git a/ietf/secr/templates/base_site_bootstrap.html b/ietf/secr/templates/base_site_bootstrap.html index c1c2fdac6b7..1653b26b856 100644 --- a/ietf/secr/templates/base_site_bootstrap.html +++ b/ietf/secr/templates/base_site_bootstrap.html @@ -1,7 +1,7 @@ {% extends "base_secr_bootstrap.html" %} {% load i18n %} {% load ietf_filters %} -{% load staticfiles %} +{% load static %} {% block title %}{{ title }}{% if user|has_role:"Secretariat" %} Secretariat Dashboard {% else %} WG Chair Dashboard {% endif %}{% endblock %} diff --git a/ietf/secr/templates/confirm_cancel.html b/ietf/secr/templates/confirm_cancel.html index 6bae631a7ec..541c82863fb 100644 --- a/ietf/secr/templates/confirm_cancel.html +++ b/ietf/secr/templates/confirm_cancel.html @@ -1,5 +1,5 @@ {% extends "base_site.html" %} -{% load staticfiles %} +{% load static %} {% block title %}Confirm Cancel{% endblock %} diff --git a/ietf/secr/templates/confirm_delete.html b/ietf/secr/templates/confirm_delete.html index ccfc7b1c2fc..3f8fd19c8fa 100644 --- a/ietf/secr/templates/confirm_delete.html +++ b/ietf/secr/templates/confirm_delete.html @@ -1,5 +1,5 @@ {% extends "base_site.html" %} -{% load staticfiles %} +{% load static %} {% block title %}Confirm Delete{% endblock %} diff --git a/ietf/secr/templates/console/main.html b/ietf/secr/templates/console/main.html deleted file mode 100644 index 5aadefc558a..00000000000 --- a/ietf/secr/templates/console/main.html +++ /dev/null @@ -1,22 +0,0 @@ -{% extends "base_site.html" %} - -{% block title %}Console{% endblock %} - -{% block breadcrumbs %}{{ block.super }} - » Console -{% endblock %} - -{% block content %} - -
    -

    Console

    - - - - - -
    Latest DocEvent{{ latest_docevent }}
    - -
    - -{% endblock %} diff --git a/ietf/secr/templates/groups/blue_dot_report.txt b/ietf/secr/templates/groups/blue_dot_report.txt deleted file mode 100644 index 7516b01dad7..00000000000 --- a/ietf/secr/templates/groups/blue_dot_report.txt +++ /dev/null @@ -1,6 +0,0 @@ -BLUE DOT REPORT - -NAMES ROSTER BADGE --------------------------------------------------------------------------- -{% for chair in chairs %}{{ chair.name|safe|stringformat:"-33s" }}{{ chair.groups|stringformat:"-36s" }}BLUE -{% endfor %} \ No newline at end of file diff --git a/ietf/secr/templates/groups/charter.html b/ietf/secr/templates/groups/charter.html deleted file mode 100644 index 84649f4fdef..00000000000 --- a/ietf/secr/templates/groups/charter.html +++ /dev/null @@ -1,25 +0,0 @@ -{% extends "base_site.html" %} -{% load staticfiles %} - -{% block title %}Groups - Charter{% endblock %} - -{% block extrahead %}{{ block.super }} - -{% endblock %} - -{% block breadcrumbs %}{{ block.super }} - » Groups - » {{ group.acronym }} - » Charter -{% endblock %} - -{% block content %} - -
    -

    Groups - Charter

    -
    -    {% if charter_txt %}{{ charter_text }}{% else %}Charter not found.{% endif %}
    -    
    -
    - -{% endblock %} diff --git a/ietf/secr/templates/groups/people.html b/ietf/secr/templates/groups/people.html deleted file mode 100644 index 3c207d3dbf1..00000000000 --- a/ietf/secr/templates/groups/people.html +++ /dev/null @@ -1,72 +0,0 @@ -{% extends "base_site.html" %} -{% load staticfiles widget_tweaks %} - -{% block title %}Groups - People{% endblock %} - -{% block extrahead %}{{ block.super }} - - - -{% endblock %} - -{% block breadcrumbs %}{{ block.super }} - » Groups - » {{ group.acronym }} - » People -{% endblock %} - -{% block content %} - -
    -

    People

    - - - - - - - - - - {% if group.role_set.all %} - - {% for role in group.role_set.all %} - - - - - - - {% endfor %} - - {% endif %} -
    RoleNameEmailAction
    {{ role.name }}{{ role.person }}{{ role.email }}Delete
    - - - -
    -
      -
    • -
    -
    - -
    - -{% endblock %} \ No newline at end of file diff --git a/ietf/secr/templates/groups/search.html b/ietf/secr/templates/groups/search.html deleted file mode 100644 index 4a1de0e4aef..00000000000 --- a/ietf/secr/templates/groups/search.html +++ /dev/null @@ -1,39 +0,0 @@ -{% extends "base_site.html" %} -{% load staticfiles %} - -{% block title %}Groups - Search{% endblock %} - -{% block extrahead %}{{ block.super }} - - - -{% endblock %} - -{% block breadcrumbs %}{{ block.super }} - » Groups -{% endblock %} - -{% block content %} - -
    -

    Groups - Search

    -
    {% csrf_token %} - - - - {{ form.as_table }} - -
    - - {% include "includes/buttons_search.html" %} - -
    - - -
    - -{% endblock %} \ No newline at end of file diff --git a/ietf/secr/templates/groups/view.html b/ietf/secr/templates/groups/view.html deleted file mode 100644 index a0509b0630b..00000000000 --- a/ietf/secr/templates/groups/view.html +++ /dev/null @@ -1,123 +0,0 @@ -{% extends "base_site.html" %} -{% load staticfiles %} - -{% block title %}Groups - View{% endblock %} - -{% block extrahead %}{{ block.super }} - -{% endblock %} - -{% block breadcrumbs %}{{ block.super }} - » Groups - » {{ group.acronym }} -{% endblock %} - -{% block content %} - -
    -
    -

    Groups - View

    - - - - - - - - - - {% comment %} - Here we need to check that group.area_director and group.area_director.area are defined before referencing. - Otherwise the template would raise errors if the group area director record didn't exist or - in the case of Area Director = TBD, the area field is NULL - {% endcomment %} - - - - - - - - - - {% if group.liaison_contacts %} - - {% endif %} - {% if group.features.has_chartering_process %} - - {% else %} - - {% endif %} - - - -
    Group Acronym:{{ group.acronym }}
    Group Name:{{ group.name }}
    Status:{{ group.state }}
    Type:{{ group.type }}
    Proposed Date:{{ group.proposed_date|date:"Y-m-d" }}
    Start Date:{{ group.start_date|date:"Y-m-d" }}
    Concluded Date:{{ group.concluded_date|date:"Y-m-d" }}
    Primary Area:{% if not group.parent %}(No Data){% else %} - {{ group.parent }} - {% endif %} -
    Primary Area Director:{% if group.ad_role %} - {{ group.ad_role.person }} - {% endif %} -
    Meeting Scheduled:{{ group.meeting_scheduled}}
    Email Address:{{ group.list_email }}
    Email Subscription:{{ group.list_subscribe }}
    Email Archive:{{ group.list_archive }}
    Default Liaison Contacts:{{ group.liaison_contacts.contacts }}
    Charter:View Charter
    Description:{{ group.description }}
    Comments:{{ group.comments }}
    Last Modified Date:{{ group.time }}
    - - -
    -
    - - - - - - - - -
    - -
    -
      -
    • -
    • - {% comment %} -
    • -
    • - {% endcomment %} -
    -
    -
    - -{% endblock %} \ No newline at end of file diff --git a/ietf/secr/templates/includes/activities.html b/ietf/secr/templates/includes/activities.html deleted file mode 100644 index 3e79c9aed48..00000000000 --- a/ietf/secr/templates/includes/activities.html +++ /dev/null @@ -1,23 +0,0 @@ -

    Activies Log

    - diff --git a/ietf/secr/templates/includes/buttons_next_cancel.html b/ietf/secr/templates/includes/buttons_next_cancel.html deleted file mode 100644 index 95d25f55bcc..00000000000 --- a/ietf/secr/templates/includes/buttons_next_cancel.html +++ /dev/null @@ -1,6 +0,0 @@ -
    -
      -
    • -
    • -
    -
    diff --git a/ietf/secr/templates/includes/buttons_submit_cancel.html b/ietf/secr/templates/includes/buttons_submit_cancel.html deleted file mode 100644 index df40c982559..00000000000 --- a/ietf/secr/templates/includes/buttons_submit_cancel.html +++ /dev/null @@ -1,6 +0,0 @@ -
    -
      -
    • -
    • -
    -
    diff --git a/ietf/secr/templates/includes/group_search_results.html b/ietf/secr/templates/includes/group_search_results.html deleted file mode 100644 index fb8b2b06e30..00000000000 --- a/ietf/secr/templates/includes/group_search_results.html +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - - - - - - - {% for item in results %} - - - - - - - - {% empty %} - - {% endfor %} - -
    Group NameGroup AcronymStatusTypeMeeting Scheduled
    {{item.name}}{{item.acronym}}{{item.state}}{{item.type}}{{item.meeting_scheduled}}
    No Results
    diff --git a/ietf/secr/templates/includes/meetings_footer.html b/ietf/secr/templates/includes/meetings_footer.html index 71a30ed9431..d8956b61487 100755 --- a/ietf/secr/templates/includes/meetings_footer.html +++ b/ietf/secr/templates/includes/meetings_footer.html @@ -1,3 +1,3 @@ \ No newline at end of file diff --git a/ietf/secr/templates/includes/proceedings_functions.html b/ietf/secr/templates/includes/proceedings_functions.html deleted file mode 100644 index 33e11a14890..00000000000 --- a/ietf/secr/templates/includes/proceedings_functions.html +++ /dev/null @@ -1,13 +0,0 @@ - -

    Use this to process meeting materials files that have been converted to PDF and uploaded to the server.

    -
      -
    • - -   {{ ppt_count }} PowerPoint files waiting to be converted -
    • -
    -

    Use this to input session recording information.

    -
      -
    • -
    • -
    diff --git a/ietf/secr/templates/includes/session_info.txt b/ietf/secr/templates/includes/session_info.txt index eea4a5f174b..bffc13e3ef9 100644 --- a/ietf/secr/templates/includes/session_info.txt +++ b/ietf/secr/templates/includes/session_info.txt @@ -14,7 +14,7 @@ Conflicts to Avoid: {% if session.adjacent_with_wg %} Adjacent with WG: {{ session.adjacent_with_wg }}{% endif %} {% if session.timeranges_display %} Can't meet: {{ session.timeranges_display|join:", " }}{% endif %} -People who must be present: +Participants who must be present: {% for person in session.bethere %} {{ person.ascii_name }} {% endfor %} Resources Requested: diff --git a/ietf/secr/templates/includes/sessions_footer.html b/ietf/secr/templates/includes/sessions_footer.html deleted file mode 100755 index a41a8b8db39..00000000000 --- a/ietf/secr/templates/includes/sessions_footer.html +++ /dev/null @@ -1,6 +0,0 @@ - \ No newline at end of file diff --git a/ietf/secr/templates/includes/sessions_request_form.html b/ietf/secr/templates/includes/sessions_request_form.html deleted file mode 100755 index 3071af16c78..00000000000 --- a/ietf/secr/templates/includes/sessions_request_form.html +++ /dev/null @@ -1,124 +0,0 @@ -* Required Field -
    {% csrf_token %} - {{ form.session_forms.management_form }} - {% if form.non_field_errors %} - {{ form.non_field_errors }} - {% endif %} - - - - - - {% if group.features.acts_like_wg %} - - {% if not is_virtual %} - - {% endif %} - - {% else %}{# else not group.features.acts_like_wg #} - {% for session_form in form.session_forms %} - - {% endfor %} - {% endif %} - - - - - - - {% if not is_virtual %} - - - - - - - - - - - - - - - - - - - - - - - {% endif %} - - - - - - -
    Working Group Name:{{ group.name }} ({{ group.acronym }})
    Area Name:{% if group.parent %}{{ group.parent.name }} ({{ group.parent.acronym }}){% endif %}
    Number of Sessions:*{{ form.num_session.errors }}{{ form.num_session }}
    Session 1:*{% include 'meeting/session_details_form.html' with form=form.session_forms.0 only %}
    Session 2:*{% include 'meeting/session_details_form.html' with form=form.session_forms.1 only %}
    Time between two sessions:{{ form.session_time_relation.errors }}{{ form.session_time_relation }}
    Additional Session Request:{{ form.third_session }} Check this box to request an additional session.
    - Additional slot may be available after agenda scheduling has closed and with the approval of an Area Director.
    -
    - Third Session: - {% include 'meeting/session_details_form.html' with form=form.session_forms.2 only %} -
    -
    Session {{ forloop.counter }}:*{% include 'meeting/session_details_form.html' with form=session_form only %}
    Number of Attendees:{% if not is_virtual %}*{% endif %}{{ form.attendees.errors }}{{ form.attendees }}
    People who must be present:{{ form.bethere.errors }}{{ form.bethere }}
    Conflicts to Avoid: - - - - - - - {% for cname, cfield, cselector in form.wg_constraint_fields %} - - {% if forloop.first %}{% endif %} - - - - {% empty %}{# shown if there are no constraint fields #} - - {% endfor %} - {% if form.inactive_wg_constraints %} - {% for cname, value, field in form.inactive_wg_constraints %} - - {% if forloop.first %} - - {% endif %} - - - - {% endfor %} - {% endif %} - - - - - -
    Other WGs that included {{ group.name }} in their conflict lists:{{ session_conflicts.inbound|default:"None" }}
    WG Sessions:
    You may select multiple WGs within each category
    {{ cname|title }}{{ cselector }} -
    - {{ cfield.errors }}{{ cfield }} -
    No constraints are enabled for this meeting.
    - Disabled for this meeting - {{ cname|title }}
    {{ field }} {{ field.label }}
    BOF Sessions:If the sessions can not be found in the fields above, please enter free form requests in the Special Requests field below.
    -
    Resources requested: - {{ form.resources.errors }} {{ form.resources }} -
    Times during which this WG can not meet:
    Please explain any selections in Special Requests below.
    {{ form.timeranges.errors }}{{ form.timeranges }}
    - Plan session adjacent with another WG:
    - (Immediately before or after another WG, no break in between, in the same room.) -
    {{ form.adjacent_with_wg.errors }}{{ form.adjacent_with_wg }}
    - Joint session with:
    - (To request one session for multiple WGs together.) -
    {{ form.joint_with_groups_selector }} -
    - {{ form.joint_with_groups.errors }}{{ form.joint_with_groups }} -
    - Of the sessions requested by this WG, the joint session, if applicable, is: - {{ form.joint_for_session.errors }}{{ form.joint_for_session }}
    Special Requests:
     
    i.e. restrictions on meeting times / days, etc.
    (limit 200 characters)
    {{ form.comments.errors }}{{ form.comments }}
    - -
    -
      -
    • -
    • -
    -
    -
    diff --git a/ietf/secr/templates/includes/sessions_request_view.html b/ietf/secr/templates/includes/sessions_request_view.html deleted file mode 100644 index 3854651d38f..00000000000 --- a/ietf/secr/templates/includes/sessions_request_view.html +++ /dev/null @@ -1,63 +0,0 @@ -{% load ams_filters %} - - - - - - {% if form %} - {% include 'includes/sessions_request_view_formset.html' with formset=form.session_forms group=group session=session only %} - {% else %} - {% include 'includes/sessions_request_view_session_set.html' with session_set=sessions group=group session=session only %} - {% endif %} - - - - - - - - - - {% if not is_virtual %} - - - - - {% endif %} - - - - - - - - - {% if not is_virtual %} - - - - - - - - - {% endif %} - - -
    Working Group Name:{{ group.name }} ({{ group.acronym }})
    Area Name:{{ group.parent }}
    Number of Sessions Requested:{% if session.third_session %}3{% else %}{{ session.num_session }}{% endif %}
    Number of Attendees:{{ session.attendees }}
    Conflicts to Avoid: - {% if session_conflicts.outbound %} - - - {% for conflict in session_conflicts.outbound %} - - {% endfor %} - -
    {{ conflict.name|title }}: {{ conflict.groups }}
    - {% else %}None{% endif %} -
    Other WGs that included {{ group }} in their conflict list:{% if session_conflicts.inbound %}{{ session_conflicts.inbound }}{% else %}None so far{% endif %}
    Resources requested:{% if session.resources %}
      {% for resource in session.resources %}
    • {{ resource.desc }}
    • {% endfor %}
    {% else %}None so far{% endif %}
    People who must be present:{% if session.bethere %}
      {% for person in session.bethere %}
    • {{ person }}
    • {% endfor %}
    {% else %}None{% endif %}
    Can not meet on:{% if session.timeranges_display %}{{ session.timeranges_display|join:', ' }}{% else %}No constraints{% endif %}
    Adjacent with WG:{{ session.adjacent_with_wg|default:'No preference' }}
    Joint session: - {% if session.joint_with_groups %} - {{ session.joint_for_session_display }} with: {{ session.joint_with_groups }} - {% else %} - Not a joint session - {% endif %} -
    Special Requests:{{ session.comments }}
    diff --git a/ietf/secr/templates/includes/sessions_request_view_formset.html b/ietf/secr/templates/includes/sessions_request_view_formset.html deleted file mode 100644 index ff502dea305..00000000000 --- a/ietf/secr/templates/includes/sessions_request_view_formset.html +++ /dev/null @@ -1,30 +0,0 @@ -{% load ams_filters %}{# keep this in sync with sessions_request_view_session_set.html #} -{% for sess_form in formset %}{% if sess_form.cleaned_data and not sess_form.cleaned_data.DELETE %} - - Session {{ forloop.counter }}: - -
    -
    Length
    -
    {{ sess_form.cleaned_data.requested_duration.total_seconds|display_duration }}
    - {% if sess_form.cleaned_data.name %} -
    Name
    -
    {{ sess_form.cleaned_data.name }}
    {% endif %} - {% if sess_form.cleaned_data.purpose.slug != 'regular' %} -
    Purpose
    -
    - {{ sess_form.cleaned_data.purpose }} - {% if sess_form.cleaned_data.purpose.timeslot_types|length > 1 %}({{ sess_form.cleaned_data.type }} - ){% endif %} -
    - {% endif %} -
    - - - {% if group.features.acts_like_wg and forloop.counter == 2 and not is_virtual %} - - Time between sessions: - {% if session.session_time_relation_display %}{{ session.session_time_relation_display }}{% else %}No - preference{% endif %} - - {% endif %} -{% endif %}{% endfor %} \ No newline at end of file diff --git a/ietf/secr/templates/includes/sessions_request_view_session_set.html b/ietf/secr/templates/includes/sessions_request_view_session_set.html deleted file mode 100644 index 1f953ae3a76..00000000000 --- a/ietf/secr/templates/includes/sessions_request_view_session_set.html +++ /dev/null @@ -1,30 +0,0 @@ -{% load ams_filters %}{# keep this in sync with sessions_request_view_formset.html #} -{% for sess in session_set %} - - Session {{ forloop.counter }}: - -
    -
    Length
    -
    {{ sess.requested_duration.total_seconds|display_duration }}
    - {% if sess.name %} -
    Name
    -
    {{ sess.name }}
    {% endif %} - {% if sess.purpose.slug != 'regular' %} -
    Purpose
    -
    - {{ sess.purpose }} - {% if sess.purpose.timeslot_types|length > 1 %}({{ sess.type }} - ){% endif %} -
    - {% endif %} -
    - - - {% if group.features.acts_like_wg and forloop.counter == 2 and not is_virtual %} - - Time between sessions: - {% if session.session_time_relation_display %}{{ session.session_time_relation_display }}{% else %}No - preference{% endif %} - - {% endif %} -{% endfor %} \ No newline at end of file diff --git a/ietf/secr/templates/includes/upload_footer.html b/ietf/secr/templates/includes/upload_footer.html deleted file mode 100755 index cc7858e1f72..00000000000 --- a/ietf/secr/templates/includes/upload_footer.html +++ /dev/null @@ -1,6 +0,0 @@ - diff --git a/ietf/secr/templates/index.html b/ietf/secr/templates/index.html new file mode 100644 index 00000000000..9ea70212793 --- /dev/null +++ b/ietf/secr/templates/index.html @@ -0,0 +1,31 @@ +{# Copyright The IETF Trust 2007-2025, All Rights Reserved #} +{% extends "base.html" %} +{% load static %} +{% load ietf_filters %} +{% block title %}Secretariat Dashboard{% endblock %} +{% block content %} +

    Secretariat Dashboard

    +
    + {% if user|has_role:"Secretariat" %} +

    IESG

    + + +

    IDs and WGs Process

    + + +

    Meetings and Proceedings

    + + {% else %} + + {% endif %} +
    +{% endblock %} \ No newline at end of file diff --git a/ietf/secr/templates/main.html b/ietf/secr/templates/main.html deleted file mode 100644 index dcda4718dee..00000000000 --- a/ietf/secr/templates/main.html +++ /dev/null @@ -1,81 +0,0 @@ -{% extends "base_site.html" %} -{% load ietf_filters %} - -{% block content %} -
    - - {% if user|has_role:"Secretariat" %} - - - - - - - - - - - - - - - {% else %} - - - - - - - - - - - - - - - {% endif %} - -
    -{% endblock %} \ No newline at end of file diff --git a/ietf/secr/templates/meetings/add.html b/ietf/secr/templates/meetings/add.html index 12b5cd47b69..b2cc2617dc3 100644 --- a/ietf/secr/templates/meetings/add.html +++ b/ietf/secr/templates/meetings/add.html @@ -1,5 +1,5 @@ {% extends "base_site.html" %} -{% load staticfiles %} +{% load static %} {% block title %}Meetings - Add{% endblock %} @@ -19,7 +19,7 @@

    Proceedings - Add

    {% csrf_token %} - + {{ form.as_table }}
    diff --git a/ietf/secr/templates/meetings/base_rooms_times.html b/ietf/secr/templates/meetings/base_rooms_times.html index dc08e9eb50f..263418fabf9 100644 --- a/ietf/secr/templates/meetings/base_rooms_times.html +++ b/ietf/secr/templates/meetings/base_rooms_times.html @@ -1,11 +1,9 @@ {% extends "base_site_bootstrap.html" %} -{% load staticfiles %} +{% load static %} {% block title %}Meetings{% endblock %} {% block extrahead %}{{ block.super }} - - {% endblock %} diff --git a/ietf/secr/templates/meetings/blue_sheet.html b/ietf/secr/templates/meetings/blue_sheet.html deleted file mode 100644 index d67efd9f636..00000000000 --- a/ietf/secr/templates/meetings/blue_sheet.html +++ /dev/null @@ -1,48 +0,0 @@ -{% extends "base_site.html" %} -{% load staticfiles %} - -{% block title %}Meetings - Blue Sheet{% endblock %} - -{% block extrahead %}{{ block.super }} - -{% endblock %} - -{% block breadcrumbs %}{{ block.super }} - » Meetings - » {{ meeting.number }} - » Blue Sheets -{% endblock %} - -{% block content %} - -
    -

    IETF {{ meeting.number }} - Blue Sheet

    - -

    Use this to generate blue sheets for meeting sessions.

    -
      -
    • - {% csrf_token %} - -
    • -   Last run: - {% if last_run %} - {{ last_run }} - {% else %} - Never - {% endif %} - -
    -

    Use this to download the blue sheets from the server.

    -
      -
    • - -
    • -
    - -
    -

    - Use the session details page for a group to upload scanned bluesheets. The session details pages for a group can be reached from the meeting's materials page. -

    -
    - -{% endblock %} diff --git a/ietf/secr/templates/meetings/edit_meeting.html b/ietf/secr/templates/meetings/edit_meeting.html index 0d7159346ac..474373dbee6 100644 --- a/ietf/secr/templates/meetings/edit_meeting.html +++ b/ietf/secr/templates/meetings/edit_meeting.html @@ -1,5 +1,5 @@ {% extends "base_site.html" %} -{% load staticfiles %} +{% load static %} {% block title %}Meetings - Edit{% endblock %} @@ -20,7 +20,7 @@

    Meetings - Edit

    - + {{ form.as_table }}
    diff --git a/ietf/secr/templates/meetings/main.html b/ietf/secr/templates/meetings/main.html index e4cfa5ce8ec..ff110dd9782 100755 --- a/ietf/secr/templates/meetings/main.html +++ b/ietf/secr/templates/meetings/main.html @@ -1,5 +1,5 @@ {% extends "base_site.html" %} -{% load staticfiles %} +{% load static %} {% block title %}Meetings{% endblock %} @@ -30,7 +30,7 @@

    Select a meeting to manage

    {% csrf_token %} - + {{ form.as_table }}
    diff --git a/ietf/secr/templates/meetings/misc_session_edit.html b/ietf/secr/templates/meetings/misc_session_edit.html index af4d1bdbd71..69f935212d0 100755 --- a/ietf/secr/templates/meetings/misc_session_edit.html +++ b/ietf/secr/templates/meetings/misc_session_edit.html @@ -8,7 +8,7 @@

    Session: {{ slot.name }}

    {% csrf_token %} - + {{ form.as_table }}
    diff --git a/ietf/secr/templates/meetings/misc_sessions.html b/ietf/secr/templates/meetings/misc_sessions.html index 9f9eb0f7aaf..a5a48266a24 100644 --- a/ietf/secr/templates/meetings/misc_sessions.html +++ b/ietf/secr/templates/meetings/misc_sessions.html @@ -1,7 +1,7 @@ {% extends "meetings/base_rooms_times.html" %} -{% load agenda_custom_tags %} +{% load agenda_custom_tags tz %} {% block subsection %} - +{% timezone meeting.time_zone %}

    TimeSlots

    @@ -57,7 +57,7 @@

    No timeslots exist for this meeting. Add rooms with the "duplicate timeslots {% csrf_token %} - + {{ form.as_table }} @@ -73,7 +73,7 @@

    No timeslots exist for this meeting. Add rooms with the "duplicate timeslots - +{% endtimezone %} {% endblock %} {% block extrahead %} diff --git a/ietf/secr/templates/meetings/notifications.html b/ietf/secr/templates/meetings/notifications.html index bf7099577eb..dbe66ff283e 100644 --- a/ietf/secr/templates/meetings/notifications.html +++ b/ietf/secr/templates/meetings/notifications.html @@ -1,5 +1,5 @@ {% extends "base_site.html" %} -{% load staticfiles %} +{% load static %} {% block title %}Meetings{% endblock %} diff --git a/ietf/secr/templates/meetings/regular_session_edit.html b/ietf/secr/templates/meetings/regular_session_edit.html index 479cef8af83..9993858be11 100644 --- a/ietf/secr/templates/meetings/regular_session_edit.html +++ b/ietf/secr/templates/meetings/regular_session_edit.html @@ -1,5 +1,5 @@ {% extends "base_site.html" %} -{% load staticfiles %} +{% load static tz %} {% block title %}Meetings{% endblock %} @@ -19,7 +19,7 @@

    Edit Session

    {% csrf_token %}
    -
    +
    {% timezone meeting.time_zone %} @@ -37,10 +37,10 @@

    Edit Session

    - + {{ form.as_table }} -
    Day: Status: {{ current_status_name }}
    + {% endtimezone %}

    diff --git a/ietf/secr/templates/meetings/rooms.html b/ietf/secr/templates/meetings/rooms.html index d3decca80bc..7d6740e5e51 100644 --- a/ietf/secr/templates/meetings/rooms.html +++ b/ietf/secr/templates/meetings/rooms.html @@ -28,7 +28,7 @@

    Rooms

    {% if form.non_field_errors %} {{ form.non_field_errors }} {% endif %} - + {% for hidden in form.hidden_fields %} {{ hidden }} diff --git a/ietf/secr/templates/meetings/session_schedule_notification.txt b/ietf/secr/templates/meetings/session_schedule_notification.txt index 95cbf35351b..5ad129f7056 100644 --- a/ietf/secr/templates/meetings/session_schedule_notification.txt +++ b/ietf/secr/templates/meetings/session_schedule_notification.txt @@ -1,4 +1,4 @@ -Dear {{ to_name }}, +{% load tz %}{% timezone meeting.time_zone %}Dear {{ to_name }}, The session(s) that you have requested have been scheduled. Below is the scheduled session information followed by @@ -16,4 +16,4 @@ iCalendar: {{ baseurl }}{% url "ietf.meeting.views.agenda_ical" num=meeting.numb Request Information: -{% include "includes/session_info.txt" %} +{% include "includes/session_info.txt" %}{% endtimezone %} diff --git a/ietf/secr/templates/meetings/sessions.html b/ietf/secr/templates/meetings/sessions.html index 03b4d8489bc..e774d83ca59 100644 --- a/ietf/secr/templates/meetings/sessions.html +++ b/ietf/secr/templates/meetings/sessions.html @@ -1,5 +1,5 @@ {% extends "meetings/base_rooms_times.html" %} -{% load django_bootstrap5 %} +{% load django_bootstrap5 tz %} {% block subsection %} @@ -18,7 +18,7 @@

    Sessions

    - + {% timezone meeting.time_zone %} {% for session in sessions %} {{ session.group.acronym }} @@ -46,7 +46,7 @@

    Sessions

    {% endfor %} - + {% endtimezone %}
    diff --git a/ietf/secr/templates/meetings/times.html b/ietf/secr/templates/meetings/times.html index 0ec175f0307..559e2fd7723 100644 --- a/ietf/secr/templates/meetings/times.html +++ b/ietf/secr/templates/meetings/times.html @@ -1,5 +1,5 @@ {% extends "meetings/base_rooms_times.html" %} - +{% load tz %} {% block subsection %}
    @@ -16,7 +16,7 @@

    Times

    - + {% timezone meeting.time_zone %} {% for item in times %} {{ item.time|date:"D M d" }} @@ -26,7 +26,7 @@

    Times

    Delete {% endfor %} - + {% endtimezone %} {% else %}

    No timeslots exist for this meeting. Add rooms with the "duplicate timeslots" option enabled to copy timeslots from the last meeting.

    diff --git a/ietf/secr/templates/meetings/times_edit.html b/ietf/secr/templates/meetings/times_edit.html index 1f52e34f10c..9718d73d9b1 100755 --- a/ietf/secr/templates/meetings/times_edit.html +++ b/ietf/secr/templates/meetings/times_edit.html @@ -8,7 +8,7 @@

    Meeting - {{ meeting }}

    {% csrf_token %} - + {{ form.as_table }}
    diff --git a/ietf/secr/templates/meetings/view.html b/ietf/secr/templates/meetings/view.html index d552d38dcae..89bd8f7e03d 100644 --- a/ietf/secr/templates/meetings/view.html +++ b/ietf/secr/templates/meetings/view.html @@ -1,5 +1,5 @@ {% extends "base_site.html" %} -{% load staticfiles %} +{% load static %} {% block title %}Meetings{% endblock %} @@ -37,7 +37,6 @@

    IETF {{ meeting.number }} - View

    • -
    • diff --git a/ietf/secr/templates/proceedings/audio_import_warning.txt b/ietf/secr/templates/proceedings/audio_import_warning.txt deleted file mode 100644 index 322a43f5fda..00000000000 --- a/ietf/secr/templates/proceedings/audio_import_warning.txt +++ /dev/null @@ -1,9 +0,0 @@ - -WARNING: - -After the last meeting session audio file import there are {{ unmatched_files|length }} -file(s) that were not matched to a timeslot. - -{% for file in unmatched_files %}{{ file }} -{% endfor %} - diff --git a/ietf/secr/templates/proceedings/interim_directory.html b/ietf/secr/templates/proceedings/interim_directory.html deleted file mode 100644 index 66d0b9714c9..00000000000 --- a/ietf/secr/templates/proceedings/interim_directory.html +++ /dev/null @@ -1,36 +0,0 @@ -{% extends "base_site.html" %} - -{% block content %} - -

      Interim Meeting Proceedings

      - - - - - - - - {% for meeting in meetings %} - - - - {% if meeting.schedule %} - - {% else %} - - {% endif %} - {% if meeting.minutes %} - - {% else %} - - {% endif %} - {% if meeting.get_proceedings_url %} - - {% else %} - - {% endif %} - - {% endfor %} -
      DateGroup
      {{ meeting.date }}{{ meeting.group.acronym }}AgendaAgendaMinutesMinutesProceedingsProceedings
      - -{% endblock %} \ No newline at end of file diff --git a/ietf/secr/templates/proceedings/main.html b/ietf/secr/templates/proceedings/main.html deleted file mode 100644 index a9689430a9e..00000000000 --- a/ietf/secr/templates/proceedings/main.html +++ /dev/null @@ -1,96 +0,0 @@ -{% extends "base_site.html" %} -{% load ietf_filters %} -{% load staticfiles %} -{% block title %}Proceeding manager{% endblock %} - -{% block extrahead %}{{ block.super }} - -{% endblock %} - -{% block breadcrumbs %}{{ block.super }} - » Proceedings -{% endblock %} - -{% block content %} - -
      -

      Proceedings

      -
      - - - - - - - {% if meetings %} - - {% for meeting in meetings %} - - - - {% endfor %} - - {% endif %} -
      IETF Meeting
      - {{ meeting.number }} -
      - {% if user|has_role:"Secretariat" %} -
      -
        -
      • -
      -
      - {% endif %} -
      - -
      -
      - - - - - - - {% if interim_meetings %} - - {% for meeting in interim_meetings %} - - - - - - {% endfor %} - - {% endif %} -
      Interim Meeting
      {{ meeting.group.acronym }}{{ meeting.date }}
      -
      -
      -
        -
      • -
      -
      -
      - -
      - {% if not user|has_role:"Secretariat" %} -
      -
      -

      The list(s) above includes those meetings which you can upload materials for. Click on the meeting number or interim meeting date to continue.

      - {% endif %} - - -
      -
        -
      • -
      -
      -
      - -{% endblock %} - -{% block footer-extras %} - {% include "includes/upload_footer.html" %} -{% endblock %} -~ -~ -~ \ No newline at end of file diff --git a/ietf/secr/templates/proceedings/recording.html b/ietf/secr/templates/proceedings/recording.html deleted file mode 100755 index 906218f9715..00000000000 --- a/ietf/secr/templates/proceedings/recording.html +++ /dev/null @@ -1,121 +0,0 @@ -{% extends "base_site.html" %} -{% load staticfiles %} - -{% block title %}Proceedings{% endblock %} - -{% block extrastyle %}{{ block.super }} - - -{% endblock %} - -{% block extrahead %}{{ block.super }} - - -{% endblock %} - -{% block breadcrumbs %}{{ block.super }} - {% if meeting.type_id == "interim" %} - » Proceedings - » {{ meeting }} - {% else %} - » Proceedings - » {{ meeting.number }} - » Recording - {% endif %} -{% endblock %} - -{% block content %} - -
      - -

      Recording Metadata

      - {% csrf_token %} - - - - {{ form.as_table }} - -
      - -
      -
        -
      • -
      • -
      -
      - - - - - - {% if unmatched_recordings %} - - {% endif %} - -
      - - -{% endblock %} - -{% block footer-extras %} - {% include "includes/upload_footer.html" %} -{% endblock %} diff --git a/ietf/secr/templates/proceedings/recording_edit.html b/ietf/secr/templates/proceedings/recording_edit.html deleted file mode 100755 index 83587c61582..00000000000 --- a/ietf/secr/templates/proceedings/recording_edit.html +++ /dev/null @@ -1,41 +0,0 @@ -{% extends "base_site.html" %} -{% load staticfiles %} -{% block title %}Edit Recording{% endblock %} - -{% block extrahead %}{{ block.super }} - -{% endblock %} - -{% block breadcrumbs %}{{ block.super }} - {% if meeting.type_id == "interim" %} - » Proceedings - » {{ meeting }} - » Recording - » {{ recording.name }} - {% else %} - » Proceedings - » {{ meeting.number }} - » Recording - » {{ recording.name }} - {% endif %} -{% endblock %} - -{% block content %} - -
      -

      Recording Metadata for Group: {{ form.instance.group.acronym }} | Session: {{ form.instance.session_set.first.official_scheduledsession.timeslot.time }}

      -

      Edit Recording Metadata:

      -
      {% csrf_token %} - - - - {{ form.as_table }} - -
      - - {% include "includes/buttons_save_cancel.html" %} - -
      -
      - -{% endblock %} diff --git a/ietf/secr/templates/proceedings/report_id_activity.txt b/ietf/secr/templates/proceedings/report_id_activity.txt deleted file mode 100644 index 6f2aaf097a1..00000000000 --- a/ietf/secr/templates/proceedings/report_id_activity.txt +++ /dev/null @@ -1,21 +0,0 @@ -IETF Activity since last IETF Meeting --------------------- - -IETF Activity since last IETF Meeting ({{ meeting.city }}) - -{{ new|stringformat:"3s" }} New I-Ds ({{ updated }} of which were updated, some ({{ updated_more }}) more than once) -{{ total_updated|stringformat:"3s" }} I-Ds were updated (Some more than once) -{{ last_call|stringformat:"3s" }} I-Ds Last Called -{{ approved|stringformat:"3s" }} I-Ds approved for publication - -In the final 4 weeks before meeting - -{{ ff_new_count|stringformat:"3s" }} New I-Ds were received - {{ ff_new_percent }} of total newbies since last meeting -{{ ff_update_count|stringformat:"3s" }} I-Ds were updated - {{ ff_update_percent }} of total updated since last meeting - - Week1 0 % - Week2 0 % - Week3 0 % - Week4 0 % - -The IESG Secretary. diff --git a/ietf/secr/templates/proceedings/report_progress_report.txt b/ietf/secr/templates/proceedings/report_progress_report.txt deleted file mode 100644 index 8c3d87548e6..00000000000 --- a/ietf/secr/templates/proceedings/report_progress_report.txt +++ /dev/null @@ -1,48 +0,0 @@ -{% load ams_filters %} - IETF Activity since last IETF Meeting - {{ start_date }} to {{ end_date }} - - 1) {{ action_events.count }} IESG Protocol and Document Actions this period -{% for event in action_events %} - {{ event.doc.title }} ({{ event.doc.intended_std_level }}) -{% endfor %} - - 2) {{ lc_events.count }} IESG Last Calls issued to the IETF this period -{% for event in lc_events %} - {{ event.doc.title }} - {{ event.doc.file_tag|safe }} ({{ event.doc.intended_std_level }}) -{% endfor %} - - 3) {{ new_groups.count }} New Working Group(s) formed this period - {% for group in new_groups %} - {{ group }} ({{ group.acronym }}) - {% endfor %} - - 4) {{ concluded_groups.count }} Working Group(s) concluded this period - {% for group in concluded_groups %} - {{ group }} ({{ group.acronym }}) - {% endfor %} - - 5) {{ new_docs|length }} new or revised Internet-Drafts this period - - (o - Revised Internet-Draft; + - New Internet-Draft) - - WG I-D Title - ------- ------------------------------------------ - {% for doc in new_docs %} - ({{ doc.group.acronym|stringformat:"8s" }}) {% if doc.rev == "00" %} + {% else %} o {% endif %}{{ doc.title }} - {{ doc.file_tag|safe }} - {% endfor %} - - 6) {{ rfcs.count }} RFC(s) produced this period - - S - Standard; PS - Proposed Standard; DS - Draft Standard; - B - Best Current Practices; E - Experimental; I - Informational - - RFC Stat WG Published Title -------- -- ---------- ---------- ----------------------------------------- -{% for event in rfcs %} -{{ event.doc.canonical_name|upper }} {{ event.doc.intended_std_level.name|abbr_status|stringformat:"2s" }} ({{ event.doc.group.acronym|stringformat:"8s" }}) {{ event.time|date:"M d" }} {{ event.doc.title }} -{% endfor %} - - {{ counts.std }} Standards Track; {{ counts.bcp }} BCP; {{ counts.exp }} Experimental; {{ counts.inf }} Informational diff --git a/ietf/secr/templates/proceedings/select.html b/ietf/secr/templates/proceedings/select.html deleted file mode 100755 index e2ac7e50bf2..00000000000 --- a/ietf/secr/templates/proceedings/select.html +++ /dev/null @@ -1,39 +0,0 @@ -{% extends "base_site.html" %} -{% load ietf_filters %} -{% load staticfiles %} -{% block title %}Proceedings{% endblock %} - -{% block extrahead %}{{ block.super }} - -{% endblock %} - - -{% block breadcrumbs %}{{ block.super }} - » Proceedings - » {{ meeting.number }} -{% endblock %} - -{% block instructions %} - Instructions -{% endblock %} - -{% block content %} - -
      - - - -
      - -{% endblock %} - -{% block footer-extras %} - {% include "includes/upload_footer.html" %} -{% endblock %} diff --git a/ietf/secr/templates/proceedings/status.html b/ietf/secr/templates/proceedings/status.html deleted file mode 100644 index f4b1160c559..00000000000 --- a/ietf/secr/templates/proceedings/status.html +++ /dev/null @@ -1,47 +0,0 @@ -{% extends "base_site.html" %} -{% load staticfiles %} -{% block title %}Proceedings - Status{% endblock %} - -{% block extrahead %}{{ block.super }} - -{% endblock %} - -{% block breadcrumbs %}{{ block.super }} - » Proceedings - » {{ meeting.meeting_num }} - » Status -{% endblock %} - -{% block content %} - - -
      • Changing one of the status below will result in changing the status of Proceedings {{ meeting.meeting_num }}.
      - -
      -

      IETF {{ meeting.meeting_num }}

      - - {% csrf_token %} - - - {% if not proceeding.frozen %} - - - - {% endif %} - {% if proceeding.frozen %} - - - - {% endif %} - - -
      Active Proceeding
      Frozen Proceeding
      - -
      -
        -
      • -
      -
      -
      - -{% endblock %} diff --git a/ietf/secr/templates/proceedings/view.html b/ietf/secr/templates/proceedings/view.html deleted file mode 100644 index c21d5c94b0e..00000000000 --- a/ietf/secr/templates/proceedings/view.html +++ /dev/null @@ -1,59 +0,0 @@ -{% extends "base_site.html" %} -{% load staticfiles %} -{% block title %}Proceedings - View{% endblock %} - -{% block extrahead %}{{ block.super }} - -{% endblock %} - -{% block breadcrumbs %}{{ block.super }} - » Proceedings - » {{ meeting.number }} -{% endblock %} - -{% block content %} - -
      -

      IETF {{meeting.number}} Meeting - View

      - {% if meeting.frozen == 1 %} -
      • THIS IS A FROZEN PROCEEDING
      - {% endif %} - - - - - - - -
      Meeting Start Date: {{ meeting.date }}
      Meeting End Date: {{ meeting.end_date }}
      Meeting City: {{ meeting.city }}
      Meeting Country: {{ meeting.country }}
      - - - -
      - {% if meeting.frozen == 0 %} -
        -
      • -
      • -
      • -
      - {% endif %} - {% if meeting.frozen == 1 %} -
        -
      • -
      - {% endif %} -
      -
      - -{% endblock %} \ No newline at end of file diff --git a/ietf/secr/templates/proceedings/wait.html b/ietf/secr/templates/proceedings/wait.html deleted file mode 100644 index 9590f78541b..00000000000 --- a/ietf/secr/templates/proceedings/wait.html +++ /dev/null @@ -1,30 +0,0 @@ -{% extends "base_site.html" %} -{% load staticfiles %} -{% block title %}Proceeding manager{% endblock %} - -{% block extrahead %}{{ block.super }} - -{% endblock %} - -{% block breadcrumbs %}{{ block.super }} - » Proceedings -{% endblock %} - -{% block content %} - -
      -

      Proceedings

      -
      -

      {{ message }}

      - loading... -
      - -{% endblock %} - -{% block footer-extras %} - {% include "includes/upload_footer.html" %} -{% endblock %} -~ -~ -~ - diff --git a/ietf/secr/templates/roles/main.html b/ietf/secr/templates/roles/main.html deleted file mode 100755 index 88be7cdccf6..00000000000 --- a/ietf/secr/templates/roles/main.html +++ /dev/null @@ -1,84 +0,0 @@ -{% extends "base_site.html" %} -{% load staticfiles %} - -{% block title %}Roles{% endblock %} - -{% block extrahead %}{{ block.super }} - - - - - -{% endblock %} - -{% block breadcrumbs %}{{ block.super }} - » Roles -{% endblock %} -{% block instructions %} - Instructions -{% endblock %} - -{% block content %} - -
      -
      {% csrf_token %} -

      Role Tool

      - -
      - - - - -
      - -
      -
        -
      • -
      -
      - -
      - -{% endblock %} \ No newline at end of file diff --git a/ietf/secr/templates/roles/roles.html b/ietf/secr/templates/roles/roles.html deleted file mode 100644 index 615452a4861..00000000000 --- a/ietf/secr/templates/roles/roles.html +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - - - - - - {% for role in roles %} - - - - - - - {% endfor %} - -
      RoleNameEmailAction
      {{ role.name }}{{ role.person }}{{ role.email }}Delete
      diff --git a/ietf/secr/templates/rolodex/add.html b/ietf/secr/templates/rolodex/add.html index 08a97986607..5adb738f2b0 100644 --- a/ietf/secr/templates/rolodex/add.html +++ b/ietf/secr/templates/rolodex/add.html @@ -1,5 +1,5 @@ {% extends "base_site.html" %} -{% load staticfiles %} +{% load static %} {% block title %}Rolodex - Add{% endblock %} @@ -41,7 +41,7 @@

      Name

      {% csrf_token %} - + {{ form.as_table }}
      diff --git a/ietf/secr/templates/rolodex/add_proceed.html b/ietf/secr/templates/rolodex/add_proceed.html index 0251cc44d43..0b1acfbb17a 100644 --- a/ietf/secr/templates/rolodex/add_proceed.html +++ b/ietf/secr/templates/rolodex/add_proceed.html @@ -15,7 +15,7 @@

      Adding {{ name }}

      Rolodex - Add

      - + {{ form.as_table }}
      diff --git a/ietf/secr/templates/rolodex/edit.html b/ietf/secr/templates/rolodex/edit.html index ee7a4db5e5d..ed4c0f97e2e 100644 --- a/ietf/secr/templates/rolodex/edit.html +++ b/ietf/secr/templates/rolodex/edit.html @@ -1,5 +1,5 @@ {% extends "base_site.html" %} -{% load staticfiles %} +{% load static %} {% block title %}Rolodex - Edit{% endblock %} @@ -19,7 +19,7 @@

      Rolodex - Edit

      - + {{ person_form.as_table }}
      @@ -43,7 +43,7 @@

      Email Addresses

      {% for form in email_formset.forms %} {% if form.non_field_errors %}{{ form.non_field_errors }}{% endif %} - + {# Include the hidden fields in the form #} {% for hidden in form.hidden_fields %} diff --git a/ietf/secr/templates/rolodex/search.html b/ietf/secr/templates/rolodex/search.html index 7dcaf282462..065b0463f89 100644 --- a/ietf/secr/templates/rolodex/search.html +++ b/ietf/secr/templates/rolodex/search.html @@ -1,5 +1,5 @@ {% extends "base_site.html" %} -{% load staticfiles %} +{% load static %} {% block title %}Rolodex - Search{% endblock %} @@ -17,7 +17,7 @@

      Rolodex - Search Add{% csrf_token %} - + {{ form.as_table }}
      diff --git a/ietf/secr/templates/rolodex/view.html b/ietf/secr/templates/rolodex/view.html index 738ab3361a0..d1a78cfaa54 100644 --- a/ietf/secr/templates/rolodex/view.html +++ b/ietf/secr/templates/rolodex/view.html @@ -44,9 +44,9 @@

      Roles

      {{ role.name }} {% if role.group.type.slug == "area" %} -
      {{ role.group.acronym }}{% if role.group.state.slug == "conclude" %} (concluded){% endif %} + {{ role.group.acronym }}{% if role.group.state.slug == "conclude" %} (concluded){% endif %} {% else %} - {{ role.group.acronym }}{% if role.group.state.slug == "conclude" %} (concluded){% endif %} + {{ role.group.acronym }}{% if role.group.state.slug == "conclude" %} (concluded){% endif %} {% endif %} {{ role.email }} diff --git a/ietf/secr/templates/sreq/confirm.html b/ietf/secr/templates/sreq/confirm.html deleted file mode 100755 index 4bf26dd8589..00000000000 --- a/ietf/secr/templates/sreq/confirm.html +++ /dev/null @@ -1,57 +0,0 @@ -{% extends "base_site.html" %} -{% load staticfiles %} - -{% block title %}Sessions - Confirm{% endblock %} - -{% block extrastyle %} - -{% endblock %} - -{% block extrahead %}{{ block.super }} - - {{ form.media }} -{% endblock %} - -{% block breadcrumbs %}{{ block.super }} - » Sessions - » New - » Session Request Confirmation -{% endblock %} - -{% block content %} - -
      -

      Sessions - Confirm

      - - {% include "includes/sessions_request_view.html" %} - - {% if group.features.acts_like_wg and form.session_forms.forms_to_keep|length > 2 %} -
      -

      - - Note: Your request for a third session must be approved by an area director before - being submitted to agenda@ietf.org. Click "Submit" below to email an approval - request to the area directors. - -

      -
      - {% endif %} - - - {% csrf_token %} - {{ form }} - {{ form.session_forms.management_form }} - {% for sf in form.session_forms %} - {% include 'meeting/session_details_form.html' with form=sf hidden=True only %} - {% endfor %} - {% include "includes/buttons_submit_cancel.html" %} - - -
      - -{% endblock %} \ No newline at end of file diff --git a/ietf/secr/templates/sreq/edit.html b/ietf/secr/templates/sreq/edit.html deleted file mode 100755 index b0bfbc1e0c1..00000000000 --- a/ietf/secr/templates/sreq/edit.html +++ /dev/null @@ -1,39 +0,0 @@ -{% extends "base_site.html" %} -{% load staticfiles %} -{% block title %}Sessions - Edit{% endblock %} - -{% block extrahead %}{{ block.super }} - - - {{ form.media }} - -{% endblock %} - -{% block breadcrumbs %}{{ block.super }} - » Sessions - » {{ group.acronym }} - » Edit -{% endblock %} - -{% block instructions %} - Instructions -{% endblock %} - -{% block content %} -
      -

      IETF {{ meeting.number }}: Edit Session Request

      - -
      -{% endblock %} - -{% block footer-extras %} - {% include "includes/sessions_footer.html" %} -{% endblock %} \ No newline at end of file diff --git a/ietf/secr/templates/sreq/locked.html b/ietf/secr/templates/sreq/locked.html deleted file mode 100755 index 5f619f37cb6..00000000000 --- a/ietf/secr/templates/sreq/locked.html +++ /dev/null @@ -1,30 +0,0 @@ -{% extends "base_site.html" %} -{% load staticfiles %} - -{% block title %}Sessions{% endblock %} - -{% block extrahead %}{{ block.super }} - -{% endblock %} - -{% block breadcrumbs %}{{ block.super }} - » Sessions (Locked) -{% endblock %} - -{% block content %} -

      » View list of timeslot requests

      -
      -

      Sessions - Status

      - -

      {{ message }}

      - -
      -
        -
      • -
      -
      - - -
      - -{% endblock %} \ No newline at end of file diff --git a/ietf/secr/templates/sreq/main.html b/ietf/secr/templates/sreq/main.html deleted file mode 100755 index bdb33bb77d0..00000000000 --- a/ietf/secr/templates/sreq/main.html +++ /dev/null @@ -1,65 +0,0 @@ -{% extends "base_site.html" %} -{% load ietf_filters %} -{% load staticfiles %} - -{% block title %}Sessions{% endblock %} - -{% block extrahead %}{{ block.super }} - -{% endblock %} - -{% block breadcrumbs %}{{ block.super }} - » Sessions -{% endblock %} -{% block instructions %} - Instructions -{% endblock %} - -{% block content %} -

      » View list of timeslot requests

      -
      -

      - Sessions Request Tool: IETF {{ meeting.number }} - {% if user|has_role:"Secretariat" %} - {% if is_locked %} - Tool Status: Locked - {% else %} - Tool Status: Unlocked - {% endif %} - {% endif %} -

      - -
      - -
      - -{% endblock %} - -{% block footer-extras %} - {% include "includes/sessions_footer.html" %} -{% endblock %} \ No newline at end of file diff --git a/ietf/secr/templates/sreq/new.html b/ietf/secr/templates/sreq/new.html deleted file mode 100755 index 2c6afb55767..00000000000 --- a/ietf/secr/templates/sreq/new.html +++ /dev/null @@ -1,43 +0,0 @@ -{% extends "base_site.html" %} -{% load staticfiles %} - -{% block title %}Sessions- New{% endblock %} - -{% block extrahead %}{{ block.super }} - - - {{ form.media }} - -{% endblock %} - -{% block breadcrumbs %}{{ block.super }} - » Sessions - » New Session Request -{% endblock %} - -{% block instructions %} - Instructions -{% endblock %} - -{% block content %} -
      -

      IETF {{ meeting.number }}: New Session Request

      - - {% include "includes/sessions_request_form.html" %} - -
      - -{% endblock %} - -{% block footer-extras %} - {% include "includes/sessions_footer.html" %} -{% endblock %} \ No newline at end of file diff --git a/ietf/secr/templates/sreq/not_meeting_notification.txt b/ietf/secr/templates/sreq/not_meeting_notification.txt deleted file mode 100644 index 1120f8480c1..00000000000 --- a/ietf/secr/templates/sreq/not_meeting_notification.txt +++ /dev/null @@ -1,7 +0,0 @@ -{% load ams_filters %} - -{{ login|smart_login }} {{ group.acronym }} working group, indicated that the {{ group.acronym }} working group does not plan to hold a session at IETF {{ meeting.number }}. - -This message was generated and sent by the IETF Meeting Session Request Tool. - - diff --git a/ietf/secr/templates/sreq/session_approval_notification.txt b/ietf/secr/templates/sreq/session_approval_notification.txt deleted file mode 100644 index 7bb63aa3fa0..00000000000 --- a/ietf/secr/templates/sreq/session_approval_notification.txt +++ /dev/null @@ -1,15 +0,0 @@ -Dear {{ group.parent }} Director(s): - -{{ header }} meeting session request has just been -submitted by {{ requester }}. -The third session requires your approval. - -To approve the session go to the session request view here: -{{ settings.IDTRACKER_BASE_URL }}{% url "ietf.secr.sreq.views.view" acronym=group.acronym %} -and click "Approve Third Session". - -Regards, - -The IETF Secretariat. - -{% include "includes/session_info.txt" %} diff --git a/ietf/secr/templates/sreq/session_cancel_notification.txt b/ietf/secr/templates/sreq/session_cancel_notification.txt deleted file mode 100644 index 3e6dd43f693..00000000000 --- a/ietf/secr/templates/sreq/session_cancel_notification.txt +++ /dev/null @@ -1,4 +0,0 @@ -{% load ams_filters %} - -A request to cancel a meeting session has just been submitted by {{ requester }}. - diff --git a/ietf/secr/templates/sreq/session_request_notification.txt b/ietf/secr/templates/sreq/session_request_notification.txt deleted file mode 100644 index db200604060..00000000000 --- a/ietf/secr/templates/sreq/session_request_notification.txt +++ /dev/null @@ -1,5 +0,0 @@ -{% load ams_filters %} - -{{ header }} meeting session request has just been submitted by {{ requester }}. - -{% include "includes/session_info.txt" %} diff --git a/ietf/secr/templates/sreq/tool_status.html b/ietf/secr/templates/sreq/tool_status.html deleted file mode 100755 index 5e30d5a0188..00000000000 --- a/ietf/secr/templates/sreq/tool_status.html +++ /dev/null @@ -1,42 +0,0 @@ -{% extends "base_site.html" %} -{% load staticfiles %} - -{% block title %}Sessions{% endblock %} - -{% block extrahead %}{{ block.super }} - -{% endblock %} - -{% block breadcrumbs %}{{ block.super }} - » Sessions - » Session Status -{% endblock %} - -{% block content %} - -
      -

      Sessions - Status

      -

      Enter the message that you would like displayed to the WG Chair when this tool is locked.

      -
      {% csrf_token %} - - - - {{ form.as_table }} - -
      -
      -
        - {% if is_locked %} -
      • - {% else %} -
      • - {% endif %} -
      • -
      -
      - -
      - -
      - -{% endblock %} diff --git a/ietf/secr/templates/sreq/view.html b/ietf/secr/templates/sreq/view.html deleted file mode 100644 index 34994c4fb1b..00000000000 --- a/ietf/secr/templates/sreq/view.html +++ /dev/null @@ -1,46 +0,0 @@ -{% extends "base_site.html" %} -{% load staticfiles %} - -{% block title %}Sessions - View{% endblock %} - -{% block extrahead %}{{ block.super }} - -{% endblock %} - -{% block breadcrumbs %}{{ block.super }} - » Sessions - » {{ group.acronym }} -{% endblock %} - -{% block instructions %} - Instructions -{% endblock %} - -{% block content %} - -
      -

      Sessions - View (meeting: {{ meeting.number }})

      - - {% include "includes/sessions_request_view.html" %} - -
      - - {% include "includes/activities.html" %} - -
      -
        -
      • - {% if show_approve_button %} -
      • - {% endif %} -
      • -
      • -
      -
      -
      - -{% endblock %} - -{% block footer-extras %} - {% include "includes/sessions_footer.html" %} -{% endblock %} diff --git a/ietf/secr/templates/telechat/base_telechat.html b/ietf/secr/templates/telechat/base_telechat.html index 73d42ea71e2..1c8feaff6fd 100644 --- a/ietf/secr/templates/telechat/base_telechat.html +++ b/ietf/secr/templates/telechat/base_telechat.html @@ -1,5 +1,5 @@ {% extends "base_site.html" %} -{% load staticfiles %} +{% load static %} {% block title %}Telechat{% endblock %} diff --git a/ietf/secr/templates/telechat/doc.html b/ietf/secr/templates/telechat/doc.html index b7fc782d912..6727e157f57 100644 --- a/ietf/secr/templates/telechat/doc.html +++ b/ietf/secr/templates/telechat/doc.html @@ -61,7 +61,7 @@

      {{ document.name }}-{{ document.rev }} ({{ document.intended_std_level }}){% csrf_token %} - + {{ state_form.as_table }}
      @@ -85,13 +85,13 @@

      Ballot Writeup

      {% if downrefs %}

      Downward References

      {% for ref in downrefs %} -

      Add {{ref.target.document.canonical_name}} - ({{ref.target.document.std_level}} - {{ref.target.document.stream.desc}}) +

      Add {{ref.target.name}} + ({{ref.target.std_level}} - {{ref.target.stream.desc}} stream) to downref registry.
      - {% if not ref.target.document.std_level %} + {% if not ref.target.std_level %} +++ Warning: The standards level has not been set yet!!!
      {% endif %} - {% if not ref.target.document.stream %} + {% if not ref.target.stream %} +++ Warning: document stream has not been set yet!!!
      {% endif %} {% endfor %}

      diff --git a/ietf/secr/templates/telechat/group.html b/ietf/secr/templates/telechat/group.html index 288316e9009..4e04f0e16e5 100644 --- a/ietf/secr/templates/telechat/group.html +++ b/ietf/secr/templates/telechat/group.html @@ -3,9 +3,9 @@ Does anyone have an objection to the creation of this working group being sent for EXTERNAL REVIEW?

      External Review APPROVED; "The Secretariat will send a Working Group Review announcement with a copy to new-work and place it back on the agenda for the next telechat."

      External Review NOT APPROVED; -
      +
      The Secretariat will wait for instructions from
      - The IESG decides the document needs more thime in INTERNAL REVIEW. The Secreatriat will put it back on the agenda for the next teleconference in the same category.
      + The IESG decides the document needs more time in INTERNAL REVIEW. The Secretariat will put it back on the agenda for the next teleconference in the same category.
      The IESG has made changes since the charter was seen in INTERNAL REVIEW, and decides to send it back to INTERNAL REVIEW the charter again.
      {% endif %} @@ -30,4 +30,4 @@ Yes, the charter is NOT APPROVED; The charter needs more work, or the IESG decides to shelve formation of the working group. "The Secretariat will await further instruction from regarding the rechartering of this working group."

      {% endif %} - + \ No newline at end of file diff --git a/ietf/secr/urls.py b/ietf/secr/urls.py index 196f139b2e6..ab210466544 100644 --- a/ietf/secr/urls.py +++ b/ietf/secr/urls.py @@ -1,16 +1,22 @@ -from django.conf.urls import url, include +# Copyright The IETF Trust 2025, All Rights Reserved + +from django.conf import settings +from django.urls import re_path, include from django.views.generic import TemplateView +from django.views.generic.base import RedirectView urlpatterns = [ - url(r'^$', TemplateView.as_view(template_name='main.html')), - url(r'^announcement/', include('ietf.secr.announcement.urls')), - url(r'^areas/', include('ietf.secr.areas.urls')), - url(r'^console/', include('ietf.secr.console.urls')), - url(r'^groups/', include('ietf.secr.groups.urls')), - url(r'^meetings/', include('ietf.secr.meetings.urls')), - url(r'^proceedings/', include('ietf.secr.proceedings.urls')), - url(r'^roles/', include('ietf.secr.roles.urls')), - url(r'^rolodex/', include('ietf.secr.rolodex.urls')), - url(r'^sreq/', include('ietf.secr.sreq.urls')), - url(r'^telechat/', include('ietf.secr.telechat.urls')), + re_path(r'^$', TemplateView.as_view(template_name='index.html'), name='ietf.secr'), + re_path(r'^announcement/', include('ietf.secr.announcement.urls')), + re_path(r'^meetings/', include('ietf.secr.meetings.urls')), + re_path(r'^rolodex/', include('ietf.secr.rolodex.urls')), + # remove these redirects after 125 + re_path(r'^sreq/$', RedirectView.as_view(url='/meeting/session/request/', permanent=True)), + re_path(r'^sreq/%(acronym)s/$' % settings.URL_REGEXPS, RedirectView.as_view(url='/meeting/session/request/%(acronym)s/view/', permanent=True)), + re_path(r'^sreq/%(acronym)s/edit/$' % settings.URL_REGEXPS, RedirectView.as_view(url='/meeting/session/request/%(acronym)s/edit/', permanent=True)), + re_path(r'^sreq/%(acronym)s/new/$' % settings.URL_REGEXPS, RedirectView.as_view(url='/meeting/session/request/%(acronym)s/new/', permanent=True)), + re_path(r'^sreq/(?P[A-Za-z0-9_\-\+]+)/%(acronym)s/view/$' % settings.URL_REGEXPS, RedirectView.as_view(url='/meeting/%(num)s/session/request/%(acronym)s/view/', permanent=True)), + re_path(r'^sreq/(?P[A-Za-z0-9_\-\+]+)/%(acronym)s/edit/$' % settings.URL_REGEXPS, RedirectView.as_view(url='/meeting/%(num)s/session/request/%(acronym)s/edit/', permanent=True)), + # --------------------------------- + re_path(r'^telechat/', include('ietf.secr.telechat.urls')), ] diff --git a/ietf/secr/utils/decorators.py b/ietf/secr/utils/decorators.py index 3dcba2c9669..5887c3c9ccd 100644 --- a/ietf/secr/utils/decorators.py +++ b/ietf/secr/utils/decorators.py @@ -1,12 +1,12 @@ # Copyright The IETF Trust 2013-2020, All Rights Reserved from functools import wraps +from urllib.parse import quote as urlquote from django.conf import settings from django.contrib.auth import REDIRECT_FIELD_NAME from django.core.exceptions import ObjectDoesNotExist from django.http import HttpResponseRedirect from django.shortcuts import render, get_object_or_404 -from django.utils.http import urlquote from ietf.ietfauth.utils import has_role from ietf.doc.models import Document @@ -18,7 +18,7 @@ def check_for_cancel(redirect_url): """ - Decorator to make a view redirect to the given url if the reuqest is a POST which contains + Decorator to make a view redirect to the given url if the request is a POST which contains a submit=Cancel. """ def decorator(func): diff --git a/ietf/secr/utils/document.py b/ietf/secr/utils/document.py index 0a34512a173..361bf836dfd 100644 --- a/ietf/secr/utils/document.py +++ b/ietf/secr/utils/document.py @@ -13,15 +13,6 @@ def get_full_path(doc): return None return os.path.join(doc.get_file_path(), doc.uploaded_filename) -def get_rfc_num(doc): - qs = doc.docalias.filter(name__startswith='rfc') - return qs[0].name[3:] if qs else None - -def is_draft(doc): - if doc.docalias.filter(name__startswith='rfc'): - return False - else: - return True def get_start_date(doc): ''' diff --git a/ietf/secr/utils/group.py b/ietf/secr/utils/group.py deleted file mode 100644 index 44ef5f02221..00000000000 --- a/ietf/secr/utils/group.py +++ /dev/null @@ -1,74 +0,0 @@ -# Copyright The IETF Trust 2013-2020, All Rights Reserved -# -*- coding: utf-8 -*- - - -# Python imports -import io -import os - -# Django imports -from django.conf import settings -from django.core.exceptions import ObjectDoesNotExist - -# Datatracker imports -from ietf.group.models import Group -from ietf.ietfauth.utils import has_role - - - - -def current_nomcom(): - qs = Group.objects.filter(acronym__startswith='nomcom',state__slug="active").order_by('-time') - if qs.count(): - return qs[0] - else: - return None - -def get_charter_text(group): - ''' - Takes a group object and returns the text or the group's charter as a string - ''' - charter = group.charter - path = os.path.join(settings.CHARTER_PATH, '%s-%s.txt' % (charter.canonical_name(), charter.rev)) - f = io.open(path,'r') - text = f.read() - f.close() - - return text - -def get_my_groups(user,conclude=False): - ''' - Takes a Django user object (from request) - Returns a list of groups the user has access to. Rules are as follows - secretariat - has access to all groups - area director - has access to all groups in their area - wg chair or secretary - has acceses to their own group - chair of irtf has access to all irtf groups - - If user=None than all groups are returned. - concluded=True means include concluded groups. Need this to upload materials for groups - after they've been concluded. it happens. - ''' - my_groups = set() - states = ['bof','proposed','active'] - if conclude: - states.extend(['conclude','bof-conc']) - - all_groups = Group.objects.filter(type__features__has_meetings=True, state__in=states).order_by('acronym') - if user == None or has_role(user,'Secretariat'): - return all_groups - - try: - person = user.person - except ObjectDoesNotExist: - return list() - - for group in all_groups: - if group.role_set.filter(person=person,name__in=('chair','secr','ad')): - my_groups.add(group) - continue - if group.parent and group.parent.role_set.filter(person=person,name__in=('ad','chair')): - my_groups.add(group) - continue - - return list(my_groups) diff --git a/ietf/settings.py b/ietf/settings.py index 0edf20229b2..d2a622d63e6 100644 --- a/ietf/settings.py +++ b/ietf/settings.py @@ -1,4 +1,4 @@ -# Copyright The IETF Trust 2007-2022, All Rights Reserved +# Copyright The IETF Trust 2007-2026, All Rights Reserved # -*- coding: utf-8 -*- @@ -9,23 +9,42 @@ import os import sys import datetime +import pathlib import warnings +from hashlib import sha384 from typing import Any, Dict, List, Tuple # pyflakes:ignore +from django.http import UnreadablePostError +# DeprecationWarnings are suppressed by default, enable them warnings.simplefilter("always", DeprecationWarning) -warnings.filterwarnings("ignore", message="The logout\(\) view is superseded by") + +# Warnings that must be resolved for Django 5.x +warnings.filterwarnings("ignore", "Log out via GET requests is deprecated") # caused by oidc_provider +warnings.filterwarnings("ignore", message="The django.utils.timezone.utc alias is deprecated.", module="oidc_provider") +warnings.filterwarnings("ignore", message="The django.utils.datetime_safe module is deprecated.", module="tastypie") +warnings.filterwarnings("ignore", message="The USE_DEPRECATED_PYTZ setting,") # https://github.com/ietf-tools/datatracker/issues/5635 +warnings.filterwarnings("ignore", message="The is_dst argument to make_aware\\(\\)") # caused by django-filters when USE_DEPRECATED_PYTZ is true +warnings.filterwarnings("ignore", message="The USE_L10N setting is deprecated.") # https://github.com/ietf-tools/datatracker/issues/5648 +warnings.filterwarnings("ignore", message="django.contrib.auth.hashers.CryptPasswordHasher is deprecated.") # https://github.com/ietf-tools/datatracker/issues/5663 + +# Other DeprecationWarnings +warnings.filterwarnings("ignore", message="pkg_resources is deprecated as an API", module="pyang.plugin") warnings.filterwarnings("ignore", message="Report.file_reporters will no longer be available in Coverage.py 4.2", module="coverage.report") -warnings.filterwarnings("ignore", message="{% load staticfiles %} is deprecated") -warnings.filterwarnings("ignore", message="Using or importing the ABCs from 'collections' instead of from 'collections.abc' is deprecated", module="bleach") +warnings.filterwarnings("ignore", message="currentThread\\(\\) is deprecated", module="coverage.pytracer") +warnings.filterwarnings("ignore", message="co_lnotab is deprecated", module="coverage.parser") +warnings.filterwarnings("ignore", message="datetime.datetime.utcnow\\(\\) is deprecated", module="botocore.auth") +warnings.filterwarnings("ignore", message="datetime.datetime.utcnow\\(\\) is deprecated", module="oic.utils.time_util") +warnings.filterwarnings("ignore", message="datetime.datetime.utcfromtimestamp\\(\\) is deprecated", module="oic.utils.time_util") +warnings.filterwarnings("ignore", message="datetime.datetime.utcfromtimestamp\\(\\) is deprecated", module="pytz.tzinfo") +warnings.filterwarnings("ignore", message="'instantiateVariableFont' is deprecated", module="weasyprint") -try: - import syslog - syslog.openlog(str("datatracker"), syslog.LOG_PID, syslog.LOG_USER) -except ImportError: - pass -BASE_DIR = os.path.dirname(os.path.abspath(__file__)) -sys.path.append(os.path.abspath(BASE_DIR + "/..")) +base_path = pathlib.Path(__file__).resolve().parent +BASE_DIR = str(base_path) + +project_path = base_path.parent +PROJECT_DIR = str(project_path) +sys.path.append(PROJECT_DIR) from ietf import __version__ import debug @@ -43,17 +62,12 @@ # Domain name of the IETF IETF_DOMAIN = 'ietf.org' +# Overriden in settings_local ADMINS = [ -# ('Henrik Levkowetz', 'henrik@levkowetz.com'), - ('Robert Sparks', 'rjsparks@nostrum.com'), -# ('Ole Laursen', 'olau@iola.dk'), - ('Ryan Cross', 'rcross@amsl.com'), - ('Glen Barney', 'glen@amsl.com'), - ('Maddy Conner', 'maddy@amsl.com'), - ('Kesara Rathnayaka', 'krathnayake@ietf.org'), + ('Tools Help', 'tools-help@ietf.org'), ] # type: List[Tuple[str, str]] -BUG_REPORT_EMAIL = "datatracker-project@ietf.org" +BUG_REPORT_EMAIL = "tools-help@ietf.org" PASSWORD_HASHERS = [ 'django.contrib.auth.hashers.Argon2PasswordHasher', @@ -63,6 +77,26 @@ 'django.contrib.auth.hashers.CryptPasswordHasher', ] + +PASSWORD_POLICY_MIN_LENGTH = 12 +PASSWORD_POLICY_ENFORCE_AT_LOGIN = False # should turn this on for prod + +AUTH_PASSWORD_VALIDATORS = [ + { + "NAME": "django.contrib.auth.password_validation.MinimumLengthValidator", + "OPTIONS": { + "min_length": PASSWORD_POLICY_MIN_LENGTH, + } + }, + { + "NAME": "ietf.ietfauth.password_validation.StrongPasswordValidator", + }, +] +# In dev environments, settings_local overrides the password validators. Save +# a handle to the original value so settings_test can restore it so tests match +# production. +ORIG_AUTH_PASSWORD_VALIDATORS = AUTH_PASSWORD_VALIDATORS + ALLOWED_HOSTS = [".ietf.org", ".ietf.org.", "209.208.19.216", "4.31.198.44", "127.0.0.1", "localhost", ] # Server name of the tools server @@ -79,28 +113,20 @@ DATABASES = { 'default': { - 'NAME': 'ietf_utf8', - 'ENGINE': 'django.db.backends.mysql', + 'NAME': 'datatracker', + 'ENGINE': 'django.db.backends.postgresql_psycopg2', 'USER': 'ietf', - #'PASSWORD': 'ietf', - 'OPTIONS': { - 'sql_mode': 'STRICT_TRANS_TABLES', - 'init_command': 'SET storage_engine=MyISAM; SET names "utf8"' - }, + #'PASSWORD': 'somepassword', }, } -DATABASE_TEST_OPTIONS = { - # Comment this out if your database doesn't support InnoDB - 'init_command': 'SET storage_engine=InnoDB', -} # Local time zone for this installation. Choices can be found here: # http://www.postgresql.org/docs/8.1/static/datetime-keywords.html#DATETIME-TIMEZONE-SET-TABLE # although not all variations may be possible on all operating systems. # If running in a Windows environment this must be set to the same as your # system time zone. -TIME_ZONE = 'PST8PDT' +TIME_ZONE = 'America/Los_Angeles' # Language code for this installation. All choices can be found here: # http://www.w3.org/TR/REC-html40/struct/dirlang.html#langcodes @@ -113,7 +139,27 @@ # to load the internationalization machinery. USE_I18N = False -USE_TZ = False +# Django 4.0 changed the default setting of USE_L10N to True. The setting +# is deprecated and will be removed in Django 5.0. +USE_L10N = False + +USE_TZ = True +USE_DEPRECATED_PYTZ = True # supported until Django 5 + +# The DjangoDivFormRenderer is a transitional class that opts in to defaulting to the div.html +# template for formsets. This will become the default behavior in Django 5.0. This configuration +# can be removed at that point. +# See https://docs.djangoproject.com/en/4.2/releases/4.1/#forms +FORM_RENDERER = "django.forms.renderers.DjangoDivFormRenderer" + +# Default primary key field type to use for models that don’t have a field with primary_key=True. +# In the future (relative to 4.2), the default will become 'django.db.models.BigAutoField.' +DEFAULT_AUTO_FIELD = 'django.db.models.AutoField' + +# OIDC configuration +_SITE_URL = os.environ.get("OIDC_SITE_URL", None) +if _SITE_URL is not None: + SITE_URL = _SITE_URL if SERVER_MODE == 'production': MEDIA_ROOT = '/a/www/www6s/lib/dt/media/' @@ -149,7 +195,6 @@ # Absolute path to the directory static files should be collected to. # Example: "/var/www/example.com/static/" - SERVE_CDN_PHOTOS = True SERVE_CDN_FILES_LOCALLY_IN_DEV_MODE = True @@ -159,7 +204,7 @@ STATIC_URL = "/static/" STATIC_ROOT = os.path.abspath(BASE_DIR + "/../static/") else: - STATIC_URL = "https://www.ietf.org/lib/dt/%s/"%__version__ + STATIC_URL = "https://static.ietf.org/dt/%s/"%__version__ STATIC_ROOT = "/a/www/www6s/lib/dt/%s/"%__version__ # List of finder classes that know how to find static files in @@ -169,165 +214,147 @@ 'django.contrib.staticfiles.finders.AppDirectoriesFinder', ) +# Client-side static.ietf.org URL +STATIC_IETF_ORG = "https://static.ietf.org" +# Server-side static.ietf.org URL (used in pdfized) +STATIC_IETF_ORG_INTERNAL = STATIC_IETF_ORG + +ENABLE_BLOBSTORAGE = True + +# "standard" retry mode is used, which does exponential backoff with a base factor of 2 +# and a cap of 20. +BLOBSTORAGE_MAX_ATTEMPTS = 5 # boto3 default is 3 (for "standard" retry mode) +BLOBSTORAGE_CONNECT_TIMEOUT = 10 # seconds; boto3 default is 60 +BLOBSTORAGE_READ_TIMEOUT = 10 # seconds; boto3 default is 60 + +# Caching for agenda data in seconds +AGENDA_CACHE_TIMEOUT_DEFAULT = 8 * 24 * 60 * 60 # 8 days +AGENDA_CACHE_TIMEOUT_CURRENT_MEETING = 6 * 60 # 6 minutes + + WSGI_APPLICATION = "ietf.wsgi.application" -AUTHENTICATION_BACKENDS = ( 'django.contrib.auth.backends.ModelBackend', ) +AUTHENTICATION_BACKENDS = ( 'ietf.ietfauth.backends.CaseInsensitiveModelBackend', ) -FILE_UPLOAD_PERMISSIONS = 0o644 +FILE_UPLOAD_PERMISSIONS = 0o644 -# ------------------------------------------------------------------------ -# Django/Python Logging Framework Modifications +FIRST_V3_RFC = 8650 -# Filter out "Invalid HTTP_HOST" emails -# Based on http://www.tiwoc.de/blog/2013/03/django-prevent-email-notification-on-suspiciousoperation/ -from django.core.exceptions import SuspiciousOperation -def skip_suspicious_operations(record): - if record.exc_info: - exc_value = record.exc_info[1] - if isinstance(exc_value, SuspiciousOperation): - return False - return True -# Filter out UreadablePostError: -from django.http import UnreadablePostError +# +# Logging config +# + +# Callback to filter out UnreadablePostError: def skip_unreadable_post(record): if record.exc_info: - exc_type, exc_value = record.exc_info[:2] # pylint: disable=unused-variable + exc_type, exc_value = record.exc_info[:2] # pylint: disable=unused-variable if isinstance(exc_value, UnreadablePostError): return False return True -# Copied from DEFAULT_LOGGING as of Django 1.10.5 on 22 Feb 2017, and modified -# to incorporate html logging, invalid http_host filtering, and more. -# Changes from the default has comments. - -# The Python logging flow is as follows: -# (see https://docs.python.org/2.7/howto/logging.html#logging-flow) -# -# Init: get a Logger: logger = logging.getLogger(name) -# -# Logging call, e.g. logger.error(level, msg, *args, exc_info=(...), extra={...}) -# --> Logger (discard if level too low for this logger) -# (create log record from level, msg, args, exc_info, extra) -# --> Filters (discard if any filter attach to logger rejects record) -# --> Handlers (discard if level too low for handler) -# --> Filters (discard if any filter attached to handler rejects record) -# --> Formatter (format log record and emit) -# - LOGGING = { - 'version': 1, - 'disable_existing_loggers': False, - # - 'loggers': { - 'django': { - 'handlers': ['debug_console', 'mail_admins'], - 'level': 'INFO', + "version": 1, + "disable_existing_loggers": False, + "loggers": { + "celery": { + "handlers": ["console"], + "level": "INFO", }, - 'django.request': { - 'handlers': ['debug_console'], - 'level': 'ERROR', + "datatracker": { + "handlers": ["console"], + "level": "INFO", }, - 'django.server': { - 'handlers': ['django.server'], - 'level': 'INFO', + "django": { + "handlers": ["console", "mail_admins"], + "level": "INFO", }, - 'django.security': { - 'handlers': ['debug_console', ], - 'level': 'INFO', + "django.request": {"level": "ERROR"}, # only log 5xx, ignore 4xx + "django.security": { + # SuspiciousOperation errors - log to console only + "handlers": ["console"], + "propagate": False, # no further handling please }, - 'oidc_provider': { - 'handlers': ['debug_console', ], - 'level': 'DEBUG', - }, - }, - # - # No logger filters - # - 'handlers': { - 'console': { - 'level': 'DEBUG', - 'class': 'logging.StreamHandler', - 'formatter': 'plain', + "django.server": { + # Only used by Django's runserver development server + "handlers": ["django.server"], + "level": "INFO", + }, + "oidc_provider": { + "handlers": ["console"], + "level": "DEBUG", }, - 'syslog': { - 'level': 'DEBUG', - 'class': 'logging.handlers.SysLogHandler', - 'facility': 'user', - 'formatter': 'plain', - 'address': '/dev/log', + }, + "handlers": { + "console": { + "level": "DEBUG", + "class": "logging.StreamHandler", + "formatter": "plain", }, - 'debug_console': { - # Active only when DEBUG=True - 'level': 'DEBUG', - 'filters': ['require_debug_true'], - 'class': 'logging.StreamHandler', - 'formatter': 'plain', + "debug_console": { + "level": "DEBUG", + "filters": ["require_debug_true"], + "class": "logging.StreamHandler", + "formatter": "plain", }, - 'django.server': { - 'level': 'INFO', - 'class': 'logging.StreamHandler', - 'formatter': 'django.server', + "django.server": { + "level": "INFO", + "class": "logging.StreamHandler", + "formatter": "django.server", }, - 'mail_admins': { - 'level': 'ERROR', - 'filters': [ - 'require_debug_false', - 'skip_suspicious_operations', # custom - 'skip_unreadable_posts', # custom + "mail_admins": { + "level": "ERROR", + "filters": [ + "require_debug_false", + "skip_unreadable_posts", ], - 'class': 'django.utils.log.AdminEmailHandler', - 'include_html': True, # non-default - } + "class": "django.utils.log.AdminEmailHandler", + "include_html": True, + }, }, - # # All these are used by handlers - 'filters': { - 'require_debug_false': { - '()': 'django.utils.log.RequireDebugFalse', - }, - 'require_debug_true': { - '()': 'django.utils.log.RequireDebugTrue', + "filters": { + "require_debug_false": { + "()": "django.utils.log.RequireDebugFalse", }, - # custom filter, function defined above: - 'skip_suspicious_operations': { - '()': 'django.utils.log.CallbackFilter', - 'callback': skip_suspicious_operations, + "require_debug_true": { + "()": "django.utils.log.RequireDebugTrue", }, # custom filter, function defined above: - 'skip_unreadable_posts': { - '()': 'django.utils.log.CallbackFilter', - 'callback': skip_unreadable_post, + "skip_unreadable_posts": { + "()": "django.utils.log.CallbackFilter", + "callback": skip_unreadable_post, }, }, - # And finally the formatters - 'formatters': { - 'django.server': { - '()': 'django.utils.log.ServerFormatter', - 'format': '[%(server_time)s] %(message)s', + "formatters": { + "django.server": { + "()": "django.utils.log.ServerFormatter", + "format": "[{server_time}] {message}", + "style": "{", }, - 'plain': { - 'style': '{', - 'format': '{levelname}: {name}:{lineno}: {message}', + "plain": { + "style": "{", + "format": "{levelname}: {name}:{lineno}: {message}", + }, + "json": { + "class": "ietf.utils.jsonlogger.DatatrackerJsonFormatter", + "style": "{", + "format": ( + "{asctime}{levelname}{message}{name}{pathname}{lineno}{funcName}" + "{process}{status_code}" + ), }, }, } -# This should be overridden by settings_local for any logger where debug (or -# other) custom log settings are wanted. Use "ietf/manage.py showloggers -l" -# to show registered loggers. The content here should match the levels above -# and is shown as an example: -UTILS_LOGGER_LEVELS: Dict[str, str] = { -# 'django': 'INFO', -# 'django.server': 'INFO', -} - -# End logging -# ------------------------------------------------------------------------ - X_FRAME_OPTIONS = 'SAMEORIGIN' -CSRF_TRUSTED_ORIGINS = ['ietf.org', '*.ietf.org', 'meetecho.com', '*.meetecho.com', 'gather.town', '*.gather.town', ] +CSRF_TRUSTED_ORIGINS = [ + "https://ietf.org", + "https://*.ietf.org", + 'https://meetecho.com', + 'https://*.meetecho.com', +] CSRF_COOKIE_SAMESITE = 'None' CSRF_COOKIE_SECURE = True @@ -337,11 +364,7 @@ def skip_unreadable_post(record): SESSION_COOKIE_SECURE = True SESSION_EXPIRE_AT_BROWSER_CLOSE = False -# We want to use the JSON serialisation, as it's safer -- but there is /secr/ -# code which stashes objects in the session that can't be JSON serialized. -# Switch when that code is rewritten. -#SESSION_SERIALIZER = "django.contrib.sessions.serializers.JSONSerializer" -SESSION_SERIALIZER = 'django.contrib.sessions.serializers.PickleSerializer' +SESSION_SERIALIZER = "django.contrib.sessions.serializers.JSONSerializer" SESSION_ENGINE = "django.contrib.sessions.backends.cache" SESSION_SAVE_EVERY_REQUEST = True SESSION_CACHE_ALIAS = 'sessions' @@ -357,6 +380,7 @@ def skip_unreadable_post(record): ], 'OPTIONS': { 'context_processors': [ + 'ietf.context_processors.traceparent_id', 'django.contrib.auth.context_processors.auth', 'django.template.context_processors.debug', # makes 'sql_queries' available in templates 'django.template.context_processors.i18n', @@ -371,6 +395,7 @@ def skip_unreadable_post(record): 'ietf.context_processors.settings_info', 'ietf.secr.context_processors.secr_revision_info', 'ietf.context_processors.rfcdiff_base_url', + 'ietf.context_processors.timezone_now', ], 'loaders': [ ('django.template.loaders.cached.Loader', ( @@ -388,42 +413,45 @@ def skip_unreadable_post(record): MIDDLEWARE = [ - 'django.middleware.csrf.CsrfViewMiddleware', - 'corsheaders.middleware.CorsMiddleware', # see docs on CORS_REPLACE_HTTPS_REFERER before using it - 'django.middleware.common.CommonMiddleware', - 'django.contrib.sessions.middleware.SessionMiddleware', - 'django.contrib.auth.middleware.AuthenticationMiddleware', - 'django.contrib.messages.middleware.MessageMiddleware', - 'django.middleware.http.ConditionalGetMiddleware', - 'simple_history.middleware.HistoryRequestMiddleware', + "ietf.middleware.add_otel_traceparent_header", + "django.middleware.csrf.CsrfViewMiddleware", + "corsheaders.middleware.CorsMiddleware", # see docs on CORS_REPLACE_HTTPS_REFERER before using it + "django.middleware.common.CommonMiddleware", + "django.contrib.sessions.middleware.SessionMiddleware", + "django.contrib.auth.middleware.AuthenticationMiddleware", + "django.contrib.messages.middleware.MessageMiddleware", + "ietf.middleware.is_authenticated_header_middleware", + "django.middleware.http.ConditionalGetMiddleware", + "simple_history.middleware.HistoryRequestMiddleware", # comment in this to get logging of SQL insert and update statements: - #'ietf.middleware.sql_log_middleware', - 'ietf.middleware.SMTPExceptionMiddleware', - 'ietf.middleware.Utf8ExceptionMiddleware', - 'ietf.middleware.redirect_trailing_period_middleware', - 'django_referrer_policy.middleware.ReferrerPolicyMiddleware', - 'django.middleware.clickjacking.XFrameOptionsMiddleware', - 'django.middleware.security.SecurityMiddleware', - # 'csp.middleware.CSPMiddleware', - 'ietf.middleware.unicode_nfkc_normalization_middleware', + #"ietf.middleware.sql_log_middleware", + "ietf.middleware.SMTPExceptionMiddleware", + "ietf.middleware.Utf8ExceptionMiddleware", + "ietf.middleware.redirect_trailing_period_middleware", + "django.middleware.clickjacking.XFrameOptionsMiddleware", + "django.middleware.security.SecurityMiddleware", + "ietf.middleware.unicode_nfkc_normalization_middleware", ] ROOT_URLCONF = 'ietf.urls' -DJANGO_VITE_ASSETS_PATH = os.path.join(BASE_DIR, 'static/dist-neue') +# Configure django_vite +DJANGO_VITE: dict = {"default": {}} if DEBUG: - DJANGO_VITE_MANIFEST_PATH = os.path.join(BASE_DIR, 'static/dist-neue/manifest.json') + DJANGO_VITE["default"]["manifest_path"] = os.path.join( + BASE_DIR, 'static/dist-neue/manifest.json' + ) # Additional locations of static files (in addition to each app's static/ dir) STATICFILES_DIRS = ( - DJANGO_VITE_ASSETS_PATH, + os.path.join(BASE_DIR, "static/dist-neue"), # for django_vite os.path.join(BASE_DIR, 'static/dist'), os.path.join(BASE_DIR, 'secr/static/dist'), ) INSTALLED_APPS = [ # Django apps - 'django.contrib.admin', + 'ietf.admin', # replaces django.contrib.admin 'django.contrib.admindocs', 'django.contrib.auth', 'django.contrib.contenttypes', @@ -437,16 +465,22 @@ def skip_unreadable_post(record): 'analytical', 'django_vite', 'django_bootstrap5', + 'django_celery_beat', + 'django_celery_results', 'corsheaders', 'django_markup', - 'django_password_strength', - 'form_utils', + 'django_filters', 'oidc_provider', + 'drf_spectacular', + 'drf_standardized_errors', + 'rest_framework', + 'rangefilter', 'simple_history', 'tastypie', 'widget_tweaks', # IETF apps 'ietf.api', + 'ietf.blobdb', 'ietf.community', 'ietf.dbtemplate', 'ietf.doc', @@ -467,18 +501,14 @@ def skip_unreadable_post(record): 'ietf.release', 'ietf.review', 'ietf.stats', + 'ietf.status', 'ietf.submit', 'ietf.sync', 'ietf.utils', # IETF Secretariat apps 'ietf.secr.announcement', - 'ietf.secr.areas', - 'ietf.secr.groups', 'ietf.secr.meetings', - 'ietf.secr.proceedings', - 'ietf.secr.roles', 'ietf.secr.rolodex', - 'ietf.secr.sreq', 'ietf.secr.telechat', ] @@ -518,8 +548,6 @@ def skip_unreadable_post(record): CORS_ALLOW_METHODS = ( 'GET', 'OPTIONS', ) CORS_URLS_REGEX = r'^(/api/.*|.*\.json|.*/json/?)$' -# Setting for django_referrer_policy.middleware.ReferrerPolicyMiddleware -REFERRER_POLICY = 'strict-origin-when-cross-origin' # django.middleware.security.SecurityMiddleware SECURE_BROWSER_XSS_FILTER = True @@ -530,6 +558,9 @@ def skip_unreadable_post(record): #SECURE_REDIRECT_EXEMPT #SECURE_SSL_HOST #SECURE_SSL_REDIRECT = True +# Relax the COOP policy to allow Meetecho authentication pop-up +SECURE_CROSS_ORIGIN_OPENER_POLICY = "unsafe-none" +SECURE_REFERRER_POLICY = "strict-origin-when-cross-origin" # Override this in your settings_local with the IP addresses relevant for you: INTERNAL_IPS = ( @@ -538,15 +569,83 @@ def skip_unreadable_post(record): '::1', ) +# django-rest-framework configuration +REST_FRAMEWORK = { + "DEFAULT_AUTHENTICATION_CLASSES": [ + "ietf.api.authentication.ApiKeyAuthentication", + "rest_framework.authentication.SessionAuthentication", + ], + "DEFAULT_PERMISSION_CLASSES": [ + "ietf.api.permissions.HasApiKey", + ], + "DEFAULT_RENDERER_CLASSES": [ + "rest_framework.renderers.JSONRenderer", + ], + "DEFAULT_PARSER_CLASSES": [ + "rest_framework.parsers.JSONParser", + ], + "DEFAULT_SCHEMA_CLASS": "drf_standardized_errors.openapi.AutoSchema", + "EXCEPTION_HANDLER": "drf_standardized_errors.handler.exception_handler", +} + +# DRF OpenApi schema settings +SPECTACULAR_SETTINGS = { + "TITLE": "Datatracker API", + "DESCRIPTION": "Datatracker API", + "VERSION": "1.0.0", + "SCHEMA_PATH_PREFIX": "/api/", + "COMPONENT_SPLIT_REQUEST": True, + "COMPONENT_NO_READ_ONLY_REQUIRED": True, + "SERVERS": [ + {"url": "http://localhost:8000", "description": "local dev server"}, + {"url": "https://datatracker.ietf.org", "description": "production server"}, + ], + # The following settings are needed for drf-standardized-errors + "ENUM_NAME_OVERRIDES": { + "ValidationErrorEnum": "drf_standardized_errors.openapi_serializers.ValidationErrorEnum.choices", + "ClientErrorEnum": "drf_standardized_errors.openapi_serializers.ClientErrorEnum.choices", + "ServerErrorEnum": "drf_standardized_errors.openapi_serializers.ServerErrorEnum.choices", + "ErrorCode401Enum": "drf_standardized_errors.openapi_serializers.ErrorCode401Enum.choices", + "ErrorCode403Enum": "drf_standardized_errors.openapi_serializers.ErrorCode403Enum.choices", + "ErrorCode404Enum": "drf_standardized_errors.openapi_serializers.ErrorCode404Enum.choices", + "ErrorCode405Enum": "drf_standardized_errors.openapi_serializers.ErrorCode405Enum.choices", + "ErrorCode406Enum": "drf_standardized_errors.openapi_serializers.ErrorCode406Enum.choices", + "ErrorCode415Enum": "drf_standardized_errors.openapi_serializers.ErrorCode415Enum.choices", + "ErrorCode429Enum": "drf_standardized_errors.openapi_serializers.ErrorCode429Enum.choices", + "ErrorCode500Enum": "drf_standardized_errors.openapi_serializers.ErrorCode500Enum.choices", + }, + "POSTPROCESSING_HOOKS": ["drf_standardized_errors.openapi_hooks.postprocess_schema_enums"], +} + +# DRF Standardized Errors settings +DRF_STANDARDIZED_ERRORS = { + # enable the standardized errors when DEBUG=True for unhandled exceptions. + # By default, this is set to False so you're able to view the traceback in + # the terminal and get more information about the exception. + "ENABLE_IN_DEBUG_FOR_UNHANDLED_EXCEPTIONS": False, + # ONLY the responses that correspond to these status codes will appear + # in the API schema. + "ALLOWED_ERROR_STATUS_CODES": [ + "400", + # "401", + # "403", + "404", + # "405", + # "406", + # "415", + # "429", + # "500", + ], + +} + # no slash at end IDTRACKER_BASE_URL = "https://datatracker.ietf.org" -RFCDIFF_BASE_URL = "https://www.ietf.org/rfcdiff" +RFCDIFF_BASE_URL = "https://author-tools.ietf.org/iddiff" IDNITS_BASE_URL = "https://author-tools.ietf.org/api/idnits" +IDNITS3_BASE_URL = "https://author-tools.ietf.org/idnits3/results" IDNITS_SERVICE_URL = "https://author-tools.ietf.org/idnits" -# Content security policy configuration (django-csp) -CSP_DEFAULT_SRC = ("'self'", "'unsafe-inline'", f"data: {IDTRACKER_BASE_URL} https://www.ietf.org/ https://analytics.ietf.org/ https://fonts.googleapis.com/") - # The name of the method to use to invoke the test suite TEST_RUNNER = 'ietf.utils.test_runner.IetfTestRunner' @@ -556,8 +655,6 @@ def skip_unreadable_post(record): TEST_DIFF_FAILURE_DIR = "/tmp/test/failure/" -TEST_GHOSTDRIVER_LOG_PATH = "ghostdriver.log" - # These are regexes TEST_URL_COVERAGE_EXCLUDE = [ r"^\^admin/", @@ -584,9 +681,10 @@ def skip_unreadable_post(record): "ietf/utils/test_runner.py", "ietf/name/generate_fixtures.py", "ietf/review/import_from_review_tool.py", - "ietf/stats/backfill_data.py", "ietf/utils/patch.py", "ietf/utils/test_data.py", + "ietf/utils/jstest.py", + "ietf/utils/coverage.py", ] # These are code line regex patterns @@ -600,21 +698,24 @@ def skip_unreadable_post(record): ] # These are filename globs. They are used by test_parse_templates() and -# get_template_paths() +# get_template_paths(). Globs are applied via pathlib.Path().match, using +# the path to the template from the project root. TEST_TEMPLATE_IGNORE = [ - ".*", # dot-files - "*~", # tilde temp-files - "#*", # files beginning with a hashmark - "500.html" # isn't loaded by regular loader, but checked by test_500_page() + ".*", # dot-files + "*~", # tilde temp-files + "#*", # files beginning with a hashmark + "500.html", # isn't loaded by regular loader, but checked by test_500_page() + "ietf/templates/admin/meeting/RegistrationTicket/change_list.html", + "ietf/templates/admin/meeting/Registration/change_list.html", ] -TEST_COVERAGE_MASTER_FILE = os.path.join(BASE_DIR, "../release-coverage.json") +TEST_COVERAGE_MAIN_FILE = os.path.join(BASE_DIR, "../release-coverage.json") TEST_COVERAGE_LATEST_FILE = os.path.join(BASE_DIR, "../latest-coverage.json") TEST_CODE_COVERAGE_CHECKER = None if SERVER_MODE != 'production': - import coverage - TEST_CODE_COVERAGE_CHECKER = coverage.Coverage(source=[ BASE_DIR ], cover_pylib=False, omit=TEST_CODE_COVERAGE_EXCLUDE_FILES) + from ietf.utils.coverage import CoverageManager + TEST_CODE_COVERAGE_CHECKER = CoverageManager() TEST_CODE_COVERAGE_REPORT_PATH = "coverage/" TEST_CODE_COVERAGE_REPORT_URL = os.path.join(STATIC_URL, TEST_CODE_COVERAGE_REPORT_PATH, "index.html") @@ -628,7 +729,7 @@ def skip_unreadable_post(record): # document state: GROUP_STATES_WITH_EXTRA_PROCESSING = ["sub-pub", "rfc-edit", ] -# Review team releated settings +# Review team related settings GROUP_REVIEW_MAX_ITEMS_TO_SHOW_IN_REVIEWER_LIST = 10 GROUP_REVIEW_DAYS_TO_SHOW_IN_REVIEWER_LIST = 365 @@ -641,6 +742,7 @@ def skip_unreadable_post(record): "acronym": r"(?P[-a-z0-9]+)", "bofreq": r"(?Pbofreq-[-a-z0-9]+)", "charter": r"(?Pcharter-[-a-z0-9]+)", + "statement": r"(?Pstatement-[-a-z0-9]+)", "date": r"(?P\d{4}-\d{2}-\d{2})", "name": r"(?P[A-Za-z0-9._+-]+?)", "document": r"(?P[a-z][-a-z0-9]+)", # regular document names @@ -649,40 +751,98 @@ def skip_unreadable_post(record): "schedule_name": r"(?P[A-Za-z0-9-:_]+)", } +STORAGES: dict[str, Any] = { + "default": {"BACKEND": "django.core.files.storage.FileSystemStorage"}, + "staticfiles": {"BACKEND": "django.contrib.staticfiles.storage.StaticFilesStorage"}, +} + +# Storages for artifacts stored as blobs +ARTIFACT_STORAGE_NAMES: list[str] = [ + "active-draft", + "agenda", + "bibxml-ids", + "bluesheets", + "bofreq", + "charter", + "chatlog", + "conflrev", + "draft", + "floorplan", + "indexes", + "liai-att", + "meetinghostlogo", + "minutes", + "narrativeminutes", + "photo", + "polls", + "procmaterials", + "review", + "rfc", + "slides", + "staging", + "statchg", + "statement", +] +for storagename in ARTIFACT_STORAGE_NAMES: + STORAGES[storagename] = { + "BACKEND": "ietf.doc.storage.StoredObjectBlobdbStorage", + "OPTIONS": {"bucket_name": storagename}, + } + +# Buckets / doc types of meeting materials the CF worker is allowed to serve. This +# differs from the list in Session.meeting_related() by the omission of "recording" +MATERIALS_TYPES_SERVED_BY_WORKER = [ + "agenda", + "bluesheets", + "chatlog", + "minutes", + "narrativeminutes", + "polls", + "procmaterials", + "slides", +] + +# Other storages +STORAGES["red_bucket"] = { + "BACKEND": "django.core.files.storage.InMemoryStorage", + "OPTIONS": {"location": "red_bucket"}, +} + # Override this in settings_local.py if needed # *_PATH variables ends with a slash/ . -#DOCUMENT_PATH_PATTERN = '/a/www/ietf-ftp/{doc.type_id}/' DOCUMENT_PATH_PATTERN = '/a/ietfdata/doc/{doc.type_id}/' INTERNET_DRAFT_PATH = '/a/ietfdata/doc/draft/repository' INTERNET_DRAFT_PDF_PATH = '/a/www/ietf-datatracker/pdf/' RFC_PATH = '/a/www/ietf-ftp/rfc/' CHARTER_PATH = '/a/ietfdata/doc/charter/' +CHARTER_COPY_PATH = '/a/www/ietf-ftp/ietf' # copy 1wg-charters files here if set +CHARTER_COPY_OTHER_PATH = '/a/ftp/ietf' +CHARTER_COPY_THIRD_PATH = '/a/ftp/charter' +GROUP_SUMMARY_PATH = '/a/www/ietf-ftp/ietf' BOFREQ_PATH = '/a/ietfdata/doc/bofreq/' CONFLICT_REVIEW_PATH = '/a/ietfdata/doc/conflict-review' STATUS_CHANGE_PATH = '/a/ietfdata/doc/status-change' AGENDA_PATH = '/a/www/www6s/proceedings/' MEETINGHOST_LOGO_PATH = AGENDA_PATH # put these in the same place as other proceedings files -IPR_DOCUMENT_PATH = '/a/www/ietf-ftp/ietf/IPR/' -IESG_TASK_FILE = '/a/www/www6/iesg/internal/task.txt' -IESG_ROLL_CALL_FILE = '/a/www/www6/iesg/internal/rollcall.txt' -IESG_ROLL_CALL_URL = 'https://www6.ietf.org/iesg/internal/rollcall.txt' -IESG_MINUTES_FILE = '/a/www/www6/iesg/internal/minutes.txt' -IESG_MINUTES_URL = 'https://www6.ietf.org/iesg/internal/minutes.txt' -IESG_WG_EVALUATION_DIR = "/a/www/www6/iesg/evaluation" # Move drafts to this directory when they expire INTERNET_DRAFT_ARCHIVE_DIR = '/a/ietfdata/doc/draft/collection/draft-archive/' -# The following directory contains linked copies of all drafts, but don't -# write anything to this directory -- its content is maintained by ghostlinkd: +# The following directory contains copies of all drafts - it used to be +# a set of hardlinks maintained by ghostlinkd, but is now explicitly written to INTERNET_ALL_DRAFTS_ARCHIVE_DIR = '/a/ietfdata/doc/draft/archive' MEETING_RECORDINGS_DIR = '/a/www/audio' DERIVED_DIR = '/a/ietfdata/derived' +FTP_DIR = '/a/ftp' +ALL_ID_DOWNLOAD_DIR = '/a/www/www6s/download' +NFS_METRICS_TMP_DIR = '/a/tmp' -DOCUMENT_FORMAT_WHITELIST = ["txt", "ps", "pdf", "xml", "html", ] +DOCUMENT_FORMAT_ALLOWLIST = ["txt", "ps", "pdf", "xml", "html", ] # Mailing list info URL for lists hosted on the IETF servers -MAILING_LIST_INFO_URL = "https://www.ietf.org/mailman/listinfo/%(list_addr)s" +MAILING_LIST_INFO_URL = "https://mailman3.%(domain)s/mailman3/lists/%(list_addr)s.%(domain)s" MAILING_LIST_ARCHIVE_URL = "https://mailarchive.ietf.org" +MAILING_LIST_ARCHIVE_SEARCH_URL = "https://mailarchive.ietf.org/api/v1/message/search/" +MAILING_LIST_ARCHIVE_API_KEY = "changeme" # Liaison Statement Tool settings (one is used in DOC_HREFS below) LIAISON_UNIVERSAL_FROM = 'Liaison Statement Management Tool ' @@ -694,7 +854,7 @@ def skip_unreadable_post(record): DOC_HREFS = { "charter": "https://www.ietf.org/charter/{doc.name}-{doc.rev}.txt", "draft": "https://www.ietf.org/archive/id/{doc.name}-{doc.rev}.txt", - "rfc": "https://www.rfc-editor.org/rfc/rfc{doc.rfcnum}.txt", + "rfc": "https://www.rfc-editor.org/rfc/rfc{doc.rfc_number}.txt", "slides": "https://www.ietf.org/slides/{doc.name}-{doc.rev}", "procmaterials": "https://www.ietf.org/procmaterials/{doc.name}-{doc.rev}", "conflrev": "https://www.ietf.org/cr/{doc.name}-{doc.rev}.txt", @@ -714,44 +874,6 @@ def skip_unreadable_post(record): CACHE_MIDDLEWARE_SECONDS = 300 CACHE_MIDDLEWARE_KEY_PREFIX = '' -# The default with no CACHES setting is 'django.core.cache.backends.locmem.LocMemCache' -# This setting is possibly overridden further down, after the import of settings_local -CACHES = { - 'default': { - 'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache', - 'LOCATION': '127.0.0.1:11211', - 'VERSION': __version__, - 'KEY_PREFIX': 'ietf:dt', - }, - 'sessions': { - 'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache', - 'LOCATION': '127.0.0.1:11211', - # No release-specific VERSION setting. - 'KEY_PREFIX': 'ietf:dt', - }, - 'htmlized': { - 'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache', - 'LOCATION': '/a/cache/datatracker/htmlized', - 'OPTIONS': { - 'MAX_ENTRIES': 100000, # 100,000 - }, - }, - 'pdfized': { - 'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache', - 'LOCATION': '/a/cache/datatracker/pdfized', - 'OPTIONS': { - 'MAX_ENTRIES': 100000, # 100,000 - }, - }, - 'slowpages': { - 'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache', - 'LOCATION': '/a/cache/datatracker/slowpages', - 'OPTIONS': { - 'MAX_ENTRIES': 5000, - }, - }, -} - HTMLIZER_VERSION = 1 HTMLIZER_URL_PREFIX = "/doc/html" HTMLIZER_CACHE_TIME = 60*60*24*14 # 14 days @@ -764,26 +886,22 @@ def skip_unreadable_post(record): SESSION_REQUEST_FROM_EMAIL = 'IETF Meeting Session Request Tool ' SECRETARIAT_SUPPORT_EMAIL = "support@ietf.org" -SECRETARIAT_ACTION_EMAIL = "ietf-action@ietf.org" -SECRETARIAT_INFO_EMAIL = "ietf-info@ietf.org" +SECRETARIAT_ACTION_EMAIL = SECRETARIAT_SUPPORT_EMAIL +SECRETARIAT_INFO_EMAIL = SECRETARIAT_SUPPORT_EMAIL # Put real password in settings_local.py IANA_SYNC_PASSWORD = "secret" IANA_SYNC_CHANGES_URL = "https://datatracker.iana.org:4443/data-tracker/changes" IANA_SYNC_PROTOCOLS_URL = "https://www.iana.org/protocols/" -RFC_TEXT_RSYNC_SOURCE="ftp.rfc-editor.org::rfcs-text-only" - -RFC_EDITOR_SYNC_PASSWORD="secret" -RFC_EDITOR_SYNC_NOTIFICATION_URL = "https://www.rfc-editor.org/parser/parser.php" RFC_EDITOR_GROUP_NOTIFICATION_EMAIL = "webmaster@rfc-editor.org" -#RFC_EDITOR_GROUP_NOTIFICATION_URL = "https://www.rfc-editor.org/notification/group.php" -RFC_EDITOR_QUEUE_URL = "https://www.rfc-editor.org/queue2.xml" RFC_EDITOR_INDEX_URL = "https://www.rfc-editor.org/rfc/rfc-index.xml" RFC_EDITOR_ERRATA_JSON_URL = "https://www.rfc-editor.org/errata.json" -RFC_EDITOR_ERRATA_URL = "https://www.rfc-editor.org/errata_search.php?rfc={rfc_number}&rec_status=0" RFC_EDITOR_INLINE_ERRATA_URL = "https://www.rfc-editor.org/rfc/inline-errata/rfc{rfc_number}.html" +RFC_EDITOR_ERRATA_BASE_URL = "https://www.rfc-editor.org/errata/" RFC_EDITOR_INFO_BASE_URL = "https://www.rfc-editor.org/info/" +RFC_EDITOR_QUEUE_SITE_BASE_URL = "https://queue.rfc-editor.org" + # NomCom Tool settings ROLODEX_URL = "" @@ -791,7 +909,7 @@ def skip_unreadable_post(record): NOMCOM_FROM_EMAIL = 'nomcom-chair-{year}@ietf.org' OPENSSL_COMMAND = '/usr/bin/openssl' DAYS_TO_EXPIRE_NOMINATION_LINK = '' -NOMINEE_FEEDBACK_TYPES = ['comment', 'questio', 'nomina'] +NOMINEE_FEEDBACK_TYPES = ['comment', 'questio', 'nomina', 'obe'] # SlideSubmission settings SLIDE_STAGING_PATH = '/a/www/www6s/staging/' @@ -843,8 +961,11 @@ def skip_unreadable_post(record): # "ietf.submit.checkers.DraftYangvalidatorChecker", ) +# Max time to allow for validation before a submission is subject to cancellation +IDSUBMIT_MAX_VALIDATION_TIME = datetime.timedelta(minutes=20) -IDSUBMIT_MANUAL_STAGING_DIR = '/tmp/' +# Age at which a submission expires if not posted +IDSUBMIT_EXPIRATION_AGE = datetime.timedelta(days=14) IDSUBMIT_FILE_TYPES = ( 'txt', @@ -855,6 +976,10 @@ def skip_unreadable_post(record): ) RFC_FILE_TYPES = IDSUBMIT_FILE_TYPES +# Paths in the red bucket +RFCINDEX_INPUT_PATH = "other/" +RFCINDEX_OUTPUT_PATH = "other/" + IDSUBMIT_MAX_DRAFT_SIZE = { 'txt': 2*1024*1024, # Max size of txt draft file in bytes 'xml': 3*1024*1024, # Max size of xml draft file in bytes @@ -884,7 +1009,10 @@ def skip_unreadable_post(record): MEETING_DOC_LOCAL_HREFS = { "agenda": "/meeting/{meeting.number}/materials/{doc.name}-{doc.rev}", "minutes": "/meeting/{meeting.number}/materials/{doc.name}-{doc.rev}", + "narrativeminutes": "/meeting/{meeting.number}/materials/{doc.name}-{doc.rev}", "slides": "/meeting/{meeting.number}/materials/{doc.name}-{doc.rev}", + "chatlog": "/meeting/{meeting.number}/materials/{doc.name}-{doc.rev}", + "polls": "/meeting/{meeting.number}/materials/{doc.name}-{doc.rev}", "recording": "{doc.external_url}", "bluesheets": "https://www.ietf.org/proceedings/{meeting.number}/bluesheets/{doc.uploaded_filename}", "procmaterials": "/meeting/{meeting.number}/materials/{doc.name}-{doc.rev}", @@ -893,6 +1021,7 @@ def skip_unreadable_post(record): MEETING_DOC_CDN_HREFS = { "agenda": "https://www.ietf.org/proceedings/{meeting.number}/agenda/{doc.name}-{doc.rev}", "minutes": "https://www.ietf.org/proceedings/{meeting.number}/minutes/{doc.name}-{doc.rev}", + "narrativeminutes": "https://www.ietf.org/proceedings/{meeting.number}/narrative-minutes/{doc.name}-{doc.rev}", "slides": "https://www.ietf.org/proceedings/{meeting.number}/slides/{doc.name}-{doc.rev}", "recording": "{doc.external_url}", "bluesheets": "https://www.ietf.org/proceedings/{meeting.number}/bluesheets/{doc.uploaded_filename}", @@ -904,6 +1033,7 @@ def skip_unreadable_post(record): MEETING_DOC_OLD_HREFS = { "agenda": "/meeting/{meeting.number}/materials/{doc.name}", "minutes": "/meeting/{meeting.number}/materials/{doc.name}", + "narrativeminutes" : "/meeting/{meeting.number}/materials/{doc.name}", "slides": "/meeting/{meeting.number}/materials/{doc.name}", "recording": "{doc.external_url}", "bluesheets": "https://www.ietf.org/proceedings/{meeting.number}/bluesheets/{doc.uploaded_filename}", @@ -913,6 +1043,7 @@ def skip_unreadable_post(record): MEETING_DOC_GREFS = { "agenda": "/meeting/{meeting.number}/materials/{doc.name}", "minutes": "/meeting/{meeting.number}/materials/{doc.name}", + "narrativeminutes": "/meeting/{meeting.number}/materials/{doc.name}", "slides": "/meeting/{meeting.number}/materials/{doc.name}", "recording": "{doc.external_url}", "bluesheets": "https://www.ietf.org/proceedings/{meeting.number}/bluesheets/{doc.uploaded_filename}", @@ -926,6 +1057,7 @@ def skip_unreadable_post(record): MEETING_VALID_UPLOAD_EXTENSIONS = { 'agenda': ['.txt','.html','.htm', '.md', ], 'minutes': ['.txt','.html','.htm', '.md', '.pdf', ], + 'narrativeminutes': ['.txt','.html','.htm', '.md', '.pdf', ], 'slides': ['.doc','.docx','.pdf','.ppt','.pptx','.txt', ], # Note the removal of .zip 'bluesheets': ['.pdf', '.txt', ], 'procmaterials':['.pdf', ], @@ -935,6 +1067,7 @@ def skip_unreadable_post(record): MEETING_VALID_UPLOAD_MIME_TYPES = { 'agenda': ['text/plain', 'text/html', 'text/markdown', 'text/x-markdown', ], 'minutes': ['text/plain', 'text/html', 'application/pdf', 'text/markdown', 'text/x-markdown', ], + 'narrativeminutes': ['text/plain', 'text/html', 'application/pdf', 'text/markdown', 'text/x-markdown', ], 'slides': [], 'bluesheets': ['application/pdf', 'text/plain', ], 'procmaterials':['application/pdf', ], @@ -966,8 +1099,6 @@ def skip_unreadable_post(record): FLOORPLAN_MEDIA_DIR = 'floor' FLOORPLAN_DIR = os.path.join(MEDIA_ROOT, FLOORPLAN_MEDIA_DIR) - -MEETING_USES_CODIMD_DATE = datetime.date(2020,7,6) MEETING_LEGACY_OFFICE_HOURS_END = 112 # last meeting to use legacy office hours representation # Maximum dimensions to accept at all @@ -991,32 +1122,35 @@ def skip_unreadable_post(record): # ============================================================================== -RSYNC_BINARY = '/usr/bin/rsync' YANGLINT_BINARY = '/usr/bin/yanglint' DE_GFM_BINARY = '/usr/bin/de-gfm.ruby2.5' # Account settings DAYS_TO_EXPIRE_REGISTRATION_LINK = 3 MINUTES_TO_EXPIRE_RESET_PASSWORD_LINK = 60 -HTPASSWD_COMMAND = "/usr/bin/htpasswd" -HTPASSWD_FILE = "/www/htpasswd" # Generation of pdf files GHOSTSCRIPT_COMMAND = "/usr/bin/gs" -# Generation of bibxml files (currently only for internet drafts) +# Generation of bibxml files (currently only for Internet-Drafts) BIBXML_BASE_PATH = '/a/ietfdata/derived/bibxml' # Timezone files for iCalendar TZDATA_ICS_PATH = BASE_DIR + '/../vzic/zoneinfo/' -SECR_BLUE_SHEET_PATH = '/a/www/ietf-datatracker/documents/blue_sheet.rtf' -SECR_BLUE_SHEET_URL = IDTRACKER_BASE_URL + '/documents/blue_sheet.rtf' -SECR_INTERIM_LISTING_DIR = '/a/www/www6/meeting/interim' -SECR_MAX_UPLOAD_SIZE = 40960000 -SECR_PROCEEDINGS_DIR = '/a/www/www6s/proceedings/' -SECR_PPT2PDF_COMMAND = ['/usr/bin/soffice','--headless','--convert-to','pdf:writer_globaldocument_pdf_Export','--outdir'] -STATS_REGISTRATION_ATTENDEES_JSON_URL = 'https://registration.ietf.org/{number}/attendees/' +DATATRACKER_MAX_UPLOAD_SIZE = 40960000 +PPT2PDF_COMMAND = [ + "/usr/bin/soffice", + "--headless", # no GUI + "--safe-mode", # use a new libreoffice profile every time (ensures no reliance on accumulated profile config) + "--norestore", # don't attempt to restore files after a previous crash (ensures that one crash won't block future conversions until UI intervention) + "--convert-to", "pdf:writer_globaldocument_pdf_Export", + "--outdir" +] + +REGISTRATION_PARTICIPANTS_API_URL = 'https://registration.ietf.org/api/v1/participants-dt/' +REGISTRATION_PARTICIPANTS_API_KEY = 'changeme' + PROCEEDINGS_VERSION_CHANGES = [ 0, # version 1 97, # version 2: meeting 97 and later (was number was NEW_PROCEEDINGS_START) @@ -1035,10 +1169,7 @@ def skip_unreadable_post(record): # If we need to revert to xmpp # CHAT_ARCHIVE_URL_PATTERN = 'https://www.ietf.org/jabber/logs/{chat_room_name}?C=M;O=D' -PRODUCTION_TIMEZONE = "America/Los_Angeles" - PYFLAKES_DEFAULT_ARGS= ["ietf", ] -VULTURE_DEFAULT_ARGS= ["ietf", ] # Automatic Scheduling # @@ -1066,6 +1197,8 @@ def skip_unreadable_post(record): DEV_PRE_APPS = [] # type: List[str] DEV_MIDDLEWARE = () +PROD_PRE_APPS = [] # type: List[str] + # django-debug-toolbar and the debug listing of sql queries at the bottom of # each page when in dev mode can overlap in functionality, and can slow down # page loading. If you wish to use the sql_queries debug listing, put this in @@ -1083,16 +1216,6 @@ def skip_unreadable_post(record): TEST_DATA_DIR = os.path.abspath(BASE_DIR + "/../test/data") -# Path to the email alias lists. Used by ietf.utils.aliases -DRAFT_ALIASES_PATH = os.path.join(TEST_DATA_DIR, "draft-aliases") -DRAFT_VIRTUAL_PATH = os.path.join(TEST_DATA_DIR, "draft-virtual") -DRAFT_VIRTUAL_DOMAIN = "virtual.ietf.org" - -GROUP_ALIASES_PATH = os.path.join(TEST_DATA_DIR, "group-aliases") -GROUP_VIRTUAL_PATH = os.path.join(TEST_DATA_DIR, "group-virtual") -GROUP_VIRTUAL_DOMAIN = "virtual.ietf.org" - -POSTCONFIRM_PATH = "/a/postconfirm/wrapper" USER_PREFERENCE_DEFAULTS = { "expires_soon" : "14", @@ -1108,21 +1231,23 @@ def skip_unreadable_post(record): "@ietf.org$", ] +# Configuration for django-markup MARKUP_SETTINGS = { 'restructuredtext': { 'settings_overrides': { + 'report_level': 3, # error (3) or severe (4) only 'initial_header_level': 3, 'doctitle_xform': False, 'footnote_references': 'superscript', 'trim_footnote_reference_space': True, 'default_reference_context': 'view', + 'raw_enabled': False, # critical for security + 'file_insertion_enabled': False, # critical for security 'link_base': '' } } } -MAILMAN_LIB_DIR = '/usr/lib/mailman' - # This is the number of seconds required between subscribing to an ietf # mailing list and datatracker account creation being accepted LIST_ACCOUNT_DELAY = 60*60*25 # 25 hours @@ -1131,15 +1256,17 @@ def skip_unreadable_post(record): SILENCED_SYSTEM_CHECKS = [ "fields.W342", # Setting unique=True on a ForeignKey has the same effect as using a OneToOneField. + "fields.W905", # django.contrib.postgres.fields.CICharField is deprecated. (see https://github.com/ietf-tools/datatracker/issues/5660) ] CHECKS_LIBRARY_PATCHES_TO_APPLY = [ 'patch/change-oidc-provider-field-sizes-228.patch', 'patch/fix-oidc-access-token-post.patch', 'patch/fix-jwkest-jwt-logging.patch', - 'patch/fix-django-password-strength-kwargs.patch', - 'patch/add-django-http-cookie-value-none.patch', - 'patch/django-cookie-delete-with-all-settings.patch', + # Patch includes old cookie-delete-with-all-settings and a backport of the fix + # to CVE-2026-35192 from Django 5.2. The patches conflict, so cannot be applied + # separately. + 'patch/django-cookie-delete-settings-and-CVE-2026-35192.patch', 'patch/tastypie-django22-fielderror-response.patch', ] if DEBUG: @@ -1149,7 +1276,7 @@ def skip_unreadable_post(record): except ImportError: pass -STATS_NAMES_LIMIT = 25 +STATS_TIMELINE_CACHE_TIMEOUT = 86400 UTILS_MEETING_CONFERENCE_DOMAINS = ['webex.com', 'zoom.us', 'jitsi.org', 'meetecho.com', 'gather.town', ] UTILS_TEST_RANDOM_STATE_FILE = '.factoryboy_random_state' @@ -1176,6 +1303,25 @@ def skip_unreadable_post(record): DEFAULT_REQUESTS_TIMEOUT = 20 # seconds +# Celery configuration +CELERY_TIMEZONE = 'UTC' +CELERY_BROKER_URL = 'amqp://mq/' +CELERY_BEAT_SCHEDULER = 'django_celery_beat.schedulers:DatabaseScheduler' +CELERY_BEAT_SYNC_EVERY = 1 # update DB after every event +CELERY_BEAT_CRON_STARTING_DEADLINE = 1800 # seconds after a missed deadline before abandoning a cron task +CELERY_BROKER_CONNECTION_RETRY_ON_STARTUP = True # the default, but setting it squelches a warning +# Use a result backend so we can chain tasks. This uses the rpc backend, see +# https://docs.celeryq.dev/en/stable/userguide/tasks.html#rpc-result-backend-rabbitmq-qpid +# Results can be retrieved only once and only by the caller of the task. Results will be +# lost if the message broker restarts. +CELERY_RESULT_BACKEND = 'django-cache' # use a Django cache for results +CELERY_CACHE_BACKEND = 'celery-results' # which Django cache to use +CELERY_RESULT_EXPIRES = datetime.timedelta(minutes=5) # how long are results valid? (Default is 1 day) +CELERY_TASK_IGNORE_RESULT = True # ignore results unless specifically enabled for a task +CELERY_TASK_ROUTES = { + "ietf.blobdb.tasks.pybob_the_blob_replicator_task": {"queue": "blobdb"} +} + # Meetecho API setup: Uncomment this and provide real credentials to enable # Meetecho conference creation for interim session requests # @@ -1184,8 +1330,22 @@ def skip_unreadable_post(record): # 'client_id': 'datatracker', # 'client_secret': 'some secret', # 'request_timeout': 3.01, # python-requests doc recommend slightly > a multiple of 3 seconds +# # How many minutes before/after session to enable slide update API. Defaults to 15. Set to None to disable, +# # or < 0 to _always_ send updates (useful for debugging) +# 'slides_notify_time': 15, +# 'debug': False, # if True, API calls will be echoed as debug instead of sent (only works for slides for now) # } +# Meetecho URLs - instantiate with url.format(session=some_session) +MEETECHO_ONSITE_TOOL_URL = "https://meetings.conf.meetecho.com/onsite{session.meeting.number}/?session={session.pk}" +MEETECHO_VIDEO_STREAM_URL = "https://meetings.conf.meetecho.com/ietf{session.meeting.number}/?session={session.pk}" +MEETECHO_AUDIO_STREAM_URL = "https://mp3.conf.meetecho.com/ietf{session.meeting.number}/{session.pk}.m3u" +MEETECHO_SESSION_RECORDING_URL = "https://meetecho-player.ietf.org/playout/?session={session_label}" + +# Errata system api configuration +# settings should provide +# ERRATA_METADATA_NOTIFICATION_URL +# ERRATA_METADATA_NOTIFICATION_API_KEY # Put the production SECRET_KEY in settings_local.py, and also any other # sensitive or site-specific changes. DO NOT commit settings_local.py to svn. @@ -1197,14 +1357,152 @@ def skip_unreadable_post(record): if os.path.exists(app_settings_file): exec("from %s import *" % (app+".settings")) -# Add DEV_APPS to INSTALLED_APPS -INSTALLED_APPS += DEV_APPS -INSTALLED_APPS = DEV_PRE_APPS + INSTALLED_APPS -MIDDLEWARE += DEV_MIDDLEWARE -TEMPLATES[0]['OPTIONS']['context_processors'] += DEV_TEMPLATE_CONTEXT_PROCESSORS - +# Add APPS from settings_local to INSTALLED_APPS if SERVER_MODE == 'production': - INSTALLED_APPS.insert(0,'scout_apm.django') + INSTALLED_APPS = PROD_PRE_APPS + INSTALLED_APPS +else: + INSTALLED_APPS += DEV_APPS + INSTALLED_APPS = DEV_PRE_APPS + INSTALLED_APPS + MIDDLEWARE += DEV_MIDDLEWARE + TEMPLATES[0]['OPTIONS']['context_processors'] += DEV_TEMPLATE_CONTEXT_PROCESSORS + +if "CACHES" not in locals(): + if SERVER_MODE == "production": + MEMCACHED_HOST = os.environ.get("MEMCACHED_SERVICE_HOST", "127.0.0.1") + MEMCACHED_PORT = os.environ.get("MEMCACHED_SERVICE_PORT", "11211") + CACHES = { + "default": { + "BACKEND": "ietf.utils.cache.LenientMemcacheCache", + "LOCATION": f"{MEMCACHED_HOST}:{MEMCACHED_PORT}", + "VERSION": __version__, + "KEY_PREFIX": "ietf:dt", + # Key function is default except with sha384-encoded key + "KEY_FUNCTION": lambda key, key_prefix, version: ( + f"{key_prefix}:{version}:{sha384(str(key).encode('utf8')).hexdigest()}" + ), + }, + "agenda": { + "BACKEND": "ietf.utils.cache.LenientMemcacheCache", + "LOCATION": f"{MEMCACHED_HOST}:{MEMCACHED_PORT}", + # No release-specific VERSION setting. + "KEY_PREFIX": "ietf:dt:agenda", + # Key function is default except with sha384-encoded key + "KEY_FUNCTION": lambda key, key_prefix, version: ( + f"{key_prefix}:{version}:{sha384(str(key).encode('utf8')).hexdigest()}" + ), + }, + "proceedings": { + "BACKEND": "ietf.utils.cache.LenientMemcacheCache", + "LOCATION": f"{MEMCACHED_HOST}:{MEMCACHED_PORT}", + # No release-specific VERSION setting. + "KEY_PREFIX": "ietf:dt:proceedings", + # Key function is default except with sha384-encoded key + "KEY_FUNCTION": lambda key, key_prefix, version: ( + f"{key_prefix}:{version}:{sha384(str(key).encode('utf8')).hexdigest()}" + ), + }, + "sessions": { + "BACKEND": "ietf.utils.cache.LenientMemcacheCache", + "LOCATION": f"{MEMCACHED_HOST}:{MEMCACHED_PORT}", + # No release-specific VERSION setting. + "KEY_PREFIX": "ietf:dt", + }, + "htmlized": { + "BACKEND": "django.core.cache.backends.filebased.FileBasedCache", + "LOCATION": "/a/cache/datatracker/htmlized", + "OPTIONS": { + "MAX_ENTRIES": 100000, # 100,000 + }, + }, + "pdfized": { + "BACKEND": "django.core.cache.backends.filebased.FileBasedCache", + "LOCATION": "/a/cache/datatracker/pdfized", + "OPTIONS": { + "MAX_ENTRIES": 100000, # 100,000 + }, + }, + "slowpages": { + "BACKEND": "django.core.cache.backends.filebased.FileBasedCache", + "LOCATION": "/a/cache/datatracker/slowpages", + "OPTIONS": { + "MAX_ENTRIES": 5000, + }, + }, + "celery-results": { + "BACKEND": "django.core.cache.backends.memcached.PyMemcacheCache", + "LOCATION": f"{MEMCACHED_HOST}:{MEMCACHED_PORT}", + "KEY_PREFIX": "ietf:celery", + }, + } + else: + CACHES = { + "default": { + "BACKEND": "django.core.cache.backends.dummy.DummyCache", + #'BACKEND': 'ietf.utils.cache.LenientMemcacheCache', + #'LOCATION': '127.0.0.1:11211', + #'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache', + "VERSION": __version__, + "KEY_PREFIX": "ietf:dt", + }, + "agenda": { + "BACKEND": "django.core.cache.backends.dummy.DummyCache", + # "BACKEND": "ietf.utils.cache.LenientMemcacheCache", + # "LOCATION": "127.0.0.1:11211", + # No release-specific VERSION setting. + "KEY_PREFIX": "ietf:dt:agenda", + # Key function is default except with sha384-encoded key + "KEY_FUNCTION": lambda key, key_prefix, version: ( + f"{key_prefix}:{version}:{sha384(str(key).encode('utf8')).hexdigest()}" + ), + }, + "proceedings": { + "BACKEND": "django.core.cache.backends.dummy.DummyCache", + # "BACKEND": "ietf.utils.cache.LenientMemcacheCache", + # "LOCATION": "127.0.0.1:11211", + # No release-specific VERSION setting. + "KEY_PREFIX": "ietf:dt:proceedings", + # Key function is default except with sha384-encoded key + "KEY_FUNCTION": lambda key, key_prefix, version: ( + f"{key_prefix}:{version}:{sha384(str(key).encode('utf8')).hexdigest()}" + ), + }, + "sessions": { + "BACKEND": "django.core.cache.backends.locmem.LocMemCache", + }, + "htmlized": { + "BACKEND": "django.core.cache.backends.dummy.DummyCache", + #'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache', + "LOCATION": "/var/cache/datatracker/htmlized", + "OPTIONS": { + "MAX_ENTRIES": 1000, + }, + }, + "pdfized": { + "BACKEND": "django.core.cache.backends.dummy.DummyCache", + #'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache', + "LOCATION": "/var/cache/datatracker/pdfized", + "OPTIONS": { + "MAX_ENTRIES": 1000, + }, + }, + "slowpages": { + "BACKEND": "django.core.cache.backends.dummy.DummyCache", + #'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache', + "LOCATION": "/var/cache/datatracker/", + "OPTIONS": { + "MAX_ENTRIES": 5000, + }, + }, + "celery-results": { + "BACKEND": "django.core.cache.backends.memcached.PyMemcacheCache", + "LOCATION": "app:11211", + "KEY_PREFIX": "ietf:celery", + }, + } + +PUBLISH_IPR_STATES = ['posted', 'removed', 'removed_objfalse'] + +ADVERTISE_VERSIONS = ["markdown", "pyang", "rfc2html", "xml2rfc"] # We provide a secret key only for test and development modes. It's # absolutely vital that django fails to start in production mode unless a @@ -1215,61 +1513,36 @@ def skip_unreadable_post(record): loaders = TEMPLATES[0]['OPTIONS']['loaders'] loaders = tuple(l for e in loaders for l in (e[1] if isinstance(e, tuple) and "cached.Loader" in e[0] else (e,))) TEMPLATES[0]['OPTIONS']['loaders'] = loaders - - CACHES = { - 'default': { - 'BACKEND': 'django.core.cache.backends.dummy.DummyCache', - #'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache', - #'LOCATION': '127.0.0.1:11211', - #'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache', - 'VERSION': __version__, - 'KEY_PREFIX': 'ietf:dt', - }, - 'sessions': { - 'BACKEND': 'django.core.cache.backends.locmem.LocMemCache', - }, - 'htmlized': { - 'BACKEND': 'django.core.cache.backends.dummy.DummyCache', - #'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache', - 'LOCATION': '/var/cache/datatracker/htmlized', - 'OPTIONS': { - 'MAX_ENTRIES': 1000, - }, - }, - 'pdfized': { - 'BACKEND': 'django.core.cache.backends.dummy.DummyCache', - #'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache', - 'LOCATION': '/var/cache/datatracker/pdfized', - 'OPTIONS': { - 'MAX_ENTRIES': 1000, - }, - }, - 'slowpages': { - 'BACKEND': 'django.core.cache.backends.dummy.DummyCache', - #'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache', - 'LOCATION': '/var/cache/datatracker/', - 'OPTIONS': { - 'MAX_ENTRIES': 5000, - }, - }, - } SESSION_ENGINE = "django.contrib.sessions.backends.db" if 'SECRET_KEY' not in locals(): SECRET_KEY = 'PDwXboUq!=hPjnrtG2=ge#N$Dwy+wn@uivrugwpic8mxyPfHka' + if 'NOMCOM_APP_SECRET' not in locals(): + NOMCOM_APP_SECRET = b'\x9b\xdas1\xec\xd5\xa0SI~\xcb\xd4\xf5t\x99\xc4i\xd7\x9f\x0b\xa9\xe8\xfeY\x80$\x1e\x12tN:\x84' ALLOWED_HOSTS = ['*',] - + try: # see https://github.com/omarish/django-cprofile-middleware - import django_cprofile_middleware # pyflakes:ignore - MIDDLEWARE = MIDDLEWARE + ['django_cprofile_middleware.middleware.ProfilerMiddleware', ] + import django_cprofile_middleware # pyflakes:ignore + + MIDDLEWARE = MIDDLEWARE + [ + "django_cprofile_middleware.middleware.ProfilerMiddleware", + ] + DJANGO_CPROFILE_MIDDLEWARE_REQUIRE_STAFF = ( + False # Do not use this setting for a public site! + ) except ImportError: pass # Cannot have this set to True if we're using http: from the dev-server: CSRF_COOKIE_SECURE = False CSRF_COOKIE_SAMESITE = 'Lax' + CSRF_TRUSTED_ORIGINS += ['http://localhost:8000', 'http://127.0.0.1:8000', 'http://[::1]:8000'] SESSION_COOKIE_SECURE = False SESSION_COOKIE_SAMESITE = 'Lax' - + + +YOUTUBE_DOMAINS = ['www.youtube.com', 'youtube.com', 'youtu.be', 'm.youtube.com', 'youtube-nocookie.com', 'www.youtube-nocookie.com'] + +IETF_DOI_PREFIX = "10.17487" diff --git a/ietf/settings_sqlitetest.py b/ietf/settings_sqlitetest.py deleted file mode 100644 index 784e8dea642..00000000000 --- a/ietf/settings_sqlitetest.py +++ /dev/null @@ -1,58 +0,0 @@ -# Copyright The IETF Trust 2010-2020, All Rights Reserved -# -*- coding: utf-8 -*- - - -# Standard settings except we use SQLite and skip migrations, this is -# useful for speeding up tests that depend on the test database, try -# for instance: -# -# ./manage.py test --settings=settings_sqlitetest doc.ChangeStateTestCase -# - -import os -from ietf.settings import * # pyflakes:ignore -from ietf.settings import TEST_CODE_COVERAGE_CHECKER, BASE_DIR, PHOTOS_DIRNAME -import debug # pyflakes:ignore -debug.debug = True - -# Use a different hostname, to catch hardcoded values -IDTRACKER_BASE_URL = "https://sqlitetest.ietf.org" - -# Workaround to avoid spending minutes stepping through the migrations in -# every test run. The result of this is to use the 'syncdb' way of creating -# the test database instead of doing it through the migrations. Taken from -# https://gist.github.com/NotSqrt/5f3c76cd15e40ef62d09 - -class DisableMigrations(object): - - def __contains__(self, item): - return True - - def __getitem__(self, item): - return None - -MIGRATION_MODULES = DisableMigrations() - - -DATABASES = { - 'default': { - 'NAME': 'test.db', - 'ENGINE': 'django.db.backends.sqlite3', - }, - } - -if TEST_CODE_COVERAGE_CHECKER and not TEST_CODE_COVERAGE_CHECKER._started: # pyflakes:ignore - TEST_CODE_COVERAGE_CHECKER.start() # pyflakes:ignore - -NOMCOM_PUBLIC_KEYS_DIR=os.path.abspath("tmp-nomcom-public-keys-dir") - -MEDIA_ROOT = os.path.join(os.path.dirname(BASE_DIR), 'test/media/') # pyflakes:ignore -MEDIA_URL = '/test/media/' -PHOTOS_DIR = MEDIA_ROOT + PHOTOS_DIRNAME # pyflakes:ignore - -# Undo any developer-dependent middleware when running the tests -MIDDLEWARE = [ c for c in MIDDLEWARE if not c in DEV_MIDDLEWARE ] # pyflakes:ignore - -TEMPLATES[0]['OPTIONS']['context_processors'] = [ p for p in TEMPLATES[0]['OPTIONS']['context_processors'] if not p in DEV_TEMPLATE_CONTEXT_PROCESSORS ] # pyflakes:ignore - -REQUEST_PROFILE_STORE_ANONYMOUS_SESSIONS = False diff --git a/ietf/settings_test.py b/ietf/settings_test.py new file mode 100755 index 00000000000..e7ebc13eb28 --- /dev/null +++ b/ietf/settings_test.py @@ -0,0 +1,126 @@ +# Copyright The IETF Trust 2010-2023, All Rights Reserved +# -*- coding: utf-8 -*- + + +# Standard settings except we use Postgres and skip migrations, this is +# useful for speeding up tests that depend on the test database, try +# for instance: +# +# ./manage.py test --settings=settings_test doc.ChangeStateTestCase +# + +import atexit +import os +import shutil +import tempfile +from ietf.settings import * # pyflakes:ignore +from ietf.settings import ORIG_AUTH_PASSWORD_VALIDATORS, STORAGES +import debug # pyflakes:ignore +debug.debug = True + +# Use a different hostname, to catch hardcoded values +IDTRACKER_BASE_URL = "https://postgrestest.ietf.org" + +# Workaround to avoid spending minutes stepping through the migrations in +# every test run. The result of this is to use the 'syncdb' way of creating +# the test database instead of doing it through the migrations. Taken from +# https://gist.github.com/NotSqrt/5f3c76cd15e40ef62d09 + +class DisableMigrations(object): + + def __contains__(self, item): + return True + + def __getitem__(self, item): + return None + +MIGRATION_MODULES = DisableMigrations() + + +DATABASES = { + 'default': { + 'HOST': 'db', + 'PORT': '5432', + 'NAME': 'test.db', + 'ENGINE': 'django.db.backends.postgresql', + 'USER': 'django', + 'PASSWORD': 'RkTkDPFnKpko', + }, + } + +# test with a single DB - do not use a DB router +BLOBDB_DATABASE = "default" +DATABASE_ROUTERS = [] # type: ignore + +if TEST_CODE_COVERAGE_CHECKER: # pyflakes:ignore + TEST_CODE_COVERAGE_CHECKER.start() # pyflakes:ignore + +def tempdir_with_cleanup(**kwargs): + """Utility to create a temporary dir and arrange cleanup""" + _dir = tempfile.mkdtemp(**kwargs) + atexit.register(shutil.rmtree, _dir) + return _dir + + +NOMCOM_PUBLIC_KEYS_DIR = tempdir_with_cleanup(suffix="-nomcom-public-keys-dir") + +MEDIA_ROOT = tempdir_with_cleanup(suffix="-media") +PHOTOS_DIRNAME = "photo" +PHOTOS_DIR = os.path.join(MEDIA_ROOT, PHOTOS_DIRNAME) +os.mkdir(PHOTOS_DIR) + +# Undo any developer-dependent middleware when running the tests +MIDDLEWARE = [ c for c in MIDDLEWARE if not c in DEV_MIDDLEWARE ] # pyflakes:ignore + +TEMPLATES[0]['OPTIONS']['context_processors'] = [ p for p in TEMPLATES[0]['OPTIONS']['context_processors'] if not p in DEV_TEMPLATE_CONTEXT_PROCESSORS ] # pyflakes:ignore + +REQUEST_PROFILE_STORE_ANONYMOUS_SESSIONS = False + +# Override loggers with a safer set in case things go to the log during testing. Specifically, +# make sure there are no syslog loggers that might send things to a real syslog. +LOGGING["loggers"] = { # pyflakes:ignore + 'django': { + 'handlers': ['debug_console'], + 'level': 'INFO', + }, + 'django.request': { + 'handlers': ['debug_console'], + 'level': 'ERROR', + }, + 'django.server': { + 'handlers': ['django.server'], + 'level': 'INFO', + }, + 'django.security': { + 'handlers': ['debug_console', ], + 'level': 'INFO', + }, + 'oidc_provider': { + 'handlers': ['debug_console', ], + 'level': 'DEBUG', + }, + 'datatracker': { + 'handlers': ['debug_console'], + 'level': 'INFO', + }, + 'celery': { + 'handlers': ['debug_console'], + 'level': 'INFO', + }, +} + +# Restore AUTH_PASSWORD_VALIDATORS if they were reset in settings_local +try: + AUTH_PASSWORD_VALIDATORS = ORIG_AUTH_PASSWORD_VALIDATORS +except NameError: + pass + +# Use InMemoryStorage for red bucket and r2-rfc storages +STORAGES["red_bucket"] = { + "BACKEND": "django.core.files.storage.InMemoryStorage", + "OPTIONS": {"location": "red_bucket"}, +} +STORAGES["r2-rfc"] = { + "BACKEND": "django.core.files.storage.InMemoryStorage", + "OPTIONS": {"location": "r2-rfc"}, +} diff --git a/ietf/settings_testcrawl.py b/ietf/settings_testcrawl.py index a1b5ce8946d..edb978757a9 100644 --- a/ietf/settings_testcrawl.py +++ b/ietf/settings_testcrawl.py @@ -27,9 +27,14 @@ 'MAX_ENTRIES': 10000, }, }, + 'agenda': { + 'BACKEND': 'django.core.cache.backends.locmem.LocMemCache', + }, + 'proceedings': { + 'BACKEND': 'django.core.cache.backends.locmem.LocMemCache', + }, 'sessions': { 'BACKEND': 'django.core.cache.backends.locmem.LocMemCache', - # No version-specific VERSION setting. }, 'htmlized': { 'BACKEND': 'django.core.cache.backends.dummy.DummyCache', diff --git a/ietf/static/css/custom-bs-import.scss b/ietf/static/css/custom-bs-import.scss new file mode 100644 index 00000000000..644efdcf108 --- /dev/null +++ b/ietf/static/css/custom-bs-import.scss @@ -0,0 +1,58 @@ +@import "bootstrap/scss/functions"; + +// Enable negative margin classes. +$enable-negative-margins: true; + +// Don't add carets to dropdowns by default. +// $enable-caret: false; + +$popover-max-width: 100%; + +// Override default fonts + +$font-family-sans-serif: "Inter", +system-ui, +-apple-system, +"Segoe UI", +Roboto, +"Helvetica Neue", +"Noto Sans", +"Liberation Sans", +Arial, +sans-serif, +"Apple Color Emoji", +"Segoe UI Emoji", +"Segoe UI Symbol", +"Noto Color Emoji"; +$font-family-monospace: "Noto Sans Mono", +SFMono-Regular, +Menlo, +Monaco, +Consolas, +"Liberation Mono", +"Courier New", +monospace; + +// Enable color modes +$color-mode-type: data; + +@import "bootstrap/scss/variables"; +@import "bootstrap/scss/variables-dark"; + +$h1-font-size: $font-size-base * 2.2; +$h2-font-size: $font-size-base * 1.8; +$h3-font-size: $font-size-base * 1.6; +$h4-font-size: $font-size-base * 1.4; +$h5-font-size: $font-size-base * 1.2; +$h6-font-size: $font-size-base; + +// Default is gray-800, which is the same as the range slider background. +$light-bg-subtle-dark: mix($gray-800, $black); + +@import "bootstrap/scss/maps"; +@import "bootstrap/scss/mixins"; +@import "bootstrap/scss/utilities"; +@import "bootstrap/scss/root"; + + + diff --git a/ietf/static/css/datepicker.scss b/ietf/static/css/datepicker.scss index c25b790e0b1..b193ccda3a8 100644 --- a/ietf/static/css/datepicker.scss +++ b/ietf/static/css/datepicker.scss @@ -1,683 +1,32 @@ -/*! - * Datepicker for Bootstrap v1.9.0 (https://github.com/uxsolutions/bootstrap-datepicker) - * - * Licensed under the Apache License v2.0 (http://www.apache.org/licenses/LICENSE-2.0) - */ +@import "custom-bs-import"; - .datepicker { - border-radius: 4px; - direction: ltr; - } - .datepicker-inline { - width: 220px; - } - .datepicker-rtl { - direction: rtl; - } - .datepicker-rtl.dropdown-menu { - left: auto; - } - .datepicker-rtl table tr td span { - float: right; - } - .datepicker-dropdown { - top: 0; - left: 0; - padding: 4px; - } - .datepicker-dropdown:before { - content: ''; - display: inline-block; - border-left: 7px solid transparent; - border-right: 7px solid transparent; - border-bottom: 7px solid rgba(0, 0, 0, 0.15); - border-top: 0; - border-bottom-color: rgba(0, 0, 0, 0.2); - position: absolute; - } - .datepicker-dropdown:after { - content: ''; - display: inline-block; - border-left: 6px solid transparent; - border-right: 6px solid transparent; - border-bottom: 6px solid #fff; - border-top: 0; - position: absolute; - } - .datepicker-dropdown.datepicker-orient-left:before { - left: 6px; - } - .datepicker-dropdown.datepicker-orient-left:after { - left: 7px; - } - .datepicker-dropdown.datepicker-orient-right:before { - right: 6px; - } - .datepicker-dropdown.datepicker-orient-right:after { - right: 7px; - } - .datepicker-dropdown.datepicker-orient-bottom:before { - top: -7px; - } - .datepicker-dropdown.datepicker-orient-bottom:after { - top: -6px; - } - .datepicker-dropdown.datepicker-orient-top:before { - bottom: -7px; - border-bottom: 0; - border-top: 7px solid rgba(0, 0, 0, 0.15); - } - .datepicker-dropdown.datepicker-orient-top:after { - bottom: -6px; - border-bottom: 0; - border-top: 6px solid #fff; - } - .datepicker table { - margin: 0; - -webkit-touch-callout: none; - -webkit-user-select: none; - -khtml-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; - } - .datepicker table tr td, - .datepicker table tr th { - text-align: center; - width: 30px; - height: 30px; - border-radius: 4px; - border: none; - } - .table-striped .datepicker table tr td, - .table-striped .datepicker table tr th { - background-color: transparent; - } - .datepicker table tr td.old, - .datepicker table tr td.new { - color: #777777; - } - .datepicker table tr td.day:hover, - .datepicker table tr td.focused { - background: #eeeeee; - cursor: pointer; - } - .datepicker table tr td.disabled, - .datepicker table tr td.disabled:hover { - background: none; - color: #777777; - cursor: default; - } - .datepicker table tr td.highlighted { - color: #000; - background-color: #d9edf7; - border-color: #85c5e5; - border-radius: 0; - } - .datepicker table tr td.highlighted:focus, - .datepicker table tr td.highlighted.focus { - color: #000; - background-color: #afd9ee; - border-color: #298fc2; - } - .datepicker table tr td.highlighted:hover { - color: #000; - background-color: #afd9ee; - border-color: #52addb; - } - .datepicker table tr td.highlighted:active, - .datepicker table tr td.highlighted.active { - color: #000; - background-color: #afd9ee; - border-color: #52addb; - } - .datepicker table tr td.highlighted:active:hover, - .datepicker table tr td.highlighted.active:hover, - .datepicker table tr td.highlighted:active:focus, - .datepicker table tr td.highlighted.active:focus, - .datepicker table tr td.highlighted:active.focus, - .datepicker table tr td.highlighted.active.focus { - color: #000; - background-color: #91cbe8; - border-color: #298fc2; - } - .datepicker table tr td.highlighted.disabled:hover, - .datepicker table tr td.highlighted[disabled]:hover, - fieldset[disabled] .datepicker table tr td.highlighted:hover, - .datepicker table tr td.highlighted.disabled:focus, - .datepicker table tr td.highlighted[disabled]:focus, - fieldset[disabled] .datepicker table tr td.highlighted:focus, - .datepicker table tr td.highlighted.disabled.focus, - .datepicker table tr td.highlighted[disabled].focus, - fieldset[disabled] .datepicker table tr td.highlighted.focus { - background-color: #d9edf7; - border-color: #85c5e5; - } - .datepicker table tr td.highlighted.focused { - background: #afd9ee; - } - .datepicker table tr td.highlighted.disabled, - .datepicker table tr td.highlighted.disabled:active { - background: #d9edf7; - color: #777777; - } - .datepicker table tr td.today { - color: #000; - background-color: #ffdb99; - border-color: #ffb733; - } - .datepicker table tr td.today:focus, - .datepicker table tr td.today.focus { - color: #000; - background-color: #ffc966; - border-color: #b37400; - } - .datepicker table tr td.today:hover { - color: #000; - background-color: #ffc966; - border-color: #f59e00; - } - .datepicker table tr td.today:active, - .datepicker table tr td.today.active { - color: #000; - background-color: #ffc966; - border-color: #f59e00; - } - .datepicker table tr td.today:active:hover, - .datepicker table tr td.today.active:hover, - .datepicker table tr td.today:active:focus, - .datepicker table tr td.today.active:focus, - .datepicker table tr td.today:active.focus, - .datepicker table tr td.today.active.focus { - color: #000; - background-color: #ffbc42; - border-color: #b37400; - } - .datepicker table tr td.today.disabled:hover, - .datepicker table tr td.today[disabled]:hover, - fieldset[disabled] .datepicker table tr td.today:hover, - .datepicker table tr td.today.disabled:focus, - .datepicker table tr td.today[disabled]:focus, - fieldset[disabled] .datepicker table tr td.today:focus, - .datepicker table tr td.today.disabled.focus, - .datepicker table tr td.today[disabled].focus, - fieldset[disabled] .datepicker table tr td.today.focus { - background-color: #ffdb99; - border-color: #ffb733; - } - .datepicker table tr td.today.focused { - background: #ffc966; - } - .datepicker table tr td.today.disabled, - .datepicker table tr td.today.disabled:active { - background: #ffdb99; - color: #777777; - } - .datepicker table tr td.range { - color: #000; - background-color: #eeeeee; - border-color: #bbbbbb; - border-radius: 0; - } - .datepicker table tr td.range:focus, - .datepicker table tr td.range.focus { - color: #000; - background-color: #d5d5d5; - border-color: #7c7c7c; - } - .datepicker table tr td.range:hover { - color: #000; - background-color: #d5d5d5; - border-color: #9d9d9d; - } - .datepicker table tr td.range:active, - .datepicker table tr td.range.active { - color: #000; - background-color: #d5d5d5; - border-color: #9d9d9d; - } - .datepicker table tr td.range:active:hover, - .datepicker table tr td.range.active:hover, - .datepicker table tr td.range:active:focus, - .datepicker table tr td.range.active:focus, - .datepicker table tr td.range:active.focus, - .datepicker table tr td.range.active.focus { - color: #000; - background-color: #c3c3c3; - border-color: #7c7c7c; - } - .datepicker table tr td.range.disabled:hover, - .datepicker table tr td.range[disabled]:hover, - fieldset[disabled] .datepicker table tr td.range:hover, - .datepicker table tr td.range.disabled:focus, - .datepicker table tr td.range[disabled]:focus, - fieldset[disabled] .datepicker table tr td.range:focus, - .datepicker table tr td.range.disabled.focus, - .datepicker table tr td.range[disabled].focus, - fieldset[disabled] .datepicker table tr td.range.focus { - background-color: #eeeeee; - border-color: #bbbbbb; - } - .datepicker table tr td.range.focused { - background: #d5d5d5; - } - .datepicker table tr td.range.disabled, - .datepicker table tr td.range.disabled:active { - background: #eeeeee; - color: #777777; - } - .datepicker table tr td.range.highlighted { - color: #000; - background-color: #e4eef3; - border-color: #9dc1d3; - } - .datepicker table tr td.range.highlighted:focus, - .datepicker table tr td.range.highlighted.focus { - color: #000; - background-color: #c1d7e3; - border-color: #4b88a6; - } - .datepicker table tr td.range.highlighted:hover { - color: #000; - background-color: #c1d7e3; - border-color: #73a6c0; - } - .datepicker table tr td.range.highlighted:active, - .datepicker table tr td.range.highlighted.active { - color: #000; - background-color: #c1d7e3; - border-color: #73a6c0; - } - .datepicker table tr td.range.highlighted:active:hover, - .datepicker table tr td.range.highlighted.active:hover, - .datepicker table tr td.range.highlighted:active:focus, - .datepicker table tr td.range.highlighted.active:focus, - .datepicker table tr td.range.highlighted:active.focus, - .datepicker table tr td.range.highlighted.active.focus { - color: #000; - background-color: #a8c8d8; - border-color: #4b88a6; - } - .datepicker table tr td.range.highlighted.disabled:hover, - .datepicker table tr td.range.highlighted[disabled]:hover, - fieldset[disabled] .datepicker table tr td.range.highlighted:hover, - .datepicker table tr td.range.highlighted.disabled:focus, - .datepicker table tr td.range.highlighted[disabled]:focus, - fieldset[disabled] .datepicker table tr td.range.highlighted:focus, - .datepicker table tr td.range.highlighted.disabled.focus, - .datepicker table tr td.range.highlighted[disabled].focus, - fieldset[disabled] .datepicker table tr td.range.highlighted.focus { - background-color: #e4eef3; - border-color: #9dc1d3; - } - .datepicker table tr td.range.highlighted.focused { - background: #c1d7e3; - } - .datepicker table tr td.range.highlighted.disabled, - .datepicker table tr td.range.highlighted.disabled:active { - background: #e4eef3; - color: #777777; - } - .datepicker table tr td.range.today { - color: #000; - background-color: #f7ca77; - border-color: #f1a417; - } - .datepicker table tr td.range.today:focus, - .datepicker table tr td.range.today.focus { - color: #000; - background-color: #f4b747; - border-color: #815608; - } - .datepicker table tr td.range.today:hover { - color: #000; - background-color: #f4b747; - border-color: #bf800c; - } - .datepicker table tr td.range.today:active, - .datepicker table tr td.range.today.active { - color: #000; - background-color: #f4b747; - border-color: #bf800c; - } - .datepicker table tr td.range.today:active:hover, - .datepicker table tr td.range.today.active:hover, - .datepicker table tr td.range.today:active:focus, - .datepicker table tr td.range.today.active:focus, - .datepicker table tr td.range.today:active.focus, - .datepicker table tr td.range.today.active.focus { - color: #000; - background-color: #f2aa25; - border-color: #815608; - } - .datepicker table tr td.range.today.disabled:hover, - .datepicker table tr td.range.today[disabled]:hover, - fieldset[disabled] .datepicker table tr td.range.today:hover, - .datepicker table tr td.range.today.disabled:focus, - .datepicker table tr td.range.today[disabled]:focus, - fieldset[disabled] .datepicker table tr td.range.today:focus, - .datepicker table tr td.range.today.disabled.focus, - .datepicker table tr td.range.today[disabled].focus, - fieldset[disabled] .datepicker table tr td.range.today.focus { - background-color: #f7ca77; - border-color: #f1a417; - } - .datepicker table tr td.range.today.disabled, - .datepicker table tr td.range.today.disabled:active { - background: #f7ca77; - color: #777777; - } - .datepicker table tr td.selected, - .datepicker table tr td.selected.highlighted { - color: #fff; - background-color: #777777; - border-color: #555555; - text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); - } - .datepicker table tr td.selected:focus, - .datepicker table tr td.selected.highlighted:focus, - .datepicker table tr td.selected.focus, - .datepicker table tr td.selected.highlighted.focus { - color: #fff; - background-color: #5e5e5e; - border-color: #161616; - } - .datepicker table tr td.selected:hover, - .datepicker table tr td.selected.highlighted:hover { - color: #fff; - background-color: #5e5e5e; - border-color: #373737; - } - .datepicker table tr td.selected:active, - .datepicker table tr td.selected.highlighted:active, - .datepicker table tr td.selected.active, - .datepicker table tr td.selected.highlighted.active { - color: #fff; - background-color: #5e5e5e; - border-color: #373737; - } - .datepicker table tr td.selected:active:hover, - .datepicker table tr td.selected.highlighted:active:hover, - .datepicker table tr td.selected.active:hover, - .datepicker table tr td.selected.highlighted.active:hover, - .datepicker table tr td.selected:active:focus, - .datepicker table tr td.selected.highlighted:active:focus, - .datepicker table tr td.selected.active:focus, - .datepicker table tr td.selected.highlighted.active:focus, - .datepicker table tr td.selected:active.focus, - .datepicker table tr td.selected.highlighted:active.focus, - .datepicker table tr td.selected.active.focus, - .datepicker table tr td.selected.highlighted.active.focus { - color: #fff; - background-color: #4c4c4c; - border-color: #161616; - } - .datepicker table tr td.selected.disabled:hover, - .datepicker table tr td.selected.highlighted.disabled:hover, - .datepicker table tr td.selected[disabled]:hover, - .datepicker table tr td.selected.highlighted[disabled]:hover, - fieldset[disabled] .datepicker table tr td.selected:hover, - fieldset[disabled] .datepicker table tr td.selected.highlighted:hover, - .datepicker table tr td.selected.disabled:focus, - .datepicker table tr td.selected.highlighted.disabled:focus, - .datepicker table tr td.selected[disabled]:focus, - .datepicker table tr td.selected.highlighted[disabled]:focus, - fieldset[disabled] .datepicker table tr td.selected:focus, - fieldset[disabled] .datepicker table tr td.selected.highlighted:focus, - .datepicker table tr td.selected.disabled.focus, - .datepicker table tr td.selected.highlighted.disabled.focus, - .datepicker table tr td.selected[disabled].focus, - .datepicker table tr td.selected.highlighted[disabled].focus, - fieldset[disabled] .datepicker table tr td.selected.focus, - fieldset[disabled] .datepicker table tr td.selected.highlighted.focus { - background-color: #777777; - border-color: #555555; - } - .datepicker table tr td.active, - .datepicker table tr td.active.highlighted { - color: #fff; - background-color: #337ab7; - border-color: #2e6da4; - text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); - } - .datepicker table tr td.active:focus, - .datepicker table tr td.active.highlighted:focus, - .datepicker table tr td.active.focus, - .datepicker table tr td.active.highlighted.focus { - color: #fff; - background-color: #286090; - border-color: #122b40; - } - .datepicker table tr td.active:hover, - .datepicker table tr td.active.highlighted:hover { - color: #fff; - background-color: #286090; - border-color: #204d74; - } - .datepicker table tr td.active:active, - .datepicker table tr td.active.highlighted:active, - .datepicker table tr td.active.active, - .datepicker table tr td.active.highlighted.active { - color: #fff; - background-color: #286090; - border-color: #204d74; - } - .datepicker table tr td.active:active:hover, - .datepicker table tr td.active.highlighted:active:hover, - .datepicker table tr td.active.active:hover, - .datepicker table tr td.active.highlighted.active:hover, - .datepicker table tr td.active:active:focus, - .datepicker table tr td.active.highlighted:active:focus, - .datepicker table tr td.active.active:focus, - .datepicker table tr td.active.highlighted.active:focus, - .datepicker table tr td.active:active.focus, - .datepicker table tr td.active.highlighted:active.focus, - .datepicker table tr td.active.active.focus, - .datepicker table tr td.active.highlighted.active.focus { - color: #fff; - background-color: #204d74; - border-color: #122b40; - } - .datepicker table tr td.active.disabled:hover, - .datepicker table tr td.active.highlighted.disabled:hover, - .datepicker table tr td.active[disabled]:hover, - .datepicker table tr td.active.highlighted[disabled]:hover, - fieldset[disabled] .datepicker table tr td.active:hover, - fieldset[disabled] .datepicker table tr td.active.highlighted:hover, - .datepicker table tr td.active.disabled:focus, - .datepicker table tr td.active.highlighted.disabled:focus, - .datepicker table tr td.active[disabled]:focus, - .datepicker table tr td.active.highlighted[disabled]:focus, - fieldset[disabled] .datepicker table tr td.active:focus, - fieldset[disabled] .datepicker table tr td.active.highlighted:focus, - .datepicker table tr td.active.disabled.focus, - .datepicker table tr td.active.highlighted.disabled.focus, - .datepicker table tr td.active[disabled].focus, - .datepicker table tr td.active.highlighted[disabled].focus, - fieldset[disabled] .datepicker table tr td.active.focus, - fieldset[disabled] .datepicker table tr td.active.highlighted.focus { - background-color: #337ab7; - border-color: #2e6da4; - } - .datepicker table tr td span { - display: block; - width: 23%; - height: 54px; - line-height: 54px; - float: left; - margin: 1%; - cursor: pointer; - border-radius: 4px; - } - .datepicker table tr td span:hover, - .datepicker table tr td span.focused { - background: #eeeeee; - } - .datepicker table tr td span.disabled, - .datepicker table tr td span.disabled:hover { - background: none; - color: #777777; - cursor: default; - } - .datepicker table tr td span.active, - .datepicker table tr td span.active:hover, - .datepicker table tr td span.active.disabled, - .datepicker table tr td span.active.disabled:hover { - color: #fff; - background-color: #337ab7; - border-color: #2e6da4; - text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); - } - .datepicker table tr td span.active:focus, - .datepicker table tr td span.active:hover:focus, - .datepicker table tr td span.active.disabled:focus, - .datepicker table tr td span.active.disabled:hover:focus, - .datepicker table tr td span.active.focus, - .datepicker table tr td span.active:hover.focus, - .datepicker table tr td span.active.disabled.focus, - .datepicker table tr td span.active.disabled:hover.focus { - color: #fff; - background-color: #286090; - border-color: #122b40; - } - .datepicker table tr td span.active:hover, - .datepicker table tr td span.active:hover:hover, - .datepicker table tr td span.active.disabled:hover, - .datepicker table tr td span.active.disabled:hover:hover { - color: #fff; - background-color: #286090; - border-color: #204d74; - } - .datepicker table tr td span.active:active, - .datepicker table tr td span.active:hover:active, - .datepicker table tr td span.active.disabled:active, - .datepicker table tr td span.active.disabled:hover:active, - .datepicker table tr td span.active.active, - .datepicker table tr td span.active:hover.active, - .datepicker table tr td span.active.disabled.active, - .datepicker table tr td span.active.disabled:hover.active { - color: #fff; - background-color: #286090; - border-color: #204d74; - } - .datepicker table tr td span.active:active:hover, - .datepicker table tr td span.active:hover:active:hover, - .datepicker table tr td span.active.disabled:active:hover, - .datepicker table tr td span.active.disabled:hover:active:hover, - .datepicker table tr td span.active.active:hover, - .datepicker table tr td span.active:hover.active:hover, - .datepicker table tr td span.active.disabled.active:hover, - .datepicker table tr td span.active.disabled:hover.active:hover, - .datepicker table tr td span.active:active:focus, - .datepicker table tr td span.active:hover:active:focus, - .datepicker table tr td span.active.disabled:active:focus, - .datepicker table tr td span.active.disabled:hover:active:focus, - .datepicker table tr td span.active.active:focus, - .datepicker table tr td span.active:hover.active:focus, - .datepicker table tr td span.active.disabled.active:focus, - .datepicker table tr td span.active.disabled:hover.active:focus, - .datepicker table tr td span.active:active.focus, - .datepicker table tr td span.active:hover:active.focus, - .datepicker table tr td span.active.disabled:active.focus, - .datepicker table tr td span.active.disabled:hover:active.focus, - .datepicker table tr td span.active.active.focus, - .datepicker table tr td span.active:hover.active.focus, - .datepicker table tr td span.active.disabled.active.focus, - .datepicker table tr td span.active.disabled:hover.active.focus { - color: #fff; - background-color: #204d74; - border-color: #122b40; - } - .datepicker table tr td span.active.disabled:hover, - .datepicker table tr td span.active:hover.disabled:hover, - .datepicker table tr td span.active.disabled.disabled:hover, - .datepicker table tr td span.active.disabled:hover.disabled:hover, - .datepicker table tr td span.active[disabled]:hover, - .datepicker table tr td span.active:hover[disabled]:hover, - .datepicker table tr td span.active.disabled[disabled]:hover, - .datepicker table tr td span.active.disabled:hover[disabled]:hover, - fieldset[disabled] .datepicker table tr td span.active:hover, - fieldset[disabled] .datepicker table tr td span.active:hover:hover, - fieldset[disabled] .datepicker table tr td span.active.disabled:hover, - fieldset[disabled] .datepicker table tr td span.active.disabled:hover:hover, - .datepicker table tr td span.active.disabled:focus, - .datepicker table tr td span.active:hover.disabled:focus, - .datepicker table tr td span.active.disabled.disabled:focus, - .datepicker table tr td span.active.disabled:hover.disabled:focus, - .datepicker table tr td span.active[disabled]:focus, - .datepicker table tr td span.active:hover[disabled]:focus, - .datepicker table tr td span.active.disabled[disabled]:focus, - .datepicker table tr td span.active.disabled:hover[disabled]:focus, - fieldset[disabled] .datepicker table tr td span.active:focus, - fieldset[disabled] .datepicker table tr td span.active:hover:focus, - fieldset[disabled] .datepicker table tr td span.active.disabled:focus, - fieldset[disabled] .datepicker table tr td span.active.disabled:hover:focus, - .datepicker table tr td span.active.disabled.focus, - .datepicker table tr td span.active:hover.disabled.focus, - .datepicker table tr td span.active.disabled.disabled.focus, - .datepicker table tr td span.active.disabled:hover.disabled.focus, - .datepicker table tr td span.active[disabled].focus, - .datepicker table tr td span.active:hover[disabled].focus, - .datepicker table tr td span.active.disabled[disabled].focus, - .datepicker table tr td span.active.disabled:hover[disabled].focus, - fieldset[disabled] .datepicker table tr td span.active.focus, - fieldset[disabled] .datepicker table tr td span.active:hover.focus, - fieldset[disabled] .datepicker table tr td span.active.disabled.focus, - fieldset[disabled] .datepicker table tr td span.active.disabled:hover.focus { - background-color: #337ab7; - border-color: #2e6da4; - } - .datepicker table tr td span.old, - .datepicker table tr td span.new { - color: #777777; - } - .datepicker .datepicker-switch { - width: 145px; - } - .datepicker .datepicker-switch, - .datepicker .prev, - .datepicker .next, - .datepicker tfoot tr th { - cursor: pointer; - } - .datepicker .datepicker-switch:hover, - .datepicker .prev:hover, - .datepicker .next:hover, - .datepicker tfoot tr th:hover { - background: #eeeeee; - } - .datepicker .prev.disabled, - .datepicker .next.disabled { - visibility: hidden; - } - .datepicker .cw { - font-size: 10px; - width: 12px; - padding: 0 2px 0 5px; - vertical-align: middle; - } - .input-group.date .input-group-addon { - cursor: pointer; - } - .input-daterange { - width: 100%; - } - .input-daterange input { - text-align: center; - } - .input-daterange input:first-child { - border-radius: 3px 0 0 3px; - } - .input-daterange input:last-child { - border-radius: 0 3px 3px 0; - } - .input-daterange .input-group-addon { - width: auto; - min-width: 16px; - padding: 4px 5px; - line-height: 1.42857143; - border-width: 1px 0; - margin-left: -5px; - margin-right: -5px; - } - /*# sourceMappingURL=bootstrap-datepicker3.css.map */ +// FIXME: color.scale doesn't seem to work with CSS variables, so avoid those:` +$dp-cell-focus-background-color: $dropdown-link-hover-bg !default; + +@import "vanillajs-datepicker/sass/datepicker-bs5"; + +[data-bs-theme="dark"] .datepicker-picker { + .datepicker-header, + .datepicker-controls .btn, + .datepicker-main, + .datepicker-footer { + background-color: $gray-800; + } + + .datepicker-cell:hover { + background-color: $gray-700; + } + + .datepicker-cell.day.focused { + background-color: $gray-600; + } + + .datepicker-cell.day.selected.focused { + background-color: $blue; + } + + .datepicker-controls .btn:hover { + background-color:$gray-700; + color: $gray-400; + } +} diff --git a/ietf/static/css/document_html.scss b/ietf/static/css/document_html.scss new file mode 100644 index 00000000000..5a4282195f9 --- /dev/null +++ b/ietf/static/css/document_html.scss @@ -0,0 +1,382 @@ +@use "sass:map"; + +@import "custom-bs-import"; + +// Layout & components +// Only import what we need: +@import "bootstrap/scss/reboot"; +@import "bootstrap/scss/type"; +// @import "bootstrap/scss/images"; +@import "bootstrap/scss/containers"; +@import "bootstrap/scss/grid"; +// @import "bootstrap/scss/tables"; +@import "bootstrap/scss/forms"; +@import "bootstrap/scss/buttons"; +@import "bootstrap/scss/transitions"; +@import "bootstrap/scss/dropdown"; +@import "bootstrap/scss/button-group"; +@import "bootstrap/scss/nav"; +@import "bootstrap/scss/navbar"; +// @import "bootstrap/scss/card"; +// @import "bootstrap/scss/accordion"; +// @import "bootstrap/scss/breadcrumb"; +@import "bootstrap/scss/pagination"; +@import "bootstrap/scss/badge"; +@import "bootstrap/scss/alert"; +// @import "bootstrap/scss/progress"; +// @import "bootstrap/scss/list-group"; +// @import "bootstrap/scss/close"; +// @import "bootstrap/scss/toasts"; +// @import "bootstrap/scss/modal"; +@import "bootstrap/scss/tooltip"; +// @import "bootstrap/scss/popover"; +// @import "bootstrap/scss/carousel"; +// @import "bootstrap/scss/spinners"; +// @import "bootstrap/scss/offcanvas"; +// @import "bootstrap/scss/placeholders"; + +// Helpers +@import "bootstrap/scss/helpers"; + +// Utilities +@import "bootstrap/scss/utilities/api"; + +:root { + --doc-ptsize-max: 16pt; +} + +.overscroll-none { + overscroll-behavior: none; +} + +.no-scrollbar { + scrollbar-width: none; +} + +.sidebar-toggle[aria-expanded="true"] .sidebar-shown { + display: none; +} + +.sidebar-toggle[aria-expanded="false"] .sidebar-collapsed { + display: none; +} + +.sidebar-toolbar { + z-index: 1; +} + +// Toggle classes for dark/light modes +[data-bs-theme="dark"] { + .d-dm-none { + display: none; + } + + .d-lm-none { + display: initial; + } +} + +[data-bs-theme="light"] { + .d-dm-none { + display: initial; + } + + .d-lm-none { + display: none; + } +} + +// Show theme toggler checkbox +.dropdown-menu .active .bi { + display: block !important; +} + +@media screen { + @include media-breakpoint-down(md) { + body { + padding-top: 60px; + } + + html { + scroll-padding-top: 60px; + } + } + + @include media-breakpoint-down(sm) { + body { + padding-top: 70px; + } + + html { + scroll-padding-top: 70px; + } + } +} + +.rfcmarkup, +.rfchtml { + font-family: var(--bs-font-monospace); + + caption { + padding: 0; + color: var(--bs-body-color); + } + + code { + font-size: 1em; + color: inherit; + } + + @media screen { + + // the viewport-width ("vw") constants are magic; they seem to work for + // many monospace fonts, but may need tweaking + @include media-breakpoint-up(xs) { + font-size: min(2.2vw, var(--doc-ptsize-max)); + } + + @include media-breakpoint-up(md) { + font-size: min(1.6vw, var(--doc-ptsize-max)); + } + + .grey, + hr { + opacity: $hr-opacity; + } + } + + h1, + h2, + h3, + h4, + h5, + h6 { + font-weight: bold; + font-size: 1em; + } + + pre, + code { + font-size: 1em; + overflow: visible; + } + + pre { + margin: 0; + padding: 0; + } + + .bcp14 { + font-weight: bold; + // color: $gray-700; + } +} + +.rfcmarkup { + + // A lot of plaintext documents seem to have line lengths >72ch. + // To handle that, we calculate with 80ch here and adjust some of the + // font sizes down accordingly. + pre { + width: 80ch; + white-space: pre-wrap; + } + + @media screen { + + // the viewport-width ("vw") constants are magic; they seem to work for + // many monospace fonts, but may need tweaking + @include media-breakpoint-up(xs) { + font-size: min(2vw, var(--doc-ptsize-max)); + } + + @include media-breakpoint-up(md) { + font-size: min(1.5vw, var(--doc-ptsize-max)); + } + } + + h1, + h2, + h3, + h4, + h5, + h6 { + white-space: pre; + display: inline; + } + +} + +tbody.meta tr { + + td:first-child, + th:first-child, + td.edit { + display: none; + } +} + +.sidebar { + height: 100vh; + + .toplink, + #name-table-of-contents { + display: none; + } + + th, + td { + display: block; + padding: 0; + } + + td { + margin-bottom: map.get($spacers, 3); + } +} + +.navbar { + + td:not(:first-child), + th:not(:first-child) { + padding-top: map.get($spacers, 3); + } + +} + +// Add some padding when there are multiple buttons in a line that can wrap +.buttonlist .btn { + margin-bottom: map.get($spacers, 1); +} + +// Make revision numbers pagination items fixed-width +.revision-list { + .page-item { + width: 2.2rem; + } + + .page-item.rfc { + width: 6.6rem; + } +} + +#docinfo { + max-height: 70vh; + z-index: -1; +} + + +.badge-obs { + color: white; + background-color: $orange-800; +} + +.badge-ps { + color: black; + background-color: $blue-300; +} + +.badge-exp { + color: black; + background-color: $yellow-200; +} + +.badge-inf { + color: white; + background-color: $orange; +} + +.badge-ds { + color: black; + background-color: $cyan-200; +} + +.badge-hist { + color: white; + background-color: $gray-700; +} + +.badge-std { + color: black; + background-color: $teal-200; +} + +.badge-bcp { + color: white; + background-color: $pink-500; +} + +.badge-unkn { + color: black; + background-color: $gray-300; +} + +.badge-draft { + color: white; + background-color: $danger; +} + +.badge-generic { + color: white; + background-color: $danger; +} + +#toc-nav { + width: inherit; + overscroll-behavior-y: none; // Prevent overscrolling from scrolling the main content +} + + +@media print { + @page { + size: letter; + margin: .75in; + } + + .rfcmarkup { + font-size: 9.75pt !important; + line-height: 1.25em !important; + } + + .rfchtml { + font-size: 9.75pt; + line-height: 1.25em; + } + + body { + margin: 0; + padding: 0; + } + + pre { + page-break-inside: avoid; + } + + /* + a:link, + a:visited { + // color: inherit; + // text-decoration: none; + } +*/ + + .newpage { + page-break-before: always !important; + } + + .noprint { + display: none; + } +} + +// Select2 styling +@import "select2"; + +.select2-results__option, +.select2-search__field { + font-size: small !important; +} + +.select2-container--open { + z-index: 9999999; +} diff --git a/ietf/static/css/document_html_inline.scss b/ietf/static/css/document_html_inline.scss new file mode 100644 index 00000000000..a7575343819 --- /dev/null +++ b/ietf/static/css/document_html_inline.scss @@ -0,0 +1,6 @@ +@import "document_html"; + +// Make the bootstrap icons available via data-url. +$bootstrap-icons-font-src: url(data-url:npm:bootstrap-icons/font/fonts/bootstrap-icons.woff2) format("woff2"), +url(data-url:npm:bootstrap-icons/font/fonts/bootstrap-icons.woff) format("woff"); +@import "bootstrap-icons/font/bootstrap-icons"; diff --git a/ietf/static/css/document_html_referenced.scss b/ietf/static/css/document_html_referenced.scss new file mode 100644 index 00000000000..5342989405b --- /dev/null +++ b/ietf/static/css/document_html_referenced.scss @@ -0,0 +1,6 @@ +@import "document_html"; + +// Make the bootstrap icons available. +$bootstrap-icons-font-src: url("npm:bootstrap-icons/font/fonts/bootstrap-icons.woff2") format("woff2"), +url("npm:bootstrap-icons/font/fonts/bootstrap-icons.woff") format("woff"); +@import "bootstrap-icons/font/bootstrap-icons"; diff --git a/ietf/static/css/document_html_txt.scss b/ietf/static/css/document_html_txt.scss new file mode 100644 index 00000000000..a5991056c96 --- /dev/null +++ b/ietf/static/css/document_html_txt.scss @@ -0,0 +1,468 @@ +// Based on https://github.com/martinthomson/rfc-txt-html/blob/main/txt.css + +:root { + --line: 1.3em; + --block: 0 0 0 3ch; + --paragraph: var(--line) 0 var(--line) 3ch; +} + +// WeasyPrint can't handle CSS variables in multi-attribute properties, so work +// around that +// https://github.com/Kozea/WeasyPrint/issues/1219 + +@mixin margin-paragraph { + margin-top: var(--line); + margin-right: 0; + margin-bottom: var(--line); + margin-left: 3ch; +} + +@mixin margin-line { + margin-top: var(--line); + margin-right: 0; + margin-bottom: var(--line); + margin-left: 0; +} + +@mixin margin-block { + margin-top: 0; + margin-right: 0; + margin-bottom: 0; + margin-left: 3ch; +} + +.rfchtml { +// body { +// color: black; +// font-family: monospace; +// font-size: 1em; + line-height: var(--line); + width: 72ch; + // margin: var(--line) 3ch; + margin-top: var(--line); + margin-right: 3ch; + margin-bottom: var(--line); + margin-left: 3ch; + + +h1, h2, h3, h4, h5 { + font-weight: bold; + font-size: inherit; + line-height: inherit; + @include margin-line; // margin: var(--line) 0; +} +.section-number { + margin-right: 1ch; +} +p { + margin: 0; +} +section > p, section > div > p { + @include margin-paragraph; // margin: var(--paragraph); +} +aside { + @include margin-block; // margin: var(--block); +} +figure { + margin: 0; +} +blockquote { + @include margin-paragraph; // margin: var(--paragraph); + padding-left: calc(2ch - 2px); + border-left: 2px solid var(--bs-border-color); +} + +/* Header junk */ +#external-metadata { + display: none !important; /* metadata.min.js is evil because it produces unstyleable goop */ +} +#identifiers dt:is(.label-stream, .label-rfc, .label-std, .label-bcp, .label-internet-draft, + .label-workgroup, .label-intended-status, .label-obsoletes, .label-updates, + .label-published, .label-expires, .label-category, .label-issn, + .label-authors), .ears { + display: none; +} +#identifiers { + margin: 0; +} +#identifiers dt { + margin: 0 1ch 0 0; + float: revert; + display: inline-block; +} +#identifiers dd { + margin: 0; + margin-left: 0 !important; /* grr */ + width: 47ch; + /* HAXX: this gets around the lack of text-content-trim support */ + display: flex; + flex-wrap: wrap; +} +#identifiers dd::before { + margin: 0 1ch 0 0; +} +#identifiers dd.rfc::before { + content: "Request for Comments:"; +} +#identifiers dd.std::before { + content: "STD:"; +} +#identifiers dd.bcp::before { + content: "BCP:"; +} +#identifiers dd.internet-draft::before { + content: "Internet-Draft:"; +} +#identifiers dd.workgroup::before { + content: "Workgroup:"; +} +#identifiers dd.intended-status::before { + content: "Intended Status:"; +} +#identifiers dd.obsoletes::before { + content: "Obsoletes:"; + margin: 0 0 0 -10ch; +} +#identifiers dd.obsoletes { + padding-left: 10ch; +} +#identifiers dd.updates::before { + content: "Updates:"; + margin: 0 0 0 -8ch; +} +#identifiers dd.updates { + padding-left: 8ch; +} +#identifiers dd:is(.updates, .obsoletes) a { + margin: 0 0 0 1ch; +} +#identifiers dd:is(.updates, .obsoletes) a:last-of-type { + margin-right: 1ch; +} +#identifiers dd.published::before { + content: "Published:"; +} +#identifiers dd.expires::before { + content: "Expires:"; +} +#identifiers dd.category::before { + content: "Category:"; +} +#identifiers dd.issn::before { + content: "ISSN:"; +} + +/* Thanks WeasyPrint for not supporting @supports */ +/* @supports not (display: grid) { */ + #identifiers dd.authors { + padding-left: 8ch; + width: 64ch; + } + #identifiers dd.authors::before { + content: "Authors:"; + margin: 0 0 0 -8ch; + } + #identifiers dd.authors .author { + display: inline-block; + margin: 0 2ch 0 1ch; + min-height: calc(2 * var(--line)); + } + #identifiers dd.authors .author:last-of-type { + margin-right: 0; + } +/* } */ +/* #identifiers styling for when grid layout is supported, or not */ +@supports(display: grid) { + #identifiers { + display: grid; + grid-template-columns: 47ch 24ch; + grid-auto-rows: auto; + gap: 0 1ch; + } + #identifiers dd { + grid-column: 1; + } + #identifiers dd.authors { + grid-area: 1 / 2 / 100 / 3; + width: 24ch; + text-align: right; + display: block; + /* overrides for @supports not block */ + padding-left: 0; + } + /* more overrides for @supports not block */ + #identifiers dd.authors::before { + display: none; + } + #identifiers dd.authors .author { + display: block; + margin: 0; + } +} + +#title { + clear: left; + text-align: center; + margin-top: calc(2 * var(--line)); +} +#rfcnum { + display: none; +} +:is(#status-of-memo, #copyright) a { + white-space: nowrap; +} +.toplink { + display: none; +} +nav.toc ul { + list-style: none; + margin: 0; + padding: 0; +} +nav.toc ul > li { + padding-left: 2ch; +} +nav.toc > ul > li { + padding-left: 3ch; +} +nav.toc ul > li > p { + margin: 0; +} + +/* Lists */ +ol, ul { + padding: 0; +} +ol { + margin: 0 0 0 6ch; /* todo: deal with lists that have >= 10 items */ +} +:is(ol, ul) ol { + margin: 0 0 0 3ch; +} +ul { + margin: 0 0 0 4ch; +} +ul.ulEmpty { + list-style: none; +} +ul:not(.ulEmpty) { + list-style-type: '*'; +} +ul ul:not(.ulEmpty) { + list-style-type: '-'; +} +:is(ul, ol) ul { + margin-left: 1ch; +} +ul ul ul:not(.ulEmpty) { + list-style-type: 'o'; +} +li { + @include margin-line; // margin: var(--line) 0; + padding: 0 0 0 2ch; +} +dl { + margin: 0; +} +section > dl, section > div > dl { + @include margin-block; // margin: var(--block); +} +dl, dt { + clear: left; +} +dt { + float: left; + font-weight: bold; + margin: 0 2ch 0 0; + break-after: avoid; +} +dd { + @include margin-paragraph; // margin: var(--paragraph); + margin-left: 3ch !important; /* override attribute added by xml2rfc */ + padding: 0; + break-before: avoid; +} +dl.dlNewline > dd { + clear: left; +} +dl.olPercent > dt { + min-width: 4ch; +} +dl.olPercent > dd { + margin-left: 6ch !important; /* as above */ +} +dl > dd > dl { + margin-top: var(--line); + margin-bottom: 0; +} +dl.references dt { + margin-right: 1ch; +} +dl.references dd { + margin-left: 11ch !important; /* grr */ +} +:is(dd, span).break { + display: none; +} +:is(li, dd, blockquote, aside) :is(p, ol, ul:not(.toc), dl):not(:first-child) { + margin-top: var(--line); +} +:is(li, dd, blockquote, aside) .break:first-child + :is(p, ol, ul, dl) { + margin-top: 0; +} +:is(ol:is(.compact, .olCompact), ul:is(.compact, .ulCompact)) > li, +:is(dl.compact, .dlCompact) > :is(dt, dd) { + margin-top: 0; + margin-bottom: 0; +} + +/* Figures, tables */ +pre { + @include margin-line; // margin: var(--line) 0; +} +div:is(.artwork, .sourcecode) { + margin-top: var(--line); + margin-bottom: var(--line); + display: flex; + flex-wrap: nowrap; + align-items: end; +} +div:is(.artwork, .sourcecode).alignCenter { + justify-content: center; +} +div:is(.artwork, .sourcecode).alignRight { + justify-content: end; +} +div:is(.artwork, .sourcecode)::before { + flex: 0 1 3ch; + content: ""; +} +div:is(.artwork, .sourcecode).alignRight::before { + flex-grow: 1; +} +div:is(.artwork, .sourcecode) pre { + flex: 0 0 content; + margin: 0; + max-width: 72ch; + overflow: auto clip; +} +div:is(.artwork, .sourcecode) .pilcrow { + flex: 0 0 1ch; +} +figcaption, table caption { + text-align: center; + margin-top: var(--line); +} +table { + --half-line: calc(var(--line) / 2 - 1px); + caption-side: bottom; + // margin: var(--line) 0 var(--half-line) 3ch; + margin-top: var(--line); + margin-right: 0; + margin-bottom: var(--half-line); + margin-left: 3ch; + border-collapse: collapse; +} +table.center { + margin-left: auto; /* todo: add 3ch */ + margin-right: auto; +} +table caption { + margin-top: calc(var(--half-line) + var(--line)); +} +thead, tfoot { + border-top-style: double; + border-bottom-style: double; +} +td, th { + border: 1px solid var(--bs-border-color); + // padding: var(--half-line) 1ch; + padding-top: var(--half-line); + padding-right: 1ch; + padding-bottom: var(--half-line); + padding-left: 1ch; +} +.text-left { + text-align: left; +} +.text-center { + text-align: center; +} +.text-right { + text-align: right; +} + +/* Links */ +a.selfRef, a.pilcrow, .iref + a.internal { + color: inherit; + text-decoration: none; +} +a.relref, a.xref { + hyphens: none; +} +a:is(.relref, .xref:is(.cite, .auto.internal)) { + white-space: nowrap; +} +.pilcrow { + display: inline-block; + margin-right: -1ch; + opacity: 0.01; + text-decoration: none; + user-select: none; +} +:hover > .pilcrow { + opacity: 0.2; +} +* > .pilcrow[href]:hover { + opacity: 0.6; +} + +/* sup, sub */ +sup, sub { + line-height: 1.1; +} + +/* Authors */ +address, address.vcard { + font-style: normal; + // margin: var(--line) 0 var(--line) 3ch + margin-top: var(--line); + margin-right: 0; + margin-bottom: var(--line); + margin-left: 3ch; +} +address .tel, address .email { + // margin: var(--line) 0 0; + margin-top: var(--line); + margin-right: 0; + margin-bottom: 0; + margin-left: 0; +} +address .tel + .email { + margin: 0; +} + +/* haxx */ +section > p, section > dl.references > dd { + /* Really long lines can wrap when all else fails. + * This won't affect
       or , or cases where soft-wrapping occurs.
      +   * Mostly this exists so that long URLs wrap properly in Safari, which
      +   * doesn't break words at '/' like other browsers. */
      +  overflow-wrap: break-word;
      +}
      +
      +/* From https://github.com/martinthomson/rfc-css/blob/main/rfc.css */
      +/* SVG Trick: a prefix match works because only black and white are allowed */
      +svg :is([stroke="black"], [stroke^="#000"]) {
      +    stroke: var(--bs-body-color);
      +}
      +svg :is([stroke="white"], [stroke^="#fff"]) {
      +    stroke: var(--bs-body-bg);
      +}
      +svg :is([fill="black"], [fill^="#000"], :not([fill])) {
      +    fill: var(--bs-body-color);
      +}
      +svg :is([fill="white"], [fill^="#fff"]) {
      +    fill: var(--bs-body-bg);
      +}
      +}
      diff --git a/ietf/static/css/edit-meeting-schedule.scss b/ietf/static/css/edit-meeting-schedule.scss
      deleted file mode 100644
      index e69de29bb2d..00000000000
      diff --git a/ietf/static/css/highcharts.scss b/ietf/static/css/highcharts.scss
      new file mode 100644
      index 00000000000..d2f5d5e0e74
      --- /dev/null
      +++ b/ietf/static/css/highcharts.scss
      @@ -0,0 +1,6 @@
      +@import "npm:highcharts/css/highcharts.css";
      +@import "custom-bs-import";
      +
      +.highcharts-container {
      +    font-family: $font-family-sans-serif;
      +}
      diff --git a/ietf/static/css/ietf.scss b/ietf/static/css/ietf.scss
      index e5d3eb88483..b8c701eae1b 100644
      --- a/ietf/static/css/ietf.scss
      +++ b/ietf/static/css/ietf.scss
      @@ -1,32 +1,9 @@
       @use "sass:map";
       
      -@import "bootstrap/scss/functions";
      -
      -// Enable negative margin classes.
      -$enable-negative-margins: true;
      -
      -// Don't add carets to dropdowns by default.
      -// $enable-caret: false;
      -
      -$popover-max-width: 100%;
      -
      -// Only import what we need:
      -
      -@import "bootstrap/scss/variables";
      -
      -$h1-font-size: $font-size-base * 2.2;
      -$h2-font-size: $font-size-base * 1.8;
      -$h3-font-size: $font-size-base * 1.6;
      -$h4-font-size: $font-size-base * 1.4;
      -$h5-font-size: $font-size-base * 1.2;
      -$h6-font-size: $font-size-base;
      -
      -@import "bootstrap/scss/maps";
      -@import "bootstrap/scss/mixins";
      -@import "bootstrap/scss/utilities";
      -@import "bootstrap/scss/root";
      +@import "custom-bs-import";
       
       // Layout & components
      +// Only import what we need:
       @import "bootstrap/scss/reboot";
       @import "bootstrap/scss/type";
       @import "bootstrap/scss/images";
      @@ -69,8 +46,13 @@ $bootstrap-icons-font-src: url("npm:bootstrap-icons/font/fonts/bootstrap-icons.w
       url("npm:bootstrap-icons/font/fonts/bootstrap-icons.woff") format("woff");
       @import "bootstrap-icons/font/bootstrap-icons";
       
      -// Leave room for fixed-top navbar...
      +// Disable contextual alternates (calt)
       body {
      +  font-feature-settings: "calt" off;
      +}
      +
      +// Leave room for fixed-top navbar...
      +body.navbar-offset {
           padding-top: 60px;
       }
       
      @@ -79,6 +61,55 @@ html {
           scroll-padding-top: 60px;
       }
       
      +// Toggle classes for dark/light modes
      +[data-bs-theme="dark"] {
      +    .d-dm-none {
      +        display: none;
      +    }
      +
      +    .d-lm-none {
      +        display: initial;
      +    }
      +}
      +
      +[data-bs-theme="light"] {
      +    .d-dm-none {
      +        display: initial;
      +    }
      +
      +    .d-lm-none {
      +        display: none;
      +    }
      +}
      +
      +// Make submenus open on hover.
      +@include media-breakpoint-up(lg) {
      +    .dropdown-menu>li>ul {
      +        display: none;
      +    }
      +
      +    .dropdown-menu>li:hover>ul {
      +        display: block;
      +    }
      +
      +}
      +
      +@include media-breakpoint-up(md) {
      +    .leftmenu .nav>li>ul {
      +        display: none;
      +    }
      +
      +    .leftmenu .nav>li:hover>ul {
      +        display: block;
      +    }
      +}
      +
      +:is(.dropdown-menu, .leftmenu .nav) .dropdown-menu {
      +    top: 0;
      +    left: 100%;
      +    right: auto;
      +}
      +
       // Make textareas in forms use a monospace font
       textarea.form-control {
           font-family: $font-family-code;
      @@ -97,6 +128,11 @@ pre {
           width: 60px;
       }
       
      +// Style preformatted alert messages better.
      +.preformatted {
      +    white-space: pre-line;
      +}
      +
       .leftmenu {
           width: 13em;
       
      @@ -122,8 +158,8 @@ pre {
               --#{$prefix}dropdown-divider-bg: #{$dropdown-divider-bg};
               --#{$prefix}dropdown-divider-margin-y: #{$dropdown-divider-margin-y};
               --#{$prefix}dropdown-box-shadow: #{$dropdown-box-shadow};
      -        --#{$prefix}dropdown-link-color: #{$dropdown-link-color};
      -        --#{$prefix}dropdown-link-hover-color: #{$dropdown-link-hover-color};
      +        --#{$prefix}dropdown-link-color: #{$nav-link-color};
      +        --#{$prefix}dropdown-link-hover-color: #{$nav-link-hover-color};
               --#{$prefix}dropdown-link-hover-bg: #{$dropdown-link-hover-bg};
               --#{$prefix}dropdown-link-active-color: #{$dropdown-link-active-color};
               --#{$prefix}dropdown-link-active-bg: #{$dropdown-link-active-bg};
      @@ -168,6 +204,17 @@ table tbody.meta {
           }
       }
       
      +// Try and hyphenate table headings and other things
      +th,
      +.hyphenate {
      +    hyphens: auto;
      +}
      +
      +// Helper to make sure very wide tables work on narrow screens.
      +.wrap-anywhere {
      +    overflow-wrap: anywhere;
      +}
      +
       // Highlight required form field labels with bi-asterisk
       .required>label:after {
           display: inline-block;
      @@ -187,16 +234,37 @@ table tbody.meta {
       .group-menu .dropdown-menu {
           height: auto;
           width: auto;
      -    max-height: 35em;
      +    max-height: 95vh;
           overflow-x: hidden;
           overflow-y: auto;
       }
       
       // Helper to constrain the size of the main logo
       .ietflogo {
      -    width: 75%;
      +    width: 100%;
           max-width: 300px;
       }
      +.ietflogo > img {
      +    min-width: 100px;
      +    width: 100%;
      +}
      +
      +// Make revision numbers pagination items fixed-width
      +.revision-list {
      +    .page-item {
      +        width: 2.2rem;
      +    }
      +
      +    .page-item.rfc {
      +        width: 6.6rem;
      +    }
      +}
      +
      +.charter.revision-list {
      +    .page-item {
      +        width: auto;
      +    }
      +}
       
       // Style the photo cards
       .photo {
      @@ -234,13 +302,13 @@ table tbody.meta {
       }
       
       // Styles for d3.js graphical SVG timelines
      -#timeline {
      +#doc-timeline {
           font-size: small;
       
           .axis path,
           .axis line {
               fill: none;
      -        stroke: black;
      +        stroke: var(--bs-body-color);
           }
       
           .axis.y path,
      @@ -257,7 +325,7 @@ table tbody.meta {
           }
       
           .bar text {
      -        fill: black;
      +        fill: var(--bs-body-color);
               dominant-baseline: central;
               pointer-events: none;
           }
      @@ -296,7 +364,7 @@ table tbody.meta {
       }
       
       .ballot-icon table .my {
      -    border: 2 * $table-border-width solid #000;
      +    border: calc(2 * $table-border-width) solid var(--bs-emphasis-color);
       }
       
       // See https://getbootstrap.com/docs/5.1/customize/color/#all-colors
      @@ -408,36 +476,64 @@ td.position-recuse {
       }
       
       td.position-norecord {
      -    background-color: $white; // $color-norecord;
      +    background-color: transparent;
       }
       
       td.position-empty {
           border: none !important;
       }
       
      -tr.position-moretime-row,
      -tr.position-notready-row,
      -tr.position-discuss-row,
      -tr.position-block-row {
      -    background-color: tint-color($color-discuss, 85%);
      -}
      +[data-bs-theme="light"] {
       
      -tr.position-yes-row {
      -    background-color: tint-color($color-yes, 75%);
      -}
      +    tr.position-moretime-row,
      +    tr.position-notready-row,
      +    tr.position-discuss-row,
      +    tr.position-block-row {
      +        background-color: tint-color($color-discuss, 85%);
      +    }
       
      -tr.position-noobj-row {
      -    background-color: tint-color($color-noobj, 50%);
      -}
      +    tr.position-yes-row {
      +        background-color: tint-color($color-yes, 75%);
      +    }
       
      -tr.position-abstain-row {
      -    background-color: tint-color($color-abstain, 85%);
      -}
      +    tr.position-noobj-row {
      +        background-color: tint-color($color-noobj, 50%);
      +    }
       
      -tr.position-recuse-row {
      -    background-color: tint-color($color-recuse, 85%);
      +    tr.position-abstain-row {
      +        background-color: tint-color($color-abstain, 85%);
      +    }
      +
      +    tr.position-recuse-row {
      +        background-color: tint-color($color-recuse, 85%);
      +    }
       }
       
      +[data-bs-theme="dark"] {
      +
      +    tr.position-moretime-row,
      +    tr.position-notready-row,
      +    tr.position-discuss-row,
      +    tr.position-block-row {
      +        background-color: shade-color($color-discuss, 65%);
      +    }
      +
      +    tr.position-yes-row {
      +        background-color: shade-color($color-yes, 65%);
      +    }
      +
      +    tr.position-noobj-row {
      +        background-color: shade-color($color-noobj, 65%);
      +    }
      +
      +    tr.position-abstain-row {
      +        background-color: shade-color($color-abstain, 65%);
      +    }
      +
      +    tr.position-recuse-row {
      +        background-color: shade-color($color-recuse, 65%);
      +    }
      +}
       
       /* === Edit Meeting Schedule ====================================== */
       
      @@ -475,7 +571,7 @@ tr.position-recuse-row {
       }
       
       .edit-meeting-schedule .edit-grid .day-label .swap-days:hover {
      -    color: #666;
      +    color: var(--bs-secondary-color);
       }
       
       .edit-meeting-schedule #swap-days-modal .modal-body label {
      @@ -507,15 +603,15 @@ tr.position-recuse-row {
       }
       
       .edit-meeting-schedule .edit-grid .time-header .time-label.would-violate-hint {
      -    background-color: #ffe0e0;
      -    outline: #ffe0e0 solid 0.4em;
      +    background-color: var(--bs-danger-bg-subtle);
      +    outline: var(--bs-danger-bg-subtle) solid 0.4em;
       }
       
       .edit-meeting-schedule .edit-grid .time-header .time-label span {
           display: inline-block;
           width: 100%;
           text-align: center;
      -    color: #444444;
      +    color: var(--bs-secondary-color);
       }
       
       .edit-meeting-schedule .edit-grid .timeslots {
      @@ -527,7 +623,7 @@ tr.position-recuse-row {
       .edit-meeting-schedule .edit-grid .timeslot {
           position: relative;
           display: inline-block;
      -    background-color: #f4f4f4;
      +    background-color: var(--bs-secondary-bg);
           height: 100%;
           overflow: hidden;
       }
      @@ -540,7 +636,7 @@ tr.position-recuse-row {
           width: 100%;
           align-items: center;
           justify-content: center;
      -    color: #999;
      +    color: var(--bs-tertiary-color);
       }
       
       .edit-meeting-schedule .edit-grid .timeslot .drop-target {
      @@ -557,22 +653,22 @@ tr.position-recuse-row {
       }
       
       .edit-meeting-schedule .edit-grid .timeslot.overfull {
      -    border-right: 0.3em dashed #f55000;
      +    border-right: 0.3em dashed var(--bs-danger);
           /* cut-off illusion */
       }
       
       .edit-meeting-schedule .edit-grid .timeslot.would-violate-hint {
      -    background-color: #ffe0e0;
      -    outline: #ffe0e0 solid 0.4em;
      +    background-color: var(--bs-danger-bg-subtle);
      +    outline: var(--bs-danger-bg-subtle) solid 0.4em;
       }
       
       .edit-meeting-schedule .edit-grid .timeslot.would-violate-hint.dropping {
      -    background-color: #ccb3b3;
      +    background-color: var(--bs-danger);
       }
       
       .edit-meeting-schedule .constraints .encircled,
       .edit-meeting-schedule .formatted-constraints .encircled {
      -    border: 1px solid #000;
      +    border: 1px solid var( --bs-body-color);
           border-radius: 1em;
           padding: 0 0.3em;
           text-align: center;
      @@ -585,7 +681,7 @@ tr.position-recuse-row {
       
       /* sessions */
       .edit-meeting-schedule .session {
      -    background-color: #fff;
      +    background-color: var(--bs-body-bg);
           margin: 0.2em;
           padding-right: 0.2em;
           padding-left: 0.5em;
      @@ -597,15 +693,15 @@ tr.position-recuse-row {
       
       .edit-meeting-schedule .session.selected {
           cursor: grabbing;
      -    outline: #0000ff solid 0.2em;
      -    /* blue, width matches margin on .session */
      +    outline: var(--bs-primary) solid 0.2em;
      +    /* width matches margin on .session */
           z-index: 2;
           /* render above timeslot outlines */
       }
       
       .edit-meeting-schedule .session.other-session-selected {
      -    outline: #00008b solid 0.2em;
      -    /* darkblue, width matches margin on .session */
      +    outline: 0.3em solid var(--bs-info);
      +    box-shadow: 0 0 1em var(--bs-info);
           z-index: 2;
           /* render above timeslot outlines */
       }
      @@ -616,7 +712,7 @@ tr.position-recuse-row {
       
       .edit-meeting-schedule .session.readonly {
           cursor: default;
      -    background-color: #ddd;
      +    background-color: var(--bs-dark-bg-subtle);
       }
       
       .edit-meeting-schedule .session.hidden-parent * {
      @@ -630,13 +726,12 @@ tr.position-recuse-row {
       }
       
       .edit-meeting-schedule .session.highlight {
      -    outline-color: #ff8c00;
      -    /* darkorange */
      -    background-color: #f3f3f3;
      +    outline-color: var(--bs-warning);
      +    background-color: var(--bs-light);
       }
       
       .edit-meeting-schedule .session.would-violate-hint {
      -    outline: 0.3em solid #F55000;
      +    outline: 0.3em solid var(--bs-danger);
           z-index: 1;
           /* raise up so the outline is not overdrawn */
       }
      @@ -658,6 +753,7 @@ tr.position-recuse-row {
       
       .edit-meeting-schedule .edit-grid,
       .edit-meeting-schedule .session {
      +    // Removing this font-family style causes selenium tests to fail :-(
           font-family: arial, helvetica, sans-serif;
           font-size: 11px;
       }
      @@ -729,9 +825,9 @@ tr.position-recuse-row {
           bottom: 0;
           left: 0;
           width: 100%;
      -    border-top: 0.2em solid #ccc;
      +    border-top: 0.2em solid var(--bs-border-color);
           margin-bottom: 2em;
      -    background-color: #fff;
      +    background-color: var(--bs-body-bg);
           opacity: 0.95;
           z-index: 5;
           /* raise above edit-grid items */
      @@ -746,7 +842,7 @@ tr.position-recuse-row {
           min-height: 4em;
           max-height: 13em;
           overflow-y: auto;
      -    background-color: #f4f4f4;
      +    background-color: var(--bs-secondary-bg);
       }
       
       .edit-meeting-schedule .unassigned-sessions.dropping {
      @@ -803,7 +899,7 @@ tr.position-recuse-row {
           font-weight: normal;
           margin-right: 1em;
           padding: 0 1em;
      -    border: 0.1em solid #eee;
      +    border: 0.1em solid var(--bs-border-color);
           cursor: pointer;
       }
       
      @@ -869,7 +965,7 @@ tr.position-recuse-row {
       }
       
       .edit-meeting-timeslots-and-misc-sessions .room-row {
      -    border-bottom: 1px solid #ccc;
      +    border-bottom: 1px solid var(--bs-border-color);
           // height: 20px;
           display: flex;
           cursor: pointer;
      @@ -889,13 +985,13 @@ tr.position-recuse-row {
       }
       
       .edit-meeting-timeslots-and-misc-sessions .timeline.hover {
      -    background: radial-gradient(#999 1px, transparent 1px);
      +    background: radial-gradient(var(--bs-tertiary-color) 1px, transparent 1px);
           background-size: 20px 20px;
       }
       
       .edit-meeting-timeslots-and-misc-sessions .timeline.selected.hover,
       .edit-meeting-timeslots-and-misc-sessions .timeline.selected {
      -    background: radial-gradient(#999 2px, transparent 2px);
      +    background: radial-gradient(var(--bs-tertiary-color) 2px, transparent 2px);
           background-size: 20px 20px;
       }
       
      @@ -911,8 +1007,8 @@ tr.position-recuse-row {
           white-space: nowrap;
           cursor: pointer;
           padding-left: 0.2em;
      -    border-left: 1px solid #999;
      -    border-right: 1px solid #999;
      +    border-left: 1px solid var(--bs-border-color);
      +    border-right: 1px solid var(--bs-border-color);
       }
       
       .edit-meeting-timeslots-and-misc-sessions .timeslot:hover {
      @@ -932,10 +1028,10 @@ tr.position-recuse-row {
           bottom: 0;
           left: 0;
           width: 100%;
      -    border-top: 0.2em solid #ccc;
      +    border-top: 0.2em solid var(--bs-border-color);
           padding-top: 0.2em;
           margin-bottom: 2em;
      -    background-color: #fff;
      +    background-color: var(--bs-body-bg);
           opacity: 0.95;
       }
       
      @@ -983,7 +1079,7 @@ tr.position-recuse-row {
       }
       
       .timeslot-edit .tstable div.timeslot {
      -    border: #000000 solid 1px;
      +    border: var(--bs-body-color) solid 1px;
           border-radius: 0.5em;
           padding: 0.5em;
       }
      @@ -1013,7 +1109,7 @@ tr.position-recuse-row {
       }
       
       .timeslot-edit .tstable .tstype_unavail {
      -    background-color: #666;
      +    background-color: var(--bs-secondary-color);
       }
       
       .timeslot-edit .official-use-warning {
      @@ -1096,3 +1192,49 @@ tr.position-recuse-row {
               }
           }
       }
      +
      +blockquote {
      +    padding-left: 1rem;
      +    border-left: solid 1px var(--bs-body-color);
      +}
      +
      +iframe.status {
      +    background-color:transparent;
      +    border:none;
      +    width:100%;
      +    height:3.5em;
      +}
      +
      +.overflow-shadows {
      +    transition: box-shadow 0.5s;
      +}
      +
      +.overflow-shadows--both {
      +    box-shadow: inset 0px 21px 18px -20px var(--bs-body-color),
      +                inset 0px -21px 18px -20px var(--bs-body-color);
      +}
      +
      +.overflow-shadows--top-only {
      +    box-shadow: inset 0px 21px 18px -20px var(--bs-body-color);
      +}
      +
      +.overflow-shadows--bottom-only {
      +    box-shadow: inset 0px -21px 18px -20px var(--bs-body-color);
      +}
      +
      +#navbar-doc-search-wrapper {
      +    position: relative;
      +}
      +
      +#navbar-doc-search-results {
      +    max-height: 400px;
      +    overflow-y: auto;
      +    min-width: auto;
      +    left: 0;
      +    right: 0;
      +
      +    .dropdown-item {
      +        white-space: normal;
      +        overflow-wrap: break-word;
      +    }
      +}
      diff --git a/ietf/static/css/list.scss b/ietf/static/css/list.scss
      index d52fc879a70..595bf360d57 100644
      --- a/ietf/static/css/list.scss
      +++ b/ietf/static/css/list.scss
      @@ -1,6 +1,4 @@
      -// Import bootstrap helpers
      -@import "bootstrap/scss/functions";
      -@import "bootstrap/scss/variables";
      +@import "custom-bs-import";
       
       table .sort {
           cursor: pointer;
      diff --git a/ietf/static/css/select2.scss b/ietf/static/css/select2.scss
      index 44824a358a3..c8e3da7adc6 100644
      --- a/ietf/static/css/select2.scss
      +++ b/ietf/static/css/select2.scss
      @@ -1,5 +1,7 @@
      -@import "bootstrap/scss/functions";
      -@import "bootstrap/scss/variables";
      -@import "bootstrap/scss/mixins";
      +@import "custom-bs-import";
      +
      +// FIXME: bs-5.3.0 workaround from https://github.com/apalfrey/select2-bootstrap-5-theme/issues/75#issuecomment-1573265695
      +$s2bs5-border-color: $border-color;
      +
       @import "select2/src/scss/core";
       @import "select2-bootstrap-5-theme/src/include-all";
      diff --git a/ietf/static/images/arrow-ani.webp b/ietf/static/images/arrow-ani.webp
      deleted file mode 100644
      index 379407db15a..00000000000
      Binary files a/ietf/static/images/arrow-ani.webp and /dev/null differ
      diff --git a/ietf/static/images/iab-logo-white.svg b/ietf/static/images/iab-logo-white.svg
      new file mode 100644
      index 00000000000..264b7bb842f
      --- /dev/null
      +++ b/ietf/static/images/iab-logo-white.svg
      @@ -0,0 +1,64 @@
      +
      +
      +  
      +  
      +  
      +  
      +  
      +  
      +  
      +  
      +
      diff --git a/ietf/static/images/ietf-logo-nor-white.svg b/ietf/static/images/ietf-logo-nor-white.svg
      index 004e58af807..42c033600fd 100644
      --- a/ietf/static/images/ietf-logo-nor-white.svg
      +++ b/ietf/static/images/ietf-logo-nor-white.svg
      @@ -1,26 +1,136 @@
      -
      -	
      -		
      -	
      -	
      -	
      -	
      -	
      -	
      -	
      -	
      -	
      -	
      -	
      -	
      -	
      -	
      -	
      -	
      -	
      -	
      -	
      -	
      -	
      +
      +
      +  
      +  
      +    
      +  
      +  
      +  
      +  
      +  
      +  
      +  
      +  
      +  
      +  
      +  
      +  
      +  
      +  
      +  
      +  
      +  
      +  
      +  
      +  
      +  
       
      diff --git a/ietf/static/images/ietf-logo-white.svg b/ietf/static/images/ietf-logo-white.svg
      new file mode 100644
      index 00000000000..2417f917ce3
      --- /dev/null
      +++ b/ietf/static/images/ietf-logo-white.svg
      @@ -0,0 +1,146 @@
      +
      +
      +  
      +  
      +    
      +  
      +  
      +  
      +  
      +  
      +  
      +  
      +  
      +  
      +  
      +  
      +  
      +  
      +  
      +  
      +  
      +  
      +  
      +  
      +  
      +  
      +  
      +  
      +
      diff --git a/ietf/static/images/irtf-logo-white.svg b/ietf/static/images/irtf-logo-white.svg
      new file mode 100644
      index 00000000000..a67412581e8
      --- /dev/null
      +++ b/ietf/static/images/irtf-logo-white.svg
      @@ -0,0 +1,65 @@
      +
      +
      +  
      +  
      +  R
      +  
      +  
      +  
      +  
      +  
      +
      diff --git a/ietf/static/images/irtf-logo.svg b/ietf/static/images/irtf-logo.svg
      index ad339fe2be1..10b2a968163 100644
      --- a/ietf/static/images/irtf-logo.svg
      +++ b/ietf/static/images/irtf-logo.svg
      @@ -1 +1,76 @@
      -R
      \ No newline at end of file
      +
      +
      +  
      +  
      +  
      +    R
      +    
      +    
      +    
      +    
      +    
      +  
      +
      diff --git a/ietf/static/js/add_session_recordings.js b/ietf/static/js/add_session_recordings.js
      new file mode 100644
      index 00000000000..c1c5932a480
      --- /dev/null
      +++ b/ietf/static/js/add_session_recordings.js
      @@ -0,0 +1,30 @@
      +// Copyright The IETF Trust 2024-2025, All Rights Reserved
      +document.addEventListener('DOMContentLoaded', () => {
      +    const form = document.getElementById('delete_recordings_form')
      +    const dialog = document.getElementById('delete_confirm_dialog')
      +    const dialog_link = document.getElementById('delete_confirm_link')
      +    const dialog_submit = document.getElementById('delete_confirm_submit')
      +    const dialog_cancel = document.getElementById('delete_confirm_cancel')
      +
      +    dialog.style.maxWidth = '30vw'
      +
      +    form.addEventListener('submit', (e) => {
      +        e.preventDefault()
      +        dialog_submit.value = e.submitter.value
      +        const recording_link = e.submitter.closest('tr').querySelector('a')
      +        dialog_link.setAttribute('href', recording_link.getAttribute('href'))
      +        dialog_link.textContent = recording_link.textContent
      +        dialog.showModal()
      +    })
      +
      +    dialog_cancel.addEventListener('click', (e) => {
      +        e.preventDefault()
      +        dialog.close()
      +    })
      +
      +    document.addEventListener('keydown', (e) => {
      +        if (dialog.open && e.key === 'Escape') {
      +            dialog.close()
      +        }
      +    })
      +})
      diff --git a/ietf/static/js/agenda_personalize.js b/ietf/static/js/agenda_personalize.js
      deleted file mode 100644
      index edb2787f3c4..00000000000
      --- a/ietf/static/js/agenda_personalize.js
      +++ /dev/null
      @@ -1,41 +0,0 @@
      -// Copyright The IETF Trust 2021, All Rights Reserved
      -
      -/**
      - * Agenda personalization JS methods
      - *
      - * Requires agenda_timezone.js and timezone.js be included.
      - */
      -'use strict';
      -
      -/**
      - * Update the checkbox state to match the filter parameters
      - */
      -function updateAgendaCheckboxes(filter_params) {
      -    var selection_inputs = document.getElementsByName('selected-sessions');
      -    selection_inputs.forEach((inp) => {
      -        const item_keywords = inp.dataset.filterKeywords.toLowerCase()
      -            .split(',');
      -        if (
      -            agenda_filter.keyword_match(item_keywords, filter_params.show) &&
      -            !agenda_filter.keyword_match(item_keywords, filter_params.hide)
      -        ) {
      -            inp.checked = true;
      -        } else {
      -            inp.checked = false;
      -        }
      -    });
      -}
      -
      -window.handleFilterParamUpdate = function (filter_params) {
      -    updateAgendaCheckboxes(filter_params);
      -};
      -
      -window.handleTableClick = function (event) {
      -    if (event.target.name === 'selected-sessions') {
      -        // hide the tooltip after clicking on a checkbox
      -        const jqElt = jQuery(event.target);
      -        if (jqElt.tooltip) {
      -            jqElt.tooltip('hide');
      -        }
      -    }
      -};
      \ No newline at end of file
      diff --git a/ietf/static/js/agenda_timezone.js b/ietf/static/js/agenda_timezone.js
      deleted file mode 100644
      index 187bea0e88d..00000000000
      --- a/ietf/static/js/agenda_timezone.js
      +++ /dev/null
      @@ -1,306 +0,0 @@
      -// Copyright The IETF Trust 2021, All Rights Reserved
      -/*
      - Timezone support specific to the agenda page
      -
      - To properly handle timezones other than local, needs a method to retrieve
      - the current timezone. Set this by passing a method taking no parameters and
      - returning the current timezone to the set_current_tz_cb() method.
      - This should be done before calling anything else in the file.
      - */
      -(function() {
      -    'use strict';
      -
      -    const local_timezone = moment.tz.guess();
      -
      -    // get_current_tz_cb must be overwritten using set_current_tz_cb
      -    let get_current_tz_cb = function() {
      -        throw new Error('Tried to get current timezone before callback registered. Use set_current_tz_cb().');
      -    };
      -
      -    // Initialize moments
      -    function initialize_moments() {
      -        const times = $('.time');
      -        $.each(times, function (i, item) {
      -            item.start_ts = moment.unix(this.getAttribute("data-start-time"))
      -                .utc();
      -            item.end_ts = moment.unix(this.getAttribute("data-end-time"))
      -                .utc();
      -            if (this.hasAttribute("data-weekday")) {
      -                item.format = 2;
      -            } else {
      -                item.format = 1;
      -            }
      -            if (this.hasAttribute("format")) {
      -                item.format = +this.getAttribute("format");
      -            }
      -        });
      -        const things_with_slots = $('[data-slot-start-ts]');
      -        $.each(things_with_slots, function (i, item) {
      -            item.slot_start_ts = moment.unix(this.getAttribute("data-slot-start-ts"))
      -                .utc();
      -            item.slot_end_ts = moment.unix(this.getAttribute("data-slot-end-ts"))
      -                .utc();
      -        });
      -    }
      -
      -    function format_time(t, tz, fmt) {
      -        let out;
      -        const mtz = window.meeting_timezone || "UTC";
      -        switch (fmt) {
      -        case 0:
      -            out = t.tz(tz)
      -                .format('dddd, ') + '' +
      -                t.tz(tz)
      -                    .format('MMMM Do YYYY, ') + '' +
      -                t.tz(tz)
      -                    .format('HH:mm') + '' +
      -                t.tz(tz)
      -                    .format(' Z z') + '';
      -            break;
      -        case 1:
      -            // Note, this code does not work if the meeting crosses the
      -            // year boundary.
      -            out = t.tz(tz)
      -                .format("HH:mm");
      -            if (+t.tz(tz)
      -                .dayOfYear() < +t.tz(mtz)
      -                .dayOfYear()) {
      -                out = out + " (-1)";
      -            } else if (+t.tz(tz)
      -                .dayOfYear() > +t.tz(mtz)
      -                .dayOfYear()) {
      -                out = out + " (+1)";
      -            }
      -            break;
      -        case 2:
      -            out = t.tz(mtz)
      -                .format("dddd, ")
      -                .toUpperCase() +
      -                t.tz(tz)
      -                    .format("HH:mm");
      -            if (+t.tz(tz)
      -                .dayOfYear() < +t.tz(mtz)
      -                .dayOfYear()) {
      -                out = out + " (-1)";
      -            } else if (+t.tz(tz)
      -                .dayOfYear() > +t.tz(mtz)
      -                .dayOfYear()) {
      -                out = out + " (+1)";
      -            }
      -            break;
      -        case 3:
      -            out = t.utc()
      -                .format("YYYY-MM-DD");
      -            break;
      -        case 4:
      -            out = t.tz(tz)
      -                .format("YYYY-MM-DD HH:mm");
      -            break;
      -        case 5:
      -            out = t.tz(tz)
      -                .format("HH:mm");
      -            break;
      -        }
      -        return out;
      -    }
      -
      -    // Format tooltip notice
      -    function format_tooltip_notice(start, end) {
      -        let notice = "";
      -
      -        if (end.isBefore()) {
      -            notice = "Event ended " + end.fromNow();
      -        } else if (start.isAfter()) {
      -            notice = "Event will start " + start.fromNow();
      -        } else {
      -            notice = "Event started " + start.fromNow() + " and will end " +
      -                end.fromNow();
      -        }
      -        return '' + notice + '';
      -    }
      -
      -    // Format tooltip table
      -    function format_tooltip_table(start, end) {
      -        const current_timezone = get_current_tz_cb();
      -        let out = '
      '; - if (window.meeting_timezone !== "") { - out += ''; - } - out += ''; - if (current_timezone !== 'UTC') { - out += ''; - } - out += ''; - out += '
      Session startSession end
      Meeting timezone' + - format_time(start, window.meeting_timezone, 0) + '' + - format_time(end, window.meeting_timezone, 0) + '
      Local timezone' + - format_time(start, local_timezone, 0) + '' + - format_time(end, local_timezone, 0) + '
      Selected Timezone' + - format_time(start, current_timezone, 0) + '' + - format_time(end, current_timezone, 0) + '
      UTC' + - format_time(start, 'UTC', 0) + '' + - format_time(end, 'UTC', 0) + '
      ' + format_tooltip_notice(start, end) + '

    '; - return out; - } - - // Format tooltip for item - function format_tooltip(start, end) { - return '
    ' + - format_tooltip_table(start, end) + - '
    '; - } - - // Add tooltips - function add_tooltips() { - $('.time') - .each(function () { - const tooltip = $(format_tooltip(this.start_ts, this.end_ts)); - tooltip[0].start_ts = this.start_ts; - tooltip[0].end_ts = this.end_ts; - tooltip[0].ustart_ts = moment(this.start_ts) - .add(-2, 'hours'); - tooltip[0].uend_ts = moment(this.end_ts) - .add(2, 'hours'); - $(this) - .closest("th, td") - .attr("data-bs-toggle", "popover") - .attr("data-bs-content", $(tooltip) - .html()) - .popover({ - html: true, - sanitize: false, - trigger: "hover" - }); - }); - } - - // Update times on the agenda based on the selected timezone - function update_times(newtz) { - $('.current-tz') - .html(newtz.replaceAll("_", " ").replaceAll("/", " / ")); - $('.time') - .each(function () { - if (this.format === 4) { - const tz = this.start_ts.tz(newtz).format(" z"); - const start_doy = this.start_ts.tz(newtz).dayOfYear(); - const end_doy = this.end_ts.tz(newtz).dayOfYear(); - if (start_doy === end_doy) { - $(this) - .html(format_time(this.start_ts, newtz, this.format) + - '
    -' + format_time(this.end_ts, newtz, 5) + tz); - } else { - $(this) - .html(format_time(this.start_ts, newtz, this.format) + - '
    -' + - format_time(this.end_ts, newtz, this.format) + tz); - } - } else { - $(this) - .html(format_time(this.start_ts, newtz, this.format) + '
    -' + - format_time(this.end_ts, newtz, this.format)); - } - }); - update_tooltips_all(); - update_clock(); - } - - // Update hrefs in anchor tags with the "now-link" class. Mark the target with the "current-session" class. - function update_now_link(agenda_rows, ongoing_rows, later_rows) { - agenda_rows.removeClass('current-session'); - const links_to_update = $('a.now-link'); - if (ongoing_rows.length > 0) { - // sessions are ongoing - find those with the latest start time and mark the first of them as "now" - const last_start_time = ongoing_rows[ongoing_rows.length - 1].slot_start_ts; - for (let ii=0; ii < ongoing_rows.length; ii++) { - const dt = ongoing_rows[ii].slot_start_ts.diff(last_start_time, 'seconds'); - if (Math.abs(dt) < 1) { - $(ongoing_rows[ii]).addClass('current-session'); - links_to_update.attr('href', '#' + ongoing_rows[ii].id); - break; - } - } - } else if (later_rows.length > 0) { - // There were no ongoing sessions, look for the next one to start and mark as current - $(later_rows[0]).addClass('current-session'); - links_to_update.attr('href', '#' + later_rows[0].id); - } else { - // No sessions in the future - meeting has apparently ended - links_to_update.attr('href', '#'); - links_to_update.addClass('disabled'); // mark link - } - } - - function update_ongoing_sessions() { - const agenda_rows = $('[data-slot-start-ts]'); - const now_moment = moment(); - const ongoing_rows = agenda_rows.filter(function () { - return now_moment.isBetween(this.slot_start_ts, this.slot_end_ts); - }); - const later_rows = agenda_rows.filter(function() { return now_moment.isBefore(this.slot_start_ts); }); - // Highlight ongoing based on the current time - agenda_rows.removeClass("table-warning"); - ongoing_rows.addClass("table-warning"); - update_now_link(agenda_rows, ongoing_rows, later_rows); // update any "now-link" anchors - } - - // Update tooltips - function update_tooltips() { - const tooltips = $('.timetooltiptext'); - tooltips.filter(function () { - return moment() - .isBetween(this.ustart_ts, this.uend_ts); - }) - .each(function () { - $(this) - .html(format_tooltip_table(this.start_ts, this.end_ts)); - }); - } - - // Update all tooltips - function update_tooltips_all() { - const tooltips = $('.timetooltiptext'); - tooltips.each(function () { - $(this) - .html(format_tooltip_table(this.start_ts, this.end_ts)); - }); - } - - // Update clock - function update_clock() { - $('span.current-time') - .html(format_time(moment(), get_current_tz_cb(), 0)); - } - - function urlParam(name) { - const results = new RegExp('[\?&]' + name + '=([^&#]*)') - .exec(window.location.href); - if (results === null) { - return null; - } else { - return results[1] || 0; - } - } - - function init_timers(speedup) { - speedup = speedup || 1; - const fast_timer = 60000 / (speedup > 600 ? 600 : speedup); - update_clock(); - update_ongoing_sessions(); - setInterval(function () { update_clock(); }, fast_timer); - setInterval(function () { update_ongoing_sessions(); }, fast_timer); - setInterval(function () { update_tooltips(); }, fast_timer); - setInterval(function () { update_tooltips_all(); }, 3600000 / speedup); - } - - /***** make public interface available on window *****/ - window.initialize_moments = initialize_moments; - window.add_tooltips = add_tooltips; - window.update_times = update_times; - window.urlParam = urlParam; - window.init_timers = init_timers; - - // set method used to find current time zone - window.set_current_tz_cb = function (fn) { - get_current_tz_cb = fn; - }; -})(); diff --git a/ietf/static/js/announcement.js b/ietf/static/js/announcement.js new file mode 100644 index 00000000000..95465120fa8 --- /dev/null +++ b/ietf/static/js/announcement.js @@ -0,0 +1,57 @@ +const announcementApp = (function() { + 'use strict'; + return { + // functions for Announcement + checkToField: function() { + document.documentElement.scrollTop = 0; // For most browsers + const toField = document.getElementById('id_to'); + const toCustomInput = document.getElementById('id_to_custom'); + const toCustomDiv = toCustomInput.closest('div.row'); + + if (toField.value === 'Other...') { + toCustomDiv.style.display = 'flex'; // Show the custom field + } else { + toCustomDiv.style.display = 'none'; // Hide the custom field + toCustomInput.value = ''; // Optionally clear the input value if hidden + } + } + }; +})(); + +// Extra care is required to ensure the back button +// works properly for the optional to_custom field. +// Take the case when a user selects "Other..." for +// "To" field. The "To custom" field appears and they +// enter a new address there. +// In Chrome, when the form is submitted and then the user +// uses the back button (or browser back), the page loads +// from bfcache then the javascript DOMContentLoaded event +// handler is run, hiding the empty to_custom field, THEN the +// browser autofills the form fields. Because to_submit +// is now hidden it does not get a value. This is a very +// bad experience for the user because the to_custom field +// was unexpectedly cleared and hidden. If they notice this +// they would need to know to first select another "To" +// option, then select "Other..." again just to get the +// to_custom field visible so they can re-enter the custom +// address. +// The solution is to use setTimeout to run checkToField +// after a short delay, giving the browser time to autofill +// the form fields before it checks to see if the to_custom +// field is empty and hides it. + +document.addEventListener('DOMContentLoaded', function() { + // Run the visibility check after allowing cache to populate values + setTimeout(announcementApp.checkToField, 300); + + const toField = document.getElementById('id_to'); + toField.addEventListener('change', announcementApp.checkToField); +}); + +// Handle back/forward navigation with pageshow +window.addEventListener('pageshow', function(event) { + if (event.persisted) { + // Then apply visibility logic after cache restoration + setTimeout(announcementApp.checkToField, 300); + } +}); \ No newline at end of file diff --git a/ietf/static/js/attendees-chart.js b/ietf/static/js/attendees-chart.js new file mode 100644 index 00000000000..fed3b1289cb --- /dev/null +++ b/ietf/static/js/attendees-chart.js @@ -0,0 +1,58 @@ +(function () { + var raw = document.getElementById('attendees-chart-data'); + if (!raw) return; + var chartData = JSON.parse(raw.textContent); + var chart = null; + var currentBreakdown = 'type'; + + // Override the global transparent background set by highcharts.js so the + // export menu and fullscreen view use the page background color. + var container = document.getElementById('attendees-pie-chart'); + var bodyBg = getComputedStyle(document.body).backgroundColor; + container.style.setProperty('--highcharts-background-color', bodyBg); + + function renderChart(breakdown) { + var seriesData = chartData[breakdown].map(function (item) { + return { name: item[0], y: item[1] }; + }); + if (chart) chart.destroy(); + chart = Highcharts.chart(container, { + chart: { type: 'pie', height: 400 }, + title: { text: null }, + tooltip: { pointFormat: '{point.name}: {point.y} ({point.percentage:.1f}%)' }, + plotOptions: { + pie: { + dataLabels: { + enabled: true, + format: '{point.name}
    {point.y} ({point.percentage:.1f}%)', + }, + showInLegend: false, + } + }, + series: [{ name: 'Attendees', data: seriesData }], + }); + } + + var modal = document.getElementById('attendees-chart-modal'); + + // Render (or re-render) the chart each time the modal becomes fully visible, + // so Highcharts can measure the container dimensions correctly. + modal.addEventListener('shown.bs.modal', function () { + renderChart(currentBreakdown); + }); + + // Release the chart when the modal closes to avoid stale renders. + modal.addEventListener('hidden.bs.modal', function () { + if (chart) { + chart.destroy(); + chart = null; + } + }); + + document.querySelectorAll('[name="attendees-breakdown"]').forEach(function (radio) { + radio.addEventListener('change', function () { + currentBreakdown = this.value; + renderChart(currentBreakdown); + }); + }); +})(); diff --git a/ietf/static/js/complete-review.js b/ietf/static/js/complete-review.js index a359dac237c..3a58ba97007 100644 --- a/ietf/static/js/complete-review.js +++ b/ietf/static/js/complete-review.js @@ -24,6 +24,8 @@ $(document) .before(mailArchiveSearchTemplate); var mailArchiveSearch = form.find(".mail-archive-search"); + const isReviewer = mailArchiveSearch.data('isReviewer'); + const searchMailArchiveUrl = mailArchiveSearch.data('searchMailArchiveUrl'); var retrievingData = null; @@ -190,4 +192,4 @@ $(document) form.find("[name=review_submission][value=link]") .trigger("click"); } - }); \ No newline at end of file + }); diff --git a/ietf/static/js/custom_striped.js b/ietf/static/js/custom_striped.js new file mode 100644 index 00000000000..480ad7cf828 --- /dev/null +++ b/ietf/static/js/custom_striped.js @@ -0,0 +1,16 @@ +// Copyright The IETF Trust 2025, All Rights Reserved + +document.addEventListener('DOMContentLoaded', () => { + // add stripes + const firstRow = document.querySelector('.custom-stripe .row') + if (firstRow) { + const parent = firstRow.parentElement; + const allRows = Array.from(parent.children).filter(child => child.classList.contains('row')) + allRows.forEach((row, index) => { + row.classList.remove('bg-light') + if (index % 2 === 1) { + row.classList.add('bg-light') + } + }) + } +}) diff --git a/ietf/static/js/datepicker.js b/ietf/static/js/datepicker.js index a94f79fc113..43d80acb5fa 100644 --- a/ietf/static/js/datepicker.js +++ b/ietf/static/js/datepicker.js @@ -1,2039 +1,54 @@ -/*! - * Datepicker for Bootstrap v1.9.0 (https://github.com/uxsolutions/bootstrap-datepicker) - * - * Licensed under the Apache License v2.0 (http://www.apache.org/licenses/LICENSE-2.0) - */ - -(function(factory){ - if (typeof define === 'function' && define.amd) { - define(['jquery'], factory); - } else if (typeof exports === 'object') { - factory(require('jquery')); - } else { - factory(jQuery); - } -}(function($, undefined){ - function UTCDate(){ - return new Date(Date.UTC.apply(Date, arguments)); - } - function UTCToday(){ - var today = new Date(); - return UTCDate(today.getFullYear(), today.getMonth(), today.getDate()); - } - function isUTCEquals(date1, date2) { - return ( - date1.getUTCFullYear() === date2.getUTCFullYear() && - date1.getUTCMonth() === date2.getUTCMonth() && - date1.getUTCDate() === date2.getUTCDate() - ); - } - function alias(method, deprecationMsg){ - return function(){ - if (deprecationMsg !== undefined) { - $.fn.datepicker.deprecated(deprecationMsg); - } - - return this[method].apply(this, arguments); - }; - } - function isValidDate(d) { - return d && !isNaN(d.getTime()); - } - - var DateArray = (function(){ - var extras = { - get: function(i){ - return this.slice(i)[0]; - }, - contains: function(d){ - // Array.indexOf is not cross-browser; - // $.inArray doesn't work with Dates - var val = d && d.valueOf(); - for (var i=0, l=this.length; i < l; i++) - // Use date arithmetic to allow dates with different times to match - if (0 <= this[i].valueOf() - val && this[i].valueOf() - val < 1000*60*60*24) - return i; - return -1; - }, - remove: function(i){ - this.splice(i,1); - }, - replace: function(new_array){ - if (!new_array) - return; - if (!$.isArray(new_array)) - new_array = [new_array]; - this.clear(); - this.push.apply(this, new_array); - }, - clear: function(){ - this.length = 0; - }, - copy: function(){ - var a = new DateArray(); - a.replace(this); - return a; - } - }; - - return function(){ - var a = []; - a.push.apply(a, arguments); - $.extend(a, extras); - return a; - }; - })(); - - - // Picker object - - var Datepicker = function(element, options){ - $.data(element, 'datepicker', this); - - this._events = []; - this._secondaryEvents = []; - - this._process_options(options); - - this.dates = new DateArray(); - this.viewDate = this.o.defaultViewDate; - this.focusDate = null; - - this.element = $(element); - this.isInput = this.element.is('input'); - this.inputField = this.isInput ? this.element : this.element.find('input'); - this.component = this.element.hasClass('date') ? this.element.find('.add-on, .input-group-addon, .input-group-append, .input-group-prepend, .btn') : false; - if (this.component && this.component.length === 0) - this.component = false; - this.isInline = !this.component && this.element.is('div'); - - this.picker = $(DPGlobal.template); - - // Checking templates and inserting - if (this._check_template(this.o.templates.leftArrow)) { - this.picker.find('.prev').html(this.o.templates.leftArrow); - } - - if (this._check_template(this.o.templates.rightArrow)) { - this.picker.find('.next').html(this.o.templates.rightArrow); - } - - this._buildEvents(); - this._attachEvents(); - - if (this.isInline){ - this.picker.addClass('datepicker-inline').appendTo(this.element); - } - else { - this.picker.addClass('datepicker-dropdown dropdown-menu'); - } - - if (this.o.rtl){ - this.picker.addClass('datepicker-rtl'); - } - - if (this.o.calendarWeeks) { - this.picker.find('.datepicker-days .datepicker-switch, thead .datepicker-title, tfoot .today, tfoot .clear') - .attr('colspan', function(i, val){ - return Number(val) + 1; - }); - } - - this._process_options({ - startDate: this._o.startDate, - endDate: this._o.endDate, - daysOfWeekDisabled: this.o.daysOfWeekDisabled, - daysOfWeekHighlighted: this.o.daysOfWeekHighlighted, - datesDisabled: this.o.datesDisabled - }); - - this._allow_update = false; - this.setViewMode(this.o.startView); - this._allow_update = true; - - this.fillDow(); - this.fillMonths(); - - this.update(); - - if (this.isInline){ - this.show(); - } - }; - - Datepicker.prototype = { - constructor: Datepicker, - - _resolveViewName: function(view){ - $.each(DPGlobal.viewModes, function(i, viewMode){ - if (view === i || $.inArray(view, viewMode.names) !== -1){ - view = i; - return false; - } - }); - - return view; - }, - - _resolveDaysOfWeek: function(daysOfWeek){ - if (!$.isArray(daysOfWeek)) - daysOfWeek = daysOfWeek.split(/[,\s]*/); - return $.map(daysOfWeek, Number); - }, - - _check_template: function(tmp){ - try { - // If empty - if (tmp === undefined || tmp === "") { - return false; - } - // If no html, everything ok - if ((tmp.match(/[<>]/g) || []).length <= 0) { - return true; - } - // Checking if html is fine - var jDom = $(tmp); - return jDom.length > 0; - } - catch (ex) { - return false; - } - }, - - _process_options: function(opts){ - // Store raw options for reference - this._o = $.extend({}, this._o, opts); - // Processed options - var o = this.o = $.extend({}, this._o); - - // Check if "de-DE" style date is available, if not language should - // fallback to 2 letter code eg "de" - var lang = o.language; - if (!dates[lang]){ - lang = lang.split('-')[0]; - if (!dates[lang]) - lang = defaults.language; - } - o.language = lang; - - // Retrieve view index from any aliases - o.startView = this._resolveViewName(o.startView); - o.minViewMode = this._resolveViewName(o.minViewMode); - o.maxViewMode = this._resolveViewName(o.maxViewMode); - - // Check view is between min and max - o.startView = Math.max(this.o.minViewMode, Math.min(this.o.maxViewMode, o.startView)); - - // true, false, or Number > 0 - if (o.multidate !== true){ - o.multidate = Number(o.multidate) || false; - if (o.multidate !== false) - o.multidate = Math.max(0, o.multidate); - } - o.multidateSeparator = String(o.multidateSeparator); - - o.weekStart %= 7; - o.weekEnd = (o.weekStart + 6) % 7; - - var format = DPGlobal.parseFormat(o.format); - if (o.startDate !== -Infinity){ - if (!!o.startDate){ - if (o.startDate instanceof Date) - o.startDate = this._local_to_utc(this._zero_time(o.startDate)); - else - o.startDate = DPGlobal.parseDate(o.startDate, format, o.language, o.assumeNearbyYear); - } - else { - o.startDate = -Infinity; - } - } - if (o.endDate !== Infinity){ - if (!!o.endDate){ - if (o.endDate instanceof Date) - o.endDate = this._local_to_utc(this._zero_time(o.endDate)); - else - o.endDate = DPGlobal.parseDate(o.endDate, format, o.language, o.assumeNearbyYear); - } - else { - o.endDate = Infinity; - } - } - - o.daysOfWeekDisabled = this._resolveDaysOfWeek(o.daysOfWeekDisabled||[]); - o.daysOfWeekHighlighted = this._resolveDaysOfWeek(o.daysOfWeekHighlighted||[]); - - o.datesDisabled = o.datesDisabled||[]; - if (!$.isArray(o.datesDisabled)) { - o.datesDisabled = o.datesDisabled.split(','); - } - o.datesDisabled = $.map(o.datesDisabled, function(d){ - return DPGlobal.parseDate(d, format, o.language, o.assumeNearbyYear); - }); - - var plc = String(o.orientation).toLowerCase().split(/\s+/g), - _plc = o.orientation.toLowerCase(); - plc = $.grep(plc, function(word){ - return /^auto|left|right|top|bottom$/.test(word); - }); - o.orientation = {x: 'auto', y: 'auto'}; - if (!_plc || _plc === 'auto') - ; // no action - else if (plc.length === 1){ - switch (plc[0]){ - case 'top': - case 'bottom': - o.orientation.y = plc[0]; - break; - case 'left': - case 'right': - o.orientation.x = plc[0]; - break; - } - } - else { - _plc = $.grep(plc, function(word){ - return /^left|right$/.test(word); - }); - o.orientation.x = _plc[0] || 'auto'; - - _plc = $.grep(plc, function(word){ - return /^top|bottom$/.test(word); - }); - o.orientation.y = _plc[0] || 'auto'; - } - if (o.defaultViewDate instanceof Date || typeof o.defaultViewDate === 'string') { - o.defaultViewDate = DPGlobal.parseDate(o.defaultViewDate, format, o.language, o.assumeNearbyYear); - } else if (o.defaultViewDate) { - var year = o.defaultViewDate.year || new Date().getFullYear(); - var month = o.defaultViewDate.month || 0; - var day = o.defaultViewDate.day || 1; - o.defaultViewDate = UTCDate(year, month, day); - } else { - o.defaultViewDate = UTCToday(); - } - }, - _applyEvents: function(evs){ - for (var i=0, el, ch, ev; i < evs.length; i++){ - el = evs[i][0]; - if (evs[i].length === 2){ - ch = undefined; - ev = evs[i][1]; - } else if (evs[i].length === 3){ - ch = evs[i][1]; - ev = evs[i][2]; - } - el.on(ev, ch); - } - }, - _unapplyEvents: function(evs){ - for (var i=0, el, ev, ch; i < evs.length; i++){ - el = evs[i][0]; - if (evs[i].length === 2){ - ch = undefined; - ev = evs[i][1]; - } else if (evs[i].length === 3){ - ch = evs[i][1]; - ev = evs[i][2]; - } - el.off(ev, ch); - } - }, - _buildEvents: function(){ - var events = { - keyup: $.proxy(function(e){ - if ($.inArray(e.keyCode, [27, 37, 39, 38, 40, 32, 13, 9]) === -1) - this.update(); - }, this), - keydown: $.proxy(this.keydown, this), - paste: $.proxy(this.paste, this) +import { + Datepicker +} from 'vanillajs-datepicker'; + +global.enable_datepicker = function (el) { + // we need to translate from bootstrap-datepicker options to + // vanillajs-datepicker options + const view_mode = { + day: 0, + days: 0, + month: 1, + months: 1, + year: 2, + years: 2, + decade: 3, + decades: 3 + }; + + let options = { + buttonClass: "btn" + }; + if (el.dataset.dateFormat) { + options = { ...options, + format: el.dataset.dateFormat + }; + if (!el.dataset.dateFormat.includes("dd")) { + options = { ...options, + pickLevel: 1 }; - - if (this.o.showOnFocus === true) { - events.focus = $.proxy(this.show, this); - } - - if (this.isInput) { // single input - this._events = [ - [this.element, events] - ]; - } - // component: input + button - else if (this.component && this.inputField.length) { - this._events = [ - // For components that are not readonly, allow keyboard nav - [this.inputField, events], - [this.component, { - click: $.proxy(this.show, this) - }] - ]; - } - else { - this._events = [ - [this.element, { - click: $.proxy(this.show, this), - keydown: $.proxy(this.keydown, this) - }] - ]; - } - this._events.push( - // Component: listen for blur on element descendants - [this.element, '*', { - blur: $.proxy(function(e){ - this._focused_from = e.target; - }, this) - }], - // Input: listen for blur on element - [this.element, { - blur: $.proxy(function(e){ - this._focused_from = e.target; - }, this) - }] - ); - - if (this.o.immediateUpdates) { - // Trigger input updates immediately on changed year/month - this._events.push([this.element, { - 'changeYear changeMonth': $.proxy(function(e){ - this.update(e.date); - }, this) - }]); - } - - this._secondaryEvents = [ - [this.picker, { - click: $.proxy(this.click, this) - }], - [this.picker, '.prev, .next', { - click: $.proxy(this.navArrowsClick, this) - }], - [this.picker, '.day:not(.disabled)', { - click: $.proxy(this.dayCellClick, this) - }], - [$(window), { - resize: $.proxy(this.place, this) - }], - [$(document), { - 'mousedown touchstart': $.proxy(function(e){ - // Clicked outside the datepicker, hide it - if (!( - this.element.is(e.target) || - this.element.find(e.target).length || - this.picker.is(e.target) || - this.picker.find(e.target).length || - this.isInline - )){ - this.hide(); - } - }, this) - }] - ]; - }, - _attachEvents: function(){ - this._detachEvents(); - this._applyEvents(this._events); - }, - _detachEvents: function(){ - this._unapplyEvents(this._events); - }, - _attachSecondaryEvents: function(){ - this._detachSecondaryEvents(); - this._applyEvents(this._secondaryEvents); - }, - _detachSecondaryEvents: function(){ - this._unapplyEvents(this._secondaryEvents); - }, - _trigger: function(event, altdate){ - var date = altdate || this.dates.get(-1), - local_date = this._utc_to_local(date); - - this.element.trigger({ - type: event, - date: local_date, - viewMode: this.viewMode, - dates: $.map(this.dates, this._utc_to_local), - format: $.proxy(function(ix, format){ - if (arguments.length === 0){ - ix = this.dates.length - 1; - format = this.o.format; - } else if (typeof ix === 'string'){ - format = ix; - ix = this.dates.length - 1; - } - format = format || this.o.format; - var date = this.dates.get(ix); - return DPGlobal.formatDate(date, format, this.o.language); - }, this) - }); - }, - - show: function(){ - if (this.inputField.is(':disabled') || (this.inputField.prop('readonly') && this.o.enableOnReadonly === false)) - return; - if (!this.isInline) - this.picker.appendTo(this.o.container); - this.place(); - this.picker.show(); - this._attachSecondaryEvents(); - this._trigger('show'); - if ((window.navigator.msMaxTouchPoints || 'ontouchstart' in document) && this.o.disableTouchKeyboard) { - $(this.element).blur(); - } - return this; - }, - - hide: function(){ - if (this.isInline || !this.picker.is(':visible')) - return this; - this.focusDate = null; - this.picker.hide().detach(); - this._detachSecondaryEvents(); - this.setViewMode(this.o.startView); - - if (this.o.forceParse && this.inputField.val()) - this.setValue(); - this._trigger('hide'); - return this; - }, - - destroy: function(){ - this.hide(); - this._detachEvents(); - this._detachSecondaryEvents(); - this.picker.remove(); - delete this.element.data().datepicker; - if (!this.isInput){ - delete this.element.data().date; - } - return this; - }, - - paste: function(e){ - var dateString; - if (e.originalEvent.clipboardData && e.originalEvent.clipboardData.types - && $.inArray('text/plain', e.originalEvent.clipboardData.types) !== -1) { - dateString = e.originalEvent.clipboardData.getData('text/plain'); - } else if (window.clipboardData) { - dateString = window.clipboardData.getData('Text'); - } else { - return; - } - this.setDate(dateString); - this.update(); - e.preventDefault(); - }, - - _utc_to_local: function(utc){ - if (!utc) { - return utc; - } - - var local = new Date(utc.getTime() + (utc.getTimezoneOffset() * 60000)); - - if (local.getTimezoneOffset() !== utc.getTimezoneOffset()) { - local = new Date(utc.getTime() + (local.getTimezoneOffset() * 60000)); - } - - return local; - }, - _local_to_utc: function(local){ - return local && new Date(local.getTime() - (local.getTimezoneOffset()*60000)); - }, - _zero_time: function(local){ - return local && new Date(local.getFullYear(), local.getMonth(), local.getDate()); - }, - _zero_utc_time: function(utc){ - return utc && UTCDate(utc.getUTCFullYear(), utc.getUTCMonth(), utc.getUTCDate()); - }, - - getDates: function(){ - return $.map(this.dates, this._utc_to_local); - }, - - getUTCDates: function(){ - return $.map(this.dates, function(d){ - return new Date(d); - }); - }, - - getDate: function(){ - return this._utc_to_local(this.getUTCDate()); - }, - - getUTCDate: function(){ - var selected_date = this.dates.get(-1); - if (selected_date !== undefined) { - return new Date(selected_date); - } else { - return null; - } - }, - - clearDates: function(){ - this.inputField.val(''); - this.update(); - this._trigger('changeDate'); - - if (this.o.autoclose) { - this.hide(); - } - }, - - setDates: function(){ - var args = $.isArray(arguments[0]) ? arguments[0] : arguments; - this.update.apply(this, args); - this._trigger('changeDate'); - this.setValue(); - return this; - }, - - setUTCDates: function(){ - var args = $.isArray(arguments[0]) ? arguments[0] : arguments; - this.setDates.apply(this, $.map(args, this._utc_to_local)); - return this; - }, - - setDate: alias('setDates'), - setUTCDate: alias('setUTCDates'), - remove: alias('destroy', 'Method `remove` is deprecated and will be removed in version 2.0. Use `destroy` instead'), - - setValue: function(){ - var formatted = this.getFormattedDate(); - this.inputField.val(formatted); - return this; - }, - - getFormattedDate: function(format){ - if (format === undefined) - format = this.o.format; - - var lang = this.o.language; - return $.map(this.dates, function(d){ - return DPGlobal.formatDate(d, format, lang); - }).join(this.o.multidateSeparator); - }, - - getStartDate: function(){ - return this.o.startDate; - }, - - setStartDate: function(startDate){ - this._process_options({startDate: startDate}); - this.update(); - this.updateNavArrows(); - return this; - }, - - getEndDate: function(){ - return this.o.endDate; - }, - - setEndDate: function(endDate){ - this._process_options({endDate: endDate}); - this.update(); - this.updateNavArrows(); - return this; - }, - - setDaysOfWeekDisabled: function(daysOfWeekDisabled){ - this._process_options({daysOfWeekDisabled: daysOfWeekDisabled}); - this.update(); - return this; - }, - - setDaysOfWeekHighlighted: function(daysOfWeekHighlighted){ - this._process_options({daysOfWeekHighlighted: daysOfWeekHighlighted}); - this.update(); - return this; - }, - - setDatesDisabled: function(datesDisabled){ - this._process_options({datesDisabled: datesDisabled}); - this.update(); - return this; - }, - - place: function(){ - if (this.isInline) - return this; - var calendarWidth = this.picker.outerWidth(), - calendarHeight = this.picker.outerHeight(), - visualPadding = 10, - container = $(this.o.container), - windowWidth = container.width(), - scrollTop = this.o.container === 'body' ? $(document).scrollTop() : container.scrollTop(), - appendOffset = container.offset(); - - var parentsZindex = [0]; - this.element.parents().each(function(){ - var itemZIndex = $(this).css('z-index'); - if (itemZIndex !== 'auto' && Number(itemZIndex) !== 0) parentsZindex.push(Number(itemZIndex)); - }); - var zIndex = Math.max.apply(Math, parentsZindex) + this.o.zIndexOffset; - var offset = this.component ? this.component.parent().offset() : this.element.offset(); - var height = this.component ? this.component.outerHeight(true) : this.element.outerHeight(false); - var width = this.component ? this.component.outerWidth(true) : this.element.outerWidth(false); - var left = offset.left - appendOffset.left; - var top = offset.top - appendOffset.top; - - if (this.o.container !== 'body') { - top += scrollTop; - } - - this.picker.removeClass( - 'datepicker-orient-top datepicker-orient-bottom '+ - 'datepicker-orient-right datepicker-orient-left' - ); - - if (this.o.orientation.x !== 'auto'){ - this.picker.addClass('datepicker-orient-' + this.o.orientation.x); - if (this.o.orientation.x === 'right') - left -= calendarWidth - width; - } - // auto x orientation is best-placement: if it crosses a window - // edge, fudge it sideways - else { - if (offset.left < 0) { - // component is outside the window on the left side. Move it into visible range - this.picker.addClass('datepicker-orient-left'); - left -= offset.left - visualPadding; - } else if (left + calendarWidth > windowWidth) { - // the calendar passes the widow right edge. Align it to component right side - this.picker.addClass('datepicker-orient-right'); - left += width - calendarWidth; - } else { - if (this.o.rtl) { - // Default to right - this.picker.addClass('datepicker-orient-right'); - } else { - // Default to left - this.picker.addClass('datepicker-orient-left'); - } - } - } - - // auto y orientation is best-situation: top or bottom, no fudging, - // decision based on which shows more of the calendar - var yorient = this.o.orientation.y, - top_overflow; - if (yorient === 'auto'){ - top_overflow = -scrollTop + top - calendarHeight; - yorient = top_overflow < 0 ? 'bottom' : 'top'; - } - - this.picker.addClass('datepicker-orient-' + yorient); - if (yorient === 'top') - top -= calendarHeight + parseInt(this.picker.css('padding-top')); - else - top += height; - - if (this.o.rtl) { - var right = windowWidth - (left + width); - this.picker.css({ - top: top, - right: right, - zIndex: zIndex - }); - } else { - this.picker.css({ - top: top, - left: left, - zIndex: zIndex - }); - } - return this; - }, - - _allow_update: true, - update: function(){ - if (!this._allow_update) - return this; - - var oldDates = this.dates.copy(), - dates = [], - fromArgs = false; - if (arguments.length){ - $.each(arguments, $.proxy(function(i, date){ - if (date instanceof Date) - date = this._local_to_utc(date); - dates.push(date); - }, this)); - fromArgs = true; - } else { - dates = this.isInput - ? this.element.val() - : this.element.data('date') || this.inputField.val(); - if (dates && this.o.multidate) - dates = dates.split(this.o.multidateSeparator); - else - dates = [dates]; - delete this.element.data().date; - } - - dates = $.map(dates, $.proxy(function(date){ - return DPGlobal.parseDate(date, this.o.format, this.o.language, this.o.assumeNearbyYear); - }, this)); - dates = $.grep(dates, $.proxy(function(date){ - return ( - !this.dateWithinRange(date) || - !date - ); - }, this), true); - this.dates.replace(dates); - - if (this.o.updateViewDate) { - if (this.dates.length) - this.viewDate = new Date(this.dates.get(-1)); - else if (this.viewDate < this.o.startDate) - this.viewDate = new Date(this.o.startDate); - else if (this.viewDate > this.o.endDate) - this.viewDate = new Date(this.o.endDate); - else - this.viewDate = this.o.defaultViewDate; - } - - if (fromArgs){ - // setting date by clicking - this.setValue(); - this.element.change(); - } - else if (this.dates.length){ - // setting date by typing - if (String(oldDates) !== String(this.dates) && fromArgs) { - this._trigger('changeDate'); - this.element.change(); - } - } - if (!this.dates.length && oldDates.length) { - this._trigger('clearDate'); - this.element.change(); - } - - this.fill(); - return this; - }, - - fillDow: function(){ - if (this.o.showWeekDays) { - var dowCnt = this.o.weekStart, - html = ''; - if (this.o.calendarWeeks){ - html += ' '; - } - while (dowCnt < this.o.weekStart + 7){ - html += ''+dates[this.o.language].daysMin[(dowCnt++)%7]+''; - } - html += ''; - this.picker.find('.datepicker-days thead').append(html); - } - }, - - fillMonths: function(){ - var localDate = this._utc_to_local(this.viewDate); - var html = ''; - var focused; - for (var i = 0; i < 12; i++){ - focused = localDate && localDate.getMonth() === i ? ' focused' : ''; - html += '' + dates[this.o.language].monthsShort[i] + ''; - } - this.picker.find('.datepicker-months td').html(html); - }, - - setRange: function(range){ - if (!range || !range.length) - delete this.range; - else - this.range = $.map(range, function(d){ - return d.valueOf(); - }); - this.fill(); - }, - - getClassNames: function(date){ - var cls = [], - year = this.viewDate.getUTCFullYear(), - month = this.viewDate.getUTCMonth(), - today = UTCToday(); - if (date.getUTCFullYear() < year || (date.getUTCFullYear() === year && date.getUTCMonth() < month)){ - cls.push('old'); - } else if (date.getUTCFullYear() > year || (date.getUTCFullYear() === year && date.getUTCMonth() > month)){ - cls.push('new'); - } - if (this.focusDate && date.valueOf() === this.focusDate.valueOf()) - cls.push('focused'); - // Compare internal UTC date with UTC today, not local today - if (this.o.todayHighlight && isUTCEquals(date, today)) { - cls.push('today'); - } - if (this.dates.contains(date) !== -1) - cls.push('active'); - if (!this.dateWithinRange(date)){ - cls.push('disabled'); - } - if (this.dateIsDisabled(date)){ - cls.push('disabled', 'disabled-date'); - } - if ($.inArray(date.getUTCDay(), this.o.daysOfWeekHighlighted) !== -1){ - cls.push('highlighted'); - } - - if (this.range){ - if (date > this.range[0] && date < this.range[this.range.length-1]){ - cls.push('range'); - } - if ($.inArray(date.valueOf(), this.range) !== -1){ - cls.push('selected'); - } - if (date.valueOf() === this.range[0]){ - cls.push('range-start'); - } - if (date.valueOf() === this.range[this.range.length-1]){ - cls.push('range-end'); } - } - return cls; - }, - - _fill_yearsView: function(selector, cssClass, factor, year, startYear, endYear, beforeFn){ - var html = ''; - var step = factor / 10; - var view = this.picker.find(selector); - var startVal = Math.floor(year / factor) * factor; - var endVal = startVal + step * 9; - var focusedVal = Math.floor(this.viewDate.getFullYear() / step) * step; - var selected = $.map(this.dates, function(d){ - return Math.floor(d.getUTCFullYear() / step) * step; - }); - - var classes, tooltip, before; - for (var currVal = startVal - step; currVal <= endVal + step; currVal += step) { - classes = [cssClass]; - tooltip = null; - - if (currVal === startVal - step) { - classes.push('old'); - } else if (currVal === endVal + step) { - classes.push('new'); - } - if ($.inArray(currVal, selected) !== -1) { - classes.push('active'); - } - if (currVal < startYear || currVal > endYear) { - classes.push('disabled'); - } - if (currVal === focusedVal) { - classes.push('focused'); - } - - if (beforeFn !== $.noop) { - before = beforeFn(new Date(currVal, 0, 1)); - if (before === undefined) { - before = {}; - } else if (typeof before === 'boolean') { - before = {enabled: before}; - } else if (typeof before === 'string') { - before = {classes: before}; - } - if (before.enabled === false) { - classes.push('disabled'); - } - if (before.classes) { - classes = classes.concat(before.classes.split(/\s+/)); - } - if (before.tooltip) { - tooltip = before.tooltip; - } - } - - html += '' + currVal + ''; - } - - view.find('.datepicker-switch').text(startVal + '-' + endVal); - view.find('td').html(html); - }, - - fill: function(){ - var d = new Date(this.viewDate), - year = d.getUTCFullYear(), - month = d.getUTCMonth(), - startYear = this.o.startDate !== -Infinity ? this.o.startDate.getUTCFullYear() : -Infinity, - startMonth = this.o.startDate !== -Infinity ? this.o.startDate.getUTCMonth() : -Infinity, - endYear = this.o.endDate !== Infinity ? this.o.endDate.getUTCFullYear() : Infinity, - endMonth = this.o.endDate !== Infinity ? this.o.endDate.getUTCMonth() : Infinity, - todaytxt = dates[this.o.language].today || dates['en'].today || '', - cleartxt = dates[this.o.language].clear || dates['en'].clear || '', - titleFormat = dates[this.o.language].titleFormat || dates['en'].titleFormat, - todayDate = UTCToday(), - titleBtnVisible = (this.o.todayBtn === true || this.o.todayBtn === 'linked') && todayDate >= this.o.startDate && todayDate <= this.o.endDate && !this.weekOfDateIsDisabled(todayDate), - tooltip, - before; - if (isNaN(year) || isNaN(month)) - return; - this.picker.find('.datepicker-days .datepicker-switch') - .text(DPGlobal.formatDate(d, titleFormat, this.o.language)); - this.picker.find('tfoot .today') - .text(todaytxt) - .css('display', titleBtnVisible ? 'table-cell' : 'none'); - this.picker.find('tfoot .clear') - .text(cleartxt) - .css('display', this.o.clearBtn === true ? 'table-cell' : 'none'); - this.picker.find('thead .datepicker-title') - .text(this.o.title) - .css('display', typeof this.o.title === 'string' && this.o.title !== '' ? 'table-cell' : 'none'); - this.updateNavArrows(); - this.fillMonths(); - var prevMonth = UTCDate(year, month, 0), - day = prevMonth.getUTCDate(); - prevMonth.setUTCDate(day - (prevMonth.getUTCDay() - this.o.weekStart + 7)%7); - var nextMonth = new Date(prevMonth); - if (prevMonth.getUTCFullYear() < 100){ - nextMonth.setUTCFullYear(prevMonth.getUTCFullYear()); - } - nextMonth.setUTCDate(nextMonth.getUTCDate() + 42); - nextMonth = nextMonth.valueOf(); - var html = []; - var weekDay, clsName; - while (prevMonth.valueOf() < nextMonth){ - weekDay = prevMonth.getUTCDay(); - if (weekDay === this.o.weekStart){ - html.push(''); - if (this.o.calendarWeeks){ - // ISO 8601: First week contains first thursday. - // ISO also states week starts on Monday, but we can be more abstract here. - var - // Start of current week: based on weekstart/current date - ws = new Date(+prevMonth + (this.o.weekStart - weekDay - 7) % 7 * 864e5), - // Thursday of this week - th = new Date(Number(ws) + (7 + 4 - ws.getUTCDay()) % 7 * 864e5), - // First Thursday of year, year from thursday - yth = new Date(Number(yth = UTCDate(th.getUTCFullYear(), 0, 1)) + (7 + 4 - yth.getUTCDay()) % 7 * 864e5), - // Calendar week: ms between thursdays, div ms per day, div 7 days - calWeek = (th - yth) / 864e5 / 7 + 1; - html.push(''+ calWeek +''); - } - } - clsName = this.getClassNames(prevMonth); - clsName.push('day'); - - var content = prevMonth.getUTCDate(); - - if (this.o.beforeShowDay !== $.noop){ - before = this.o.beforeShowDay(this._utc_to_local(prevMonth)); - if (before === undefined) - before = {}; - else if (typeof before === 'boolean') - before = {enabled: before}; - else if (typeof before === 'string') - before = {classes: before}; - if (before.enabled === false) - clsName.push('disabled'); - if (before.classes) - clsName = clsName.concat(before.classes.split(/\s+/)); - if (before.tooltip) - tooltip = before.tooltip; - if (before.content) - content = before.content; - } - - //Check if uniqueSort exists (supported by jquery >=1.12 and >=2.2) - //Fallback to unique function for older jquery versions - if ($.isFunction($.uniqueSort)) { - clsName = $.uniqueSort(clsName); - } else { - clsName = $.unique(clsName); - } - - html.push('' + content + ''); - tooltip = null; - if (weekDay === this.o.weekEnd){ - html.push(''); - } - prevMonth.setUTCDate(prevMonth.getUTCDate() + 1); - } - this.picker.find('.datepicker-days tbody').html(html.join('')); - - var monthsTitle = dates[this.o.language].monthsTitle || dates['en'].monthsTitle || 'Months'; - var months = this.picker.find('.datepicker-months') - .find('.datepicker-switch') - .text(this.o.maxViewMode < 2 ? monthsTitle : year) - .end() - .find('tbody span').removeClass('active'); - - $.each(this.dates, function(i, d){ - if (d.getUTCFullYear() === year) - months.eq(d.getUTCMonth()).addClass('active'); - }); - - if (year < startYear || year > endYear){ - months.addClass('disabled'); - } - if (year === startYear){ - months.slice(0, startMonth).addClass('disabled'); - } - if (year === endYear){ - months.slice(endMonth+1).addClass('disabled'); - } - - if (this.o.beforeShowMonth !== $.noop){ - var that = this; - $.each(months, function(i, month){ - var moDate = new Date(year, i, 1); - var before = that.o.beforeShowMonth(moDate); - if (before === undefined) - before = {}; - else if (typeof before === 'boolean') - before = {enabled: before}; - else if (typeof before === 'string') - before = {classes: before}; - if (before.enabled === false && !$(month).hasClass('disabled')) - $(month).addClass('disabled'); - if (before.classes) - $(month).addClass(before.classes); - if (before.tooltip) - $(month).prop('title', before.tooltip); - }); - } - - // Generating decade/years picker - this._fill_yearsView( - '.datepicker-years', - 'year', - 10, - year, - startYear, - endYear, - this.o.beforeShowYear - ); - - // Generating century/decades picker - this._fill_yearsView( - '.datepicker-decades', - 'decade', - 100, - year, - startYear, - endYear, - this.o.beforeShowDecade - ); - - // Generating millennium/centuries picker - this._fill_yearsView( - '.datepicker-centuries', - 'century', - 1000, - year, - startYear, - endYear, - this.o.beforeShowCentury - ); - }, - - updateNavArrows: function(){ - if (!this._allow_update) - return; - - var d = new Date(this.viewDate), - year = d.getUTCFullYear(), - month = d.getUTCMonth(), - startYear = this.o.startDate !== -Infinity ? this.o.startDate.getUTCFullYear() : -Infinity, - startMonth = this.o.startDate !== -Infinity ? this.o.startDate.getUTCMonth() : -Infinity, - endYear = this.o.endDate !== Infinity ? this.o.endDate.getUTCFullYear() : Infinity, - endMonth = this.o.endDate !== Infinity ? this.o.endDate.getUTCMonth() : Infinity, - prevIsDisabled, - nextIsDisabled, - factor = 1; - switch (this.viewMode){ - case 4: - factor *= 10; - /* falls through */ - case 3: - factor *= 10; - /* falls through */ - case 2: - factor *= 10; - /* falls through */ - case 1: - prevIsDisabled = Math.floor(year / factor) * factor <= startYear; - nextIsDisabled = Math.floor(year / factor) * factor + factor > endYear; - break; - case 0: - prevIsDisabled = year <= startYear && month <= startMonth; - nextIsDisabled = year >= endYear && month >= endMonth; - break; - } - - this.picker.find('.prev').toggleClass('disabled', prevIsDisabled); - this.picker.find('.next').toggleClass('disabled', nextIsDisabled); - }, - - click: function(e){ - e.preventDefault(); - e.stopPropagation(); - - var target, dir, day, year, month; - target = $(e.target); - - // Clicked on the switch - if (target.hasClass('datepicker-switch') && this.viewMode !== this.o.maxViewMode){ - this.setViewMode(this.viewMode + 1); - } - - // Clicked on today button - if (target.hasClass('today') && !target.hasClass('day')){ - this.setViewMode(0); - this._setDate(UTCToday(), this.o.todayBtn === 'linked' ? null : 'view'); - } - - // Clicked on clear button - if (target.hasClass('clear')){ - this.clearDates(); - } - - if (!target.hasClass('disabled')){ - // Clicked on a month, year, decade, century - if (target.hasClass('month') - || target.hasClass('year') - || target.hasClass('decade') - || target.hasClass('century')) { - this.viewDate.setUTCDate(1); - - day = 1; - if (this.viewMode === 1){ - month = target.parent().find('span').index(target); - year = this.viewDate.getUTCFullYear(); - this.viewDate.setUTCMonth(month); - } else { - month = 0; - year = Number(target.text()); - this.viewDate.setUTCFullYear(year); - } - - this._trigger(DPGlobal.viewModes[this.viewMode - 1].e, this.viewDate); - - if (this.viewMode === this.o.minViewMode){ - this._setDate(UTCDate(year, month, day)); - } else { - this.setViewMode(this.viewMode - 1); - this.fill(); - } - } - } - - if (this.picker.is(':visible') && this._focused_from){ - this._focused_from.focus(); - } - delete this._focused_from; - }, - - dayCellClick: function(e){ - var $target = $(e.currentTarget); - var timestamp = $target.data('date'); - var date = new Date(timestamp); - - if (this.o.updateViewDate) { - if (date.getUTCFullYear() !== this.viewDate.getUTCFullYear()) { - this._trigger('changeYear', this.viewDate); - } - - if (date.getUTCMonth() !== this.viewDate.getUTCMonth()) { - this._trigger('changeMonth', this.viewDate); - } - } - this._setDate(date); - }, - - // Clicked on prev or next - navArrowsClick: function(e){ - var $target = $(e.currentTarget); - var dir = $target.hasClass('prev') ? -1 : 1; - if (this.viewMode !== 0){ - dir *= DPGlobal.viewModes[this.viewMode].navStep * 12; - } - this.viewDate = this.moveMonth(this.viewDate, dir); - this._trigger(DPGlobal.viewModes[this.viewMode].e, this.viewDate); - this.fill(); - }, - - _toggle_multidate: function(date){ - var ix = this.dates.contains(date); - if (!date){ - this.dates.clear(); - } - - if (ix !== -1){ - if (this.o.multidate === true || this.o.multidate > 1 || this.o.toggleActive){ - this.dates.remove(ix); - } - } else if (this.o.multidate === false) { - this.dates.clear(); - this.dates.push(date); - } - else { - this.dates.push(date); - } - - if (typeof this.o.multidate === 'number') - while (this.dates.length > this.o.multidate) - this.dates.remove(0); - }, - - _setDate: function(date, which){ - if (!which || which === 'date') - this._toggle_multidate(date && new Date(date)); - if ((!which && this.o.updateViewDate) || which === 'view') - this.viewDate = date && new Date(date); - - this.fill(); - this.setValue(); - if (!which || which !== 'view') { - this._trigger('changeDate'); - } - this.inputField.trigger('change'); - if (this.o.autoclose && (!which || which === 'date')){ - this.hide(); - } - }, - - moveDay: function(date, dir){ - var newDate = new Date(date); - newDate.setUTCDate(date.getUTCDate() + dir); - - return newDate; - }, - - moveWeek: function(date, dir){ - return this.moveDay(date, dir * 7); - }, - - moveMonth: function(date, dir){ - if (!isValidDate(date)) - return this.o.defaultViewDate; - if (!dir) - return date; - var new_date = new Date(date.valueOf()), - day = new_date.getUTCDate(), - month = new_date.getUTCMonth(), - mag = Math.abs(dir), - new_month, test; - dir = dir > 0 ? 1 : -1; - if (mag === 1){ - test = dir === -1 - // If going back one month, make sure month is not current month - // (eg, Mar 31 -> Feb 31 == Feb 28, not Mar 02) - ? function(){ - return new_date.getUTCMonth() === month; - } - // If going forward one month, make sure month is as expected - // (eg, Jan 31 -> Feb 31 == Feb 28, not Mar 02) - : function(){ - return new_date.getUTCMonth() !== new_month; - }; - new_month = month + dir; - new_date.setUTCMonth(new_month); - // Dec -> Jan (12) or Jan -> Dec (-1) -- limit expected date to 0-11 - new_month = (new_month + 12) % 12; - } - else { - // For magnitudes >1, move one month at a time... - for (var i=0; i < mag; i++) - // ...which might decrease the day (eg, Jan 31 to Feb 28, etc)... - new_date = this.moveMonth(new_date, dir); - // ...then reset the day, keeping it in the new month - new_month = new_date.getUTCMonth(); - new_date.setUTCDate(day); - test = function(){ - return new_month !== new_date.getUTCMonth(); - }; - } - // Common date-resetting loop -- if date is beyond end of month, make it - // end of month - while (test()){ - new_date.setUTCDate(--day); - new_date.setUTCMonth(new_month); - } - return new_date; - }, - - moveYear: function(date, dir){ - return this.moveMonth(date, dir*12); - }, - - moveAvailableDate: function(date, dir, fn){ - do { - date = this[fn](date, dir); - - if (!this.dateWithinRange(date)) - return false; - - fn = 'moveDay'; - } - while (this.dateIsDisabled(date)); - - return date; - }, - - weekOfDateIsDisabled: function(date){ - return $.inArray(date.getUTCDay(), this.o.daysOfWeekDisabled) !== -1; - }, - - dateIsDisabled: function(date){ - return ( - this.weekOfDateIsDisabled(date) || - $.grep(this.o.datesDisabled, function(d){ - return isUTCEquals(date, d); - }).length > 0 - ); - }, - - dateWithinRange: function(date){ - return date >= this.o.startDate && date <= this.o.endDate; - }, - - keydown: function(e){ - if (!this.picker.is(':visible')){ - if (e.keyCode === 40 || e.keyCode === 27) { // allow down to re-show picker - this.show(); - e.stopPropagation(); - } - return; - } - var dateChanged = false, - dir, newViewDate, - focusDate = this.focusDate || this.viewDate; - switch (e.keyCode){ - case 27: // escape - if (this.focusDate){ - this.focusDate = null; - this.viewDate = this.dates.get(-1) || this.viewDate; - this.fill(); - } - else - this.hide(); - e.preventDefault(); - e.stopPropagation(); - break; - case 37: // left - case 38: // up - case 39: // right - case 40: // down - if (!this.o.keyboardNavigation || this.o.daysOfWeekDisabled.length === 7) - break; - dir = e.keyCode === 37 || e.keyCode === 38 ? -1 : 1; - if (this.viewMode === 0) { - if (e.ctrlKey){ - newViewDate = this.moveAvailableDate(focusDate, dir, 'moveYear'); - - if (newViewDate) - this._trigger('changeYear', this.viewDate); - } else if (e.shiftKey){ - newViewDate = this.moveAvailableDate(focusDate, dir, 'moveMonth'); - - if (newViewDate) - this._trigger('changeMonth', this.viewDate); - } else if (e.keyCode === 37 || e.keyCode === 39){ - newViewDate = this.moveAvailableDate(focusDate, dir, 'moveDay'); - } else if (!this.weekOfDateIsDisabled(focusDate)){ - newViewDate = this.moveAvailableDate(focusDate, dir, 'moveWeek'); - } - } else if (this.viewMode === 1) { - if (e.keyCode === 38 || e.keyCode === 40) { - dir = dir * 4; - } - newViewDate = this.moveAvailableDate(focusDate, dir, 'moveMonth'); - } else if (this.viewMode === 2) { - if (e.keyCode === 38 || e.keyCode === 40) { - dir = dir * 4; - } - newViewDate = this.moveAvailableDate(focusDate, dir, 'moveYear'); - } - if (newViewDate){ - this.focusDate = this.viewDate = newViewDate; - this.setValue(); - this.fill(); - e.preventDefault(); - } - break; - case 13: // enter - if (!this.o.forceParse) - break; - focusDate = this.focusDate || this.dates.get(-1) || this.viewDate; - if (this.o.keyboardNavigation) { - this._toggle_multidate(focusDate); - dateChanged = true; - } - this.focusDate = null; - this.viewDate = this.dates.get(-1) || this.viewDate; - this.setValue(); - this.fill(); - if (this.picker.is(':visible')){ - e.preventDefault(); - e.stopPropagation(); - if (this.o.autoclose) - this.hide(); - } - break; - case 9: // tab - this.focusDate = null; - this.viewDate = this.dates.get(-1) || this.viewDate; - this.fill(); - this.hide(); - break; - } - if (dateChanged){ - if (this.dates.length) - this._trigger('changeDate'); - else - this._trigger('clearDate'); - this.inputField.trigger('change'); - } - }, - - setViewMode: function(viewMode){ - this.viewMode = viewMode; - this.picker - .children('div') - .hide() - .filter('.datepicker-' + DPGlobal.viewModes[this.viewMode].clsName) - .show(); - this.updateNavArrows(); - this._trigger('changeViewMode', new Date(this.viewDate)); - } - }; - - var DateRangePicker = function(element, options){ - $.data(element, 'datepicker', this); - this.element = $(element); - this.inputs = $.map(options.inputs, function(i){ - return i.jquery ? i[0] : i; - }); - delete options.inputs; - - this.keepEmptyValues = options.keepEmptyValues; - delete options.keepEmptyValues; - - datepickerPlugin.call($(this.inputs), options) - .on('changeDate', $.proxy(this.dateUpdated, this)); - - this.pickers = $.map(this.inputs, function(i){ - return $.data(i, 'datepicker'); - }); - this.updateDates(); - }; - DateRangePicker.prototype = { - updateDates: function(){ - this.dates = $.map(this.pickers, function(i){ - return i.getUTCDate(); - }); - this.updateRanges(); - }, - updateRanges: function(){ - var range = $.map(this.dates, function(d){ - return d.valueOf(); - }); - $.each(this.pickers, function(i, p){ - p.setRange(range); - }); - }, - clearDates: function(){ - $.each(this.pickers, function(i, p){ - p.clearDates(); - }); - }, - dateUpdated: function(e){ - // `this.updating` is a workaround for preventing infinite recursion - // between `changeDate` triggering and `setUTCDate` calling. Until - // there is a better mechanism. - if (this.updating) - return; - this.updating = true; - - var dp = $.data(e.target, 'datepicker'); - - if (dp === undefined) { - return; - } - - var new_date = dp.getUTCDate(), - keep_empty_values = this.keepEmptyValues, - i = $.inArray(e.target, this.inputs), - j = i - 1, - k = i + 1, - l = this.inputs.length; - if (i === -1) - return; - - $.each(this.pickers, function(i, p){ - if (!p.getUTCDate() && (p === dp || !keep_empty_values)) - p.setUTCDate(new_date); - }); - - if (new_date < this.dates[j]){ - // Date being moved earlier/left - while (j >= 0 && new_date < this.dates[j]){ - this.pickers[j--].setUTCDate(new_date); - } - } else if (new_date > this.dates[k]){ - // Date being moved later/right - while (k < l && new_date > this.dates[k]){ - this.pickers[k++].setUTCDate(new_date); - } - } - this.updateDates(); - - delete this.updating; - }, - destroy: function(){ - $.map(this.pickers, function(p){ p.destroy(); }); - $(this.inputs).off('changeDate', this.dateUpdated); - delete this.element.data().datepicker; - }, - remove: alias('destroy', 'Method `remove` is deprecated and will be removed in version 2.0. Use `destroy` instead') - }; - - function opts_from_el(el, prefix){ - // Derive options from element data-attrs - var data = $(el).data(), - out = {}, inkey, - replace = new RegExp('^' + prefix.toLowerCase() + '([A-Z])'); - prefix = new RegExp('^' + prefix.toLowerCase()); - function re_lower(_,a){ - return a.toLowerCase(); - } - for (var key in data) - if (prefix.test(key)){ - inkey = key.replace(replace, re_lower); - out[inkey] = data[key]; - } - return out; - } - - function opts_from_locale(lang){ - // Derive options from locale plugins - var out = {}; - // Check if "de-DE" style date is available, if not language should - // fallback to 2 letter code eg "de" - if (!dates[lang]){ - lang = lang.split('-')[0]; - if (!dates[lang]) - return; - } - var d = dates[lang]; - $.each(locale_opts, function(i,k){ - if (k in d) - out[k] = d[k]; - }); - return out; - } - - var old = $.fn.datepicker; - var datepickerPlugin = function(option){ - var args = Array.apply(null, arguments); - args.shift(); - var internal_return; - this.each(function(){ - var $this = $(this), - data = $this.data('datepicker'), - options = typeof option === 'object' && option; - if (!data){ - var elopts = opts_from_el(this, 'date'), - // Preliminary otions - xopts = $.extend({}, defaults, elopts, options), - locopts = opts_from_locale(xopts.language), - // Options priority: js args, data-attrs, locales, defaults - opts = $.extend({}, defaults, locopts, elopts, options); - if ($this.hasClass('input-daterange') || opts.inputs){ - $.extend(opts, { - inputs: opts.inputs || $this.find('input').toArray() - }); - data = new DateRangePicker(this, opts); - } - else { - data = new Datepicker(this, opts); - } - $this.data('datepicker', data); - } - if (typeof option === 'string' && typeof data[option] === 'function'){ - internal_return = data[option].apply(data, args); - } - }); - - if ( - internal_return === undefined || - internal_return instanceof Datepicker || - internal_return instanceof DateRangePicker - ) - return this; - - if (this.length > 1) - throw new Error('Using only allowed for the collection of a single element (' + option + ' function)'); - else - return internal_return; - }; - $.fn.datepicker = datepickerPlugin; - - var defaults = $.fn.datepicker.defaults = { - assumeNearbyYear: false, - autoclose: false, - beforeShowDay: $.noop, - beforeShowMonth: $.noop, - beforeShowYear: $.noop, - beforeShowDecade: $.noop, - beforeShowCentury: $.noop, - calendarWeeks: false, - clearBtn: false, - toggleActive: false, - daysOfWeekDisabled: [], - daysOfWeekHighlighted: [], - datesDisabled: [], - endDate: Infinity, - forceParse: true, - format: 'mm/dd/yyyy', - keepEmptyValues: false, - keyboardNavigation: true, - language: 'en', - minViewMode: 0, - maxViewMode: 4, - multidate: false, - multidateSeparator: ',', - orientation: "auto", - rtl: false, - startDate: -Infinity, - startView: 0, - todayBtn: false, - todayHighlight: false, - updateViewDate: true, - weekStart: 0, - disableTouchKeyboard: false, - enableOnReadonly: true, - showOnFocus: true, - zIndexOffset: 10, - container: 'body', - immediateUpdates: false, - title: '', - templates: { - leftArrow: '«', - rightArrow: '»' - }, - showWeekDays: true - }; - var locale_opts = $.fn.datepicker.locale_opts = [ - 'format', - 'rtl', - 'weekStart' - ]; - $.fn.datepicker.Constructor = Datepicker; - var dates = $.fn.datepicker.dates = { - en: { - days: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"], - daysShort: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], - daysMin: ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"], - months: ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"], - monthsShort: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"], - today: "Today", - clear: "Clear", - titleFormat: "MM yyyy" - } - }; - - var DPGlobal = { - viewModes: [ - { - names: ['days', 'month'], - clsName: 'days', - e: 'changeMonth' - }, - { - names: ['months', 'year'], - clsName: 'months', - e: 'changeYear', - navStep: 1 - }, - { - names: ['years', 'decade'], - clsName: 'years', - e: 'changeDecade', - navStep: 10 - }, - { - names: ['decades', 'century'], - clsName: 'decades', - e: 'changeCentury', - navStep: 100 - }, - { - names: ['centuries', 'millennium'], - clsName: 'centuries', - e: 'changeMillennium', - navStep: 1000 - } - ], - validParts: /dd?|DD?|mm?|MM?|yy(?:yy)?/g, - nonpunctuation: /[^ -\/:-@\u5e74\u6708\u65e5\[-`{-~\t\n\r]+/g, - parseFormat: function(format){ - if (typeof format.toValue === 'function' && typeof format.toDisplay === 'function') - return format; - // IE treats \0 as a string end in inputs (truncating the value), - // so it's a bad format delimiter, anyway - var separators = format.replace(this.validParts, '\0').split('\0'), - parts = format.match(this.validParts); - if (!separators || !separators.length || !parts || parts.length === 0){ - throw new Error("Invalid date format."); - } - return {separators: separators, parts: parts}; - }, - parseDate: function(date, format, language, assumeNearby){ - if (!date) - return undefined; - if (date instanceof Date) - return date; - if (typeof format === 'string') - format = DPGlobal.parseFormat(format); - if (format.toValue) - return format.toValue(date, format, language); - var fn_map = { - d: 'moveDay', - m: 'moveMonth', - w: 'moveWeek', - y: 'moveYear' - }, - dateAliases = { - yesterday: '-1d', - today: '+0d', - tomorrow: '+1d' - }, - parts, part, dir, i, fn; - if (date in dateAliases){ - date = dateAliases[date]; - } - if (/^[\-+]\d+[dmwy]([\s,]+[\-+]\d+[dmwy])*$/i.test(date)){ - parts = date.match(/([\-+]\d+)([dmwy])/gi); - date = new Date(); - for (i=0; i < parts.length; i++){ - part = parts[i].match(/([\-+]\d+)([dmwy])/i); - dir = Number(part[1]); - fn = fn_map[part[2].toLowerCase()]; - date = Datepicker.prototype[fn](date, dir); - } - return Datepicker.prototype._zero_utc_time(date); - } - - parts = date && date.match(this.nonpunctuation) || []; - - function applyNearbyYear(year, threshold){ - if (threshold === true) - threshold = 10; - - // if year is 2 digits or less, than the user most likely is trying to get a recent century - if (year < 100){ - year += 2000; - // if the new year is more than threshold years in advance, use last century - if (year > ((new Date()).getFullYear()+threshold)){ - year -= 100; - } - } - - return year; - } - - var parsed = {}, - setters_order = ['yyyy', 'yy', 'M', 'MM', 'm', 'mm', 'd', 'dd'], - setters_map = { - yyyy: function(d,v){ - return d.setUTCFullYear(assumeNearby ? applyNearbyYear(v, assumeNearby) : v); - }, - m: function(d,v){ - if (isNaN(d)) - return d; - v -= 1; - while (v < 0) v += 12; - v %= 12; - d.setUTCMonth(v); - while (d.getUTCMonth() !== v) - d.setUTCDate(d.getUTCDate()-1); - return d; - }, - d: function(d,v){ - return d.setUTCDate(v); - } - }, - val, filtered; - setters_map['yy'] = setters_map['yyyy']; - setters_map['M'] = setters_map['MM'] = setters_map['mm'] = setters_map['m']; - setters_map['dd'] = setters_map['d']; - date = UTCToday(); - var fparts = format.parts.slice(); - // Remove noop parts - if (parts.length !== fparts.length){ - fparts = $(fparts).filter(function(i,p){ - return $.inArray(p, setters_order) !== -1; - }).toArray(); - } - // Process remainder - function match_part(){ - var m = this.slice(0, parts[i].length), - p = parts[i].slice(0, m.length); - return m.toLowerCase() === p.toLowerCase(); - } - if (parts.length === fparts.length){ - var cnt; - for (i=0, cnt = fparts.length; i < cnt; i++){ - val = parseInt(parts[i], 10); - part = fparts[i]; - if (isNaN(val)){ - switch (part){ - case 'MM': - filtered = $(dates[language].months).filter(match_part); - val = $.inArray(filtered[0], dates[language].months) + 1; - break; - case 'M': - filtered = $(dates[language].monthsShort).filter(match_part); - val = $.inArray(filtered[0], dates[language].monthsShort) + 1; - break; - } - } - parsed[part] = val; - } - var _date, s; - for (i=0; i < setters_order.length; i++){ - s = setters_order[i]; - if (s in parsed && !isNaN(parsed[s])){ - _date = new Date(date); - setters_map[s](_date, parsed[s]); - if (!isNaN(_date)) - date = _date; - } - } - } - return date; - }, - formatDate: function(date, format, language){ - if (!date) - return ''; - if (typeof format === 'string') - format = DPGlobal.parseFormat(format); - if (format.toDisplay) - return format.toDisplay(date, format, language); - var val = { - d: date.getUTCDate(), - D: dates[language].daysShort[date.getUTCDay()], - DD: dates[language].days[date.getUTCDay()], - m: date.getUTCMonth() + 1, - M: dates[language].monthsShort[date.getUTCMonth()], - MM: dates[language].months[date.getUTCMonth()], - yy: date.getUTCFullYear().toString().substring(2), - yyyy: date.getUTCFullYear() - }; - val.dd = (val.d < 10 ? '0' : '') + val.d; - val.mm = (val.m < 10 ? '0' : '') + val.m; - date = []; - var seps = $.extend([], format.separators); - for (var i=0, cnt = format.parts.length; i <= cnt; i++){ - if (seps.length) - date.push(seps.shift()); - date.push(val[format.parts[i]]); - } - return date.join(''); - }, - headTemplate: ''+ - ''+ - ''+ - ''+ - ''+ - ''+defaults.templates.leftArrow+''+ - ''+ - ''+defaults.templates.rightArrow+''+ - ''+ - '', - contTemplate: '', - footTemplate: ''+ - ''+ - ''+ - ''+ - ''+ - ''+ - ''+ - '' - }; - DPGlobal.template = '
    '+ - '
    '+ - ''+ - DPGlobal.headTemplate+ - ''+ - DPGlobal.footTemplate+ - '
    '+ - '
    '+ - '
    '+ - ''+ - DPGlobal.headTemplate+ - DPGlobal.contTemplate+ - DPGlobal.footTemplate+ - '
    '+ - '
    '+ - '
    '+ - ''+ - DPGlobal.headTemplate+ - DPGlobal.contTemplate+ - DPGlobal.footTemplate+ - '
    '+ - '
    '+ - '
    '+ - ''+ - DPGlobal.headTemplate+ - DPGlobal.contTemplate+ - DPGlobal.footTemplate+ - '
    '+ - '
    '+ - '
    '+ - ''+ - DPGlobal.headTemplate+ - DPGlobal.contTemplate+ - DPGlobal.footTemplate+ - '
    '+ - '
    '+ - '
    '; - - $.fn.datepicker.DPGlobal = DPGlobal; - - - /* DATEPICKER NO CONFLICT - * =================== */ - - $.fn.datepicker.noConflict = function(){ - $.fn.datepicker = old; - return this; - }; - - /* DATEPICKER VERSION - * =================== */ - $.fn.datepicker.version = '1.9.0'; - - $.fn.datepicker.deprecated = function(msg){ - var console = window.console; - if (console && console.warn) { - console.warn('DEPRECATED: ' + msg); - } - }; - - - /* DATEPICKER DATA-API - * ================== */ + } + if (el.dataset.dateMinViewMode && view_mode[el.dataset.dateMinViewMode]) { + options = { ...options, + startView: view_mode[el.dataset.dateMinViewMode] + }; + } + if (el.dataset.dateViewMode && view_mode[el.dataset.dateViewMode]) { + options = { ...options, + maxView: view_mode[el.dataset.dateViewMode] + }; + } + if (el.dataset.dateAutoclose) { + options = { ...options, + autohide: el.dataset.dateAutoclose + }; + } - $(document).on( - 'focus.datepicker.data-api click.datepicker.data-api', - '[data-provide="datepicker"]', - function(e){ - var $this = $(this); - if ($this.data('datepicker')) - return; - e.preventDefault(); - // component click requires us to explicitly show it - datepickerPlugin.call($this, 'show'); - } - ); - $(function(){ - datepickerPlugin.call($('[data-provide="datepicker-inline"]')); - }); + new Datepicker(el, options); +} -})); +document.addEventListener("DOMContentLoaded", function () { + const elems = document.querySelectorAll('[data-provide="datepicker"]'); + elems.forEach(el => enable_datepicker(el)); +}); diff --git a/ietf/static/js/document_html.js b/ietf/static/js/document_html.js new file mode 100644 index 00000000000..3e609f3965d --- /dev/null +++ b/ietf/static/js/document_html.js @@ -0,0 +1,199 @@ +import { + Tooltip as Tooltip, + // Button as Button, + // Collapse as Collapse, + // ScrollSpy as ScrollSpy, + Tab as Tab +} from "bootstrap"; + +import Cookies from "js-cookie"; +import { populate_nav } from "./nav.js"; +import "./select2.js"; + +const cookies = Cookies.withAttributes({ sameSite: "strict" }); + +// set initial point size from cookie before DOM is ready, to avoid flickering +const ptsize_var = "doc-ptsize-max"; + +function change_ptsize(ptsize) { + document.documentElement.style.setProperty(`--${ptsize_var}`, + `${ptsize}pt`); + localStorage.setItem(ptsize_var, ptsize); +} + +const ptsize = localStorage.getItem(ptsize_var); +change_ptsize(ptsize ? Math.min(Math.max(7, ptsize), 16) : 12); + +document.addEventListener("DOMContentLoaded", function (event) { + // handle point size slider + document.getElementById("ptsize") + .oninput = function () { change_ptsize(this.value) }; + + // Use the Bootstrap tooltip plugin for all elements with a title attribute + const tt_triggers = document.querySelectorAll( + "[title]:not([title=''])"); + [...tt_triggers].map(tt_el => { + const tooltip = Tooltip.getOrCreateInstance(tt_el); + tt_el.addEventListener("click", el => { + tooltip.hide(); + tt_el.blur(); + }); + }); + + // Set up a nav pane + const toc_pane = document.getElementById("toc-nav"); + const headings = document.querySelectorAll(`#content :is(h2, h3, h4, h5, h6, .h2, .h3, .h4, .h5, .h6)`); + populate_nav(toc_pane, headings, ["py-0"]); + + // activate pref buttons selected by pref cookies or localStorage + const in_localStorage = ["deftab", "reflinks"]; + const btn_pref = { + "sidebar": "on", + "deftab": "docinfo", + "htmlconf": "html", + "pagedeps": "reference", + "reflinks": "refsection" + }; + document.querySelectorAll("#pref-tab-pane .btn-check") + .forEach(btn => { + const id = btn.id.replace("-radio", ""); + + const val = in_localStorage.includes(btn.name) ? + localStorage.getItem(btn.name) : cookies.get(btn.name); + if (val === id || (val === null && btn_pref[btn.name] === id)) { + btn.checked = true; + } + + btn.addEventListener("click", el => { + // only use cookies for things used in HTML templates + if (in_localStorage.includes(btn.name)) { + localStorage.setItem(btn.name, id) + } else { + cookies.set(btn.name, id); + } + window.location.reload(); + }); + }); + + // activate tab selected in prefs + let defpane; + try { + defpane = Tab.getOrCreateInstance( + `#${localStorage.getItem("deftab")}-tab`); + } catch (err) { + defpane = Tab.getOrCreateInstance("#docinfo-tab"); + }; + defpane.show(); + document.activeElement.blur(); + + if (localStorage.getItem("reflinks") != "refsection") { + // make links to references go directly to the referenced doc + document.querySelectorAll("a[href^='#'].xref") + .forEach(ref => { + const loc = document + .getElementById(ref.hash.substring(1)) + .nextElementSibling; + + if (!loc || + loc.tagName != "DD" || + !loc.closest(".references")) { + return; + } + + const url = loc.querySelector( + "a:not([href='']:last-of-type)"); + if (url) { + const rfc = url.href.match(/(rfc\d+)$/i); + if (rfc) { + // keep RFC links within the datatracker + const base = ref.href.match( + /^(.*\/)rfc\d+.*$/i); + if (base) { + ref.href = base[1] + rfc[1]; + return; + } + } + ref.href = url.href; + } + }); + } + + // Rewrite these CSS properties so that the values are available for restyling. + document.querySelectorAll("svg [style]").forEach(el => { + // Push these CSS properties into their own attributes + const SVG_PRESENTATION_ATTRS = new Set([ + 'alignment-baseline', 'baseline-shift', 'clip', 'clip-path', 'clip-rule', + 'color', 'color-interpolation', 'color-interpolation-filters', + 'color-rendering', 'cursor', 'direction', 'display', 'dominant-baseline', + 'fill', 'fill-opacity', 'fill-rule', 'filter', 'flood-color', + 'flood-opacity', 'font-family', 'font-size', 'font-size-adjust', + 'font-stretch', 'font-style', 'font-variant', 'font-weight', + 'image-rendering', 'letter-spacing', 'lighting-color', 'marker-end', + 'marker-mid', 'marker-start', 'mask', 'opacity', 'overflow', 'paint-order', + 'pointer-events', 'shape-rendering', 'stop-color', 'stop-opacity', + 'stroke', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', + 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke-width', + 'text-anchor', 'text-decoration', 'text-rendering', 'unicode-bidi', + 'vector-effect', 'visibility', 'word-spacing', 'writing-mode', + ]); + + // Simple CSS splitter: respects quoted strings and parens so semicolons + // inside url(...) or "..." don't get treated as declaration boundaries. + function parseDeclarations(styleText) { + const decls = []; + let buf = ''; + let inStr = false; + let strChar = ''; + let escaped = false; + let depth = 0; + + for (const ch of styleText) { + if (inStr) { + if (escaped) { + escaped = false; + } else if (ch === '\\') { + escaped = true; + } else if (ch === strChar) { + inStr = false; + } + } else if (ch === '"' || ch === "'") { + inStr = true; + strChar = ch; + } else if (ch === '(') { + depth++; + } else if (ch === ')') { + depth--; + } else if (ch === ';' && depth === 0) { + const trimmed = buf.trim(); + if (trimmed) { + decls.push(trimmed); + } + buf = ''; + continue; + } + buf += ch; + } + const trimmed = buf.trim(); + if (trimmed) { + decls.push(trimmed); + } + return decls; + } + + const remainder = []; + for (const decl of parseDeclarations(el.getAttribute('style'))) { + const [prop, val] = decl.split(":", 2).map(v => v.trim()); + if (val && !/!important$/.test(val) && SVG_PRESENTATION_ATTRS.has(prop)) { + el.setAttribute(prop, val); + } else { + remainder.push(decl); + } + } + + if (remainder.length > 0) { + el.setAttribute('style', remainder.join('; ')); + } else { + el.removeAttribute('style'); + } + }); +}); diff --git a/ietf/static/js/document_relations.js b/ietf/static/js/document_relations.js index e6b885d837c..07a85d0da50 100644 --- a/ietf/static/js/document_relations.js +++ b/ietf/static/js/document_relations.js @@ -315,7 +315,7 @@ function draw_graph(data, group) { }) ]; - // // See https://github.com/d3/d3-force/blob/master/README.md#simulation_tick + // // See https://github.com/d3/d3-force/blob/main/README.md#simulation_tick // for (let i = 0, n = Math.ceil(Math.log(simulation.alphaMin()) / // Math.log(1 - simulation.alphaDecay())); i < // n; ++i) { @@ -449,7 +449,7 @@ $("#deps-modal") .replaceWith(dep_el); dep_sim.restart(); - $('svg [title][title!=""]') + $('svg [title]:not([title=""])') .tooltip(); $("#legend") @@ -467,7 +467,7 @@ $("#deps-modal") dep_sim.restart(); } - $('svg [title][title!=""]') + $('svg [title]:not([title=""])') .tooltip(); }); diff --git a/ietf/static/js/document_timeline.js b/ietf/static/js/document_timeline.js index babde0deeb4..d8532c36233 100644 --- a/ietf/static/js/document_timeline.js +++ b/ietf/static/js/document_timeline.js @@ -86,7 +86,7 @@ function scale_x() { } function update_x_axis() { - d3.select("#timeline svg .x.axis") + d3.select("#doc-timeline svg .x.axis") .call(x_axis) .selectAll("text") .style("text-anchor", "end") @@ -96,7 +96,7 @@ function update_x_axis() { function update_timeline() { bar_y = {}; scale_x(); - var chart = d3.select("#timeline svg") + var chart = d3.select("#doc-timeline svg") .attr("width", width); // enter data (skip the last pseudo entry) var bar = chart.selectAll("g") @@ -111,12 +111,12 @@ function draw_timeline() { bar_height = parseFloat($("body") .css("line-height")); - var div = $("#timeline"); + var div = $("#doc-timeline"); div.addClass("my-3"); if (div.is(":empty")) { div.append(""); } - var chart = d3.select("#timeline svg") + var chart = d3.select("#doc-timeline svg") .attr("width", width); var defs = chart.append("defs"); @@ -249,7 +249,7 @@ d3.json("doc.json") published: expiration_date(data[data.length - 1]) }); - width = $("#timeline") + width = $("#doc-timeline") .width(); draw_timeline(); } @@ -258,11 +258,11 @@ d3.json("doc.json") $(window) .on({ resize: function () { - var g = $("#timeline svg"); + var g = $("#doc-timeline svg"); g.remove(); - width = $("#timeline") + width = $("#doc-timeline") .width(); - $("#timeline") + $("#doc-timeline") .append(g); update_timeline(); } diff --git a/ietf/static/js/draft-submit.js b/ietf/static/js/draft-submit.js index d3657a8377f..38ac7eb2633 100644 --- a/ietf/static/js/draft-submit.js +++ b/ietf/static/js/draft-submit.js @@ -1,69 +1,96 @@ -$(document) - .ready(function () { - // fill in submitter info when an author button is clicked - $("form.idsubmit button.author") - .on("click", function () { - var name = $(this) - .data("name"); - var email = $(this) - .data("email"); +$(function () { + // fill in submitter info when an author button is clicked + $("form.idsubmit button.author") + .on("click", function () { + var name = $(this) + .data("name"); + var email = $(this) + .data("email"); - $(this) - .parents("form") - .find("input[name=submitter-name]") - .val(name || ""); - $(this) - .parents("form") - .find("input[name=submitter-email]") - .val(email || ""); - }); + $(this) + .parents("form") + .find("input[name=submitter-name]") + .val(name || ""); + $(this) + .parents("form") + .find("input[name=submitter-email]") + .val(email || ""); + }); - $("form.idsubmit") - .on("submit", function () { - if (this.submittedAlready) - return false; - else { - this.submittedAlready = true; - return true; - } - }); + $("form.idsubmit") + .on("submit", function () { + if (this.submittedAlready) + return false; + else { + this.submittedAlready = true; + return true; + } + }); - $("form.idsubmit #add-author") - .on("click", function () { - // clone the last author block and make it empty - var cloner = $("#cloner"); - var next = cloner.clone(); - next.find('input:not([type=hidden])') - .val(''); + $("form.idsubmit #add-author") + .on("click", function () { + // clone the last author block and make it empty + var cloner = $("#cloner"); + var next = cloner.clone(); + next.find('input:not([type=hidden])') + .val(''); - // find the author number - var t = next.children('h3') - .text(); - var n = parseInt(t.replace(/\D/g, '')); + // find the author number + var t = next.children('h3') + .text(); + var n = parseInt(t.replace(/\D/g, '')); - // change the number in attributes and text - next.find('*') - .each(function () { - var e = this; - $.each(['id', 'for', 'name', 'value'], function (i, v) { - if ($(e) - .attr(v)) { - $(e) - .attr(v, $(e) - .attr(v) - .replace(n - 1, n)); - } - }); + // change the number in attributes and text + next.find('*') + .each(function () { + var e = this; + $.each(['id', 'for', 'name', 'value'], function (i, v) { + if ($(e) + .attr(v)) { + $(e) + .attr(v, $(e) + .attr(v) + .replace(n - 1, n)); + } }); + }); + + t = t.replace(n, n + 1); + next.children('h3') + .text(t); - t = t.replace(n, n + 1); - next.children('h3') - .text(t); + // move the cloner id to next and insert next into the DOM + cloner.removeAttr('id'); + next.attr('id', 'cloner'); + next.insertAfter(cloner); - // move the cloner id to next and insert next into the DOM - cloner.removeAttr('id'); - next.attr('id', 'cloner'); - next.insertAfter(cloner); + }); - }); - }); + // If draft is validating, poll until validation is complete, then reload the page + const submissionValidatingAlert = document.getElementById('submission-validating-alert'); + if (submissionValidatingAlert) { + let statusPollTimer; + const statusUrl = submissionValidatingAlert.dataset['submissionStatusUrl']; + let statusPollInterval = 2000; // ms + const maxPollInterval = 32000; // ms + + function checkStatus() { + if (statusPollInterval < maxPollInterval) { + statusPollInterval *= 2; + } + const xhr = new XMLHttpRequest(); + xhr.open("GET", statusUrl, true); + xhr.onload = (e) => { + if (xhr.response && xhr.response.state !== 'validating') { + location.reload(); + } else { + statusPollTimer = setTimeout(checkStatus, statusPollInterval); + } + }; + xhr.onerror = (e) => {statusPollTimer = setTimeout(checkStatus, statusPollInterval);}; + xhr.responseType = 'json'; + xhr.send(''); + } + statusPollTimer = setTimeout(checkStatus, statusPollInterval); + } +}); diff --git a/ietf/static/js/edit-meeting-schedule.js b/ietf/static/js/edit-meeting-schedule.js index 724f336c937..2a73a8c29d4 100644 --- a/ietf/static/js/edit-meeting-schedule.js +++ b/ietf/static/js/edit-meeting-schedule.js @@ -50,6 +50,7 @@ $(function () { let sessionPurposeInputs = schedEditor.find('.session-purpose-toggles input'); let timeSlotGroupInputs = schedEditor.find("#timeslot-group-toggles-modal .modal-body .individual-timeslots input"); let sessionParentInputs = schedEditor.find(".session-parent-toggles input"); + let sessionParentToggleAll = schedEditor.find(".session-parent-toggles .session-parent-toggle-all") const classes_to_hide = '.hidden-timeslot-group,.hidden-timeslot-type'; // hack to work around lack of position sticky support in old browsers, see https://caniuse.com/#feat=css-sticky @@ -312,7 +313,9 @@ $(function () { // Was this drag started by dragging a session? function isSessionDragEvent(event) { - return Boolean(event.originalEvent.dataTransfer.getData(dnd_mime_type)); + return event.originalEvent.dataTransfer.types.some( + (item_type) => item_type.indexOf(dnd_mime_type) === 0 + ); } /** @@ -324,7 +327,7 @@ $(function () { if (!isSessionDragEvent(event)) { return null; } - const sessionId = event.originalEvent.dataTransfer.getData(dnd_mime_type); + const sessionId = event.originalEvent.dataTransfer.types[0].slice(dnd_mime_type.length); const sessionElements = sessions.filter("#" + sessionId); if (sessionElements.length > 0) { return sessionElements[0]; @@ -357,7 +360,15 @@ $(function () { // dragging sessions.on("dragstart", function (event) { if (canEditSession(this)) { - event.originalEvent.dataTransfer.setData(dnd_mime_type, this.id); + /* Bit of a hack here - per the w3c drag and drop spec, the data being dragged + * and dropped are only available during dragstart and drop events. Otherwise, + * only their count and type are guaranteed to be available. (See + * https://www.w3.org/TR/2011/WD-html5-20110113/dnd.html#drag-data-store-mode) + * To work around this, append the sessionId to the dnd_mime_type in the type we + * report for our event. The event handlers can then pull it out when needed. + * (At least Chrome v106 breaks if we try to peek at the payload.) + */ + event.originalEvent.dataTransfer.setData(dnd_mime_type + this.id, this.id); jQuery(this).addClass("dragging"); selectSessionElement(this); showPastTimeslotHints(); @@ -477,13 +488,13 @@ $(function () { // Disable a particular swap modal radio input let updateSwapRadios = function (labels, radios, disableValue, datePrecision) { - labels.removeClass('text-muted'); + labels.removeClass('text-body-secondary'); radios.prop('disabled', false); radios.prop('checked', false); // disable the input requested by value let disableInput = radios.filter('[value="' + disableValue + '"]'); if (disableInput) { - disableInput.parent().addClass('text-muted'); + disableInput.parent().addClass('text-body-secondary'); disableInput.prop('disabled', true); } if (officialSchedule) { @@ -492,7 +503,7 @@ $(function () { const past_radios = radios.filter( (_, radio) => parseISOTimestamp(radio.closest('*[data-start]').dataset.start).isSameOrBefore(now, datePrecision) ); - past_radios.parent().addClass('text-muted'); + past_radios.parent().addClass('text-body-secondary'); past_radios.prop('disabled', true); } return disableInput; // return the input that was specifically disabled, if any @@ -637,12 +648,9 @@ $(function () { function updateTimeSlotDurationViolations() { timeslots.each(function () { - let total = 0; - jQuery(this).find(".session").each(function () { - total += +jQuery(this).data("duration"); - }); - - jQuery(this).toggleClass("overfull", total > +jQuery(this).data("duration")); + const sessionsInSlot = Array.from(this.getElementsByClassName('session')); + const requiredDuration = Math.max(sessionsInSlot.map(elt => Number(elt.dataset.duration))); + this.classList.toggle('overfull', requiredDuration > Number(this.dataset.duration)); }); } @@ -762,6 +770,17 @@ $(function () { sessionParentInputs.on("click", updateSessionParentToggling); updateSessionParentToggling(); + // Toggle _all_ session parents + function toggleAllSessionParents() { + if (sessionParentInputs.filter(":checked").length < sessionParentInputs.length) { + sessionParentInputs.prop("checked", true); + } else { + sessionParentInputs.prop("checked", false); + } + updateSessionParentToggling(); + } + sessionParentToggleAll.on("click", toggleAllSessionParents); + // Toggling timeslot types function updateTimeSlotTypeToggling() { const checkedTypes = jQuery.map(timeSlotTypeInputs.filter(":checked"), elt => elt.value); @@ -852,10 +871,10 @@ $(function () { .not('.hidden') .length === 0) { purpose_input.setAttribute('disabled', 'disabled'); - purpose_input.closest('.session-purpose-toggle').classList.add('text-muted'); + purpose_input.closest('.session-purpose-toggle').classList.add('text-body-secondary'); } else { purpose_input.removeAttribute('disabled'); - purpose_input.closest('.session-purpose-toggle').classList.remove('text-muted'); + purpose_input.closest('.session-purpose-toggle').classList.remove('text-body-secondary'); } }); } @@ -882,8 +901,12 @@ $(function () { * Responsible for final determination of whether a timeslot is visible, invisible, or hidden. */ function updateTimeSlotVisibility() { - timeslots.not(classes_to_hide).removeClass('hidden'); - timeslots.filter(classes_to_hide).addClass('hidden'); + const tsToShow = timeslots.not(classes_to_hide); + tsToShow.removeClass('hidden'); + tsToShow.show(); + const tsToHide = timeslots.filter(classes_to_hide); + tsToHide.addClass('hidden'); + tsToHide.hide(); } /** @@ -892,8 +915,12 @@ $(function () { * Responsible for final determination of whether a session is visible or hidden. */ function updateSessionVisibility() { - sessions.not(classes_to_hide).removeClass('hidden'); - sessions.filter(classes_to_hide).addClass('hidden'); + const sessToShow = sessions.not(classes_to_hide); + sessToShow.removeClass('hidden'); + sessToShow.show(); + const sessToHide = sessions.filter(classes_to_hide); + sessToHide.addClass('hidden'); + sessToHide.hide(); } /** @@ -1005,4 +1032,4 @@ $(function () { .on("mouseleave", ".other-session", function () { sessions.filter("#session" + this.dataset.othersessionid).removeClass("highlight"); }); -}); \ No newline at end of file +}); diff --git a/ietf/static/js/edit-milestones.js b/ietf/static/js/edit-milestones.js index 2a7e2ce2ae5..2b64900d6cc 100644 --- a/ietf/static/js/edit-milestones.js +++ b/ietf/static/js/edit-milestones.js @@ -134,6 +134,11 @@ $(document) window.setupSelect2Field($(this)); // from select2-field.js }); + new_edit_milestone.find("[data-provide='datepicker']") + .each(function () { + enable_datepicker($(this)[0]); // from datepicker.js + }); + if (!group_uses_milestone_dates) { setOrderControlValue(); } @@ -231,4 +236,4 @@ $(document) var el = document.getElementById('dragdropcontainer'); Sortable.create(el, options); } - }); \ No newline at end of file + }); diff --git a/ietf/static/js/fullcalendar.js b/ietf/static/js/fullcalendar.js index 0d58a24e70a..dfdad730e9f 100644 --- a/ietf/static/js/fullcalendar.js +++ b/ietf/static/js/fullcalendar.js @@ -1,5 +1,9 @@ import { Calendar } from '@fullcalendar/core'; import dayGridPlugin from '@fullcalendar/daygrid'; +import iCalendarPlugin from '@fullcalendar/icalendar'; +import bootstrap5Plugin from '@fullcalendar/bootstrap5'; global.FullCalendar = Calendar; -global.dayGridPlugin = dayGridPlugin; \ No newline at end of file +global.dayGridPlugin = dayGridPlugin; +global.iCalendarPlugin = iCalendarPlugin; +global.bootstrap5Plugin = bootstrap5Plugin; diff --git a/ietf/static/js/highcharts.js b/ietf/static/js/highcharts.js index f9b7aa61544..6c3b68051f0 100644 --- a/ietf/static/js/highcharts.js +++ b/ietf/static/js/highcharts.js @@ -3,11 +3,113 @@ import Highcharts from "highcharts"; import Highcharts_Exporting from "highcharts/modules/exporting"; import Highcharts_Offline_Exporting from "highcharts/modules/offline-exporting"; import Highcharts_Export_Data from "highcharts/modules/export-data"; -import Highcharts_Accessibility from"highcharts/modules/accessibility"; +import Highcharts_Accessibility from "highcharts/modules/accessibility"; +import Highcharts_Sunburst from "highcharts/modules/sunburst"; + +document.documentElement.style.setProperty("--highcharts-background-color", "transparent"); Highcharts_Exporting(Highcharts); Highcharts_Offline_Exporting(Highcharts); Highcharts_Export_Data(Highcharts); Highcharts_Accessibility(Highcharts); +Highcharts_Sunburst(Highcharts); + +Highcharts.setOptions({ + chart: { + height: "100%", + styledMode: true, + }, + credits: { + enabled: false + }, +}); window.Highcharts = Highcharts; + +window.group_stats = function (url, chart_selector) { + $.getJSON(url, function (data) { + $(chart_selector) + .each(function (_, e) { + const dataset = e.dataset.dataset; + if (!dataset) { + console.log("dataset data attribute not set"); + return; + } + const area = e.dataset.area; + if (!area) { + console.log("area data attribute not set"); + return; + } + + const chart = Highcharts.chart(e, { + title: { + text: `${dataset == "docs" ? "Documents" : "Pages"} in ${area.toUpperCase()}` + }, + series: [{ + type: "sunburst", + data: [], + tooltip: { + pointFormatter: function () { + return `There ${this.value == 1 ? "is" : "are"} ${this.value} ${dataset == "docs" ? "documents" : "pages"} in ${this.name}.`; + } + }, + dataLabels: { + formatter() { + return this.point.active ? this.point.name : `(${this.point.name})`; + } + }, + allowDrillToNode: true, + cursor: 'pointer', + levels: [{ + level: 1, + color: "transparent", + levelSize: { + value: .5 + } + }, { + level: 2, + colorByPoint: true + }, { + level: 3, + colorVariation: { + key: "brightness", + to: 0.5 + } + }] + }], + }); + + // limit data to area if set and (for now) drop docs + const slice = data.filter(d => (area == "ietf" && d.grandparent == area) || d.parent == area || d.id == area) + .map((d) => { + return { + value: d[dataset], + id: d.id, + parent: d.parent, + grandparent: d.grandparent, + active: d.active, + }; + }) + .sort((a, b) => { + if (a.parent != b.parent) { + if (a.parent < b.parent) { + return -1; + } + if (a.parent > b.parent) { + return 1; + } + } else if (a.parent == area) { + if (a.id < b.id) { + return 1; + } + if (a.id > b.id) { + return -1; + } + return 0; + } + return b.value - a.value; + }); + chart.series[0].setData(slice); + }); + }); +} diff --git a/ietf/static/js/highstock.js b/ietf/static/js/highstock.js index e1965acb625..05b1250ed0c 100644 --- a/ietf/static/js/highstock.js +++ b/ietf/static/js/highstock.js @@ -5,9 +5,20 @@ import Highcharts_Offline_Exporting from "highcharts/modules/offline-exporting"; import Highcharts_Export_Data from "highcharts/modules/export-data"; import Highcharts_Accessibility from"highcharts/modules/accessibility"; +document.documentElement.style.setProperty("--highcharts-background-color", "transparent"); + Highcharts_Exporting(Highcharts); Highcharts_Offline_Exporting(Highcharts); Highcharts_Export_Data(Highcharts); Highcharts_Accessibility(Highcharts); +Highcharts.setOptions({ + chart: { + styledMode: true, + }, + credits: { + enabled: false + }, +}); + window.Highcharts = Highcharts; diff --git a/ietf/static/js/ietf.js b/ietf/static/js/ietf.js index 8d93823cd75..09fa324e42c 100644 --- a/ietf/static/js/ietf.js +++ b/ietf/static/js/ietf.js @@ -13,7 +13,7 @@ import "bootstrap/js/dist/scrollspy"; import "bootstrap/js/dist/tab"; // import "bootstrap/js/dist/toast"; import "bootstrap/js/dist/tooltip"; - +import { debounce } from 'lodash-es'; import jquery from "jquery"; window.$ = window.jQuery = jquery; @@ -24,7 +24,7 @@ if (!process.env.BUILD_DEPLOY) { import Cookies from "js-cookie"; -import debounce from "lodash/debounce"; +import { populate_nav } from "./nav.js"; // setup CSRF protection using jQuery function csrfSafeMethod(method) { @@ -44,7 +44,7 @@ jQuery.ajaxSetup({ // Use the Bootstrap tooltip plugin for all elements with a title attribute $(document) .ready(function () { - $('[title][title!=""]') + $("[title]:not([title=''])") .tooltip(); }); @@ -57,7 +57,7 @@ $(document) var text = $(this) .text(); // insert some at strategic places - var newtext = text.replace(/([@._])/g, "$1"); + var newtext = text.replace(/(\S)([@._+])(\S)/g, "$1$2$3"); if (newtext === text) { return; } @@ -91,20 +91,57 @@ $(document) // }); }); -$(document) - .ready(function () { +function overflowShadows(el) { + function handleScroll(){ + const canScrollUp = el.scrollTop > 0 + const canScrollDown = el.offsetHeight + el.scrollTop < el.scrollHeight + el.classList.toggle("overflow-shadows--both", canScrollUp && canScrollDown) + el.classList.toggle("overflow-shadows--top-only", canScrollUp && !canScrollDown) + el.classList.toggle("overflow-shadows--bottom-only", !canScrollUp && canScrollDown) + } - function dropdown_hover(e) { - var navbar = $(this) - .closest(".navbar"); - if (navbar.length === 0 || navbar.find(".navbar-toggler") - .is(":hidden")) { - $(this) - .children(".dropdown-toggle") - .dropdown(e.type == "mouseenter" ? "show" : "hide"); - } + el.addEventListener("scroll", handleScroll, {passive: true}) + handleScroll() + + const observer = new IntersectionObserver(handleScroll) + observer.observe(el) // el won't have scrollTop etc when hidden, so we need to recalculate when it's revealed + + return () => { + el.removeEventListener("scroll", handleScroll) + observer.unobserve(el) + } +} + +function ensureDropdownOnscreen(elm) { + const handlePlacement = () => { + if(!(elm instanceof HTMLElement)) { + return + } + const rect = elm.getBoundingClientRect() + const BUFFER_PX = 5 // additional distance from bottom of viewport + const existingStyleTop = parseInt(elm.style.top, 10) + const offscreenBy = Math.round(window.innerHeight - (rect.top + rect.height) - BUFFER_PX) + if(existingStyleTop === offscreenBy) { + console.log(`Already set top to ${offscreenBy}. Ignoring`) + // already set, nothing to do + return } + if(offscreenBy < 0) { + elm.style.top = `${offscreenBy}px` + } + } + + const debouncedHandler = debounce(handlePlacement, 100) + + const observer = new MutationObserver(debouncedHandler) + + observer.observe(elm, { + attributes: true + }) +} +$(document) + .ready(function () { // load data for the menu $.ajax({ url: $(document.body) @@ -120,7 +157,7 @@ $(document) } attachTo.find(".dropdown-menu") .remove(); - var menu = ['

    diff --git a/ietf/templates/base.html b/ietf/templates/base.html index 1ccef06c9b0..b0df04f30a3 100644 --- a/ietf/templates/base.html +++ b/ietf/templates/base.html @@ -1,4 +1,4 @@ -{# Copyright The IETF Trust 2015-2022, All Rights Reserved #} +{# Copyright The IETF Trust 2015-2023, All Rights Reserved #} {% load analytical %} {% load ietf_filters static %} @@ -6,7 +6,7 @@ {% origin %} {% load django_bootstrap5 %} {% load django_vite %} - + {% analytical_head_top %} @@ -15,56 +15,69 @@ {% block title %}No title{% endblock %} - {% comment Halloween %} - - {% endcomment %} - - - + + + + {# load this in the head, to prevent flickering #} + {% vite_hmr_client %} {% block pagehead %}{% endblock %} + {% vite_asset 'client/embedded.js' %} {% include "base/icons.html" %} {% analytical_head_bottom %} - {% analytical_body_top %} + {% include "base/status.html" %} Skip to main content -

    +
    +
    + {% if html and request.COOKIES.htmlconf != 'txt' %} +
    +
    + {{ html|safe }} +
    + {% else %} +
    +
    + + {{ doc.htmlized|default:"Generation of htmlized text failed"|safe }} +
    + {% endif %} +
    + +
    + {% analytical_body_bottom %} + + diff --git a/ietf/templates/doc/document_info.html b/ietf/templates/doc/document_info.html new file mode 100644 index 00000000000..1666c42ae51 --- /dev/null +++ b/ietf/templates/doc/document_info.html @@ -0,0 +1,438 @@ +{# Copyright The IETF Trust 2016-2023, All Rights Reserved #} +{% load origin %} +{% load static %} +{% load ietf_filters %} +{% load person_filters %} +{% load document_type_badge %} +{% origin %} + + + + Document + {% if document_html %}Document type{% else %}Type{% endif %} + + + {% document_type_badge doc snapshot submission resurrected_by %} + {% if doc.type_id == "rfc" %} + {% if doc.pub_date %} + {% if document_html %}
    {% else %}({% endif %}{{ doc.pub_date|date:"F Y" }}{% if not document_html %}){% endif %} + {% else %} + (Publication date unknown) + {% endif %} + {% if document_html %}
    {% endif %} + {% if has_verified_errata or has_errata %} + + {% if document_html %}View errata{% else %}Errata{% endif %} + + {% endif %} + {% if document_html and doc.type_id == "rfc" %} + + Report errata + + {% endif %} + {% if doc.related_ipr %} + IPR + {% endif %} + {% if obsoleted_by %}
    Obsoleted by {{ obsoleted_by|urlize_related_source_list:document_html|join:", " }}
    {% endif %} + {% if updated_by %}
    Updated by {{ updated_by|urlize_related_source_list:document_html|join:", " }}
    {% endif %} + {% if obsoletes %}
    Obsoletes {{ obsoletes|urlize_related_target_list:document_html|join:", " }}
    {% endif %} + {% if updates %}
    Updates {{ updates|urlize_related_target_list:document_html|join:", " }}
    {% endif %} + {% if status_changes %} +
    Status changed by {{ status_changes|urlize_related_source_list|join:", " }}
    + {% endif %} + {% if proposed_status_changes %} +
    Proposed status changed by {{ proposed_status_changes|urlize_related_source_list|join:", " }}
    + {% endif %} + {% if doc.came_from_draft %} +
    + Was + {{ doc.came_from_draft.name }} + {% if submission %}({{ submission|safe }}){% endif %} +
    + {% endif %} + {% endif %} + {% if doc.get_state_slug != "active" and doc.get_state_slug != "rfc" and doc.type_id != "rfc" %} +
    + Expired & archived +
    + {% endif %} + {% if document_html %} + {% include "doc/disclaimer.html" with document_html=document_html %} + {% endif %} + + + {% if document_html %} + + + Select version + + + {% include "doc/revisions_list.html" with document_html=document_html %} + + + {% if diff_revisions|length > 1 %} + + + Compare versions + + + {% include "doc/document_history_form.html" with doc=doc diff_revisions=diff_revisions action=rfcdiff_base_url document_html=document_html snapshot=snapshot only %} + + + {% endif %} + {% endif %} + + + Author{% if doc.pk %}{{ doc.author_persons_or_names|pluralize }}{% endif %} + + {% if can_edit_authors %} + Edit + {% endif %} + + + {# Implementation that uses the current primary email for each author #} + {% if doc.pk %}{% for author in doc.author_persons_or_names %} + {% if author.person %}{% person_link author.person titlepage_name=author.titlepage_name %}{% else %}{{ author.titlepage_name }}{% endif %}{% if not forloop.last %},{% endif %} + {% endfor %}{% endif %} + {% if document_html and not snapshot or document_html and doc.rev == latest_rev%} +
    + Email authors + {% endif %} + + + {% if not document_html %} + {# FIXME: This shows the date of the last history event, which is not what participants necessarily expect here. #} + + + Last updated + + + {{ doc.time|date:"Y-m-d" }} + {% if latest_revision and latest_revision.time|date:"Y-m-d" != doc.time|date:"Y-m-d" %} + (Latest revision {{ latest_revision.time|date:"Y-m-d" }}) + {% endif %} + + + {% endif %} + {% if doc.type_id != "rfc" %} + {% if replaces or not document_html and can_edit_stream_info %} + + + Replaces + + {% if can_edit_stream_info and not snapshot %} + Edit + {% endif %} + + + {% if replaces %} + {% if document_html %} + {{ replaces|urlize_related_target_list:document_html|join:"
    " }} + {% else %} + {{ replaces|urlize_related_target_list:document_html|join:", " }} + {% endif %} + {% else %} + (None) + {% endif %} + + + {% endif %} + {% if replaced_by %} + + + + Replaced by + + + + + {% if document_html %} + {{ replaced_by|urlize_related_source_list:document_html|join:"
    " }} + {% else %} + {{ replaced_by|urlize_related_source_list:document_html|join:", " }} + {% endif %} + + + {% endif %} + {% if can_view_possibly_replaces %} + {% if possibly_replaces %} + + + + Possibly Replaces + + + {% if can_edit_replaces and not snapshot %} + + Edit + + {% endif %} + + + {% if document_html %} + {{ possibly_replaces|urlize_related_target_list:document_html|join:"
    " }} + {% else %} + {{ possibly_replaces|urlize_related_target_list:document_html|join:", " }} + {% endif %} + + + {% endif %} + {% if possibly_replaced_by %} + + + + Possibly Replaced By + + + {% if can_edit_replaces and not snapshot %} + {% comment %}Edit{% endcomment %} + {% endif %} + + + {% if document_html %} + {{ possibly_replaced_by|urlize_related_source_list:document_html|join:"
    " }} + {% else %} + {{ possibly_replaced_by|urlize_related_source_list:document_html|join:", " }} + {% endif %} + + + {% endif %} + {% endif %} + {% endif %} + + + + RFC stream + + + {% if can_change_stream and not snapshot %} + + Edit + + {% endif %} + + + {% if doc.stream is not None %} + {% if doc.stream.name|lower in 'iab,irtf,ise,editorial' %} + + {% endif %} + {% if document_html %} + {% if doc.stream.name|lower in 'iab,ietf,irtf' %} + {% include "logo.html" with org=doc.stream.name|lower classes="w-25 mt-1" title=stream_desc nor=True only %} + {% else %} + {{ doc.stream.desc }} + {% endif %} + {% else %} + {{ doc.stream.desc }} + {% endif %} + {% if doc.stream.name|lower in 'iab,irtf,ise,editorial' %} + + {% endif %} + {% else %} + (None) + {% endif %} + + + {% if doc.type_id != "rfc" and not snapshot %} + + + + Intended RFC status + + + {% if can_edit_stream_info and not snapshot %} + + Edit + + {% endif %} + + + {% if doc.intended_std_level %} + {{ doc.intended_std_level }} + {% else %} + + (None) + + {% endif %} + + + {% endif %} + + + + {% if document_html %}Other formats{% else %}Formats{% endif %} + + + + + {% if document_html %} + {% include "doc/document_format_buttons.html" with skip_format="htmlized" %} + {% else %} + {% include "doc/document_format_buttons.html" %} + {% endif %} + + + {% if not document_html %} + {% for check in doc.submission.latest_checks %} + {% if check.passed != None and check.symbol.strip %} + + + + {{ check.checker|title }} + + + + + {% if check.errors or check.warnings %} + + {{ check.symbol|safe }} + + {% else %} + + {{ check.symbol|safe }} + + {% endif %} + + {{ check.errors }} errors, {{ check.warnings }} warnings + + {% include "doc/yang-check-modal-overlay.html" %} + + + {% endif %} + {% endfor %} + {% if doc.type_id != "rfc" %}{# do not show reviews or conflict_reviews for RFCs, even if present #} + {% if review_assignments or can_request_review %} + + + + Reviews + + + + + {% for review_assignment in review_assignments %} + {% include "doc/review_assignment_summary.html" with current_doc_name=doc.name current_rev=doc.rev review_assignment=review_assignment only %} + {% endfor %} + {% for review_request in review_requests %} + {% include "doc/review_request_summary.html" with review_request=review_request only %} + {% endfor %} + {% if no_review_from_teams %} + {% for team in no_review_from_teams %} + {{ team.acronym.upper }}{% if not forloop.last %},{% endif %} + {% endfor %} + will not review this version + {% endif %} + {% if can_request_review or can_submit_unsolicited_review_for_teams %} +
    + {% if can_request_review %} + + + + Request review + + {% endif %} + {% if can_submit_unsolicited_review_for_teams|length == 1 %} + + + + Submit unsolicited review + + {% elif can_submit_unsolicited_review_for_teams %} + + + + Submit unsolicited review + + {% endif %} +
    + {% endif %} + + + {% endif %} + {% if conflict_reviews %} + + + + IETF conflict review + + + + + {{ conflict_reviews|join:", "|urlize_ietf_docs }} + + + {% endif %} + {% endif %} + {% endif %} + {% with doc.docextresource_set.all as resources %} + {% if resources or doc.group and doc.group.list_archive or can_edit_stream_info or can_edit_individual %} + + + + + Additional resources + + + {% if can_edit_stream_info or can_edit_individual %} + + Edit + + {% endif %} + + + {% if resources or doc.group and doc.group.list_archive %} + {% for resource in resources|dictsort:"display_name" %} + {% if resource.name.type.slug == 'url' or resource.name.type.slug == 'email' %} + + {% firstof resource.display_name resource.name.name %} + +
    + {# Maybe make how a resource displays itself a method on the class so templates aren't doing this switching #} + {% else %} + + {% firstof resource.display_name resource.name.name %}: {{ resource.value|escape }} + +
    + {% endif %} + {% endfor %} + {% if doc.group and doc.group.list_archive %} + {% if doc.group.list_archive|startswith:settings.MAILING_LIST_ARCHIVE_URL %} + + Mailing list discussion + + {% elif doc.group.list_archive|is_valid_url %} + + Mailing list discussion + + {% else %} + {{ doc.group.list_archive|urlencode }} + {% endif %} + {% endif %} + {% endif %} + + + {% endif %} + {% endwith %} + \ No newline at end of file diff --git a/ietf/templates/doc/document_material.html b/ietf/templates/doc/document_material.html index f05a478f6df..cf6dd1ab647 100644 --- a/ietf/templates/doc/document_material.html +++ b/ietf/templates/doc/document_material.html @@ -2,13 +2,13 @@ {# Copyright The IETF Trust 2015, All Rights Reserved #} {% load origin %} {% load static %} -{% load ietf_filters textfilters %} +{% load ietf_filters textfilters tz %} {% block title %}{{ doc.title|default:"Untitled" }}{% endblock %} {% block content %} {% origin %} {{ top|safe }} {% include "doc/revisions_list.html" %} -
    +
    {% if doc.rev != latest_rev %}
    The information below is for an old version of the document.
    {% endif %} @@ -19,16 +19,34 @@ {% if doc.meeting_related %}Meeting{% endif %} {{ doc.type.name }} - + {% if doc.group %} {{ doc.group.name }} ({{ doc.group.acronym }}) {{ doc.group.type.name }} {% endif %} - {% if snapshot %}Snapshot{% endif %} + {% if snapshot %}Snapshot{% endif %} + {% if doc.meeting_related %} + + + Date and time + + + + {% with session=doc.get_related_session %} + {% with timeslot=session.official_timeslotassignment.timeslot %} + {% if session.meeting %} + {{ timeslot.time|utc|date:'Y-m-d H:i' }} + {% include "meeting/tz-display.html" with meeting_timezone=session.meeting.time_zone id_suffix="" minimal=True only %} + {% endif %} + {% endwith %} + {% endwith %} + + + {% endif %} Title @@ -36,7 +54,7 @@ {% doc_edit_button 'ietf.doc.views_material.edit_material' name=doc.name action="title" %} {% endif %} - {{ doc.title|default:'(None)' }} + {{ doc.title|default:'(None)' }} {% if doc.abstract or doc.type_id == 'slides' and can_manage_material and not snapshot %} @@ -60,7 +78,7 @@ {% if doc.get_state.name %} {{ doc.get_state.name }} {% else %} - (None) + (None) {% endif %} @@ -97,10 +115,24 @@ {% if presentations %} {% for pres in presentations %} {{ pres.session.short_name }} at {{ pres.session.meeting }} - {% if pres.rev != doc.rev %}(version -{{ pres.rev }}){% endif %}{% if not forloop.last %},{% endif %} + {% if pres.rev != doc.rev %}(version -{{ pres.rev }}){% endif %} +
    + Remote instructions: + {% if pres.session.agenda_note|first_url|conference_url %} + + + + {% elif pres.session.remote_instructions|first_url|conference_url %} + + + + {% endif %} + {{ pres.session.remote_instructions|linkify }} + {% if not forloop.last %}
    {% endif %} {% endfor %} {% else %} - (None) + (None) {% endif %} @@ -121,9 +153,12 @@ {% endif %}

    + {% if session_statusid == "canceled" %} +
    The session for this document was cancelled.
    + {% endif %}
    {{ doc.name }}-{{ doc.rev }}
    -
    +
    {% if doc.rev and content != None %} {% if content_is_html %} {{ content|sanitize|safe }} @@ -142,4 +177,16 @@ {% block js %} + {% if doc.meeting_related %} + + + + + {% endif %} {% endblock %} \ No newline at end of file diff --git a/ietf/templates/doc/document_polls.html b/ietf/templates/doc/document_polls.html new file mode 100644 index 00000000000..06ddc31b0b2 --- /dev/null +++ b/ietf/templates/doc/document_polls.html @@ -0,0 +1,64 @@ +{% extends "base.html" %} +{# Copyright The IETF Trust 2022, All Rights Reserved #} +{% load origin %} +{% load static %} +{% load ietf_filters textfilters %} +{% block title %}{{ doc.title|default:"Untitled" }}{% endblock %} +{% block content %} + {% origin %} + {{ top|safe }} + {% include "doc/revisions_list.html" %} +
    + {% if doc.rev != latest_rev %} +
    The information below is for an old version of the document.
    + {% endif %} + + + + + + + + + + + + + + + + + + + + + + + + +
    + {% if doc.meeting_related %}Meeting{% endif %} + {{ doc.type.name }} + + {% if doc.group %} + {{ doc.group.name }} + ({{ doc.group.acronym }}) + {{ doc.group.type.name }} + {% endif %} + {% if snapshot %}Snapshot{% endif %} +
    Title{{ doc.title|default:'(None)' }}
    Session + + Materials +
    Last updated{{ doc.time|date:"Y-m-d" }}
    +
    +
    {{ doc.name }}-{{ doc.rev }}
    +
    + +
    Loading...
    +
    +
    +{% endblock %} +{% block js %} + + +{% endblock %} \ No newline at end of file diff --git a/ietf/templates/doc/document_referenced_by.html b/ietf/templates/doc/document_referenced_by.html index 30d536d79f2..e1137768b71 100644 --- a/ietf/templates/doc/document_referenced_by.html +++ b/ietf/templates/doc/document_referenced_by.html @@ -1,13 +1,13 @@ {% extends "base.html" %} -{# Copyright The IETF Trust 2015, All Rights Reserved #} +{# Copyright The IETF Trust 2015-2023, All Rights Reserved #} {% load origin static ietf_filters %} {% block pagehead %} {% endblock %} -{% block title %}References to {{ alias_name }}{% endblock %} +{% block title %}References to {{ name|prettystdname }}{% endblock %} {% block content %} {% origin %} -

    References to {{ alias_name }}

    +

    References to {{ name|prettystdname }}

    These dependencies are extracted using heuristics looking for strings with particular prefixes. Notably, this means that references to I-Ds by title only are not reflected here. If it's really important, please inspect the documents' references sections directly.

    @@ -38,33 +38,33 @@

    References to {{ alias_name }}

    {% for ref in refs %} - {% with ref.source.canonical_name as name %} + {% with ref.source.name as src_name %} - {{ name|prettystdname }} - {% if ref.target.name != alias_name %} + {{ src_name|prettystdname }} + {% if ref.target.name != name %}
    - As {{ ref.target.name }} + As {{ ref.target.name }} {% endif %} {{ ref.source.title }}
    References Referenced by - {% ifequal ref.source.get_state.slug 'rfc' %} + {% if ref.source.type_id == "rfc" %} {% with ref.source.std_level as lvl %} {% if lvl %}{{ lvl }}{% endif %} {% endwith %} @@ -72,7 +72,7 @@

    References to {{ alias_name }}

    {% with ref.source.intended_std_level as lvl %} {% if lvl %}{{ lvl }}{% endif %} {% endwith %} - {% endifequal %} + {% endif %} {{ ref.relationship.name }} {{ ref.is_downref|default:'' }} diff --git a/ietf/templates/doc/document_references.html b/ietf/templates/doc/document_references.html index 4578d6b8cec..8725b759c25 100644 --- a/ietf/templates/doc/document_references.html +++ b/ietf/templates/doc/document_references.html @@ -1,13 +1,13 @@ {% extends "base.html" %} -{# Copyright The IETF Trust 2015, All Rights Reserved #} +{# Copyright The IETF Trust 2015-2023, All Rights Reserved #} {% load origin static ietf_filters %} {% block pagehead %} {% endblock %} -{% block title %}References from {{ doc.canonical_name }}{% endblock %} +{% block title %}References from {{ doc.name|prettystdname }}{% endblock %} {% block content %} {% origin %} -

    References from {{ doc.canonical_name }}

    +

    References from {{ doc.name|prettystdname }}

    These dependencies are extracted using heuristics looking for strings with particular prefixes. Notably, this means that references to I-Ds by title only are not reflected here. If it's really important, please inspect the documents' references sections directly.

    @@ -35,7 +35,7 @@

    References from {{ doc.canonical_name }}

    {{ name|prettystdname }} - {{ ref.target.document.title }} + {{ ref.target.title }}
    References from {{ doc.canonical_name }} - {% ifequal ref.target.document.get_state.slug 'rfc' %} - {% with ref.target.document.std_level as lvl %} + {% if ref.target.type_id == "rfc" %} + {% with ref.target.std_level as lvl %} {% if lvl %}{{ lvl }}{% endif %} {% endwith %} {% else %} - {% with ref.target.document.intended_std_level as lvl %} + {% with ref.target.intended_std_level as lvl %} {% if lvl %}{{ lvl }}{% endif %} {% endwith %} - {% endifequal %} + {% endif %} {{ ref.relationship.name }} {{ ref.is_downref|default:'' }} diff --git a/ietf/templates/doc/document_review.html b/ietf/templates/doc/document_review.html index 113c407fe59..feb30ae93a2 100644 --- a/ietf/templates/doc/document_review.html +++ b/ietf/templates/doc/document_review.html @@ -29,7 +29,7 @@ {% if doc.get_state.name %} {{ doc.get_state.name }} {% else %} - (None) + (None) {% endif %} diff --git a/ietf/templates/doc/document_rfc.html b/ietf/templates/doc/document_rfc.html new file mode 100644 index 00000000000..d4b309a9645 --- /dev/null +++ b/ietf/templates/doc/document_rfc.html @@ -0,0 +1,188 @@ +{% extends "base.html" %} +{# Copyright The IETF Trust 2016-2024, All Rights Reserved #} +{% load origin %} +{% load static %} +{% load ietf_filters %} +{% load person_filters %} +{% load textfilters %} +{% block html_attrs %}prefix="og: http://ogp.me/ns# article: http://ogp.me/ns/article#"{% endblock %} +{% block pagehead %} + {% include "doc/opengraph.html" %} + + +{% endblock %} +{% block morecss %}.inline { display: inline; }{% endblock %} +{% block title %} + RFC {{ doc.rfc_number }} - {{ doc.title }} +{% endblock %} +{% block content %} + {% origin %} + {{ top|safe }} + {% include "doc/disclaimer.html" with document_html=document_html %} +
    + + {% include "doc/document_info.html" %} + + + {% if doc.stream_id != 'iab' %} + + + + + + + + + + + + + + + {% endif %} +
    + IESG + + Responsible AD + + {% if can_edit %} + + Edit + + {% endif %} + + {% if doc.ad %} + {% person_link doc.ad %} + {% else %} + + (None) + + {% endif %} +
    + Send notices to + + {% if can_edit_notify %} + + Edit + + {% endif %} + + {% if doc.notify %} + {{ doc.notify|linkify }} + {% else %} + + (None) + + {% endif %} +
    +
    + {% if mailto_name %} + + + + Email authors + + {% endif %} + {% if doc.group.type_id == "wg" or doc.group.type_id == "rg" %} + + + + Email {{ doc.group.type }} + + {% endif %} + + + + IPR + {% if doc.related_ipr %} + + {{ doc.related_ipr|length }} + + {% endif %} + + + + + References + + + + + Referenced by + + {% if doc.rfc_number >= settings.FIRST_V3_RFC %} + + + + Get editor source + + {% endif %} + + Search Lists + + {% if user.is_authenticated %} + + + + Untrack + + + + + Track + + {% endif %} + {% if actions %} + {% for label, url in actions %} + + {{ label|capfirst_allcaps }} + + {% endfor %} + {% endif %} +
    +
    +
    + RFC {{ doc.rfc_number }} +
    +
    +
    {{ content|sanitize|safe|default:"(Unavailable)" }}
    +
    +
    + {% if split_content %} + + + + Show full document + + {% endif %} + + {% endblock %} + {% block js %} + + + {% endblock %} diff --git a/ietf/templates/doc/document_statement.html b/ietf/templates/doc/document_statement.html new file mode 100644 index 00000000000..cc3ea5a44c4 --- /dev/null +++ b/ietf/templates/doc/document_statement.html @@ -0,0 +1,139 @@ +{% extends "base.html" %} +{# Copyright The IETF Trust 2023-2025, All Rights Reserved #} +{% load origin %} +{% load static %} +{% load ietf_filters %} +{% load person_filters textfilters %} +{% block title %}{{ doc.title }}{% endblock %} +{% block content %} + {% origin %} + {{ top|safe }} + {% include "doc/revisions_list.html" %} +
    + {% if doc.rev != latest_rev %} +
    The information below is for an older version of this statement.
    + {% endif %} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {% with doc.docextresource_set.all as resources %} + {% if resources or can_manage %} + + + + + + + {% endif %} + {% endwith %} + + + + + + + +
    DocumentType + {% if doc.get_state.slug != "active" %}{{doc.get_state.name}} {% endif %}{% if doc.group %}{{doc.group.acronym|upper}} {%endif%}Statement + {% if snapshot %}Snapshot{% endif %} + {% if replaced_by %}
    Replaced by {{ replaced_by|urlize_related_source_list:False|join:", " }}
    {% endif %} + {% if replaces %}
    Replaces {{ replaces|urlize_related_target_list:False|join:", " }}
    {% endif %} +
    Title{{ doc.title }}
    Published{{ published|date:"Y-m-d" }}
    Metadata last updated{{ doc.time|date:"Y-m-d" }}
    + State + {% if can_manage %} + + Edit + + {% endif %} + {% if doc.get_state %} + {{ doc.get_state.name }} + {% else %} + No document state + {% endif %} +
    Additional resources + {% if can_manage %} + Edit + {% endif %} + + {% if resources %} + {% for resource in resources|dictsort:"display_name" %} + {% if resource.name.type.slug == 'url' or resource.name.type.slug == 'email' %} + + {% firstof resource.display_name resource.name.name %} + +
    + {# Maybe make how a resource displays itself a method on the class so templates aren't doing this switching #} + {% else %} + {% firstof resource.display_name resource.name.name %}: {{ resource.value|escape }} +
    + {% endif %} + {% endfor %} + {% endif %} +
    + Send notices to + + {% if not snapshot %} + {% if can_manage %} + {% doc_edit_button 'ietf.doc.views_doc.edit_notify' name=doc.name %} + {% endif %} + {% endif %} + + {{ doc.notify|default:'(None)' }} +
    + {% if not snapshot %} + {% if request.user|has_role:"Secretariat" %} +

    + + Edit or upload revised statement text + +

    + {% endif %} +{% endif %} + +
    +
    + {{ doc.name }}-{{ doc.rev }} +
    +
    + {{ content }} +
    +
    +{% endblock %} +{% block js %} + + +{% endblock %} \ No newline at end of file diff --git a/ietf/templates/doc/document_status_change.html b/ietf/templates/doc/document_status_change.html index 7926fec8ec8..fdb9bab4cda 100644 --- a/ietf/templates/doc/document_status_change.html +++ b/ietf/templates/doc/document_status_change.html @@ -10,7 +10,7 @@ {% origin %} {{ top|safe }} {% include "doc/revisions_list.html" %} -
    +
    {% if doc.rev != latest_rev %}
    The information below is for an old version of the document.
    {% endif %} @@ -35,7 +35,7 @@ {{ doc.title }} - {% if snapshot %}Snapshot{% endif %} + {% if snapshot %}Snapshot{% endif %} @@ -52,7 +52,7 @@ {% for rel in relation_group.list %} - {{ rel.target.document.canonical_name|upper|urlize_ietf_docs }}{% if not forloop.last %},{% endif %} + {{ rel.target.name|upper|urlize_ietf_docs }}{% if not forloop.last %},{% endif %} {% endfor %} @@ -89,7 +89,7 @@ {% if not telechat %} - (None) + (None) {% else %} On agenda of {{ telechat.telechat_date|date:"Y-m-d" }} IESG telechat {% if doc.returning_item %}(returning item){% endif %} diff --git a/ietf/templates/doc/document_subseries.html b/ietf/templates/doc/document_subseries.html new file mode 100644 index 00000000000..f0273c9093d --- /dev/null +++ b/ietf/templates/doc/document_subseries.html @@ -0,0 +1,30 @@ +{% extends "base.html" %} +{# Copyright The IETF Trust 2023, All Rights Reserved #} +{% load origin %} +{% load static %} +{% load ietf_filters %} +{% block title %}{{ doc.name|prettystdname }}{% endblock %} +{% block content %} + {% origin %} + {{ top|safe }} +

    {{ doc.name|prettystdname }} {% if doc.contains %}consists of:{% else %}currently contains no RFCs{% endif %}

    + {% for rfc in doc.contains|dictsort:"rfc_number" %} +

    RFC {{rfc.name|slice:"3:"}} : {{rfc.title}}

    + {% endfor %} + +{% endblock %} diff --git a/ietf/templates/doc/document_subseries_top.html b/ietf/templates/doc/document_subseries_top.html new file mode 100644 index 00000000000..742ea51372b --- /dev/null +++ b/ietf/templates/doc/document_subseries_top.html @@ -0,0 +1,17 @@ +{# Copyright The IETF Trust 2015, All Rights Reserved #} +{% load origin %} +{% origin %} +{% load ietf_filters %} +

    + {{ doc.name|prettystdname }} +

    + diff --git a/ietf/templates/doc/document_top.html b/ietf/templates/doc/document_top.html index 1fa2c22c2a9..8a6923ee739 100644 --- a/ietf/templates/doc/document_top.html +++ b/ietf/templates/doc/document_top.html @@ -5,7 +5,9 @@

    {{ doc.title|default:"(Untitled)" }}
    - {{ name }} + {{ name }}{% if doc.part_of %} + {% for sub in doc.part_of %}{% if sub.contains|length_is:"1" %} also known as {% else %} part of {% endif %}{{sub.name|slice:":3"|upper}} {{sub.name|slice:"3:"}}{% if not forloop.last %}, {%endif%}{% endfor %} + {% endif %}

    + href="{% url "ietf.doc.views_doc.document_main" name=doc.name %}"> Back diff --git a/ietf/templates/doc/edit_authors.html b/ietf/templates/doc/edit_authors.html index ed28855e405..a0b8eb4cc70 100644 --- a/ietf/templates/doc/edit_authors.html +++ b/ietf/templates/doc/edit_authors.html @@ -12,7 +12,7 @@

    Edit authors
    - {{ titletext }} + {{ titletext }}

    {% csrf_token %} @@ -48,7 +48,7 @@

    + href="{% url "ietf.doc.views_doc.document_main" name=doc.name %}"> Back diff --git a/ietf/templates/doc/edit_field.html b/ietf/templates/doc/edit_field.html index d1f4d96411e..10a14645816 100644 --- a/ietf/templates/doc/edit_field.html +++ b/ietf/templates/doc/edit_field.html @@ -2,13 +2,13 @@ {# Copyright The IETF Trust 2015, All Rights Reserved #} {% load origin %} {% load django_bootstrap5 %} -{% block title %}{{ title }} {{ doc.canonical_name }}{% endblock %} +{% block title %}{{ title }} {{ doc.name }}{% endblock %} {% block content %} {% origin %}

    {{ title }}
    - {{ doc.canonical_name }} + {{ doc.name }}

    {{ info|safe }} @@ -18,7 +18,7 @@

    {% bootstrap_form form %} + href="{% url "ietf.doc.views_doc.document_main" name=doc.name %}"> Back diff --git a/ietf/templates/doc/edit_notify.html b/ietf/templates/doc/edit_notify.html index 6701c58523c..9eaede521b5 100644 --- a/ietf/templates/doc/edit_notify.html +++ b/ietf/templates/doc/edit_notify.html @@ -8,7 +8,7 @@

    Edit notification addresses
    - {{ titletext }} + {{ titletext }}

    {% csrf_token %} @@ -22,7 +22,7 @@

    name="regenerate_addresses"> Regenerate address list + href="{% url "ietf.doc.views_doc.document_main" name=doc.name %}"> Back diff --git a/ietf/templates/doc/edit_sessionpresentation.html b/ietf/templates/doc/edit_sessionpresentation.html index 79508b7836f..5cc8e2f566d 100644 --- a/ietf/templates/doc/edit_sessionpresentation.html +++ b/ietf/templates/doc/edit_sessionpresentation.html @@ -8,7 +8,7 @@

    Change document revision for session
    - {{ sp.document.name }} + {{ sp.document.name }}

    {{ sp.document.title }} at {{ sp.session }}

    {% if sp.session.is_material_submission_cutoff %} diff --git a/ietf/templates/doc/edit_telechat_date.html b/ietf/templates/doc/edit_telechat_date.html index b95b38936da..f3efc80144c 100644 --- a/ietf/templates/doc/edit_telechat_date.html +++ b/ietf/templates/doc/edit_telechat_date.html @@ -8,7 +8,7 @@

    Set telechat date
    - {{ doc.name }} ({{ doc.pages }} page{{ doc.pages|pluralize }}) + {{ doc.name }} ({{ doc.pages }} page{{ doc.pages|pluralize }})

    {% for warning in warnings %}
    {{ warning }}
    {% endfor %}
    diff --git a/ietf/templates/doc/email_aliases.html b/ietf/templates/doc/email_aliases.html index 3311f2e28e2..111d31b0ba3 100644 --- a/ietf/templates/doc/email_aliases.html +++ b/ietf/templates/doc/email_aliases.html @@ -3,13 +3,11 @@ {% load origin %} {% block title %} Document email aliases - {% if doc %}for {{ doc.name }}{% endif %} {% endblock %} {% block content %} {% origin %}

    Document email aliases - {% if doc %}for {{ doc.name }}{% endif %}

    {% regroup aliases|dictsort:"doc_name" by doc_name as alias_list %} diff --git a/ietf/templates/doc/frontpage.html b/ietf/templates/doc/frontpage.html index 38575aab457..b845c2628f2 100644 --- a/ietf/templates/doc/frontpage.html +++ b/ietf/templates/doc/frontpage.html @@ -11,9 +11,9 @@
    - + {% if server_mode != "production" %}

    Datatracker – {{ server_mode|capfirst }} Mode

    {% else %} diff --git a/ietf/templates/doc/htmlized_base.html b/ietf/templates/doc/htmlized_base.html deleted file mode 100644 index e3624c0dfd2..00000000000 --- a/ietf/templates/doc/htmlized_base.html +++ /dev/null @@ -1,139 +0,0 @@ - -{% load ietf_filters static %} -{# Copyright The IETF Trust 2021, All Rights Reserved #} -{% load origin %} -{% origin %} - - - - - - {% block title %}No title{% endblock %} - - - - {% block pagehead %}{% endblock %} - {% include "base/icons.html" %} - - -
    - {% block content %}{{ content|safe }}{% endblock %} - {% block content_end %}{% endblock %} -
    - {% block footer %}{% endblock %} - {% block js %}{% endblock %} - - \ No newline at end of file diff --git a/ietf/templates/doc/idnits2-state.txt b/ietf/templates/doc/idnits2-state.txt index 7706549797d..55fc78927a3 100644 --- a/ietf/templates/doc/idnits2-state.txt +++ b/ietf/templates/doc/idnits2-state.txt @@ -1,7 +1,7 @@ {% load ietf_filters %}{% filter linebreaks_lf %}{% comment %} -{% endcomment %}Doc-tag: {{doc.name}};datatracker{% if doc.rfcnum %} -Doc-rfcnum: {{doc.rfcnum}}{% endif %} +{% endcomment %}Doc-tag: {{doc.name}};datatracker{% if doc.type_id == "rfc" %} +Doc-rfcnum: {{doc.rfc_number}}{% endif %} Doc-created: {{doc.created|date:"Y-m-d"}};datatracker{% if doc.deststatus %} Doc-deststatus: {{doc.deststatus}};datatracker{% endif %} Doc-rev: {{doc.rev}};datatracker -{% endfilter %} \ No newline at end of file +{% endfilter %} diff --git a/ietf/templates/doc/index_active_drafts.html b/ietf/templates/doc/index_active_drafts.html index 8d561b1c7e5..607385f56fd 100644 --- a/ietf/templates/doc/index_active_drafts.html +++ b/ietf/templates/doc/index_active_drafts.html @@ -5,7 +5,7 @@ {% load cache %} {% block title %}Active Internet-Drafts{% endblock %} {% block content %} - {% cache 900 ietf_doc_index_active_drafts %} + {% cache 900 ietf_doc_index_active_drafts using="slowpages" %} {% origin %}

    Active Internet-Drafts

    @@ -29,7 +29,7 @@

    Active Internet-Drafts

    {% for group in groups %}

    {{ group.name }} ({{ group.acronym }})

    - {% for d in group.active_drafts %} + {% for d in group.active_drafts %}{# n.b., d is a dict, not a Document #}
    {{ d.title }}. diff --git a/ietf/templates/doc/index_subseries.html b/ietf/templates/doc/index_subseries.html new file mode 100644 index 00000000000..3180a4535dc --- /dev/null +++ b/ietf/templates/doc/index_subseries.html @@ -0,0 +1,21 @@ +{% extends "base.html" %} +{# Copyright The IETF Trust 2023, All Rights Reserved #} +{% load origin %} +{% load static ietf_filters %} +{% block title %}{{type.name}}s{% endblock %} +{% block content %} + {% origin %} +

    {{type.name}}s

    + {% for doc in docs %} +
    + +
    + {% for rfc in doc.contains|dictsort:"rfc_number" %} +

    {{rfc.name|prettystdname}} : {{rfc.title}}

    + {% empty %} +

    {{doc.name|prettystdname}} currently contains no RFCs + {% endfor %} +

    +
    + {% endfor %} +{% endblock %} \ No newline at end of file diff --git a/ietf/templates/doc/investigate.html b/ietf/templates/doc/investigate.html new file mode 100644 index 00000000000..8b613117d5c --- /dev/null +++ b/ietf/templates/doc/investigate.html @@ -0,0 +1,129 @@ +{% extends "base.html" %} +{# Copyright The IETF Trust 2024, All Rights Reserved #} +{% load django_bootstrap5 ietf_filters origin static %} +{% block title %}Investigate{% endblock %} +{% block pagehead %} + +{% endblock %} +{% block content %} + {% origin %} +

    Investigate

    +
    + + {% csrf_token %} + {% bootstrap_form form %} + +
    + Please be patient, processing may take several minutes. +
    + +
    + {% if results %} +
    + {% if results.can_verify %} +

    These can be authenticated

    +
    + + + + + + + + + + {% for path in results.can_verify %} + {% with url=path|url_for_path %} + + + + + + + {% endwith %} + {% endfor %} + +
    NameLast Modified OnLinkSource
    {{ path.name }} + {% if path|mtime_is_epoch %} + Timestamp has been lost (is Unix Epoch) + {% else %} + {{ path|mtime|date:"DATETIME_FORMAT" }} + {% endif %} + {{ url }}{{ path }}
    + {% else %} +

    Nothing with this name fragment can be authenticated

    + {% endif %} +
    + {% if results.unverifiable_collections %} +

    These are in the archive, but cannot be authenticated

    + + + + + + + + + + + {% for path in results.unverifiable_collections %} + {% with url=path|url_for_path %} + + + + + + + {% endwith %} + {% endfor %} + +
    NameLast Modified OnLinkSource
    {{ path.name }} + {% if path|mtime_is_epoch %} + Timestamp has been lost (is Unix Epoch) + {% else %} + {{ path|mtime|date:"DATETIME_FORMAT" }} + {% endif %} + {{ url }}{{ path }}
    + {% endif %} + {% if results.unexpected %} +

    These are unexpected and we do not know what their origin is. These cannot be authenticated

    + + + + + + + + + + {% for path in results.unexpected %} + {% with url=path|url_for_path %} + + + + + + {% endwith %} + {% endfor %} + +
    NameLast Modified OnLink
    {{ path.name }} + {% if path|mtime_is_epoch %} + Timestamp has been lost (is Unix Epoch) + {% else %} + {{ path|mtime|date:"DATETIME_FORMAT" }} + {% endif %} + {{ url }}
    + {% endif %} +
    + {% endif %} +{% endblock %} +{% block js %} + + +{% endblock %} \ No newline at end of file diff --git a/ietf/templates/doc/irsg_ballot_status.html b/ietf/templates/doc/irsg_ballot_status.html index 017866eb255..f295b968c09 100644 --- a/ietf/templates/doc/irsg_ballot_status.html +++ b/ietf/templates/doc/irsg_ballot_status.html @@ -10,24 +10,28 @@ {% block content %} {% origin %}

    IRSG ballot status

    - - - - - - - - {% if docs %} - - {% for doc in docs %} - - - {% include "doc/search/status_columns.html" %} - - {% endfor %} - - {% endif %} -
    DocumentStatus
    {{ doc.displayname_with_link }}
    + {% if docs %} + + + + + + + + + {% for doc in docs %} + + + {% include "doc/search/status_columns.html" %} + + {% endfor %} + +
    DocumentStatus
    {{ doc.displayname_with_link }}
    + {% else %} +

    + No open IRSG ballots. +

    + {% endif %} {% endblock %} {% block js %} diff --git a/ietf/templates/doc/mail/ballot_writeup.txt b/ietf/templates/doc/mail/ballot_writeup.txt index c808e5a4a70..74871e5a861 100644 --- a/ietf/templates/doc/mail/ballot_writeup.txt +++ b/ietf/templates/doc/mail/ballot_writeup.txt @@ -1,11 +1,12 @@ -{% autoescape off %} -Technical Summary - +{% load ietf_filters %}{% autoescape off %}Technical Summary +{% if doc.abstract %} +{{ doc.abstract.rstrip }} +{% else %} Relevant content can frequently be found in the abstract and/or introduction of the document. If not, this may be an indication that there are deficiencies in the abstract or introduction. - +{% endif %} Working Group Summary Was there anything in the WG process that is worth noting? @@ -26,23 +27,14 @@ Document Quality Review, on what date was the request posted? Personnel - +{% if doc.shepherd and doc.ad %}{% filter wordwrap:"76" %} + The Document Shepherd for this document is {{ doc.shepherd.person.name }}. The Responsible Area Director is {{ doc.ad.name }}.{% endfilter %} +{% else %} Who is the Document Shepherd for this document? Who is the - Responsible Area Director? If the document requires IANA - experts(s), insert 'The IANA Expert(s) for the registries - in this document are .' - -IRTF Note - - (Insert IRTF Note here or remove section) - -IESG Note - - (Insert IESG Note here or remove section) - + Responsible Area Director? +{% endif %} IANA Note {% if iana %} - {% load ietf_filters %}{% filter wordwrap:"76"|indent:2 %}{{ iana }}{% endfilter %} + {% filter wordwrap:"76"|indent:2 %}{{ iana }}{% endfilter %} {% endif %} - (Insert IANA Note here or remove section) -{% endautoescape%} + (Insert IANA Note here or remove section){% endautoescape%} diff --git a/ietf/templates/doc/mail/close_rsab_ballot_mail.txt b/ietf/templates/doc/mail/close_rsab_ballot_mail.txt new file mode 100644 index 00000000000..10d5c55d4e2 --- /dev/null +++ b/ietf/templates/doc/mail/close_rsab_ballot_mail.txt @@ -0,0 +1,3 @@ +{% load ietf_filters %}{% load mail_filters %}{% autoescape off %} {% filter wordwrap:78 %}The RSAB ballot for {{ doc.file_tag }} has been closed. The evaluation for this document can be found at {{ doc_url }}{% endfilter %} + +{% endautoescape%} diff --git a/ietf/templates/doc/mail/issue_rsab_ballot_mail.txt b/ietf/templates/doc/mail/issue_rsab_ballot_mail.txt new file mode 100644 index 00000000000..302fcad8ee5 --- /dev/null +++ b/ietf/templates/doc/mail/issue_rsab_ballot_mail.txt @@ -0,0 +1,6 @@ +{% load ietf_filters %}{% load mail_filters %}{% autoescape off %}{% filter wordwrap:78 %}Evaluation for {{ doc.file_tag }} can be found at {{ doc_url }} + +{% endfilter %} +{% filter wordwrap:78 %}{{ needed_ballot_positions }}{% endfilter %} + +{% endautoescape%} diff --git a/ietf/templates/doc/mail/last_call_announcement.txt b/ietf/templates/doc/mail/last_call_announcement.txt index 79abcc1488a..5cf2e9c45b5 100644 --- a/ietf/templates/doc/mail/last_call_announcement.txt +++ b/ietf/templates/doc/mail/last_call_announcement.txt @@ -33,7 +33,7 @@ No IPR declarations have been submitted directly on this I-D. {% if downrefs %} The document contains these normative downward references. See RFC 3967 for additional information: -{% for ref in downrefs %} {{ref.target.document.canonical_name}}: {{ref.target.document.title}} ({{ref.target.document.std_level}} - {{ref.target.document.stream.desc}}) +{% for ref in downrefs %} {{ref.target.name}}: {{ref.target.title}} ({{ref.target.std_level}} - {{ref.target.stream.desc}} stream) {% endfor %}{%endif%} {% endautoescape %} diff --git a/ietf/templates/doc/mail/resurrect_completed_email.txt b/ietf/templates/doc/mail/resurrect_completed_email.txt index 7b5e52be5bd..18e3d3dfa8d 100644 --- a/ietf/templates/doc/mail/resurrect_completed_email.txt +++ b/ietf/templates/doc/mail/resurrect_completed_email.txt @@ -1,4 +1,4 @@ -{% autoescape off %}As you requsted, the Internet Draft {{ doc.file_tag }} +{% autoescape off %}As you requested, the Internet-Draft {{ doc.file_tag }} has been resurrected. Datatracker URL: {{ url }} diff --git a/ietf/templates/doc/mail/wg_call_for_adoption_issued.txt b/ietf/templates/doc/mail/wg_call_for_adoption_issued.txt new file mode 100644 index 00000000000..15ace9495b2 --- /dev/null +++ b/ietf/templates/doc/mail/wg_call_for_adoption_issued.txt @@ -0,0 +1,31 @@ +{% load ietf_filters %}{% load mail_filters %}{% autoescape off %}{% filter wordwrap:78 %}This message starts a {{group.acronym}} WG Call for Adoption of: +{{ doc.name }}-{{ doc.rev }} + + +This Working Group Call for Adoption ends on {{ end_date }} + +Abstract: +{{ doc.abstract }} + +Please reply to this message and indicate whether or not you support adoption of this Internet-Draft by the {{group.acronym}} WG. Comments to explain your preference are greatly appreciated. Please reply to all recipients of this message and include this message in your response. + +Authors, and WG participants in general, are reminded of the Intellectual Property Rights (IPR) disclosure obligations described in BCP 79 [2]. Appropriate IPR disclosures required for full conformance with the provisions of BCP 78 [1] and BCP 79 [2] must be filed, if you are aware of any. Sanctions available for application to violators of IETF IPR Policy can be found at [3]. + +Thank you. +[1] https://datatracker.ietf.org/doc/bcp78/ +[2] https://datatracker.ietf.org/doc/bcp79/ +[3] https://datatracker.ietf.org/doc/rfc6701/ + +The IETF datatracker status page for this Internet-Draft is: +{{ settings.IDTRACKER_BASE_URL }}{% url 'ietf.doc.views_doc.document_main' name=doc.name %} +{% if doc.submission.xml_version == "3" %} +There is also an HTML version available at: +{{ settings.IETF_ID_ARCHIVE_URL }}{{ doc.name }}-{{ doc.rev }}.html{% else %} +There is also an HTMLized version available at: +{{ settings.IDTRACKER_BASE_URL }}{% url 'ietf.doc.views_doc.document_html' name=doc.name rev=doc.rev %}{% endif %} +{% if doc.rev != "00" %} +A diff from the previous version is available at: +{{settings.RFCDIFF_BASE_URL}}?url2={{ doc.name }}-{{ doc.rev }} +{% endif %} +{% endfilter %} +{% endautoescape %} diff --git a/ietf/templates/doc/mail/wg_last_call_issued.txt b/ietf/templates/doc/mail/wg_last_call_issued.txt new file mode 100644 index 00000000000..114f8bc5e22 --- /dev/null +++ b/ietf/templates/doc/mail/wg_last_call_issued.txt @@ -0,0 +1,34 @@ +{% load ietf_filters %}{% load mail_filters %}{% autoescape off %}{% filter wordwrap:78 %}This message starts a WG Last Call for: +{{ doc.name }}-{{ doc.rev }} + +This Working Group Last Call ends on {{ end_date }} + +Abstract: +{{ doc.abstract }} + +File can be retrieved from: +{{ url }} + +Please review and indicate your support or objection to proceed with the publication of this document by replying to this email keeping {{ wg_list }} in copy. Objections should be explained and suggestions to resolve them are highly appreciated. + +Authors, and WG participants in general, are reminded of the Intellectual Property Rights (IPR) disclosure obligations described in BCP 79 [1]. Appropriate IPR disclosures required for full conformance with the provisions of BCP 78 [1] and BCP 79 [2] must be filed, if you are aware of any. Sanctions available for application to violators of IETF IPR Policy can be found at [3]. + +Thank you. + +[1] https://datatracker.ietf.org/doc/bcp78/ +[2] https://datatracker.ietf.org/doc/bcp79/ +[3] https://datatracker.ietf.org/doc/rfc6701/ + +The IETF datatracker status page for this Internet-Draft is: +{{ settings.IDTRACKER_BASE_URL }}{% url 'ietf.doc.views_doc.document_main' name=doc.name %} +{% if doc.submission.xml_version == "3" %} +There is also an HTML version available at: +{{ settings.IETF_ID_ARCHIVE_URL }}{{ doc.name }}-{{ doc.rev }}.html{% else %} +There is also an HTMLized version available at: +{{ settings.IDTRACKER_BASE_URL }}{% url 'ietf.doc.views_doc.document_html' name=doc.name rev=doc.rev %}{% endif %} +{% if doc.rev != "00" %} +A diff from the previous version is available at: +{{settings.RFCDIFF_BASE_URL}}?url2={{ doc.name }}-{{ doc.rev }} +{% endif %} +{% endfilter %} +{% endautoescape %} diff --git a/ietf/templates/doc/material/all_presentations.html b/ietf/templates/doc/material/all_presentations.html index 4c0a8d698e9..b5ea1f3718e 100644 --- a/ietf/templates/doc/material/all_presentations.html +++ b/ietf/templates/doc/material/all_presentations.html @@ -10,7 +10,7 @@

    Sessions linked to
    - {{ doc.name }} + {{ doc.name }}

    {% if user|has_role:"Secretariat,Area Director,WG Chair,WG Secretary,RG Chair,RG Secretary,IRTF Chair,Team Chair" %}
    diff --git a/ietf/templates/doc/material/choose_material_type.html b/ietf/templates/doc/material/choose_material_type.html index 041209bc6bc..f76fcd83044 100644 --- a/ietf/templates/doc/material/choose_material_type.html +++ b/ietf/templates/doc/material/choose_material_type.html @@ -8,7 +8,7 @@

    Upload Material
    - {{ group.name }} ({{ group.acronym }}) + {{ group.name }} ({{ group.acronym }})

    Select what kind of material you wish to upload: diff --git a/ietf/templates/doc/material/edit_material.html b/ietf/templates/doc/material/edit_material.html index 1d64baf532a..a613bc1e0ba 100644 --- a/ietf/templates/doc/material/edit_material.html +++ b/ietf/templates/doc/material/edit_material.html @@ -25,7 +25,7 @@

    {% endif %} {{ material_type|lower }}
    - + {% if group is not None %} {{ group.name }} ({{ group.acronym }}) {% elif doc.meeting_related %} diff --git a/ietf/templates/doc/notprepped_wrapper.html b/ietf/templates/doc/notprepped_wrapper.html new file mode 100644 index 00000000000..078db7bc51a --- /dev/null +++ b/ietf/templates/doc/notprepped_wrapper.html @@ -0,0 +1,26 @@ +{% extends "base.html" %} +{# Copyright The IETF Trust 2026, All Rights Reserved #} +{% load origin %} +{% block title %}RFC {{ rfc.rfc_number }} — Not-prepped XML{% endblock %} +{% block content %} + {% origin %} +

    RFC {{ rfc.rfc_number }} — Not-prepped XML

    +

    + The not-prepped XML + is the RFC XML v3 source for an RFC at the moment in the publication process + just before the prep tool was used to expand default + values, generate section numbers, resolve cross-references, and embed + boilerplate. +

    + It is useful for authors who want to begin a new draft based on + the RFC's text, such as when creating a bis-draft, and for tools that process + author-facing RFC XML. +

    +

    + + + Download not-prepped XML for RFC {{ rfc.rfc_number }} + +

    +{% endblock %} diff --git a/ietf/templates/doc/opengraph.html b/ietf/templates/doc/opengraph.html index be5646f8001..1c8c5abe912 100644 --- a/ietf/templates/doc/opengraph.html +++ b/ietf/templates/doc/opengraph.html @@ -1,16 +1,16 @@ -{# Copyright The IETF Trust 2016-2020, All Rights Reserved #} +{# Copyright The IETF Trust 2016-2025, All Rights Reserved #} {% load origin %} {% load static %} {% load ietf_filters %} {% origin %} - + {% if doc.stream.slug == "ietf" or doc.name|startswith:"draft-ietf" %} - + @@ -18,7 +18,7 @@ {% elif doc.stream.slug == "irtf" or doc.name|startswith:"draft-irtf" %} - + @@ -26,7 +26,7 @@ {% elif doc.stream.slug == "iab" or doc.name|startswith:"draft-iab" %} - + @@ -36,7 +36,7 @@ {% else %}{# TODO: We need a card image for individual I-Ds. #} {% endif %} -{% for author in doc.documentauthor_set.all %} -{% endfor %} +{% if doc.pk %}{% for author_name in doc.author_names %} +{% endfor %}{% endif %} {% if published %}{% endif %} {% if expires %}{% endif %} \ No newline at end of file diff --git a/ietf/templates/doc/recent_drafts.html b/ietf/templates/doc/recent_drafts.html index 339bb3d3c49..9674ba8b661 100644 --- a/ietf/templates/doc/recent_drafts.html +++ b/ietf/templates/doc/recent_drafts.html @@ -13,7 +13,7 @@

    Internet-Drafts submitted during the last {{ days|default:7 }} days {% if pages %}
    - {{ pages }} pages + {{ pages }} pages {% endif %}

    {% include "doc/search/search_results.html" with start_table=True end_table=True %} diff --git a/ietf/templates/doc/remind_action_holders.html b/ietf/templates/doc/remind_action_holders.html index be6a4ed46da..0e7ce9d5ce8 100644 --- a/ietf/templates/doc/remind_action_holders.html +++ b/ietf/templates/doc/remind_action_holders.html @@ -10,7 +10,7 @@

    Send reminder to action holder{{ doc.action_holders.all|pluralize }}
    - {{ titletext }} + {{ titletext }}

    {% csrf_token %} @@ -27,7 +27,7 @@

    name="submit" value="Send reminder">Send + href="{% url "ietf.doc.views_doc.document_main" name=doc.name %}"> Back diff --git a/ietf/templates/doc/remove_sessionpresentation.html b/ietf/templates/doc/remove_sessionpresentation.html index 79bda98b78e..b519b73b360 100644 --- a/ietf/templates/doc/remove_sessionpresentation.html +++ b/ietf/templates/doc/remove_sessionpresentation.html @@ -8,7 +8,7 @@

    Confirm removing from session
    - {{ sp.document.name }} + {{ sp.document.name }}

    {% if sp.session.is_material_submission_cutoff %}

    diff --git a/ietf/templates/doc/review/assign_reviewer.html b/ietf/templates/doc/review/assign_reviewer.html index c4aca8d0f02..a5c7c6622fc 100644 --- a/ietf/templates/doc/review/assign_reviewer.html +++ b/ietf/templates/doc/review/assign_reviewer.html @@ -7,7 +7,7 @@

    Assign reviewer
    - {{ review_req.doc.name }} + {{ review_req.doc.name }}

    {% include "doc/review/request_info.html" %}
    @@ -15,7 +15,7 @@

    {% bootstrap_form form %} + href="{% url "ietf.doc.views_review.review_request" name=doc.name request_id=review_req.pk %}"> Back diff --git a/ietf/templates/doc/review/close_request.html b/ietf/templates/doc/review/close_request.html index cf0a6d09082..4e0f4359119 100644 --- a/ietf/templates/doc/review/close_request.html +++ b/ietf/templates/doc/review/close_request.html @@ -7,7 +7,7 @@

    Close review request
    - {{ review_req.doc.name }} + {{ review_req.doc.name }}

    {% include "doc/review/request_info.html" %}

    @@ -18,7 +18,7 @@

    {% bootstrap_form form %} + href="{% url "ietf.doc.views_review.review_request" name=doc.name request_id=review_req.pk %}"> Back diff --git a/ietf/templates/doc/review/complete_review.html b/ietf/templates/doc/review/complete_review.html index 561aa8ca092..8aeb1486a4c 100644 --- a/ietf/templates/doc/review/complete_review.html +++ b/ietf/templates/doc/review/complete_review.html @@ -1,5 +1,5 @@ {% extends "base.html" %} -{# Copyright The IETF Trust 2016, All Rights Reserved #} +{# Copyright The IETF Trust 2016-2024, All Rights Reserved #} {% load origin django_bootstrap5 static person_filters textfilters %} {% block title %} {% if revising_review %} @@ -26,7 +26,7 @@

    {% endif %} review
    - {{ doc.name }} + {{ doc.name }}

    {% if assignment %} @@ -66,9 +66,7 @@

    If you enter the review below, the review will be sent - to {{ review_to|join:", "|linkify }} - {% if review_cc %}, with a CC to {{ review_cc|join:", "|linkify }}{% endif %} - . + to {% for addr in review_to %}{{ addr|linkify }}{% if not forloop.last %}, {% endif %}{% endfor %}{% if review_cc %}, with a CC to {% for addr in review_cc %}{{ addr|linkify }}{% if not forloop.last %}, {% endif %}{% endfor %}{% endif %}.

    {% elif assignment %}

    @@ -88,21 +86,27 @@

    {% if assignment %} + href="{% url "ietf.doc.views_review.review_request" name=doc.name request_id=assignment.review_request.pk %}"> Back {% else %} Back {% endif %}
    - {% if mail_archive_query_urls %} -

    @@ -27,7 +27,7 @@ No specific revision {% endif %} {% if review_req.reviewed_rev != review_req.doc.rev %} - (document currently at {{ review_req.doc.rev }}) + (document currently at {{ review_req.doc.rev }}) {% endif %} @@ -74,13 +74,13 @@ {% endif %} - {% if review_req.doc.authors %} + {% if review_req.doc.author_persons_or_names %} @@ -96,15 +96,18 @@ {% endif %} - {% if doc.time %} + {% if review_req.doc.time %} {% endif %} @@ -177,6 +180,8 @@
    {% if assignment.state_id == "assigned" %} Assignment not accepted yet + {% elif assignment.state_id == "rejected" %} + Assignment rejected {% else %} Assignment accepted {% endif %} @@ -217,17 +222,29 @@ State
    - {% if assignment.state_id != "withdrawn" and assignment.state_id != "no-response" and assignment.state_id != "rejected" %} + {% if doc == assignment.review %} + + + + + + {% endif %} + {% if assignment.state_id != "withdrawn" and assignment.state_id != "no-response" and assignment.state_id != "rejected" and doc != assignment.review%} @@ -312,8 +329,8 @@ - {% endif %} @@ -339,4 +356,4 @@ Assign reviewer -{% endif %} \ No newline at end of file +{% endif %} diff --git a/ietf/templates/doc/review/request_review.html b/ietf/templates/doc/review/request_review.html index 220ca4fe904..b765871d65d 100644 --- a/ietf/templates/doc/review/request_review.html +++ b/ietf/templates/doc/review/request_review.html @@ -11,7 +11,7 @@

    Request review
    - {{ doc.name }} + {{ doc.name }}

    Submit a request to have the document reviewed. @@ -44,7 +44,7 @@

    {% bootstrap_field form.comment layout="horizontal" %} + href="{% url "ietf.doc.views_doc.document_main" name=doc.name %}"> Back diff --git a/ietf/templates/doc/review/review_request.html b/ietf/templates/doc/review/review_request.html index 6ae15b08a3c..85335aab6e8 100644 --- a/ietf/templates/doc/review/review_request.html +++ b/ietf/templates/doc/review/review_request.html @@ -10,7 +10,7 @@

    Review request
    - {{ review_req.doc.name }} + {{ review_req.doc.name }}

    {% include "doc/review/request_info.html" %} {% if can_close_request %} @@ -21,6 +21,15 @@

    {% endif %}

    History

    + {% if can_add_comment %} + + {% endif %}
    {% person_link review_req.requested_by %}
    Authors - {% for author in review_req.doc.authors %} - {% person_link author %}{% if not forloop.last %},{% endif %} + {% for person, tp_name in review_req.doc.author_persons_or_names %} + {% if person %}{% person_link person %}{% else %}{{ tp_name }}{% endif %}{% if not forloop.last %},{% endif %} {% endfor %}
    - Draft last updated + I-D last updated - {{ doc.time|date:"Y-m-d" }} + {{ review_req.doc.time|date:"Y-m-d" }} + {% if review_req.doc.pub_date %} + (Latest revision {{ review_req.doc.pub_date|date:"Y-m-d" }}) + {% endif %}
    - - {{ assignment.state.name }} - + {{ assignment.state.name|badgeify }} {% if snapshot %} - + Snapshot {% endif %}
    + + Request + + + {{ review_req }} + +
    Result - {{ assignment.result.name }} + + {{ assignment.result.name|badgeify }}
    @@ -30,6 +39,7 @@

    History

    + {% for h in history %} {% if h.history_change_reason %} @@ -39,6 +49,7 @@

    History

    {% endif %} {% endfor %} +
    Description

    {% endblock %} diff --git a/ietf/templates/doc/review/review_wish_add.html b/ietf/templates/doc/review/review_wish_add.html index bd2df52ce8b..73ce549288a 100644 --- a/ietf/templates/doc/review/review_wish_add.html +++ b/ietf/templates/doc/review/review_wish_add.html @@ -7,7 +7,7 @@

    Add review wish
    - {{ doc.name }} + {{ doc.name }}

    You are a reviewer for multiple teams, and need to select a team first. diff --git a/ietf/templates/doc/review/review_wishes_remove.html b/ietf/templates/doc/review/review_wishes_remove.html index aadf3c5deb6..ee30c3cfcc6 100644 --- a/ietf/templates/doc/review/review_wishes_remove.html +++ b/ietf/templates/doc/review/review_wishes_remove.html @@ -8,7 +8,7 @@

    Remove review wish {% if doc.name %}
    - {{ doc.name }} + {{ doc.name }} {% endif %}

    diff --git a/ietf/templates/doc/review/submit_unsolicited_review.html b/ietf/templates/doc/review/submit_unsolicited_review.html index 3f52c2bc755..5db7e9cd62c 100644 --- a/ietf/templates/doc/review/submit_unsolicited_review.html +++ b/ietf/templates/doc/review/submit_unsolicited_review.html @@ -7,7 +7,7 @@

    Submit unsolicited review
    - {{ doc.name }} + {{ doc.name }}

    You are submitting an unsolicited review for this document. @@ -18,7 +18,7 @@

    {% bootstrap_form form layout="horizontal" %} + href="{% url "ietf.doc.views_doc.document_main" name=doc.name %}"> Back diff --git a/ietf/templates/doc/review/withdraw_reviewer_assignment.html b/ietf/templates/doc/review/withdraw_reviewer_assignment.html index 6ff1f926b29..aed48ba78b4 100644 --- a/ietf/templates/doc/review/withdraw_reviewer_assignment.html +++ b/ietf/templates/doc/review/withdraw_reviewer_assignment.html @@ -7,7 +7,7 @@

    Withdraw review assignment
    - {{ assignment.review_request.doc.name }} + {{ assignment.review_request.doc.name }}

    Withdraw review assignment for {% person_link assignment.reviewer.person %}. @@ -16,7 +16,7 @@

    {% csrf_token %} + href="{% url "ietf.doc.views_review.review_request" name=assignment.review_request.doc.name request_id=assignment.review_request.pk %}"> Back diff --git a/ietf/templates/doc/review_assignment_summary.html b/ietf/templates/doc/review_assignment_summary.html index 29781fcad9a..6bb42ea074e 100644 --- a/ietf/templates/doc/review_assignment_summary.html +++ b/ietf/templates/doc/review_assignment_summary.html @@ -1,3 +1,4 @@ +{% load ietf_filters %}
    {% if review_assignment.state_id == "completed" or review_assignment.state_id == "part-completed" %} @@ -7,21 +8,20 @@ {% if review_assignment.review_request.doc.name != current_doc_name %} {{ review_assignment.review_request.doc.name }} {% endif %} - -{{ review_assignment.reviewed_rev }}){% endif %} + -{{ review_assignment.reviewed_rev }}){% endif %} + by {{ review_assignment.reviewer.person.plain_name }} {% if review_assignment.state_id == "part-completed" %} - Partially completed + Partially completed {% endif %} {% if review_assignment.result %} - - {{ review_assignment.result.name }} - + {{ review_assignment.result.name|badgeify }} {% endif %} {% else %} - - {{ review_assignment.review_request.team.acronym|upper }} {{ review_assignment.review_request.type.name }} Review - - Incomplete, due {{ review_assignment.review_request.deadline|date:"Y-m-d" }} + {{ review_assignment.review_request.team.acronym|upper }} {{ review_assignment.review_request.type.name }} Review due {{ review_assignment.review_request.deadline|date:"Y-m-d" }} + + Incomplete {% endif %}
    \ No newline at end of file diff --git a/ietf/templates/doc/review_request_summary.html b/ietf/templates/doc/review_request_summary.html new file mode 100644 index 00000000000..af4f2d5f7b6 --- /dev/null +++ b/ietf/templates/doc/review_request_summary.html @@ -0,0 +1,9 @@ + \ No newline at end of file diff --git a/ietf/templates/doc/revisions_list.html b/ietf/templates/doc/revisions_list.html index 04b12ed091a..761d4cd04b3 100644 --- a/ietf/templates/doc/revisions_list.html +++ b/ietf/templates/doc/revisions_list.html @@ -1,21 +1,53 @@ {# Copyright The IETF Trust 2015, All Rights Reserved #} -{% load origin %} +{% load origin ietf_filters %} {% origin %} - - +{% endif %} \ No newline at end of file diff --git a/ietf/templates/doc/rsab_ballot_status.html b/ietf/templates/doc/rsab_ballot_status.html new file mode 100755 index 00000000000..c3c183014fe --- /dev/null +++ b/ietf/templates/doc/rsab_ballot_status.html @@ -0,0 +1,38 @@ +{% extends "base.html" %} +{# Copyright The IETF Trust 2023, All Rights Reserved #} +{% load origin static %} +{% load ballot_icon %} +{% load ietf_filters %} +{% block pagehead %} + +{% endblock %} +{% block title %}RSAB ballot status{% endblock %} +{% block content %} + {% origin %} +

    RSAB ballot status

    + {% if docs %} + + + + + + + + + {% for doc in docs %} + + + {% include "doc/search/status_columns.html" %} + + {% endfor %} + +
    DocumentStatus
    {{ doc.displayname_with_link }}
    + {% else %} +

    + No open RSAB ballots. +

    + {% endif %} +{% endblock %} +{% block js %} + +{% endblock %} \ No newline at end of file diff --git a/ietf/templates/doc/search/search_form.html b/ietf/templates/doc/search/search_form.html index 1f40e5a5254..d4f463ec663 100644 --- a/ietf/templates/doc/search/search_form.html +++ b/ietf/templates/doc/search/search_form.html @@ -6,7 +6,6 @@
    - {% csrf_token %}
    {{ form.name|add_class:"form-control"|attr:"placeholder:Document name/title/RFC number"|attr:"aria-label:Document name/title/RFC number" }} @@ -180,5 +179,5 @@

    Search page for www.ietf.org website - Search page for IETF mail list archives + Search page for IETF mail list archives

    \ No newline at end of file diff --git a/ietf/templates/doc/search/search_result_row.html b/ietf/templates/doc/search/search_result_row.html index 8767f2a52a6..cb50a1b214e 100644 --- a/ietf/templates/doc/search/search_result_row.html +++ b/ietf/templates/doc/search/search_result_row.html @@ -7,30 +7,30 @@ {% load person_filters %} {% load django_bootstrap5 %} - + {% if user.is_authenticated %} - + aria-label="Remove from your personal I-D list" + title="Remove from your personal I-D list"> - + aria-label="Add to your personal I-D list" + title="Add to your personal I-D list">
    {% endif %} - {% if user.review_teams %} + {% if user.person.review_teams %} - @@ -45,17 +45,17 @@ {% endfor %} - - {% if doc.pages %}{{ doc.pages }} page{{ doc.pages|pluralize }}{% endif %} + + {% if doc.pages %}{{ doc.pages }} page{{ doc.pages|pluralize }}{% endif %}
    - {% if doc.get_state_slug == "rfc" %} + {% if doc.type_id == "rfc" %} RFC {{ doc.rfc_number }} {% else %} {{ doc.name }}-{{ doc.rev }} {% endif %} - {% if doc.get_state_slug == "rfc" and "draft" in doc.name %}(was {{ doc.name }}){% endif %} +{# {% if doc.type_id == "rfc" and "draft" in doc.name %}(was {{ doc.name }}){% endif %} TODO drop this or look up the corresponding draft name#}
    {% comment %}
    @@ -85,12 +85,12 @@ {% endcomment %} {{ doc.title }} {% if doc.has_verified_errata %} - Errata {% elif doc.has_errata %} - Errata @@ -105,50 +105,52 @@
    {% endif %} - - {% if doc.latest_revision_date|timesince_days|new_enough:request and doc.get_state_slug != "rfc" %} - {% if doc.rev != "00" %} - - {% elif doc.replaces %} - - {% endif %} - {% endif %} - {% if doc.get_state_slug == "rfc" %} - {{ doc.latest_revision_date|date:"Y-m" }} - {% else %} - {{ doc.latest_revision_date|date:"Y-m-d" }} - {% endif %} - {% if doc.latest_revision_date|timesince_days|new_enough:request and doc.get_state_slug != "rfc" %} - {% if doc.rev != "00" or doc.replaces %}{% endif %} - {% endif %} - {% if doc.latest_revision_date|timesince_days|new_enough:request %} -
    -
    - New -
    - {% endif %} - {% if doc.get_state_slug == "active" and doc.expirable and doc.expires|timesince_days|expires_soon:request %} -
    - Expires soon - {% endif %} - - {% include "doc/search/status_columns.html" %} - - {% if doc.related_ipr %} - - {{ doc.related_ipr|length }} - - {% endif %} - - {% if ad_name == None or ad_name != doc.ad.plain_name %} - - {% if doc.ad %} - {% person_link doc.ad title="Area Director" %} - {% endif %} -
    - {% if doc.shepherd %} - {% email_person_link doc.shepherd title="Shepherd" class="small text-muted" %} - {% endif %} - + + {% if doc.latest_revision_date|timesince_days|new_enough:request and doc.type_id != "rfc" %} + {% if doc.rev != "00" %} + + {% elif doc.replaces %} + {% with first_replaces=doc.replaces|first %} + + {% endwith %} + {% endif %} + {% endif %} + {% if doc.type_id == "rfc" %} + {{ doc.latest_revision_date|date:"Y-m" }} + {% else %} + {{ doc.latest_revision_date|date:"Y-m-d" }} + {% endif %} + {% if doc.latest_revision_date|timesince_days|new_enough:request and doc.type_id != "rfc" %} + {% if doc.rev != "00" or doc.replaces %}{% endif %} + {% endif %} + {% if doc.latest_revision_date|timesince_days|new_enough:request %} +
    +
    + New +
    + {% endif %} + {% if doc.get_state_slug == "active" and doc.expirable and doc.expires|timesince_days|expires_soon:request %} +
    + Expires soon + {% endif %} + + {% include "doc/search/status_columns.html" %} + + {% if doc.related_ipr %} + + {{ doc.related_ipr|length }} + + {% endif %} + + {% if show_ad_and_shepherd %} + + {% if doc.ad %} + {% person_link doc.ad title="Area Director" %} + {% endif %} +
    + {% if doc.shepherd %} + {% email_person_link doc.shepherd title="Shepherd" class="small text-body-secondary" %} {% endif %} - + + {% endif %} + diff --git a/ietf/templates/doc/search/search_results.html b/ietf/templates/doc/search/search_results.html index cb004627299..bd6b072f0d2 100644 --- a/ietf/templates/doc/search/search_results.html +++ b/ietf/templates/doc/search/search_results.html @@ -20,6 +20,8 @@ {% if "sort_url" in h %} @@ -53,7 +55,7 @@ {% for doc in doc_group.list %} - {% include "doc/search/search_result_row.html" %} + {% include "doc/search/search_result_row.html" with show_ad_and_shepherd=meta.show_ad_and_shepherd %} {% endfor %} {% endfor %} diff --git a/ietf/templates/doc/search/status_columns.html b/ietf/templates/doc/search/status_columns.html index 91660f1dbb5..50d70fcb379 100644 --- a/ietf/templates/doc/search/status_columns.html +++ b/ietf/templates/doc/search/status_columns.html @@ -2,18 +2,16 @@ {% load origin %} {% origin %} {% load ietf_filters ballot_icon person_filters %} - - {% if doc.ballot %} -
    {% ballot_icon doc %}
    - {% endif %} - {% if not doc.get_state_slug == "rfc" %} + +
    {% ballot_icon doc %}
    + {% if not doc.type_id == "rfc" %} {% if '::' in doc.friendly_state %} {{ doc.friendly_state|safe }} {% else %} {{ doc.friendly_state|safe }} {% endif %} {% if doc|state:"draft-rfceditor" %} - :
    {{ doc|state:"draft-rfceditor" }} + : {{ doc|state:"draft-rfceditor" }} {% endif %} {{ doc|auth48_alert_badge }} {{ doc|state_age_colored }} @@ -52,9 +50,9 @@ {% for review_assignment in doc.review_assignments %} {% if review_assignment.state_id == "completed" or review_assignment.state_id == "part-completed" %} + class="badge rounded-pill {% if review_assignment.result.name|slice:5|slugify == 'ready' %}text-bg-success{% elif review_assignment.result.name|slice:9|slugify == 'not-ready' %}text-bg-danger{% elif review_assignment.result.name|slice:10|slugify == 'has-issues' %}text-bg-warning{% else %}text-bg-info{% endif %}"> {% else %} - + {% endif %} {{ review_assignment.review_request.team.acronym }} @@ -80,16 +78,24 @@ {% person_link action_holder.person title=action_holder.role_for_doc %}{% if action_holder|action_holder_badge %} {{ action_holder|action_holder_badge }}{% endif %}{% if not forloop.last %},{% endif %} {% endfor %} {% endif %} + {% if doc|is_unexpected_wg_state %} +
    + Unexpected WG state + {% endif %} {% else %} {# RFC #} {{ doc.std_level|safe }} RFC {% if doc.obsoleted_by_list %}
    - Obsoleted by {{ doc.obsoleted_by_list|join:", "|urlize_ietf_docs }} + Obsoleted by {{ doc.obsoleted_by_list|join:", "|urlize_ietf_docs }} {% endif %} {% if doc.updated_by_list %}
    - Updated by {{ doc.updated_by_list|join:", "|urlize_ietf_docs }} + Updated by {{ doc.updated_by_list|join:", "|urlize_ietf_docs }} + {% endif %} + {% if doc.part_of %} +
    + {% for sub in doc.part_of %}{% if sub.contains|length_is:"1" %} Also known as {% else %} Part of {% endif %}
    {{sub.name|slice:":3"|upper}} {{sub.name|slice:"3:"}}{% if not forloop.last %}, {%endif%}{% endfor %}
    {% endif %} {% endif %} - + \ No newline at end of file diff --git a/ietf/templates/doc/shepherd_writeup.html b/ietf/templates/doc/shepherd_writeup.html index 8cf99aff02e..09fb179fa69 100644 --- a/ietf/templates/doc/shepherd_writeup.html +++ b/ietf/templates/doc/shepherd_writeup.html @@ -3,13 +3,13 @@ {% load origin %} {% load ietf_filters %} {% load textfilters %} -{% block title %}Shepherd writeup for {{ doc.canonical_name }}-{{ doc.rev }}{% endblock %} +{% block title %}Shepherd writeup for {{ doc.name }}{% endblock %} {% block content %} {% origin %}

    Shepherd writeup
    - {{ doc.canonical_name }}-{{ doc.rev }} + {{ doc.name }}

    {{writeup|maybewordwrap|urlize_ietf_docs|linkify}}
    {% if can_edit %} diff --git a/ietf/templates/doc/shepherd_writeup.txt b/ietf/templates/doc/shepherd_writeup.txt index 7c81ef3dd9f..b366e395711 100644 --- a/ietf/templates/doc/shepherd_writeup.txt +++ b/ietf/templates/doc/shepherd_writeup.txt @@ -1,4 +1,4 @@ -{# Keep in sync with https://github.com/ietf-chairs/chairs.ietf.org/blob/main/documents/qa-style-writeup-template.md #}{% if stream %}{% if stream == 'ietf' %}# Document Shepherd Write-Up{% if type != "individ" %} for Group Documents{% else %} for Individual Documents{% endif %} +{# For more information see https://github.com/ietf/chairs.ietf.org/blob/main/documents/document-shepherding.md #}{% if stream %}{% if stream == 'ietf' %}# Document Shepherd Write-Up{% if type != "individ" %} for Group Documents{% else %} for Individual Documents{% endif %} *This version is dated 4 July 2022.* @@ -75,7 +75,7 @@ to answer all of them. of RFC? Do all Datatracker state attributes correctly reflect this intent? 12. Have reasonable efforts been made to remind all authors of the intellectual - property rights (IPR) disclosure obligations described in [BCP 79][8]? To + property rights (IPR) disclosure obligations described in [BCP 79][7]? To the best of your knowledge, have all required disclosures been filed? If not, explain why. If yes, summarize any relevant discussion, including links to publicly-available messages when applicable. @@ -125,9 +125,9 @@ to answer all of them. [1]: https://www.ietf.org/about/groups/iesg/ [2]: https://www.rfc-editor.org/rfc/rfc4858.html [3]: https://www.rfc-editor.org/rfc/rfc7942.html -[4]: https://trac.ietf.org/trac/ops/wiki/yang-review-tools +[4]: https://wiki.ietf.org/group/ops/yang-review-tools [5]: https://www.rfc-editor.org/rfc/rfc8342.html -[6]: https://trac.ietf.org/trac/iesg/wiki/ExpertTopics +[6]: https://wiki.ietf.org/group/iesg/ExpertTopics [7]: https://www.rfc-editor.org/info/bcp79 [8]: https://www.ietf.org/tools/idnits/ [9]: https://www.rfc-editor.org/rfc/rfc3967.html diff --git a/ietf/templates/doc/state_help.html b/ietf/templates/doc/state_help.html index d7678987ac8..3a61e048996 100644 --- a/ietf/templates/doc/state_help.html +++ b/ietf/templates/doc/state_help.html @@ -1,7 +1,6 @@ {% extends "base.html" %} {# Copyright The IETF Trust 2015, All Rights Reserved #} -{% load origin %} -{% load static %} +{% load origin static ietf_filters textfilters %} {% block title %}{{ title }}{% endblock %} {% block pagehead %} @@ -15,6 +14,37 @@

    {{ title }}

    href="{% static 'ietf/images/iesg-draft-state-diagram.png' %}">View diagram

    {% endif %} + {% if queue_status_values %} +

    Queue status

    +

    + The RFC Editor state shown for a document in the publication queue is its + Status in the RFC Production Center's publication queue, matching + what is shown at + the RFC Editor publication queue. + This status is derived from the document's current editor assignments, pending + activities, blocking reasons and IANA status, so it can take the following forms. + (Processing labels such as github, markdown and + Expedited shown on the publication queue are not part of this status.) +

    + + + + + + + + + {% for value, description in queue_status_values %} + + + + + {% endfor %} + +
    StatusDescription
    {{ value }}{{ description }}
    +

    Legacy states

    +

    {{ legacy_states_note }}

    + {% endif %} @@ -27,7 +57,7 @@

    {{ title }}

    {% for state in states %} - + {% if has_next_states %} - - {% for group in teams %} - - - - - - {% endfor %} - + {% regroup teams by parent as grouped_teams %} + {% for group_entry in grouped_teams %} + + + + + {% for group in group_entry.list %} + + + + + + {% endfor %} + + {% endfor %}
    {{ state.name }}{{ state.desc|safe|linebreaksbr }}{{ state.desc|safe|urlize_ietf_docs|linkify }} {% for s in state.next_states.all %} diff --git a/ietf/templates/doc/state_index.html b/ietf/templates/doc/state_index.html new file mode 100644 index 00000000000..602d54d1c4f --- /dev/null +++ b/ietf/templates/doc/state_index.html @@ -0,0 +1,48 @@ +{% extends "base.html" %} +{# Copyright The IETF Trust 2015, All Rights Reserved #} +{% load origin static %} +{% block pagehead %} + +{% endblock %} +{% block title %}Document state index{% endblock %} +{% block content %} + {% origin %} +

    Document state index

    +

    + Document state information is available for the following document and document state groups. +

    + + + + + + + + + {% for type in types %} + {% if type.stategroups != None %} + + + + + {% endif %} + {% endfor %} + +
    DocumentState groups
    + {{ type.slug }} + + {% for group in type.stategroups %} + {# djlint:off #} + {% if type.slug == "draft" %} + + {% else %} + + {% endif %} + {{ group }}{% if not forloop.last %},{% endif %} + {# djlint:on #} + {% endfor %} +
    +{% endblock %} +{% block js %} + +{% endblock %} \ No newline at end of file diff --git a/ietf/templates/doc/statement/change_statement_state.html b/ietf/templates/doc/statement/change_statement_state.html new file mode 100644 index 00000000000..aa5cb934e84 --- /dev/null +++ b/ietf/templates/doc/statement/change_statement_state.html @@ -0,0 +1,22 @@ +{# Copyright The IETF Trust 2025, All Rights Reserved #} +{% extends "base.html" %} +{% load origin %} +{% load django_bootstrap5 %} +{% block title %}Change state for {{ statement }}{% endblock %} +{% block content %} + {% origin %} +

    + Change state +
    + {{ statement }} +

    +
    + {% csrf_token %} + {% bootstrap_form form %} + + + Back + +
    +{% endblock %} \ No newline at end of file diff --git a/ietf/templates/doc/statement/new_statement.html b/ietf/templates/doc/statement/new_statement.html new file mode 100644 index 00000000000..0742314ed19 --- /dev/null +++ b/ietf/templates/doc/statement/new_statement.html @@ -0,0 +1,18 @@ +{% extends "base.html" %} +{# Copyright The IETF Trust 2023, All Rights Reserved #} +{% load origin django_bootstrap5 static textfilters %} +{% block title %}Start a new Statement{% endblock %} +{% block content %} + {% origin %} +

    Start a new Statement

    +
    + {% csrf_token %} + {% bootstrap_form form layout="horizontal" %} + +
    +{% endblock %} +{% block js %} + +{% endblock %} \ No newline at end of file diff --git a/ietf/templates/doc/statement/statement_template.md b/ietf/templates/doc/statement/statement_template.md new file mode 100644 index 00000000000..cc311530ec5 --- /dev/null +++ b/ietf/templates/doc/statement/statement_template.md @@ -0,0 +1 @@ +Replace this with the content of the statement in markdown source diff --git a/ietf/templates/doc/statement/upload_content.html b/ietf/templates/doc/statement/upload_content.html new file mode 100644 index 00000000000..712c44043dc --- /dev/null +++ b/ietf/templates/doc/statement/upload_content.html @@ -0,0 +1,23 @@ +{% extends "base.html" %} +{# Copyright The IETF Trust 2023, All Rights Reserved #} +{% load origin django_bootstrap5 static %} +{% block title %}Upload new revision: {{ doc.name }}{% endblock %} +{% block content %} + {% origin %} +

    + Upload New Revision +
    + {{ doc.name }} +

    +
    + {% csrf_token %} + {% bootstrap_form form layout="horizontal" %} + + Back +
    +{% endblock %} +{% block js %} + +{% endblock %} \ No newline at end of file diff --git a/ietf/templates/doc/stats/highstock.html b/ietf/templates/doc/stats/highstock.html deleted file mode 100644 index d6a36f58e1f..00000000000 --- a/ietf/templates/doc/stats/highstock.html +++ /dev/null @@ -1,26 +0,0 @@ -{% extends "base.html" %} -{# Copyright The IETF Trust 2015, All Rights Reserved #} -{% load origin %} -{% load static %} -{% load ietf_filters %} -{% block js %} - - -{% endblock %} -{% block title %}Document Statistics{% endblock %} -{% block content %} - {% origin %} -
    -{% endblock %} \ No newline at end of file diff --git a/ietf/templates/doc/status_change/ad_approval_pending_email.txt b/ietf/templates/doc/status_change/ad_approval_pending_email.txt index 23ef4715547..7d132a322eb 100644 --- a/ietf/templates/doc/status_change/ad_approval_pending_email.txt +++ b/ietf/templates/doc/status_change/ad_approval_pending_email.txt @@ -1,7 +1,7 @@ {% load ietf_filters %}{% load mail_filters %}{% autoescape off %} {% filter wordwrap:78 %}The AD has approved changing the status of the following {% if related_doc_info|length == 1 %}document{% else %}documents{% endif %}: {% for relateddoc in related_doc_info %}- {{relateddoc.title }} - ({{relateddoc.canonical_name }}) to {{ relateddoc.newstatus }} + ({{relateddoc.name }}) to {{ relateddoc.newstatus }} {% endfor %} An announcement has not yet been sent. {% endfilter %} diff --git a/ietf/templates/doc/status_change/approval_text.txt b/ietf/templates/doc/status_change/approval_text.txt index bf722dccee3..e2bbe3bf68a 100644 --- a/ietf/templates/doc/status_change/approval_text.txt +++ b/ietf/templates/doc/status_change/approval_text.txt @@ -1,11 +1,11 @@ {% load ietf_filters %}{% load mail_filters %}{% autoescape off %}From: The IESG To: {{ to }}{% if cc %} Cc: {{ cc }}{% endif %} -Subject: {{action}}: {{relateddoc.target.document.title}} to {{newstatus}} +Subject: {{action}}: {{relateddoc.target.title}} to {{newstatus}} {% filter wordwrap:78 %}The IESG has approved changing the status of the following document: -- {{relateddoc.target.document.title }} - ({{relateddoc.target.document.canonical_name }}) to {{ newstatus }} +- {{relateddoc.target.title }} + ({{relateddoc.target.name }}) to {{ newstatus }} This {{action|lower}} is documented at: {{status_change_url}} diff --git a/ietf/templates/doc/status_change/approve.html b/ietf/templates/doc/status_change/approve.html index 7984329766f..786ec451cac 100644 --- a/ietf/templates/doc/status_change/approve.html +++ b/ietf/templates/doc/status_change/approve.html @@ -2,13 +2,13 @@ {# Copyright The IETF Trust 2015, All Rights Reserved #} {% load origin %} {% load django_bootstrap5 %} -{% block title %}Approve {{ doc.canonical_name }}{% endblock %} +{% block title %}Approve {{ doc.name }}{% endblock %} {% block content %} {% origin %}

    Approve
    - {{ doc.canonical_name }} + {{ doc.name }}

    {% csrf_token %} diff --git a/ietf/templates/doc/status_change/edit_related_rows.html b/ietf/templates/doc/status_change/edit_related_rows.html index 8912c99fdab..044ebb1dbc5 100644 --- a/ietf/templates/doc/status_change/edit_related_rows.html +++ b/ietf/templates/doc/status_change/edit_related_rows.html @@ -5,7 +5,7 @@ {% for rfc,choice_slug in form.relations.items %}
    Chairs
    - {{ group.acronym }} - {{ group.name }} - {% for chair in group.chairs %} - {% person_link chair.person %}{% if not forloop.last %},{% endif %} - {% endfor %} -
    + {% if group_entry.grouper %}{{ group_entry.grouper.name }}{% else %}Other{% endif %} +
    + {{ group.acronym }} + {{ group.name }} + {% for chair in group.chairs %} + {% person_link chair.person %}{% if not forloop.last %},{% endif %} + {% endfor %} +
    {% endblock %} {% block js %} diff --git a/ietf/templates/group/active_wgs.html b/ietf/templates/group/active_wgs.html index 412601424b6..0e581ea7cc8 100644 --- a/ietf/templates/group/active_wgs.html +++ b/ietf/templates/group/active_wgs.html @@ -17,34 +17,24 @@

    Active IETF working groups

    href="{% url "ietf.group.views.chair_photos" group_type="wg" %}">Chair photos
    {% for area in areas %} -

    {{ area.name }} ({{ area.acronym }})

    +

    {{ area.name }} ({{ area.acronym|upper }})

    {% if area.ads_and_pre_ads %}
      {% for ad in area.ads_and_pre_ads %}
    • {% person_link ad.person %} - {% if ad.name == "pre-ad" %}Incoming AD{% endif %} -
    • - {% endfor %} -
    - {% endif %} - {% if area.urls %} - -
      - {% for url in area.urls %} -
    • - {{ url.name }} + {% if ad.name == "pre-ad" %}Incoming AD{% endif %}
    • {% endfor %}
    {% endif %} {% if area.groups %} @@ -84,7 +74,7 @@
    {% else %} - + {% endif %} {% endfor %} {% endblock %} diff --git a/ietf/templates/group/add_comment.html b/ietf/templates/group/add_comment.html index 0aea914f026..05313edda04 100644 --- a/ietf/templates/group/add_comment.html +++ b/ietf/templates/group/add_comment.html @@ -8,7 +8,7 @@

    Add comment
    - {{ group }} ({{ group.acronym }}) + {{ group }} ({{ group.acronym }})

    {% csrf_token %} diff --git a/ietf/templates/group/all_photos.html b/ietf/templates/group/all_photos.html index d32cccb4e34..0b4947ccbae 100644 --- a/ietf/templates/group/all_photos.html +++ b/ietf/templates/group/all_photos.html @@ -8,7 +8,8 @@

    {{ group_type | upper }} {{ role }} photos

    {% regroup roles|dictsort:"last_initial" by last_initial as alphabet_blocks %} {% for letter in alphabet_blocks %} -

    {{ letter.grouper }}

    + +

    {{ letter.grouper }}

    {% regroup letter.list by person as person_groups %} {# keep in sync with group_photos.html #}
    @@ -17,4 +18,4 @@

    {{ area_item.grouper.name }} ({{ area_item.grouper.acronym|uppe
    {{ rpt.group.acronym }} {% if rpt.group.state.slug != "active" %} - {{ rpt.group.state.slug|upper }} + {{ rpt.group.state.slug|upper }} {% endif %} {{ rpt.time|date:"Y-m-d" }}
    @@ -33,7 +33,7 @@

    Internet Research Task Force (IRTF)

    {{ rpt.group.acronym }} {% if rpt.group.state.slug != "active" %} - {{ rpt.group.state.slug|upper }} + {{ rpt.group.state.slug|upper }} {% endif %} {{ rpt.time|date:"Y-m-d" }}
    diff --git a/ietf/templates/group/appeal_artifact.html b/ietf/templates/group/appeal_artifact.html new file mode 100644 index 00000000000..4f810078a2a --- /dev/null +++ b/ietf/templates/group/appeal_artifact.html @@ -0,0 +1,24 @@ +{% extends "base.html" %} +{% load ietf_filters %} +{# Copyright The IETF Trust 2023. All Rights Reserved. #} +{% load origin %} +{% block title %}{{artifact.display_title}} - {{artifact.appeal.name}}{% endblock %} +{% block pagehead %} + +{% endblock %} +{% block content %} + {% origin %} +

    + {{artifact.appeal.name}} - {{artifact.appeal.date}} +
    + {{ artifact.display_title }} - {{ artifact.date }} +

    + {{ artifact_html }} + {% if request.user|has_role:"Secretariat" %} +
    + + {% endif %} +{% endblock %} \ No newline at end of file diff --git a/ietf/templates/group/appeals.html b/ietf/templates/group/appeals.html new file mode 100644 index 00000000000..2e0ab654642 --- /dev/null +++ b/ietf/templates/group/appeals.html @@ -0,0 +1,38 @@ +{% extends "group/group_base.html" %} +{# Copyright The IETF Trust 2023, All Rights Reserved #} +{% load origin %} +{% load ietf_filters person_filters textfilters %} +{% load static %} +{% block pagehead %} + +{% endblock %} +{% block group_content %} + {% origin %} +

    {{group.acronym|upper}} Appeals

    + + + + + + + + + + {% for appeal in appeals %} + + + + + {% endfor %} + +
    DateAppeal
    {{ appeal.date|date:"Y-m-d" }}{{appeal.name}} +
    + {% for part in appeal.appealartifact_set.all %} + {{part.display_title}} - {{part.date|date:"Y-m-d"}} + {% endfor %} +
    +
    +{% endblock %} +{% block js %} + +{% endblock %} \ No newline at end of file diff --git a/ietf/templates/group/change_reviewer_settings.html b/ietf/templates/group/change_reviewer_settings.html index 91964ff3c9c..75451fdd750 100644 --- a/ietf/templates/group/change_reviewer_settings.html +++ b/ietf/templates/group/change_reviewer_settings.html @@ -13,7 +13,7 @@

    Change {{ group.acronym }} reviewer settings
    - {{ reviewer_email }} + {{ reviewer_email }}

    Settings

    @@ -89,7 +89,7 @@

    Unavailable periods

    + value="add_period">Save new period

    History of settings

    @@ -105,11 +105,17 @@

    History of settings

    {% if reviewersettings.history.all %} {% for h in reviewersettings.history.all %} + {% if h|simple_history_delta_change_cnt > 0 or h.history_change_reason != "skipped" and h.history_change_reason %} {{ h.history_date|date }} {% person_link h.history_user.person %} - {{ h.history_change_reason }} + {% if h.history_change_reason != "skipped" and h.history_change_reason %} {{ h.history_change_reason }}
    {% endif %} + {% for change in h|simple_history_delta_changes %} + {{ change.field }} changed from "{{change.old}}" to "{{change.new}}"
    + {% endfor %} + + {% endif %} {% endfor %} {% endif %} diff --git a/ietf/templates/group/conclude.html b/ietf/templates/group/conclude.html index 1742bafa13a..3f99877336d 100644 --- a/ietf/templates/group/conclude.html +++ b/ietf/templates/group/conclude.html @@ -8,7 +8,7 @@

    Request closing of {{ group.acronym }} {{ group.type.name }}

    Please provide instructions regarding the disposition of each - active Internet-Draft (such as to withdraw the draft, move it to + active Internet-Draft (such as to withdraw it, move it to another group, convert it to an individual submission, and so on), wording for the closure announcement, and the status of the group mailing list (will it remain open or should it be closed). diff --git a/ietf/templates/group/concluded_groups.html b/ietf/templates/group/concluded_groups.html index c748c2061bc..725e8bd3cc6 100644 --- a/ietf/templates/group/concluded_groups.html +++ b/ietf/templates/group/concluded_groups.html @@ -40,8 +40,8 @@

    {{ label }}

    Group Name - Start - Concluded + Start + Concluded @@ -51,8 +51,8 @@

    {{ label }}

    {{ g.acronym }} {{ g.name }} - {{ g.start_date|date:"Y-m" }} - {{ g.conclude_date|date:"Y-m" }} + {{ g.start_date|date:"Y-m" }} + {{ g.conclude_date|date:"Y-m" }} {% endfor %} diff --git a/ietf/templates/group/customize_workflow.html b/ietf/templates/group/customize_workflow.html index 8ebf004a062..e0904d2f4c1 100644 --- a/ietf/templates/group/customize_workflow.html +++ b/ietf/templates/group/customize_workflow.html @@ -12,10 +12,10 @@

    Customize Workflow
    - {{ group.acronym }} {{ group.type.name }} + {{ group.acronym }} {{ group.type.name }}

    - Below you can customize the draft states and tags used in the + Below you can customize the Internet-Draft states and tags used in the {{ group.acronym }} {{ group.type.name }}. Note that some states are mandatory for group operation and cannot be deactivated. @@ -48,8 +48,8 @@

    States

    title="{{ state.desc|striptags|truncatewords:40 }}"> {{ state.name }} - {% if not state.used %}(not used in {{ group.acronym }}){% endif %} - {% if state.mandatory %}Mandatory{% endif %} + {% if not state.used %}(not used in {{ group.acronym }}){% endif %} + {% if state.mandatory %}Mandatory{% endif %} {% if state.used_next_states %} @@ -79,7 +79,7 @@

    States

    {% endfor %} @@ -124,7 +124,7 @@

    Tags

    {{ tag.name }} - {% if not tag.used %}(not used in {{ group.acronym }}){% endif %} + {% if not tag.used %}(not used in {{ group.acronym }}){% endif %}
    diff --git a/ietf/templates/group/edit.html b/ietf/templates/group/edit.html index 5544f862e2e..1afe9116f7d 100644 --- a/ietf/templates/group/edit.html +++ b/ietf/templates/group/edit.html @@ -18,7 +18,7 @@

    {% if action == "edit" %} Edit {{ group.type.name }}
    - {{ group.acronym }} + {{ group.acronym }} {% elif action == "charter" %} Start chartering new group {% else %} diff --git a/ietf/templates/group/edit_milestones.html b/ietf/templates/group/edit_milestones.html index 36a4a714ca5..b576ace1849 100644 --- a/ietf/templates/group/edit_milestones.html +++ b/ietf/templates/group/edit_milestones.html @@ -14,8 +14,8 @@

    {{ title }}

    {{ group.acronym }} {{ group.type.name }} {% if group.charter %} - {{ group.charter.canonical_name }} + href="{% url "ietf.doc.views_doc.document_main" name=group.charter.name %}"> + {{ group.charter.name }} {% endif %} {% if can_change_uses_milestone_dates %} @@ -65,7 +65,7 @@

    {{ title }}

    {% if form.milestone.resolved %} - {{ form.milestone.resolved }} + {{ form.milestone.resolved }} {% elif group.uses_milestone_dates and form.milestone.due %} {{ form.milestone.due|date:"M Y" }} {% endif %} @@ -74,12 +74,12 @@

    {{ title }}

    {{ form.milestone.desc|urlize_ietf_docs }} {% if form.needs_review %} + class="badge rounded-pill text-bg-warning"> Awaiting accept {% endif %} - {% if form.changed %}Changed{% endif %} - {% if form.delete.data %}Deleted{% endif %} + {% if form.changed %}Changed{% endif %} + {% if form.delete.data %}Deleted{% endif %} {% for d in form.docs_names %}
    {{ d }}
    {% endfor %}
    @@ -106,7 +106,7 @@

    {{ title }}

    + href="{% if milestone_set == "charter" %}{% url "ietf.doc.views_doc.document_main" name=group.charter.name %}{% else %}{{ group.about_url }}{% endif %}"> Cancel + \ No newline at end of file diff --git a/ietf/templates/group/index.html b/ietf/templates/group/index.html index 4087ebfe8a4..609c650180c 100644 --- a/ietf/templates/group/index.html +++ b/ietf/templates/group/index.html @@ -27,7 +27,7 @@

    Other RFC streams

    {% with stream.get_chair as role %} {% person_link role.person %} - {% if role %}{{ role.name }}{% endif %} + {% if role %}{{ role.name }}{% endif %} {% endwith %} diff --git a/ietf/templates/group/manage_review_requests.html b/ietf/templates/group/manage_review_requests.html index 175bfff5c98..d240ef24fa0 100644 --- a/ietf/templates/group/manage_review_requests.html +++ b/ietf/templates/group/manage_review_requests.html @@ -12,7 +12,7 @@

    Manage {{ assignment_status }} open review requests
    - {{ group.acronym }} + {{ group.acronym }}

    {% if newly_closed > 0 or newly_opened > 0 or newly_assigned > 0 %}

    @@ -36,7 +36,7 @@

    {{ r.type.name }} {% endif %} deadline {{ r.deadline|date:"Y-m-d" }} - {% if r.due %}{{ r.due }} day{{ r.due|pluralize }}{% endif %} + {% if r.due %}{{ r.due }} day{{ r.due|pluralize }}{% endif %} {{ r.doc.name }}- @@ -63,13 +63,13 @@

    {% endif %}
    {% else %} - Auto-suggested + Auto-suggested
    {% endif %} - {% if r.doc.authors %} + {% if r.doc.author_persons_or_names %} Authors: - {% for person in r.doc.authors %} - {% person_link person %}{% if not forloop.last %},{% endif %} + {% for person, tp_name in r.doc.author_persons_or_names %} + {% if person %}{% person_link person %}{% else %}{{ tp_name }}{% endif %}{% if not forloop.last %},{% endif %} {% endfor %}
    {% endif %} @@ -135,10 +135,10 @@

    {% endfor %} {% endif %}
    - {{ r.doc.pages }} page{{ r.doc.pages|pluralize }} - {{ r.doc.friendly_state }} + {{ r.doc.pages }} page{{ r.doc.pages|pluralize }} + {{ r.doc.friendly_state }}
    - {% if r.doc.telechat_date %}IESG telechat {{ r.doc.telechat_date }}{% endif %} + {% if r.doc.telechat_date %}IESG telechat {{ r.doc.telechat_date }}{% endif %} {% if r.comment %}
    {{ r.comment }}
    {% endif %}
    @@ -169,8 +169,8 @@

    title="Click to reassign reviewer"> {% person_link r.reviewer.person %} - {% if r.state_id == "accepted" %}Accepted{% endif %} - {% if r.reviewer_unavailable %}Unavailable{% endif %} + {% if r.state_id == "accepted" %}Accepted{% endif %} + {% if r.reviewer_unavailable %}Unavailable{% endif %} {% else %}

    {% for p in past_pres_list %} {{ p.grouper }} {% if p.list|length > 1 %} - {{ p.list|length }} sessions + {{ p.list|length }} sessions {% else %} {% for pr in p.list %} {% if pr.rev != d.rev %}(-{{ pr.rev }}){% endif %} @@ -52,7 +52,7 @@

    {{ doc_type.name }}

    {% for p in meeting_pres_list %} {{ p.grouper }} {% if p.list|length > 1 %} - {{ p.list|length }} sessions + {{ p.list|length }} sessions {% else %} {% for pr in p.list %} {% if pr.rev != d.rev %}(-{{ pr.rev }}){% endif %} diff --git a/ietf/templates/group/meetings-row.html b/ietf/templates/group/meetings-row.html index ff3b3af3769..8927eb61a26 100644 --- a/ietf/templates/group/meetings-row.html +++ b/ietf/templates/group/meetings-row.html @@ -1,3 +1,6 @@ +{# Copyright The IETF Trust 2025, All Rights Reserved #} +{% load origin tz %} +{% origin %} {% for s in sessions %} @@ -8,28 +11,33 @@ {% endif %} - {% if s.name %}{{ s.name }}{% endif %} {% if s.current_status == "sched" %} - {{ s.time|date:"Y-m-d" }} + {% with timeslot=s.official_timeslotassignment.timeslot %} + + {% endwith %} {% else %} - {{ s.current_status_name }} +
    {{ s.current_status_name }}
    + {% if s.current_status == "canceled" %} + {% with timeslot=s.official_timeslotassignment.timeslot %} + + {% endwith %} + {% endif %} {% endif %} {% if show_request and s.meeting.type_id == 'ietf' %} {% if can_edit %}
    + href="{% url 'ietf.meeting.views_session_request.view_request' num=s.meeting.number acronym=s.group.acronym %}"> Edit Session Request {% endif %} {% endif %} - {% if s.current_status == "sched" %}{{ s.time|date:"D" }}{% endif %} + {% if s.name %}{{ s.name }}{% endif %} - {% if show_ical %} + {% if show_ical and s.current_status == "sched" %} {% if s.meeting.type_id == 'ietf' %} - {{ s.time|date:"H:i" }} Minutes + {% if group.acronym == "iesg" %} + + Narrative Minutes + + {% endif %} + href="{% url 'ietf.meeting.views.session_details' num=s.meeting.number acronym=s.group.acronym %}"> + {% if can_always_edit or can_edit_materials %} + + + {% endif %} Materials - {% if can_always_edit or can_edit_materials %} - - Edit Materials - + {% if not s.cancelled %} +
    + {# see note in the included templates re: show_agenda parameter and required JS import #} + {% if s.meeting.type.slug == 'interim' %} + {% include "meeting/interim_session_buttons.html" with show_agenda=False show_empty=False session=s meeting=s.meeting %} + {% else %} + {% include "meeting/session_buttons_include.html" with show_agenda=False item=s.official_timeslotassignment session=s meeting=s.meeting %} + {% endif %} +
    {% endif %} diff --git a/ietf/templates/group/meetings.html b/ietf/templates/group/meetings.html index 69ec5458ccb..30f478da131 100644 --- a/ietf/templates/group/meetings.html +++ b/ietf/templates/group/meetings.html @@ -1,6 +1,6 @@ +{# Copyright The IETF Trust 2025, All Rights Reserved #} {% extends "group/group_base.html" %} -{# Copyright The IETF Trust 2015, All Rights Reserved #} -{% load origin %} +{% load origin static %} {% block title %} Meetings {% if group %}for {{ group.acronym }}{% endif %} @@ -10,7 +10,7 @@ Session requests {% if can_edit or can_always_edit %} - Request a session + Request a session Request an interim meeting @@ -19,14 +19,15 @@ {% endblock %} {% block group_content %} {% origin %} + {% include "meeting/tz-display.html" with meeting_timezone=None id_suffix="" minimal=False only %} {% if in_progress %} -

    Meetings in progress

    +

    Meetings in progress

    {% with sessions=in_progress show_request=True show_ical=True can_edit_materials=can_edit %} - - + + @@ -38,20 +39,20 @@

    Meetings in progress

    {% endwith %} {% endif %} {% if future %} -

    +

    Future Meetings - - - + {% for cal_action in cal_actions %} + + {{ cal_action.label }} + + {% endfor %}

    MeetingDateMeetingDate Materials
    - - + + @@ -64,12 +65,12 @@

    MeetingDateMeetingDate Materials
    {% endif %} {% if past or recent %} -

    Past Meetings

    +

    Past Meetings (within the last four years)

    - - + + @@ -84,7 +85,94 @@

    Past Meetings

    MeetingDateMeetingDate Materials
    {% endif %} -

    - This page shows meetings within the last four years. For earlier meetings, please see the proceedings. -

    -{% endblock %} \ No newline at end of file + {# The following is a temporary performance workaround, not long term design #} + {% if group.acronym != "iab" and group.acronym != "iesg" %} +

    + This page shows meetings within the last four years. For earlier meetings, please see the + proceedings. +

    + {% else %} + {% comment %} + Note: This block is only capable of correctly processing interim sessions. + If the view starts sending other types of meetings with a non-empty + older_sessions value, this block will need to be adjusted. + {% endcomment %} + {% if far_past %} +

    Meetings more than four years ago

    + + + + + + + + + + + {% for s in far_past %} + + + + + + + + {% endfor %} + +
    MeetingDateMaterials
    + {% if s.meeting.type.slug == 'ietf' %} + IETF {{ s.meeting.number }} + {% else %} + {{ s.meeting.number }} + {% endif %} + {% if s.current_status == "sched" %} + {{ s.time|date:"Y-m-d" }} + {% else %} + {{ s.current_status_name }} + {% endif %} + + {% if s.name %}{{ s.name }}{% endif %} + + {% if s.current_status == "sched" %}{{ s.time|date:"D" }}{% endif %} + + {% if not s.canceled %} + + Agenda + + + Minutes + + {% if group.acronym == "iesg" %} + + Narrative Minutes + + {% endif %} + + {% if can_always_edit or can_edit_materials %} + + + {% endif %} + Materials + + {% endif %} +
    + {% endif %} + {% endif %} +{% endblock %} +{% block js %} + + + + + +{% endblock %} diff --git a/ietf/templates/group/milestones.html b/ietf/templates/group/milestones.html index 8375a51e81b..51579ce80ad 100644 --- a/ietf/templates/group/milestones.html +++ b/ietf/templates/group/milestones.html @@ -7,7 +7,7 @@ {% if heading %}

    {% if milestoneset.grouper %} - {{ milestoneset.grouper }} milestones + {{ milestoneset.grouper|title }} milestones {% else %} {% if group.state_id == "proposed" %} Proposed milestones @@ -20,15 +20,15 @@

    - - - + + @@ -36,10 +36,10 @@

    diff --git a/ietf/templates/group/reset_charter_milestones.html b/ietf/templates/group/reset_charter_milestones.html index 00f4917ef8e..79f26e3e368 100644 --- a/ietf/templates/group/reset_charter_milestones.html +++ b/ietf/templates/group/reset_charter_milestones.html @@ -8,7 +8,7 @@

    Reset Charter Milestones
    - {{ group.acronym }} {{ group.type.name }} + {{ group.acronym }} {{ group.type.name }}

    Select which of the current {{ group.type.name }} milestones you would like to copy to the charter: @@ -30,7 +30,7 @@

    - + {% if milestone.resolved %} {{ milestone.resolved }} {% else %} diff --git a/ietf/templates/group/reset_next_reviewer.html b/ietf/templates/group/reset_next_reviewer.html index e5439078953..ce8dde1de8a 100644 --- a/ietf/templates/group/reset_next_reviewer.html +++ b/ietf/templates/group/reset_next_reviewer.html @@ -4,7 +4,7 @@ {% origin %} {% load ietf_filters static django_bootstrap5 %} {% block content %} -

    Set next reviewer in queue
    {{ group.acronym }}

    +

    Set next reviewer in queue
    {{ group.acronym }}

    {% csrf_token %} {% bootstrap_form form %} diff --git a/ietf/templates/group/review_requests.html b/ietf/templates/group/review_requests.html index 59beb0ff845..61b93de2b66 100644 --- a/ietf/templates/group/review_requests.html +++ b/ietf/templates/group/review_requests.html @@ -2,7 +2,7 @@ {# Copyright The IETF Trust 2015, All Rights Reserved #} {% load origin %} {% origin %} -{% load ietf_filters static person_filters %} +{% load ietf_filters static person_filters ietf_filters %} {% block group_subtitle %}Review requests{% endblock %} {% block pagehead %} @@ -48,13 +48,13 @@

    Unassigned and open re {% if r.pk %} {{ r.time|date:"Y-m-d" }} by {% person_link r.requested_by %} {% else %} - Auto-suggested + Auto-suggested {% endif %}

    @@ -96,14 +96,13 @@

    Unassigned and open re

    {% endfor %} @@ -242,10 +241,10 @@

    Closed review requests and assignme {% person_link a.reviewer.person %}

    {% endfor %} @@ -255,4 +254,4 @@

    Closed review requests and assignme {% block js %} - {% endblock %} + {% endblock %} \ No newline at end of file diff --git a/ietf/templates/group/review_requests_history.html b/ietf/templates/group/review_requests_history.html new file mode 100644 index 00000000000..1b1fb4d2636 --- /dev/null +++ b/ietf/templates/group/review_requests_history.html @@ -0,0 +1,90 @@ +{% extends "group/group_base.html" %} +{# Copyright The IETF Trust 2015, All Rights Reserved #} +{% load origin %} +{% load tz %} +{% load ietf_filters person_filters textfilters %} +{% load static %} +{% block pagehead %} + +{% endblock %} +{% block group_content %} + {% origin %} + {% if reviewer_email %} +

    Review requests history of {{ reviewer_email }}

    + {% else %} +

    Review requests history

    + {% endif %} + +
    + + + +
    +
    + Past: +
    + {% for key, label in since_choices %} + + {% endfor %} +
    +
    + + +
    + {% if group.uses_milestone_dates %} Date {% else %} Order {% endif %} MilestoneAssociated documentsMilestoneAssociated documents
    {% if milestone.resolved %} - {{ milestone.resolved }} + {{ milestone.resolved|title }} {% else %} {% if group.uses_milestone_dates %} - {{ milestone.due|date:"M Y" }} + {{ milestone.due|date:"M Y" }} {% else %} {% if forloop.first %}Last{% endif %} {% if forloop.last %}Next{% endif %} @@ -49,7 +49,7 @@

    {{ milestone.desc|urlize_ietf_docs }} {% for d in milestone.docs.all %} - {{ d.name }} + {% if d.became_rfc %}{{ d.became_rfc }} (was {% endif %}{{ d.name }}{% if d.became_rfc %}){% endif %}
    {% endfor %}
    {{ r.deadline|date:"Y-m-d" }} {% if r.due %} - {{ r.due }} day{{ r.due|pluralize }} {% endif %} {{ a.review_request.deadline|date:"Y-m-d" }} {% if a.due %} - {{ a.due }} day{{ a.due|pluralize }} {% endif %} {% person_link a.reviewer.person %} - {% if a.state_id == "accepted" %}Accepted{% endif %} - {% if a.reviewer_unavailable %}Unavailable{% endif %} + {{ a.state_id|badgeify }} {{ a.review_request.doc.friendly_state }} @@ -178,7 +177,7 @@

    Closed review requests and assignme {{ r.request_closed_time|date:"Y-m-d" }}

    - {{ r.state.name }} + {{ r.state.name|badgeify }}
    - {{ a.state }} + {{ a.state|badgeify }} - {% if a.result %}{{ a.result }}{% endif %} + {% if a.result %}{{ a.result|badgeify }}{% endif %}
    + + + + + + + + + + + + {% if history %} + + {% for h in history %} + + + + + + + + + + {% endfor %} + + {% endif %} +
    Date (UTC)ByDocumentStateReviewerResultDescription
    {{ h.history_date|utc|date:"Y-m-d H:i:s" }}{% person_link h.history_user.person %}{% if h.reviewed_rev %} + + {{ h.review_request.doc.name }}-{{ h.reviewed_rev }} + + {% else %} + {{ h.review_request.doc.name }} + {% endif %} + + {{ h.state }} + + {% person_link h.reviewer.person %} + + (set as filter) + + + {% if h.review %} + {{ h.result }} + {% else %} + {{ h.result }} + {% endif %} + {{ h.history_change_reason }}
    +{% endblock %} +{% block js %} + +{% endblock %} diff --git a/ietf/templates/group/reviewer_overview.html b/ietf/templates/group/reviewer_overview.html index 39ba7606a9c..75bd15f1d30 100644 --- a/ietf/templates/group/reviewer_overview.html +++ b/ietf/templates/group/reviewer_overview.html @@ -24,7 +24,7 @@

    Reviewers

    rotation with the next reviewer in the rotation at the top. Rows with darker backgrounds have the following meaning:

    -

    +

    Has already been assigned a document within the given interval.

    @@ -44,89 +44,102 @@

    Reviewers

    {% endif %} {% if reviewers %} - +
    - + - - - + + + {% for person in reviewers %} - + + + - - + {% endfor %} diff --git a/ietf/templates/group/statements.html b/ietf/templates/group/statements.html new file mode 100644 index 00000000000..6bbe3cb3945 --- /dev/null +++ b/ietf/templates/group/statements.html @@ -0,0 +1,51 @@ +{% extends "group/group_base.html" %} +{# Copyright The IETF Trust 2023, All Rights Reserved #} +{% load origin %} +{% load ietf_filters person_filters textfilters %} +{% load static %} +{% block pagehead %} + +{% endblock %} +{% block group_content %} + {% origin %} +

    {{group.acronym|upper}} Statements

    + {% if request.user|has_role:"Secretariat" %} + + {% endif %} +
    NextNext ReviewerRecent historyDays since completedSettings +
    +
    Assigned
    +
    Deadline
    +
    State
    +
    Days for review
    +
    Document
    +
    +
    Days since reviewSettings
    {{ forloop.counter }} - {% person_link person %} - {% if person.settings_url %} - Edit - - {% endif %} + {% person_link person with_email=False %} + +
    + {% if person.settings_url %} + + + + {% endif %} + +
    {% if person.latest_reqs %} - - - - - - - - - - - - {% for assn_pk, req_pk, doc_name, reviewed_rev, assigned_time, deadline, state, assignment_to_closure_days in person.latest_reqs %} - - - - - - - - {% endfor %} - -
    AssignedDeadlineStateReview timeDocument
    - {{ assigned_time|date }} - - {{ deadline|date }} - - {{ state.name }} - - {% if assignment_to_closure_days != None %} - {{ assignment_to_closure_days }} day{{ assignment_to_closure_days|pluralize }} - {% endif %} - - {{ doc_name }} - {% if reviewed_rev %}-{{ reviewed_rev }}{% endif %} -
    + {% for assn_pk, req_pk, doc_name, reviewed_rev, assigned_time, deadline, state, assignment_to_closure_days in person.latest_reqs %} +
    +
    + {{ assigned_time|date|split:"-"|join:"-" }} +
    + +
    + {{ state.name|badgeify }} +
    +
    + {% if assignment_to_closure_days != None %} + {{ assignment_to_closure_days }} + {% endif %} +
    +
    + {{ doc_name }}{% if reviewed_rev %}-{{ reviewed_rev }}{% endif %} +
    +
    + {% endfor %} {% endif %}
    + + {% if person.days_since_completed_review != 9999 %} {{ person.days_since_completed_review }} {% endif %} - {% if person.settings.min_interval %} - {{ person.settings.get_min_interval_display }} -
    - {% endif %} - {% if person.settings.skip_next %} - Skip: {{ person.settings.skip_next }} -
    - {% endif %} - {% if person.settings.filter_re %} - Filter: {{ person.settings.filter_re|truncatechars:15 }} -
    - {% endif %} - {% if person.unavailable_periods %} - {% include "review/unavailable_table.html" with unavailable_periods=person.unavailable_periods %} - {% endif %} + +
    + {% include "review/unavailable_table.html" with person=person unavailable_periods=person.unavailable_periods %} +
    + + + + + + +{% regroup statements by status as grouped_statements %} +{% for statement_group in grouped_statements %} + + + + + + + {% for statement in statement_group.list %} + + + + + {% endfor %} + +{% endfor %} +
    DateStatement
    + {{ statement_group.grouper|title }} {{"Statement"|plural:statement_group.list }} ({{ statement_group.list|length }} {{"hit"|plural:statement_group.list }}) +
    {{ statement.published|date:"Y-m-d" }}{{statement.title}} +
    +{% endblock %} +{% block js %} + +{% endblock %} \ No newline at end of file diff --git a/ietf/templates/help/personal-information.html b/ietf/templates/help/personal-information.html deleted file mode 100644 index d60ee93b61c..00000000000 --- a/ietf/templates/help/personal-information.html +++ /dev/null @@ -1,86 +0,0 @@ -{# Copyright The IETF Trust 2018-2018, All Rights Reserved #} -{% extends "base.html" %} -{% load origin %} -{% block title %} - Personal Information in the Datatracker -{% endblock %} -{% block content %} - {% origin %} -

    Personal Information in the Datatracker

    -

    - RFC 3935, "A Mission Statement for the IETF" - lays out - the goal and the mission of the IETF as follows -

    -
    -    The goal of the IETF is to make the Internet work better.
    -
    -    The mission of the IETF is to produce high quality, relevant
    -    technical and engineering documents that influence the way people
    -    design, use, and manage the Internet in such a way as to make the
    -    Internet work better.  These documents include protocol standards,
    -    best current practices, and informational documents of various kinds.
    -
    -
    - {% comment %} - The following text has been reviewed by legal counsel (Thomas Zych) - on Thu, 26 Apr 2018 17:24:03 -0400 - *** DO NOT CHANGE WITHOUT LEGAL REVIEW *** -{% endcomment %} -

    - In order to fulfill its mission, the IETF provides various ways to distribute - and discuss Internet-Drafts, and otherwise process them until there is - consensus that they are ready for publication. -

    -

    - This makes the information in the content of the draft documents, as well - as contributions related to the draft documents and their processing as - laid out in the - "Note Well" - statement, of legitimate interest to the IETF when it pursues - its mission; not only in general terms, but specifically under Article - 6(1) f) of - - EU's General Data Protection Regulation - . -

    -

    - The datatracker treats all personal information derived from draft documents and - documents published as RFC, as well as personal information derived from - processing draft documents through the IETF procedures, in accordance with - applicable law, including the GDPR. This includes author names, - email addresses and other address information provided in draft documents or as - contact information for IETF roles such as Working Group chairs, secretaries, - Area Directors and other roles. -

    -

    - There is however additional personal information held in the datatracker that - is used for other purposes. This information requires the consent of the - individuals whose information is stored and processed which IETF secures - through various means, and the person it relates to may at any time request - its correction or removal. This includes: -

    -
      -
    • Personal photograph or other likeness;
    • -
    • Personal biography;
    • -
    • Personal email addresses not derived from IETF contributions; and
    • -
    • Personal account login information
    • -
    • Personal notification subscriptions
    • -
    -

    - Most of this information can be edited on the individual's - Account Info - page by the individual - after logging in to the account. If the datatracker holds such - information about a person, and they don't have an account, a request to - the - IETF secretariat - to change - or remove the information will be honoured to the extent feasible and - legally permitted. -

    -

    - Please also see the IETF's overall - Statement concerning personal data. -

    -{% endblock %} \ No newline at end of file diff --git a/ietf/templates/help/state_index.html b/ietf/templates/help/state_index.html deleted file mode 100644 index 29233cca094..00000000000 --- a/ietf/templates/help/state_index.html +++ /dev/null @@ -1,43 +0,0 @@ -{% extends "base.html" %} -{# Copyright The IETF Trust 2015, All Rights Reserved #} -{% load origin static %} -{% block pagehead %} - -{% endblock %} -{% block title %}Document state index{% endblock %} -{% block content %} - {% origin %} -

    Document state index

    -

    - Document state information is available for the following document and document state groups. -

    - - - - - - - - - {% for type in types %} - {% if type.stategroups != None %} - - - - - {% endif %} - {% endfor %} - -
    DocumentState groups
    - {{ type.slug }} - - {% for group in type.stategroups %} - {# djlint:off #} - {{ group }}{% if not forloop.last %},{% endif %} - {# djlint:on #} - {% endfor %} -
    -{% endblock %} -{% block js %} - -{% endblock %} \ No newline at end of file diff --git a/ietf/templates/help/states.html b/ietf/templates/help/states.html deleted file mode 100644 index b68625811d2..00000000000 --- a/ietf/templates/help/states.html +++ /dev/null @@ -1,38 +0,0 @@ -{% extends "base.html" %} -{# Copyright The IETF Trust 2015, All Rights Reserved #} -{% load origin static %} -{% block pagehead %} - -{% endblock %} -{% block title %}{{ type.label|cut:"state"|cut:"state" }} states{% endblock %} -{% block content %} - {% origin %} -

    {{ type.label|cut:"state"|cut:"State" }} states

    - - - - - - - - - - {% for state in states %} - - - - - - {% endfor %} - -
    StateDescriptionNext states
    {{ state.name }}{{ state.desc|safe }} -
      - {% for s in state.next_states.all %} -
    • {{ s.name }}
    • - {% endfor %} -
    -
    -{% endblock %} -{% block js %} - -{% endblock %} \ No newline at end of file diff --git a/ietf/templates/idindex/.gitignore b/ietf/templates/idindex/.gitignore deleted file mode 100644 index a74b07aee47..00000000000 --- a/ietf/templates/idindex/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/*.pyc diff --git a/ietf/templates/idindex/all_id2.txt b/ietf/templates/idindex/all_id2.txt index 5d810ab96b7..29c43231e4d 100644 --- a/ietf/templates/idindex/all_id2.txt +++ b/ietf/templates/idindex/all_id2.txt @@ -3,29 +3,29 @@ # generated: {% now "Y-m-d H:i:s T" %} # # Description of fields: -# 0 draft name and latest revision +# 0 Internet-Draft name and latest revision # 1 always -1 (was internal numeric database id in earlier schema) # 2 one of "Active", "Expired", "RFC", "Withdrawn by Submitter", # "Replaced", or "Withdrawn by IETF" # 3 if #2 is "Active", the IESG state for the document (such as -# "In Last Call", "AD Evaluation::Revised ID Needed", or "I-D Exists"); +# "In Last Call", "AD Evaluation::Revised I-D Needed", or "I-D Exists"); # otherwise empty # 4 if #2 is "RFC", the RFC number (otherwise empty) -# 5 if #2 is "Replaced", the replacing draft name (otherwise empty) +# 5 if #2 is "Replaced", the replacing Internet-Draft name (otherwise empty) # 6 revision date (YYYY-MM-DD) # 7 group acronym (or empty if no group/not known) # 8 area acronym (or empty if not known; not necessarily accurate -# for older drafts) +# for older Internet-Drafts) # 9 responsible AD name (or empty if not known) # 10 intended maturity level (or empty if not known) # 11 if #3 is "In Last Call" (with any substate), the last call # end date (YYYY-MM-DD); otherwise empty # 12 if #2 is "Active", list of file types; otherwise empty -# 13 draft title -# 14 draft authors (often quite inaccurate, especially the email +# 13 Internet-Draft title +# 14 Internet-Draft authors (often quite inaccurate, especially the email # addresses...) -# 15 draft shepherd (Shep Erd ) -# 16 draft areadirector (Aread Irector ) +# 15 Internet-Draft shepherd (Shep Erd ) +# 16 Internet-Draft areadirector (Aread Irector ) # # new fields can be added to the end in the future, so remember to # ignore those in your code diff --git a/ietf/templates/idindex/id_index.txt b/ietf/templates/idindex/id_index.txt index 95cf504883f..f4707b5d011 100644 --- a/ietf/templates/idindex/id_index.txt +++ b/ietf/templates/idindex/id_index.txt @@ -2,10 +2,10 @@ {% if with_abstracts %} This summary sheet provides a short synopsis of each Internet-Draft available within the "internet-drafts" directory at the shadow -sites directory. These drafts are listed alphabetically by working +sites directory. These Internet-Drafts are listed alphabetically by working group acronym and start date.{% else %} This summary sheet provides an index of each Internet-Draft. These -drafts are listed alphabetically by Working Group acronym and initial +Internet-Drafts are listed alphabetically by Working Group acronym and initial post date.{% endif %} Generated {{ time }}. {% for group in groups %} diff --git a/ietf/templates/iesg/.gitignore b/ietf/templates/iesg/.gitignore deleted file mode 100644 index a74b07aee47..00000000000 --- a/ietf/templates/iesg/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/*.pyc diff --git a/ietf/templates/iesg/agenda.html b/ietf/templates/iesg/agenda.html index 629c0946f4f..8567d5e357c 100644 --- a/ietf/templates/iesg/agenda.html +++ b/ietf/templates/iesg/agenda.html @@ -9,9 +9,15 @@

    IESG agenda
    - {{ date }} + {{ date }}

    {% include "iesg/nav.html" with active="agenda" %} + {% if user|has_role:"Secretariat" %} + + Manage administrivia + + {% endif %} {% for num, section in sections %} {% if num|sectionlevel == 1 %}

    {{ num }}. {{ section.title|safe }}

    @@ -45,48 +51,48 @@

    {{ num }} {{ section.title|safe }} {% endif %} {% if num == "3.4" %} -

    - The IESG will use RFC 5742 responses: -

    -
      -
    1. - The IESG has concluded - that there is no conflict between this document and IETF work; -
    2. -
    3. - The IESG has concluded that this work is related to IETF work done - in WG <X>, but this relationship does not prevent - publishing; -
    4. -
    5. - The IESG has concluded that publication could - potentially disrupt the IETF work done in WG <X> and - recommends not publishing the document at this time; -
    6. -
    7. - The IESG - has concluded that this document violates IETF procedures for - <Y> and should therefore not be published without IETF - review and IESG approval; or -
    8. -
    9. - The IESG has concluded that this - document extends an IETF protocol in a way that requires IETF - review and should therefore not be published without IETF review - and IESG approval. -
    10. -
    -

    - The document shepherd must propose one of these responses in the - conflict-review document, and the document shepherd may supply text - for an IESG Note in that document. The Area Director ballot positions - indicate consensus with the response proposed by the document shepherd - and agreement that the IESG should request inclusion of the IESG Note. -

    -

    - Other matters may be recorded in comments, and the comments will - be passed on to the RFC Editor as community review of the document. -

    +
    +

    The IESG will use RFC 5742 responses:

    +
      +
    1. + The IESG has concluded + that there is no conflict between this document and IETF work; +
    2. +
    3. + The IESG has concluded that this work is related to IETF work done + in WG <X>, but this relationship does not prevent + publishing; +
    4. +
    5. + The IESG has concluded that publication could + potentially disrupt the IETF work done in WG <X> and + recommends not publishing the document at this time; +
    6. +
    7. + The IESG + has concluded that this document violates IETF procedures for + <Y> and should therefore not be published without IETF + review and IESG approval; or +
    8. +
    9. + The IESG has concluded that this + document extends an IETF protocol in a way that requires IETF + review and should therefore not be published without IETF review + and IESG approval. +
    10. +
    +

    + The document shepherd must propose one of these responses in the + conflict-review document, and the document shepherd may supply text + for an IESG Note in that document. The Area Director ballot positions + indicate consensus with the response proposed by the document shepherd + and agreement that the IESG should request inclusion of the IESG Note. +

    +

    + Other matters may be recorded in comments, and the comments will + be passed on to the RFC Editor as community review of the document. +

    +
    {% endif %} {% if "docs" in section %} {% for doc in section.docs %} @@ -100,7 +106,7 @@

    {{ num }} {{ section.title|safe }} +

    (None)

    {% endfor %} @@ -111,4 +117,4 @@

    {{ num }} {{ section.title|safe }}// automatically generate a right-hand navigation tab for long pages{% endblock %} +{% block js %}{% endblock %} \ No newline at end of file diff --git a/ietf/templates/iesg/agenda_charter.html b/ietf/templates/iesg/agenda_charter.html index 20bd23e06ff..b4124914db5 100644 --- a/ietf/templates/iesg/agenda_charter.html +++ b/ietf/templates/iesg/agenda_charter.html @@ -24,7 +24,7 @@
    Area
    - + {{ doc.group.parent.acronym|upper }} ({% person_link doc.ad %})
    diff --git a/ietf/templates/iesg/agenda_conflict_doc.html b/ietf/templates/iesg/agenda_conflict_doc.html index ceb84199cfb..316dd8e2ccc 100644 --- a/ietf/templates/iesg/agenda_conflict_doc.html +++ b/ietf/templates/iesg/agenda_conflict_doc.html @@ -1,7 +1,7 @@ {# Copyright The IETF Trust 2015, All Rights Reserved #} {% load origin %} {% origin %} -{% load ietf_filters ballot_icon person_filters %} +{% load ietf_filters ballot_icon person_filters textfilters %}
    {% ballot_icon doc %}
    @@ -11,7 +11,7 @@
    @@ -27,7 +27,7 @@ {% if conflictdoc.note %}
    Note
    -
    {{ conflictdoc.note|linebreaksbr }}
    +
    {{ conflictdoc.note|urlize_ietf_docs|linkify|linebreaksbr }}
    {% endif %}
    diff --git a/ietf/templates/iesg/agenda_conflict_doc.txt b/ietf/templates/iesg/agenda_conflict_doc.txt index 4ff2e3b00c3..e4fbcc32b33 100644 --- a/ietf/templates/iesg/agenda_conflict_doc.txt +++ b/ietf/templates/iesg/agenda_conflict_doc.txt @@ -1,8 +1,7 @@ {% load ietf_filters %}{% with doc.conflictdoc as conflictdoc %} - o {{ doc.canonical_name }}-{{ doc.rev }} + o {{ doc.name }}-{{ doc.rev }} {% filter wordwrap:"68"|indent|indent %}{{ doc.title }}{% endfilter %} - {{ conflictdoc.canonical_name }}-{{ conflictdoc.rev }} + {{ conflictdoc.name }}-{{ conflictdoc.rev }} {% filter wordwrap:"66"|indent:"4" %}{{ conflictdoc.title }} ({{ conflictdoc.stream }}: {{ conflictdoc.intended_std_level }}){% endfilter %} -{% if conflictdoc.note %}{# note: note is not escaped #} {% filter wordwrap:"64"|indent:"6" %}Note: {{ conflictdoc.note|striptags }}{% endfilter %} -{% endif %} Token: {{ doc.ad }} + Token: {{ doc.ad }} {% with doc.active_defer_event as defer %}{% if defer %} Was deferred by {{defer.by}} on {{defer.time|date:"Y-m-d"}}{% endif %}{% endwith %}{% endwith %} diff --git a/ietf/templates/iesg/agenda_doc.html b/ietf/templates/iesg/agenda_doc.html index 16b223186c7..87051fda26b 100644 --- a/ietf/templates/iesg/agenda_doc.html +++ b/ietf/templates/iesg/agenda_doc.html @@ -19,9 +19,9 @@ {% with doc.rfc_number as rfc_number %} {% endwith %} - {{ doc.canonical_name }} + {{ doc.name }} {% if doc.has_rfc_editor_note %} - + (Has RFC Editor Note) {% endif %} @@ -37,7 +37,7 @@
    Token
    diff --git a/ietf/templates/iesg/agenda_doc.txt b/ietf/templates/iesg/agenda_doc.txt index 247d456a5a8..015af32409f 100644 --- a/ietf/templates/iesg/agenda_doc.txt +++ b/ietf/templates/iesg/agenda_doc.txt @@ -1,8 +1,7 @@ {% load ietf_filters %}{% with doc.rfc_number as rfc_number %} - o {{doc.canonical_name}}{% if not rfc_number %}-{{doc.rev}}{% endif %}{% endwith %}{%if doc.has_rfc_editor_note %} (Has RFC Editor Note){% endif %}{% if doc.stream %} - {{ doc.stream }} stream{% endif %} + o {{doc.name}}{% if not rfc_number %}-{{doc.rev}}{% endif %}{% endwith %}{%if doc.has_rfc_editor_note %} (Has RFC Editor Note){% endif %}{% if doc.stream %} - {{ doc.stream }} stream{% endif %} {% filter wordwrap:"68"|indent|indent %}{{ doc.title }} ({{ doc.intended_std_level }}){% endfilter %} -{% if doc.note %}{# note: note is not escaped #} {% filter wordwrap:"68"|indent|indent %}Note: {{ doc.note|striptags }}{% endfilter %} -{% endif %} Token: {{ doc.ad }}{% if doc.iana_review_state %} + Token: {{ doc.ad }}{% if doc.iana_review_state %} IANA Review: {{ doc.iana_review_state }}{% endif %}{% if doc.consensus %} Consensus: {{ doc.consensus }}{% endif %}{% if doc.lastcall_expires %} Last call expires: {{ doc.lastcall_expires|date:"Y-m-d" }}{% endif %}{% if doc.review_assignments %} diff --git a/ietf/templates/iesg/agenda_documents.html b/ietf/templates/iesg/agenda_documents.html index 1935c44e03f..f732672df0e 100644 --- a/ietf/templates/iesg/agenda_documents.html +++ b/ietf/templates/iesg/agenda_documents.html @@ -21,7 +21,12 @@

    Documents on future IESG telechat agendas

    IESG telechat {{ t.date }}
    - {{ t.pages }} page{{ t.pages|pluralize }} + + {{ t.pages }} page{{ t.pages|pluralize }} + {% if t.ad_pages_left_to_ballot_on %} + ({{ t.ad_pages_left_to_ballot_on }} pages left to ballot on) + {% endif %} +

    @@ -55,7 +60,7 @@

    {% for doc in section.docs %} - {% include "doc/search/search_result_row.html" with color_ad_position=True %} + {% include "doc/search/search_result_row.html" with color_ad_position=True show_ad_and_shepherd=True %} {% endfor %} diff --git a/ietf/templates/iesg/agenda_package.txt b/ietf/templates/iesg/agenda_package.txt index ad95c39d318..99188bcb336 100644 --- a/ietf/templates/iesg/agenda_package.txt +++ b/ietf/templates/iesg/agenda_package.txt @@ -3,13 +3,13 @@ Contents: 1. Roll Call and Dial-In Instructions - {{ roll_call_url }} + {% url "ietf.iesg.views.telechat_agenda_content_view" section="roll_call" %} 2. Agenda {{ settings.IDTRACKER_BASE_URL }}{% url 'ietf.iesg.views.agenda' %} 3. Management Item Details {{ settings.IDTRACKER_BASE_URL }}{% url 'ietf.iesg.views.agenda' %}#6 4. Previous minutes - {{ minutes_url }} + {% url "ietf.iesg.views.telechat_agenda_content_view" section="minutes" %} ------------------------------------------------------------------------ 1. ROLL CALL AND DIAL-IN INSTRUCTIONS diff --git a/ietf/templates/iesg/discusses.html b/ietf/templates/iesg/discusses.html index 8237b162d28..ca031e2bc2c 100644 --- a/ietf/templates/iesg/discusses.html +++ b/ietf/templates/iesg/discusses.html @@ -60,7 +60,7 @@

    IESG discuss positions

    {% person_link doc.ad %} {% for p in doc.blocking_positions %} - {% if p.is_old_pos %}{% endif %} + {% if p.is_old_pos %}{% endif %} {% person_link p.balloter %} ({% if p.discuss_time %}{{ p.discuss_time|timesince_days }} days ago{% endif %}{% if doc.get_state_url != "rfc" and p.rev != doc.rev %} for -{{ p.rev }}{% endif %})
    diff --git a/ietf/templates/iesg/ietf_activity_report.html b/ietf/templates/iesg/ietf_activity_report.html new file mode 100644 index 00000000000..030110026ae --- /dev/null +++ b/ietf/templates/iesg/ietf_activity_report.html @@ -0,0 +1,25 @@ +{% extends "base.html" %} +{% load ams_filters ietf_filters django_bootstrap5 %} +{% block title %}IETF Activity Report{% endblock %} +{% block content %} +

    IETF Activity Report

    +

    {{ sdate|date:"F Y" }}

    + +
    +
    +
    + {% bootstrap_field form.month show_label=True layout="inline" %} +
    +
    + {% bootstrap_field form.year layout="inline" %} +
    +
    + +
    +
    +
    + +

    Draft Activity

    + {% include "meeting/activity_report.html" %} + +{% endblock %} \ No newline at end of file diff --git a/ietf/templates/iesg/moderator_doc.html b/ietf/templates/iesg/moderator_doc.html index fb48b75be18..1a06ffa1d4e 100644 --- a/ietf/templates/iesg/moderator_doc.html +++ b/ietf/templates/iesg/moderator_doc.html @@ -93,7 +93,7 @@

    If APPROVED with caveats - The Secretariat will send a working group submission, Protocol Action Announcement that includes the - [RFC Editor Note, IESG Note, etc.] to be drafted by [Name that + [RFC Editor Note, etc.] to be drafted by [Name that AD].

    {% endif %} @@ -103,7 +103,7 @@

    If APPROVED with caveats - The Secretariat will send an individual submission, Protocol Action Announcement that includes - the [RFC Editor Note, IESG Note, etc.] to be drafted by [Name that + the [RFC Editor Note, etc.] to be drafted by [Name that AD].

    {% endif %} @@ -113,7 +113,7 @@

    If APPROVED with caveats - The Secretariat will send the associated status change Protocol Action Announcements that includes the - [RFC Editor Note, IESG Note, etc.] to be drafted by [Name that + [RFC Editor Note, etc.] to be drafted by [Name that AD].

    {% endif %} @@ -123,7 +123,7 @@

    If APPROVED with caveats - The Secretariat will send a working group submission Document Action announcement that includes the [RFC - Ed. Note, IESG, note, etc.] from [Name that AD].

    + Ed. Note, etc.] from [Name that AD].

    {% endif %} {% if num|startswith:"3.2.1" or num|startswith:"3.2.2" %} @@ -132,7 +132,7 @@

    If APPROVED with caveats - The Secretariat will send an individual submission Document Action announcement that includes the - [RFC Ed. Note, IESG, note, etc.] from [Name that AD].

    + [RFC Ed. Note, etc.] from [Name that AD].

    {% endif %} {% if num|startswith:"3.3.1" or num|startswith:"3.3.2" %} @@ -141,13 +141,12 @@

    If APPROVED with caveats - The Secretariat will send the associated status change Document Action announcements that includes the [RFC - Ed. Note, IESG, note, etc.] from [Name that AD].

    + Ed. Note, etc.] from [Name that AD].

    {% endif %} {% if num|startswith:"3.4.1" or num|startswith:"3.4.2" %}

    If APPROVED - The Secretariat will send a standard no problem - message to the RFC Editor. [Name of AD] will you supply the text for - the IESG Note?

    + message to the RFC Editor.

    If APPROVED with caveats - The Secretariat will send a standard no problem message to the RFC Editor that includes the note drafted @@ -165,13 +164,13 @@ {% if downrefs %}

    If APPROVED - The Secretariat will add to the downref registry:
    {% for ref in downrefs %} - + Add {{ref.target.document.canonical_name}} - ({{ref.target.document.std_level}} - {{ref.target.document.stream.desc}}) + + Add {{ref.target.name}} + ({{ref.target.std_level}} - {{ref.target.stream.desc}}) to downref registry.
    - {% if not ref.target.document.std_level %} + {% if not ref.target.std_level %} +++ Warning: The standards level has not been set yet!!!
    {% endif %} - {% if not ref.target.document.stream %} + {% if not ref.target.stream %} +++ Warning: document stream has not been set yet!!!
    {% endif %} {% endfor %}

    diff --git a/ietf/templates/iesg/moderator_package.html b/ietf/templates/iesg/moderator_package.html index 7b7fc9c449b..6698486e00d 100644 --- a/ietf/templates/iesg/moderator_package.html +++ b/ietf/templates/iesg/moderator_package.html @@ -96,9 +96,7 @@

    Are there narrative minutes to approve for today?

    - {% filter linebreaks_crlf %} -
    {{ section.text }}
    - {% endfilter %} +
    Draft minutes {% endif %} {% if num == "1.4" %} {% filter linebreaks_crlf %} diff --git a/ietf/templates/iesg/past_documents.html b/ietf/templates/iesg/past_documents.html index 72d005d1a85..ee0a2f8288d 100644 --- a/ietf/templates/iesg/past_documents.html +++ b/ietf/templates/iesg/past_documents.html @@ -12,7 +12,7 @@

    Documents on recent agendas
    - in states + in states {% for state in states %} {{ state.name }}{% if not forloop.last %},{% endif %} {% endfor %} @@ -49,7 +49,7 @@

    {% person_link doc.ad %} {% for p in doc.blocking_positions %} - {% if p.is_old_pos %}{% endif %} + {% if p.is_old_pos %}{% endif %} {% person_link p.balloter %} ({% if p.discuss_time %}{{ p.discuss_time|timesince_days }} days ago{% endif %}{% if doc.get_state_url != "rfc" and p.rev != doc.rev %} for -{{ p.rev }}{% endif %})
    diff --git a/ietf/templates/iesg/review_decisions.html b/ietf/templates/iesg/review_decisions.html index 68a9d7fb953..2f69c1809b4 100644 --- a/ietf/templates/iesg/review_decisions.html +++ b/ietf/templates/iesg/review_decisions.html @@ -1,8 +1,8 @@ -{% extends "base.html" %} -{# Copyright The IETF Trust 2015, All Rights Reserved #} +{% extends "group/group_base.html" %} +{# Copyright The IETF Trust 2015-2026, All Rights Reserved #} {% load origin %} -{% block title %}IESG review decisions in {{ timeframe }}{% endblock %} -{% block content %} +{% block group_subtitle %}IESG review decisions in {{ timeframe }}{% endblock %} +{% block group_content %} {% origin %}

    IESG review decisions in {{ timeframe }}

    diff --git a/ietf/templates/iesg/telechat_agenda_content_edit.html b/ietf/templates/iesg/telechat_agenda_content_edit.html new file mode 100644 index 00000000000..f24d81df989 --- /dev/null +++ b/ietf/templates/iesg/telechat_agenda_content_edit.html @@ -0,0 +1,21 @@ +{% extends "base.html" %} +{# Copyright The IETF Trust 2023, All Rights Reserved #} +{% load origin %} +{% load django_bootstrap5 %} +{% block pagehead %}{{ form.media.css }}{% endblock %} +{% block title %}Edit "{{ section }}"{% endblock %} +{% block content %} + {% origin %} +

    + Edit Telechat Agenda Contents +
    + {{ section }} +

    +
    + {% csrf_token %} + {% bootstrap_form form %} + + Cancel +
    +{% endblock %} +{% block js %}{{ form.media.js }}{% endblock %} diff --git a/ietf/templates/iesg/telechat_agenda_content_manage.html b/ietf/templates/iesg/telechat_agenda_content_manage.html new file mode 100644 index 00000000000..045e8affd6d --- /dev/null +++ b/ietf/templates/iesg/telechat_agenda_content_manage.html @@ -0,0 +1,49 @@ +{% extends "base.html" %} +{# Copyright The IETF Trust 2023, All Rights Reserved #} +{% load origin %} +{% load django_bootstrap5 %} +{% block title %}Telechat agenda contents{% endblock %} +{% block content %} +{% origin %} +

    Telechat Agenda Contents

    +

    + Go to IESG agenda... +

    +
    +
    + +
    +
    + {% for item in contents %} +
    + + Edit + + {% if item.text %} +
    {{ item.text }}
    + {% else %} +
    No {{ item.section }}
    + {% endif %} +
    + {% endfor %} +
    +
    +{% endblock %} diff --git a/ietf/templates/iesg/working_groups.html b/ietf/templates/iesg/working_groups.html new file mode 100644 index 00000000000..1bde1362c50 --- /dev/null +++ b/ietf/templates/iesg/working_groups.html @@ -0,0 +1,159 @@ +{% extends "group/group_base.html" %} +{# Copyright The IETF Trust 2025-2026, All Rights Reserved #} +{% load origin static %} +{% block pagehead %} + +{% endblock %} +{% block group_subtitle %}IESG view of working groups{% endblock %} +{% block group_content %} + {% origin %} +

    IESG view of working groups

    +

    Area Size and Load

    + + + + + + + + {# (divider) #} + + + + + + {% for area in area_summary %} + + + + + + + + + {% endfor %} + + + + + + + + + + + +
    Area NameWGsI-DsPages% I-Ds% Pages
    {{area.area}}{{area.groups_in_area}}{{area.doc_count}}{{area.page_count}}{{area.doc_percent|floatformat:1}}{{area.page_percent|floatformat:1}}
    Totals{{totals.group_count}}{{totals.doc_count}}{{totals.page_count}}
    + +

    Area Director Load: Documents not yet directly assigned to AD

    +
    Typically these are pre-pubreq documents
    + + + + + + + + + {# (divider) #} + + + + + + {% for ad in noad_summary %} + + + + + + + + + + {% endfor %} + + + + + + + + + + + + +
    ADArea NameWGs for ADI-DsPages% I-Ds% Pages
    {{ad.ad}}{{ad.area}}{{ad.ad_group_count}}{{ad.doc_count}}{{ad.page_count}}{{ad.doc_percent|floatformat:1}}{{ad.page_percent|floatformat:1}}
    Totals{{noad_totals.ad_group_count}}{{noad_totals.doc_count}}{{noad_totals.page_count}}
    + +

    Area Director Load: Documents directly assigned to AD

    + + + + + + + + + {# (divider) #} + + + + + + {% for ad in ad_summary %} + + + + + + + + + + {% endfor %} + + + + + + + + + + + + +
    ADArea NameWGs for ADI-DsPages% I-Ds% Pages
    {{ad.ad}}{{ad.area}}{{ad.ad_group_count}}{{ad.doc_count}}{{ad.page_count}}{{ad.doc_percent|floatformat:1}}{{ad.page_percent|floatformat:1}}
    Totals{{ad_totals.ad_group_count}}{{ad_totals.doc_count}}{{ad_totals.page_count}}
    + +

    Working Group Summary

    + + + + + + + + + + + + + + {% for wg in wg_summary %} + + + + + + + + + + {% endfor %} + +
    WGAreaADI-DsPagesRFCsRFCs in last 2 years
    {{wg.wg}}{{wg.area}}{{wg.ad}}{{wg.doc_count}}{{wg.page_count}}{{wg.rfc_count}}{{wg.recent_rfc_count}}
    +{% endblock %} +{% block js %} + +{% endblock %} \ No newline at end of file diff --git a/ietf/templates/ietfauth/apikeys.html b/ietf/templates/ietfauth/apikeys.html index ab6194151c8..f4769d2d90a 100644 --- a/ietf/templates/ietfauth/apikeys.html +++ b/ietf/templates/ietfauth/apikeys.html @@ -12,7 +12,7 @@

    API keys
    - {{ user.username }} + {{ user.username }}

    {% csrf_token %} {% if person.apikeys.all %} @@ -37,9 +37,9 @@

    {{ key.created }} {{ key.latest }} {{ key.count }} - {{ key.valid }} + {{ key.valid }} - {{ key.hash }} + {{ key.hash }} {% if key.valid %} @@ -63,4 +63,4 @@

    {% endblock %} {% block js %} -{% endblock %} +{% endblock %} \ No newline at end of file diff --git a/ietf/templates/ietfauth/edit_field.html b/ietf/templates/ietfauth/edit_field.html index 4e8c5177a79..23d1b71982f 100644 --- a/ietf/templates/ietfauth/edit_field.html +++ b/ietf/templates/ietfauth/edit_field.html @@ -8,7 +8,7 @@

    {{ title }}
    - {{ person.plain_name }} + {{ person.plain_name }}

    {{ info|striptags }} diff --git a/ietf/templates/ietfauth/review_overview.html b/ietf/templates/ietfauth/review_overview.html index 0f7e66913f1..28c6e055993 100644 --- a/ietf/templates/ietfauth/review_overview.html +++ b/ietf/templates/ietfauth/review_overview.html @@ -1,7 +1,7 @@ {% extends "base.html" %} {# Copyright The IETF Trust 2015-2019, All Rights Reserved #} {% load origin %} -{% load django_bootstrap5 static %} +{% load django_bootstrap5 static ietf_filters %} {% block pagehead %} {{ review_wish_form.media.css }} @@ -12,7 +12,7 @@

    Review overview
    - {{ request.user }} + {{ request.user }}

    Assigned reviews

    {% if open_review_assignments %} @@ -51,7 +51,7 @@

    Assigned reviews

    {{ r.review_request.type.name }} {{ r.review_request.deadline|date:"Y-m-d" }} - {% if r.due %}{{ r.due }} day{{ r.due|pluralize }}{% endif %} + {% if r.due %}{{ r.due }} day{{ r.due|pluralize }}{% endif %} {% endfor %} @@ -98,10 +98,10 @@

    Latest closed review assignments

    {{ r.review_request.type.name }} {{ r.review_request.deadline|date:"Y-m-d" }} - {% if r.due %}{{ r.due }} day{{ r.due|pluralize }}{% endif %} + {% if r.due %}{{ r.due }} day{{ r.due|pluralize }}{% endif %} - {{ r.state.name }} + {{ r.state.name|badgeify }} {% if r.result %}{{ r.result.name }}{% endif %} @@ -169,13 +169,13 @@

    {% endif %} {% if teams %}

    - Add a draft that you would like to review when it becomes available for review: + Add an Internet-Draft that you would like to review when it becomes available for review:

    {% csrf_token %} {% bootstrap_form review_wish_form %}
    {% endif %} @@ -186,10 +186,10 @@

    - - @@ -208,7 +208,7 @@

    Skip next assignments

    diff --git a/ietf/templates/ietfauth/whitelist_form.html b/ietf/templates/ietfauth/whitelist_form.html deleted file mode 100644 index 8b5670931cb..00000000000 --- a/ietf/templates/ietfauth/whitelist_form.html +++ /dev/null @@ -1,78 +0,0 @@ -{% extends "base.html" %} -{# Copyright The IETF Trust 2016, All Rights Reserved #} -{% load origin %} -{% load django_bootstrap5 %} -{% block title %}Set up test email address{% endblock %} -{% block content %} - {% origin %} - {% if success %} -

    Whitelist entry creation successful

    -

    - Please ask the requestor to try the - account creation form - again, with the whitelisted email address. -

    - {% else %} -

    Add a whitelist entry for account creation.

    -

    - When an email request comes in for assistance with account creation - because the automated account creation has failed, you can add the - address to an account creation whitelist here. -

    -

    - Before you do so, please complete the following 3 verification steps: -

    -
      -
    1. - Has the person provided relevant information in his request, or has he simply - copied the text from the account creation failure message? All genuine (non-spam) - account creation requests seen between 2009 and 2016 for tools.ietf.org have - contained a reasonable request message, rather than just copy-pasting the account - creation failure message. If there's no proper request message, step 2 below can - be performed to make sure the request is bogus, but if that also fails, no further - effort should be needed. -
    2. -
    3. - Google for the person's name within the ietf.org site: "Jane Doe site:ietf.org". If - found, and the email address matches an address used in drafts or discussions, - things are fine, and it's OK to add the address to the whitelist using this form, - and ask the person to please try the - account creation form - again. -
    4. -
    5. -

      - If google finds no trace of the person being an ietf participant, he or she could - still be somebody who is just getting involved in IETF work. A datatracker account - is probably not necessary, (no account is necessary to 'join' a WG -- the right thing - in that case is to join the right mailing list, and the person could be told so) -- - but in case this is a legitimate request, please email the person and ask: - - "Which wgs do you require a password for?" - -

      -

      - This is a bit of a trick question, because it is very unlikely that somebody who - isn't involved in IETF work will give a reasonable response, while almost any answer - from somebody who is doing IETF work will show that they have some clue. -

      -

      - Please note the exact wording. Do not ask about "working groups" -- - that will make it easier for people to google for IETF working groups. Ask the - question as given above, with lowercase "wgs". -

      -

      - If the answer to this question shows clue, then add the address to the whitelist - using this form, and ask the person to please try the - account creation form - again. -

      -
    6. -
    - - {% csrf_token %} - {% bootstrap_form form %} - - - {% endif %} -{% endblock %} \ No newline at end of file diff --git a/ietf/templates/ipr/.gitignore b/ietf/templates/ipr/.gitignore deleted file mode 100644 index a74b07aee47..00000000000 --- a/ietf/templates/ipr/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/*.pyc diff --git a/ietf/templates/ipr/add_comment.html b/ietf/templates/ipr/add_comment.html index 7855224c433..18bc37c75ca 100644 --- a/ietf/templates/ipr/add_comment.html +++ b/ietf/templates/ipr/add_comment.html @@ -8,7 +8,7 @@

    Add comment
    - {{ ipr }} + {{ ipr }}

    The comment will be added to the history trail of the disclosure. diff --git a/ietf/templates/ipr/add_email.html b/ietf/templates/ipr/add_email.html index 2d3940049a0..e7be36f73b8 100644 --- a/ietf/templates/ipr/add_email.html +++ b/ietf/templates/ipr/add_email.html @@ -8,7 +8,7 @@

    Add email
    - {{ ipr }} + {{ ipr }}

    The email will be added to the history trail of the disclosure. diff --git a/ietf/templates/ipr/admin_list.html b/ietf/templates/ipr/admin_list.html index feb6c9d2f52..23e5883eaa6 100644 --- a/ietf/templates/ipr/admin_list.html +++ b/ietf/templates/ipr/admin_list.html @@ -18,7 +18,7 @@

    IPR Admin
    - + {% for s in states %} {{ s.name }} {% if not forloop.last %}/{% endif %} diff --git a/ietf/templates/ipr/deleted.html b/ietf/templates/ipr/deleted.html new file mode 100644 index 00000000000..24f696ebca0 --- /dev/null +++ b/ietf/templates/ipr/deleted.html @@ -0,0 +1,16 @@ +{% extends "base.html" %} +{# Copyright The IETF Trust 2015-2023, All Rights Reserved #} +{% load ietf_filters origin %} +{% block title %}Removed IPR Disclosure{% endblock %} +{% block content %} + {% origin %} +

    Removed IPR disclosure

    +

    + {{ removed.reason }} +

    + {% if user|has_role:"Secretariat" and ipr.exists %} +

    + This disclosure has not yet been deleted and parts of its content is available through, e.g, the history view and the /api/v1 views. +

    + {% endif %} + {% endblock %} \ No newline at end of file diff --git a/ietf/templates/ipr/details_edit.html b/ietf/templates/ipr/details_edit.html index 2dc51bc7edc..1aadb5bb3d0 100644 --- a/ietf/templates/ipr/details_edit.html +++ b/ietf/templates/ipr/details_edit.html @@ -32,7 +32,7 @@

    The Patent Disclosure and Licensing Declaration Template for Third Party IPR regarding an IETF document or contribution when the person letting the IETF know about the patent has no relationship with the patent owners. Click - here + here if you want to disclose information about patents or patent applications where you do have a relationship to the patent owners or patent applicants. @@ -121,47 +121,22 @@

    {% endif %} {% if type != "generic" %}

    {% cycle section %}. IETF document or other contribution to which this IPR disclosure relates

    -

    +

    If an Internet-Draft or RFC includes multiple parts and it is not reasonably apparent which part of such Internet-Draft or RFC is alleged - to be covered by the patent information disclosed in Section - V(A) or V(B), please identify the sections of - the Internet-Draft or RFC that are alleged to be so + to be covered by the patent information disclosed in Section V, + please identify the sections of the Internet-Draft or RFC that are alleged to be so covered.

    {{ draft_formset.management_form }} {% for draft_form in draft_formset %} -
    - -
    - {{ draft_form.id }} - {{ draft_form.document }} - {% if draft_form.document.errors %}
    {{ draft_form.document.errors }}
    {% endif %} -
    -
    - {% bootstrap_field draft_form.revisions class="form-control" placeholder="Revisions, e.g., 04-07" show_help=False show_label=False %} - -
    -
    - {% bootstrap_field draft_form.sections class="form-control" placeholder="Sections" show_help=False show_label=False %} - -
    -
    - {% endfor %} - {% comment %} - {% for draft_form in draft_formset %} -
    -
    {% bootstrap_label draft_form.document.label %}
    -
    {% bootstrap_field draft_form.document label_class="d-none" show_help=False %}
    -
    - {% bootstrap_field draft_form.revisions placeholder="Revisions, e.g., 04-07" label_class="d-none" show_help=False %} -
    -
    - {% bootstrap_field draft_form.sections placeholder="Sections" label_class="d-none" show_help=False %} -
    +
    + {% include "ipr/details_edit_draft.html" with draft_form=draft_form only %}
    {% endfor %} - {% endcomment %} +
    + {% include "ipr/details_edit_draft.html" with draft_form=draft_formset.empty_form only %} +
    @@ -178,6 +153,13 @@

    i.e., patents or patent applications required to be disclosed by Section 5 of RFC8179

    {% if form.patent_number %} + {% if form.is_blanket_disclosure %} +

    + This IPR disclosure must either identify a specific patent or patents in sections V(A) and V(B) + below, or be made as a blanket IPR disclosure. +

    + {% bootstrap_field form.is_blanket_disclosure layout='horizontal' %} + {% endif %}

    A. For granted patents or published pending patent applications, please provide the following information: diff --git a/ietf/templates/ipr/details_edit_draft.html b/ietf/templates/ipr/details_edit_draft.html new file mode 100644 index 00000000000..64e5afe60a1 --- /dev/null +++ b/ietf/templates/ipr/details_edit_draft.html @@ -0,0 +1,14 @@ +{% load django_bootstrap5 %} +

    + {{ draft_form.id }} + {{ draft_form.document }} + {% if draft_form.document.errors %}
    {{ draft_form.document.errors }}
    {% endif %} +
    +
    + {% bootstrap_field draft_form.revisions class="form-control" placeholder="Revisions, e.g., 04-07" show_help=False show_label=False %} + +
    +
    + {% bootstrap_field draft_form.sections class="form-control" placeholder="Sections" show_help=False show_label=False %} + +
    diff --git a/ietf/templates/ipr/details_history.html b/ietf/templates/ipr/details_history.html index f796901938b..11730741b47 100644 --- a/ietf/templates/ipr/details_history.html +++ b/ietf/templates/ipr/details_history.html @@ -11,7 +11,7 @@

    History for IPR disclosure
    - {{ ipr.title }} + {{ ipr.title }}

    {% include "ipr/details_tabs.html" %} {% if user|has_role:"Area Director,Secretariat,IANA,RFC Editor" %} @@ -51,7 +51,7 @@

    {% if administrative_list == 'pending' %} {% with ipr.get_latest_event_msgout as latest_msgout %} diff --git a/ietf/templates/ipr/notify.html b/ietf/templates/ipr/notify.html index 0ac966a5d85..7afb30add63 100644 --- a/ietf/templates/ipr/notify.html +++ b/ietf/templates/ipr/notify.html @@ -8,7 +8,7 @@

    Send Notification{{ formset|pluralize }}
    - {{ ipr }} + {{ ipr }}

    {% csrf_token %} diff --git a/ietf/templates/ipr/posted_document_email.txt b/ietf/templates/ipr/posted_document_email.txt index 397b686b295..1c56e8deac1 100644 --- a/ietf/templates/ipr/posted_document_email.txt +++ b/ietf/templates/ipr/posted_document_email.txt @@ -6,7 +6,7 @@ Cc: {{ cc_email }} Dear {{ to_name }}: {% filter wordwrap:78 %} -An IPR disclosure that pertains to your {{ doc_info }} was submitted to the IETF Secretariat on {{ ipr.get_latest_event_submitted.time|date:"Y-m-d" }} and has been posted on the "IETF Page of Intellectual Property Rights Disclosures" ({{ settings.IDTRACKER_BASE_URL }}{% url "ietf.ipr.views.history" id=ipr.pk %}). The title of the IPR disclosure is "{{ ipr.title }}" +An IPR disclosure that pertains to your {{ doc_info }} was submitted to the IETF Secretariat on {{ ipr.get_latest_event_submitted.time|date:"Y-m-d" }} and has been posted on the "IETF Page of Intellectual Property Rights Disclosures" ({{ settings.IDTRACKER_BASE_URL }}{% url "ietf.ipr.views.show" id=ipr.pk %}). The title of the IPR disclosure is "{{ ipr.title }}" {% endfilter %} Thank you diff --git a/ietf/templates/ipr/removed.html b/ietf/templates/ipr/removed.html index 775819df62f..96bf6ab899f 100644 --- a/ietf/templates/ipr/removed.html +++ b/ietf/templates/ipr/removed.html @@ -1,11 +1,15 @@ {% extends "base.html" %} -{# Copyright The IETF Trust 2015, All Rights Reserved #} +{# Copyright The IETF Trust 2015-2023, All Rights Reserved #} {% load origin %} {% block title %}{{ ipr.title }}{% endblock %} {% block content %} {% origin %}

    {{ ipr.title }}

    - This IPR disclosure was removed at the submitter's request. + {% if ipr.state.slug == "removed" %} + This IPR disclosure was removed at the submitter's request. + {% elif ipr.state.slug == "removed_objfalse" %} + This IPR disclosure was removed as objectively false. + {% endif %}

    {% endblock %} \ No newline at end of file diff --git a/ietf/templates/ipr/search_doc_list.html b/ietf/templates/ipr/search_doc_list.html index 24fbfd01ba0..e67f67fecda 100644 --- a/ietf/templates/ipr/search_doc_list.html +++ b/ietf/templates/ipr/search_doc_list.html @@ -7,15 +7,15 @@

    IPR disclosures
    - Select Internet-Draft + Select Internet-Draft

    Please select one of following I-Ds:

    diff --git a/ietf/templates/ipr/search_doc_result.html b/ietf/templates/ipr/search_doc_result.html index 5a0186c8fd7..b003a321089 100644 --- a/ietf/templates/ipr/search_doc_result.html +++ b/ietf/templates/ipr/search_doc_result.html @@ -8,7 +8,7 @@ {% endblock %} -{% block search_header %}Document IPR search results
    {{doc}}{% endblock %} +{% block search_header %}Document IPR search results
    {{doc}}{% endblock %} {% block search_result %}

    Total number of IPR disclosures found: {{ iprs|length }}.

    @@ -28,7 +28,7 @@
    - @@ -54,23 +54,34 @@ - {% for doc in docs %} + {% for d in docs %} - {% with doc.iprdocrel_set.all as doc_iprs %} + {% with d.iprdocrel_set.all as doc_iprs %} {% if doc_iprs %} {% for ipr in doc_iprs %} {% if ipr.disclosure.state_id in states %} - @@ -81,7 +92,7 @@ diff --git a/ietf/templates/ipr/search_doctitle_result.html b/ietf/templates/ipr/search_doctitle_result.html index b7a8a8b31ef..57fa17e912c 100644 --- a/ietf/templates/ipr/search_doctitle_result.html +++ b/ietf/templates/ipr/search_doctitle_result.html @@ -24,20 +24,20 @@ - {% for alias in docs %} + {% for doc in docs %} - {% if alias.document.ipr %} - {% for ipr in alias.document.ipr %} + {% if doc.ipr %} + {% for ipr in doc.ipr %} @@ -58,7 +58,7 @@ - + {% endif %} diff --git a/ietf/templates/ipr/search_form.html b/ietf/templates/ipr/search_form.html index e35eafd26ee..34f5af87b65 100644 --- a/ietf/templates/ipr/search_form.html +++ b/ietf/templates/ipr/search_form.html @@ -3,86 +3,103 @@ {% load origin %} {% origin %}

    IPR Search

    - - {% if user|has_role:"Secretariat" %} -

    State Filter

    - {% bootstrap_field form.state %} - {% endif %} -

    Document search

    -
    - {% bootstrap_label form.draft.label label_for=form.draft.id_for_label label_class="form-label" %} -
    - {% render_field form.draft class="form-control" placeholder="draft-..." %} - -
    + +
    +
    +

    + +

    +
    +
    + + + {% if user|has_role:"Secretariat" %} +

    State Filter

    + {% bootstrap_field form.state %} + {% endif %} +

    Document search

    +
    + {% bootstrap_label form.draft.label label_for=form.draft.id_for_label label_class="form-label" %} +
    + {% render_field form.draft class="form-control" placeholder="draft-..." %} + +
    +
    +
    + {% bootstrap_label form.rfc.label label_for=form.rfc.id_for_label label_class="form-label" %} +
    + {% render_field form.rfc class="form-control" placeholder="123..." %} + +
    +
    +
    + {% bootstrap_label form.doctitle.label|cut:":" label_for=form.doctitle.id_for_label label_class="form-label" %} +
    + {% render_field form.doctitle class="form-control" placeholder="protocol..." %} + +
    +
    +
    + {% bootstrap_label form.group.label|cut:":" label_for=form.group.id_for_label label_class="form-label" %} +
    + {% render_field form.group class="form-select" %} + +
    +
    +

    IPR search

    +
    + {% bootstrap_label form.holder.label|cut:":" label_for=form.holder.id_for_label label_class="form-label" %} +
    + {% render_field form.holder class="form-control" placeholder="John Doe..." %} + +
    +
    +
    + {% bootstrap_label form.iprtitle.label|cut:":" label_for=form.iprtitle.id_for_label label_class="form-label" %} +
    + {% render_field form.iprtitle class="form-control" placeholder="protocol..." %} + +
    +
    +
    + {% bootstrap_label form.patent.label|cut:":" label_for=form.patent.id_for_label label_class="form-label" %} +
    + {% render_field form.patent class="form-control" %} + +
    +
    + This search string must contain at least three characters, including + at least one digit, and include punctuation marks. For best results, + please enter the entire string, or as much of it as possible. +
    +
    + + + +
    -
    - {% bootstrap_label form.rfc.label label_for=form.rfc.id_for_label label_class="form-label" %} -
    - {% render_field form.rfc class="form-control" placeholder="123..." %} - -
    -
    -
    - {% bootstrap_label form.doctitle.label|cut:":" label_for=form.doctitle.id_for_label label_class="form-label" %} -
    - {% render_field form.doctitle class="form-control" placeholder="protocol..." %} - -
    -
    -
    - {% bootstrap_label form.group.label|cut:":" label_for=form.group.id_for_label label_class="form-label" %} -
    - {% render_field form.group class="form-select" %} - -
    -
    -

    IPR search

    -
    - {% bootstrap_label form.holder.label|cut:":" label_for=form.holder.id_for_label label_class="form-label" %} -
    - {% render_field form.holder class="form-control" placeholder="John Doe..." %} - -
    -
    -
    - {% bootstrap_label form.iprtitle.label|cut:":" label_for=form.iprtitle.id_for_label label_class="form-label" %} -
    - {% render_field form.iprtitle class="form-control" placeholder="protocol..." %} - -
    -
    -
    - {% bootstrap_label form.patent.label|cut:":" label_for=form.patent.id_for_label label_class="form-label" %} -
    - {% render_field form.patent class="form-control" %} - -
    -
    - This search string must contain at least three characters, including - at least one digit, and include punctuation marks. For best results, - please enter the entire string, or as much of it as possible. -
    -
    - - -

    +

    +
    + +

    The material posted as IPR disclosures should be viewed as originating from the source of that information, and any issue or question related to the material should be directed to the source rather than the diff --git a/ietf/templates/ipr/search_result.html b/ietf/templates/ipr/search_result.html index a104e45c070..449a6f7f8bc 100644 --- a/ietf/templates/ipr/search_result.html +++ b/ietf/templates/ipr/search_result.html @@ -54,7 +54,7 @@

    is related to {% for item in iprdocrels %} {% if forloop.last and forloop.counter > 1 %}and{% endif %} - {{ item.formatted_name|urlize_ietf_docs }} ("{{ item.document.document.title }}"){% if not forloop.last and forloop.counter > 1 %},{% endif %} + {{ item.formatted_name|urlize_ietf_docs }}{% if item.document.title %} ("{{ item.document.title }}"){% endif %}{% if not forloop.last and forloop.counter > 1 %},{% endif %} {% endfor %} {% endif %} {% endwith %} @@ -100,4 +100,4 @@

    {% block js %} -{% endblock %} +{% endblock %} \ No newline at end of file diff --git a/ietf/templates/ipr/search_wg_result.html b/ietf/templates/ipr/search_wg_result.html index ae477a26999..1561e05ba30 100644 --- a/ietf/templates/ipr/search_wg_result.html +++ b/ietf/templates/ipr/search_wg_result.html @@ -20,22 +20,22 @@

    - {% for alias in docs %} + {% for doc in docs %} - {% if alias.document.ipr %} - {% for ipr in alias.document.ipr %} + {% if doc.ipr %} + {% for ipr in doc.ipr %} @@ -57,7 +57,7 @@ {% endif %} diff --git a/ietf/templates/ipr/state.html b/ietf/templates/ipr/state.html index 259a007483e..0b6391a7826 100644 --- a/ietf/templates/ipr/state.html +++ b/ietf/templates/ipr/state.html @@ -8,7 +8,7 @@

    Change State
    - {{ ipr }} + {{ ipr }}

    {% csrf_token %} diff --git a/ietf/templates/ipr/update_submitter_email.txt b/ietf/templates/ipr/update_submitter_email.txt index 599ceab54fc..f45a9072ab1 100644 --- a/ietf/templates/ipr/update_submitter_email.txt +++ b/ietf/templates/ipr/update_submitter_email.txt @@ -5,22 +5,25 @@ Reply-To: {{ reply_to }} Dear {{ to_name }}: -We have just received a request to update the IPR disclosure(s) submitted by you: +We have just received a request to update one or more IPR disclosures +previously submitted by you: {% for ipr in iprs %} {{ ipr.title }} {{ ipr.get_absolute_url }} {% endfor %} -The name and email address of the person who submitted the update to your IPR disclosure are: -{{ new_ipr.submitter_name }}, {{ new_ipr.submitter_email }}. +The name and email address of the person who submitted the update to +your IPR disclosure are: {{ new_ipr.submitter_name }}, {{ new_ipr.submitter_email }}. +If this is you or someone known by you to be authorized to update +the above disclosures, please respond to this message to confirm. -We will not post this update unless we receive positive confirmation from you that -{{ new_ipr.submitter_name }} is authorized to update your disclosure. -Please respond to this message to confirm. +We will not post this update unless we receive positive confirmation +from you that the update is indeed from you or someone authorized to +update the above listed disclosures. If we do not hear from you within 30 days, we will inform {{ new_ipr.submitter_name }} -that we were not able to secure approval for posting and that we are therefore rejecting -the update until we can be assured it is authorized. +that we were not able to secure approval for posting and that we are +therefore rejecting the update until we can be assured it is authorized. Thank you diff --git a/ietf/templates/liaisons/.gitignore b/ietf/templates/liaisons/.gitignore deleted file mode 100644 index a74b07aee47..00000000000 --- a/ietf/templates/liaisons/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/*.pyc diff --git a/ietf/templates/liaisons/add_comment.html b/ietf/templates/liaisons/add_comment.html index 8497d4c2f35..0bf8bb59af5 100644 --- a/ietf/templates/liaisons/add_comment.html +++ b/ietf/templates/liaisons/add_comment.html @@ -8,7 +8,7 @@

    Add comment
    - {{ liaison.title }} + {{ liaison.title }}

    The comment will be added to the history trail of the statement. diff --git a/ietf/templates/liaisons/detail.html b/ietf/templates/liaisons/detail.html index 63f427f383c..d46c8d1c989 100644 --- a/ietf/templates/liaisons/detail.html +++ b/ietf/templates/liaisons/detail.html @@ -11,8 +11,9 @@

    Liaison statement
    - {% include 'liaisons/liaison_title.html' %} + {% include 'liaisons/liaison_title.html' %}

    + {% include "liaisons/liaison_desc.html" only %} {% include "liaisons/detail_tabs.html" %}
    + Setting + Value
    - {{ t.reviewer_settings.skip_next }} + {{ t.reviewer_settings.skip_next|yesno }}
    {% person_link e.by %} {% if e.message %} - {% if e.response_due %}Response due {{ e.response_due|date:"Y-m-d" }}{% endif %} + {% if e.response_due %}Response due {{ e.response_due|date:"Y-m-d" }}{% endif %} {# FIXME: can't do format_history_text, because that inserts a
    into the
    , which is illegal. Need to rework the snippeting. #}
                                     
    {{ e.message|render_message_for_history|urlize_ietf_docs|linkify }}
    {% else %} diff --git a/ietf/templates/ipr/details_view.html b/ietf/templates/ipr/details_view.html index bdda164a629..9ba63114ae6 100644 --- a/ietf/templates/ipr/details_view.html +++ b/ietf/templates/ipr/details_view.html @@ -1,5 +1,5 @@ {% extends "base.html" %} -{# Copyright The IETF Trust 2015, 2017. All Rights Reserved. #} +{# Copyright The IETF Trust 2015-2023. All Rights Reserved. #} {% load origin %} {% load ietf_filters ipr_filters textfilters %} {% block title %}IPR Details - {{ ipr.title }}{% endblock %} @@ -12,7 +12,7 @@

    IPR Details
    - {{ ipr.title }} + {{ ipr.title }}

    {% include "ipr/details_tabs.html" %}
    @@ -103,6 +103,8 @@

    Updates

    IPR Disclosure ID #{{ item.source.id }}, {% if item.source.state.slug == "removed" %} "{{ item.source.title }}" (which was removed at the request of the submitter) + {% elif item.source.state.slug == "removed_objfalse" %} + "{{ item.source.title }}" (which was removed as objectively false) {% else %} "{{ item.source.title }}" {% endif %} @@ -122,6 +124,8 @@

    Updates

    IPR Disclosure ID #{{ item.target.id }}, {% if item.target.state.slug == "removed" %} "{{ item.target.title }}" (which was removed at the request of the submitter) + {% elif item.source.state.slug == "removed_objfalse" %} + "{{ item.source.title }}" (which was removed as objectively false) {% elif item.target.state.slug == "rejected" %} "{{ item.target.title }}" (which was rejected) {% elif item.target.state.slug == "parked" %} @@ -379,7 +383,8 @@

    {{ iprdocrel.doc_type }}:
    - {{ iprdocrel.formatted_name|urlize_ietf_docs }} ("{{ iprdocrel.document.document.title }}") + {{ iprdocrel.formatted_name|urlize_ietf_docs }} + {% if iprdocrel.document.title %}("{{ iprdocrel.document.title }}"){% endif %}
    {% if iprdocrel.revisions %}
    @@ -388,6 +393,13 @@

    {{ iprdocrel.revisions }}
    + {% elif iprdocrel.doc_type == "Internet-Draft" %} +
    + Notice: +
    +
    + {{ iprdocrel|no_revisions_message }} +
    {% endif %} {% if iprdocrel.sections %}
    @@ -418,7 +430,8 @@

    {{ iprdocrel.doc_type }}:

    - {{ iprdocrel.formatted_name|urlize_ietf_docs }} ("{{ iprdocrel.document.document.title }}") + {{ iprdocrel.formatted_name|urlize_ietf_docs }} + {% if iprdocrel.document.title %}("{{ iprdocrel.document.title }}"){% endif %}
    {% if iprdocrel.revisions %}
    @@ -427,6 +440,13 @@

    {{ iprdocrel.revisions }}
    + {% elif iprdocrel.doc_type == "Internet-Draft" %} +
    + Notice: +
    +
    + {{ iprdocrel|no_revisions_message }} +
    {% endif %} {% if iprdocrel.sections %}
    @@ -455,7 +475,7 @@

    {% cycle section %}. Disclosure of Patent Information
    - i.e., patents or patent applications required to be disclosed by {{ in_force_ipr_rfc|urlize_ietf_docs }} + i.e., patents or patent applications required to be disclosed by {{ in_force_ipr_rfc|urlize_ietf_docs }}

    A. For granted patents or published pending patent applications, please provide the following information: diff --git a/ietf/templates/ipr/email.html b/ietf/templates/ipr/email.html index 9830c731136..1291247f904 100644 --- a/ietf/templates/ipr/email.html +++ b/ietf/templates/ipr/email.html @@ -12,7 +12,7 @@

    Email submitter
    - {{ ipr.title }} + {{ ipr.title }}

    {% csrf_token %} diff --git a/ietf/templates/ipr/ipr_table.html b/ietf/templates/ipr/ipr_table.html index ce3982c9873..d8247ea5875 100644 --- a/ietf/templates/ipr/ipr_table.html +++ b/ietf/templates/ipr/ipr_table.html @@ -39,10 +39,13 @@ {% endif %} {% endfor %} - {% else %} + {% elif ipr.state_id == 'removed' %}
    {{ ipr.title }}
    This IPR disclosure was removed at the request of the submitter. - {% endif %} + {% elif ipr.state_id == 'removed_objfalse' %} +
    {{ ipr.title }}
    + This IPR disclosure was removed as objectively false. + {% endif %} {# Intentionally not emitting anything for any other states #}

    {{ ipr.time|date:"Y-m-d" }} {{ ipr.id }}{{ ipr.title }}{% if ipr.state_id == 'removed' %}Removed{% endif %} + {{ ipr.title }}{% if ipr.state_id == 'removed' or ipr.state_id == 'removed_objfalse' %}Removed{% endif %} {% if ipr.updates %}
    (Updates ID#: {% for upd in ipr.updates %}{{upd.target_id}}{% if not forloop.last %}, {% endif %}{% endfor %}){% endif %}
    - Results for {{ doc.name|prettystdname|urlize_ietf_docs }} ("{{ doc.document.title }}"){% if not forloop.first %}{% if doc.related %}, which was {{ doc.relation|lower }} {{ doc.related.source|prettystdname|urlize_ietf_docs }} ("{{ doc.related.source.title }}"){% endif %}{% endif %} + Results for {{ d.name|prettystdname|urlize_ietf_docs }} + ("{{ d.title }}"){% if d != doc and d.related %}, which + {% if d == d.related.source %} + {{ d.relation|lower }} + {{ d.related.target|prettystdname|urlize_ietf_docs }} + ("{{ d.related.target.title }}") + {% else %} + was {{ d.relation|lower }} + {{ d.related.source|prettystdname|urlize_ietf_docs }} + ("{{ d.related.source.title }}") + {% endif %} + {% endif %}
    {{ ipr.disclosure.time|date:"Y-m-d" }} {{ ipr.disclosure.id }}{{ ipr.disclosure.title }}{% if ipr.disclosure.state_id == 'removed' %} (Removed) {% endif %} + {{ ipr.disclosure.title }}{% if ipr.disclosure.state_id == 'removed' or ipr.disclosure.state_id == 'removed_objfalse' %} (Removed) {% endif %} {% if ipr.disclosure.updates %}
    (Updates ID#: {% for upd in ipr.disclosure.updates %}{{upd.target_id}}{% if not forloop.last %}, {% endif %}{% endfor %}){% endif %}
    - No IPR disclosures have been submitted directly on {{ doc.name|prettystdname|urlize_ietf_docs }}{% if iprs %}, + No IPR disclosures have been submitted directly on {{ d.name|prettystdname|urlize_ietf_docs }}{% if iprs %}, but there are disclosures on {% if docs|length == 2 %}a related document{% else %}related documents{% endif %}, listed on this page{% endif %}.
    Statement
    - IPR that is related to {{ alias.name|prettystdname:""|urlize_ietf_docs }} ("{{ alias.document.title }}") - {% if alias.related %} - that was {{ alias.relation|lower }} {{ alias.related.source.name|prettystdname:""|urlize_ietf_docs }} ("{{ alias.related.source.title }}") + IPR that is related to {{ doc.name|prettystdname:""|urlize_ietf_docs }} ("{{ doc.title }}") + {% if doc.related %} + that was {{ doc.relation|lower }} {{ doc.related.source.name|prettystdname:""|urlize_ietf_docs }} ("{{ doc.related.source.title }}") {% endif %}
    {{ ipr.disclosure.time|date:"Y-m-d" }} {{ ipr.disclosure.id }}
    No IPR disclosures related to {{ alias.name|prettystdname|urlize_ietf_docs }} have been submitted.No IPR disclosures related to {{ doc.name|prettystdname|urlize_ietf_docs }} have been submitted.
    Statement
    - IPR related to {{ alias.name|prettystdname|urlize_ietf_docs }} ("{{ alias.document.title }}") - {% if alias.related %} - that was {{ alias.relation|lower }} {{ alias.related.source|prettystdname|urlize_ietf_docs }} ("{{ alias.related.source.title|escape }}") + IPR related to {{ doc.name|prettystdname|urlize_ietf_docs }} ("{{ doc.title }}") + {% if doc.related %} + that was {{ doc.relation|lower }} {{ doc.related.source|prettystdname|urlize_ietf_docs }} ("{{ doc.related.source.title|escape }}") {% endif %} - {% if alias.product_of_this_wg %}, a product of the {{ q }} WG{% endif %} + {% if doc.product_of_this_wg %}, a product of the {{ q }} WG{% endif %} :
    {{ ipr.disclosure.time|date:"Y-m-d" }} {{ ipr.disclosure.id }} - No IPR disclosures related to {{ alias.name|prettystdname|urlize_ietf_docs }} have been submitted. + No IPR disclosures related to {{ doc.name|prettystdname|urlize_ietf_docs }} have been submitted.
    @@ -31,7 +32,7 @@

    {% if liaison.from_contact %}

    - + {% endif %} @@ -87,6 +88,7 @@

    {% csrf_token %} @@ -229,9 +231,10 @@

    {% endif %} {% if liaison.state.slug == 'pending' and can_edit %} - + {% endif %} {% if liaison.state.slug == 'posted' and user|has_role:"Secretariat" %} @@ -243,7 +246,8 @@

    {% if liaison.state.slug == 'dead' and can_edit %} {% endif %} {% if liaison.state.slug == 'pending' and can_edit or liaison.state.slug == 'dead' and can_edit %}{% endif %} -{% endblock %} +{% endblock %} \ No newline at end of file diff --git a/ietf/templates/liaisons/detail_history.html b/ietf/templates/liaisons/detail_history.html index fcb91e301f0..635466ed3ab 100644 --- a/ietf/templates/liaisons/detail_history.html +++ b/ietf/templates/liaisons/detail_history.html @@ -8,7 +8,7 @@

    History for Liaison Statement
    - {{ liaison.title }} + {{ liaison.title }}

    {% include "liaisons/detail_tabs.html" %} {% if user|has_role:"Area Director,Secretariat,IANA,RFC Editor" %} diff --git a/ietf/templates/liaisons/edit.html b/ietf/templates/liaisons/edit.html index 2c7b4b65ba4..1684425eb2a 100644 --- a/ietf/templates/liaisons/edit.html +++ b/ietf/templates/liaisons/edit.html @@ -19,7 +19,7 @@ {% origin %}

    {% if liaison %} - Edit liaison
    {{ liaison }} + Edit liaison
    {{ liaison }} {% else %} Send Liaison Statement {% endif %} @@ -47,21 +47,43 @@

    method="post" enctype="multipart/form-data" data-edit-form="{{ form.edit }}" - data-ajax-info-url="{% url "ietf.liaisons.views.ajax_get_liaison_info" %}"> + data-ajax-info-url="{% url 'ietf.liaisons.views.ajax_get_liaison_info' %}"> {% csrf_token %} - {% for fieldset in form.fieldsets %} -

    {{ fieldset.name }}

    - {% for field in fieldset %} - {% if field.id_for_label != "id_attachments" %} - {% bootstrap_field field layout="horizontal" %} - {% else %} -
    -

    {{ field.label }}

    -
    {{ field }}
    -
    - {% endif %} - {% endfor %} - {% endfor %} +

    From

    + {% bootstrap_field form.from_groups layout="horizontal" %} + {% bootstrap_field form.from_contact layout="horizontal" %} + {% bootstrap_field form.response_contacts layout="horizontal" %} + {% if form.approved %} + {% bootstrap_field form.approved layout="horizontal" %} + {% endif %} +

    To

    + {% bootstrap_field form.to_groups layout="horizontal" %} + {% bootstrap_field form.to_contacts layout="horizontal" %} +

    Other email addresses

    + {% bootstrap_field form.technical_contacts layout="horizontal" %} + {% if form.action_holder_contacts %} + {% bootstrap_field form.action_holder_contacts layout="horizontal" %} + {% endif %} + {% bootstrap_field form.cc_contacts layout="horizontal" %} +

    Purpose

    + {% bootstrap_field form.purpose layout="horizontal" %} + {% bootstrap_field form.deadline layout="horizontal" %} +

    Reference

    + {% bootstrap_field form.other_identifiers layout="horizontal" %} + {% bootstrap_field form.related_to layout="horizontal" %} +

    Liaison Statement

    + {% bootstrap_field form.title layout="horizontal" %} + {% bootstrap_field form.submitted_date layout="horizontal" %} + {% bootstrap_field form.body layout="horizontal" %} +
    +

    {{ form.attachments.label }}

    +
    {{ form.attachments }}
    +
    +

    Add attachment

    + {% bootstrap_field form.attach_title layout="horizontal" %} + {% bootstrap_field form.attach_file layout="horizontal" %} + {% bootstrap_field form.attach_button layout="horizontal" %} + Cancel diff --git a/ietf/templates/liaisons/guide_from_ietf.html b/ietf/templates/liaisons/guide_from_ietf.html index 53568d1a4a0..226c78d827d 100644 --- a/ietf/templates/liaisons/guide_from_ietf.html +++ b/ietf/templates/liaisons/guide_from_ietf.html @@ -11,7 +11,7 @@

    Liaison statements from the IETF
    - Guidelines for completing the "Cc:" field + Guidelines for completing the "Cc:" field

    The individuals copied on a liaison statement that is sent by the IETF to another Standards Development Organization (SDO) depend on the IETF entity that is sending the liaison statement. diff --git a/ietf/templates/liaisons/guide_to_ietf.html b/ietf/templates/liaisons/guide_to_ietf.html index 4ff53dd6f5c..02244430310 100644 --- a/ietf/templates/liaisons/guide_to_ietf.html +++ b/ietf/templates/liaisons/guide_to_ietf.html @@ -11,7 +11,7 @@

    Liaison statements to the IETF
    - Guidelines for completing the "To:" and "Cc:" fields + Guidelines for completing the "To:" and "Cc:" fields

    The following table provides guidelines for completing the "To:" and "Cc:" fields of liaison statements that are sent to the IETF by other Standards Development Organizations (SDOs). diff --git a/ietf/templates/liaisons/liaison_base.html b/ietf/templates/liaisons/liaison_base.html index aacab6dea04..21818175827 100644 --- a/ietf/templates/liaisons/liaison_base.html +++ b/ietf/templates/liaisons/liaison_base.html @@ -11,6 +11,7 @@ {% block content %} {% origin %}

    Liaison Statements

    + {% include "liaisons/liaison_desc.html" only %} {% if with_search %}
    {% include "liaisons/search_form.html" %}
    {% endif %} diff --git a/ietf/templates/liaisons/liaison_desc.html b/ietf/templates/liaisons/liaison_desc.html new file mode 100644 index 00000000000..8fb9fbf0458 --- /dev/null +++ b/ietf/templates/liaisons/liaison_desc.html @@ -0,0 +1,6 @@ +
    \ No newline at end of file diff --git a/ietf/templates/liaisons/liaison_mail.txt b/ietf/templates/liaisons/liaison_mail.txt index c92c68ff760..18dfe610fd7 100644 --- a/ietf/templates/liaisons/liaison_mail.txt +++ b/ietf/templates/liaisons/liaison_mail.txt @@ -1,13 +1,20 @@ -{% load ietf_filters %}{% autoescape off %}Title: {{ liaison.title|clean_whitespace }} +{% load ietf_filters group_filters %}{% autoescape off %}Title: {{ liaison.title|clean_whitespace }} Submission Date: {{ liaison.submitted|date:"Y-m-d" }} URL of the IETF Web page: {{ liaison.get_absolute_url }} + +To: {% for g in liaison.to_groups.all %}{{g|name_with_conditional_acronym}}{% if not forloop.last %}, {% endif %}{% endfor %} +From: {% for g in liaison.from_groups.all %}{{g|name_with_conditional_acronym}}{% if not forloop.last %}, {% endif %}{% endfor %} +Purpose: {{ liaison.purpose.name }} {% if liaison.deadline %}Please reply by {{ liaison.deadline }}{% endif %} -From: {% if liaison.from_contact %}{{ liaison.from_contact.formatted_email }}{% endif %} + +Email Addresses +--------------- +From: {% if liaison.from_contact %}{{ liaison.from_contact }}{% endif %} To: {{ liaison.to_contacts }} Cc: {{ liaison.cc_contacts }} Response Contacts: {{ liaison.response_contacts }} Technical Contacts: {{ liaison.technical_contacts }} -Purpose: {{ liaison.purpose.name }} + {% for related in liaison.source_of_set.all %} Referenced liaison: {% if related.target.title %}{{ related.target.title }}{% else %}Liaison #{{ related.target.pk }}{% endif %} ({{ related.target.get_absolute_url }}) {% endfor %} diff --git a/ietf/templates/liaisons/liaison_table.html b/ietf/templates/liaisons/liaison_table.html index 03c9b36b758..e74b08f21b8 100644 --- a/ietf/templates/liaisons/liaison_table.html +++ b/ietf/templates/liaisons/liaison_table.html @@ -24,9 +24,9 @@ Action needed {% endif %} diff --git a/ietf/templates/liaisons/list_other_sdo.html b/ietf/templates/liaisons/list_other_sdo.html new file mode 100644 index 00000000000..e6a567ae50f --- /dev/null +++ b/ietf/templates/liaisons/list_other_sdo.html @@ -0,0 +1,41 @@ +{% extends "base.html" %} +{# Copyright The IETF Trust 2025, All Rights Reserved #} +{% load origin static person_filters %} +{% block pagehead %} + +{% endblock %} +{% block title %} + Other SDO groups +{% endblock %} +{% block content %} + {% origin %} + {% regroup sdos by state.name as sdos_by_state %} + {% for sdos_in_state in sdos_by_state %} +

    {{sdos_in_state.grouper|capfirst}} SDO groups

    +
    From Contact{% person_link liaison.from_contact.person %}{{ liaison.from_contact }}
    + + + + + + + + + {% for group in sdos_in_state.list%} + + + + + + {% endfor %} + +
    AcronymNameLiaison Managers
    {{ group.acronym }}{{ group.name }} + {% for person in group.liaison_managers %} + {% person_link person %}{% if not forloop.last %}, {% endif %} + {% endfor %} +
    + {% endfor %} +{% endblock %} +{% block js %} + +{% endblock %} \ No newline at end of file diff --git a/ietf/templates/logo.html b/ietf/templates/logo.html new file mode 100644 index 00000000000..0de2eaeaeac --- /dev/null +++ b/ietf/templates/logo.html @@ -0,0 +1,35 @@ +{% load origin %} +{% load static %} +{% origin %} + +{{ org|upper }} Logo + +{{ org|upper }} Logo \ No newline at end of file diff --git a/ietf/templates/mailinglists/.gitignore b/ietf/templates/mailinglists/.gitignore deleted file mode 100644 index a74b07aee47..00000000000 --- a/ietf/templates/mailinglists/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/*.pyc diff --git a/ietf/templates/mailinglists/nonwg.html b/ietf/templates/mailinglists/nonwg.html index ae97323288b..bee2a8829ec 100644 --- a/ietf/templates/mailinglists/nonwg.html +++ b/ietf/templates/mailinglists/nonwg.html @@ -5,10 +5,16 @@ {% block pagehead %} {% endblock %} -{% block title %}Non-Working Group email lists{% endblock %} +{% block title %}Other (not WG) email lists{% endblock %} {% block content %} {% origin %} -

    Non-Working Group email lists

    +

    Other (not Working Group) email lists

    +

    Guidelines for these lists, including how to request a + new one to be created, can be found on the + + Non–Working Group email list guidelines + webpage. +

    {% cache 900 nonwglisttable %} diff --git a/ietf/templates/mailtrigger/recipient.html b/ietf/templates/mailtrigger/recipient.html index 0ded49a7c5d..008d08e9060 100644 --- a/ietf/templates/mailtrigger/recipient.html +++ b/ietf/templates/mailtrigger/recipient.html @@ -39,12 +39,12 @@

    Mail recipients

    @@ -55,4 +55,4 @@

    Mail recipients

    {% endblock %} {% block js %} -{% endblock %} +{% endblock %} \ No newline at end of file diff --git a/ietf/templates/meeting/.gitignore b/ietf/templates/meeting/.gitignore deleted file mode 100644 index a74b07aee47..00000000000 --- a/ietf/templates/meeting/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/*.pyc diff --git a/ietf/templates/meeting/activity_report.html b/ietf/templates/meeting/activity_report.html new file mode 100644 index 00000000000..dbfc717dab0 --- /dev/null +++ b/ietf/templates/meeting/activity_report.html @@ -0,0 +1,60 @@ + {% load ams_filters ietf_filters %} +
      +
    • {{ actions_count }} IESG Protocol and Document Actions this period
    • +
    • {{ last_calls_count }} IESG Last Calls issued to the IETF this period
    • +
    • + {{ new_drafts_count|stringformat:"3s" }} New I-Ds ({{ new_drafts_updated_count }} of which were updated, some ({{ new_drafts_updated_more_count }}) more than once) +
    • +
    • {{ updated_drafts_count|stringformat:"3s" }} I-Ds were updated (Some more than once)
    • + {% if is_meeting_report %} +
    • +

      In the final 4 weeks before meeting

      +
    • +
    • + {{ ffw_new_count|stringformat:"3s" }} New I-Ds were received - {{ ffw_new_percent }} of total newbies since last meeting +
    • +
    • + {{ ffw_update_count|stringformat:"3s" }} I-Ds were updated - {{ ffw_update_percent }} of total updated since last meeting +
    • + {% endif %} +
    +

    {{ new_groups.count }} New Working Group(s) formed this period

    +
      + {% for group in new_groups %}
    • {{ group.name }} ({{ group.acronym }})
    • {% endfor %} +
    +

    {{ concluded_groups.count }} Working Group(s) concluded this period

    +
      + {% for group in concluded_groups %}
    • {{ group.name }} ({{ group.acronym }})
    • {% endfor %} +
    +

    {{ rfcs.count }} RFCs published this period

    +

    + {{ counts.std }} Standards Track; {{ counts.bcp }} BCP; {{ counts.exp }} Experimental; {{ counts.inf }} Informational +

    +
    {% if recipient.template %} - {{ recipient.template|escape|linebreaksbr }} +
    {{ recipient.template|escape }}
    {% endif %}
    {% if recipient.code %} - {{ recipient.code|escape|linebreaksbr }} +
    {{ recipient.code|escape }}
    {% endif %}
    + + + + + + + + + + {% if rfcs|length > 0 %} + + {% for rfc in rfcs %} + + + + + + + + {% endfor %} + + {% endif %} +
    RFCStatusGroupDateTitle
    + {{ rfc.doc.name|prettystdname }} + {{ rfc.doc.std_level.name }} + {{ rfc.doc.group.acronym }} + {{ rfc.time|date:"F Y" }}{{ rfc.doc.title }}
    diff --git a/ietf/templates/meeting/add_session_drafts.html b/ietf/templates/meeting/add_session_drafts.html index 1efcc5963ea..0dd0635d113 100644 --- a/ietf/templates/meeting/add_session_drafts.html +++ b/ietf/templates/meeting/add_session_drafts.html @@ -1,15 +1,15 @@ {% extends "base.html" %} {# Copyright The IETF Trust 2015, All Rights Reserved #} {% load origin static django_bootstrap5 %} -{% block title %}Add drafts to {{ session.meeting }} : {{ session.group.acronym }}{% endblock %} +{% block title %}Add I-Ds to {{ session.meeting }} : {{ session.group.acronym }}{% endblock %} {% block pagehead %}{{ form.media.css }}{% endblock %} {% block content %} {% origin %}

    - Add drafts to {{ session.meeting }} + Add Internet-Drafts to {{ session.meeting }} {% if session_number %}: Session {{ session_number }}{% endif %}
    - {{ session.group.acronym }} + {{ session.group.acronym }} {% if session.name %}: {{ session.name }}{% endif %}

    @@ -20,9 +20,9 @@

    {% endif %}
    - This form will link additional drafts to this session with a revision of "Current at time of presentation". For more fine grained control of versions, or to remove a draft from a session, adjust the sessions associated with a draft from the draft's main page. + This form will link additional Internet-Drafts to this session with a revision of "Current at time of presentation". For more fine grained control of versions, or to remove an Internet-Draft from a session, adjust the sessions associated with an Internet-Draft from the Internet-Draft's main page.
    -

    Drafts already linked to this sesssion

    +

    Internet-Drafts already linked to this session

    @@ -47,7 +47,7 @@

    Drafts already linked to this sesssion

    {% endif %}
    -

    Additional drafts to link to this session

    +

    Additional Internet-Drafts to link to this session

    {% csrf_token %} {% bootstrap_form form %} diff --git a/ietf/templates/meeting/add_session_recordings.html b/ietf/templates/meeting/add_session_recordings.html new file mode 100644 index 00000000000..4f21e8f4d0b --- /dev/null +++ b/ietf/templates/meeting/add_session_recordings.html @@ -0,0 +1,78 @@ +{% extends "base.html" %} +{# Copyright The IETF Trust 2015, All Rights Reserved #} +{% load origin static django_bootstrap5 %} +{% block title %}Add I-Ds to {{ session.meeting }} : {{ session.group.acronym }}{% endblock %} +{% block pagehead %}{{ form.media.css }}{% endblock %} +{% block content %} + {% origin %} +

    + Add Recordings to {{ session.meeting }} + {% if session_number %}: Session {{ session_number }}{% endif %} +
    + {{ session.group.acronym }} + {% if session.name %}: {{ session.name }}{% endif %} + +

    + {% if session.is_material_submission_cutoff %} +
    + The deadline for submission corrections has passed. This may affect published proceedings. +
    + {% endif %} + {% if already_linked|length > 0 %} +

    Recordings already linked to this session

    + + {% csrf_token %} + + + + + + + + + + {% for sp in already_linked %}{% with recording_doc=sp.document %} + + + + + + {% endwith %}{% endfor %} + +
    TitleURLDelete
    {{ recording_doc.title }}{{ recording_doc.external_url }} + +
    +
    + {% endif %} + +

    Really delete the link to (default)?

    +
    + {% csrf_token %} + + +
    +
    +

    Add a recording to this session

    +
    + {% csrf_token %} + {% bootstrap_form form %} + + + Back + +
    +{% endblock %} +{% block js %} + {{ form.media.js }} + +{% endblock %} \ No newline at end of file diff --git a/ietf/templates/meeting/agenda-neue.html b/ietf/templates/meeting/agenda-neue.html deleted file mode 100644 index 2962c13c0b0..00000000000 --- a/ietf/templates/meeting/agenda-neue.html +++ /dev/null @@ -1,79 +0,0 @@ -{% extends "base.html" %} -{# Copyright The IETF Trust 2015-2021, All Rights Reserved #} -{% load origin %} -{% load static %} -{% load ietf_filters %} -{% load textfilters %} -{% load htmlfilters agenda_custom_tags %} -{% load django_vite %} - -{% block title %} - IETF {{ meetingData.meetingNumber }} Meeting Agenda -{% endblock %} -{% block pagehead %} - - - {{ meetingData|json_script:"meeting-data" }} - {% vite_asset 'client/agenda/main.js' %} -{% endblock %} -{% block morecss %} -body { - font-family: 'Montserrat', system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif; -} - -@keyframes initspinner { - to { transform: rotate(360deg); } -} - -#app-meeting-loading { - position: fixed; - top: 60px; - left: 0; - width: 100%; - height: calc(100% - 60px); - background-color: rgba(255,255,255,.75); - z-index: 2000000000; - backdrop-filter: blur(10px); -} - -#app-meeting-loading:before { - content: ''; - box-sizing: border-box; - position: absolute; - top: 50%; - left: 50%; - width: 50px; - height: 50px; - margin-top: -25px; - margin-left: -25px; - border-radius: 50%; - border-top: 2px solid #999; - border-right: 2px solid transparent; - animation: initspinner .6s linear infinite; - z-index: 2000000000; -} - -#app-meeting-loading:after { - content: 'Loading meeting {{ meetingData.meetingNumber }}...'; - position: absolute; - text-align: center; - top: 50%; - margin-top: -100px; - left: 0; - right: 0; - font-weight: 500; - color: #999; - z-index: 2000000000; -} -{% endblock %} -{% block precontent %} - -{% endblock %} -{% block content %} - {% origin %} -
    -
    -{% endblock %} diff --git a/ietf/templates/meeting/agenda.html b/ietf/templates/meeting/agenda.html index 1d037010ab2..089141bde80 100644 --- a/ietf/templates/meeting/agenda.html +++ b/ietf/templates/meeting/agenda.html @@ -5,529 +5,103 @@ {% load ietf_filters %} {% load textfilters %} {% load htmlfilters agenda_custom_tags %} +{% load django_vite %} {% block title %} - IETF {{ schedule.meeting.number }} Meeting Agenda - {% if "-utc" in request.path %}(UTC){% endif %} - {% if personalize %}Personalization{% endif %} + IETF {{ meetingData.meetingNumber }} Meeting Agenda {% endblock %} {% block pagehead %} - + + + {{ meetingData|json_script:"meeting-data" }} + {% vite_asset 'client/main.js' %} {% endblock %} -{% block morecss %}#weekview iframe { height: 25em; }{% endblock %} -{% block precontent %} - +{% block morecss %} + +/* Avoid hiding the page footer when on mobile with the footer toolbar overlay */ +@media screen and (max-width: 992px) { + body { + padding-bottom: 50px; + } +} + +@keyframes initspinner { + to { transform: rotate(360deg); } +} + +#app-loading { + position: fixed; + top: 60px; + left: 0; + width: 100%; + height: calc(100% - 60px); + background-color: rgba(255,255,255,.75); + z-index: 2000000000; + backdrop-filter: blur(10px); +} + +.theme-dark #app-loading { + background-color: rgba(0,0,0,.75); +} + +#app-loading:before { + content: ''; + box-sizing: border-box; + position: absolute; + top: 50%; + left: 50%; + width: 50px; + height: 50px; + margin-top: -25px; + margin-left: -25px; + border-radius: 50%; + border-top: 2px solid #999; + border-right: 2px solid transparent; + animation: initspinner .6s linear infinite; + z-index: 2000000000; +} + +.theme-dark #app-loading:before { + border-top-color: #FFF; +} + +#app-loading:after { + content: 'Loading meeting {{ meetingData.meetingNumber }}...'; + position: absolute; + text-align: center; + top: 50%; + margin-top: -100px; + left: 0; + right: 0; + font-weight: 500; + color: #999; + z-index: 2000000000; +} + +.theme-dark #app-loading:after { + color: #FFF; +} + +#app-loading-footer { + position: absolute; + text-align: center; + bottom: 0; + left: 0; + right: 0; + z-index: 1000000000; +} + +.theme-dark #app-loading-footer .btn-light { + background-color: rgba(255,255,255,.1) !important; + border-color: rgba(255,255,255,.05) !important; + color: #FFF !important; +} {% endblock %} {% block content %} {% origin %} - {% if "-utc" in request.path %} - {% include "meeting/meeting_heading.html" with meeting=schedule.meeting updated=updated selected="agenda-utc" title_extra="(UTC)" %} - {% elif personalize %} - {% include "meeting/meeting_heading.html" with meeting=schedule.meeting updated=updated selected="select-sessions" title_extra="" %} - {% else %} - {% include "meeting/meeting_heading.html" with meeting=schedule.meeting updated=updated selected="agenda" title_extra="" %} - {% endif %} - {# the contents of #extra-nav will be moved into the RH nav panel #} -
    -
    - {% if now.date <= schedule.meeting.end_date %} - Jump to current session - {% endif %} -
    - {% include 'meeting/tz-display.html' with id_suffix="-rh" meeting_timezone=timezone minimal=True only %} -
    -
    - Showing {{ timezone|split:"_"|join:" "|split:"/"|join:" / " }} time -
    +
    + - {# cache this part -- it takes 3-6 seconds to generate #} - {% load cache %} - {% cache cache_time ietf_meeting_agenda_utc schedule.meeting.number request.path %} -

    - {% if personalize %} - Session selection - {% else %} - Agenda - {% endif %} -

    - {% if is_current_meeting %} -

    - Note: IETF agendas are subject to change, up to and during a meeting. -

    - {% endif %} - {% if schedule.meeting.agenda_info_note %} -

    - {{ schedule.meeting.agenda_info_note|removetags:"h1"|safe }} -

    - {% endif %} - {% include 'meeting/tz-display.html' with id_suffix="" meeting_timezone=timezone only %} - {% include "meeting/agenda_filter.html" with filter_categories=filter_categories customize_button_text="Filter this agenda view..." always_show=personalize %} - {% include "meeting/agenda_personalize_buttonlist.html" with meeting=schedule.meeting personalize=personalize only %} -
    - - - - Download non-area events - -
    -
    -

    - Schedule - {% if schedule.meeting.agenda_warning_note %} - - {{ schedule.meeting.agenda_warning_note|removetags:"h1" |safe }} - - {% endif %} -

    - -
    -

    - {% if personalize %}Personalize{% endif %} - Detailed Agenda - {% if schedule.meeting.agenda_warning_note %} - - {{ schedule.meeting.agenda_warning_note|removetags:"h1" |safe }} - - {% endif %} -

    - {% if personalize %} -

    - Check boxes below to select individual sessions. -

    - {% endif %} - - - - {% if personalize %}{% endif %} - - - - - - - - - {% for item in filtered_assignments %} - {% ifchanged item.timeslot.time|date:"Y-m-d" %} - - - - {% endifchanged %} - {% if item|is_special_agenda_item %} - - {% if personalize %} - - {% endif %} - - - - - {% elif item|is_regular_agenda_item or item|is_plenary_agenda_item %} - {% if item|is_regular_agenda_item %} - {% ifchanged %} - - {% if personalize %}{% endif %} - - - - {% endifchanged %} - {% endif %} - {% if item.session.historic_group %} - - {% if personalize %} - - {% endif %} - {% if item.slot_type.slug == 'plenary' %} - - - {% else %} - - - - - {% endif %} - - -{% endif %} -{% endif %} -{% endfor %} - -
    - {{ item.timeslot.time|date:"l, F j, Y" }} -
    - {% if item.session_keyword %} - - - {% endif %} - {% include "meeting/timeslot_start_end.html" %} - {% if item.timeslot.show_location and item.timeslot.location %} - {% location_anchor item.timeslot %} - {{ item.timeslot.get_html_location }} - {% end_location_anchor %} - {% endif %} - {% if item.timeslot.show_location and item.timeslot.get_html_location %} - {% with item.timeslot.location.floorplan as floor %} - {% if item.timeslot.location.floorplan %} - - {% endif %} - {% endwith %} - {% endif %} - - {% agenda_anchor item.session %} - {% assignment_display_name item %} - {% end_agenda_anchor %} - {% if item.session.current_status == 'canceled' %} - CANCELLED - {% else %} - {% if item.slot_type.slug == 'other' %} - {% if item.session.agenda or item.session.remote_instructions or item.session.agenda_note %} -
    - {% include "meeting/session_buttons_include.html" with show_agenda=True item=item schedule=schedule %} -
    - {% else %} -
    - {% for slide in item.session.slides %} - {{ slide.title|clean_whitespace }} -
    - {% endfor %} -
    - {% endif %} - {% endif %} - {% endif %} -
    {% include "meeting/timeslot_start_end.html" %} - {{ item.timeslot.time|date:"l" }} - {{ item.timeslot.name|capfirst_allcaps }} -
    - {% if item.session_keyword %} - - - {% endif %} - {% include "meeting/timeslot_start_end.html" %} - {% if item.timeslot.show_location and item.timeslot.location %} - {% location_anchor item.timeslot %} - {{ item.timeslot.get_html_location }} - {% end_location_anchor %} - {% endif %} - - {% with item.timeslot.location.floorplan as floor %} - {% if item.timeslot.location.floorplan %} - - {% endif %} - {% endwith %} - - {% if item.timeslot.show_location and item.timeslot.location %} - {% location_anchor item.timeslot %} - {{ item.timeslot.get_html_location }} - {% end_location_anchor %} - {% endif %} - - {% if item.session.historic_group.historic_parent.acronym %} -
    {{ item.session.historic_group.historic_parent.acronym }}
    - {% endif %} -
    -
    - {% if item.session.historic_group %} - - {{ item.session.historic_group.acronym }} - - {% else %} - {{ item.session.historic_group.acronym }} - {% endif %} -
    -
    - {% if item.session.current_status == 'canceled' %} - Cancelled - {% else %} -
    - {% include "meeting/session_buttons_include.html" with show_agenda=True session=item.session meeting=schedule.meeting %} -
    - {% endif %} -
    - {% if item.session.historic_group %} - - {{ item.session.historic_group.acronym }} - {% else %} - {{ item.session.historic_group.acronym }} - {% endif %} - {% if item.session.historic_group.historic_parent.acronym %} - {{ item.session.historic_group.historic_parent.acronym }} - {% endif %} -
    - - {% agenda_anchor item.session %} - {% assignment_display_name item %} - {% end_agenda_anchor %} - {% if item.session.historic_group.state_id == "bof" %} - BOF - {% endif %} - {% if item.session.current_status == 'resched' %} -
    - Rescheduled - {% if item.session.rescheduled_to %} - TO -
    -
    - {% if "-utc" in request.path %} - {{ item.session.rescheduled_to.utc_start_time|date:"l G:i"|upper }}-{{ item.session.rescheduled_to.utc_end_time|date:"G:i" }} - {% else %} - {{ item.session.rescheduled_to.time|date:"l G:i"|upper }}-{{ item.session.rescheduled_to.end_time|date:"G:i" }} - {% endif %} -
    -
    - {% endif %} -
    - {% endif %} - {% if item.session.agenda_note|first_url|conference_url %} -
    - {{ item.session.agenda_note|slice:":23" }} - - {% elif item.session.agenda_note %} -
    - {{ item.session.agenda_note }} - {% endif %} -
    -{% if personalize %}{# only show second copy of buttons for the personalize tab #} - {% include "meeting/agenda_personalize_buttonlist.html" with meeting=schedule.meeting personalize=personalize only %} -{% endif %} -{% endcache %} {% endblock %} -{% block js %} - - - - - - - - {% if personalize %} - - {% endif %} - -{% endblock %} \ No newline at end of file diff --git a/ietf/templates/meeting/agenda.ics b/ietf/templates/meeting/agenda.ics deleted file mode 100644 index 4f207afae36..00000000000 --- a/ietf/templates/meeting/agenda.ics +++ /dev/null @@ -1,28 +0,0 @@ -{% load humanize %}{% autoescape off %}{% load ietf_filters textfilters %}{% load cache %}{% cache 1800 ietf_meeting_agenda_ics schedule.meeting.number request.path request.GET %}BEGIN:VCALENDAR -VERSION:2.0 -METHOD:PUBLISH -PRODID:-//IETF//datatracker.ietf.org ical agenda//EN -{{schedule.meeting.vtimezone}}{% for item in assignments %}{% if item.session.historic_group %}BEGIN:VEVENT -UID:ietf-{{schedule.meeting.number}}-{{item.timeslot.pk}}-{{item.session.group.acronym}} -SUMMARY:{% if item.session.name %}{{item.session.name|ics_esc}}{% else %}{% if not item.session.historic_group %}{{item.timeslot.name|ics_esc}}{% else %}{{item.session.historic_group.acronym|lower}} - {{item.session.historic_group.name}}{% endif%}{%endif%}{% if item.session.agenda_note %} ({{item.session.agenda_note}}){% endif %} -{% if item.timeslot.show_location %}LOCATION:{{item.timeslot.get_location}} -{% endif %}STATUS:{{item.session.ical_status}} -CLASS:PUBLIC -DTSTART{% if schedule.meeting.time_zone %};TZID={{schedule.meeting.time_zone|ics_esc}}{%endif%}:{{ item.timeslot.time|date:"Ymd" }}T{{item.timeslot.time|date:"Hi"}}00 -DTEND{% if schedule.meeting.time_zone %};TZID={{schedule.meeting.time_zone|ics_esc}}{%endif%}:{{ item.timeslot.end_time|date:"Ymd" }}T{{item.timeslot.end_time|date:"Hi"}}00 -DTSTAMP:{{ item.timeslot.modified|date:"Ymd" }}T{{ item.timeslot.modified|date:"His" }}Z{% if item.session.agenda %} -URL:{{item.session.agenda.get_versionless_href}}{% endif %} -DESCRIPTION:{{item.timeslot.name|ics_esc}}\n{% if item.session.agenda_note %} - Note: {{item.session.agenda_note|ics_esc}}\n{% endif %}{% if item.timeslot.location.webex_url %} - \n - Webex: {{ item.timeslot.location.webex_url }}\n{% endif %}{% if item.timeslot.location.video_stream_url %} - \n - Meetecho: {{ item.timeslot.location.video_stream_url|format:item.session }}\n{% endif %}{% if item.session.agenda %}{% with agenda=item.session.agenda %} - \n - {{agenda.type}} {{agenda.get_versionless_href}}\n{% endwith %}{% endif %} - \n - Session materials: {% absurl 'ietf.meeting.views.session_details' num=schedule.meeting.number acronym=item.session.group.acronym %}\n{% if schedule.meeting.get_number is not None %} - \n{# link agenda for ietf meetings #} - See in schedule: {% absurl 'ietf.meeting.views.agenda' num=schedule.meeting.number %}#row-{{ item.slug }}\n{% endif %} -END:VEVENT -{% endif %}{% endfor %}END:VCALENDAR{% endcache %}{% endautoescape %} diff --git a/ietf/templates/meeting/agenda.txt b/ietf/templates/meeting/agenda.txt index 489ebbe6aa2..7a49dde0c87 100644 --- a/ietf/templates/meeting/agenda.txt +++ b/ietf/templates/meeting/agenda.txt @@ -7,25 +7,28 @@ {% filter center:72 %}{{ schedule.meeting.agenda_info_note|striptags|wordwrap:72|safe }}{% endfilter %} {% endif %} {% filter center:72 %}{{ schedule.meeting.date|date:"F j" }}-{% if schedule.meeting.date.month != schedule.meeting.end_date.month %}{{ schedule.meeting.end_date|date:"F " }}{% endif %}{{ schedule.meeting.end_date|date:"j, Y" }}{% endfilter %} +{% if updated %} {% filter center:72 %}Updated {{ updated|date:"Y-m-d H:i:s T" }}{% endfilter %} +{% endif %} {% filter center:72 %}IETF agendas are subject to change, up to and during the meeting.{% endfilter %} +{% filter center:72 %}Times are shown in {% if display_timezone.lower == "utc" %}UTC{% else %}the {{ display_timezone }} time zone{% endif %}.{% endfilter %} {% for item in filtered_assignments %}{% ifchanged %} {{ item.timeslot.time|date:"l"|upper }}, {{ item.timeslot.time|date:"F j, Y" }} {% endifchanged %}{% if item.slot_type.slug == "reg" %} -{{ item.timeslot.time_desc }} {{ item.timeslot.name }}{% if schedule.meeting.reg_area %} - {{ schedule.meeting.reg_area }}{% endif %}{% endif %}{% if item.slot_type.slug == "plenary" %} -{{ item.timeslot.time_desc }} {{ item.session.name }} - {{ item.timeslot.location.name }} +{{ item.timeslot.time|date:"Hi" }}-{{ item.timeslot.end_time|date:"Hi" }} {{ item.timeslot.name }}{% if schedule.meeting.reg_area %} - {{ schedule.meeting.reg_area }}{% endif %}{% endif %}{% if item.slot_type.slug == "plenary" %} +{{ item.timeslot.time|date:"Hi" }}-{{ item.timeslot.end_time|date:"Hi" }} {{ item.session.name }} - {{ item.timeslot.location.name }} {{ item.session.agenda_text.strip|indent:"3" }} -{% endif %}{% if item.slot_type.slug == 'regular' %}{% if item.session.historic_group %}{% ifchanged %} +{% endif %}{% if item.slot_type.slug == 'regular' %}{% ifchanged %} -{{ item.timeslot.time_desc }} {{ item.timeslot.name }} -{% endifchanged %}{{ item.timeslot.location.name|ljust:14 }} {{ item.session.historic_group.historic_parent.acronym|upper|ljust:4 }} {{ item.session.historic_group.acronym|ljust:10 }} {{ item.session.historic_group.name }} {% if item.session.historic_group.state_id == "bof" %}BOF{% elif item.session.historic_group.type_id == "wg" %}WG{% endif %}{% if item.session.agenda_note %} - {{ item.session.agenda_note }}{% endif %}{% if item.session.current_status == 'canceled' %} *** CANCELLED ***{% elif item.session.current_status == 'resched' %} *** RESCHEDULED{% if item.session.rescheduled_to %} TO {{ item.session.rescheduled_to.time|date:"l G:i"|upper }}-{{ item.session.rescheduled_to.end_time|date:"G:i" }}{% endif %} ***{% endif %} -{% endif %}{% endif %}{% if item.slot_type.slug == "break" %} -{{ item.timeslot.time_desc }} {{ item.timeslot.name }}{% if schedule.meeting.break_area and item.timeslot.show_location %} - {{ schedule.meeting.break_area }}{% endif %}{% endif %}{% if item.slot_type.slug == "other" %} -{{ item.timeslot.time_desc }} {{ item.timeslot.name }} - {{ item.timeslot.location.name }}{% endif %}{% endfor %} +{{ item.timeslot.time|date:"Hi" }}-{{ item.timeslot.end_time|date:"Hi" }} {{ item.timeslot.name }} +{% endifchanged %}{{ item.timeslot.location.name|truncatechars:18|ljust:18 }} {% if item.session.group_parent_at_the_time %}{{ item.session.group_parent_at_the_time.acronym|upper|truncatechars:6|ljust:6 }}{% else %} {% endif %} {{ item.session.group_at_the_time.acronym|truncatechars:12|ljust:12 }} {{ item.session.group_at_the_time.name }} {% if item.session.group_at_the_time.state_id == "bof" %}BOF{% elif item.session.group_at_the_time.type_id == "wg" %}WG{% endif %}{% if item.session.agenda_note %} - {{ item.session.agenda_note }}{% endif %}{% if item.session.current_status == 'canceled' %} *** CANCELLED ***{% elif item.session.current_status == 'resched' %} *** RESCHEDULED{% if item.session.rescheduled_to %} TO {{ item.session.rescheduled_to.time|date:"l G:i"|upper }}-{{ item.session.rescheduled_to.end_time|date:"G:i" }}{% endif %} ***{% endif %} +{% endif %}{% if item.slot_type.slug == "break" %} +{{ item.timeslot.time|date:"Hi" }}-{{ item.timeslot.end_time|date:"Hi" }} {{ item.timeslot.name }}{% if schedule.meeting.break_area and item.timeslot.show_location %} - {{ schedule.meeting.break_area }}{% endif %}{% endif %}{% if item.slot_type.slug == "other" %} +{{ item.timeslot.time|date:"Hi" }}-{{ item.timeslot.end_time|date:"Hi" }} {{ item.timeslot.name }} - {{ item.timeslot.location.name }}{% endif %}{% endfor %} ==================================================================== {% endautoescape %} diff --git a/ietf/templates/meeting/agenda_by_room.html b/ietf/templates/meeting/agenda_by_room.html deleted file mode 100644 index 017138c7e03..00000000000 --- a/ietf/templates/meeting/agenda_by_room.html +++ /dev/null @@ -1,27 +0,0 @@ -{% extends "base.html" %} -{% block morecss %} - .type-lead:after { content: " (DO NOT POST)"; color:red; } - .type-offagenda:after { content:" (not published on agenda)"; } -{% endblock %} -{% block title %}Agenda for {{ meeting }} by room{% endblock %} -{% block content %} - {% include "meeting/meeting_heading.html" with updated=meeting.updated selected="by-room" title_extra="By room" %} -
    - {% for day,sessions in ss_by_day.items %} -

    {{ day|date:'l, j F Y' }}

    - {% regroup sessions by timeslot.get_functional_location as room_list %} -
    - {% for room in room_list %} - {{ room.grouper|default:"Location Unavailable" }} -
      - {% for ss in room.list %} -
    • - {{ ss.timeslot.time|date:"H:i" }}-{{ ss.timeslot.end_time|date:"H:i" }} {{ ss.session.short_name }} -
    • - {% endfor %} -
    - {% endfor %} -
    - {% endfor %} -
    -{% endblock %} \ No newline at end of file diff --git a/ietf/templates/meeting/agenda_by_type.html b/ietf/templates/meeting/agenda_by_type.html deleted file mode 100644 index 87b91567550..00000000000 --- a/ietf/templates/meeting/agenda_by_type.html +++ /dev/null @@ -1,49 +0,0 @@ -{% extends "base.html" %} -{% block morecss %} - .type-lead:after { content: " (DO NOT POST)"; color:red; } - .type-offagenda:after { content:" (not published on agenda)"; } -{% endblock %} -{% block title %}Agenda for {{ meeting }} by Session Type{% endblock %} -{% block content %} - {% include "meeting/meeting_heading.html" with updated=meeting.updated selected="by-type" title_extra="By session type" %} - {% regroup assignments by session.type_id as type_list %} -
    - {% for type in type_list %} -
    -

    {{ type.grouper|title }}

    - {% if schedule == meeting.schedule %} - - Download to Calendar - - {% endif %} -
    - {% regroup type.list by timeslot.time|date:"l Y-M-d" as daylist %} - {% for day in daylist %} -
    -

    {{ day.grouper }}

    - - - {% for ss in day.list %} - - - - - - - {% endfor %} - -
    {{ ss.timeslot.time|date:"H:i" }}-{{ ss.timeslot.end_time|date:"H:i" }}{{ ss.timeslot.get_hidden_location }}{{ ss.session.short_name }} - {% if ss.session.type_id == 'regular' or ss.session.type_id == 'plenary' or ss.session.type_id == 'other' %} - - Materials - - {% endif %} -
    -
    - {% endfor %} -
    -
    - {% endfor %} -
    -{% endblock %} \ No newline at end of file diff --git a/ietf/templates/meeting/agenda_personalize_buttonlist.html b/ietf/templates/meeting/agenda_personalize_buttonlist.html deleted file mode 100644 index 55acb9337c0..00000000000 --- a/ietf/templates/meeting/agenda_personalize_buttonlist.html +++ /dev/null @@ -1,24 +0,0 @@ -{% comment %} -Buttons for the agenda_personalize.html template - -Required parameters: - meeting - meeting being displayed - personalize - if True, show buttons relevant only for personalize tab -{% endcomment %} -{% load agenda_custom_tags %} - \ No newline at end of file diff --git a/ietf/templates/meeting/approve_proposed_slides.html b/ietf/templates/meeting/approve_proposed_slides.html index 584e280815e..204473f4551 100644 --- a/ietf/templates/meeting/approve_proposed_slides.html +++ b/ietf/templates/meeting/approve_proposed_slides.html @@ -1,6 +1,6 @@ {% extends "base.html" %} {# Copyright The IETF Trust 2015, All Rights Reserved #} -{% load origin static django_bootstrap5 %} +{% load origin static django_bootstrap5 tz %} {% block title %} Approve Slides Proposed for {{ submission.session.meeting }} : {{ submission.session.group.acronym }} {% endblock %} @@ -9,13 +9,13 @@

    Approve slides proposed for {{ submission.session.meeting }}
    - {{ submission.session.group.acronym }} + {{ submission.session.group.acronym }} {% if session.name %}: {{ submission.session.name }}{% endif %}

    {% if session_number %}

    - Session {{ session_number }} : {{ submission.session.official_timeslotassignment.timeslot.time|date:"D M-d-Y Hi" }} + Session {{ session_number }} : {{ submission.session.official_timeslotassignment.timeslot.time|timezone:submission.session.meeting.time_zone|date:"D M-d-Y Hi" }}

    {% endif %}

    @@ -34,6 +34,6 @@

    + value="disapprove">Decline and Delete -{% endblock %} \ No newline at end of file +{% endblock %} diff --git a/ietf/templates/meeting/attendance.html b/ietf/templates/meeting/attendance.html new file mode 100644 index 00000000000..5a9aa2dce24 --- /dev/null +++ b/ietf/templates/meeting/attendance.html @@ -0,0 +1,44 @@ +{% extends "base.html" %} +{# Copyright The IETF Trust 2024, All Rights Reserved #} +{% load origin %} +{% block title %}Bluesheet for {{session}}{% endblock %} +{% block content %} + {% origin %} +

    + Attendance for {{session}} +

    +
    + This list will be used to generate the official bluesheet for this session. + {% if can_add %} +
    If you attended this session, you can use the "I was there" button at the bottom to add yourself. + {% endif %} + {% if was_there %} +
    If the affiliation listed here needs to be updated, request the change using support@ietf.org. Note which sessions you are wanting to change in your request. + {% endif %} +
    +

    + {{ data|length }} attendees. +

    + + + + + + + + + {% for item in data %} + + + + + {% endfor %} + +
    NameAffiliation
    {{ item.name }}{{ item.affiliation }}
    + {% if can_add %} +
    + {% csrf_token %} + +
    + {% endif %} +{% endblock %} \ No newline at end of file diff --git a/ietf/templates/meeting/bluesheet.txt b/ietf/templates/meeting/bluesheet.txt index dd3bf36ac7c..5b3960f3aa7 100644 --- a/ietf/templates/meeting/bluesheet.txt +++ b/ietf/templates/meeting/bluesheet.txt @@ -1,7 +1,8 @@ -Bluesheet for {{session}} +{% autoescape off %}Bluesheet for {{session}} ======================================================================== {{ data|length }} attendees. {% for item in data %} {{ item.name }} {{ item.affiliation }}{% endfor %} +{% endautoescape %} diff --git a/ietf/templates/meeting/cancel_session.html b/ietf/templates/meeting/cancel_session.html new file mode 100644 index 00000000000..9bf80e0c495 --- /dev/null +++ b/ietf/templates/meeting/cancel_session.html @@ -0,0 +1,24 @@ +{% extends "base.html" %} +{# Copyright The IETF Trust 2021-2022, All Rights Reserved #} +{% load origin %} +{% load django_bootstrap5 %} +{% block pagehead %}{{ form.media.css }}{% endblock %} +{% block title %} Cancel session "{{ session }}"{% endblock %} +{% block content %} + {% origin %} +

    + Cancel session +
    + {{ session }} +

    +
    + {% csrf_token %} + {% bootstrap_form form %} + + + Back + +
    +{% endblock %} +{% block js %}{{ form.media.js }}{% endblock %} \ No newline at end of file diff --git a/ietf/templates/meeting/create_timeslot.html b/ietf/templates/meeting/create_timeslot.html index 8a47b9c969d..62847c1a08e 100755 --- a/ietf/templates/meeting/create_timeslot.html +++ b/ietf/templates/meeting/create_timeslot.html @@ -12,7 +12,7 @@

    Create timeslot for {{ meeting }}

    {% bootstrap_form form %} Back + href="{% url 'ietf.meeting.views.edit_timeslots' num=meeting.number %}{% if 'sched' in request.GET %}?sched={{ request.GET.sched }}{% endif %}">Back {% endblock %} {% block js %} diff --git a/ietf/templates/meeting/delete_schedule.html b/ietf/templates/meeting/delete_schedule.html index 334479ba795..f5012d0f6be 100644 --- a/ietf/templates/meeting/delete_schedule.html +++ b/ietf/templates/meeting/delete_schedule.html @@ -12,7 +12,7 @@

    Delete IETF {{ meeting.number }} Schedule
    - {{ schedule.owner }}/{{ schedule.name }} + {{ schedule.owner }}/{{ schedule.name }}

    {% csrf_token %} diff --git a/ietf/templates/meeting/diff_schedules.html b/ietf/templates/meeting/diff_schedules.html index c5b117d2d76..67abbe5345d 100644 --- a/ietf/templates/meeting/diff_schedules.html +++ b/ietf/templates/meeting/diff_schedules.html @@ -2,14 +2,14 @@ {# Copyright The IETF Trust 2020, All Rights Reserved #} {% load origin %} {% load ietf_filters %} -{% load django_bootstrap5 %} +{% load django_bootstrap5 tz %} {% block title %}Differences between Meeting Agendas for IETF {{ meeting.number }}{% endblock %} {% block content %} {% origin %}

    Differences between Meeting Agendas
    - IETF {{ meeting.number }} + IETF {{ meeting.number }}

    {% bootstrap_form form layout="horizontal" %} @@ -26,7 +26,7 @@

    - + {% timezone meeting.time_zone %} {% for d in diffs %} @@ -40,7 +40,7 @@

    {% endfor %} - + {% endtimezone %} {% else %} No differences in scheduled sessions found. diff --git a/ietf/templates/meeting/edit_meeting_schedule.html b/ietf/templates/meeting/edit_meeting_schedule.html index 067ba790815..a975c2e61a1 100644 --- a/ietf/templates/meeting/edit_meeting_schedule.html +++ b/ietf/templates/meeting/edit_meeting_schedule.html @@ -35,27 +35,27 @@

    Agenda name: {{ schedule.name }}
    - Owner: {{ schedule.owner }} + Owner: {{ schedule.owner }}

    @@ -64,19 +64,19 @@

    You can't edit this schedule. {% if schedule.is_official_record %}This is the official schedule for a meeting in the past.{% endif %} Make a - - new agenda from this - . + + new agenda from this.

    {% endif %} {% if timeslot_groups|length == 0 %} -

    +

    No timeslots exist for this meeting yet.

    - - Edit timeslots. + + Edit timeslots

    {% else %} @@ -193,6 +193,7 @@

    +
    - +
    +
    Show: {% for p in session_parents %}
    +
    {% if session_purposes|length > 1 %} +
    diff --git a/ietf/templates/meeting/edit_meeting_schedule_session.html b/ietf/templates/meeting/edit_meeting_schedule_session.html index 80bab3d1bcf..4a2bbfdde72 100644 --- a/ietf/templates/meeting/edit_meeting_schedule_session.html +++ b/ietf/templates/meeting/edit_meeting_schedule_session.html @@ -1,4 +1,4 @@ -{% load person_filters editor_tags %} +{% load person_filters editor_tags ietf_filters textfilters %}
    off agenda{% endif %}
    {% endif %} + {% if session.comments %}
    {{ session.comments|urlize_ietf_docs|linkify|linebreaksbr }}
    {% endif %} {% if session.requested_by_person %} -
    - {% person_link session.requested_by_person %} - {% if session.requested_time %}({{ session.requested_time|date:"Y-m-d" }}){% endif %} +
    +
    + +
    +
    + {% person_link session.requested_by_person %} + {% if session.requested_time %}({{ session.requested_time|date:"Y-m-d" }}){% endif %} +
    {% endif %} {% if session.resources.all %} -
    - Resources: - {% for r in session.resources.all %} - {{ r.name }}{% if not forloop.last %},{% endif %} - {% endfor %} +
    +
    +
    + {% for r in session.resources.all %} + {{ r.name }}{% if not forloop.last %}, {% endif %} + {% endfor %} +
    {% endif %} - {% if session.comments %}
    {{ session.comments|linebreaksbr }}
    {% endif %} {% if session.formatted_constraints %}
    + {% with ad=session.group.ads|first %} {% for constraint_name, values in session.formatted_constraints.items %} -
    - {% constraint_icon_for constraint_name %}: {{ values|join:", " }} +
    +
    {% constraint_icon_for constraint_name %}
    + {% if constraint_name.slug != 'bethere' or not ad %} + {{ values|join:", " }} + {% else %} + {% for val in values %} + {% if val != ad.person.plain_name %} + {{ val }}{% if forloop.revcounter > 2 or forloop.revcounter > 1 and values|last != ad.person.plain_name %}, {% endif %} + {% endif %} + {% endfor %} + {% endif %} +
    {% endfor %} + {% endwith %}
    {% endif %} {% for s in session.other_sessions %} -
    - Other session +
    +
    + +
    +
    + +
    {% endfor %} - - Edit session - + {% if secretariat %} + + Edit session + + + Cancel session + + {% endif %}
    \ No newline at end of file diff --git a/ietf/templates/meeting/edit_meeting_timeslots_and_misc_sessions.html b/ietf/templates/meeting/edit_meeting_timeslots_and_misc_sessions.html index 2148450355d..5f08d3d4b68 100644 --- a/ietf/templates/meeting/edit_meeting_timeslots_and_misc_sessions.html +++ b/ietf/templates/meeting/edit_meeting_timeslots_and_misc_sessions.html @@ -1,7 +1,7 @@ {% extends "base.html" %} {# Copyright The IETF Trust 2015-2020, All Rights Reserved #} {% load origin %} -{% load staticfiles %} +{% load static %} {% load ietf_filters %} {% load django_bootstrap5 %} {% block title %}{{ schedule.name }}: IETF {{ meeting.number }} meeting agenda{% endblock %} @@ -12,7 +12,7 @@

    IETF {{ meeting.number }} meeting agenda
    - {{ schedule.name }} + {{ schedule.name }}

    {% origin %}
    data-day="{{ day.day.isoformat }}">
    {{ room.name }} - {% if room.capacity %}{{ room.capacity }}{% endif %} + {% if room.capacity %}{{ room.capacity }}{% endif %}
    diff --git a/ietf/templates/meeting/edit_session.html b/ietf/templates/meeting/edit_session.html index be385e2fa7d..90139b81802 100644 --- a/ietf/templates/meeting/edit_session.html +++ b/ietf/templates/meeting/edit_session.html @@ -1,24 +1,22 @@ {% extends "base.html" %} -{# Copyright The IETF Trust 2021, All Rights Reserved #} +{# Copyright The IETF Trust 2023, All Rights Reserved #} {% load origin %} {% load django_bootstrap5 %} +{% load session_filters %} {% block pagehead %}{{ form.media.css }}{% endblock %} -{% block title %}Edit session "{{ session }}"{% endblock %} +{% block title %}Edit session "{{ session|describe_with_tz }}"{% endblock %} {% block content %} {% origin %}

    Edit session
    - {{ session }} + {{ session|describe_with_tz }}

    {% csrf_token %} {% bootstrap_form form %} - - Back - + Back {% endblock %} {% block js %}{{ form.media.js }}{% endblock %} \ No newline at end of file diff --git a/ietf/templates/meeting/edit_timeslot.html b/ietf/templates/meeting/edit_timeslot.html index c969f171dc7..c881cad994a 100644 --- a/ietf/templates/meeting/edit_timeslot.html +++ b/ietf/templates/meeting/edit_timeslot.html @@ -9,7 +9,7 @@

    Edit {{ timeslot.meeting }} timeslot
    - {{ timeslot.name }} + {{ timeslot.name }}

    {% if sessions %}
    @@ -25,7 +25,7 @@

    {% bootstrap_form form %} + href="{% url 'ietf.meeting.views.edit_timeslots' num=timeslot.meeting.number %}{% if "sched" in request.GET %}?sched={{ request.GET.sched }}{% endif %}"> Back diff --git a/ietf/templates/meeting/edit_timeslot_type.html b/ietf/templates/meeting/edit_timeslot_type.html index d19cbaaf15c..d21e189e517 100644 --- a/ietf/templates/meeting/edit_timeslot_type.html +++ b/ietf/templates/meeting/edit_timeslot_type.html @@ -8,7 +8,7 @@

    Edit timeslot type
    - {{ timeslot }} + {{ timeslot }}

    {% if sessions %}
    diff --git a/ietf/templates/meeting/finalize.html b/ietf/templates/meeting/finalize.html index dec518293cd..ba218a91ce8 100644 --- a/ietf/templates/meeting/finalize.html +++ b/ietf/templates/meeting/finalize.html @@ -8,13 +8,13 @@

    Finalize Proceedings
    - IETF {{ meeting.number }} + IETF {{ meeting.number }}

    This will make the proceedings for IETF {{ meeting.number }} final.

    - All drafts associated with sessions that are marked "current version" will have their version set to whatever the version was at the end of the meeting. + All Internet-Drafts associated with sessions that are marked "current version" will have their version set to whatever the version was at the end of the meeting.

    {# This would be a good place to put any warnings about important things missing from the proceedings #}
    diff --git a/ietf/templates/meeting/floor-plan.html b/ietf/templates/meeting/floor-plan.html deleted file mode 100644 index c0c80cc0981..00000000000 --- a/ietf/templates/meeting/floor-plan.html +++ /dev/null @@ -1,107 +0,0 @@ -{% extends "base.html" %} -{# Copyright The IETF Trust 2015, All Rights Reserved #} -{% load origin %} -{% load ietf_filters %} -{% load textfilters %} -{% load static %} -{% block title %} - IETF {{ meeting.number }} meeting agenda - {% if "-utc" in request.path %}(UTC){% endif %} -{% endblock %} -{% block bodyAttrs %}onload="automaticarrow(); checkParams();" onresize="checkParams();"{% endblock %} -{% block precontent %} - -{% endblock %} -{% block content %} - {% origin %} - {% include "meeting/meeting_heading.html" with selected="floor-plan" title_extra="Floor Plan" %} - {% for floor in floors %} -

    {{ floor.name }}

    -
    -
    - {% for f in floors %} - {% for room in f.room_set.all %} - {{ room.name }} -
    - {% endfor %} - {% endfor %} -
    -
    - {% for f in floors %} - {% for room in f.room_set.all %} - {% if room.functional_display_name %} - {{ room.functional_display_name }} -
    - {% endif %} - {% endfor %} - {% endfor %} -
    -
    -
    - {% if floor.image %} - {{ floor.name }} Map - {# We need as many of these as we can have individual rooms combining into one #} - - - - - {% else %} - No floor image available yet. - {% endif %} -
    -
    -
    - {% endfor %} -{% endblock %} -{% block js %} - - -{% endblock %} \ No newline at end of file diff --git a/ietf/templates/meeting/group_materials.html b/ietf/templates/meeting/group_materials.html index 8f3fd49a579..74ed8bafca5 100644 --- a/ietf/templates/meeting/group_materials.html +++ b/ietf/templates/meeting/group_materials.html @@ -1,122 +1,98 @@ -{# Copyright The IETF Trust 2015-2019, All Rights Reserved #} +{# Copyright The IETF Trust 2015-2024, All Rights Reserved #} {% load origin %} {% origin %} {% load ietf_filters proceedings_filters managed_groups %} {% load tz %} - {% if session.name %} -
    {{ session.name }}
    + {% if entry.name %} +
    {{ entry.name }}
    {% else %} -
    - {{ session.group.acronym }} + - {% if session.group.state.slug == "bof" %} - {{ session.group.state.slug|upper }} + {% if entry.group.state.slug == "bof" %} + {{ entry.group.state.slug|upper }} {% endif %} {% endif %} - {% if session.all_meeting_sessions_cancelled %} + {% if entry.canceled %} - Session cancelled + Session cancelled {% else %} - {% if session.all_meeting_agendas %} - {% for agenda in session.all_meeting_agendas %} - {% if session.all_meeting_agendas|length == 1 %} - {% if agenda.time > old %} - - {% endif %} - Agenda -
    - {% else %} - - Agenda {{ agenda.sessionpresentation_set.first.session.official_timeslotassignment.timeslot.time|date:"D G:i" }} - -
    - {% endif %} - {% endfor %} - {% else %} - {% if show_agenda == "True" %}No agenda{% endif %} - {% endif %} + {% for agenda in entry.agendas %} + {% if entry.agendas|length == 1 and agenda.time > old %} + + {% endif %} + + Agenda {% if agenda.time %}{{agenda.time|date:"D G:i"}}{% endif %} + +
    + {% empty %} + {% if show_agenda == "True" %}No agenda{% endif %} + {% endfor %} - {% if session.all_meeting_minutes %} - {% if session.all_meeting_minutes|length == 1 %} - Minutes -
    - {% else %} - {% for minutes in session.all_meeting_minutes %} - - Minutes {{ minutes.sessionpresentation_set.first.session.official_timeslotassignment.timeslot.time|date:"D G:i" }} + {% for minutes in entry.minutes %} + + Minutes {% if minutes.time %}{{minutes.time|date:"D G:i"}}{% endif %} + +
    + {% empty %} + {% if show_agenda == "True" %}No minutes{% endif %} + {% endfor %} + {% if entry.session.type_id == 'regular' and show_agenda == "True" %} + {% for attendance in entry.attendances %} + {% with session=attendance.material %} + + Attendance + {% if attendance.time %}{{ attendance.time|date:"D G:i" }}{% endif %} -
    - {% endfor %} - {% endif %} - {% else %} - {% if show_agenda == "True" %}No minutes{% endif %} - {% endif %} - {% if session.type_id == 'regular' and show_agenda == "True" %} - {% if session.all_meeting_bluesheets %} - {% if session.all_meeting_bluesheets|length == 1 %} - Bluesheets -
    - {% else %} - {% for bluesheets in session.all_meeting_bluesheets %} - - Bluesheets -
    - {{ bluesheets.sessionpresentation_set.first.session.official_timeslotassignment.timeslot.time|date:"D G:i" }} -
    -
    - {% endfor %} - {% endif %} - {% else %} - No bluesheets - {% endif %} + {% endwith %} +
    + {% endfor %} {% endif %} - {% with session.all_meeting_slides as slides %} - {% for slide in slides %} + {% for slide in entry.slides %} {% if slide.time > old %} {% endif %} - {{ slide.title|clean_whitespace }} + {{ slide.material.title|clean_whitespace }}
    {% empty %} - No slides + No slides {% endfor %} - {% endwith %} - {% with session.all_meeting_drafts as drafts %} - {% for draft in drafts %} + {% for draft in entry.drafts %} {% if draft.time > old %} {% endif %} - {{ draft.name }} + + {{ draft.material.name }} +
    {% empty %} - No drafts + No Internet-Drafts {% endfor %} - {% endwith %} - {% if session.last_update %} - {{ session.last_update|utc|date:"Y-m-d" }} + {% if entry.last_update %} + {{ entry.last_update|utc|date:"Y-m-d" }}
    - {{ session.last_update|utc|date:"H:i:s" }} UTC + {{ entry.last_update|utc|date:"H:i:s" }} UTC {% endif %} {% if user|has_role:"Secretariat" or user_groups %} - {% if user|has_role:"Secretariat" or session.group in user_groups %} -
    {% include "meeting/edit_materials_button.html" %}
    + {% if user|has_role:"Secretariat" or entry.group in user_groups %} +
    {% include "meeting/edit_materials_button.html" with session=entry.session only %}
    {% endif %} {% endif %} diff --git a/ietf/templates/meeting/group_proceedings.html b/ietf/templates/meeting/group_proceedings.html index 99722fca4b7..496fa922634 100644 --- a/ietf/templates/meeting/group_proceedings.html +++ b/ietf/templates/meeting/group_proceedings.html @@ -1,115 +1,120 @@ -{# Copyright The IETF Trust 2015, All Rights Reserved #} +{# Copyright The IETF Trust 2015-2024, All Rights Reserved #} {% load origin %} {% origin %} {% load ietf_filters %} {% load proceedings_filters %} - {% if session.name %} -
    {{ session.name }}
    - {% else %} -
    - {{ session.group.acronym }} + {% if entry.name %} +
    {{ entry.name }}
    + {% elif entry.group.acronym %} + - {% if session.group.state_id == "bof" %}BOF{% endif %} + {% if entry.group.state_id == "bof" %}BOF{% endif %} + {% else %} +

    {{ entry.group }}

    {% endif %} - {% if session.all_meeting_sessions_cancelled %} + {% if entry.canceled %} - Session cancelled + Session cancelled {% else %} + {# artifacts #} - {% if session.all_meeting_agendas %} - {% if session.all_meeting_agendas|length == 1 %} - Agenda + {% for agenda in entry.agendas %} + + Agenda + {% if agenda.time %}{{agenda.time|date:"D G:i"}}{% endif %} + +
    + {% empty %} + {% if show_agenda and not meeting.proceedings_final %} + No agenda
    - {% else %} - {% for agenda in session.all_meeting_agendas %} - - Agenda {{ agenda.sessionpresentation_set.first.session.official_timeslotassignment.timeslot.time|date:"D G:i" }} - -
    - {% endfor %} {% endif %} - {% else %} - {% if show_agenda == "True" and not meeting.proceedings_final %} - No agenda + {% endfor %} + {% for minutes in entry.minutes %} + + Minutes + {% if minutes.time %}{{minutes.time|date:"D G:i"}}{% endif %} + +
    + {% empty %} + {% if show_agenda and not meeting.proceedings_final %} + No minutes
    {% endif %} - {% endif %} - {% if session.all_meeting_minutes %} - {% if session.all_meeting_minutes|length == 1 %} - Minutes -
    - {% else %} - {% for minutes in session.all_meeting_minutes %} - - Minutes {{ minutes.sessionpresentation_set.first.session.official_timeslotassignment.timeslot.time|date:"D G:i" }} + {% endfor %} + {% if not meeting.proceedings_final %} + {% for attendance in entry.attendances %} + {% with session=attendance.material %} + + Attendance + {% if attendance.time %}{{ attendance.time|date:"D G:i" }}{% endif %} -
    - {% endfor %} - {% endif %} - {% else %} - {% if show_agenda == "True" and not meeting.proceedings_final %} - No minutes -
    - {% endif %} - {% endif %} - {% if session.all_meeting_bluesheets %} - {% if session.all_meeting_bluesheets|length == 1 %} - Bluesheets -
    - {% else %} - {% for bs in session.all_meeting_bluesheets %} - - Bluesheets {{ bs.sessionpresentation_set.first.session.official_timeslotassignment.timeslot.time|date:"D G:i" }} - -
    - {% endfor %} - {% endif %} - {% endif %} - {% with session.group|status_for_meeting:meeting as status %} - {% if status %} - - Status - -
    - {% endif %} - {% endwith %} - - - {% if session.all_meeting_sessions_for_group|length == 1 %} - {% for rec in session.all_meeting_recordings %} - {{ rec|hack_recording_title:False }} + {% endwith %}
    {% endfor %} {% else %} - {% for rec in session.all_meeting_recordings %} - {{ rec|hack_recording_title:True }} + {% for bs in entry.bluesheets %} + + Bluesheets + {% if bs.time %}{{ bs.time|date:"D G:i" }}{% endif %} +
    {% endfor %} {% endif %} + {% for chatlog in entry.chatlogs %} + + Chatlog + {% if chatlog.time %}{{chatlog.time|date:"D G:i"}}{% endif %} + +
    + {% empty %} + + Chatlog + +
    + {% endfor %} + {# recordings #} - {% with session.all_meeting_slides as slides %} - {% for slide in slides %} - {{ slide.title|clean_whitespace }} -
    - {% empty %} - {% if not meeting.proceedings_final %}No slides{% endif %} - {% endfor %} - {% endwith %} + {% for rec in entry.recordings %} + + {{ rec.material|hack_recording_title }} + {% if rec.time %}{{ rec.time|date:"D G:i"}}{% endif %} + +
    + {% endfor %} + {% for rec in entry.meetecho_recordings %} + + Session recording + {% if rec.time %}{{ rec.time|date:"D G:i"}}{% endif %} + +
    + {% endfor%} + {# slides #} - {% with session.all_meeting_drafts as drafts %} - {% for draft in drafts %} - {{ draft.canonical_name }} -
    - {% empty %} - {% if not meeting.proceedings_final %}No drafts{% endif %} - {% endfor %} - {% endwith %} + {% for slide in entry.slides %} + {{ slide.material.title|clean_whitespace }} +
    + {% empty %} + {% if not meeting.proceedings_final %}No slides{% endif %} + {% endfor %} + + {# drafts #} + + {% for draft in entry.drafts %} + + {{ draft.material.name }} + +
    + {% empty %} + {% if not meeting.proceedings_final %}No Internet-Drafts{% endif %} + {% endfor %} {% endif %} \ No newline at end of file diff --git a/ietf/templates/meeting/important-dates.html b/ietf/templates/meeting/important-dates.html index a21fbc47881..568276f5665 100644 --- a/ietf/templates/meeting/important-dates.html +++ b/ietf/templates/meeting/important-dates.html @@ -1,7 +1,10 @@ {% extends "base.html" %} {# Copyright The IETF Trust 2017, All Rights Reserved #} {% load origin %} -{% load ietf_filters static textfilters ietf_filters %} +{% load ietf_filters static textfilters htmlfilters %} +{% block pagehead %} + +{% endblock %} {% block title %}IETF {{ meetings.0.number }}: Important Dates{% endblock %} {% block content %} {% origin %} @@ -16,15 +19,15 @@

    Important Dates

    {% for meeting in meetings %} {% if meeting.show_important_dates %} -

    +

    IETF {{ meeting.number }}
    - {{ meeting.date }}, {{ meeting.city }}, {{ meeting.country }} + {{ meeting.date }}, {{ meeting.city }}, {{ meeting.country }}

    - +
    - + @@ -42,30 +45,7 @@

    {% endif %}

    DateDate Weekday Description
    - {{ d.name.desc|urlize_ietf_docs|linkify }} - {% if first and d.name.slug == 'openreg' or first and d.name.slug == 'earlybird' %} - Register here. - {% endif %} - {% if d.name.slug == 'opensched' %} - To request a Working Group session, use the - IETF Meeting Session Request Tool. - If you are working on a BOF request, it is highly recommended - to tell the IESG now by sending an email to - iesg@ietf.org - to get advance help with the request. - {% endif %} - {% if d.name.slug == 'cutoffwgreq' %} - To request a Working Group session, use the - IETF Meeting Session Request Tool. - {% endif %} - {% if d.name.slug == 'cutoffbofreq' %} - To request a BOF, please see instructions on - Requesting a BOF. - {% endif %} - {% if d.name.slug == 'idcutoff' %} - Upload using the - ID Submission Tool. - {% endif %} + {{ d.name.desc|urlize_ietf_docs|markdown|linkify }}{% if d.name.desc|slice:"-1:" != "." %}.{% endif %} {% if d.name.slug == 'draftwgagenda' or d.name.slug == 'revwgagenda' or d.name.slug == 'procsub' or d.name.slug == 'revslug' %} Upload using the Meeting Materials Management Tool. @@ -78,4 +58,30 @@

    {% endif %} {% endfor %} + +{% endblock %} +{% block js %} + + + {% endblock %} \ No newline at end of file diff --git a/ietf/templates/meeting/important_dates.ics b/ietf/templates/meeting/important_dates.ics deleted file mode 100644 index 35079e01eb2..00000000000 --- a/ietf/templates/meeting/important_dates.ics +++ /dev/null @@ -1,5 +0,0 @@ -{% load humanize %}{% autoescape off %}{% load ietf_filters %}BEGIN:VCALENDAR -VERSION:2.0 -METHOD:PUBLISH -PRODID:-//IETF//datatracker.ietf.org ical importantdates//EN -{% for meeting in meetings %}{% include "meeting/important_dates_for_meeting.ics" %}{% endfor %}END:VCALENDAR{% endautoescape %} diff --git a/ietf/templates/meeting/important_dates_for_meeting.ics b/ietf/templates/meeting/important_dates_for_meeting.ics deleted file mode 100644 index 25c26eabf21..00000000000 --- a/ietf/templates/meeting/important_dates_for_meeting.ics +++ /dev/null @@ -1,23 +0,0 @@ -{% for d in meeting.important_dates %}BEGIN:VEVENT -UID:ietf-{{ meeting.number }}-{{ d.name_id }}-{{ d.date.isoformat }} -SUMMARY:IETF {{ meeting.number }}: {{ d.name.name }} -CLASS:PUBLIC -DTSTART{% if not d.midnight_cutoff %};VALUE=DATE{% endif %}:{{ d.date|date:"Ymd" }}{% if d.midnight_cutoff %}235900Z{% endif %} -DTSTAMP:{{ meeting.cached_updated|date:"Ymd" }}T{{ meeting.cached_updated|date:"His" }}Z -TRANSP:TRANSPARENT -DESCRIPTION:{{ d.name.desc }}{% if first and d.name.slug == 'openreg' or first and d.name.slug == 'earlybird' %}\n - Register here: https://www.ietf.org/how/meetings/register/{% endif %}{% if d.name.slug == 'opensched' %}\n - To request a Working Group session, use the IETF Meeting Session Request Tool:\n - {{ request.scheme }}://{{ request.get_host}}{% url 'ietf.secr.sreq.views.main' %}\n - If you are working on a BOF request, it is highly recommended to tell the IESG\n - now by sending an email to iesg@ietf.org to get advance help with the request.{% endif %}{% if d.name.slug == 'cutoffwgreq' %}\n - To request a Working Group session, use the IETF Meeting Session Request Tool:\n - {{ request.scheme }}://{{ request.get_host }}{% url 'ietf.secr.sreq.views.main' %}{% endif %}{% if d.name.slug == 'cutoffbofreq' %}\n - To request a BOF, please see instructions on Requesting a BOF:\n - https://www.ietf.org/how/bofs/bof-procedures/{% endif %}{% if d.name.slug == 'idcutoff' %}\n - Upload using the ID Submission Tool:\n - {{ request.scheme }}://{{ request.get_host }}{% url 'ietf.submit.views.upload_submission' %}{% endif %}{% if d.name.slug == 'draftwgagenda' or d.name.slug == 'revwgagenda' or d.name.slug == 'procsub' or d.name.slug == 'revslug' %}\n - Upload using the Meeting Materials Management Tool:\n - {{ request.scheme }}://{{ request.get_host }}{% url 'ietf.meeting.views.materials' num=meeting.number %}{% endif %} -END:VEVENT -{% endfor %} \ No newline at end of file diff --git a/ietf/templates/meeting/interim_announcement.txt b/ietf/templates/meeting/interim_announcement.txt index 07439409967..6ea2e4c9dc5 100644 --- a/ietf/templates/meeting/interim_announcement.txt +++ b/ietf/templates/meeting/interim_announcement.txt @@ -1,19 +1,22 @@ -{% load ietf_filters %}{% if is_change %}MEETING DETAILS HAVE CHANGED. SEE LATEST DETAILS BELOW. +{% load ietf_filters tz %}{% timezone meeting.tz %}{% if is_change %}MEETING DETAILS HAVE CHANGED. SEE LATEST DETAILS BELOW. -{% endif %}The {{ group.name }} ({{ group.acronym }}) {% if group.type.slug == 'wg' and group.state.slug == 'bof' %}BOF{% else %}{{group.type.name}}{% endif %} will hold -{% if assignments.count == 1 %}a{% if meeting.city %}n {% else %} virtual {% endif %}interim meeting on {{ meeting.date }} from {{ assignments.first.timeslot.time | date:"H:i" }} to {{ assignments.first.timeslot.end_time | date:"H:i" }} {{ meeting.time_zone}}{% if meeting.time_zone != 'UTC' %} ({{ assignments.first.timeslot.utc_start_time | date:"H:i" }} to {{ assignments.first.timeslot.utc_end_time | date:"H:i" }} UTC){% endif %}. -{% else %}a multi-day {% if not meeting.city %}virtual {% endif %}interim meeting. +{% endif %}{% filter wordwrap:78 %}The {{ group.name }} ({{ group.acronym }}) {% if group.type.slug == 'wg' and group.state.slug == 'bof' %}BOF{% else %}{{group.type.name}}{% endif %} will hold {% if assignments.count == 1 %}a{% if meeting.city %}n {% else %} virtual {% endif %}interim meeting on {{ meeting.date }} from {{ assignments.first.timeslot.time | date:"H:i" }} to {{ assignments.first.timeslot.end_time | date:"H:i" }} {{ meeting.time_zone}}{% if meeting.time_zone != 'UTC' %} ({{ assignments.first.timeslot.time | utc | date:"H:i" }} to {{ assignments.first.timeslot.end_time | utc | date:"H:i" }} UTC){% endif %}.{% else %}a multi-day {% if not meeting.city %}virtual {% endif %}interim meeting. {% for assignment in assignments %}Session {{ forloop.counter }}: -{{ assignment.timeslot.time | date:"Y-m-d" }} {{ assignment.timeslot.time | date:"H:i" }} to {{ assignment.timeslot.end_time | date:"H:i" }} {{ meeting.time_zone }}{% if meeting.time_zone != 'UTC' %}({{ assignment.timeslot.utc_start_time | date:"H:i" }} to {{ assignment.timeslot.utc_end_time | date:"H:i" }} UTC){% endif %} +{{ assignment.timeslot.time | date:"Y-m-d" }} {{ assignment.timeslot.time | date:"H:i" }} to {{ assignment.timeslot.end_time | date:"H:i" }} {{ meeting.time_zone }}{% if meeting.time_zone != 'UTC' %}({{ assignment.timeslot.time | utc | date:"H:i" }} to {{ assignment.timeslot.end_time | utc | date:"H:i" }} UTC){% endif %} {% endfor %}{% endif %} {% if meeting.city %}Meeting Location: {{ meeting.city }}, {{ meeting.country }} -{% endif %}Agenda: +{% endif %}{% endfilter %} +Agenda: {{ meeting.session_set.first.agenda | document_content | default_if_none:"(No agenda submitted)" }} Information about remote participation: -{{ meeting.session_set.first.remote_instructions }} +{{ meeting.session_set.first.remote_instructions.rstrip }} -{{ meeting.session_set.first.agenda_note }} +{{ meeting.session_set.first.agenda_note.rstrip|wordwrap:78 }}{% endtimezone %} + +-- +A calendar subscription for all {{ group.acronym }} meetings is available at +{{ settings.IDTRACKER_BASE_URL }}{% url 'ietf.meeting.views.upcoming_ical' %}?show={{ group.acronym }} diff --git a/ietf/templates/meeting/interim_info.txt b/ietf/templates/meeting/interim_info.txt index 4bb950b7d51..6180bc664f1 100644 --- a/ietf/templates/meeting/interim_info.txt +++ b/ietf/templates/meeting/interim_info.txt @@ -1,4 +1,4 @@ -{% load ietf_filters %} +{% load ietf_filters tz %}{% timezone meeting.time_zone %} --------------------------------------------------------- {{ group.type.verbose_name }} Name: {{ group.name|safe }} {% if group.type.slug == "wg" or group.type.slug == "directorate" or group.type.slug == "team" %}Area Name: {{ group.parent }} @@ -17,3 +17,4 @@ Remote Participation Information: {{ session.remote_instructions }} Agenda Note: {{ session.agenda_note }} {% endfor %} --------------------------------------------------------- +{% endtimezone %} \ No newline at end of file diff --git a/ietf/templates/meeting/interim_meeting_cancellation_notice.txt b/ietf/templates/meeting/interim_meeting_cancellation_notice.txt index 615342d9850..83f29bf1ed6 100644 --- a/ietf/templates/meeting/interim_meeting_cancellation_notice.txt +++ b/ietf/templates/meeting/interim_meeting_cancellation_notice.txt @@ -1,8 +1,8 @@ -{% load ams_filters %} +{% load ams_filters tz %}{% timezone meeting.time_zone %} The {{ group.name }} ({{ group.acronym }}) {% if not meeting.city %}virtual {% endif %}{% if is_multi_day %}multi-day {% endif %} interim meeting for {{ meeting.date|date:"Y-m-d" }} from {{ start_time|time:"H:i" }} to {{ end_time|time:"H:i" }} {{ meeting.time_zone }} has been cancelled. -{{ meeting.session_set.0.agenda_note }} - +{{ meeting.session_set.first.agenda_note }} +{% endtimezone %} diff --git a/ietf/templates/meeting/interim_pending.html b/ietf/templates/meeting/interim_pending.html index 7fbc4347bc0..b702f645827 100644 --- a/ietf/templates/meeting/interim_pending.html +++ b/ietf/templates/meeting/interim_pending.html @@ -31,11 +31,11 @@

    Pending Interim Meetings

    {{ meeting.number }} - {% if meeting.interim_meeting_cancelled %}Cancelled{% endif %} + {% if meeting.interim_meeting_cancelled %}Cancelled{% endif %} - {% if meeting.can_approve %}Can be approved{% endif %} + {% if meeting.can_approve %}Can be approved{% endif %} {% endfor %} diff --git a/ietf/templates/meeting/interim_request.html b/ietf/templates/meeting/interim_request.html index 977eaad3ffe..995a612b5a8 100644 --- a/ietf/templates/meeting/interim_request.html +++ b/ietf/templates/meeting/interim_request.html @@ -24,8 +24,8 @@

    Interim Meeting Request

    {% endif %} {% bootstrap_field form.meeting_type layout='horizontal' %} - {% bootstrap_field form.city layout='horizontal' %} - {% bootstrap_field form.country layout='horizontal' %} + {% bootstrap_field form.city layout='horizontal' wrapper_class='location mb-3' %} + {% bootstrap_field form.country layout='horizontal' wrapper_class='location mb-3' %} {% bootstrap_field form.time_zone layout='horizontal' %} {{ formset.management_form }} {% if formset.non_form_errors %}
    {{ formset.non_form_errors }}
    {% endif %} diff --git a/ietf/templates/meeting/interim_request_details.html b/ietf/templates/meeting/interim_request_details.html index 0cfec501be1..89545d14e56 100644 --- a/ietf/templates/meeting/interim_request_details.html +++ b/ietf/templates/meeting/interim_request_details.html @@ -1,12 +1,12 @@ {% extends "base.html" %} {# Copyright The IETF Trust 2015, All Rights Reserved #} {% load origin %} -{% load static django_bootstrap5 widget_tweaks ietf_filters person_filters textfilters %} +{% load static django_bootstrap5 widget_tweaks ietf_filters person_filters textfilters tz %} {% block title %}Interim Request Details{% endblock %} {% block pagehead %} {% endblock %} -{% block content %} +{% block content %}{% timezone meeting.tz %} {% origin %}

    Interim Meeting Request Details

    @@ -67,7 +67,7 @@

    Interim Meeting Request Details

    {{ assignment.timeslot.time|date:"H:i" }} {% if meeting.time_zone != 'UTC' %} - ({{ assignment.timeslot.utc_start_time|date:"H:i" }} UTC) + ({{ assignment.timeslot.time|utc|date:"H:i" }} UTC) {% endif %}
    @@ -103,56 +103,56 @@

    Interim Meeting Request Details

    {% endif %} {% endfor %}
    - {% if can_approve and status_slug == 'apprw' %} - - {% csrf_token %} - {% endif %} - {% with meeting_status.slug as status_slug %} - {% if can_edit %} - Edit - {% endif %} - {% if can_approve and status_slug == 'apprw' %} - - - {% endif %} - {% if user|has_role:"Secretariat" and status_slug == 'scheda' %} - - Announce - - - Skip announcement + {% with meeting_status.slug as status_slug %} + {% if can_approve and status_slug == 'apprw' %} + + {% csrf_token %} + {% endif %} + {% if can_edit %} + Edit + {% endif %} + {% if can_approve and status_slug == 'apprw' %} + + + {% endif %} + {% if user|has_role:"Secretariat" and status_slug == 'scheda' %} + + Announce + + + Skip announcement + + {% endif %} + {% if can_edit %} + {% if status_slug == 'apprw' or status_slug == 'scheda' or status_slug == 'sched' %} + + Cancel meeting {% endif %} - {% if can_edit %} - {% if status_slug == 'apprw' or status_slug == 'scheda' or status_slug == 'sched' %} - - Cancel meeting - - {% endif %} - {% endif %} - {% if status_slug == "apprw" %} - Back - {% elif status_slug == "scheda" %} - Back - {% elif status_slug == "sched" %} - - Back - - {% else %} - Back - {% endif %} - {% endwith %} - {% if can_approve and status_slug == 'apprw' %}{% endif %} -{% endblock %} + {% endif %} + {% if status_slug == "apprw" %} + Back + {% elif status_slug == "scheda" %} + Back + {% elif status_slug == "sched" %} + + Back + + {% else %} + Back + {% endif %} + {% if can_approve and status_slug == 'apprw' %}{% endif %} + {% endwith %} +{% endtimezone %}{% endblock %} {% block js %} -{% endblock %} +{% endblock %} \ No newline at end of file diff --git a/ietf/templates/meeting/interim_send_announcement.html b/ietf/templates/meeting/interim_send_announcement.html index fa05c72346d..d54229200ac 100644 --- a/ietf/templates/meeting/interim_send_announcement.html +++ b/ietf/templates/meeting/interim_send_announcement.html @@ -1,5 +1,5 @@ {% extends "base.html" %} -{# Copyright The IETF Trust 2015, All Rights Reserved #} +{# Copyright The IETF Trust 2015-2023, All Rights Reserved #} {% load origin %} {% load static django_bootstrap5 widget_tweaks %} {% block title %}Announce Interim Meeting{% endblock %} @@ -11,26 +11,7 @@

    Announce Interim Meeting

    {% csrf_token %} -
    - -
    {% render_field form.to class="form-control" readonly="readonly" %}
    -
    -
    - -
    {% render_field form.cc class="form-control" %}
    -
    -
    - -
    {% render_field form.frm class="form-control" readonly="readonly" %}
    -
    -
    - -
    {% render_field form.subject class="form-control" readonly="readonly" %}
    -
    -
    - -
    {% render_field form.body class="form-control" %}
    -
    + {% bootstrap_form form layout="horizontal" %} diff --git a/ietf/templates/meeting/interim_session_buttons.html b/ietf/templates/meeting/interim_session_buttons.html index b8443851b96..23263b98593 100644 --- a/ietf/templates/meeting/interim_session_buttons.html +++ b/ietf/templates/meeting/interim_session_buttons.html @@ -1,13 +1,15 @@ -{# Copyright The IETF Trust 2015, All Rights Reserved #} +{# Copyright The IETF Trust 2015-2022, All Rights Reserved #} {% load origin %} {% load static %} -{% load textfilters %} +{% load textfilters tz %} {% origin %} -{% with item=session.official_timeslotassignment acronym=session.historic_group.acronym %} +{% with item=session.official_timeslotassignment acronym=session.group_at_the_time.acronym %} + {% if session.agenda and show_agenda %} + {# Note: if called with show_agenda=True, calling template must load agenda_materials.js, needed by session_agenda_include.html #} + {% include "meeting/session_agenda_include.html" with slug=item.slug session=session timeslot=item.timeslot only %} + {% endif %}
    {% if session.agenda and show_agenda %} - {% include "meeting/session_agenda_include.html" with slug=item.slug session=session timeslot=item.timeslot only %} - {# Note: if called with show_agenda=True, calling template must load agenda_materials.js, needed by session_agenda_include.html #} {# agenda pop-up button #} {% endif %} - {# etherpad #} - {% if use_codimd %} + {# notes #} + {% if session.agenda.uses_notes %} {# Video stream (meetecho) #} - {% elif item.timeslot.location.video_stream_url %} + {% elif session.video_stream_url %} @@ -90,8 +92,8 @@ {# iCalendar item #} + aria-label="icalendar entry for {{ acronym }} session on {{ item.timeslot.time|utc|date:'Y-m-d H:i' }} UTC" + title="icalendar entry for {{ acronym }} session on {{ item.timeslot.time|utc|date:'Y-m-d H:i' }} UTC"> {% else %} @@ -144,17 +146,18 @@ {% endif %} {% endwith %} {% endfor %} - {% elif item.timeslot.location.video_stream_url %} + {% elif show_empty %} + {# #} + {% endif %} + {% if session.session_recording_url %} - {% elif show_empty %} - {# #} {% endif %} {% endwith %} {% endif %}
    -{% endwith %} \ No newline at end of file +{% endwith %} diff --git a/ietf/templates/meeting/interim_session_cancellation_notice.txt b/ietf/templates/meeting/interim_session_cancellation_notice.txt index 7be4c612bcf..b7a7321a246 100644 --- a/ietf/templates/meeting/interim_session_cancellation_notice.txt +++ b/ietf/templates/meeting/interim_session_cancellation_notice.txt @@ -1,7 +1,7 @@ -{% load ams_filters %} +{% load ams_filters tz %}{% timezone session.meeting.time_zone %} {% if session.name %}The "{{ session.name }}"{% else %}A{% endif %} session of the {{ group.name }} ({{ group.acronym }}) {% if not session.meeting.city %}virtual {% endif %}{% if is_multi_day %}multi-day {% endif %} -interim meeting has been cancelled. This session had been scheduled for {{ meeting.date|date:"Y-m-d" }} from {{ start_time|time:"H:i" }} to {{ end_time|time:"H:i" }} {{ meeting.time_zone }}. +interim meeting has been cancelled. This session had been scheduled for {{ session.meeting.date|date:"Y-m-d" }} from {{ start_time|time:"H:i" }} to {{ end_time|time:"H:i" }} {{ session.meeting.time_zone }}. {{ session.agenda_note }} - +{% endtimezone %} diff --git a/ietf/templates/meeting/make_schedule_official.html b/ietf/templates/meeting/make_schedule_official.html index 59bccaa967b..a35dc7c7f8e 100644 --- a/ietf/templates/meeting/make_schedule_official.html +++ b/ietf/templates/meeting/make_schedule_official.html @@ -10,7 +10,7 @@

    Make IETF {{ meeting.number }} Schedule Official
    - {{ schedule.owner }}/{{ schedule.name }} + {{ schedule.owner }}/{{ schedule.name }}

    {% csrf_token %} diff --git a/ietf/templates/meeting/materials.html b/ietf/templates/meeting/materials.html index c11744bafb7..ff4964a9735 100644 --- a/ietf/templates/meeting/materials.html +++ b/ietf/templates/meeting/materials.html @@ -23,8 +23,6 @@

    IETF {{ meeting.number }} meeting materials

    href="{% url 'ietf.meeting.views_proceedings.edit_meetinghosts' num=meeting.number %}"> Edit meeting hosts - Secretariat proceedings functions {% if meeting.end_date.today > meeting.end_date %} @@ -46,7 +44,7 @@

    Plenaries

    Agenda Minutes Slides - Drafts + Internet-Drafts Updated {% if user|has_role:"Secretariat" or user_groups %} @@ -54,17 +52,16 @@

    Plenaries

    - {% for session in plenaries %} + {% for entry in plenaries %} {% include "meeting/group_materials.html" %} {% endfor %} {% endif %} - {% regroup ietf|dictsort:"group.parent.acronym" by group.parent.name as areas %} - {% for sessions in areas %} -

    - {{ sessions.list.0.group.parent.acronym|upper }} {{ sessions.grouper }} + {% for area, meeting_groups, not_meeting_groups in ietf_areas %} +

    + {{ area.acronym|upper }} {{ area.name }}

    @@ -73,7 +70,7 @@

    - + {% if user|has_role:"Secretariat" or user_groups %} @@ -81,10 +78,8 @@

    - {% for session in sessions.list|dictsort:"group.acronym" %} - {% ifchanged session.group.acronym %} - {% include "meeting/group_materials.html" %} - {% endifchanged %} + {% for entry in meeting_groups %} + {% include "meeting/group_materials.html" %} {% endfor %}
    Agenda Minutes SlidesDraftsInternet-Drafts Updated
    @@ -101,7 +96,7 @@

    Training

    Minutes Slides - Drafts + Internet-Drafts Updated @@ -112,11 +107,8 @@

    Training

    - {% for session in training %} - {% ifchanged %} - {# TODO: Find a better way to represent purposed sessions in both materials and proceedings #} - {% include "meeting/group_materials.html" %} - {% endifchanged %} + {% for entry in training %} + {% include "meeting/group_materials.html" %} {% endfor %} @@ -143,7 +135,7 @@

    Slides - Drafts + Internet-Drafts Updated @@ -154,10 +146,8 @@

    - {% for session in iab %} - {% ifchanged session.group.acronym %} - {% include "meeting/group_materials.html" %} - {% endifchanged %} + {% for entry in iab %} + {% include "meeting/group_materials.html" %} {% endfor %} @@ -183,7 +173,7 @@

    Slides - Drafts + Internet-Drafts Updated @@ -194,10 +184,44 @@

    - {% for session in irtf|dictsort:"group.acronym" %} - {% ifchanged session.group.acronym %} - {% include "meeting/group_materials.html" %} - {% endifchanged %} + {% for entry in irtf %} + {% include "meeting/group_materials.html" %} + {% endfor %} + + + {% endif %} + + {% if editorial %} +

    Editorial Stream

    + + + + + + + + + + {% if user|has_role:"Secretariat" or user_groups %} + + {% endif %} + + + + {% for entry in editorial %} + {% include "meeting/group_materials.html" %} {% endfor %}
    + Group + + Agenda + + Minutes + + Slides + + Internet-Drafts + + Updated +
    @@ -222,7 +246,7 @@

    Slides - Drafts + Internet-Drafts Updated @@ -233,10 +257,8 @@

    - {% for session in other|dictsort:"group.acronym" %} - {% ifchanged session.group.acronym %} - {% include "meeting/group_materials.html" %} - {% endifchanged %} + {% for entry in other %} + {% include "meeting/group_materials.html" %} {% endfor %} @@ -247,4 +269,4 @@

    {% block js %} -{% endblock %} \ No newline at end of file +{% endblock %} diff --git a/ietf/templates/meeting/materials_editable_groups.html b/ietf/templates/meeting/materials_editable_groups.html index d91e6f21410..5c8645ecff2 100644 --- a/ietf/templates/meeting/materials_editable_groups.html +++ b/ietf/templates/meeting/materials_editable_groups.html @@ -14,7 +14,7 @@

    IETF {{ meeting_num }} meeting materials that you can edit

    {% if g|has_sessions:meeting_num %}
    {{ g.acronym }} {% else %} - {{ g.acronym }} No session requested + {{ g.acronym }} No session requested {% endif %} {% endfor %} diff --git a/ietf/templates/meeting/meeting_heading.html b/ietf/templates/meeting/meeting_heading.html deleted file mode 100644 index ec44fc78bfe..00000000000 --- a/ietf/templates/meeting/meeting_heading.html +++ /dev/null @@ -1,85 +0,0 @@ -{# Copyright The IETF Trust 2015, All Rights Reserved #} -{% load origin %} -{% origin %} -{# assumes meeting is in context #} -{% load origin %} -{% load ietf_filters htmlfilters %} -{% origin %} -

    - IETF {{ meeting.number }} meeting agenda - {% if personalize %}personalization{% endif %} - {% if schedule.meeting.agenda_warning_note %} - - {{ schedule.meeting.agenda_warning_note|removetags:"h1" |safe }} - - {% endif %} - {% if title_extra %} -
    - {{ title_extra }} - {% endif %} -

    -
    -
    - {{ meeting.city|default:"Location TBD" }}, {{ meeting.date|date:"F j" }}{% if meeting.date.month != meeting.end_date.month %} - {{ meeting.end_date|date:"F " }}{% else %}-{% endif %}{{ meeting.end_date|date:"j, Y" }} -
    - {% if updated %} -
    - Updated {{ updated|date:"Y-m-d \a\t G:i (T)" }} -
    - {% endif %} -
    -{% if schedule != meeting.schedule %} -
    - This is schedule {{ schedule.owner.email }}/{{ schedule.name }}, not the official schedule. -
    -{% endif %} -{# a tags with the agenda-link filterable classes will be updated with show/hide parameters #} - \ No newline at end of file diff --git a/ietf/templates/meeting/new_meeting_schedule.html b/ietf/templates/meeting/new_meeting_schedule.html index c93d72b2ab5..d1b5263c531 100644 --- a/ietf/templates/meeting/new_meeting_schedule.html +++ b/ietf/templates/meeting/new_meeting_schedule.html @@ -1,7 +1,7 @@ {% extends "base.html" %} {# Copyright The IETF Trust 2015-2020, All Rights Reserved #} {% load origin %} -{% load staticfiles %} +{% load static %} {% load ietf_filters %} {% load django_bootstrap5 %} {% block content %} diff --git a/ietf/templates/meeting/no-agenda.html b/ietf/templates/meeting/no-agenda.html deleted file mode 100644 index 534236ed156..00000000000 --- a/ietf/templates/meeting/no-agenda.html +++ /dev/null @@ -1,9 +0,0 @@ -{% extends "base.html" %} -{# Copyright The IETF Trust 2015, All Rights Reserved #} -{% load origin %} -{% block title %}IETF {{ meeting.number }} Meeting Agenda{% endblock %} -{% block content %} - {% origin %} - {% include "meeting/meeting_heading.html" with title_extra="" selected="" %} -
    There is no agenda available yet.
    -{% endblock %} \ No newline at end of file diff --git a/ietf/templates/meeting/past.html b/ietf/templates/meeting/past.html index 8c330cd4121..7c8ac621fff 100644 --- a/ietf/templates/meeting/past.html +++ b/ietf/templates/meeting/past.html @@ -2,11 +2,13 @@ {# Copyright The IETF Trust 2015, All Rights Reserved #} {% load origin %} {% load ietf_filters static %} +{% load cache %} {% block pagehead %} {% endblock %} {% block title %}Past Meetings{% endblock %} {% block content %} + {% cache 3600 pastmeetings %} {% origin %}

    Past Meetings

    {% if meetings %} @@ -35,9 +37,13 @@

    Past Meetings

    {% if meeting.type_id == "interim" %} {{ meeting.number }} - {% if meeting.interim_meeting_cancelled %}Cancelled{% endif %} + {% if meeting.interim_meeting_cancelled %}Cancelled{% endif %} {% else %} - IETF-{{ meeting.number }} + {% if meeting.get_number > 28 %} + IETF-{{ meeting.number }} + {% else %} + IETF-{{ meeting.number }} + {% endif %} {% endif %} @@ -55,6 +61,7 @@

    Past Meetings

    {% else %}

    No past meetings

    {% endif %} + {% endcache %} {% endblock %} {% block js %} diff --git a/ietf/templates/meeting/previously_approved_slides.html b/ietf/templates/meeting/previously_approved_slides.html index 060be438e06..95975cb63f8 100644 --- a/ietf/templates/meeting/previously_approved_slides.html +++ b/ietf/templates/meeting/previously_approved_slides.html @@ -1,6 +1,6 @@ {% extends "base.html" %} {# Copyright The IETF Trust 2020, All Rights Reserved #} -{% load origin staticfiles django_bootstrap5 %} +{% load origin static django_bootstrap5 %} {% block title %} Approved Slides for {{ submission.session.meeting }} : {{ submission.session.group.acronym }} {% endblock %} @@ -11,7 +11,7 @@

    {% if submission.status.slug == 'approved' %} approved {% else %} - rejected + declined {% endif %}

    @@ -19,7 +19,7 @@

    {% if submission.status.slug == 'approved' %} approved. {% else %} - rejected. + declined. {% endif %} No further action is needed.

    @@ -33,4 +33,4 @@

    return to this meeting session .

    -{% endblock %} \ No newline at end of file +{% endblock %} diff --git a/ietf/templates/meeting/proceedings.html b/ietf/templates/meeting/proceedings.html index 687c5dac177..0aa8197fe93 100644 --- a/ietf/templates/meeting/proceedings.html +++ b/ietf/templates/meeting/proceedings.html @@ -1,201 +1,215 @@ -{% extends "base.html" %} -{# Copyright The IETF Trust 2015, All Rights Reserved #} -{% load origin %} -{% load ietf_filters static %} -{% block pagehead %} - -{% endblock %} -{% block title %} - IETF {{ meeting.number }} - {% if not meeting.proceedings_final %}Draft{% endif %} - Proceedings -{% endblock %} -{% block content %} - {% origin %} - {% include 'meeting/proceedings/title.html' with meeting=meeting attendance=attendance only %} - {% if user|has_role:"Secretariat" and not meeting.proceedings_final %} - - Finalize proceedings - +{% include 'meeting/proceedings/introduction.html' with meeting=meeting only %} + +{% if plenaries %} +

    Plenaries

    + + + + + + + + + + + + {% for entry in plenaries %} + {% include "meeting/group_proceedings.html" with entry=entry meeting=meeting show_agenda=True only %} + {% endfor %} + +
    GroupArtifactsRecordingsSlidesInternet-Drafts
    +{% endif %} + +{% for area, meeting_groups, not_meeting_groups in ietf_areas %} +

    + {{ area.acronym|upper }} {{ area.name }} +

    + {% if meeting_groups %} + + + + + + + + + + + + {% for entry in meeting_groups %} + {% include "meeting/group_proceedings.html" with entry=entry meeting=meeting show_agenda=True only %} + {% endfor %} + +
    GroupArtifactsRecordingsSlidesInternet-Drafts
    + {% endif %} + {% if not_meeting_groups %} +

    + {{ area.name }} groups not meeting: + {% for entry in not_meeting_groups %} + {% if entry.name == "" %}{# do not show named sessions in this list #} + + {{ entry.group.acronym }} + {% if not forloop.last %},{% endif %} + {% endif %} + {% endfor %} +

    + + + + + + + + + + + + {% for entry in not_meeting_groups %}{% if entry.has_materials %} + {% include "meeting/group_proceedings.html" with entry=entry meeting=meeting show_agenda=True only %} + {% endif %}{% endfor %} + +
    {% endif %} - {# cache for 15 minutes, as long as there's no proceedings activity. takes 4-8 seconds to generate. #} - {% load cache %} - {% cache 900 ietf_meeting_proceedings meeting.number cache_version %} - {% include 'meeting/proceedings/introduction.html' with meeting=meeting only %} - {% with "True" as show_agenda %} - - {% if plenaries %} -

    Plenaries

    - - - - - - - - - - - - {% for session in plenaries %} - {% include "meeting/group_proceedings.html" %} - {% endfor %} - -
    GroupArtifactsRecordingsSlidesDrafts
    - {% endif %} - - {% for area, meeting_sessions, not_meeting_sessions in ietf_areas %} -

    - {{ area.acronym|upper }} {{ area.name }} -

    - {% if meeting_sessions %} - - - - - - - - - - - - {% for session in meeting_sessions %} - {% ifchanged session.group.acronym %} - {% include "meeting/group_proceedings.html" %} - {% endifchanged %} - {% endfor %} - -
    GroupArtifactsRecordingsSlidesDrafts
    - {% endif %} - {% if not_meeting_sessions %} -

    - {{ area.name }} groups not meeting: - {% for session in not_meeting_sessions %} - {% ifchanged session.group.acronym %} - {{ session.group.acronym }}{% if not forloop.last %},{% endif %} - {% endifchanged %} - {% endfor %} -

    - - - - - - - - - - - - {% for session in not_meeting_sessions %} - {% ifchanged session.group.acronym %} - {% if session.sessionpresentation_set.exists %} - {% include "meeting/group_proceedings.html" %} - {% endif %} - {% endifchanged %} - {% endfor %} - -
    - {% endif %} +{% endfor %} + +{% if training %} +

    Training

    + + + + + + + + + + + + {% for entry in training %} + {% include "meeting/group_proceedings.html" with entry=entry meeting=meeting show_agenda=False only %} + {% endfor %} + +
    GroupArtifactsRecordingsSlidesInternet-Drafts
    +{% endif %} + +{% if iab %} +

    + IAB Internet Architecture Board +

    + + + + + + + + + + + + {% for entry in iab %} + {% include "meeting/group_proceedings.html" with entry=entry meeting=meeting show_agenda=True only %} {% endfor %} - - {% if training %} - {% with "False" as show_agenda %} -

    Training

    -
    + Group + + Artifacts + + Recordings + + Slides + + Internet-Drafts +
    - - - - - - - - - - - {% for session in training %} - {% ifchanged %} - {% include "meeting/group_proceedings.html" %} - {% endifchanged %} - {% endfor %} - -
    GroupArtifactsRecordingsSlidesDrafts
    - {% endwith %} - {% endif %} - - {% if iab %} -

    - IAB Internet Architecture Board -

    - - - - - - - - - - - - {% for session in iab %} - {% ifchanged %} - {% include "meeting/group_proceedings.html" %} - {% endifchanged %} - {% endfor %} - -
    - Group - - Artifacts - - Recordings - - Slides - - Drafts -
    - {% endif %} - - {% if irtf %} -

    - IRTF Internet Research Task Force -

    - - - - - - - - - - - - {% for session in irtf|dictsort:"group.acronym" %} - {% ifchanged %} - {% include "meeting/group_proceedings.html" %} - {% endifchanged %} - {% endfor %} - -
    - Group - - Artifacts - - Recordings - - Slides - - Drafts -
    - {% endif %} - {% endwith %} -{% endcache %} -{% endblock %} -{% block js %} - -{% endblock %} \ No newline at end of file + + +{% endif %} + +{% if irtf.meeting_groups %} +

    + IRTF Internet Research Task Force +

    + + + + + + + + + + + + {% for entry in irtf.meeting_groups %} + {% include "meeting/group_proceedings.html" with entry=entry meeting=meeting show_agenda=True only %} + {% endfor %} + +
    + Group + + Artifacts + + Recordings + + Slides + + Internet-Drafts +
    + {% if irtf.not_meeting_groups %} +

    + IRTF groups not meeting: + {% for entry in irtf.not_meeting_groups %} + {% if entry.name == "" %}{# do not show named sessions in this list #} + + {{ entry.group.acronym }} + {% if not forloop.last %},{% endif %} + {% endif %} + {% endfor %} +

    + + + + + + + + + + + + {% for entry in irtf.not_meeting %}{% if entry.has_materials %} + {% include "meeting/group_proceedings.html" with entry=entry meeting=meeting show_agenda=True only %} + {% endif %}{% endfor %} + +
    + {% endif %} + + {% if editorial %} +

    Editorial Stream

    + + + + + + + + + + + + {% for entry in editorial %} + {% include "meeting/group_proceedings.html" with entry=entry meeting=meeting show_agenda=True only %} + {% endfor %} + +
    + Group + + Artifacts + + Recordings + + Slides + + Internet-Drafts +
    + {% endif %} +{% endif %} diff --git a/ietf/templates/meeting/proceedings/edit_material_base.html b/ietf/templates/meeting/proceedings/edit_material_base.html index 173e1d2360b..be66fa3305e 100644 --- a/ietf/templates/meeting/proceedings/edit_material_base.html +++ b/ietf/templates/meeting/proceedings/edit_material_base.html @@ -9,7 +9,7 @@

    {% block content_header %} Edit Proceedings Material
    - {{ meeting }} {{ material_type.name }} + {{ meeting }} {{ material_type.name }} {% endblock %}

    {% if meeting.proceedings_final %} diff --git a/ietf/templates/meeting/proceedings/edit_meetinghosts.html b/ietf/templates/meeting/proceedings/edit_meetinghosts.html index 89e3eb25f3b..68c684a2fa5 100644 --- a/ietf/templates/meeting/proceedings/edit_meetinghosts.html +++ b/ietf/templates/meeting/proceedings/edit_meetinghosts.html @@ -8,7 +8,7 @@

    Edit Meeting Hosts
    - {{ meeting }} + {{ meeting }}

    {% if meeting.proceedings_final %}
    The proceedings for this meeting have already been finalized.
    diff --git a/ietf/templates/meeting/proceedings/introduction.html b/ietf/templates/meeting/proceedings/introduction.html index 90c3822f4a5..9f6f9af0025 100644 --- a/ietf/templates/meeting/proceedings/introduction.html +++ b/ietf/templates/meeting/proceedings/introduction.html @@ -11,10 +11,10 @@ Participants
    Important Dates diff --git a/ietf/templates/meeting/proceedings/material_details.html b/ietf/templates/meeting/proceedings/material_details.html index 0b5f048c99a..aa2c45fde3b 100644 --- a/ietf/templates/meeting/proceedings/material_details.html +++ b/ietf/templates/meeting/proceedings/material_details.html @@ -7,7 +7,7 @@

    {{ meeting }}
    - Proceedings Materials + Proceedings Materials

    {% if meeting.proceedings_final %}
    The proceedings have been finalized for this meeting.
    @@ -43,7 +43,7 @@

    {% with timestamp=mat.document.time|utc %} {{ timestamp|date:"Y-m-d" }}
    - {{ timestamp|date:"H:i:s" }} UTC + {{ timestamp|date:"H:i:s" }} UTC {% endwith %} {% else %} diff --git a/ietf/templates/meeting/proceedings/materials_table.html b/ietf/templates/meeting/proceedings/materials_table.html index 25a17252259..d18f2ce8d7d 100644 --- a/ietf/templates/meeting/proceedings/materials_table.html +++ b/ietf/templates/meeting/proceedings/materials_table.html @@ -26,7 +26,7 @@

    Proceedings Materials

    {% with timestamp=material.document.time|utc %} {{ timestamp|date:"Y-m-d" }}
    - {{ timestamp|date:"H:i:s" }} UTC + {{ timestamp|date:"H:i:s" }} UTC {% endwith %} {% else %} diff --git a/ietf/templates/meeting/proceedings/title.html b/ietf/templates/meeting/proceedings/title.html index 6e7fe8068ab..afeaac8ea41 100644 --- a/ietf/templates/meeting/proceedings/title.html +++ b/ietf/templates/meeting/proceedings/title.html @@ -13,9 +13,9 @@

    {% if attendance is not None %}
    {% if attendance.onsite > 0 %} - {{ attendance.onsite }} onsite participant{{ attendance.onsite|pluralize }}{% if attendance.online > 0 %},{% endif %} + {{ attendance.onsite }} onsite participant{{ attendance.onsite|pluralize }}{% if attendance.remote > 0 %},{% endif %} {% endif %} - {% if attendance.online > 0 %}{{ attendance.online }} online participant{{ attendance.online|pluralize }}{% endif %} + {% if attendance.remote > 0 %}{{ attendance.remote }} online participant{{ attendance.remote|pluralize }}{% endif %}
    {% endif %}

    diff --git a/ietf/templates/meeting/proceedings/upload_material.html b/ietf/templates/meeting/proceedings/upload_material.html index a581b987f04..4c97d5b3666 100644 --- a/ietf/templates/meeting/proceedings/upload_material.html +++ b/ietf/templates/meeting/proceedings/upload_material.html @@ -6,7 +6,7 @@ {% block content_header %} Upload Proceedings Material
    - {{ meeting }} {{ material_type.name }} + {{ meeting }} {{ material_type.name }} {% endblock %} {% block intro %}

    diff --git a/ietf/templates/meeting/proceedings_activity_report.html b/ietf/templates/meeting/proceedings_activity_report.html new file mode 100644 index 00000000000..dd5b082bf54 --- /dev/null +++ b/ietf/templates/meeting/proceedings_activity_report.html @@ -0,0 +1,18 @@ +{% extends "base.html" %} +{% load ams_filters ietf_filters cache %} +{% block title %}IETF {{ meeting.number }} Proceedings - Activity Report{% endblock %} +{% block content %} + {% cache 3600 proceedings_activity_report meeting.number %} +

    + + IETF {{ meeting.number }} proceedings + +

    +

    IETF Activity Report

    +

    {{ sdate|date:"d-F-y" }} to {{ edate|date:"d-F-y" }}

    + + {% include "meeting/activity_report.html" %} + + {% endcache %} +{% endblock %} \ No newline at end of file diff --git a/ietf/templates/meeting/proceedings_attendees.html b/ietf/templates/meeting/proceedings_attendees.html index 5d2742863fc..0c59d4ab155 100644 --- a/ietf/templates/meeting/proceedings_attendees.html +++ b/ietf/templates/meeting/proceedings_attendees.html @@ -1,6 +1,10 @@ {% extends "base.html" %} {# Copyright The IETF Trust 2015, All Rights Reserved #} -{% load origin markup_tags %} +{% load origin markup_tags static %} +{% block pagehead %} + + {% if chart_data %}{% endif %} +{% endblock %} {% block title %}IETF {{ meeting.number }} proceedings{% endblock %} {% block content %} {% origin %} @@ -11,5 +15,82 @@

    Attendee list of IETF {{ meeting.number }} meeting

    - {{ template|safe }} -{% endblock %} \ No newline at end of file + + {% if chart_data %} +
    +
    +
    Onsite: {{ stats.onsite }}
    +
    Remote: {{ stats.remote }}
    +
    Total: {{ stats.total }}
    +
    + +
    + + + + {{ chart_data|json_script:"attendees-chart-data" }} + {% endif %}{# chart_data #} + + {% if template %} + + {{template|safe}} + {% else %} + + + + + + + + + + + + {% for reg in registrations %} + + + + + + + + {% endfor %} + +
    Last NameFirst NameOrganizationCountryRegistration Type
    {{ reg.last_name }}{{ reg.first_name }}{{ reg.affiliation }}{{ reg.country_code }}{{ reg.attendance_type }}
    + {% endif %} +{% endblock %} +{% block js %} + + {% if chart_data %} + + + {% endif %} +{% endblock %} diff --git a/ietf/templates/meeting/proceedings_attendees_table.html b/ietf/templates/meeting/proceedings_attendees_table.html deleted file mode 100644 index 9ac1fda2acf..00000000000 --- a/ietf/templates/meeting/proceedings_attendees_table.html +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - - - - - - {% for attendee in attendees %} - - - - - - - {% endfor %} - -
    Last nameFirst nameOrganizationCountry
    {{ attendee.LastName }}{{ attendee.FirstName }}{{ attendee.Company }}{{ attendee.Country }}
    \ No newline at end of file diff --git a/ietf/templates/meeting/proceedings_overview.html b/ietf/templates/meeting/proceedings_overview.html index 3b43261feea..1590acb2b07 100644 --- a/ietf/templates/meeting/proceedings_overview.html +++ b/ietf/templates/meeting/proceedings_overview.html @@ -11,6 +11,6 @@

    IETF overview

    - + {{ template|safe }} {% endblock %} \ No newline at end of file diff --git a/ietf/templates/meeting/proceedings_progress_report.html b/ietf/templates/meeting/proceedings_progress_report.html deleted file mode 100644 index a51fb01e6c4..00000000000 --- a/ietf/templates/meeting/proceedings_progress_report.html +++ /dev/null @@ -1,70 +0,0 @@ -{% extends "base.html" %} -{% load ams_filters ietf_filters %} -{% block title %}IETF {{ meeting.number }} Proceedings - Progress Report{% endblock %} -{% block content %} -

    - - IETF {{ meeting.number }} proceedings - -

    -

    IETF Progress Report

    -

    {{ sdate|date:"d-F-y" }} to {{ edate|date:"d-F-y" }}

    -
      -
    • {{ actions_count }} IESG Protocol and Document Actions this period
    • -
    • {{ last_calls_count }} IESG Last Calls issued to the IETF this period
    • -
    • - {{ new_drafts_count|stringformat:"3s" }} New I-Ds ({{ new_drafts_updated_count }} of which were updated, some ({{ new_drafts_updated_more_count }}) more than once) -
    • -
    • {{ updated_drafts_count|stringformat:"3s" }} I-Ds were updated (Some more than once)
    • -
    • -

      In the final 4 weeks before meeting

      -
    • -
    • - {{ ffw_new_count|stringformat:"3s" }} New I-Ds were received - {{ ffw_new_percent }} of total newbies since last meeting -
    • -
    • - {{ ffw_update_count|stringformat:"3s" }} I-Ds were updated - {{ ffw_update_percent }} of total updated since last meeting -
    • -
    -

    {{ new_groups.count }} New Working Group(s) formed this period

    -
      - {% for group in new_groups %}
    • {{ group.name }} ({{ group.acronym }})
    • {% endfor %} -
    -

    {{ concluded_groups.count }} Working Group(s) concluded this period

    -
      - {% for group in concluded_groups %}
    • {{ group.name }} ({{ group.acronym }})
    • {% endfor %} -
    -

    {{ rfcs.count }} RFCs published this period

    -

    - {{ counts.std }} Standards Track; {{ counts.bcp }} BCP; {{ counts.exp }} Experimental; {{ counts.inf }} Informational -

    - - - - - - - - - - - {% if rfcs %} - - {% for rfc in rfcs %} - - - - - - - - {% endfor %} - - {% endif %} -
    RFCStatusGroupDateTitle
    - {{ rfc.doc.canonical_name|prettystdname }} - {{ rfc.doc.intended_std_level.name }} - {{ rfc.doc.group.acronym }} - {{ rfc.time|date:"F Y" }}{{ rfc.doc.title }}
    -{% endblock %} \ No newline at end of file diff --git a/ietf/templates/meeting/proceedings_wrapper.html b/ietf/templates/meeting/proceedings_wrapper.html new file mode 100644 index 00000000000..a20291a6930 --- /dev/null +++ b/ietf/templates/meeting/proceedings_wrapper.html @@ -0,0 +1,27 @@ +{% extends "base.html" %} +{# Copyright The IETF Trust 2015, All Rights Reserved #} +{% load origin %} +{% load ietf_filters static %} +{% block pagehead %} + +{% endblock %} +{% block title %} + IETF {{ meeting.number }} + {% if not meeting.proceedings_final %}Draft{% endif %} + Proceedings +{% endblock %} +{% block content %} + {% origin %} + {% include 'meeting/proceedings/title.html' with meeting=meeting attendance=attendance only %} + {% if user|has_role:"Secretariat" and not meeting.proceedings_final %} + + Finalize proceedings + + {% endif %} + {{ proceedings_content }} +{% endblock %} +{% block js %} + +{% endblock %} diff --git a/ietf/templates/meeting/properties_edit.html b/ietf/templates/meeting/properties_edit.html index a6b6fc477f1..57172d86c80 100644 --- a/ietf/templates/meeting/properties_edit.html +++ b/ietf/templates/meeting/properties_edit.html @@ -7,7 +7,7 @@ {% block title %}IETF {{ meeting.number }} Meeting Agenda: {{ schedule.owner }} / {{ schedule.name }}{% endblock %} {% block content %} {% origin %} -

    IETF {{ meeting.number }} Schedule
    +

    IETF {{ meeting.number }} Schedule
    {{ schedule.owner }}/{{ schedule.name }} ({{ schedule.official_token }})

    {% if not schedule.is_official %} diff --git a/ietf/templates/meeting/propose_session_slides.html b/ietf/templates/meeting/propose_session_slides.html deleted file mode 100644 index 8315c2deba4..00000000000 --- a/ietf/templates/meeting/propose_session_slides.html +++ /dev/null @@ -1,27 +0,0 @@ -{% extends "base.html" %} -{# Copyright The IETF Trust 2015, All Rights Reserved #} -{% load origin static django_bootstrap5 %} -{% block title %}Propose Slides for {{ session.meeting }} : {{ session.group.acronym }}{% endblock %} -{% block content %} - {% origin %} -

    - Propose Slides for {{ session.meeting }} -
    - {{ session.group.acronym }} - {% if session.name %}: {{ session.name }}{% endif %} - -

    - {% if session_number %} -

    - Session {{ session_number }} : {{ session.official_timeslotassignment.timeslot.time|date:"D M-d-Y Hi" }} -

    - {% endif %} -

    - This form will allow you to propose a slide deck to the session chairs. After you upload your proposal, mail will be sent to the session chairs asking for their approval. -

    - - {% csrf_token %} - {% bootstrap_form form %} - - -{% endblock %} \ No newline at end of file diff --git a/ietf/templates/meeting/request_minutes.html b/ietf/templates/meeting/request_minutes.html index fc39c034f95..4231b8d12dd 100644 --- a/ietf/templates/meeting/request_minutes.html +++ b/ietf/templates/meeting/request_minutes.html @@ -9,7 +9,7 @@

    Request Minutes
    - IETF {{ meeting.number }} + IETF {{ meeting.number }}
    {{ meeting.city }}, {{ meeting.country }} – {{ meeting.venue_name }}

    diff --git a/ietf/templates/meeting/requests.html b/ietf/templates/meeting/requests.html index 1a4db6b9932..0abee95887b 100644 --- a/ietf/templates/meeting/requests.html +++ b/ietf/templates/meeting/requests.html @@ -1,7 +1,7 @@ {% extends "base.html" %} -{# Copyright The IETF Trust 2015, All Rights Reserved #} +{# Copyright The IETF Trust 2015-2025, All Rights Reserved #} {% load origin %} -{% load ietf_filters static person_filters %} +{% load ietf_filters static person_filters textfilters %} {% block pagehead %} {% endblock %} @@ -11,15 +11,112 @@

    IETF {{ meeting.number }} timeslot requests
    - {{ meeting.city }}, {{ meeting.country }} + {{ meeting.city }}, {{ meeting.country }} {% if meeting.venue_name %}– {{ meeting.venue_name }}{% endif %}

    + +

    Requests Summary

    +

    This summary section focuses on sessions that have conflict lists to manage. It excludes requests from groups of type "team", such as those for the hackathon or for tutorials.

    +
    + + {% for row in summary_by_area %} + {% if forloop.first %} + + + {% for col in row %} + + {% endfor %} + + + + {% elif forloop.last %} + + + + {% for col in row %} + + {% endfor %} + {# last line is missing two columns? #} + + + + {% else %} + + {% for col in row %} + {% if forloop.first %} + + {% else %} + + {% endif %} + {% endfor %} + + {% endif %} + {% endfor %} +
    {{ col }}
    {{ col }}
    {{ col }}{{ col }}
    +
    +
    +
    + + {% for row in summary_by_group_type %} + {% if forloop.first %} + + + {% for col in row %} + + {% endfor %} + + + + {% else %} + + {% for col in row %} + {% if forloop.first %} + + {% else %} + + {% endif %} + {% endfor %} + + {% endif %} + {% endfor %} + +
    {{ col }}
    {{ col }}{{ col }}
    +
    +
    + + {% for row in summary_by_purpose %} + {% if forloop.first %} + + + {% for col in row %} + + {% endfor %} + + + + {% else %} + + {% for col in row %} + {% if forloop.first %} + + {% else %} + + {% endif %} + {% endfor %} + + {% endif %} + {% endfor %} + +
    {{ col }}
    {{ col }}{{ col }}
    +
    +
    + {% regroup sessions by display_area as area_sessions %} {% for area in area_sessions %}

    {% if area.grouper is not None %} - {{ area.grouper.acronym|upper }} {{ area.grouper.name }} + {{ area.grouper.acronym|upper }} {{ area.grouper.name }} {% else %} Other Groups {% endif %} @@ -34,10 +131,10 @@

    Group - Length - Size - Requester - AD + Length + Size + Requester + AD Constraints Special requests @@ -54,38 +151,49 @@

    {% endifchanged %} - + {{ session.group.acronym }} + {% if session.purpose_id != "regular" and session.purpose_id != "none" %} +
    {{session.purpose}} + {% endif %} {% if session.joint_with_groups.count %}joint with {{ session.joint_with_groups_acronyms|join:' ' }}{% endif %} + {% if session.requested_duration %} +
    + {{ session.requested_duration|stringformat:"s"|slice:"0:4" }} +
    + {% endif %} + {% if session.attendees %} +
    + {{ session.attendees }} +
    + {% endif %} + {% if session.group.state.slug != "active" %} +
    {{ session.group.state.name }} + {% endif %} - + {% if session.requested_duration %}{{ session.requested_duration|stringformat:"s"|slice:"0:4" }}{% endif %} - {{ session.attendees|default:"" }} - {% person_link session.requested_by_person %} - + {{ session.attendees|default:"" }} + {% person_link session.requested_by_person with_email=False %} + {% if session.group.ad_role %} - {% person_link session.group.ad_role.person %} + {% person_link session.group.ad_role.person with_email=False %} {% endif %} {% if session.requested_duration %} {% regroup session.constraints by name as prioritized_constraints %} {% for grouped_constraint in prioritized_constraints %} - {% if not forloop.first %} - {% ifchanged grouped_constraint.grouper %} -
    - {% endifchanged %} - {% endif %} + {{ grouped_constraint.grouper.name }}: {% for constraint in grouped_constraint.list %} {% with constraint.target.parent.id as constraint_target_parent_id %} {% with constraint.source.parent.id as constraint_source_parent_id %} {% with constraint.person as constraint_person %} {% if constraint_target_parent_id == constraint_source_parent_id and not constraint_person %}{% endif %} - {% if constraint.name.slug == "bethere" %}{% person_link constraint_person %} - {% else %} + {% if constraint.name.slug == "bethere" %}{% person_link constraint_person with_email=False %}{% else %} {% with constraint.name.slug as constraint_name_slug %} {% endwith %} @@ -94,11 +202,12 @@

    {% endwith %} {% endwith %} {% endfor %} +

    {% endfor %} {% endif %} - {% if session.comments %}{{ session.comments|linebreaksbr }}{% endif %} + {% if session.comments %}{{ session.comments|urlize_ietf_docs|linkify|linebreaksbr }}{% endif %} {% if forloop.last %}{% endif %} @@ -108,4 +217,4 @@

    {% endblock %} {% block js %} -{% endblock %} +{% endblock %} \ No newline at end of file diff --git a/ietf/templates/meeting/schedule_list.html b/ietf/templates/meeting/schedule_list.html index 2a1a829db22..1de121a6b1e 100644 --- a/ietf/templates/meeting/schedule_list.html +++ b/ietf/templates/meeting/schedule_list.html @@ -9,7 +9,7 @@

    Possible Meeting Agendas
    - IETF {{ meeting.number }} + IETF {{ meeting.number }}

    {% if can_edit_timeslots %} {{ label }}

    {{ schedule.notes|linebreaksbr }} {% if schedule.visible %} -
    Visible
    +
    Visible
    {% else %} -
    Hidden
    +
    Hidden
    {% endif %} {% if schedule.public %} -
    Public
    +
    Public
    {% else %} -
    Private
    +
    Private
    {% endif %} diff --git a/ietf/templates/meeting/session_agenda_include.html b/ietf/templates/meeting/session_agenda_include.html index 098b8c5a96d..190b7a8a06e 100644 --- a/ietf/templates/meeting/session_agenda_include.html +++ b/ietf/templates/meeting/session_agenda_include.html @@ -1,4 +1,4 @@ -{# Copyright The IETF Trust 2015, All Rights Reserved #} +{# Copyright The IETF Trust 2015-2022, All Rights Reserved #} {# expects slug, session, and timeslot to be in the context. Calling template must load the agenda_materials.js script. #} {% load origin %} {% origin %} @@ -19,7 +19,7 @@ {% if timeslot.type.slug == 'plenary' %} {{ timeslot.name }} {% else %} - {{ session.historic_group.name }} + {{ session.group_at_the_time.name }} {% endif %}

    + {# materials tar file #} +
    + + + {# materials PDF file #} + + + + {% endif %} + {# Notes #} + {% if meeting.uses_notes %} + + + + {% endif %} + {# show stream buttons up till end of session, then show archive buttons #} + {% if timezone_now < timeslot.end_time %} + {# chat #} + + + + {# Video stream (meetecho) #} + {% if session.video_stream_url %} + + + + {% endif %} + {# Onsite tool (meetecho_onsite) #} + {% if session.onsite_tool_url %} + + + + {% endif %} + {# Audio stream #} + {% if session.audio_stream_url %} + + + + {% endif %} + {# Remote call-in #} + {% if session.agenda_note|first_url|conference_url %} + + + + {% elif session.remote_instructions|first_url|conference_url %} + + + + {% elif timeslot.location.webex_url %} + + + + {% endif %} + {# iCalendar item #} + + + + {% else %} + {# chat logs #} + {% if meeting.has_chat_logs and session.chatlog %} + + + + {% endif %} + {# Recordings #} + {% if meeting.has_recordings %} + {% with session.recordings as recordings %} + {% if recordings %} + {# There's no guaranteed order, so this is a bit messy: #} + {# First, the audio recordings, if any #} + {% for r in recordings %} + {% if r.get_href and 'audio' in r.get_href %} + + + + {% endif %} + {% endfor %} + {# Then the youtube recordings #} + {% for r in recordings %} + {% if r.get_href and 'youtu' in r.get_href %} + + + + {% endif %} + {% endfor %} + {# Finally, any other recordings #} + {% for r in recordings %} + {% if r.get_href and not 'audio' in r.get_href and not 'youtu' in r.get_href %} + + + + {% endif %} + {% endfor %} + {% endif %} + {% endwith %} + {% if session.video_stream_url %} + + + + {% endif %} + {% endif %} + {% endif %} + {% endwith %} +
    + {% endwith %} -{% endif %} \ No newline at end of file +{% endif %} diff --git a/ietf/templates/meeting/session_cancel_notification.txt b/ietf/templates/meeting/session_cancel_notification.txt new file mode 100644 index 00000000000..3de67fc8f48 --- /dev/null +++ b/ietf/templates/meeting/session_cancel_notification.txt @@ -0,0 +1,4 @@ +{# Copyright The IETF Trust 2025, All Rights Reserved #} +{% autoescape off %}{% load ams_filters %} + +A request to cancel a meeting session has just been submitted by {{ requester }}.{% endautoescape %} diff --git a/ietf/templates/meeting/session_details.html b/ietf/templates/meeting/session_details.html index 2ecb7e1d5ca..a4d9ba10904 100644 --- a/ietf/templates/meeting/session_details.html +++ b/ietf/templates/meeting/session_details.html @@ -1,10 +1,10 @@ {% extends "base.html" %} -{# Copyright The IETF Trust 2015, All Rights Reserved #} +{# Copyright The IETF Trust 2015-2026, All Rights Reserved #} {% load origin ietf_filters static %} -{% block title %}{{ meeting }} : {{ acronym }}{% endblock %} +{% block title %}{{ meeting }} : {{ group.acronym }}{% endblock %} {% block morecss %} - .slides tr { - cursor:pointer; + .drag-handle { + cursor: move; } {% endblock %} {% block content %} @@ -12,13 +12,13 @@

    {{ meeting }}
    - {{ acronym }} + {{ group.acronym }}: {{ group.name }}

    - {% if meeting.date >= thisweek %} + {% if meeting.start_datetime >= thisweek %} + title="icalendar entry for {{ group.acronym }}@{{ meeting.number }}" + aria-label="icalendar entry for {{ group.acronym }}@{{ meeting.number }}" + href="{% url 'ietf.meeting.views.agenda_ical' num=meeting.number acronym=group.acronym %}"> {% endif %} @@ -31,81 +31,58 @@

    Scheduled Sessions

    {% include 'meeting/session_details_panel.html' with sessions=scheduled_sessions %}

    Unscheduled Sessions

    {% include 'meeting/session_details_panel.html' with sessions=unscheduled_sessions %} - {% if pending_suggestions %} -

    + {% for s in pending_suggestions %} + {% if forloop.first %}

    {% if can_manage_materials %} Proposed slides awaiting your approval {% else %} Your proposed slides awaiting chair approval {% endif %}

    -
    - {% for s in pending_suggestions %} - {% if can_manage_materials %} -

    - - {{ s.submitter }} - {{ s.title }} ({{ s.time }}) - -

    - {% else %} -

    - {{ s.title }} ({{ s.time }}) -

    - {% endif %} - {% endfor %} +
    {% endif %} + {% if can_manage_materials %} +

    + + {{ s.submitter }} - {{ s.title }} ({{ s.time }}) + +

    + {% else %} +

    + {{ s.title }} ({{ s.time }}) +

    + {% endif %} + {% if forloop.last %}
    {% endif %} + {% endfor %} + {% if user|has_role:"Secretariat" %} +
    +
    + Secretariat Only +
    +
    +
    + {% csrf_token %} + +
    +
    {% endif %} + {% comment %} + The existence of an element with id canManageMaterialsFlag is checked in + session_details.js to determine whether it should init the sortable tables. + Not the most elegant approach, but it works. + {% endcomment %} + {% if can_manage_materials %}
    {% endif %} {% endblock %} {% block js %} + + + + {% if can_manage_materials %} - {% endif %} + {% endblock %} \ No newline at end of file diff --git a/ietf/templates/meeting/session_details_form.html b/ietf/templates/meeting/session_details_form.html index 321305f497d..9cd1b6e85c9 100644 --- a/ietf/templates/meeting/session_details_form.html +++ b/ietf/templates/meeting/session_details_form.html @@ -1,34 +1,48 @@ -{# Copyright The IETF Trust 2007-2020, All Rights Reserved #} +{# Copyright The IETF Trust 2007-2025, All Rights Reserved #} +{% load django_bootstrap5 %} +
    {% if hidden %} {{ form.name.as_hidden }}{{ form.purpose.as_hidden }}{{ form.type.as_hidden }}{{ form.requested_duration.as_hidden }} + {{ form.has_onsite_tool.as_hidden }} {% else %} - - {% comment %} The form-group class is used by session_details_form.js to identify the correct element to hide the name / purpose / type fields when not needed. This is a bootstrap class - the secr app does not use it, so this (and the hidden class, also needed by session_details_form.js) are defined in edit.html and new.html as a kludge to make this work. {% endcomment %} - - - - - - - - - - - - - -
    {{ form.name.label_tag }}{{ form.name }}{{ form.purpose.errors }}
    {{ form.purpose.label_tag }} - {{ form.purpose }}
    {{ form.type }}
    - {{ form.purpose.errors }}{{ form.type.errors }} -
    {{ form.requested_duration.label_tag }}{{ form.requested_duration }}{{ form.requested_duration.errors }}
    + +
    + {% bootstrap_field form.name layout="horizontal" %} +
    + +
    +
    + +
    {{ form.purpose }}
    +
    {{ form.type }}
    + {{ form.purpose.errors }}{{ form.type.errors }} +
    +
    + + {% bootstrap_field form.requested_duration layout="horizontal" %} + {% if not hide_onsite_tool_prompt %} + {% bootstrap_field form.has_onsite_tool layout="horizontal" %} + {% endif %} + + {% if hide_onsite_tool_prompt %} + {{ form.has_onsite_tool.as_hidden }} + {% endif %} {% endif %} - {# hidden fields shown whether or not the whole form is hidden #} - {{ form.attendees.as_hidden }}{{ form.comments.as_hidden }}{{ form.id.as_hidden }}{{ form.on_agenda.as_hidden }}{{ form.DELETE.as_hidden }} -
    \ No newline at end of file + + {# hidden fields included whether or not the whole form is hidden #} + {{ form.attendees.as_hidden }} + {{ form.comments.as_hidden }} + {{ form.id.as_hidden }} + {{ form.on_agenda.as_hidden }} + {{ form.DELETE.as_hidden }} + {{ form.remote_instructions.as_hidden }} + {{ form.short.as_hidden }} + {{ form.agenda_note.as_hidden }} +
    diff --git a/ietf/templates/meeting/session_details_panel.html b/ietf/templates/meeting/session_details_panel.html index c3bd70fa6d1..7c52ac0b4ab 100644 --- a/ietf/templates/meeting/session_details_panel.html +++ b/ietf/templates/meeting/session_details_panel.html @@ -1,33 +1,33 @@ {% load origin ietf_filters textfilters tz dateformat %} {% origin %} {% for session in sessions %} - {% with item=session.official_timeslotassignment %} -

    - {% if sessions|length > 1 %}Session {{ forloop.counter }} :{% endif %} - {% for time in session.times %} - {% if not forloop.first %},{% endif %} - {{ time|dateformat:"l Y-m-d H:i T" }} - {% if time.tzinfo.zone != "UTC" %}({{ time|utc|dateformat:"H:i T" }}){% endif %} - {% endfor %} - {% if session.cancelled %} - Cancelled - {% else %} - {{ session.status }} + {% with item=session.official_timeslotassignment %} {% with timeslot=item.timeslot %} +
    + {% if not session.cancelled %} +
    + {# see note in the included templates re: show_agenda parameter and required JS import #} + {% if meeting.type.slug == 'interim' %} + {% include "meeting/interim_session_buttons.html" with show_agenda=False show_empty=False %} + {% else %} + {% include "meeting/session_buttons_include.html" with show_agenda=False item=session.official_timeslotassignment %} + {% endif %} +
    {% endif %} - {% if session.name %}: {{ session.name }}{% endif %} -

    - {% if not session.cancelled %} -
    - {# see note in the included templates re: show_agenda parameter and required JS import #} - {% if meeting.type.slug == 'interim' %} - {% include "meeting/interim_session_buttons.html" with show_agenda=False show_empty=False %} +

    + {% if sessions|length > 1 %}Session {{ forloop.counter }} :{% endif %} + {% for time in session.times %} + {% if not forloop.first %},{% endif %} + + {% include "meeting/tz-display.html" with meeting_timezone=session.meeting.time_zone id_suffix=session.pk minimal=True only %} + {% endfor %} + {% if session.cancelled %} + Cancelled {% else %} - {% with schedule=meeting.schedule %} - {% include "meeting/session_buttons_include.html" with show_agenda=False %} - {% endwith %} + {{ session.status }} {% endif %} -

    - {% endif %} + {% if session.name %}: {{ session.name }}{% endif %} +

    +
    {% if session.agenda_note %}

    {{ session.agenda_note }}

    {% endif %} {% if can_manage_materials %} {% if session.current_status == 'sched' or session.current_status == 'schedw' %} @@ -62,7 +62,7 @@

    {% endif %}

    Agenda, Minutes, and Bluesheets

    - {% if session.filtered_artifacts %} + {% if session.filtered_artifacts or session.bluesheet_title %} {% for pres in session.filtered_artifacts %} @@ -70,11 +70,11 @@

    Agenda, Minutes, and Bluesheets

    - {% endfor %} + {% if session.bluesheet_title %} + + {% endif %} {% endif %}
    {{ pres.document.title }} ({{ pres.document.name }}) - {% if user|has_role:"Secretariat" or can_manage_materials %} {% if pres.document.type.slug == 'minutes' %} {% url 'ietf.meeting.views.upload_session_minutes' session_id=session.pk num=session.meeting.number as upload_url %} + {% elif pres.document.type.slug == 'narrativeminutes' %} + {% url 'ietf.meeting.views.upload_session_narrativeminutes' session_id=session.pk num=session.meeting.number as upload_url %} {% elif pres.document.type.slug == 'agenda' %} {% url 'ietf.meeting.views.upload_session_agenda' session_id=session.pk num=session.meeting.number as upload_url %} {% else %} @@ -82,14 +82,22 @@

    Agenda, Minutes, and Bluesheets

    {% endif %} {% if pres.document.type.slug != 'bluesheets' or user|has_role:"Secretariat" or meeting.type.slug == 'interim' and can_manage_materials %} {% if pres.document.type.slug == 'minutes' %} - Import from notes.ietf.org + Import from notes.ietf.org {% endif %} - Upload revision + Upload revision {% endif %} + {% endif %}
    + + {{ session.bluesheet_title }} + +
    @@ -101,12 +109,18 @@

    Agenda, Minutes, and Bluesheets

    {% endif %} {% if not session.type_counter.minutes %} - Import minutes from notes.ietf.org + Import minutes from notes.ietf.org Upload minutes {% endif %} + {% if not session.type_counter.narrativeminutes and session.group.acronym == "iesg" %} + + Upload narrative minutes + + {% endif %} {% endif %} {% if user|has_role:"Secretariat" and not session.type_counter.bluesheets or meeting.type.slug == 'interim' and can_manage_materials and not session.type_counter.bluesheets %} Agenda, Minutes, and Bluesheets

    Upload bluesheets {% endif %} + {% if session.filtered_chatlog_and_polls %} +

    Chatlog and polls

    + + + {% for pres in session.filtered_chatlog_and_polls %} + + {% url 'ietf.doc.views_doc.document_main' name=pres.document.name as url %} + + + {% endfor %} + +
    + {{ pres.document.title }} + ( as json ) +
    + {% endif %}

    Slides

    @@ -123,24 +154,26 @@

    Slides

    data-remove-from-session="{% url 'ietf.meeting.views.ajax_remove_slides_from_session' session_id=session.pk num=session.meeting.number %}" data-reorder-in-session="{% url 'ietf.meeting.views.ajax_reorder_slides_in_session' session_id=session.pk num=session.meeting.number %}"> {% for pres in session.filtered_slides %} - + {% url 'ietf.doc.views_doc.document_main' name=pres.document.name as url %} - + {% if can_manage_materials %} + + {% endif %} - {% endfor %} @@ -154,13 +187,13 @@

    Slides

    {% elif request.user.is_authenticated and not session.is_material_submission_cutoff %} + href="{% url 'ietf.meeting.views.upload_session_slides' session_id=session.pk num=session.meeting.number %}"> Propose slides {% endif %} {% if can_manage_materials %}
    Drag-and-drop to reorder slides
    {% endif %} -

    Drafts

    +

    Internet-Drafts

    + + - {{ pres.document.title }} - ({{ pres.document.name }}) - {% if can_manage_materials %} - Upload revision - Remove {% endif %} + {{ pres.document.title }} + ({{ pres.document.name }})
    {% if session.filtered_drafts %} @@ -189,8 +222,159 @@

    Drafts

    {% if can_manage_materials %} - Link additional drafts to session + Link additional I-Ds to session + + {% endif %} + {% if timezone_now < timeslot.end_time %}{# show meeting tools until the session ends #} +

    Meeting tools

    +
    + + {% if meeting.uses_notes %} + + + + {% endif %} + {# chat #} + + + + {# Video stream (meetecho) #} + {% if session.video_stream_url and timezone_now < timeslot.end_time %} + + + + {% endif %} + {# Onsite tool (meetecho_onsite) #} + {% if session.onsite_tool_url %} + + + + {% endif %} + {# Audio stream #} + {% if session.audio_stream_url %} + + + + {% endif %} + {# Remote call-in #} + {% if session.agenda_note|first_url|conference_url %} + + + + {% elif session.remote_instructions|first_url|conference_url %} + + + + {% elif timeslot.location.webex_url %} + + + + {% endif %} + +
    + + Notepad for note-takers + +
    + + Chat room + +
    + + Video stream + +
    + + Onsite tool + +
    + + Audio stream + +
    + + Online conference + +
    + + Online conference + +
    + + Webex session + +
    + {% else %}{# session is in the past #} +

    Notes and recordings

    + + + {% if meeting.uses_notes %} + + + + {% endif %} + {# Recordings #} + {% with session.recordings as recordings %} + {% if recordings %} + {# There's no guaranteed order, so this is a bit messy: #} + {# First, the audio recordings, if any #} + {% for r in recordings %} + {% if r.get_href and 'audio' in r.get_href %} + + + + {% endif %} + {% endfor %} + {# Then the youtube recordings #} + {% for r in recordings %} + {% if r.get_href and 'youtu' in r.get_href %} + + + + {% endif %} + {% endfor %} + {# Finally, any other recordings #} + {% for r in recordings %} + {% if r.get_href and not 'audio' in r.get_href and not 'youtu' in r.get_href %} + + + + {% endif %} + {% endfor %} + {% endif %} + {% endwith %} + {% if session.session_recording_url %} + + + + {% endif %} + +
    + + Notepad for note-takers + +
    + {{ r.title }} +
    + {{ r.title }} +
    + {{ r.title }} +
    + + + Meetecho session recording + +
    + {% endif %} + + {% if can_manage_materials %} + + Link additional recordings to session {% endif %} -{% endwith %} + +{% endwith %}{% endwith %} {% endfor %} diff --git a/ietf/templates/meeting/session_materials.html b/ietf/templates/meeting/session_materials.html index 198bb1140b1..40d02fb63b7 100644 --- a/ietf/templates/meeting/session_materials.html +++ b/ietf/templates/meeting/session_materials.html @@ -18,10 +18,10 @@

    Agenda

    {% else %} - Agenda submitted as {{ agenda.file_extension|upper }} + Agenda submitted as {{ agenda.file_extension|upper }} {% endif %} {% else %} - No agenda submitted + No agenda submitted {% endif %} {% endwith %} {% if item.session.slides %} @@ -41,10 +41,10 @@

    Slides

    Minutes

    {% else %} - Minutes submitted as {{ minutes.file_extension|upper }} + Minutes submitted as {{ minutes.file_extension|upper }} {% endif %} {% else %} - No minutes submitted + No minutes submitted {% endif %} {% endwith %} diff --git a/ietf/templates/meeting/session_not_meeting_notification.txt b/ietf/templates/meeting/session_not_meeting_notification.txt new file mode 100644 index 00000000000..0e5c9407089 --- /dev/null +++ b/ietf/templates/meeting/session_not_meeting_notification.txt @@ -0,0 +1,8 @@ +{# Copyright The IETF Trust 2025, All Rights Reserved #} +{% load ams_filters %} + +{{ login|smart_login }} {{ group.acronym }} working group, indicated that the {{ group.acronym }} working group does not plan to hold a session at IETF {{ meeting.number }}. + +This message was generated and sent by the IETF Meeting Session Request Tool. + + diff --git a/ietf/templates/meeting/session_request_confirm.html b/ietf/templates/meeting/session_request_confirm.html new file mode 100644 index 00000000000..09043d3d0cb --- /dev/null +++ b/ietf/templates/meeting/session_request_confirm.html @@ -0,0 +1,38 @@ +{# Copyright The IETF Trust 2025, All Rights Reserved #} +{% extends "base.html" %} +{% load static ietf_filters django_bootstrap5 %} +{% block title %}Confirm Session Request{% endblock %} + +{% block content %} +

    Confirm Session Request - IETF {{ meeting.number }}

    + + + +
    + +
    + + {% include "meeting/session_request_view_table.html" %} + +
    + {% csrf_token %} + {{ form }} + {{ form.session_forms.management_form }} + {% for sf in form.session_forms %} + {% include 'meeting/session_details_form.html' with form=sf hidden=True only %} + {% endfor %} + + + + +
    + +
    + +{% endblock %} + +{% block js %} + +{% endblock %} \ No newline at end of file diff --git a/ietf/templates/meeting/session_request_form.html b/ietf/templates/meeting/session_request_form.html new file mode 100644 index 00000000000..ecf5cb7268c --- /dev/null +++ b/ietf/templates/meeting/session_request_form.html @@ -0,0 +1,206 @@ +{# Copyright The IETF Trust 2025, All Rights Reserved #} +{% extends "base.html" %} +{% load static ietf_filters django_bootstrap5 %} +{% block title %}{% if is_create %}New {% else %}Edit {% endif %}Session Request{% endblock %} +{% block morecss %}{{ block.super }} + .hidden {display: none !important;} + div.form-group {display: inline;} +{% endblock %} +{% block content %} +

    {% if is_create %}New {% else %}Edit {% endif %}Session Request

    + + {% if is_create %} + + {% endif %} + +
    + +
    + {% csrf_token %} + {{ form.session_forms.management_form }} + {% if form.non_field_errors %} +
    {{ form.non_field_errors }}
    + {% endif %} + +
    + +
    + +
    +
    + +
    + +
    + +
    +
    + + {% bootstrap_field form.num_session layout="horizontal" %} + + {% if group.features.acts_like_wg %} + +
    +
    Session 1
    +
    + {% include 'meeting/session_details_form.html' with form=form.session_forms.0 hide_onsite_tool_prompt=True only %} +
    +
    + +
    +
    Session 2
    +
    + {% include 'meeting/session_details_form.html' with form=form.session_forms.1 hide_onsite_tool_prompt=True only %} +
    +
    + + {% if not is_virtual %} + {% bootstrap_field form.session_time_relation layout="horizontal" %} + {% endif %} + +
    +
    Additional Session Request
    +
    +
    + {{ form.third_session }} + +
    Additional slot may be available after agenda scheduling has closed and with the approval of an Area Director.
    +
    + +
    +
    + +
    +
    Third session request
    +
    + {% include 'meeting/session_details_form.html' with form=form.session_forms.2 hide_onsite_tool_prompt=True only %} +
    +
    + + {% else %}{# else not group.features.acts_like_wg #} + {% for session_form in form.session_forms %} +
    +
    Session {{ forloop.counter }}
    +
    + {% include 'meeting/session_details_form.html' with form=session_form only %} +
    +
    + {% endfor %} + {% endif %} + + {% bootstrap_field form.attendees layout="horizontal" %} + + {% bootstrap_field form.bethere layout="horizontal" %} + +
    +
    Conflicts to avoid
    +
    +
    +
    Other WGs that included {{ group.acronym }} in their conflict lists
    +
    {{ session_conflicts.inbound|default:"None" }}
    +
    +
    +
    WG Sessions
    You may select multiple WGs within each category
    +
    + {% for cname, cfield, cselector in form.wg_constraint_fields %} +
    +
    +
    +
    +
    + {{ cselector }} +
    +
    + +
    +
    +
    +
    + {{ cfield.errors }}{{ cfield }} +
    +
    +
    +
    + {% empty %}{# shown if there are no constraint fields #} +
    +
    No constraints are enabled for this meeting.
    + {% endfor %} +
    +
    + + {% if form.inactive_wg_constraint_count %} +
    +
    Disabled for this meeting
    +
    + {% for cname, value, field in form.inactive_wg_constraints %} +
    +
    {{ cname|title }}
    +
    +
    +
    + +
    +
    + + +
    +
    +
    +
    + {% endfor %} +
    +
    + {% endif %} + +
    +
    BOF Sessions
    +
    If the sessions can not be found in the fields above, please enter free form requests in the Special Requests field below.
    +
    +
    +
    + + {% if not is_virtual %} + + {% bootstrap_field form.resources layout="horizontal" %} + + {% bootstrap_field form.timeranges layout="horizontal" %} + + {% bootstrap_field form.adjacent_with_wg layout="horizontal" %} + +
    +
    Joint session with: (To request one session for multiple WGs together)
    +
    To request a joint session with another group, please contact the secretariat.
    +
    + + {% endif %} + + {% bootstrap_field form.comments layout="horizontal" %} + + {% if form.notifications_optional %} +
    + +
    +
    + + +
    +
    +
    + {% endif %} + + + Cancel +
    + +{% endblock %} +{% block js %} + + {{ form.media }} +{% endblock %} \ No newline at end of file diff --git a/ietf/templates/meeting/session_request_info.txt b/ietf/templates/meeting/session_request_info.txt new file mode 100644 index 00000000000..2e96efb31f1 --- /dev/null +++ b/ietf/templates/meeting/session_request_info.txt @@ -0,0 +1,26 @@ +{# Copyright The IETF Trust 2025, All Rights Reserved #} +{% load ams_filters %} +--------------------------------------------------------- +Working Group Name: {{ group.name }} +Area Name: {{ group.parent }} +Session Requester: {{ login }} +{% if session.joint_with_groups %}{{ session.joint_for_session_display }} joint with: {{ session.joint_with_groups }}{% endif %} + +Number of Sessions: {{ session.num_session }} +Length of Session(s): {% for session_length in session_lengths %}{{ session_length.total_seconds|display_duration }}{% if not forloop.last %}, {% endif %}{% endfor %} +Number of Attendees: {{ session.attendees }} +Conflicts to Avoid: +{% for line in session.outbound_conflicts %} {{line}} +{% endfor %}{% if session.session_time_relation_display %} {{ session.session_time_relation_display }}{% endif %} +{% if session.adjacent_with_wg %} Adjacent with WG: {{ session.adjacent_with_wg }}{% endif %} +{% if session.timeranges_display %} Can't meet: {{ session.timeranges_display|join:", " }}{% endif %} + +Participants who must be present: +{% for person in session.bethere %} {{ person.ascii_name }} +{% endfor %} +Resources Requested: +{% for resource in session.resources %} {{ resource.desc }} +{% endfor %} +Special Requests: + {{ session.comments }} +--------------------------------------------------------- diff --git a/ietf/templates/meeting/session_request_list.html b/ietf/templates/meeting/session_request_list.html new file mode 100644 index 00000000000..789b7006e5d --- /dev/null +++ b/ietf/templates/meeting/session_request_list.html @@ -0,0 +1,65 @@ +{# Copyright The IETF Trust 2025, All Rights Reserved #} +{% extends "base.html" %} +{% load static %} +{% load ietf_filters %} +{% load django_bootstrap5 %} +{% block title %}Session Requests{% endblock %} +{% block content %} +

    Session Requests IETF {{ meeting.number }}

    + +
    + Instructions + + View list of timeslot requests + {% if user|has_role:"Secretariat" %} + {% if is_locked %} + Unlock Tool + {% else %} + Lock Tool + {% endif %} + {% endif %} +
    + +
    +
    + Request New Session +
    +
    +

    The list below includes those working groups that you currently chair which do not already have a session scheduled. You can click on an acronym to complete a request for a new session at the upcoming IETF meeting. Click "Group will not meet" to send a notification that the group does not plan to meet.

    +
      + {% for group in unscheduled_groups %} +
    • + {{ group.acronym }} + {% if group.not_meeting %} + (Currently, this group does not plan to hold a session at IETF {{ meeting.number }}) + {% endif %} +
    • + {% empty %} +
    • NONE
    • + {% endfor %} +
    +
    +
    + + +
    +
    + Edit / Cancel Previously Requested Sessions +
    +
    +

    The list below includes those working groups for which you or your co-chair has requested sessions at the upcoming IETF meeting. You can click on an acronym to initiate changes to a session, or cancel a session.

    + +
    +
    + +{% endblock %} + +{% block footer-extras %} + {% include "includes/sessions_footer.html" %} +{% endblock %} \ No newline at end of file diff --git a/ietf/templates/meeting/session_request_locked.html b/ietf/templates/meeting/session_request_locked.html new file mode 100644 index 00000000000..15c023ce332 --- /dev/null +++ b/ietf/templates/meeting/session_request_locked.html @@ -0,0 +1,21 @@ +{# Copyright The IETF Trust 2025, All Rights Reserved #} +{% extends "base.html" %} +{% load static ietf_filters django_bootstrap5 %} +{% block title %}Session Request{% endblock %} + +{% block content %} +

    Session Request - IETF {{ meeting.number }}

    + + View list of timeslot requests + +
    + +
    +

    {{ message }}

    + +
    + +
    +
    + +{% endblock %} diff --git a/ietf/templates/meeting/session_request_notification.txt b/ietf/templates/meeting/session_request_notification.txt new file mode 100644 index 00000000000..49dbbfc42ca --- /dev/null +++ b/ietf/templates/meeting/session_request_notification.txt @@ -0,0 +1,6 @@ +{# Copyright The IETF Trust 2025, All Rights Reserved #} +{% autoescape off %}{% load ams_filters %} + +{% filter wordwrap:78 %}{{ header }} meeting session request has just been submitted by {{ requester }}.{% endfilter %} + +{% include "meeting/session_request_info.txt" %}{% endautoescape %} diff --git a/ietf/templates/meeting/session_request_status.html b/ietf/templates/meeting/session_request_status.html new file mode 100644 index 00000000000..65e98d6d238 --- /dev/null +++ b/ietf/templates/meeting/session_request_status.html @@ -0,0 +1,28 @@ +{# Copyright The IETF Trust 2025, All Rights Reserved #} +{% extends "base.html" %} +{% load static %} +{% load ietf_filters %} +{% load django_bootstrap5 %} +{% block title %}Session Request Status{% endblock %} +{% block content %} +

    Session Request Status

    + +
    +
    + Session Request Status +
    +
    +

    Enter the message that you would like displayed to the WG Chair when this tool is locked.

    +
    {% csrf_token %} + {% bootstrap_form form %} + {% if is_locked %} + + {% else %} + + {% endif %} + +
    +
    +
    + +{% endblock %} diff --git a/ietf/templates/meeting/session_request_view.html b/ietf/templates/meeting/session_request_view.html new file mode 100644 index 00000000000..3db16f56cbf --- /dev/null +++ b/ietf/templates/meeting/session_request_view.html @@ -0,0 +1,59 @@ +{# Copyright The IETF Trust 2025, All Rights Reserved #} +{% extends "base.html" %} +{% load static ietf_filters django_bootstrap5 %} +{% block title %}Session Request{% endblock %} + +{% block content %} +

    Session Request - IETF {{ meeting.number }}

    + + + +
    + +
    + + {% include "meeting/session_request_view_table.html" %} + +
    + +

    Activities Log

    +
    + + + + + + + + + + + {% for entry in activities %} + + + + + + + {% endfor %} + +
    DateTimeActionName
    {{ entry.act_date }}{{ entry.act_time }}{{ entry.activity }}{{ entry.act_by }}
    +
    + + + + {% if show_approve_button %} + Approve Third Session + {% endif %} + + Back + +
    + +{% endblock %} + +{% block js %} + +{% endblock %} \ No newline at end of file diff --git a/ietf/templates/meeting/session_request_view_formset.html b/ietf/templates/meeting/session_request_view_formset.html new file mode 100644 index 00000000000..72811b8c2c4 --- /dev/null +++ b/ietf/templates/meeting/session_request_view_formset.html @@ -0,0 +1,49 @@ +{# Copyright The IETF Trust 2025, All Rights Reserved #} +{% load ams_filters %}{# keep this in sync with sessions_request_view_session_set.html #} +{% for sess_form in formset %} + {% if sess_form.cleaned_data and not sess_form.cleaned_data.DELETE %} +
    +
    + Session {{ forloop.counter }} +
    +
    +
    +
    Length
    +
    {{ sess_form.cleaned_data.requested_duration.total_seconds|display_duration }}
    +
    + {% if sess_form.cleaned_data.name %} +
    +
    Name
    +
    {{ sess_form.cleaned_data.name }}
    +
    + {% endif %} + {% if sess_form.cleaned_data.purpose.slug != 'regular' %} +
    +
    Purpose
    +
    + {{ sess_form.cleaned_data.purpose }} + {% if sess_form.cleaned_data.purpose.timeslot_types|length > 1 %}({{ sess_form.cleaned_data.type }} + ){% endif %} +
    +
    +
    +
    Onsite tool?
    +
    {{ sess_form.cleaned_data.has_onsite_tool|yesno }}
    +
    + {% endif %} +
    +
    + + {% if group.features.acts_like_wg and forloop.counter == 2 and not is_virtual %} +
    +
    + Time between sessions +
    +
    + {% if session.session_time_relation_display %}{{ session.session_time_relation_display }}{% else %}No + preference{% endif %} +
    +
    + {% endif %} + {% endif %} +{% endfor %} \ No newline at end of file diff --git a/ietf/templates/meeting/session_request_view_session_set.html b/ietf/templates/meeting/session_request_view_session_set.html new file mode 100644 index 00000000000..0b8412b04f3 --- /dev/null +++ b/ietf/templates/meeting/session_request_view_session_set.html @@ -0,0 +1,47 @@ +{# Copyright The IETF Trust 2025, All Rights Reserved #} +{% load ams_filters %}{# keep this in sync with sessions_request_view_formset.html #} +{% for sess in session_set %} +
    +
    + Session {{ forloop.counter }} +
    +
    +
    +
    Length
    +
    {{ sess.requested_duration.total_seconds|display_duration }}
    +
    + {% if sess.name %} +
    +
    Name
    +
    {{ sess.name }}
    +
    + {% endif %} + {% if sess.purpose.slug != 'regular' %} +
    +
    Purpose
    +
    + {{ sess.purpose }} + {% if sess.purpose.timeslot_types|length > 1 %}({{ sess.type }}){% endif %} +
    +
    +
    +
    Onsite tool?
    +
    {{ sess.has_onsite_tool|yesno }}
    +
    + {% endif %} +
    +
    + +{% if group.features.acts_like_wg and forloop.counter == 2 and not is_virtual %} +
    +
    + Time between sessions +
    +
    + {% if session.session_time_relation_display %}{{ session.session_time_relation_display }}{% else %}No + preference{% endif %} +
    +
    +{% endif %} + +{% endfor %} \ No newline at end of file diff --git a/ietf/templates/meeting/session_request_view_table.html b/ietf/templates/meeting/session_request_view_table.html new file mode 100644 index 00000000000..a5cb85c2520 --- /dev/null +++ b/ietf/templates/meeting/session_request_view_table.html @@ -0,0 +1,146 @@ +{# Copyright The IETF Trust 2025, All Rights Reserved #} +{% load ams_filters %} + +
    +
    + Working Group Name +
    +
    + {{ group.name }} ({{ group.acronym }}) +
    +
    + +
    +
    + Area Name +
    +
    + {{ group.parent }} +
    +
    + +
    +
    + Number of Sessions Requested +
    +
    + {% if session.third_session %}3{% else %}{{ session.num_session }}{% endif %} +
    +
    + +{% if form %} + {% include 'meeting/session_request_view_formset.html' with formset=form.session_forms group=group session=session only %} +{% else %} + {% include 'meeting/session_request_view_session_set.html' with session_set=sessions group=group session=session only %} +{% endif %} + + +
    +
    + Number of Attendees +
    +
    + {{ session.attendees }} +
    +
    + +
    +
    + Conflicts to Avoid +
    +
    + {% if session_conflicts.outbound %} + {% for conflict in session_conflicts.outbound %} +
    +
    + {{ conflict.name|title }} +
    +
    + {{ conflict.groups }} +
    +
    + {% endfor %} + {% else %}None{% endif %} +
    +
    + +
    +
    + Other WGs that included {{ group }} in their conflict list +
    +
    + {% if session_conflicts.inbound %}{{ session_conflicts.inbound }}{% else %}None so far{% endif %} +
    +
    + +{% if not is_virtual %} +
    +
    + Resources requested +
    +
    + {% if session.resources %}
      {% for resource in session.resources %}
    • {{ resource.desc }}
    • {% endfor %}
    {% else %}None so far{% endif %} +
    +
    +{% endif %} + +
    +
    + Participants who must be present +
    +
    + {% if session.bethere %}
      {% for person in session.bethere %}
    • {{ person }}
    • {% endfor %}
    {% else %}None{% endif %} +
    +
    + +
    +
    + Can not meet on +
    +
    + {% if session.timeranges_display %}{{ session.timeranges_display|join:', ' }}{% else %}No constraints{% endif %} +
    +
    + +{% if not is_virtual %} +
    +
    + Adjacent with WG +
    +
    + {{ session.adjacent_with_wg|default:'No preference' }} +
    +
    +
    +
    + Joint session +
    +
    + {% if session.joint_with_groups %} + {{ session.joint_for_session_display }} with: {{ session.joint_with_groups }} + {% else %} + Not a joint session + {% endif %} +
    +
    +{% endif %} + +
    +
    + Special Requests +
    +
    + {{ session.comments }} +
    +
    + +{% if form and form.notifications_optional %} +
    +
    + {{ form.send_notifications.label}} +
    +
    + {% if form.cleaned_data.send_notifications %}Yes{% else %}No{% endif %} +
    +
    +{% endif %} diff --git a/ietf/templates/meeting/slides_approved.txt b/ietf/templates/meeting/slides_approved.txt new file mode 100644 index 00000000000..61ffafcd18e --- /dev/null +++ b/ietf/templates/meeting/slides_approved.txt @@ -0,0 +1,5 @@ +{% load ietf_filters %}{% autoescape off %}Your proposed slides have been approved for {{ submission.session.meeting }} : {{ submission.session.group.acronym }}{% if submission.session.name %} : {{submission.session.name}}{% endif %} by {{approver}} + +Title: {{submission.title}} + +{% endautoescape %} \ No newline at end of file diff --git a/ietf/templates/meeting/timeslot_edit.html b/ietf/templates/meeting/timeslot_edit.html index 5c31c819503..3259dba9daf 100644 --- a/ietf/templates/meeting/timeslot_edit.html +++ b/ietf/templates/meeting/timeslot_edit.html @@ -11,31 +11,33 @@ {% endcomment %} .timeslot-edit { overflow: auto; height: max(30rem, calc(100vh - 25rem));} .tstable { width: 100%; border-collapse: separate; } {# "separate" to ensure sticky cells keep their borders #} -.tstable thead { position: sticky; top: 0; z-index: 3; background-color: white;} -.tstable th:first-child, .tstable td:first-child { - background-color: white; {# needs to match the lighter of the striped-table colors! #} -position: sticky; -left: 0; - z-index: 2; {# render above other cells / borders but below thead (z-index 3, above) #} -} -.tstable tbody > tr:nth-of-type(odd) > th:first-child { - background-color: rgb(249, 249, 249); {# needs to match the darker of the striped-table colors! #} -} -.tstable th { white-space: nowrap;} -.tstable td { white-space: nowrap;} -.capacity { font-size:80%; font-weight: normal;} -a.new-timeslot-link { color: lightgray; font-size: large;} + .tstable tr th:first-child { min-width: 25rem; max-width: 25rem; overflow: hidden; } + .tstable thead { position: sticky; top: 0; z-index: 3; background-color: white;} + .tstable thead th span.day { position: sticky; left: 25.5rem; } + .tstable th:first-child, .tstable td:first-child { + background-color: white; {# needs to match the lighter of the striped-table colors! #} + position: sticky; + left: 0; + z-index: 2; {# render above other cells / borders but below thead (z-index 3, above) #} + } + .tstable tbody > tr:nth-of-type(odd) > th:first-child { + background-color: rgb(249, 249, 249); {# needs to match the darker of the striped-table colors! #} + } + .tstable th { white-space: nowrap;} + .tstable td { white-space: nowrap;} + .capacity { font-size:80%; font-weight: normal;} + a.new-timeslot-link { color: lightgray; font-size: large;} {% endblock %} {% block content %} {% origin %}

    IETF {{ meeting.number }} Meeting Agenda
    - Timeslots and Room Availability + Timeslots and Room Availability

    + href="{% url "ietf.meeting.views.create_timeslot" num=meeting.number %}{% if "sched" in request.GET %}?sched={{ request.GET.sched }}{% endif %}"> New timeslot {% if meeting.schedule %} @@ -51,6 +53,9 @@

    href="{% url "ietf.meeting.views.list_schedules" num=meeting.number %}"> Agenda list + {% if schedule_edit_url %} + Back to agenda + {% endif %}

    {% if rooms|length == 0 %} @@ -81,12 +86,14 @@

    {% for day in time_slices %} - {{ day|date:'D' }} ({{ day }}) - - + + {{ day|date:'D' }} ({{ day }}) + + + {% endfor %} {% endif %} @@ -118,6 +125,7 @@

    {{ room.name }} + {% if room.functional_name and room.name != room.functional_name %} - {{ room.functional_name }}{% endif %} {% if room.capacity %}({{ room.capacity }}){% endif %} @@ -126,7 +134,9 @@

    No timeslots exist for this meeting yet.

    - Create a timeslot. + + Create a timeslot. + {% else %} {% for day in time_slices %} @@ -137,11 +147,11 @@

    {% if cell_ts %} {% for ts in cell_ts %} - {% include 'meeting/timeslot_edit_timeslot.html' with ts=ts in_use=ts_with_any_assignments in_official_use=ts_with_official_assignments only %} + {% include 'meeting/timeslot_edit_timeslot.html' with ts=ts in_use=ts_with_any_assignments in_official_use=ts_with_official_assignments request=request only %} {% endfor %} {% endif %} + href="{% url 'ietf.meeting.views.create_timeslot' num=meeting.number %}?day={{ day.toordinal }}&date={{ day|date:'Y-m-d' }}&location={{ room.pk }}&time={{ slot.time|date:'H:i' }}&duration={{ slot.duration }}{% if "sched" in request.GET %}&sched={{ request.GET.sched }}{% endif %}"> diff --git a/ietf/templates/meeting/timeslot_edit_timeslot.html b/ietf/templates/meeting/timeslot_edit_timeslot.html index 88e1e5a196f..e3c51fb75aa 100644 --- a/ietf/templates/meeting/timeslot_edit_timeslot.html +++ b/ietf/templates/meeting/timeslot_edit_timeslot.html @@ -1,8 +1,8 @@
    - + diff --git a/ietf/templates/meeting/timeslot_start_end.html b/ietf/templates/meeting/timeslot_start_end.html deleted file mode 100644 index 4ee4a9d3c7d..00000000000 --- a/ietf/templates/meeting/timeslot_start_end.html +++ /dev/null @@ -1,11 +0,0 @@ -
    -
    - {% if "-utc" in request.path %} - {{ item.timeslot.utc_start_time|date:"H:i" }}
    -{{ item.timeslot.utc_end_time|date:"H:i" }} - {% else %} - {{ item.timeslot.time|date:"H:i" }}
    -{{ item.timeslot.end_time|date:"H:i" }} - {% endif %} -
    -
    \ No newline at end of file diff --git a/ietf/templates/meeting/tz-display.html b/ietf/templates/meeting/tz-display.html index 16bc35ef389..2d11c6633ce 100644 --- a/ietf/templates/meeting/tz-display.html +++ b/ietf/templates/meeting/tz-display.html @@ -12,8 +12,8 @@ {% load origin %} {% origin %} {% firstof id_suffix "" as suffix %} -
    - {% if not minimal %}{% endif %} + + {% if not minimal %}{% endif %} {% if meeting_timezone is not None %} {% endif %} -
    \ No newline at end of file + \ No newline at end of file diff --git a/ietf/templates/meeting/upcoming.html b/ietf/templates/meeting/upcoming.html index 43f998c9a60..13a27ed9102 100644 --- a/ietf/templates/meeting/upcoming.html +++ b/ietf/templates/meeting/upcoming.html @@ -2,10 +2,9 @@ {# Copyright The IETF Trust 2015, 2020, All Rights Reserved #} {% load origin %} {% load cache %} -{% load ietf_filters static classname %} +{% load ietf_filters static classname tz %} {% block pagehead %} - {% endblock %} {% block title %}Upcoming Meetings{% endblock %} {% block content %} @@ -46,19 +45,24 @@

    Upcoming Meetings

    {% for entry in entries %} + {% if entry|classname == 'Session' %} + data-filter-keywords="{{ entry.filter_keywords|join:',' }}" + {% elif entry|classname == 'Meeting' %} + data-filter-keywords="ietf-meetings" + {% endif %} + > {% if entry|classname == 'Meeting' %} {% with meeting=entry %} - {{ meeting.date }} to {{ meeting.end }} + {{ meeting.date }} to {{ meeting.end_date }} ietf + href="{% url 'agenda' num=meeting.number %}"> IETF {{ meeting.number }} @@ -67,9 +71,9 @@

    Upcoming Meetings

    {% elif entry|classname == 'Session' %} {% with session=entry group=entry.group meeting=entry.meeting %} - {{ session.official_timeslotassignment.timeslot.utc_start_time | date:"Y-m-d H:i" }}-{{ session.official_timeslotassignment.timeslot.utc_end_time | date:"H:i" }} + data-start-utc="{{ session.official_timeslotassignment.timeslot.time | utc | date:'Y-m-d H:i' }}Z" + data-end-utc="{{ session.official_timeslotassignment.timeslot.end_time | utc | date:'Y-m-d H:i' }}Z"> + {{ session.official_timeslotassignment.timeslot.time | utc | date:"Y-m-d H:i" }}-{{ session.official_timeslotassignment.timeslot.end_time | utc | date:"H:i" }} {{ group.acronym }} @@ -82,7 +86,7 @@

    Upcoming Meetings

    {% if session.current_status == 'canceled' %} - Cancelled + Cancelled {% else %} {% include "meeting/interim_session_buttons.html" with show_agenda=True %} @@ -90,7 +94,7 @@

    Upcoming Meetings

    {% endwith %} {% else %} - Unexpected entry type: {{ entry|classname }} + Unexpected entry type: {{ entry|classname }} @@ -122,18 +126,20 @@

    No upcoming meetings

    {% with meeting=entry %} { ietf_meeting_number: '{{ meeting.number }}', + filter_keywords: ['ietf-meetings'], start_moment: moment.tz('{{meeting.date}}', '{{ meeting.time_zone }}').startOf('day'), - end_moment: moment.tz('{{meeting.end}}', '{{ meeting.time_zone }}').endOf('day'), - url: '{% url 'ietf.meeting.views.agenda' num=meeting.number %}' + end_moment: moment.tz('{{meeting.end_date}}', '{{ meeting.time_zone }}').endOf('day'), + url: '{% url 'agenda' num=meeting.number %}' }{% if not forloop.last %}, {% endif %} {% endwith %} {% else %} {# if it's not a Meeting, it's a Session #} {% with session=entry %} { group: '{% if session.group %}{{session.group.acronym}}{% endif %}{% if session.name %} - {{session.name}}{% endif %}', + current_status: '{{ session.current_status }}', filter_keywords: ["{{ session.filter_keywords|join:'","' }}"], - start_moment: moment.utc('{{session.official_timeslotassignment.timeslot.utc_start_time | date:"Y-m-d H:i"}}'), - end_moment: moment.utc('{{session.official_timeslotassignment.timeslot.utc_end_time | date:"Y-m-d H:i"}}'), + start_moment: moment.utc('{{session.official_timeslotassignment.timeslot.time | utc | date:"Y-m-d H:i"}}'), + end_moment: moment.utc('{{session.official_timeslotassignment.timeslot.end_time | utc | date:"Y-m-d H:i"}}'), url: '{% url 'ietf.meeting.views.session_details' num=session.meeting.number acronym=session.group.acronym %}' } {% endwith %} @@ -151,4 +157,4 @@

    No upcoming meetings

    agenda_filter.enable(); }); -{% endblock %} +{% endblock %} \ No newline at end of file diff --git a/ietf/templates/meeting/upcoming.ics b/ietf/templates/meeting/upcoming.ics deleted file mode 100644 index 088b94bf5bb..00000000000 --- a/ietf/templates/meeting/upcoming.ics +++ /dev/null @@ -1,31 +0,0 @@ -{% load humanize %}{% autoescape off %}{% load ietf_filters %}BEGIN:VCALENDAR -VERSION:2.0 -METHOD:PUBLISH -PRODID:-//IETF//datatracker.ietf.org ical upcoming//EN -{{vtimezones}}{% for item in assignments %}BEGIN:VEVENT -UID:ietf-{{item.session.meeting.number}}-{{item.timeslot.pk}} -SUMMARY:{% if item.session.name %}{{item.session.group.acronym|lower}} - {{item.session.name|ics_esc}}{% else %}{{item.session.group.acronym|lower}} - {{item.session.group.name}}{%endif%} -{% if item.schedule.meeting.city %}LOCATION:{{item.schedule.meeting.city}},{{item.schedule.meeting.country}} -{% endif %}STATUS:{{item.session.ical_status}} -CLASS:PUBLIC -DTSTART{% if item.schedule.meeting.time_zone %};TZID={{ item.schedule.meeting.time_zone|ics_esc }}{%endif%}:{{ item.timeslot.time|date:"Ymd" }}T{{item.timeslot.time|date:"Hi"}}00 -DTEND{% if item.schedule.meeting.time_zone %};TZID={{ item.schedule.meeting.time_zone|ics_esc }}{%endif%}:{{ item.timeslot.end_time|date:"Ymd" }}T{{item.timeslot.end_time|date:"Hi"}}00 -DTSTAMP:{{ item.timeslot.modified|date:"Ymd" }}T{{ item.timeslot.modified|date:"His" }}Z -{% if item.session.agenda %}URL:{{item.session.agenda.get_href}} -DESCRIPTION:{{item.timeslot.name|ics_esc}}\n{% if item.session.agenda_note %} - Note: {{item.session.agenda_note|ics_esc}}\n{% endif %}{% for material in item.session.materials.all %} - \n{{material.type}}{% if material.type.name != "Agenda" %} - ({{material.title|ics_esc}}){% endif %}: - {{material.get_href}}\n{% endfor %} -{% endif %}END:VEVENT -{% endfor %}{% for meeting in ietfs %}BEGIN:VEVENT -UID:ietf-{{ meeting.number }} -SUMMARY:IETF {{ meeting.number }}{% if meeting.city %} -LOCATION:{{ meeting.city }},{{ meeting.country }}{% endif %} -CLASS:PUBLIC -DTSTART;VALUE=DATE{% if meeting.time_zone %};TZID={{ meeting.time_zone|ics_esc }}{% endif %}:{{ meeting.date|date:"Ymd" }} -DTEND;VALUE=DATE{% if meeting.time_zone %};TZID={{ meeting.time_zone|ics_esc }}{% endif %}:{{ meeting.end_date|date:"Ymd" }} -DTSTAMP:{{ meeting.cached_updated|date:"Ymd" }}T{{ meeting.cached_updated|date:"His" }}Z -URL:{{ request.scheme }}://{{ request.get_host }}{% url 'ietf.meeting.views.agenda' num=meeting.number %} -END:VEVENT -{% endfor %}END:VCALENDAR{% endautoescape %} diff --git a/ietf/templates/meeting/upload_session_agenda.html b/ietf/templates/meeting/upload_session_agenda.html index 4bd0b8971fe..57cba6b53c6 100644 --- a/ietf/templates/meeting/upload_session_agenda.html +++ b/ietf/templates/meeting/upload_session_agenda.html @@ -1,6 +1,6 @@ {% extends "base.html" %} -{# Copyright The IETF Trust 2015, All Rights Reserved #} -{% load origin static django_bootstrap5 %} +{# Copyright The IETF Trust 2015-2023, All Rights Reserved #} +{% load origin static django_bootstrap5 tz %} {% block title %} {% if agenda_sp %} Revise @@ -19,16 +19,19 @@

    {% endif %} Agenda for {{ session.meeting }}
    - {{ session.group.acronym }} + {{ session.group.acronym }} {% if session.name %}: {{ session.name }}{% endif %}

    {% if session_number %} -

    Session {{ session_number }} : {{ session.official_timeslotassignment.timeslot.time|date:"D M-d-Y Hi" }}

    +

    Session {{ session_number }} : {{ session.official_timeslotassignment.timeslot.time|timezone:session.meeting.time_zone|date:"D M-d-Y Hi" }}

    {% endif %}
    {% csrf_token %} {% bootstrap_form form %} - +
    +{% endblock %} +{% block js %} + {% endblock %} \ No newline at end of file diff --git a/ietf/templates/meeting/upload_session_bluesheets.html b/ietf/templates/meeting/upload_session_bluesheets.html index 4a2f484be9a..19af4847ad0 100644 --- a/ietf/templates/meeting/upload_session_bluesheets.html +++ b/ietf/templates/meeting/upload_session_bluesheets.html @@ -1,6 +1,6 @@ {% extends "base.html" %} {# Copyright The IETF Trust 2015, All Rights Reserved #} -{% load origin static django_bootstrap5 %} +{% load origin static django_bootstrap5 tz %} {% block title %} {% if bluesheet_sp %} Revise @@ -19,12 +19,12 @@

    {% endif %} Bluesheets for {{ session.meeting }}
    - {{ session.group.acronym }} + {{ session.group.acronym }} {% if session.name %}: {{ session.name }}{% endif %}

    {% if session_number %} -

    Session {{ session_number }} : {{ session.official_timeslotassignment.timeslot.time|date:"D M-d-Y Hi" }}

    +

    Session {{ session_number }} : {{ session.official_timeslotassignment.timeslot.time|timezone:session.meeting.time_zone|date:"D M-d-Y Hi" }}

    {% endif %}
    {% csrf_token %} diff --git a/ietf/templates/meeting/upload_session_minutes.html b/ietf/templates/meeting/upload_session_minutes.html index 2e3f875249d..324440681f9 100644 --- a/ietf/templates/meeting/upload_session_minutes.html +++ b/ietf/templates/meeting/upload_session_minutes.html @@ -1,6 +1,6 @@ {% extends "base.html" %} {# Copyright The IETF Trust 2015, All Rights Reserved #} -{% load origin static django_bootstrap5 %} +{% load origin static django_bootstrap5 tz %} {% block title %} {% if minutes_sp %} Revise @@ -19,12 +19,17 @@

    {% endif %} Minutes for {{ session.meeting }}
    - {{ session.group.acronym }} + {{ session.group.acronym }} {% if session.name %}: {{ session.name }}{% endif %}

    {% if session_number %} -

    Session {{ session_number }} : {{ session.official_timeslotassignment.timeslot.time|date:"D M-d-Y Hi" }}

    +

    Session {{ session_number }} : {{ session.official_timeslotassignment.timeslot.time|timezone:session.meeting.time_zone|date:"D M-d-Y Hi" }}

    + {% endif %} + {% if future %} +

    + Caution: Session has not ended yet +

    {% endif %} {% csrf_token %} diff --git a/ietf/templates/meeting/upload_session_narrativeminutes.html b/ietf/templates/meeting/upload_session_narrativeminutes.html new file mode 100644 index 00000000000..d990985510e --- /dev/null +++ b/ietf/templates/meeting/upload_session_narrativeminutes.html @@ -0,0 +1,34 @@ +{% extends "base.html" %} +{# Copyright The IETF Trust 2024, All Rights Reserved #} +{% load origin static django_bootstrap5 tz %} +{% block title %} + {% if narrativeminutes_sp %} + Revise + {% else %} + Upload + {% endif %} + Narrative Minutes for {{ session.meeting }} : {{ session.group.acronym }} +{% endblock %} +{% block content %} + {% origin %} +

    + {% if narrativeminutes_sp %} + Revise + {% else %} + Upload + {% endif %} + Narrative Minutes for {{ session.meeting }} +
    + {{ session.group.acronym }} + {% if session.name %}: {{ session.name }}{% endif %} + +

    + {% if session_number %} +

    Session {{ session_number }} : {{ session.official_timeslotassignment.timeslot.time|timezone:session.meeting.time_zone|date:"D M-d-Y Hi" }}

    + {% endif %} + + {% csrf_token %} + {% bootstrap_form form %} + + +{% endblock %} \ No newline at end of file diff --git a/ietf/templates/meeting/upload_session_slides.html b/ietf/templates/meeting/upload_session_slides.html index f5cd35d9679..059ffae16f9 100644 --- a/ietf/templates/meeting/upload_session_slides.html +++ b/ietf/templates/meeting/upload_session_slides.html @@ -1,6 +1,6 @@ {% extends "base.html" %} {# Copyright The IETF Trust 2015, All Rights Reserved #} -{% load origin static django_bootstrap5 %} +{% load origin static django_bootstrap5 tz %} {% block title %} {% if slides_sp %} Revise @@ -17,15 +17,21 @@

    {% else %} Upload new {% endif %} - slides for {{ session.meeting }} -
    - + slides for {{ session.meeting }}
    + {{ session.group.acronym }} {% if session.name %}: {{ session.name }}{% endif %}

    {% if session_number %} -

    Session {{ session_number }} : {{ session.official_timeslotassignment.timeslot.time|date:"D M-d-Y Hi" }}

    +

    + Session {{ session_number }} : {{ session.official_timeslotassignment.timeslot.time|timezone:session.meeting.time_zone|date:"D M-d-Y Hi" }} +

    + {% endif %} + {% if not manage %} +

    + This form will allow you to propose a slide deck to the session chairs. After you upload your proposal, mail will be sent to the session chairs asking for their approval. +

    {% endif %} {% if slides_sp %}

    {{ slides_sp.document.name }}

    {% endif %}
    diff --git a/ietf/templates/meeting/week-view.html b/ietf/templates/meeting/week-view.html deleted file mode 100644 index 70496457a9c..00000000000 --- a/ietf/templates/meeting/week-view.html +++ /dev/null @@ -1,40 +0,0 @@ -{# Copyright The IETF Trust 2015, All Rights Reserved #} -{% load origin %} -{% load static %} -{# FIXME: the weekview only renders correctly in quirks mode, i.e., not in HTML5 with "" in the next line; it should be rewritten with fullcalendar #} -{# #} - - {% origin %} - - Weekview - - - - - - - - - -

    - Error loading calendar. -

    - - \ No newline at end of file diff --git a/ietf/templates/message/message.html b/ietf/templates/message/message.html index fba7ba43928..01d72e96384 100644 --- a/ietf/templates/message/message.html +++ b/ietf/templates/message/message.html @@ -8,7 +8,7 @@

    {{ message.subject }}
    - {{ message.time|date:"F j, Y" }} + {{ message.time|date:"F j, Y" }}

    diff --git a/ietf/templates/minimal.html b/ietf/templates/minimal.html new file mode 100644 index 00000000000..15c432505ef --- /dev/null +++ b/ietf/templates/minimal.html @@ -0,0 +1,21 @@ +{# Copyright The IETF Trust 2015-2023, All Rights Reserved #} + +{% load static %} +{% load origin %} +{% origin %} + + + + + {{ title }} + + + + + {# load this in the head, to prevent flickering #} + + + + {{ content }} + + \ No newline at end of file diff --git a/ietf/templates/nomcom/announcements.html b/ietf/templates/nomcom/announcements.html index aa67fbb68e0..771f2b4fb01 100644 --- a/ietf/templates/nomcom/announcements.html +++ b/ietf/templates/nomcom/announcements.html @@ -15,7 +15,7 @@

    NomCom

    {% for regime in regimes %}

    - Messages from {{ regime.group.start_year }}/{{ regime.group.end_year }} + Messages from {{ regime.group.start_year }} NomCom

    {# use person email address here rather than the generic nomcom-chair@ietf.org #}

    @@ -56,9 +56,14 @@

    References

  • - IAB, IESG, IETF Trust, and IETF LLC Selection, Confirmation, and Recall Process: Operation of the IETF Nominating and Recall Committees (RFC 8713) (Also BCP10) + IAB, IESG, IETF Trust, and IETF LLC Selection, Confirmation, and Recall Process: Operation of the IETF Nominating and Recall Committees (RFC 8713)
  • +
  • + + Nominating Committee Eligibility (RFC 9389) + +
  • Publicly Verifiable Nominations Committee (NomCom) Random Selection (RFC 3797) diff --git a/ietf/templates/nomcom/download_questionnaire.txt b/ietf/templates/nomcom/download_questionnaire.txt new file mode 100644 index 00000000000..71514095c8e --- /dev/null +++ b/ietf/templates/nomcom/download_questionnaire.txt @@ -0,0 +1,9 @@ +{# Copyright The IETF Trust 2023, All Rights Reserved #}{% autoescape off %}{% load nomcom_tags %}Questionnaire response from {{ nominee.person.name }} + +From: {{ feedback.author|formatted_email|default:"Anonymous" }} +Date: {{ feedback.time|date:"Y-m-d" }} +Positions: {{ positions }}{% if feedback.subject %} +Subject: {{ feedback.subject }}{% endif %} + +{% decrypt feedback.comments request year 1 %} +{% endautoescape %} \ No newline at end of file diff --git a/ietf/templates/nomcom/edit_nominee.html b/ietf/templates/nomcom/edit_nominee.html index aa9f6a80464..7f20e204bb0 100644 --- a/ietf/templates/nomcom/edit_nominee.html +++ b/ietf/templates/nomcom/edit_nominee.html @@ -9,7 +9,7 @@

    Edit email
    - {{ nominee }} + {{ nominee }}

    {% csrf_token %} diff --git a/ietf/templates/nomcom/edit_position.html b/ietf/templates/nomcom/edit_position.html index 3dfa62fe1c8..fd01a2c4fa9 100644 --- a/ietf/templates/nomcom/edit_position.html +++ b/ietf/templates/nomcom/edit_position.html @@ -31,5 +31,14 @@

    {% if position %}Save{% else %}Add{% endif %} Back + {% if position.name %} +

    + Templates +

    + {% for template in position.get_templates %} + {{ template }} +
    + {% endfor %} + {% endif %} {% endblock %} -{% block content_end %}{{ form.media.js }}{% endblock %} \ No newline at end of file +{% block content_end %}{{ form.media.js }}{% endblock %} diff --git a/ietf/templates/nomcom/edit_template.html b/ietf/templates/nomcom/edit_template.html index 5c6ba618df1..b901104cf0a 100644 --- a/ietf/templates/nomcom/edit_template.html +++ b/ietf/templates/nomcom/edit_template.html @@ -8,7 +8,7 @@

    Template
    - {{ template }} + {{ template }}

    diff --git a/ietf/templates/nomcom/eligible.html b/ietf/templates/nomcom/eligible.html index fcf06e6e514..f5cfc2e2dcd 100644 --- a/ietf/templates/nomcom/eligible.html +++ b/ietf/templates/nomcom/eligible.html @@ -4,9 +4,6 @@ {% load django_bootstrap5 textfilters person_filters %} {% load static %} {% block subtitle %}- Eligible People{% endblock %} -{% block pagehead %} - -{% endblock %} {% block nomcom_content %} {% origin %}

    Eligible People for {{ nomcom.group }}

    @@ -41,7 +38,4 @@

    Eligible People for {{ nomcom.group }}

    {% endif %} } -{% endblock %} -{% block js %} - {% endblock %} \ No newline at end of file diff --git a/ietf/templates/nomcom/email_list_panel.html b/ietf/templates/nomcom/email_list_panel.html index 84dc8bec1ec..0ee0c8a284a 100644 --- a/ietf/templates/nomcom/email_list_panel.html +++ b/ietf/templates/nomcom/email_list_panel.html @@ -6,4 +6,6 @@
  • {% person_link n.person with_email=False %} ({{ n.email.address|linkify }})
  • {% endfor %} +{% else %} +None {% endif %} \ No newline at end of file diff --git a/ietf/templates/nomcom/extract_email_lists.html b/ietf/templates/nomcom/extract_email_lists.html index b2a5fec493d..b80119cf01a 100644 --- a/ietf/templates/nomcom/extract_email_lists.html +++ b/ietf/templates/nomcom/extract_email_lists.html @@ -8,7 +8,7 @@

    Email lists
    - {{ nomcom.group }} + {{ nomcom.group }}

    {% with title='Nominees Pending Acceptance' list=pending heading="h3" %} {% include 'nomcom/email_list_panel.html' %} diff --git a/ietf/templates/nomcom/feedback.html b/ietf/templates/nomcom/feedback.html index 880fb42dfd6..8c9e8c824f9 100644 --- a/ietf/templates/nomcom/feedback.html +++ b/ietf/templates/nomcom/feedback.html @@ -9,13 +9,20 @@

    {% if nomcom.group.state_id == 'conclude' %} Feedback to this NomCom is closed. + {% elif positions|length != 0 and topics|length != 0 %} + Select a nominee or topic from the list on the right to obtain a new feedback form. + {% elif positions|length != 0 %} + Select a nominee from the list on the right to obtain a new feedback form. + {% elif topics|length != 0 %} + Select a topic from the list on the right to obtain a new feedback form. {% else %} - Select a nominee from the list of nominees on the right to obtain a new feedback form. + This NomCom is not accepting feedback at this time. {% endif %}

    {% if nomcom|has_publickey %}
    {% if form %} {% if form.position %} {% if nomcom.show_nominee_pictures and form.nominee.email.person.photo_thumb %} -
    {% include "person/photo.html" with person=form.nominee.person %}
    +
    {% include "person/photo.html" with person=form.nominee.person %}
    {% endif %}

    - Provide feedback about {% person_link form.nominee.person %} + Provide feedback about {% person_link form.nominee.person with_email=False %} for the {{ form.position.name }} position.

    {% elif form.topic %}

    Provide feedback
    - {{ form.topic.subject }} + {{ form.topic.subject }}

    Description: {{ form.topic.subject }}
    @@ -87,10 +97,10 @@

    {% endif %}

    This feedback will only be available to - NomCom {{ year }}. - You may have the feedback mailed back to you by selecting the option below. + the current NomCom. + You can have the feedback mailed back to you by selecting the option below.

    -
    + {% csrf_token %} {% bootstrap_form form %} diff --git a/ietf/templates/nomcom/history.html b/ietf/templates/nomcom/history.html index 74e7efff7b8..8262876b11b 100644 --- a/ietf/templates/nomcom/history.html +++ b/ietf/templates/nomcom/history.html @@ -11,7 +11,7 @@

    NomCom Membership History

    Note: The data for concluded NomComs is occasionally incorrect.

    {% for regime in regimes %} -

    {{ regime.label }}

    +

    {{ regime.year }} NomCom

    {% for slug, label, roles in regime.nomcom.personnel %}
    @@ -25,7 +25,7 @@

    {{ regime.label }}

    {% endfor %}
    {% endfor %} -

    2012/2013

    +

    2012 NomCom

    Chair @@ -58,13 +58,13 @@

    2012/2013

    Liaison Members
    - Marc Blanchet (IAB Liaison), - Scott Bradner (IAOC Liaison), - Sean Turner (IESG Liaison), - Rudi Vansnick (ISOC Liaison) + Marc Blanchet (IAB Liaison), + Scott Bradner (IAOC Liaison), + Sean Turner (IESG Liaison), + Rudi Vansnick (ISOC Liaison)
    -

    2011/2012

    +

    2011 NomCom

    Chair @@ -77,7 +77,7 @@

    2011/2012

    Tom Walsh, - Henrik Levkowetz (Tools Advisor) + Henrik Levkowetz (Tools Advisor)
    Members @@ -98,13 +98,13 @@

    2011/2012

    Liaison Members
    - Dave Thaler (IAB Liaison), - Dave Crocker (IAOC Liaison), - Ralph Droms (IESG Liaison), - Jason Livingood (ISOC Liaison) + Dave Thaler (IAB Liaison), + Dave Crocker (IAOC Liaison), + Ralph Droms (IESG Liaison), + Jason Livingood (ISOC Liaison)
    -

    2010/2011

    +

    2010 NomCom

    Chair @@ -117,7 +117,7 @@

    2010/2011

    Mary Barnes, - Henrik Levkowetz (Tools Advisor) + Henrik Levkowetz (Tools Advisor)
    Members @@ -137,13 +137,13 @@

    2010/2011

    Liaison Members
    - Spencer Dawkins (IAB Liaison), - Ole Jacobsen (IAOC Liaison), - Dan Romascanu (IESG Liaison), - Eric Burger (ISOC Liaison) + Spencer Dawkins (IAB Liaison), + Ole Jacobsen (IAOC Liaison), + Dan Romascanu (IESG Liaison), + Eric Burger (ISOC Liaison)
    -

    2009/2010

    +

    2009 NomCom

    Chair @@ -156,7 +156,7 @@

    2009/2010

    Joel Halpern, - Henrik Levkowetz (Tools Advisor) + Henrik Levkowetz (Tools Advisor)
    Members @@ -177,14 +177,14 @@

    2009/2010

    Liaison Members
    - Jon Peterson (IAB Liaison), - Tim Polk (IESG Liaison), - Henk Uijterwall (IAOC liaison), - TBA (ISOC Liaison) + Jon Peterson (IAB Liaison), + Tim Polk (IESG Liaison), + Henk Uijterwall (IAOC liaison), + TBA (ISOC Liaison)

    - 2008/2009 + 2008 NomCom

    @@ -218,13 +218,13 @@

    Liaison Members

    - Dave Oran (IAB Liaison), - Ross Callon (IESG Liaison), - Bert Wijnen (ISOC Liaison) + Dave Oran (IAB Liaison), + Ross Callon (IESG Liaison), + Bert Wijnen (ISOC Liaison)

    - 2007/2008 + 2007 NomCom

    @@ -258,13 +258,13 @@

    Liaison Members

    - Danny McPherson (IAB Liaison), - Lars Eggert (IESG Liaison), - Fred Baker (ISOC Liaison) + Danny McPherson (IAB Liaison), + Lars Eggert (IESG Liaison), + Fred Baker (ISOC Liaison)

    - 2006/2007 + 2006 NomCom

    @@ -277,7 +277,7 @@

    Advisor

    - Ralph Droms (Previous Chair) + Ralph Droms (Previous Chair)
    Members @@ -298,13 +298,13 @@

    Liaison Members

    - Olaf Kolkman (IAB Liaison), - Cullen Jennings (IESG Liaison), - Fred Baker (ISOC Liaison) + Olaf Kolkman (IAB Liaison), + Cullen Jennings (IESG Liaison), + Fred Baker (ISOC Liaison)

    - 2005/2006 + 2005 NomCom

    @@ -317,7 +317,7 @@

    Advisor

    - Danny McPherson (Previous Chair) + Danny McPherson (Previous Chair)
    Members @@ -338,13 +338,13 @@

    Liaison Members

    - David Meyer (IAB Liaison), - Russ Housley (IESG Liaison), - Steve Crocker (ISOC Liaison) + David Meyer (IAB Liaison), + Russ Housley (IESG Liaison), + Steve Crocker (ISOC Liaison)

    - 2004/2005 + 2004 NomCom

    @@ -357,7 +357,7 @@

    Advisor

    - Richard Draves (Previous Chair) + Richard Draves (Previous Chair)
    Members @@ -378,14 +378,14 @@

    Liaison Members

    - Eric Rescorla (IAB Liaison), - Alex Zinin (IESG Liaison), - Steve Crocker (ISOC Liaison), - Richard Draves (Previous Chair/Advisor) + Eric Rescorla (IAB Liaison), + Alex Zinin (IESG Liaison), + Steve Crocker (ISOC Liaison), + Richard Draves (Previous Chair/Advisor)

    - 2003/2004 + 2003 NomCom

    @@ -398,7 +398,7 @@

    Advisor

    - Phil Roberts (Previous Chair) + Phil Roberts (Previous Chair)
    Members @@ -419,12 +419,12 @@

    Liaison Members

    - Geoff Huston (IAB Liaison), - Bill Fenner (IESG liaison) + Geoff Huston (IAB Liaison), + Bill Fenner (IESG liaison)

    - 2002/2003 + 2002 NomCom

    @@ -437,7 +437,7 @@

    Advisor

    - Theodore Ts'o (Previous Chair) + Theodore Ts'o (Previous Chair)
    Members @@ -458,12 +458,12 @@

    Liaison Members

    - Eric Rescorla (IAB liaison), - Allison Mankin (IETF liaison) + Eric Rescorla (IAB liaison), + Allison Mankin (IETF liaison)

    - 2001/2002 + 2001 NomCom

    @@ -476,7 +476,7 @@

    Advisor

    - Bernard Aboba (Previous Chair) + Bernard Aboba (Previous Chair)
    Members @@ -497,12 +497,12 @@

    Liaison Members

    - Fred Baker (IAB liaison), - Thomas Narten (IESG Liaison) + Fred Baker (IAB liaison), + Thomas Narten (IESG Liaison)

    - 2000/2001 + 2000 NomCom

    @@ -515,7 +515,7 @@

    Advisor

    - Avri Doria (Previous Chair) + Avri Doria (Previous Chair)
    Members @@ -536,12 +536,12 @@

    Liaison Members

    - Leslie Daigle (IAB Liaison), - Allison Mankin (IESG Liaison) + Leslie Daigle (IAB Liaison), + Allison Mankin (IESG Liaison)

    - 1999/2000 + 1999 NomCom

    @@ -554,7 +554,7 @@

    Advisor

    - Donald E. Eastlake (Previous Chair) + Donald E. Eastlake (Previous Chair)
    Members @@ -575,12 +575,12 @@

    Liaison Members

    - Geoff Huston (IAB Liaison), - Thomas Narten (IESG Liaison) + Geoff Huston (IAB Liaison), + Thomas Narten (IESG Liaison)

    - 1998/1999 + 1998 NomCom

    @@ -593,7 +593,7 @@

    Advisor

    - Michael St Johns (Previous Chair) + Michael St Johns (Previous Chair)
    Members @@ -614,13 +614,13 @@

    Liaison Members

    - Steven Bellovin (IAB Liaison), - Bert Wijnen (IESG Liaison), - Michael St Johns (Previous Chair) + Steven Bellovin (IAB Liaison), + Bert Wijnen (IESG Liaison), + Michael St Johns (Previous Chair)

    - 1997/1998 + 1997 NomCom

    @@ -633,7 +633,7 @@

    Advisor

    - Geoff Huston (Previous Chair) + Geoff Huston (Previous Chair)
    Members @@ -654,12 +654,12 @@

    Liaison Members

    - Tony Hain (IAB Liaison), - Scott Bradner (IESG Liaison), + Tony Hain (IAB Liaison), + Scott Bradner (IESG Liaison),

    - 1996/1997 + 1996 NomCom

    @@ -672,7 +672,7 @@

    Advisor

    - Guy Almes (Previous Chair) + Guy Almes (Previous Chair)
    Members @@ -693,14 +693,14 @@

    Liaison Members

    - Radia Perlman (IAB Liaison), - Joyce Reynolds (IESG Liaison), - Christian Huitema (ISOC Liaison), - Guy Almes (Previous Chair), + Radia Perlman (IAB Liaison), + Joyce Reynolds (IESG Liaison), + Christian Huitema (ISOC Liaison), + Guy Almes (Previous Chair),

    - 1995/1996 + 1995 NomCom

    @@ -713,7 +713,7 @@

    Advisor

    - John Curran (Previous Chair) + John Curran (Previous Chair)
    Members @@ -734,12 +734,12 @@

    Liaison Members

    - Bob Moskowitz (IAB Liaison), - Harald Alvestrand (IESG Liaison), + Bob Moskowitz (IAB Liaison), + Harald Alvestrand (IESG Liaison),

    - 1994/1995 + 1994 NomCom

    @@ -752,7 +752,7 @@

    Advisor

    - Fred Baker (Previous Chair) + Fred Baker (Previous Chair)
    Members @@ -771,7 +771,7 @@

    - 1993/1994 + 1993 NomCom

    @@ -796,13 +796,13 @@

    Liaison Members

    - Bob Braden (IAB Liaison), - Stev Knowles (IESG Liaison), - Jon Postel (IRSG Liaison), + Bob Braden (IAB Liaison), + Stev Knowles (IESG Liaison), + Jon Postel (IRSG Liaison),

    - 1992/1993 + 1992 NomCom

    @@ -821,10 +821,10 @@

    Liaison Members

    - Barry Leiner (IAB Liaison), - Erik Huizer (IESG Liaison), - Jon Postel (IRSG Liaison), - Geoff Huston (ISOC Liaison), + Barry Leiner (IAB Liaison), + Erik Huizer (IESG Liaison), + Jon Postel (IRSG Liaison), + Geoff Huston (ISOC Liaison),
    {% endblock %} \ No newline at end of file diff --git a/ietf/templates/nomcom/index.html b/ietf/templates/nomcom/index.html index 91f63f74ebc..e765dd7c2ea 100644 --- a/ietf/templates/nomcom/index.html +++ b/ietf/templates/nomcom/index.html @@ -12,7 +12,7 @@

    NomComs

    - + diff --git a/ietf/templates/nomcom/list_positions.html b/ietf/templates/nomcom/list_positions.html index e2affefb813..59e549fc3d3 100644 --- a/ietf/templates/nomcom/list_positions.html +++ b/ietf/templates/nomcom/list_positions.html @@ -1,6 +1,6 @@ {% extends "nomcom/nomcom_private_base.html" %} {# Copyright The IETF Trust 2015, All Rights Reserved #} -{% load origin %} +{% load origin static %} {% block subtitle %}- Positions{% endblock %} {% block nomcom_content %} {% origin %} @@ -13,51 +13,122 @@

    Positions in {{ nomcom.group }}

    Configuration Hints.

    {% endif %} + + {% if nomcom.group.state_id == 'active' %} + + {% csrf_token %} + {% endif %} {% if positions %} - {% regroup positions by is_open as posgroups %} - {% for group in posgroups %} -

    {{ group.grouper| yesno:"Open Positions,Closed Positions" }}

    - {% for position in group.list %} -

    - {{ position.name }} - {% if position.is_iesg_position %}(IESG){% endif %} -

    - {% if group.grouper %} -
    -
    - Accepting -
    -
    - {% if position.accepting_nominations %}Nominations{% endif %} - {% if position.accepting_nominations and position.accepting_feedback %}and{% endif %} - {% if position.accepting_feedback %}Feedback{% endif %} -
    -
    - {% endif %} -
    -
    - Templates -
    -
    - {% for template in position.get_templates %} - {{ template }} -
    - {% endfor %} -
    +
    YearYear Convened Chair
    + + {% if nomcom.group.state_id == 'active' %} -
    - Actions -
    -
    - Edit - Remove -
    + + {% endif %} - - {% endfor %} - {% endfor %} + + + + + + + + + + {% for position in positions %} + + {% if nomcom.group.state_id == 'active' %} + + + {% endif %} + + + + + + + {% endfor %} + +
    + ✓ + + Position + + IESG + + Open + + Accepting Nominations + + Accepting Feedback +
    + + + + Edit + + + Remove + + + {{ position.name }} + + {{ position.is_iesg_position|yesno:"✓," }} + + {{ position.is_open|yesno:"✓," }} + + {{ position.accepting_nominations|yesno:"✓," }} + + {{ position.accepting_feedback|yesno:"✓," }} +
    + {% if nomcom.group.state_id == 'active' %} +
    + + +
    + +
    + {% endif %} {% else %}

    There are no positions defined. diff --git a/ietf/templates/nomcom/nomcom_private_base.html b/ietf/templates/nomcom/nomcom_private_base.html index 2a0495fbe6c..6b12f513697 100644 --- a/ietf/templates/nomcom/nomcom_private_base.html +++ b/ietf/templates/nomcom/nomcom_private_base.html @@ -1,147 +1,162 @@ {% extends "base.html" %} {# Copyright The IETF Trust 2015, All Rights Reserved #} -{% load origin %} +{% load origin static %} {% load nomcom_tags %} {% load ietf_filters %} +{% block pagehead %} + +{% endblock %} {% block title %} NomCom {{ year }} Private {% block subtitle %}{% endblock %} {% endblock %} {% block content %} {% origin %} + {% with selected=request.path|split:'/'|slice:'4:-1'|join:'-' %}

    NomCom {{ year }} - {% if nomcom.group.state_id == 'conclude' %}Concluded{% endif %} + {% if nomcom.group.state_id == 'conclude' %}Concluded{% endif %}
    - Private area + Private area {% if is_chair_task %}- Chair/Advisors only{% endif %}

    {% block nomcom_content %}{% endblock %} + {% endwith %} {% endblock %} {% block js %} + {% endblock %} \ No newline at end of file diff --git a/ietf/templates/nomcom/private_key.html b/ietf/templates/nomcom/private_key.html index 847389e26b3..128605ecf39 100644 --- a/ietf/templates/nomcom/private_key.html +++ b/ietf/templates/nomcom/private_key.html @@ -7,7 +7,7 @@ {% origin %}

    Enter private key

    - In order to access the {{ nomcom.group }} data you have to enter your private key. Please paste it in the text area below. The key must be in the following format: + In order to access the {{ nomcom.group }} data you have to enter the NomCom group's private key (which you should have received from the NomCom Chair). The key must be in the following format:

       -----BEGIN PRIVATE KEY-----
    diff --git a/ietf/templates/nomcom/public_nominate.html b/ietf/templates/nomcom/public_nominate.html
    index 084c1ee8d61..5320eb2acfc 100644
    --- a/ietf/templates/nomcom/public_nominate.html
    +++ b/ietf/templates/nomcom/public_nominate.html
    @@ -24,7 +24,7 @@ 

    Nominate Candidate

    Nominees
    - who accepted nominations + who accepted nominations

    {% for p in positions %} {% if p.nomineeposition_set.accepted.not_duplicated %} diff --git a/ietf/templates/nomcom/qualified_volunteer_list_for_announcement.txt b/ietf/templates/nomcom/qualified_volunteer_list_for_announcement.txt new file mode 100644 index 00000000000..46fae1e06cd --- /dev/null +++ b/ietf/templates/nomcom/qualified_volunteer_list_for_announcement.txt @@ -0,0 +1,4 @@ +{% load ietf_filters %}{% autoescape off %}Name Affiliation + +{% for volunteer in volunteers %}{{ volunteer.person.plain_name|ljust:"25" }}{{ volunteer.affiliation|default:"No affiliation provided" }} +{% endfor %}{% endautoescape %} diff --git a/ietf/templates/nomcom/reclassify_feedback_item.html b/ietf/templates/nomcom/reclassify_feedback_item.html new file mode 100644 index 00000000000..fb967493cfe --- /dev/null +++ b/ietf/templates/nomcom/reclassify_feedback_item.html @@ -0,0 +1,103 @@ +{# Copyright The IETF Trust 2023, All Rights Reserved #} +{% load nomcom_tags textfilters %} +

    Reclassify feedback item

    +
    + {% csrf_token %} + + + + + + + + + + + + + {% for ft in feedback_types %} + + + + + {% endfor %} + +
    CodeExplanation
    UUnclassified
    {{ ft.legend }}{{ ft.name }}
    + + + + + + {% for ft in feedback_types %} + + {% endfor %} + + + + + + + + + + + {% for ft in feedback_types %} + + {% endfor %} + + + + + +
    DateU{{ ft.legend }}AuthorSubject
    {{ reclassify_feedback.time|date:"r" }} + + + + {{ reclassify_feedback.author }}{{ reclassify_feedback.subject }} + + +
    + + +
    diff --git a/ietf/templates/nomcom/view_feedback.html b/ietf/templates/nomcom/view_feedback.html index 9215d3c82c7..0758329d606 100644 --- a/ietf/templates/nomcom/view_feedback.html +++ b/ietf/templates/nomcom/view_feedback.html @@ -1,11 +1,8 @@ {% extends "nomcom/nomcom_private_base.html" %} -{# Copyright The IETF Trust 2015, All Rights Reserved #} +{# Copyright The IETF Trust 2015-2023, All Rights Reserved #} {% load origin static %} {% load nomcom_tags %} {% block subtitle %}- View feedback{% endblock %} -{% block pagehead %} - -{% endblock %} {% block nomcom_content %} {% origin %}

    Feedback related to nominees

    @@ -46,14 +43,26 @@

    Declined each nominated position

    {% for fbtype_name, fbtype_count, fbtype_newflag in fb_dict.feedback %} - - {% if fbtype_newflag %}New{% endif %} + + {% if fbtype_newflag %}New{% endif %} {{ fbtype_count }} {% endfor %} {% endfor %} + + + Totals + + + {% for fbtype_count in staterank.list|feedback_totals %} + + {{ fbtype_count }} + + {% endfor %} + + {% endfor %}

    Feedback related to topics

    @@ -73,8 +82,8 @@

    Feedback related to topics

    {% for fbtype_name, fbtype_count, fbtype_newflag in fb_dict.feedback %} - - {% if fbtype_newflag %}New{% endif %} + + {% if fbtype_newflag %}New{% endif %} {{ fbtype_count }} {% endfor %} @@ -101,7 +110,4 @@

    Feedback not related to Nominees

    {% endif %} -{% endblock %} -{% block js %} - -{% endblock %} +{% endblock %} \ No newline at end of file diff --git a/ietf/templates/nomcom/view_feedback_nominee.html b/ietf/templates/nomcom/view_feedback_nominee.html index 2dd53d41d28..9194ee84bf1 100644 --- a/ietf/templates/nomcom/view_feedback_nominee.html +++ b/ietf/templates/nomcom/view_feedback_nominee.html @@ -1,10 +1,13 @@ {% extends "nomcom/nomcom_private_base.html" %} -{# Copyright The IETF Trust 2015, All Rights Reserved #} +{# Copyright The IETF Trust 2015-2023, All Rights Reserved #} {% load origin %} {% load nomcom_tags textfilters %} {% block subtitle %}- View feedback about {{ nominee.email.person.name }}{% endblock %} {% block nomcom_content %} - {% origin %} +{% origin %} +{% if reclassify_feedback %} + {% include "nomcom/reclassify_feedback_item.html" %} +{% else %}

    Feedback about {{ nominee }}

    Back +{% endif %} {% endblock %} {% block js %} -{% endblock %} \ No newline at end of file +{% endblock %} diff --git a/ietf/templates/nomcom/view_feedback_pending.html b/ietf/templates/nomcom/view_feedback_pending.html index 72b4beb0690..5681ca5d70f 100644 --- a/ietf/templates/nomcom/view_feedback_pending.html +++ b/ietf/templates/nomcom/view_feedback_pending.html @@ -1,11 +1,11 @@ {% extends "nomcom/nomcom_private_base.html" %} -{# Copyright The IETF Trust 2015, All Rights Reserved #} +{# Copyright The IETF Trust 2015-2023, All Rights Reserved #} {% load origin %} {% load django_bootstrap5 %} {% load static %} {% load nomcom_tags person_filters %} {% block pagehead %}{{ formset.media.css }}{% endblock %} -{% block subtitle %}- Feeback pending{% endblock %} +{% block subtitle %}- Feedback pending{% endblock %} {% block nomcom_content %} {% origin %}

    Feedback pending from email list

    @@ -42,7 +42,7 @@

    Feedback pending from email list

    Type
    - {{ form.feedback_type }} + {{ form.feedback_type }}
    Feedback @@ -61,7 +61,7 @@

    Feedback pending from email list

    {% endfor %} + name="end" value="1">Save feedback Back {% else %} @@ -73,13 +73,9 @@

    Feedback pending from email list

    - - U - Unclassified - - {% for legend, t in type_dict.items %} + {% for t in types %} - {{ legend }} + {{ t.legend }} {{ t.name }} {% endfor %} @@ -89,8 +85,7 @@

    Feedback pending from email list

    Date - U - {% for legend, t in type_dict.items %}{{ legend }}{% endfor %} + {% for t in types %}{{ t.legend }}{% endfor %} Author Subject @@ -118,7 +113,7 @@

    Feedback pending from email list

    title="{{ choice.1 }}"> {% endfor %} - {% person_link form.instance.author %} + {{ form.instance.author }} {{ form.instance.subject }}
  • Back +{% endif %} {% endblock %} {% block js %} -{% endblock %} \ No newline at end of file +{% endblock %} diff --git a/ietf/templates/nomcom/view_feedback_unrelated.html b/ietf/templates/nomcom/view_feedback_unrelated.html index b098d7748de..0e749e748f9 100644 --- a/ietf/templates/nomcom/view_feedback_unrelated.html +++ b/ietf/templates/nomcom/view_feedback_unrelated.html @@ -1,10 +1,13 @@ {% extends "nomcom/nomcom_private_base.html" %} -{# Copyright The IETF Trust 2015, All Rights Reserved #} +{# Copyright The IETF Trust 2015-2023, All Rights Reserved #} {% load origin %} {% load nomcom_tags textfilters %} {% block subtitle %}- View unrelated feedback{% endblock %} {% block nomcom_content %} - {% origin %} +{% origin %} +{% if reclassify_feedback %} + {% include "nomcom/reclassify_feedback_item.html" %} +{% else %}

    Feedback not related to nominees

    aria-label="Close"> - {% endif %} {% endfor %} + {% endif %} {% if submission.state_id == "waiting-for-draft" %}

    - This submission is awaiting the first draft upload. + This submission is awaiting the first Internet-Draft upload.

    + {% elif submission.state_id == 'validating' %} +
    + Notice: The Internet-Draft submission process has changed as of Datatracker version 10.3.0. + Your Internet-Draft is currently being processed and validated asynchronously. Results will be + displayed at this URL when they are available. If JavaScript is enabled in your + browser, this page will refreshed automatically. If JavaScript is not enabled, + please reload this page in a few minutes to see the results. +
    +
    + This submission is being processed and validated. This usually takes a few seconds but may + take a few minutes for complex drafts or during periods of heavy load. + {% with earliest_event=submission.submissionevent_set.last %} + {% if earliest_event %} + Your draft was uploaded at {{ earliest_event.time }}. + {% endif %} + {% endwith %} + Please contact the secretariat for assistance if it has been more than an hour. +
    {% else %}

    Meta-data from the submission

    - {% if errors %} + {% if submission.state.slug == "cancel" %} +
    + Note: The meta-data shown for a cancelled draft may be incorrect or incomplete. +
    + {% elif errors %}

    Meta-Data errors found! @@ -172,12 +198,14 @@

    Meta-data from the submission

    {% else %} {{ submission.name }} {% endif %} - + {% if submission.first_two_pages %} + + {% endif %} {% show_submission_files submission %} {% if errors.files %}

    @@ -215,159 +243,141 @@

    Meta-data from the submission

    {% endif %} - - Document date - - {{ submission.document_date }} - {% if errors.document_date %} -

    - {{ errors.document_date }} -

    - {% endif %} - - - - Submission date - {{ submission.submission_date }} - - - Title - - {{ submission.title|default:"" }} - {% if errors.title %} -

    - {{ errors.title }} -

    - {% endif %} - - - - Author count - - {{ submission.authors|length }} author{{ submission.authors|pluralize }} - {% if errors.authors %} -

    - {{ errors.authors|safe }} -

    - {% endif %} - - - {% for author in submission.authors %} + {% if submission.state_id != 'validating' %} - Author {{ forloop.counter }} + Document date - {{ author.name }} - {% if author.email %}<{{ author.email|linkify }}>{% endif %} -
    - {% if author.affiliation %} - {{ author.affiliation }} - {% else %} - unknown affiliation + {{ submission.document_date }} + {% if errors.document_date %} +

    + {{ errors.document_date }} +

    {% endif %} -
    - {% if author.country %} - {{ author.country }} - {% if author.cleaned_country and author.country != author.cleaned_country %} - (understood to be {{ author.cleaned_country }}) - {% endif %} - {% else %} - unknown country + + + + Submission date + {{ submission.submission_date }} + + + Title + + {{ submission.title|default:"" }} + {% if errors.title %} +

    + {{ errors.title }} +

    {% endif %} - {% if author.country and not author.cleaned_country %} + + + + Author count + + {{ submission.authors|length }} author{{ submission.authors|pluralize }} + {% if errors.authors %} +

    + {{ errors.authors|safe }} +

    + {% endif %} + + + {% for author in submission.authors %} + + Author {{ forloop.counter }} + + {% if author.name %}{{ author.name }}{% endif %} + {% if author.email %}<{{ author.email|linkify }}>{% endif %} +
    + {% if author.affiliation %} + {{ author.affiliation }} + {% else %} + unknown affiliation + {% endif %}
    - Unrecognized country: "{{ author.country }}": See - - recognized country names - . + {% if author.country %} + {{ author.country }} + {% if author.cleaned_country and author.country != author.cleaned_country %} + (understood to be {{ author.cleaned_country }}) + {% endif %} + {% else %} + unknown country + {% endif %} + {% if author.country and not author.cleaned_country %} +
    + Unrecognized country: "{{ author.country }}": See + + recognized country names + . + {% endif %} + {% for auth_err in author.errors %} +

    + {{ auth_err }} +

    + {% endfor %} + + + {% endfor %} + + + Abstract + + + {{ submission.abstract|urlize_ietf_docs|linkify|linebreaksbr }} + {% if errors.abstract %} +

    + {{ errors.abstract }} +

    {% endif %} - {% for auth_err in author.errors %} + + + + + Page count + + + {{ submission.pages }} + {% if errors.pages %}

    - {{ auth_err }} + {{ errors.pages }}

    + {% endif %} + + + + + File size + + + {{ submission.file_size|filesizeformat }} + + + + + Formal languages used + + + {% for l in submission.formal_languages.all %} + {{ l.name }}{% if not forloop.last %},{% endif %} + {% empty %}None recognized {% endfor %} + {% if errors.formal_languages %} +

    + {{ errors.formal_languages }} +

    + {% endif %} - {% endfor %} - - - Abstract - - - {{ submission.abstract|urlize_ietf_docs|linkify|linebreaksbr }} - {% if errors.abstract %} -

    - {{ errors.abstract }} -

    - {% endif %} - - - - - Page count - - - {{ submission.pages }} - {% if errors.pages %} -

    - {{ errors.pages }} -

    - {% endif %} - - - - - File size - - - {{ submission.file_size|filesizeformat }} - - - - - Formal languages used - - - {% for l in submission.formal_languages.all %} - {{ l.name }}{% if not forloop.last %},{% endif %} - {% empty %}None recognized - {% endfor %} - {% if errors.formal_languages %} -

    - {{ errors.formal_languages }} -

    - {% endif %} - - - - - Submission additional resources - - - {% for r in external_resources.current %} - {% with res=r.res added=r.added %} -
    - {{ res.name.name }}: {{ res.value }} - {% if res.display_name %}(as "{{ res.display_name }}"){% endif %} - {% if external_resources.show_changes and added %}New{% endif %} -
    - {% endwith %} - {% empty %} - None - {% endfor %} - - - {% if external_resources.show_changes %} - Current document additional resources + Submission additional resources - {% for r in external_resources.previous %} - {% with res=r.res removed=r.removed %} + {% for r in external_resources.current %} + {% with res=r.res added=r.added %}
    {{ res.name.name }}: {{ res.value }} {% if res.display_name %}(as "{{ res.display_name }}"){% endif %} - {% if removed %}Removed{% endif %} + {% if external_resources.show_changes and added %}New{% endif %}
    {% endwith %} {% empty %} @@ -375,6 +385,26 @@

    Meta-data from the submission

    {% endfor %} + {% if external_resources.show_changes %} + + + Current document additional resources + + + {% for r in external_resources.previous %} + {% with res=r.res removed=r.removed %} +
    + {{ res.name.name }}: {{ res.value }} + {% if res.display_name %}(as "{{ res.display_name }}"){% endif %} + {% if removed %}Removed{% endif %} +
    + {% endwith %} + {% empty %} + None + {% endfor %} + + + {% endif %} {% endif %} @@ -410,7 +440,7 @@

    {% if requires_group_approval %} Notifies group chairs to get approval. {% elif requires_prev_authors_approval %} - Notifies authors of previous revision of draft to get approval. + Notifies authors of previous revision of Internet-Draft to get approval. {% else %} Notifies submitter and authors for confirmation. {% endif %} @@ -490,16 +520,8 @@

    {% endif %} - {% if user|has_role:"Secretariat" %} - - Send Email - - {% endif %} {% if show_send_full_url %} -
    +

    You are not allowed to modify or cancel this submission. You can only modify or cancel this submission from the same URL you were @@ -518,7 +540,7 @@

    {% csrf_token %} -
    @@ -546,7 +568,7 @@

    {% for e in submission.submissionevent_set.all %} - {{ e.time|date:"Y-m-d" }} + {{ e.time|date:"Y-m-d" }} {% if e.by %} @@ -554,39 +576,10 @@

    {% endif %} - {% if e.desc|startswith:"Received message" or e.desc|startswith:"Sent message" %} - {% with m=e.submissionemailevent.message %} - {% if user.is_authenticated %} - - {% if e.desc|startswith:"Received message" and user|has_role:"Secretariat" %} - - Reply - - {% endif %} - Email: - - {{ e.desc }} - - - {% else %} - - Email: - - {{ e.desc }} - - - {% endif %} - {% endwith %} - {% else %} - - {{ e.desc|urlize_ietf_docs|linkify }} - - {% endif %} + + + {{ e.desc|urlize_ietf_docs|linkify }} + {% endfor %} diff --git a/ietf/templates/submit/submit_base.html b/ietf/templates/submit/submit_base.html index 0613cf5d6a1..a2c7be1a3be 100644 --- a/ietf/templates/submit/submit_base.html +++ b/ietf/templates/submit/submit_base.html @@ -4,7 +4,7 @@ {% block pagehead %}{{ block.super }}{% endblock %} {% block content %} {% origin %} -

    Internet-Draft submission

    +

    Submit an Internet-Draft

    {% load ietf_filters %} {% for author in submission.authors %} - + {% if author.name %} + + {% endif %} {% endfor %} {% bootstrap_form_errors submitter_form %} {% bootstrap_field submitter_form.name %} diff --git a/ietf/templates/submit/tool_instructions.html b/ietf/templates/submit/tool_instructions.html index 1a1486f0e1b..08265f52977 100644 --- a/ietf/templates/submit/tool_instructions.html +++ b/ietf/templates/submit/tool_instructions.html @@ -1,5 +1,5 @@ {% extends "submit/submit_base.html" %} -{# Copyright The IETF Trust 2015, All Rights Reserved #} +{# Copyright The IETF Trust 2015-2023, All Rights Reserved #} {% load origin %} {% block title %}I-D Submission tool instructions{% endblock %} {% block submit_content %} @@ -12,7 +12,7 @@

    I-D submission tool instructions

    - This page will explain the purpose and content of each screen in the I-D Submission Tool, and the actions that result by clicking the form buttons on each screen. + This page explains the purpose and content of each screen in the Internet-Draft (I-D) Submission Tool, including the actions that result by clicking the form buttons on each screen.

    Internet-Drafts are working documents of the Internet Engineering @@ -29,16 +29,12 @@

    I-D submission tool instructions

    https://www.ietf.org/ietf/1id-abstracts.txt.

    - An API for automated draft submission is available as an alternative to this webpage at - {{ settings.IDTRACKER_BASE_URL }}{% url 'ietf.submit.views.api_submit' %}. -

    -

    - The specification for this tool can be found in - RFC 4228. + An API for automated Internet-Draft submission is available as an alternative to this webpage at + https://datatracker.ietf.org/api/submission.

    Upload screen

    - The Upload screen is the first screen that a user will see when he or she starts the I-D submission process. A user can submit three different formats of an I-D, XML, plain-text, and PDF, at the same time. Failure to submit at least one of a plain-text or xml version will cause an error, and an error screen will be displayed. A single v3 .xml source is preferred. A single v2 .xml source will be accepted. If neither of those are available, a plain-text document may be provided. + The Upload screen is the first screen in the I-D submission process. You can submit an I-D in one or more format: XML, PDF, and plain text. You can submit an XML file, and the other formats will be created automatically. A single v3 .xml source file is preferred; however, a single v2 .xml source file is also accepted. If a .xml file is not available, a single plain text document is also accepted.

    By submitting your I-D, you are granting some rights to the IETF Trust. Before you submit your I-D, @@ -60,39 +56,32 @@

    Upload screen

    - - .txt format - Button to select a plain-text file of an I-D from a user's local file system. - .xml format Button to select an XML file of an I-D from a user's local file system. - .pdf format - Button to select a PDF file of an I-D from a user's local file system. + .txt format + Button to select a plain text file of an I-D from a user's local file system. Upload - Button to upload the document(s). The tool will begin parsing the plain-text document (or creating it from the xml if only xml is provided) and validate the document. The parsed meta-data will be displayed for user confirmation along with the validation results. + Button to upload the document(s). The tool parses the .xml file or the .txt file, and the metadata is displayed for your confirmation along with the validation results.

    Validation screen

    - After a user uploads the document(s), the tool will parse the plain-text version, validate the I-D, and display the validation results with option(s) for next steps. The validation includes: checking for all IPR-related notices and I-D boilerplate described in - Guidelines to Authors of Internet-Drafts; - the required sections described in - the I-D Check List; - the version number; and the creation date. + After you upload the file(s) and the tool parses the the metadata, the validation results are displayed, and you are offered option(s) for next steps. Validation checks cover IPR-related notices, boilerplate, required sections, version number, and creation date as described in the + Internet-Draft Author Resources.

    - If the submission does not have any validation errors, then the user will be allowed to proceed with the automated posting process. This process will begin with submitter authentication, which will be done by e-mail. + If the submission does not have any validation errors, then you can proceed with the posting process. Submitter authentication is performed by email or via login to your IETF datatracker account.

    - A user must carefully examine the meta-data that are displayed on this screen, and make sure that these data were extracted correctly. If the data were not extracted correctly, then the user can correct the errors via the Adjust page. In such a case, the user will pass the draft to the Secretariat for manual posting. + A user must carefully examine the metadata that is displayed to ensure that it was correctly extracted. If the data were not extracted correctly, then the user can correct the errors on the Adjust page. In such a case, the IETF Secretariat will be responsible for manually posting the Internet-Draft.

    @@ -102,22 +91,22 @@

    Validation screen

    - + @@ -136,13 +125,13 @@

    Validation screen

    @@ -152,7 +141,7 @@

    Adjust screen

    - This is the screen where a user can adjust any meta-data that could have been incorrectly parsed from the submitted document. The document with adjusted meta-data will be submitted to the Secretariat for manual posting. + This is the screen where a user can adjust any metadata that could have been incorrectly parsed from the submitted document. The document with adjusted metadata will be submitted to the IETF Secretariat for manual posting.

    Adjust meta-dataAdjust metadata - Button to proceed to a screen with editable form fields for correcting the meta-data. A user can use this button to request manual posting by the Secretariat. + Button to proceed to a screen with editable form fields for correcting the metadata. Use this button to request manual posting by the IETF Secretariat.
    Cancel - Button to cancel the current submission. A user will be prompted for a confirmation before the submission is canceled. Once confirmed, the current submission will be canceled, the uploaded document(s) will be deleted permanently from the server, and a notification message will be sent to all authors with the IP address of the user who just canceled the submission. + Button to cancel the current submission. You will be prompted for a confirmation before the submission is canceled. Once confirmed, uploaded document(s) will be deleted permanently from the server, and a notification message will be sent to all authors.
    - When no meta-data error is detected: + When no metadata error is detected:

    - Button to start the automated posting process with submitter authentication. Once clicked, an email message will be sent to the parties who can verify the submission. For a new draft (-00), that will be the authors listed in the document. For -01 and subsequent drafts, the confirmation message is sent to the authors of the previous version. One of the recipients of the confirmation message will need to open the email message via his or her email application, and click the link provided in the message body. + Button to start the posting process. If the submitter has authenticated with a IETF datatracker account, everything will happen automatically. Otherwise, an email message will be sent to the parties who can verify the submission. For a new Internet-Draft (-00), the email goes to the authors listed in the document. For -01 and subsequent Internet-Drafts, the confirmation message is sent to the authors of the previous version. One of the confirmation message recipients will need to open the email message and click the link provided.

    - Once a link in the email body is clicked, the document gets pushed to the IETF Web and FTP sites, a notification is sent to the authors of the document, and an I-D Action announcement will be sent out within the next 15 minutes. + Once a link in the email body is clicked, the document gets posted in the I-D repository, a notification is sent to the authors of the document, and an I-D Action announcement will be sent out within the next 15 minutes.

    - If the document requires an additional approval from a chair of a working group, i.e., for submission of a 00 version of a working group document, then a message will be sent to the chairs of the working group for the approval. Once approved, the document will be immediately announced and available via the IETF Web and FTP sites. + If the document requires an additional approval from a chair of a working group, i.e., for submission of a -00 version of a working group document, then a message will be sent to the chairs of the working group for the approval. Once approved, the document will be immediately announced and in the I-D repository.

    @@ -176,7 +165,7 @@

    Submit for manual posting

    @@ -184,8 +173,7 @@

    Cancel

    @@ -194,7 +182,7 @@

    Status screen

    - The Status screen is the screen where a user can view the current status of a document that has just been submitted by the user, or a document that was submitted previously via the tool. If a link 'Status' is clicked from the tool's first page, then a form field will be provided for a user to look up a document by name. + The Status screen is the screen where you can view the current status of a document that has just been submitted, or a document that was submitted previously via the tool. If a link 'Status' is clicked from the tool's first page, then a form field will be provided for a user to look up a document by name.

    - Button to send a manual posting request to the Secretariat including any corrected meta-data and comments for the Secretariat. Once clicked, a notification message will be sent to the Secretariat, and a receipt page will be displayed. + Button to send a manual posting request to the Secretariat including any corrected metadata and comments for the Secretariat. Once clicked, a notification message will be sent to the Secretariat, and a receipt page will be displayed.
    - Button to cancel the current submission. A user will be prompted for a confirmation before the submission is canceled. Once confirmed, the current suissio - n will be canceled, the uploaded document(s) will be deleted permanently from the server, and a notification message will be sent to all authors with the IP address of the user who just canceled the submission. + Button to cancel the current submission. You will be prompted for a confirmation before the submission is canceled. Once confirmed, uploaded document(s) will be deleted permanently from the server, and a notification message will be sent to all authors.
    @@ -210,10 +198,10 @@

    Cancel

    - Button to cancel the current submission. This button will be displayed only when the document is in the process of being submitted. A user will be prompted for a confirmation before the submission is canceled. Once confirmed, the current submission will be canceled, the uploaded document(s) will be deleted permanently from the server, and a notification message will be sent to all authors with the IP address of the user who just canceled the submission. + Button to cancel the current submission. This button will be displayed only when the document is in the process of being submitted. You will be prompted for a confirmation before the submission is canceled. Once confirmed, the current submission will be canceled, the uploaded document(s) will be deleted permanently from the server, and a notification message will be sent to all authors.
    {% include "submit/problem-reports-footer.html" %} -{% endblock %} +{% endblock %} \ No newline at end of file diff --git a/ietf/templates/submit/upload_submission.html b/ietf/templates/submit/upload_submission.html index 5858da6f9c2..b8b1aca29c9 100644 --- a/ietf/templates/submit/upload_submission.html +++ b/ietf/templates/submit/upload_submission.html @@ -47,7 +47,8 @@ aria-controls="other-formats"> + type="checkbox" + {% if form.errors.txt %}checked {% endif %}> Submit other formats
    @@ -60,14 +61,8 @@ However, if you cannot for some reason submit XML, you must submit a plaintext rendering of your I-D.

    - {% bootstrap_label ' PDF rendering of the I-D' label_class="form-label fw-bold" %} - {% bootstrap_field form.pdf show_label=False %} -

    - Optional to submit, will be auto-generated based - on the submitted XML. -

    - {% bootstrap_form_errors form %} + {% bootstrap_form_errors form type="non_fields" %} {% bootstrap_button button_type="submit" name="upload" content="Upload" %} {% include "submit/problem-reports-footer.html" %} @@ -78,6 +73,11 @@ $(document).ready(function() { if ($("#checkbox").is(':checked')) $("#other-formats").collapse('show') + + $("form").one('submit', function() { + $("button").attr('disabled', 'disabled'); + return true; + }) }); {% endblock %} diff --git a/ietf/templates/sync/bcp-index.txt b/ietf/templates/sync/bcp-index.txt new file mode 100644 index 00000000000..dd19920eba8 --- /dev/null +++ b/ietf/templates/sync/bcp-index.txt @@ -0,0 +1,52 @@ + + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + BCP INDEX + ------------- + +(CREATED ON: {{created_on}}.) + +This file contains citations for all BCPs in numeric order. The BCPs +form a sub-series of the RFC document series, specifically those RFCs +with the status BEST CURRENT PRACTICE. + +BCP citations appear in this format: + + [BCP#] Best Current Practice #, + . + At the time of writing, this BCP comprises the following: + + Author 1, Author 2, "Title of the RFC", BCP #, RFC №, + DOI DOI string, Issue date, + . + +For example: + + [BCP3] Best Current Practice 3, + . + At the time of writing, this BCP comprises the following: + + F. Kastenholz, "Variance for The PPP Compression Control Protocol + and The PPP Encryption Control Protocol", BCP 3, RFC 1915, + DOI 10.17487/RFC1915, February 1996, + . + +Key to fields: + +# is the BCP number. + +№ is the RFC number. + +BCPs and other RFCs may be obtained from https://www.rfc-editor.org. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + BCP INDEX + --------- + + + +{% for bcp in bcps %}{{bcp|safe}} + +{% endfor %} diff --git a/ietf/templates/sync/discrepancies.html b/ietf/templates/sync/discrepancies.html index 2616ca9173a..7561e39a200 100644 --- a/ietf/templates/sync/discrepancies.html +++ b/ietf/templates/sync/discrepancies.html @@ -14,7 +14,7 @@

    {{ title }}

    - + @@ -34,7 +34,7 @@

    {{ title }}

    Draft nameInternet-Draft name IESG state RFC Editor state IANA Action state
    {% else %} -

    +

    (None)

    {% endif %} diff --git a/ietf/templates/sync/fyi-index.txt b/ietf/templates/sync/fyi-index.txt new file mode 100644 index 00000000000..cf9d57d5706 --- /dev/null +++ b/ietf/templates/sync/fyi-index.txt @@ -0,0 +1,52 @@ + + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + FYI INDEX + ------------- + +(CREATED ON: {{created_on}}.) + +This file contains citations for all FYIs in numeric order. The FYIs +(For Your Information) documents form a sub-series of the RFC series, +specifically those documents that may be of particular interest +to Internet users. The corresponding RFCs have status INFORMATIONAL. + +FYI citations appear in this format: + + [FYI#] For Your Information #, + . + At the time of writing, this FYI comprises the following: + + Author 1, Author 2, "Title of the RFC", FYI #, RFC №, + DOI DOI string, Issue date, + . + +For example: + + [FYI8] For Your Information 8, + . + At the time of writing, this FYI comprises the following: + + B. Fraser, "Site Security Handbook", FYI 8, RFC 2196, + DOI 10.17487/RFC2196, September 1997, + . + +Key to fields: + +# is the FYI number. + +№ is the RFC number. + +FYIs and other RFCs may be obtained from https://www.rfc-editor.org. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + FYI INDEX + --------- + + + +{% for fyi in fyis %}{{fyi|safe}} + +{% endfor %} diff --git a/ietf/templates/sync/rfc-index.txt b/ietf/templates/sync/rfc-index.txt new file mode 100644 index 00000000000..050afd130e7 --- /dev/null +++ b/ietf/templates/sync/rfc-index.txt @@ -0,0 +1,70 @@ + + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + RFC INDEX + ------------- + +(CREATED ON: {{created_on}}.) + +This file contains citations for all RFCs in numeric order. + +RFC citations appear in this format: + + #### Title of RFC. Author 1, Author 2, Author 3. Issue date. + (Format: ASCII) (Obsoletes xxx) (Obsoleted by xxx) (Updates xxx) + (Updated by xxx) (Also FYI ####) (Status: ssssss) (DOI: ddd) + +or + + #### Not Issued. + +For example: + + 9915 Dynamic Host Configuration Protocol for IPv6 (DHCPv6). T. Mrugalski, + B. Volz, M. Richardson, S. Jiang, T. Winters. January 2026. (Format: + HTML, TXT, PDF, XML) (Obsoletes RFC8415) (Also STD102) (Status: + INTERNET STANDARD) (DOI: 10.17487/RFC9915) + +Key to citations: + +#### is the RFC number. + +Following the RFC number are the title, the author(s), and the +publication date of the RFC. Each of these is terminated by a period. + +Following the number are the title (terminated with a period), the +author, or list of authors (terminated with a period), and the date +(terminated with a period). + +The format follows in parentheses. One or more of the following formats +are listed: text (TXT), PostScript (PS), Portable Document Format +(PDF), HTML, XML. + +Obsoletes xxxx refers to other RFCs that this one replaces; +Obsoleted by xxxx refers to RFCs that have replaced this one. +Updates xxxx refers to other RFCs that this one merely updates (but +does not replace); Updated by xxxx refers to RFCs that have updated +(but not replaced) this one. Generally, only immediately succeeding +and/or preceding RFCs are indicated, not the entire history of each +related earlier or later RFC in a related series. + +The (Also FYI ##) or (Also STD ##) or (Also BCP ##) phrase gives the +equivalent FYI, STD, or BCP number if the RFC is also in those +document sub-series. The Status field gives the document's +current status (see RFC 2026). The (DOI ddd) field gives the +Digital Object Identifier. + +RFCs may be obtained in a number of ways, using HTTP, FTP, or email. +See the RFC Editor Web page http://www.rfc-editor.org + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + RFC INDEX + --------- + + + +{% for rfc in rfcs %}{{rfc|safe}} + +{% endfor %} diff --git a/ietf/templates/sync/std-index.txt b/ietf/templates/sync/std-index.txt new file mode 100644 index 00000000000..a4a5fba9461 --- /dev/null +++ b/ietf/templates/sync/std-index.txt @@ -0,0 +1,51 @@ + + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + STD INDEX + ------------- + +(CREATED ON: {{created_on}}.) + +This file contains citations for all STDs in numeric order. Each +STD represents a single Internet Standard technical specification, +composed of one or more RFCs with Internet Standard status. + +STD citations appear in this format: + + [STD#] Internet Standard #, + . + At the time of writing, this STD comprises the following: + + Author 1, Author 2, "Title of the RFC", STD #, RFC №, + DOI DOI string, Issue date, + . + +For example: + + [STD6] Internet Standard 6, + . + At the time of writing, this STD comprises the following: + + J. Postel, "User Datagram Protocol", STD 6, RFC 768, + DOI 10.17487/RFC0768, August 1980, + . + +Key to fields: + +# is the STD number. + +№ is the RFC number. + +STDs and other RFCs may be obtained from https://www.rfc-editor.org. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + STD INDEX + --------- + + + +{% for std in stds %}{{std|safe}} + +{% endfor %} diff --git a/ietf/templates/utils/personal_information_notice.txt b/ietf/templates/utils/personal_information_notice.txt deleted file mode 100644 index 379d8e4ef30..00000000000 --- a/ietf/templates/utils/personal_information_notice.txt +++ /dev/null @@ -1,36 +0,0 @@ -{% load ietf_filters %}{% filter wordwrap:78 %} -Dear {{ person.plain_name }}, - -We write to address certain personal information stored in your IETF -datatracker profile. Going forward, we will maintain and use your personal -information only with your consent. - -If you do nothing in response to this email, the information in your profile -that requires consent ({{ fields|safe }}) will be deleted {{ days }} days from -the date of this email, that is, on {{ date }}. If you later wish to create a -new login, you can do so at -{{ settings.IDTRACKER_BASE_URL }}{% url 'ietf.ietfauth.views.create_account' %}. - -If you would like us to continue to maintain and process the information that -requires your consent, please go to -{{ settings.IDTRACKER_BASE_URL }}{% url 'ietf.ietfauth.views.profile' %}, -and review and edit the information as desired and confirm your consent to our -continued maintenance and use of your information by checking the 'Consent' -checkbox found at the bottom of the page, and then submit the form. - -For information on how personal information is handled in the datatracker, please see -{{ settings.IDTRACKER_BASE_URL }}{% url 'personal-information' %}. - -In case you prefer to not follow any email links, due to phishing -considerations, please just go to the datatracker and use the menu -entries to log in or create an account. The links above are provided -for your convenience, but it works just as well to go the datracker -manually and do what's needed. - -Please note that you cannot give consent simply by replying to this email; -you must log in to your account and do so there. - - -Thank You, -The IETF Secretariat -{% endfilter %} diff --git a/ietf/urls.py b/ietf/urls.py index e5ba86d8ebe..e822b2042ef 100644 --- a/ietf/urls.py +++ b/ietf/urls.py @@ -1,28 +1,25 @@ # Copyright The IETF Trust 2007-2022, All Rights Reserved from django.conf import settings -from django.conf.urls import include from django.conf.urls.static import static as static_url from django.contrib import admin from django.contrib.sitemaps import views as sitemap_views from django.contrib.staticfiles.urls import staticfiles_urlpatterns +from django.http import HttpResponse +from django.urls import include, path from django.views import static as static_view from django.views.generic import TemplateView from django.views.defaults import server_error -from django.urls import path import debug # pyflakes:ignore from ietf.doc import views_search from ietf.group.urls import group_urls, grouptype_urls, stream_urls -from ietf.help import views as help_views from ietf.ipr.sitemaps import IPRMap from ietf.liaisons.sitemaps import LiaisonMap from ietf.utils.urls import url -admin.autodiscover() - # sometimes, this code gets called more than once, which is an # that seems impossible to work around. try: @@ -37,6 +34,7 @@ urlpatterns = [ url(r'^$', views_search.frontpage), + url(r'^health/', lambda _: HttpResponse()), url(r'^accounts/', include('ietf.ietfauth.urls')), url(r'^admin/', admin.site.urls), url(r'^admin/docs/', include('django.contrib.admindocs.urls')), @@ -63,11 +61,12 @@ url(r'^sitemap-(?P
    .+).xml$', sitemap_views.sitemap, {'sitemaps': sitemaps}), url(r'^sitemap.xml$', sitemap_views.index, { 'sitemaps': sitemaps}), url(r'^stats/', include('ietf.stats.urls')), + url(r'^status/', include('ietf.status.urls')), url(r'^stream/', include(stream_urls)), url(r'^submit/', include('ietf.submit.urls')), url(r'^sync/', include('ietf.sync.urls')), url(r'^templates/', include('ietf.dbtemplate.urls')), - url(r'^(?P(wg|rg|ag|rag|team|dir|review|area|program|iabasg|adhoc|ise|adm|rfcedtyp))/', include(grouptype_urls)), + url(r'^(?P(wg|rg|ag|rag|team|dir|review|area|program|iabasg|iabworkshop|adhoc|ise|adm|rfcedtyp|edwg|edappr))/', include(grouptype_urls)), # Redirects url(r'^(?Ppublic)/', include('ietf.redirects.urls')), @@ -86,7 +85,6 @@ urlpatterns += staticfiles_urlpatterns() urlpatterns += [ url(r'^_test500/$', server_error), #utils_views.exception), - url(r'^environment/$', help_views.environment), ## maybe preserve some static legacy URLs ? url(r'^(?P(?:images|css|js)/.*)$', static_view.serve, {'document_root': settings.STATIC_ROOT+'ietf/'}), ] diff --git a/ietf/utils/.gitignore b/ietf/utils/.gitignore deleted file mode 100644 index ba8bdb3afc4..00000000000 --- a/ietf/utils/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -/*.pyc -/*.swp diff --git a/ietf/utils/__init__.py b/ietf/utils/__init__.py index 7f1df976025..fbe55eb0434 100644 --- a/ietf/utils/__init__.py +++ b/ietf/utils/__init__.py @@ -1 +1,29 @@ -# Copyright The IETF Trust 2007, All Rights Reserved +# Copyright The IETF Trust 2007-2024, All Rights Reserved +import subprocess + + +class _ToolVersionManager: + _known = [ + "pyang", + "xml2rfc", + "xym", + "yanglint", + ] + _versions: dict[str, str] = dict() + + def __getitem__(self, item): + if item not in self._known: + return "Unknown" + elif item not in self._versions: + try: + self._versions[item] = subprocess.run( + [item, "--version"], + capture_output=True, + check=True, + ).stdout.decode().strip() + except subprocess.CalledProcessError: + return "Unknown" + return self._versions[item] + + +tool_version = _ToolVersionManager() diff --git a/ietf/utils/accesstoken.py b/ietf/utils/accesstoken.py index b2a93f77d4c..243d3f24ddb 100644 --- a/ietf/utils/accesstoken.py +++ b/ietf/utils/accesstoken.py @@ -5,7 +5,7 @@ import time, random, hashlib from django.conf import settings -from django.utils.encoding import force_bytes, force_text +from django.utils.encoding import force_bytes, force_str def generate_random_key(max_length=32): @@ -18,4 +18,4 @@ def generate_access_token(key, max_length=32): # we hash it with the private key to make sure only we can # generate and use the final token - so storing the key in the # database is safe - return force_text(hashlib.sha256(force_bytes(settings.SECRET_KEY) + force_bytes(key)).hexdigest()[:max_length]) + return force_str(hashlib.sha256(force_bytes(settings.SECRET_KEY) + force_bytes(key)).hexdigest()[:max_length]) diff --git a/ietf/utils/admin.py b/ietf/utils/admin.py index 3e562c2bc1b..cb8841cdc67 100644 --- a/ietf/utils/admin.py +++ b/ietf/utils/admin.py @@ -1,65 +1,30 @@ -# Copyright The IETF Trust 2011-2020, All Rights Reserved -# -*- coding: utf-8 -*- +# Copyright The IETF Trust 2011-2026, All Rights Reserved from django.contrib import admin -from django.utils.encoding import force_text +from .models import DumpInfo, DirtyBits -from ietf.utils.models import VersionInfo -def name(obj): - if hasattr(obj, 'abbrev'): - return obj.abbrev() - elif hasattr(obj, 'name'): - if callable(obj.name): - name = obj.name() - else: - name = force_text(obj.name) - if name: - return name - return str(obj) - -def admin_link(field, label=None, ordering="", display=name, suffix=""): - if not label: - label = field.capitalize().replace("_", " ").strip() - if ordering == "": - ordering = field - def _link(self): - obj = self - for attr in field.split("__"): - obj = getattr(obj, attr) - if callable(obj): - obj = obj() - if hasattr(obj, "all"): - objects = obj.all() - elif callable(obj): - objects = obj() - if not hasattr(objects, "__iter__"): - objects = [ objects ] - elif hasattr(obj, "__iter__"): - objects = obj - else: - objects = [ obj ] - chunks = [] - for obj in objects: - app = obj._meta.app_label - model = obj.__class__.__name__.lower() - id = obj.pk - chunks += [ '%(display)s' % - {'app':app, "model": model, "id":id, "display": display(obj), "suffix":suffix, } ] - return ", ".join(chunks) - _link.allow_tags = True - _link.short_description = label - _link.admin_order_field = ordering - return _link +class SaferStackedInline(admin.StackedInline): + """StackedInline without delete by default""" -from .models import DumpInfo + can_delete = False # no delete button + show_change_link = True # show a link to the resource (where it can be deleted) + + +class SaferTabularInline(admin.TabularInline): + """TabularInline without delete by default""" + + can_delete = False # no delete button + show_change_link = True # show a link to the resource (where it can be deleted) + + +@admin.register(DumpInfo) class DumpInfoAdmin(admin.ModelAdmin): - list_display = ['date', 'host', 'tz'] - list_filter = ['date'] -admin.site.register(DumpInfo, DumpInfoAdmin) + list_display = ["date", "host", "tz"] + list_filter = ["date"] -class VersionInfoAdmin(admin.ModelAdmin): - list_display = ['command', 'switch', 'version', 'time', ] -admin.site.register(VersionInfo, VersionInfoAdmin) +@admin.register(DirtyBits) +class DirtyBitsAdmin(admin.ModelAdmin): + list_display = ["slug", "dirty_time", "processed_time"] diff --git a/ietf/utils/aiosmtpd.py b/ietf/utils/aiosmtpd.py new file mode 100644 index 00000000000..3e4cd65dd99 --- /dev/null +++ b/ietf/utils/aiosmtpd.py @@ -0,0 +1,73 @@ +# Copyright The IETF Trust 2014-2025, All Rights Reserved +"""aiosmtpd-related utilities + +These are for testing / dev use. If you're using this for production code, think very +hard about the choices you're making... +""" +from aiosmtpd import handlers +from aiosmtpd.controller import Controller +from aiosmtpd.smtp import SMTP +from email.utils import parseaddr +from typing import Optional, TextIO + + +class SMTPTestHandler: + + def __init__(self, inbox: list): + self.inbox = inbox + + async def handle_DATA(self, server, session, envelope): + """Handle the DATA command and 'deliver' the message""" + + self.inbox.append(envelope.content) + # Per RFC2033: https://datatracker.ietf.org/doc/html/rfc2033.html#section-4.2 + # ...after the final ".", the server returns one reply + # for each previously successful RCPT command in the mail transaction, + # in the order that the RCPT commands were issued. Even if there were + # multiple successful RCPT commands giving the same forward-path, there + # must be one reply for each successful RCPT command. + return "\n".join("250 OK" for _ in envelope.rcpt_tos) + + async def handle_RCPT(self, server, session, envelope, address, rcpt_options): + """Handle an RCPT command and add the address to the envelope if it is acceptable""" + _, address = parseaddr(address) + if address == "": + return "501 Syntax: RCPT TO:
    " + if "poison" in address: + return "550 Error: Not touching that" + # At this point the address is acceptable + envelope.rcpt_tos.append(address) + return "250 OK" + + +class SMTPTestServerDriver: + + def __init__(self, address: str, port: int, inbox: Optional[list] = None): + # Allow longer lines than the 1001 that RFC 5321 requires. As of 2025-04-16 the + # datatracker emits some non-compliant messages. + # See https://aiosmtpd.aio-libs.org/en/latest/smtp.html + SMTP.line_length_limit = 4000 # tests start failing between 3000 and 4000 + self.controller = Controller( + hostname=address, + port=port, + handler=SMTPTestHandler(inbox=[] if inbox is None else inbox), + ) + + def start(self): + self.controller.start() + + def stop(self): + self.controller.stop() + + +class DevDebuggingHandler(handlers.Debugging): + """Debugging handler for use in dev ONLY""" + def __init__(self, stream: Optional[TextIO] = None): + # Allow longer lines than the 1001 that RFC 5321 requires. As of 2025-04-16 the + # datatracker emits some non-compliant messages. + # See https://aiosmtpd.aio-libs.org/en/latest/smtp.html + # Doing this in a handler class is a huge hack. Tests all pass with this set + # to 4000, but make the limit longer for dev just in case. + SMTP.line_length_limit = 10000 + super().__init__(stream) + diff --git a/ietf/utils/aliases.py b/ietf/utils/aliases.py deleted file mode 100644 index 9f9aebc0b9a..00000000000 --- a/ietf/utils/aliases.py +++ /dev/null @@ -1,82 +0,0 @@ -#!/usr/bin/env python -# Copyright The IETF Trust 2013-2020, All Rights Reserved -# -*- coding: utf-8 -*- -# -*- Python -*- -# -# $Id: aliasutil.py $ -# -# Author: Markus Stenberg -# - - -""" - -Mailing list alias dumping utilities - -""" - - -from django.conf import settings -from ietf.utils.log import log - -import debug # pyflakes:ignore - -def rewrite_email_address(email): - """ Prettify the email address (and if it's empty, skip it by - returning None). """ - if not email: - return - email = email.strip() - if not email: - return - if email[0]=='<' and email[-1] == '>': - email = email[1:-1] - # If it doesn't look like email, skip - if '@' not in email and '?' not in email: - return - return email - -def rewrite_address_list(l): - """ This utility function makes sure there is exactly one instance - of an address within the result list, and preserves order - (although it may not be relevant to start with) """ - h = {} - for address in l: - #address = address.strip() - if address in h: continue - h[address] = True - yield address - -def dump_sublist(afile, vfile, alias, adomains, vdomain, emails): - if not emails: - return emails - # Nones in the list should be skipped - emails = [_f for _f in emails if _f] - - # Make sure emails are sane and eliminate the Nones again for - # non-sane ones - emails = [rewrite_email_address(e) for e in emails] - emails = [_f for _f in emails if _f] - - # And we'll eliminate the duplicates too but preserve order - emails = list(rewrite_address_list(emails)) - if not emails: - return emails - try: - filtername = 'xfilter-%s' % (alias, ) # in aliases, --> | expandname - expandname = 'expand-%s' % (alias, ) # in virtual, --> email list - - for domain in adomains: - aliasaddr = '%s@%s' % (alias, domain) # in virtual, --> filtername - vfile.write('%-64s %s\n' % (aliasaddr, filtername)) - afile.write('%-64s "|%s filter %s %s"\n' % (filtername+':', settings.POSTCONFIRM_PATH, expandname, vdomain)) - vfile.write('%-64s %s\n' % ("%s@%s"%(expandname, vdomain), ', '.join(emails))) - - except UnicodeEncodeError: - # If there's unicode in email address, something is badly - # wrong and we just silently punt - # XXX - is there better approach? - log('Error encoding email address for an %s alias: %s' % (alias, repr(emails))) - return [] - return emails - diff --git a/ietf/utils/cache.py b/ietf/utils/cache.py new file mode 100644 index 00000000000..0baa56da2da --- /dev/null +++ b/ietf/utils/cache.py @@ -0,0 +1,20 @@ +# Copyright The IETF Trust 2023, All Rights Reserved +# -*- coding: utf-8 -*- + +from django.core.cache.backends.base import DEFAULT_TIMEOUT +from django.core.cache.backends.memcached import PyMemcacheCache +from pymemcache.exceptions import MemcacheServerError + +from .log import log + + +class LenientMemcacheCache(PyMemcacheCache): + """PyMemcacheCache backend that tolerates failed inserts due to object size""" + def set(self, key, value, timeout=DEFAULT_TIMEOUT, version=None): + try: + super().set(key, value, timeout, version) + except MemcacheServerError as err: + if "object too large for cache" in str(err): + log(f"Memcache failed to cache large object for {key}") + else: + raise diff --git a/ietf/utils/coverage.py b/ietf/utils/coverage.py new file mode 100644 index 00000000000..bd205ce5867 --- /dev/null +++ b/ietf/utils/coverage.py @@ -0,0 +1,90 @@ +# Copyright The IETF Trust 2025, All Rights Reserved +from coverage import Coverage, CoverageData, FileReporter +from coverage.control import override_config as override_coverage_config +from coverage.results import Numbers +from coverage.report_core import get_analysis_to_report +from coverage.results import Analysis +from django.conf import settings + + +class CoverageManager: + checker: Coverage | None = None + started = False + + def start(self): + if settings.SERVER_MODE != "production" and not self.started: + self.checker = Coverage( + source=[settings.BASE_DIR], + cover_pylib=False, + omit=settings.TEST_CODE_COVERAGE_EXCLUDE_FILES, + ) + for exclude_regex in getattr( + settings, + "TEST_CODE_COVERAGE_EXCLUDE_LINES", + [], + ): + self.checker.exclude(exclude_regex) + self.checker.start() + self.started = True + + def stop(self): + if self.checker is not None: + self.checker.stop() + + def save(self): + if self.checker is not None: + self.checker.save() + + def report(self, include: list[str] | None = None): + if self.checker is None: + return None + reporter = CustomDictReporter() + with override_coverage_config( + self.checker, + report_include=include, + ): + return reporter.report(self.checker) + + +class CustomDictReporter: # pragma: no cover + total = Numbers() + + def report(self, coverage): + coverage_data = coverage.get_data() + coverage_data.set_query_contexts(None) + measured_files = {} + for file_reporter, analysis in get_analysis_to_report(coverage, None): + measured_files[file_reporter.relative_filename()] = self.report_one_file( + coverage_data, + analysis, + file_reporter, + ) + tot_numer, tot_denom = self.total.ratio_covered + return { + "coverage": 1 if tot_denom == 0 else tot_numer / tot_denom, + "covered": measured_files, + "format": 5, + } + + def report_one_file( + self, + coverage_data: CoverageData, + analysis: Analysis, + file_reporter: FileReporter, + ): + """Extract the relevant report data for a single file.""" + nums = analysis.numbers + self.total += nums + n_statements = nums.n_statements + numer, denom = nums.ratio_covered + fraction_covered = 1 if denom == 0 else numer / denom + missing_line_nums = sorted(analysis.missing) + # Extract missing lines from source files + source_lines = file_reporter.source().splitlines() + missing_lines = [source_lines[num - 1] for num in missing_line_nums] + return ( + n_statements, + fraction_covered, + missing_line_nums, + missing_lines, + ) diff --git a/ietf/utils/crawlurls.txt b/ietf/utils/crawlurls.txt deleted file mode 100644 index 30a1d038b9e..00000000000 --- a/ietf/utils/crawlurls.txt +++ /dev/null @@ -1,18 +0,0 @@ -# List of starting points for the test crawler (see -# bin/run-real-data-tests). Add URLs that have no link from inside the -# project. - -/ -/doc/all/ -/doc/iesg/last-call/ -/doc/in-last-call/ -/iesg/decisions/ -/iesg/agenda/documents.txt -/iesg/agenda/agenda.json -/wg/1wg-summary.txt -/wg/1wg-summary-by-acronym.txt -/wg/1wg-charters.txt -/wg/1wg-charters-by-acronym.txt -/sitemap.xml -/sitemap-ipr.xml -/sitemap-liaison.xml \ No newline at end of file diff --git a/ietf/utils/db.py b/ietf/utils/db.py index d451f6cfd86..49c89da13ac 100644 --- a/ietf/utils/db.py +++ b/ietf/utils/db.py @@ -1,28 +1,67 @@ -# Copyright The IETF Trust 2021, All Rights Reserved -# -*- coding: utf-8 -*- - -# Taken from/inspired by -# https://stackoverflow.com/questions/55147169/django-admin-jsonfield-default-empty-dict-wont-save-in-admin -# -# JSONField should recognize {}, (), and [] as valid, non-empty JSON -# values. However, the base Field class excludes them +# Copyright The IETF Trust 2021-2025, All Rights Reserved + import jsonfield +from django.db import models + +from ietf.utils.fields import ( + IETFJSONField as FormIETFJSONField, + EmptyAwareJSONField as FormEmptyAwareJSONField, +) + + +class EmptyAwareJSONField(models.JSONField): + """JSONField that allows empty JSON values when model specifies empty=False + + Taken from/inspired by + https://stackoverflow.com/questions/55147169/django-admin-jsonfield-default-empty-dict-wont-save-in-admin + + JSONField should recognize {}, (), and [] as valid, non-empty JSON values. -from ietf.utils.fields import IETFJSONField as FormIETFJSONField + If customizing the formfield, the field must accept the `empty_values` argument. + """ + + def __init__( + self, + *args, + empty_values=FormEmptyAwareJSONField.empty_values, + accepted_empty_values=None, + **kwargs, + ): + if accepted_empty_values is None: + accepted_empty_values = [] + self.empty_values = [x for x in empty_values if x not in accepted_empty_values] + super().__init__(*args, **kwargs) + + def formfield(self, **kwargs): + defaults = { + "form_class": FormEmptyAwareJSONField, + "empty_values": self.empty_values, + } + defaults.update(kwargs) + return super().formfield(**defaults) -class IETFJSONField(jsonfield.JSONField): +class IETFJSONField(jsonfield.JSONField): # pragma: no cover + # Deprecated - use EmptyAwareJSONField instead (different base class requires a + # new field name) + # Remove this class when migrations are squashed and it is no longer referenced form_class = FormIETFJSONField - def __init__(self, *args, empty_values=FormIETFJSONField.empty_values, accepted_empty_values=None, **kwargs): + def __init__( + self, + *args, + empty_values=FormIETFJSONField.empty_values, + accepted_empty_values=None, + **kwargs, + ): if accepted_empty_values is None: accepted_empty_values = [] - self.empty_values = [x - for x in empty_values - if x not in accepted_empty_values] + self.empty_values = [x for x in empty_values if x not in accepted_empty_values] super().__init__(*args, **kwargs) def formfield(self, **kwargs): - if 'form_class' not in kwargs or issubclass(kwargs['form_class'], FormIETFJSONField): - kwargs.setdefault('empty_values', self.empty_values) + if "form_class" not in kwargs or issubclass( + kwargs["form_class"], FormIETFJSONField + ): + kwargs.setdefault("empty_values", self.empty_values) return super().formfield(**{**kwargs}) diff --git a/ietf/utils/decorators.py b/ietf/utils/decorators.py index 694e989f835..b50e0e7f96d 100644 --- a/ietf/utils/decorators.py +++ b/ietf/utils/decorators.py @@ -4,109 +4,133 @@ import datetime -from decorator import decorator, decorate +from functools import wraps from django.conf import settings from django.contrib.auth import login from django.http import HttpResponse from django.shortcuts import render +from django.utils import timezone from django.utils.encoding import force_bytes import debug # pyflakes:ignore -from ietf.utils.test_runner import set_coverage_checking from ietf.person.models import Person, PersonalApiKey, PersonApiKeyEvent from ietf.utils import log -@decorator -def skip_coverage(f, *args, **kwargs): - if settings.TEST_CODE_COVERAGE_CHECKER: - set_coverage_checking(False) - result = f(*args, **kwargs) - set_coverage_checking(True) - return result - else: - return f(*args, **kwargs) - -@decorator -def person_required(f, request, *args, **kwargs): - if not request.user.is_authenticated: - raise ValueError("The @person_required decorator should be called after @login_required.") - try: - request.user.person - except Person.DoesNotExist: - return render(request, 'registration/missing_person.html') - return f(request, *args, **kwargs) - -@decorator -def require_api_key(f, request, *args, **kwargs): - - def err(code, text): - return HttpResponse(text, status=code, content_type='text/plain') - # Check method and get hash - if request.method == 'POST': - hash = request.POST.get('apikey') - elif request.method == 'GET': - hash = request.GET.get('apikey') - else: - return err(405, "Method not allowed") - if not hash: - return err(400, "Missing apikey parameter") - # Check hash - key = PersonalApiKey.validate_key(force_bytes(hash)) - if not key: - return err(403, "Invalid apikey") - # Check endpoint - urlpath = request.META.get('PATH_INFO') - if not (urlpath and urlpath == key.endpoint): - return err(400, "Apikey endpoint mismatch") - # Check time since regular login - person = key.person - last_login = person.user.last_login - if not person.user.is_staff: - time_limit = (datetime.datetime.now() - datetime.timedelta(days=settings.UTILS_APIKEY_GUI_LOGIN_LIMIT_DAYS)) - if last_login == None or last_login < time_limit: - return err(400, "Too long since last regular login") - # Log in - login(request, person.user) - # restore the user.last_login field, so it reflects only gui logins - person.user.last_login = last_login - person.user.save() - # Update stats - key.count += 1 - key.latest = datetime.datetime.now() - key.save() - PersonApiKeyEvent.objects.create(person=person, type='apikey_login', key=key, desc="Logged in with key ID %s, endpoint %s" % (key.id, key.endpoint)) - # Execute decorated function - try: - ret = f(request, *args, **kwargs) - except AttributeError as e: - log.log("Bad API call: args: %s, kwargs: %s, exception: %s" % (args, kwargs, e)) - return err(400, "Bad or missing parameters") - return ret - - -def _memoize(func, self, *args, **kwargs): - ''''Memoize wrapper for instance methouds. Use @lru_cache for functions.''' - if kwargs: # frozenset is used to ensure hashability - key = args, frozenset(list(kwargs.items())) - else: - key = args - # instance method, set up cache if needed - if not hasattr(self, '_cache'): - self._cache = {} - if not func in self._cache: - self._cache[func] = {} - # - cache = self._cache[func] - if key not in cache: - cache[key] = func(self, *args, **kwargs) - return cache[key] + +def person_required(f): + @wraps(f) + def _wrapper(request, *args, **kwargs): + if not request.user.is_authenticated: + raise ValueError("The @person_required decorator should be called after @login_required.") + try: + request.user.person + except Person.DoesNotExist: + return render(request, 'registration/missing_person.html') + return f(request, *args, **kwargs) + return _wrapper + + +def require_api_key(f): + @wraps(f) + def _wrapper(request, *args, **kwargs): + def err(code, text): + return HttpResponse(text, status=code, content_type=f"text/plain; charset={settings.DEFAULT_CHARSET}") + # Check method and get hash + if request.method == 'POST': + hash = request.POST.get('apikey') + elif request.method == 'GET': + hash = request.GET.get('apikey') + else: + return err(405, "Method not allowed") + if not hash: + return err(400, "Missing apikey parameter") + # Check hash + key = PersonalApiKey.validate_key(force_bytes(hash)) + if not key: + return err(403, "Invalid apikey") + # Check endpoint + urlpath = request.META.get('PATH_INFO') + if not (urlpath and urlpath == key.endpoint): + return err(400, "Apikey endpoint mismatch") + # Check time since regular login + person = key.person + last_login = person.user.last_login + if not person.user.is_staff: + time_limit = (timezone.now() - datetime.timedelta(days=settings.UTILS_APIKEY_GUI_LOGIN_LIMIT_DAYS)) + if last_login == None or last_login < time_limit: + return err(400, "Too long since last regular login") + # Log in + login(request, person.user) + # restore the user.last_login field, so it reflects only gui logins + person.user.last_login = last_login + person.user.save() + # Update stats + key.count += 1 + key.latest = timezone.now() + key.save() + PersonApiKeyEvent.objects.create(person=person, type='apikey_login', key=key, desc="Logged in with key ID %s, endpoint %s" % (key.id, key.endpoint)) + # Execute decorated function + try: + ret = f(request, *args, **kwargs) + except AttributeError as e: + log.log("Bad API call: args: %s, kwargs: %s, exception: %s" % (args, kwargs, e)) + return err(400, "Bad or missing parameters") + return ret + return _wrapper + + def memoize(func): + @wraps(func) + def _memoize(self, *args, **kwargs): + '''Memoize wrapper for instance methods. Use @lru_cache for functions.''' + if kwargs: # frozenset is used to ensure hashability + key = args, frozenset(list(kwargs.items())) + else: + key = args + # instance method, set up cache if needed + if not hasattr(self, '_cache'): + self._cache = {} + if not func in self._cache: + self._cache[func] = {} + # + cache = self._cache[func] + if key not in cache: + cache[key] = func(self, *args, **kwargs) + return cache[key] + if not hasattr(func, '__class__'): - raise NotImplementedError("Use @lru_cache instead of memoize() for funcitons.") + raise NotImplementedError("Use @lru_cache instead of memoize() for functions.") # For methods, we want the cache on the object, not on the class, in order # to not having to think about cache bloat and content becoming stale, so # we cannot set up the cache here. - return decorate(func, _memoize) + return _memoize + + +def ignore_view_kwargs(*args): + """Ignore the specified kwargs if they are present + + Usage: + @ignore_view_kwargs("ignore_arg1", "ignore_arg2") + def my_view(request, good_arg): + ... + + This will allow my_view() to be used in url() paths that have zero, one, or both of + ignore_arg1 and ignore_arg2 captured. These will be ignored, while good_arg will still + be captured as usual. + """ + kwargs_to_ignore = args + + def decorate(view): + @wraps(view) + def wrapped(*args, **kwargs): + for kwarg in kwargs_to_ignore: + kwargs.pop(kwarg, None) + return view(*args, **kwargs) + + return wrapped + + return decorate + diff --git a/ietf/utils/draft.py b/ietf/utils/draft.py index 64f5c6b05e8..53d3d40811c 100755 --- a/ietf/utils/draft.py +++ b/ietf/utils/draft.py @@ -13,7 +13,7 @@ DESCRIPTION Extract information about authors' names and email addresses, - intended status and number of pages from Internet Drafts. + intended status and number of pages from Internet-Drafts. The information is emitted in the form of a line containing xml-style attributes, prefixed with the name of the draft. @@ -50,6 +50,9 @@ from typing import Dict, List # pyflakes:ignore +from .timezone import date_today + + version = "0.35" program = os.path.basename(sys.argv[0]) progdir = os.path.dirname(sys.argv[0]) @@ -62,7 +65,6 @@ opt_debug = False opt_timestamp = False opt_trace = False -opt_authorinfo = False opt_attributes = False # Don't forget to add the option variable to the globals list in _main below @@ -128,6 +130,24 @@ def acronym_match(s, l): #_debug(" s:%s; l:%s => %s; %s" % (s, l, acronym, s==acronym)) return s == acronym +def get_status_from_draft_text(text): + + # Take prefix to shortcut work over very large drafts + # 5000 is conservatively much more than a full page of characters and we + # only want the first 10 lines. + text = text.strip()[:5000] # Take prefix to shortcut work over very large drafts + text = re.sub(".\x08", "", text) # Get rid of inkribbon backspace-emphasis + text = text.replace("\r\n", "\n") # Convert DOS to unix + text = text.replace("\r", "\n") # Convert MAC to unix + lines = text.split("\n")[:10] + status = None + for line in lines: + status_match = re.search(r"^\s*Intended [Ss]tatus:\s*(.*?) ", line) + if status_match: + status = status_match.group(1) + break + return status + class Draft: """Base class for drafts @@ -142,12 +162,28 @@ def get_abstract(self): raise NotImplementedError def get_author_list(self): + """Get detailed author list + + Returns a list of dicts with the following keys: + full_name, first_name, middle_initial, last_name, + name_suffix, email, country, company + Values will be None if not available + """ raise NotImplementedError def get_authors(self): + """Get simple author list + + Get as list of strings with author name and email within angle brackets + """ raise NotImplementedError def get_authors_with_firm(self): + """Get simple list of authors with firm (company) info + + Get as list of strings with author name and email within angle brackets and + company in parentheses + """ raise NotImplementedError def get_creation_date(self): @@ -170,7 +206,7 @@ def get_title(self): def get_wordcount(self): raise NotImplementedError - + # ---------------------------------------------------------------------- class PlaintextDraft(Draft): @@ -184,7 +220,7 @@ def __init__(self, text, source, name_from_source=False): """ super().__init__() assert isinstance(text, str) - self.source = source + self.source = str(source) self.rawtext = text self.name_from_source = name_from_source @@ -451,7 +487,7 @@ def get_creation_date(self): month = int(mon) else: continue - today = datetime.date.today() + today = date_today() if day==0: # if the date was given with only month and year, use # today's date if month and year is today's month and @@ -513,13 +549,13 @@ def _check_abstract_indent(self, abstract, indent): indent_lines.append(indent) percents = {} total = float(len(indent_lines)) - formated = False + formatted = False for indent in set(indent_lines): count = indent_lines.count(indent)/total percents[indent] = count if count > 0.9: - formated = True - if not formated: + formatted = True + if not formatted: return abstract new_abstract = [] for line in abstract.split('\n'): @@ -558,6 +594,8 @@ def get_authors_with_firm(self): def get_author_list(self): # () -> List[List[str, str, str, str, str, str, str]] """Returns a list of tuples, with each tuple containing (given_names, surname, email, company). Email will be None if unknown. + + Todo update to agree with superclass method signature """ if self._author_info == None: self.extract_authors() @@ -571,8 +609,8 @@ def extract_authors(self): "honor" : r"(?:[A-Z]\.|Dr\.?|Dr\.-Ing\.|Prof(?:\.?|essor)|Sir|Lady|Dame|Sri)", "prefix": r"([Dd]e|Hadi|van|van de|van der|Ver|von|[Ee]l)", "suffix": r"(jr.?|Jr.?|II|2nd|III|3rd|IV|4th)", - "first" : r"([A-Z][-A-Za-z'`~]*)(( ?\([A-Z][-A-Za-z'`~]*\))?(\.?[- ]{1,2}[A-Za-z'`~]+)*)", - "last" : r"([-A-Za-z'`~]{2,})", + "first" : r"([A-Z][-A-Za-z'`~,]*)(( ?\([A-Z][-A-Za-z'`~,]*\))?(\.?[- ]{1,2}[A-Za-z'`~]+)*)", + "last" : r"([-A-Za-z'`~,]+)", # single-letter last names exist "months": r"(January|February|March|April|May|June|July|August|September|October|November|December)", "mabbr" : r"(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\.?", } @@ -608,6 +646,8 @@ def extract_authors(self): address_section = r"^ *([0-9]+\.)? *(Author|Editor)('s|s'|s|\(s\)) (Address|Addresses|Information)" + # "Internet Draft" (without the dash) is correct here, because the usage is to + # suppress incorrect author name extraction ignore = [ "Standards Track", "Current Practice", "Internet Draft", "Working Group", "Expiration Date", @@ -637,7 +677,12 @@ def dotexp(s): # permit insertion of middle names between first and last, and # add possible honorific and suffix information - authpat = r"(?:^| and )(?:%(hon)s ?)?(['`]*%(first)s\S*( +[^ ]+)* +%(last)s)( *\(.*|,( [A-Z][-A-Za-z0-9]*)?| %(suffix)s| [A-Z][a-z]+)?" % {"hon":hon, "first":first, "last":last, "suffix":suffix,} + if last: + authpat = r"(?:^| and )((?:%(hon)s ?)?['`]*%(first)s\S*( +[^ ]+)* +%(last)s(?: %(suffix)s)?)( *\(.*|,( [A-Z][-A-Za-z0-9]*)?| [A-Z][a-z]+)?" % {"hon":hon, "first":first, "last":last, "suffix":suffix,} + else: + # handle single-word names + authpat = r"(?:^| and )((?:%(hon)s ?)?['`]*%(first)s\S*( +[^ ]+)*(?: %(suffix)s)?)( *\(.*|,( [A-Z][-A-Za-z0-9]*)?| [A-Z][a-z]+)?" % {"hon":hon, "first":first, "suffix":suffix,} + return authpat authors = [] @@ -791,7 +836,7 @@ def dotexp(s): author = author[:-len(suffix)].strip() else: suffix = None - if "," in author: + if ", " in author: last, first = author.split(",",1) author = "%s %s" % (first.strip(), last.strip()) if not " " in author: @@ -799,8 +844,9 @@ def dotexp(s): first, last = author.rsplit(".", 1) first += "." else: - author = "[A-Z].+ " + author - first, last = author.rsplit(" ", 1) + # handle single-word names + first = author + last = "" else: if "." in author: first, last = author.rsplit(".", 1) @@ -878,10 +924,14 @@ def dotexp(s): #else: # fullname = author_match fullname = re.sub(" +", " ", fullname) - if left == firstname: - given_names, surname = fullname.rsplit(None, 1) + if re.search(r"\s", fullname): + if left == firstname: + given_names, surname = fullname.rsplit(None, 1) + else: + surname, given_names = fullname.split(None, 1) else: - surname, given_names = fullname.split(None, 1) + # handle single-word names + given_names, surname = (fullname, "") if " " in given_names: first, middle = given_names.split(None, 1) else: @@ -905,7 +955,7 @@ def dotexp(s): companies[i] = None break else: - _warn("Author tuple doesn't match text in draft: %s, %s" % (authors[i], fullname)) + _warn("Author tuple doesn't match text in Internet-Draft: %s, %s" % (authors[i], fullname)) authors[i] = None break except AssertionError: @@ -1235,7 +1285,7 @@ def getmeta(fn): fields["eventsource"] = "draft" if " " in fn or not fn.endswith(".txt"): - _warn("Skipping unexpected draft name: '%s'" % (fn)) + _warn("Skipping unexpected Internet-Draft name: '%s'" % (fn)) return {} if os.path.exists(fn): @@ -1281,8 +1331,6 @@ def getmeta(fn): # ---------------------------------------------------------------------- def _output(docname, fields, outfile=sys.stdout): - global company_domain - if opt_attributes: def outputkey(key, fields): field = fields[key] @@ -1322,9 +1370,8 @@ def _printmeta(fn, outfile=sys.stdout): # Main # ---------------------------------------------------------------------- -company_domain = {} # type: Dict[str, str] def _main(outfile=sys.stdout): - global opt_debug, opt_timestamp, opt_trace, opt_authorinfo, files, company_domain, opt_attributes + global opt_debug, opt_timestamp, opt_trace, files, opt_attributes # set default values, if any # ---------------------------------------------------------------------- # Option processing @@ -1372,13 +1419,11 @@ def _main(outfile=sys.stdout): elif opt in ["-T", "--trace"]: # Emit trace information while working opt_trace = True - company_domain = {} - if not files: files = [ "-" ] for file in files: - _debug( "Reading drafts from '%s'" % file) + _debug( "Reading Internet-Drafts from '%s'" % file) if file == "-": file = sys.stdin elif file.endswith(".gz"): diff --git a/ietf/utils/fields.py b/ietf/utils/fields.py index 15cd992c47d..6e8765612f8 100644 --- a/ietf/utils/fields.py +++ b/ietf/utils/fields.py @@ -1,12 +1,11 @@ -# Copyright The IETF Trust 2012-2020, All Rights Reserved +# Copyright The IETF Trust 2012-2025, All Rights Reserved # -*- coding: utf-8 -*- import datetime import json import re - -import jsonfield +from email.utils import parseaddr import debug # pyflakes:ignore @@ -14,10 +13,11 @@ from django import forms from django.db import models # pyflakes:ignore -from django.core.validators import validate_email +from django.core.validators import ProhibitNullCharactersValidator, validate_email from django.core.exceptions import ValidationError from django.utils.dateparse import parse_duration + class MultiEmailField(forms.Field): def to_python(self, value): "Normalize data to a list of strings." @@ -40,6 +40,25 @@ def validate(self, value): for email in value: validate_email(email) + +def validate_name_addr_email(value): + "Validate name-addr style email address" + name, addr = parseaddr(value) + if not addr: + raise ValidationError("Invalid email format.") + try: + validate_email(addr) # validate the actual address part + except ValidationError: + raise ValidationError("Invalid email address.") + + +class NameAddrEmailField(forms.CharField): + def validate(self, value): + "Check if value consists only of valid emails." + super().validate(value) + validate_name_addr_email(value) + + def yyyymmdd_to_strftime_format(fmt): translation_table = sorted([ ("yyyy", "%Y"), @@ -200,7 +219,7 @@ class SearchableField(forms.MultipleChoiceField): # model = None # must be filled in by subclass model = None # type:Optional[Type[models.Model]] # max_entries = None # may be overridden in __init__ - max_entries = None # type: Optional[int] + max_entries = None # type: Optional[int] min_search_length = None # type: Optional[int] default_hint_text = 'Type a value to search' @@ -284,7 +303,7 @@ def prepare_value(self, value): for d in pre: if isinstance(value, list): d["selected"] = any([v.pk == d["id"] for v in value]) - else: + elif value: d["selected"] = value.exists() and value.filter(pk__in=[d["id"]]).exists() self.widget.attrs["data-pre"] = json.dumps(list(pre)) @@ -320,9 +339,29 @@ def clean(self, pks): return objs.first() if self.max_entries == 1 else objs + def has_changed(self, initial, data): + # When max_entries == 1, we behave like a ChoiceField so initial will likely be a single + # value. Make it a list so MultipleChoiceField's has_changed() can work with it. + if initial is not None and self.max_entries == 1 and not isinstance(initial, (list, tuple)): + initial = [initial] + return super().has_changed(initial, data) -class IETFJSONField(jsonfield.fields.forms.JSONField): - def __init__(self, *args, empty_values=jsonfield.fields.forms.JSONField.empty_values, + +class IETFJSONField(forms.JSONField): # pragma: no cover + # Deprecated - use EmptyAwareJSONField instead + def __init__(self, *args, empty_values=forms.JSONField.empty_values, + accepted_empty_values=None, **kwargs): + if accepted_empty_values is None: + accepted_empty_values = [] + self.empty_values = [x + for x in empty_values + if x not in accepted_empty_values] + + super().__init__(*args, **kwargs) + + +class EmptyAwareJSONField(forms.JSONField): + def __init__(self, *args, empty_values=forms.JSONField.empty_values, accepted_empty_values=None, **kwargs): if accepted_empty_values is None: accepted_empty_values = [] @@ -346,3 +385,20 @@ def update_dimension_fields(self, *args, **kwargs): super().update_dimension_fields(*args, **kwargs) except FileNotFoundError: pass # don't do anything if the file has gone missing + + +class ModelMultipleChoiceField(forms.ModelMultipleChoiceField): + """ModelMultipleChoiceField that rejects null characters cleanly""" + validate_no_nulls = ProhibitNullCharactersValidator() + + def clean(self, value): + try: + for item in value: + self.validate_no_nulls(item) + except TypeError: + # A TypeError probably means value is not iterable, which most commonly comes up + # with None as a value. If it's something more exotic, we don't know how to test + # for null characters anyway. Either way, trust the superclass clean() method to + # handle it. + pass + return super().clean(value) diff --git a/ietf/utils/html.py b/ietf/utils/html.py index 9d0cd7c84fa..3f3efe2f371 100644 --- a/ietf/utils/html.py +++ b/ietf/utils/html.py @@ -5,11 +5,7 @@ import bleach -import copy import html2text -import lxml.etree -import lxml.html -import lxml.html.clean import debug # pyflakes:ignore @@ -17,62 +13,66 @@ from django.utils.functional import keep_lazy from ietf.utils.mime import get_mime_type -from ietf.utils.text import bleach_cleaner, tags as acceptable_tags -acceptable_protocols = ['http', 'https', 'mailto', 'xmpp', ] -def unescape(text): - """ - Returns the given text with ampersands, quotes and angle brackets decoded - for use in URLs. +# Allow the protocols/tags/attributes we specifically want, plus anything that bleach declares +# to be safe. As of 2025-01-27, the explicit lists for protocols and tags are a strict superset +# of bleach's defaults. +acceptable_protocols = bleach.sanitizer.ALLOWED_PROTOCOLS.union( + {"http", "https", "mailto", "ftp", "xmpp"} +) +acceptable_tags = bleach.sanitizer.ALLOWED_TAGS.union( + { + # fmt: off + "a", "abbr", "acronym", "address", "b", "big", + "blockquote", "body", "br", "caption", "center", "cite", "code", "col", + "colgroup", "dd", "del", "dfn", "dir", "div", "dl", "dt", "em", "font", + "h1", "h2", "h3", "h4", "h5", "h6", "head", "hr", "html", "i", "ins", "kbd", + "li", "ol", "p", "pre", "q", "s", "samp", "small", "span", "strike", "style", + "strong", "sub", "sup", "table", "title", "tbody", "td", "tfoot", "th", "thead", + "tr", "tt", "u", "ul", "var" + # fmt: on + } +) +acceptable_attributes = bleach.sanitizer.ALLOWED_ATTRIBUTES | { + "*": ["id"], + "ol": ["start"], +} + + +# Instantiate sanitizer classes +_bleach_cleaner = bleach.sanitizer.Cleaner( + tags=acceptable_tags, + attributes=acceptable_attributes, + protocols=acceptable_protocols, + strip=True, +) + + +_liberal_bleach_cleaner = bleach.sanitizer.Cleaner( + tags=acceptable_tags.union({"img", "figure", "figcaption"}), + attributes=acceptable_attributes | {"img": ["src", "alt"]}, + protocols=acceptable_protocols, + strip=True, +) + + +def clean_html(text: str): + """Clean the HTML in a string""" + return _bleach_cleaner.clean(text) + + +def liberal_clean_html(text: str): + """More permissively clean the HTML in a string""" + return _liberal_bleach_cleaner.clean(text) - This function undoes what django.utils.html.escape() does - """ - return text.replace('&', '&').replace(''', "'").replace('"', '"').replace('>', '>').replace('<', '<' ) @keep_lazy(str) def remove_tags(html, tags): """Returns the given HTML sanitized, and with the given tags removed.""" - allowed = set(acceptable_tags) - set([ t.lower() for t in tags ]) + allowed = acceptable_tags - set(t.lower() for t in tags) return bleach.clean(html, tags=allowed, strip=True) -# ---------------------------------------------------------------------- -# Html fragment cleaning - -def sanitize_fragment(html): - return bleach_cleaner.clean(html) - -# ---------------------------------------------------------------------- -# Page cleaning - - -class Cleaner(lxml.html.clean.Cleaner): - charset = 'utf-8' - def __init__(self, charset='utf-8', **kw): - self.charset = charset - super(Cleaner, self).__init__(**kw) - - # Copied from lxml 4.2.0 and modified to insert charset meta: - def clean_html(self, html): - result_type = type(html) - if isinstance(html, (str, bytes)): - doc = lxml.html.fromstring(html) - else: - doc = copy.deepcopy(html) - self(doc) - head = doc.find('head') - if head != None: - meta = lxml.etree.Element('meta', charset=self.charset) - meta.tail = '\n' - head.insert(0, meta) - return lxml.html._transform_result(result_type, doc) - -# We will be saving as utf-8 later, so set that in the meta tag. -lxml_cleaner = Cleaner(allow_tags=acceptable_tags, remove_unknown_tags=None, style=False, page_structure=False, charset='utf-8') - -def sanitize_document(html): - return lxml_cleaner.clean_html(html) - # ---------------------------------------------------------------------- # Text field cleaning @@ -86,4 +86,15 @@ def clean_text_field(text): else: raise forms.ValidationError("Unexpected text field mime type: %s" % mime_type) return text - + + +def unescape(text): + """ + Returns the given text with ampersands, quotes and angle brackets decoded + for use in URLs. + + This function undoes what django.utils.html.escape() does + """ + return text.replace('&', '&').replace(''', "'").replace('"', '"').replace('>', '>').replace('<', '<' ) + + diff --git a/ietf/utils/http.py b/ietf/utils/http.py new file mode 100644 index 00000000000..cda51680ab9 --- /dev/null +++ b/ietf/utils/http.py @@ -0,0 +1,34 @@ +# Copyright The IETF Trust 2023-2024, All Rights Reserved +# -*- coding: utf-8 -*- + +from django.urls import resolve as urlresolve, Resolver404 + +def is_ajax(request): + """Checks whether a request was an AJAX call + + See https://docs.djangoproject.com/en/3.1/releases/3.1/#id2 - this implements the + exact reproduction of the deprecated method suggested there. + """ + return request.headers.get("x-requested-with") == "XMLHttpRequest" + +def validate_return_to_path(path, get_default_path, allowed_path_handlers): + if path is None: + path = get_default_path() + + # we need to ensure the path isn't used for attacks (eg phishing). + # `path` can be used in HttpResponseRedirect() which could redirect to Datatracker or offsite. + # Eg http://datatracker.ietf.org/...?ballot_edit_return_point=https://example.com/phish + # offsite links could be phishing attempts so let's reject them all, and require valid Datatracker + # routes + try: + # urlresolve will throw if the url doesn't match a route known to Django + match = urlresolve(path) + # further restrict by whether it's in the list of valid routes to prevent + # (eg) redirecting to logout + if match.url_name not in allowed_path_handlers: + raise ValueError("Invalid return to path not among valid matches") + pass + except Resolver404: + raise ValueError("Invalid return to path doesn't match a route") + + return path diff --git a/ietf/utils/jsonlogger.py b/ietf/utils/jsonlogger.py new file mode 100644 index 00000000000..589132977d8 --- /dev/null +++ b/ietf/utils/jsonlogger.py @@ -0,0 +1,34 @@ +# Copyright The IETF Trust 2024, All Rights Reserved +from pythonjsonlogger.json import JsonFormatter +import time + + +class DatatrackerJsonFormatter(JsonFormatter): + converter = time.gmtime # use UTC + default_msec_format = "%s.%03d" # '.' instead of ',' + + +class GunicornRequestJsonFormatter(DatatrackerJsonFormatter): + """Only works with Gunicorn's logging""" + def add_fields(self, log_record, record, message_dict): + super().add_fields(log_record, record, message_dict) + log_record.setdefault("method", record.args["m"]) + log_record.setdefault("proto", record.args["H"]) + log_record.setdefault("remote_ip", record.args["h"]) + path = record.args["U"] # URL path + if record.args["q"]: # URL query string + path = "?".join([path, record.args["q"]]) + log_record.setdefault("path", path) + log_record.setdefault("status", record.args["s"]) + log_record.setdefault("referer", record.args["f"]) + log_record.setdefault("user_agent", record.args["a"]) + log_record.setdefault("len_bytes", record.args["B"]) + log_record.setdefault("duration_s", record.args["L"]) # decimal seconds + log_record.setdefault("host", record.args["{host}i"]) + log_record.setdefault("x_request_start", record.args["{x-request-start}i"]) + log_record.setdefault("x_forwarded_for", record.args["{x-forwarded-for}i"]) + log_record.setdefault("x_forwarded_proto", record.args["{x-forwarded-proto}i"]) + log_record.setdefault("cf_connecting_ip", record.args["{cf-connecting-ip}i"]) + log_record.setdefault("cf_ray", record.args["{cf-ray}i"]) + log_record.setdefault("asn", record.args["{x-ip-src-asnum}i"]) + log_record.setdefault("is_authenticated", record.args["{x-datatracker-is-authenticated}o"]) diff --git a/ietf/utils/jstest.py b/ietf/utils/jstest.py index 722b4058103..cf242fc4eb9 100644 --- a/ietf/utils/jstest.py +++ b/ietf/utils/jstest.py @@ -1,7 +1,10 @@ # Copyright The IETF Trust 2014-2021, All Rights Reserved # -*- coding: utf-8 -*- +import os + from django.conf import settings +from django.contrib.staticfiles.testing import StaticLiveServerTestCase from django.urls import reverse as urlreverse from unittest import skipIf @@ -9,19 +12,24 @@ skip_message = "" try: from selenium import webdriver - from selenium.webdriver.chrome.service import Service - from selenium.webdriver.chrome.options import Options + from selenium.webdriver.firefox.service import Service + from selenium.webdriver.firefox.options import Options + from selenium.webdriver.support.ui import WebDriverWait + from selenium.webdriver.support import expected_conditions from selenium.webdriver.common.by import By - from selenium.webdriver.common.desired_capabilities import DesiredCapabilities except ImportError as e: skip_selenium = True skip_message = "Skipping selenium tests: %s" % e from ietf.utils.pipe import pipe -from ietf.utils.test_runner import IetfLiveServerTestCase +from ietf.utils.test_runner import ( + set_template_coverage, + set_url_coverage, + load_and_run_fixtures, +) -executable_name = 'chromedriver' +executable_name = 'geckodriver' code, out, err = pipe('{} --version'.format(executable_name)) if code != 0: skip_selenium = True @@ -30,20 +38,11 @@ print(" "+skip_message) def start_web_driver(): - service = Service(executable_path="chromedriver", - log_path=settings.TEST_GHOSTDRIVER_LOG_PATH) - service.start() + service = Service(executable_path=f"/usr/bin/{executable_name}", log_output=f"{executable_name}.log", service_args=['--log-no-truncate']) options = Options() - options.add_argument("headless") - options.add_argument("disable-extensions") - options.add_argument("disable-gpu") # headless needs this - options.add_argument("no-sandbox") # docker needs this - dc = DesiredCapabilities.CHROME - dc["goog:loggingPrefs"] = {"browser": "ALL"} - # For selenium 3: - return webdriver.Chrome("chromedriver", options=options, desired_capabilities=dc) - # For selenium 4: - # return webdriver.Chrome(service=service, options=options, desired_capabilities=dc) + options.add_argument("--headless") + os.environ["MOZ_REMOTE_SETTINGS_DEVTOOLS"] = "1" + return webdriver.Firefox(service=service, options=options) def selenium_enabled(): @@ -56,17 +55,44 @@ def ifSeleniumEnabled(func): return skipIf(skip_selenium, skip_message)(func) -class IetfSeleniumTestCase(IetfLiveServerTestCase): +class IetfSeleniumTestCase(StaticLiveServerTestCase): # pragma: no cover login_view = 'ietf.ietfauth.views.login' + @classmethod + def setUpClass(cls): + set_template_coverage(False) + set_url_coverage(False) + super().setUpClass() + + @classmethod + def tearDownClass(cls): + super().tearDownClass() + set_template_coverage(True) + set_url_coverage(True) + def setUp(self): - super(IetfSeleniumTestCase, self).setUp() + super().setUp() + # LiveServerTestCase uses TransactionTestCase which seems to + # somehow interfere with the fixture loading process in + # IetfTestRunner when running multiple tests (the first test + # is fine, in the next ones the fixtures have been wiped) - + # this is no doubt solvable somehow, but until then we simply + # recreate them here + from ietf.person.models import Person + if not Person.objects.exists(): + load_and_run_fixtures(verbosity=0) + self.replaced_settings = dict() + if hasattr(settings, 'IDTRACKER_BASE_URL'): + self.replaced_settings['IDTRACKER_BASE_URL'] = settings.IDTRACKER_BASE_URL + settings.IDTRACKER_BASE_URL = self.live_server_url self.driver = start_web_driver() self.driver.set_window_size(1024,768) def tearDown(self): - super(IetfSeleniumTestCase, self).tearDown() self.driver.close() + for k, v in self.replaced_settings.items(): + setattr(settings, k, v) + super().tearDown() def absreverse(self,*args,**kwargs): return '%s%s'%(self.live_server_url, urlreverse(*args, **kwargs)) @@ -81,7 +107,7 @@ def login(self, username='plain'): self.driver.get(url) self.driver.find_element(By.NAME, 'username').send_keys(username) self.driver.find_element(By.NAME, 'password').send_keys(password) - self.driver.find_element(By.XPATH, '//button[@type="submit"]').click() + self.driver.find_element(By.XPATH, '//*[@id="content"]//button[@type="submit"]').click() def scroll_to_element(self, element): """Scroll an element into view""" @@ -96,6 +122,48 @@ def scroll_to_element(self, element): # actions = ActionChains(self.driver) # actions.move_to_element(element).perform() + def scroll_and_click(self, element_locator, timeout_seconds=5): + """ + Selenium has restrictions around clicking elements outside the viewport, so + this wrapper encapsulates the boilerplate of forcing scrolling and clicking. + + :param element_locator: A two item tuple of a Selenium locator eg `(By.CSS_SELECTOR, '#something')` + """ + + # so that we can restore the state of the webpage after clicking + original_html_scroll_behaviour_to_restore = self.driver.execute_script('return document.documentElement.style.scrollBehavior') + original_html_overflow_to_restore = self.driver.execute_script('return document.documentElement.style.overflow') + + original_body_scroll_behaviour_to_restore = self.driver.execute_script('return document.body.style.scrollBehavior') + original_body_overflow_to_restore = self.driver.execute_script('return document.body.style.overflow') + + self.driver.execute_script('document.documentElement.style.scrollBehavior = "auto"') + self.driver.execute_script('document.documentElement.style.overflow = "auto"') + + self.driver.execute_script('document.body.style.scrollBehavior = "auto"') + self.driver.execute_script('document.body.style.overflow = "auto"') + + element = self.driver.find_element(element_locator[0], element_locator[1]) + self.scroll_to_element(element) + + # Note that Selenium itself seems to have multiple definitions of 'clickable'. + # You might expect that the following wait for the 'element_to_be_clickable' + # would confirm that the following .click() would succeed but it doesn't. + # That's why the preceeding code attempts to force scrolling to bring the + # element into the viewport to allow clicking. + WebDriverWait(self.driver, timeout_seconds).until(expected_conditions.element_to_be_clickable(element_locator)) + + element.click() + + if original_html_scroll_behaviour_to_restore: + self.driver.execute_script(f'document.documentElement.style.scrollBehavior = "{original_html_scroll_behaviour_to_restore}"') + if original_html_overflow_to_restore: + self.driver.execute_script(f'document.documentElement.style.overflow = "{original_html_overflow_to_restore}"') + + if original_body_scroll_behaviour_to_restore: + self.driver.execute_script(f'document.body.style.scrollBehavior = "{original_body_scroll_behaviour_to_restore}"') + if original_body_overflow_to_restore: + self.driver.execute_script(f'document.body.style.overflow = "{original_body_overflow_to_restore}"') class presence_of_element_child_by_css_selector: """Wait for presence of a child of a WebElement matching a CSS selector @@ -108,4 +176,4 @@ def __init__(self, element, child_selector): def __call__(self, driver): child = self.element.find_element(By.CSS_SELECTOR, self.child_selector) - return child if child is not None else False \ No newline at end of file + return child if child is not None else False diff --git a/ietf/utils/log.py b/ietf/utils/log.py index d5a54e55168..2a068ade9af 100644 --- a/ietf/utils/log.py +++ b/ietf/utils/log.py @@ -9,37 +9,10 @@ import os.path import traceback -from typing import Callable # pyflakes:ignore - -try: - import syslog - logfunc = syslog.syslog # type: Callable -except ImportError: # import syslog will fail on Windows boxes - logging.basicConfig(filename='tracker.log',level=logging.INFO) - logfunc = logging.info - pass - from django.conf import settings import debug # pyflakes:ignore -formatter = logging.Formatter('{levelname}: {name}:{lineno}: {message}', style='{') -for name, level in settings.UTILS_LOGGER_LEVELS.items(): - logger = logging.getLogger(name) - if not logger.hasHandlers(): - debug.say(' Adding handlers to logger %s' % logger.name) - - handlers = [ - logging.StreamHandler(), - logging.handlers.SysLogHandler(address='/dev/log', - facility=logging.handlers.SysLogHandler.LOG_USER), - ] - for h in handlers: - h.setFormatter(formatter) - h.setLevel(level) - logger.addHandler(h) - debug.say(" Setting %s logging level to %s" % (logger.name, level)) - logger.setLevel(level) def getclass(frame): cls = None @@ -56,20 +29,9 @@ def getcaller(): return (pmodule, pclass, pfunction, pfile, pline) def log(msg, e=None): - "Uses syslog by preference. Logs the given calling point and message." - global logfunc - def _flushfunc(): - pass - _logfunc = logfunc - if settings.SERVER_MODE == 'test': - if getattr(settings, 'show_logging', False) is True: - _logfunc = debug.say - _flushfunc = sys.stdout.flush # pyflakes:ignore (intentional redefinition) - else: + "Logs the given calling point and message to the logging framework's datatracker handler at severity INFO" + if settings.SERVER_MODE == 'test' and not getattr(settings, 'show_logging',False): return - elif settings.DEBUG == True: - _logfunc = debug.say - _flushfunc = sys.stdout.flush # pyflakes:ignore (intentional redefinition) if not isinstance(msg, str): msg = msg.encode('unicode_escape') try: @@ -82,11 +44,8 @@ def _flushfunc(): where = " in " + func + "()" except IndexError: file, line, where = "/", 0, "" - _flushfunc() - _logfunc("ietf%s(%d)%s: %s" % (file, line, where, msg)) - -logger = logging.getLogger('django') + logging.getLogger("datatracker").info(msg=msg, extra = {"file":file, "line":line, "where":where}) def exc_parts(): @@ -124,6 +83,7 @@ def assertion(statement, state=True, note=None): This acts like an assertion. It uses the django logger in order to send the failed assertion and a backtrace as for an internal server error. """ + logger = logging.getLogger("django") # Note this is a change - before this would have gone to "django" frame = inspect.currentframe().f_back value = eval(statement, frame.f_globals, frame.f_locals) if bool(value) != bool(state): @@ -148,6 +108,7 @@ def assertion(statement, state=True, note=None): def unreachable(date="(unknown)"): "Raises an assertion or sends traceback to admins if executed." + logger = logging.getLogger("django") frame = inspect.currentframe().f_back if settings.DEBUG is True or settings.SERVER_MODE == 'test': raise AssertionError("Arrived at code in %s() which was marked unreachable on %s." % (frame.f_code.co_name, date)) diff --git a/ietf/utils/mail.py b/ietf/utils/mail.py index 45a145b30a3..54171614511 100644 --- a/ietf/utils/mail.py +++ b/ietf/utils/mail.py @@ -3,7 +3,6 @@ import copy -import datetime #import logging import re import smtplib @@ -20,14 +19,17 @@ from email.header import Header, decode_header from email import message_from_bytes, message_from_string from email import charset as Charset +from typing import Optional from django.conf import settings from django.contrib import messages from django.core.exceptions import ImproperlyConfigured, ValidationError from django.core.validators import validate_email +from django.http import HttpRequest from django.template.loader import render_to_string from django.template import Context,RequestContext -from django.utils.encoding import force_text, force_str, force_bytes +from django.utils import timezone +from django.utils.encoding import force_str, force_bytes import debug # pyflakes:ignore @@ -64,6 +66,18 @@ def add_headers(msg): msg['From'] = settings.DEFAULT_FROM_EMAIL return msg + +def decode_header_value(value: str) -> str: + """Decode a header value + + Easier-to-use wrapper around email.message.decode_header() + """ + return "".join( + part.decode(charset if charset else "utf-8") if isinstance(part, bytes) else part + for part, charset in decode_header(value) + ) + + class SMTPSomeRefusedRecipients(smtplib.SMTPException): def __init__(self, message, original_msg, refusals): @@ -92,7 +106,17 @@ def send_smtp(msg, bcc=None): ''' mark = time.time() add_headers(msg) - (fname, frm) = parseaddr(msg.get('From')) + # N.B. We have a disconnect with most of this code assuming a From header value will only + # have one address. + # The frm computed here is only used as the envelope from. + # Previous code simply ran `parseaddr(msg.get('From'))`, getting lucky if the string returned + # from the get had more than one address in it. Python 3.9.20 changes the behavior of parseaddr + # and that erroneous use of the function no longer gets lucky. + # For the short term, to match behavior to date as closely as possible, if we get a message + # that has multiple addresses in the From header, we will use the first for the envelope from + from_tuples = getaddresses(msg.get_all('From', [settings.DEFAULT_FROM_EMAIL])) + assertion('len(from_tuples)==1', note=f"send_smtp received multiple From addresses: {from_tuples}") + _ , frm = from_tuples[0] addrlist = msg.get_all('To') + msg.get_all('Cc', []) if bcc: addrlist += [bcc] @@ -137,7 +161,7 @@ def send_smtp(msg, bcc=None): server.quit() except smtplib.SMTPServerDisconnected: pass - subj = force_text(msg.get('Subject', '[no subject]')) + subj = force_str(msg.get('Subject', '[no subject]')) tau = time.time() - mark log("sent email (%.3fs) from '%s' to %s id %s subject '%s'" % (tau, frm, to, msg.get('Message-ID', ''), subj)) @@ -166,7 +190,7 @@ def copy_email(msg, to, toUser=False, originalBcc=None): # Overwrite the From: header, so that the copy from a development or # test server doesn't look like spam. new['From'] = settings.DEFAULT_FROM_EMAIL - new['Subject'] = '[Django %s] %s' % (settings.SERVER_MODE, force_text(msg.get('Subject', '[no subject]'))) + new['Subject'] = '[Django %s] %s' % (settings.SERVER_MODE, force_str(msg.get('Subject', '[no subject]'))) new['To'] = to send_smtp(new) @@ -192,7 +216,10 @@ def encode_message(txt): return MIMEText(txt.encode('utf-8'), 'plain', 'UTF-8') def send_mail_text(request, to, frm, subject, txt, cc=None, extra=None, toUser=False, bcc=None, copy=True, save=True): - """Send plain text message.""" + """Send plain text message. + + request can be None unless it is needed by the template + """ msg = encode_message(txt) return send_mail_mime(request, to, frm, subject, msg, cc, extra, toUser, bcc, copy=copy, save=save) @@ -238,8 +265,7 @@ def parseaddr(addr): """ - addr = ''.join( [ ( s.decode(m) if m else s.decode()) if isinstance(s, bytes) else s for (s,m) in decode_header(addr) ] ) - name, addr = simple_parseaddr(addr) + name, addr = simple_parseaddr(decode_header_value(addr)) return name, addr def excludeaddrs(addrlist, exlist): @@ -317,23 +343,50 @@ def condition_message(to, frm, subject, msg, cc, extra): msg['Message-ID'] = make_msgid() -def show_that_mail_was_sent(request,leadline,msg,bcc): - if request and request.user: - from ietf.ietfauth.utils import has_role - if has_role(request.user,['Area Director','Secretariat','IANA','RFC Editor','ISE','IAD','IRTF Chair','WG Chair','RG Chair','WG Secretary','RG Secretary']): - info = "%s at %s %s\n" % (leadline,datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"),settings.TIME_ZONE) - info += "Subject: %s\n" % force_text(msg.get('Subject','[no subject]')) - info += "To: %s\n" % msg.get('To','[no to]') - if msg.get('Cc'): - info += "Cc: %s\n" % msg.get('Cc') - if bcc: - info += "Bcc: %s\n" % bcc - messages.info(request,info,extra_tags='preformatted',fail_silently=True) +def show_that_mail_was_sent(request: HttpRequest, leadline: str, msg: Message, bcc: Optional[str]): + if request and request.user: + from ietf.ietfauth.utils import has_role + + if has_role( + request.user, + [ + "Area Director", + "Secretariat", + "IANA", + "RFC Editor", + "ISE", + "IAD", + "IRTF Chair", + "WG Chair", + "RG Chair", + "WG Secretary", + "RG Secretary", + ], + ): + subject = decode_header_value(msg.get("Subject", "[no subject]")) + _to = decode_header_value(msg.get("To", "[no to]")) + info_lines = [ + f"{leadline} at {timezone.now():%Y-%m-%d %H:%M:%S %Z}", + f"Subject: {subject}", + f"To: {_to}", + ] + cc = msg.get("Cc", None) + if cc: + info_lines.append(f"Cc: {decode_header_value(cc)}") + if bcc: + info_lines.append(f"Bcc: {decode_header_value(bcc)}") + messages.info( + request, + "\n".join(info_lines), + extra_tags="preformatted", + fail_silently=True, + ) + def save_as_message(request, msg, bcc): by = ((request and request.user and not request.user.is_anonymous and request.user.person) or ietf.person.models.Person.objects.get(name="(System)")) - headers, body = force_text(str(msg)).split('\n\n', 1) + headers, body = force_str(str(msg)).split('\n\n', 1) kwargs = {'by': by, 'body': body, 'content_type': msg.get_content_type(), 'bcc': bcc or '' } for (arg, field) in [ ('cc', 'Cc'), @@ -375,7 +428,7 @@ def send_mail_mime(request, to, frm, subject, msg, cc=None, extra=None, toUser=F try: send_smtp(msg, bcc) if save: - message.sent = datetime.datetime.now() + message.sent = timezone.now() message.save() if settings.SERVER_MODE != 'development': show_that_mail_was_sent(request,'Email was sent',msg,bcc) @@ -443,6 +496,8 @@ def parse_preformatted(preformatted, extra=None, override=None): values = msg.get_all(key, []) if values: values = getaddresses(values) + if key=='From': + assertion('len(values)<2', note=f'parse_preformatted is constructing a From with multiple values: {values}') del msg[key] msg[key] = ',\n '.join(formataddr(v) for v in values) for key in ['Subject', ]: @@ -502,7 +557,7 @@ def send_mail_message(request, message, extra=None): # msg = send_mail_text(request, message.to, message.frm, message.subject, # message.body, cc=message.cc, bcc=message.bcc, extra=e, save=False) - message.sent = datetime.datetime.now() + message.sent = timezone.now() message.save() return msg @@ -530,7 +585,7 @@ def log_smtp_exception(e): def build_warning_message(request, e): (extype, value, tb) = exception_components(e) if request: - warning = "An error occured while sending email:\n" + warning = "An error occurred while sending email:\n" if getattr(e,'original_msg',None): warning += "Subject: %s\n" % e.original_msg.get('Subject','[no subject]') warning += "To: %s\n" % e.original_msg.get('To','[no to]') diff --git a/ietf/utils/management/commands/check_draft_event_revision_integrity.py b/ietf/utils/management/commands/check_draft_event_revision_integrity.py index a4c38bd1c09..c2d42727823 100644 --- a/ietf/utils/management/commands/check_draft_event_revision_integrity.py +++ b/ietf/utils/management/commands/check_draft_event_revision_integrity.py @@ -13,6 +13,7 @@ django.setup() from django.core.management.base import BaseCommand #, CommandError +from django.utils import timezone import debug # pyflakes:ignore @@ -29,7 +30,7 @@ class Command(BaseCommand): """ def add_arguments(self, parser): - default_start = datetime.datetime.now() - datetime.timedelta(days=60) + default_start = timezone.now() - datetime.timedelta(days=60) parser.add_argument( '-d', '--from', type=str, default=default_start.strftime('%Y-%m-%d'), help='Limit the list to messages saved after the given date (default %(default)s).', @@ -53,7 +54,7 @@ def to_dict(instance): doc = getattr(obj, docattr) time = getattr(obj, timeattr) if not obj.rev: - if not doc.is_rfc(): + if doc.type_id != "rfc": self.stdout.write("Bad revision number: %-52s: '%s'" % (doc.name, obj.rev)) continue rev = int(obj.rev.lstrip('0') or '0') diff --git a/ietf/utils/management/commands/coverage_changes.py b/ietf/utils/management/commands/coverage_changes.py index 7a445bd0c4a..4137dbc592f 100644 --- a/ietf/utils/management/commands/coverage_changes.py +++ b/ietf/utils/management/commands/coverage_changes.py @@ -34,7 +34,7 @@ class Command(BaseCommand): " $ manage.py {name} --absolute --sections=url | grep False\n" "\n".format(**locals()) ) - args = "[[master_json] latest_json]" + args = "[[main_json] latest_json]" def create_parser(self, prog_name, subcommand): import argparse @@ -73,18 +73,19 @@ def read_coverage(self, filename, version=None): data = json.load(file) except ValueError as e: raise CommandError("Failure to read json data from %s: %s" % (filename, e)) + file.close() version = version or data["version"] if not version in data: raise CommandError("There is no data for version %s available in %s" % (version, filename)) return data[version], version - def coverage_diff(self, master, latest, sections, release=None, **options): - master_coverage, mversion = self.read_coverage(master, release) + def coverage_diff(self, main, latest, sections, release=None, **options): + main_coverage, mversion = self.read_coverage(main, release) latest_coverage, lversion = self.read_coverage(latest) self.stdout.write("\nShowing coverage differeces between %s and %s:\n" % (mversion, lversion)) for section in sections: - mcoverage = master_coverage[section]["covered"] - mformat = master_coverage[section].get("format", 1) + mcoverage = main_coverage[section]["covered"] + mformat = main_coverage[section].get("format", 1) lcoverage = latest_coverage[section]["covered"] lformat = latest_coverage[section].get("format", 1) # @@ -235,7 +236,7 @@ def handle(self, *args, **options): # verbosity = int(options.get('verbosity')) if not filenames: filenames = [ - getattr(settings, 'TEST_COVERAGE_MASTER_FILE'), + getattr(settings, 'TEST_COVERAGE_MAIN_FILE'), getattr(settings, 'TEST_COVERAGE_LATEST_FILE'), ] if len(filenames) != 2: diff --git a/ietf/utils/management/commands/dumprelated.py b/ietf/utils/management/commands/dumprelated.py deleted file mode 100644 index 66fbb33bf1d..00000000000 --- a/ietf/utils/management/commands/dumprelated.py +++ /dev/null @@ -1,209 +0,0 @@ -# Copyright The IETF Trust 2018-2020, All Rights Reserved -# -*- coding: utf-8 -*- - - -import io -import warnings -from collections import OrderedDict - -from django.apps import apps -from django.contrib.admin.utils import NestedObjects -from django.core import serializers -from django.core.management.base import BaseCommand, CommandError -from django.core.management.utils import parse_apps_and_model_labels -from django.db import DEFAULT_DB_ALIAS, router - -import debug # pyflakes:ignore -debug.debug = True - -class ProxyModelWarning(Warning): - pass - - -class Command(BaseCommand): - help = ( - "Output a database object and its related objects as a fixture of the given format " - ) - - def add_arguments(self, parser): - parser.add_argument( - 'args', metavar='app_label.ModelName', nargs=1, - help='Specifies the app_label.ModelName for which to dump objects given by --pks', - ) - parser.add_argument( - '--format', default='json', dest='format', - help='Specifies the output serialization format for fixtures.', - ) - parser.add_argument( - '--indent', default=None, dest='indent', type=int, - help='Specifies the indent level to use when pretty-printing output.', - ) - parser.add_argument( - '--database', action='store', dest='database', - default=DEFAULT_DB_ALIAS, - help='Nominates a specific database to dump fixtures from. ' - 'Defaults to the "default" database.', - ) - parser.add_argument( - '-e', '--exclude', dest='exclude', action='append', default=[], - help='An app_label or app_label.ModelName to exclude ' - '(use multiple --exclude to exclude multiple apps/models).', - ) - parser.add_argument( - '--natural-foreign', action='store_true', dest='use_natural_foreign_keys', default=False, - help='Use natural foreign keys if they are available.', - ) - parser.add_argument( - '--natural-primary', action='store_true', dest='use_natural_primary_keys', default=False, - help='Use natural primary keys if they are available.', - ) - parser.add_argument( - '-o', '--output', default=None, dest='output', - help='Specifies file to which the output is written.' - ) - parser.add_argument( - '--pks', dest='primary_keys', required=True, - help="Only dump objects with given primary keys. Accepts a comma-separated " - "list of keys. This option only works when you specify one model.", - ) - - def handle(self, *app_labels, **options): - format = options['format'] - indent = options['indent'] - using = options['database'] - excludes = options['exclude'] - output = options['output'] - show_traceback = options['traceback'] - use_natural_foreign_keys = options['use_natural_foreign_keys'] - use_natural_primary_keys = options['use_natural_primary_keys'] - pks = options['primary_keys'] - - if pks: - primary_keys = [pk.strip() for pk in pks.split(',')] - else: - primary_keys = [] - - excluded_models, excluded_apps = parse_apps_and_model_labels(excludes) - - if len(app_labels) == 0: - if primary_keys: - raise CommandError("You can only use --pks option with one model") - app_list = OrderedDict( - (app_config, None) for app_config in apps.get_app_configs() - if app_config.models_module is not None and app_config not in excluded_apps - ) - else: - if len(app_labels) > 1 and primary_keys: - raise CommandError("You can only use --pks option with one model") - app_list = OrderedDict() - for label in app_labels: - try: - app_label, model_label = label.split('.') - try: - app_config = apps.get_app_config(app_label) - except LookupError as e: - raise CommandError(str(e)) - if app_config.models_module is None or app_config in excluded_apps: - continue - try: - model = app_config.get_model(model_label) - except LookupError: - raise CommandError("Unknown model: %s.%s" % (app_label, model_label)) - - app_list_value = app_list.setdefault(app_config, []) - - # We may have previously seen a "all-models" request for - # this app (no model qualifier was given). In this case - # there is no need adding specific models to the list. - if app_list_value is not None: - if model not in app_list_value: - app_list_value.append(model) - except ValueError: - if primary_keys: - raise CommandError("You can only use --pks option with one model") - # This is just an app - no model qualifier - app_label = label - try: - app_config = apps.get_app_config(app_label) - except LookupError as e: - raise CommandError(str(e)) - if app_config.models_module is None or app_config in excluded_apps: - continue - app_list[app_config] = None - - # Check that the serialization format exists; this is a shortcut to - # avoid collating all the objects and _then_ failing. - if format not in serializers.get_public_serializer_formats(): - try: - serializers.get_serializer(format) - except serializers.SerializerDoesNotExist: - pass - - raise CommandError("Unknown serialization format: %s" % format) - - def flatten(l): - if isinstance(l, list): - for el in l: - if isinstance(el, list): - for sub in flatten(el): - yield sub - else: - yield el - else: - yield l - - def get_objects(count_only=False): - """ - Collate the objects to be serialized. If count_only is True, just - count the number of objects to be serialized. - """ - models = serializers.sort_dependencies(list(app_list.items())) - for model in models: - if model in excluded_models: - continue - if model._meta.proxy and model._meta.proxy_for_model not in models: - warnings.warn( - "%s is a proxy model and won't be serialized." % model._meta.label, - category=ProxyModelWarning, - ) - if not model._meta.proxy and router.allow_migrate_model(using, model): - objects = model._default_manager - - queryset = objects.using(using).order_by(model._meta.pk.name) - if primary_keys: - queryset = queryset.filter(pk__in=primary_keys) - if count_only: - yield queryset.order_by().count() - else: - for obj in queryset.iterator(): - collector = NestedObjects(using=using) - collector.collect([obj,]) - object_list = list(flatten(collector.nested())) - object_list.reverse() - for o in object_list: - yield o - - try: - self.stdout.ending = None - progress_output = None - object_count = 0 - # If dumpdata is outputting to stdout, there is no way to display progress - if (output and self.stdout.isatty() and options['verbosity'] > 0): - progress_output = self.stdout - object_count = sum(get_objects(count_only=True)) - stream = io.open(output, 'w') if output else None - try: - serializers.serialize( - format, get_objects(), indent=indent, - use_natural_foreign_keys=use_natural_foreign_keys, - use_natural_primary_keys=use_natural_primary_keys, - stream=stream or self.stdout, progress_output=progress_output, - object_count=object_count, - ) - finally: - if stream: - stream.close() - except Exception as e: - if show_traceback: - raise - raise CommandError("Unable to serialize database: %s" % e) diff --git a/ietf/utils/management/commands/fix_ambiguous_timestamps.py b/ietf/utils/management/commands/fix_ambiguous_timestamps.py index fc872f45867..84a82bb3098 100644 --- a/ietf/utils/management/commands/fix_ambiguous_timestamps.py +++ b/ietf/utils/management/commands/fix_ambiguous_timestamps.py @@ -10,6 +10,7 @@ from django.conf import settings from django.core.management.base import BaseCommand from django.db import models +from django.utils import timezone import debug # pyflakes:ignore @@ -53,7 +54,7 @@ def fixup(self, model, field, start, stop): def handle(self, *app_labels, **options): self.verbosity = options['verbosity'] self.quiet = self.verbosity < 1 - stop = datetime.datetime.now() + stop = timezone.now() start = stop - datetime.timedelta(days=14) for name, appconf in apps.app_configs.items(): diff --git a/ietf/utils/management/commands/import_htpasswd.py b/ietf/utils/management/commands/import_htpasswd.py deleted file mode 100644 index ed19eea6fda..00000000000 --- a/ietf/utils/management/commands/import_htpasswd.py +++ /dev/null @@ -1,63 +0,0 @@ -# Copyright The IETF Trust 2014-2020, All Rights Reserved -import io -import sys - -from textwrap import dedent - -from django.contrib.auth.models import User -from django.core.management.base import BaseCommand - -def import_htpasswd_file(filename, verbosity=1, overwrite=False): - with io.open(filename) as file: - for line in file: - if not ':' in line: - raise ValueError('Found a line without colon separator in the htpassword file %s:' - ' "%s"' % (file.name, line)) - username, password = line.strip().split(':', 1) - try: - user = User.objects.get(username=username) - if overwrite == True or not user.password: - if password.startswith('{SHA}'): - user.password = "sha1$$%s" % password[len('{SHA}'):] - elif password.startswith('$apr1$'): - user.password = "md5$%s" % password[len('$apr1$'):] - else: # Assume crypt - user.password = "crypt$$%s" % password - user.save() - if verbosity > 0: - sys.stderr.write('.') - if verbosity > 1: - sys.stderr.write(' %s\n' % username) - except User.DoesNotExist: - if verbosity > 1: - sys.stderr.write('\nNo such user: %s\n' % username) - -class Command(BaseCommand): - """ - Import passwords from one or more htpasswd files to Django's auth_user table. - - This command only imports passwords; it does not import usernames, as that - would leave usernames without associated Person records in the database, - something which is undesirable. - - By default the command won't overwrite existing password entries, but - given the --force switch, it will overwrite existing entries too. Without - the --force switch, the command is safe to run repeatedly. - """ - - help = dedent(__doc__).strip() - - def add_arguments(self, parser): - parser.add_argument('--force', - action='store_true', dest='overwrite', default=False, - help='Overwrite existing passwords in the auth_user table.') - - - args = '[path [path [...]]]' - - def handle(self, *filenames, **options): - overwrite = options.get('overwrite', False) - verbosity = int(options.get('verbosity')) - for fn in filenames: - import_htpasswd_file(fn, verbosity=verbosity, overwrite=overwrite) - diff --git a/ietf/utils/management/commands/loadrelated.py b/ietf/utils/management/commands/loadrelated.py deleted file mode 100644 index e3d84990c99..00000000000 --- a/ietf/utils/management/commands/loadrelated.py +++ /dev/null @@ -1,129 +0,0 @@ -# Copyright The IETF Trust 2018-2020, All Rights Reserved -# -*- coding: utf-8 -*- - - -import gzip -import os -#import sys -import tqdm -import zipfile - -try: - import bz2 - has_bz2 = True -except ImportError: - has_bz2 = False - -from django.core.exceptions import ObjectDoesNotExist -from django.core import serializers -from django.db import DEFAULT_DB_ALIAS, DatabaseError, IntegrityError, connections -from django.db.models.signals import post_save -from django.utils.encoding import force_text -import django.core.management.commands.loaddata as loaddata - -import debug # pyflakes:ignore - -from ietf.community.models import notify_events - -class Command(loaddata.Command): - help = (""" - - Load a fixture of related objects to the database. The fixture is expected - to contain a set of related objects, created with the 'dumprelated' management - command. It differs from the 'loaddata' command in that it silently ignores - attempts to load duplicate entries, and continues loading subsequent entries. - - """) - - def add_arguments(self, parser): - parser.add_argument('args', metavar='fixture', nargs='+', help='Fixture files.') - parser.add_argument( - '--database', action='store', dest='database', default=DEFAULT_DB_ALIAS, - help='Nominates a specific database to load fixtures into. Defaults to the "default" database.', - ) - parser.add_argument( - '--ignorenonexistent', '-i', action='store_true', dest='ignore', default=False, - help='Ignores entries in the serialized data for fields that do not ' - 'currently exist on the model.', - ) - - def handle(self, *args, **options): - self.ignore = options['ignore'] - self.using = options['database'] - self.verbosity = options['verbosity'] - # - self.compression_formats = { - None: (open, 'rb'), - 'gz': (gzip.GzipFile, 'rb'), - 'zip': (SingleZipReader, 'r'), - } - if has_bz2: - self.compression_formats['bz2'] = (bz2.BZ2File, 'r') - # - self.serialization_formats = serializers.get_public_serializer_formats() - # - post_save.disconnect(notify_events) - # - connection = connections[self.using] - self.fixture_count = 0 - self.loaded_object_count = 0 - self.fixture_object_count = 0 - # - for arg in args: - fixture_file = arg - self.stdout.write("Loading objects from %s" % fixture_file) - _, ser_fmt, cmp_fmt = self.parse_name(os.path.basename(fixture_file)) - open_method, mode = self.compression_formats[cmp_fmt] - fixture = open_method(fixture_file, mode) - objects_in_fixture = 0 - self.stdout.write("Getting object count...\b\b\b", ending='') - self.stdout.flush() - for o in serializers.deserialize(ser_fmt, fixture, using=self.using, ignorenonexistent=self.ignore,): - objects_in_fixture += 1 - self.stdout.write(" %d" % objects_in_fixture) - # - fixture = open_method(fixture_file, mode) - self.fixture_count += 1 - objects = serializers.deserialize(ser_fmt, fixture, using=self.using, ignorenonexistent=self.ignore,) - with connection.constraint_checks_disabled(): - for obj in tqdm.tqdm(objects, total=objects_in_fixture): - try: - obj.save(using=self.using) - self.loaded_object_count += 1 - except (DatabaseError, IntegrityError, ObjectDoesNotExist, AttributeError) as e: - error_msg = force_text(e) - if "Duplicate entry" in error_msg: - pass - else: - self.stderr.write("Could not load %(app_label)s.%(object_name)s(pk=%(pk)s): %(error_msg)s" % { - 'app_label': obj.object._meta.app_label, - 'object_name': obj.object._meta.object_name, - 'pk': obj.object.pk, - 'error_msg': error_msg, - }, ) - self.fixture_object_count += objects_in_fixture - - if self.verbosity >= 1: - if self.fixture_object_count == self.loaded_object_count: - self.stdout.write( - "Installed %d object(s) from %d fixture(s)" - % (self.loaded_object_count, self.fixture_count) - ) - else: - self.stdout.write( - "Installed %d object(s) (of %d) from %d fixture(s)" - % (self.loaded_object_count, self.fixture_object_count, self.fixture_count) - ) - - -class SingleZipReader(zipfile.ZipFile): - - def __init__(self, *args, **kwargs): - zipfile.ZipFile.__init__(self, *args, **kwargs) - if len(self.namelist()) != 1: - raise ValueError("Zip-compressed fixtures must contain one file.") - - def read(self): - return zipfile.ZipFile.read(self, self.namelist()[0]) - - diff --git a/ietf/utils/management/commands/mergedata.py b/ietf/utils/management/commands/mergedata.py index 3a169c51e33..e73014c789f 100644 --- a/ietf/utils/management/commands/mergedata.py +++ b/ietf/utils/management/commands/mergedata.py @@ -15,7 +15,7 @@ from django.core.management.commands.loaddata import Command as LoadCommand, humanize from django.db import DatabaseError, IntegrityError, router, transaction from django.db.models import ManyToManyField -from django.utils.encoding import force_text +from django.utils.encoding import force_str from ietf.utils.models import ForeignKey @@ -188,7 +188,7 @@ def get_unique_field(obj): #debug.say("Found matching object with new pk: %s" % (obj.object.pk, )) new_pk = obj.object.pk if new_pk != old_pk: - # Update other objects refering to this + # Update other objects referring to this # object to use the new pk #debug.show('old_pk, new_pk') mname = model._meta.app_label + '.' + model.__name__ @@ -234,7 +234,7 @@ def get_unique_field(obj): 'object_name': obj.object._meta.object_name, 'pk': obj.object.pk, 'data': obj_to_dict(obj.object), - 'error_msg': force_text(e) + 'error_msg': force_str(e) },) raise if objects and show_progress: @@ -262,4 +262,4 @@ def find_fixtures(self, fixture_label): fixture_files = [ (fixture_label, os.path.dirname(fixture_label) or os.getcwd(), os.path.basename(fixture_label)) ] else: fixture_files = super(Command, self).find_fixtures(fixture_label) - return fixture_files \ No newline at end of file + return fixture_files diff --git a/ietf/utils/management/commands/patch_libraries.py b/ietf/utils/management/commands/patch_libraries.py new file mode 100644 index 00000000000..d9ae11097be --- /dev/null +++ b/ietf/utils/management/commands/patch_libraries.py @@ -0,0 +1,31 @@ +# Copyright The IETF Trust 2024, All Rights Reserved +import django + +from django.conf import settings +from django.core.management.base import BaseCommand, CommandError +from pathlib import Path + +from ietf.utils import patch + + +class Command(BaseCommand): + """Apply IETF patches to libraries""" + requires_system_checks = tuple() + + def handle(self, *args, **options): + library_path = Path(django.__file__).parent.parent + top_dir = Path(settings.BASE_DIR).parent + + # All patches in settings.CHECKS_LIBRARY_PATCHES_TO_APPLY must have a + # relative file path starting from the site-packages dir, e.g. + # 'django/db/models/fields/__init__.py' + for patch_file in settings.CHECKS_LIBRARY_PATCHES_TO_APPLY: + patch_set = patch.fromfile(top_dir / Path(patch_file)) + if not patch_set: + raise CommandError(f"Could not parse patch file '{patch_file}'") + if not patch_set.apply(root=bytes(library_path)): + raise CommandError(f"Could not apply the patch from '{patch_file}'") + if patch_set.already_patched: + self.stdout.write(f"Patch from '{patch_file}' was already applied") + else: + self.stdout.write(f"Applied the patch from '{patch_file}'") diff --git a/ietf/utils/management/commands/periodic_tasks.py b/ietf/utils/management/commands/periodic_tasks.py new file mode 100644 index 00000000000..c878ba49f10 --- /dev/null +++ b/ietf/utils/management/commands/periodic_tasks.py @@ -0,0 +1,282 @@ +# Copyright The IETF Trust 2024, All Rights Reserved +import json +from django_celery_beat.models import CrontabSchedule, PeriodicTask + +from django.core.management.base import BaseCommand + +CRONTAB_DEFS = { + # same as "@weekly" in a crontab + "weekly": { + "minute": "0", + "hour": "0", + "day_of_month": "*", + "month_of_year": "*", + "day_of_week": "0", + "timezone": "America/Los_Angeles", + }, + "daily": { + "minute": "5", + "hour": "0", + "day_of_month": "*", + "month_of_year": "*", + "day_of_week": "*", + "timezone": "America/Los_Angeles", + }, + "hourly": { + "minute": "5", + "hour": "*", + "day_of_month": "*", + "month_of_year": "*", + "day_of_week": "*", + }, + "every_15m": { + "minute": "*/15", + "hour": "*", + "day_of_month": "*", + "month_of_year": "*", + "day_of_week": "*", + }, + "every_15m_except_midnight": { + "minute": "*/15", + "hour": "1-23", + "day_of_month": "*", + "month_of_year": "*", + "day_of_week": "*", + "timezone": "America/Los_Angeles", + }, +} + + +class Command(BaseCommand): + """Manage periodic tasks""" + crontabs = None + + def add_arguments(self, parser): + parser.add_argument("--create-default", action="store_true") + parser.add_argument("--enable", type=int, action="append") + parser.add_argument("--disable", type=int, action="append") + + def handle(self, *args, **options): + self.crontabs = self.get_or_create_crontabs() + if options["create_default"]: + self.create_default_tasks() + if options["enable"]: + self.enable_tasks(options["enable"]) + if options["disable"]: + self.disable_tasks(options["disable"]) + self.show_tasks() + + def get_or_create_crontabs(self): + crontabs = {} + for label, definition in CRONTAB_DEFS.items(): + crontabs[label], _ = CrontabSchedule.objects.get_or_create(**definition) + return crontabs + + def create_default_tasks(self): + PeriodicTask.objects.get_or_create( + name="Send scheduled mail", + task="ietf.message.tasks.send_scheduled_mail_task", + defaults=dict( + enabled=False, + crontab=self.crontabs["every_15m"], + description="Send mail scheduled to go out at certain times" + ), + ) + + PeriodicTask.objects.get_or_create( + name="Fetch meeting attendance", + task="ietf.stats.tasks.fetch_meeting_attendance_task", + defaults=dict( + enabled=False, + crontab=self.crontabs["daily"], + description="Fetch meeting attendance data from ietf.org/registration/attendees", + ), + ) + + PeriodicTask.objects.get_or_create( + name="Send review reminders", + task="ietf.review.tasks.send_review_reminders_task", + defaults=dict( + enabled=False, + crontab=self.crontabs["daily"], + description="Send reminders originating from the review app", + ), + ) + + PeriodicTask.objects.get_or_create( + name="Expire I-Ds", + task="ietf.doc.tasks.expire_ids_task", + defaults=dict( + enabled=False, + crontab=self.crontabs["daily"], + description="Create expiration notices for expired I-Ds", + ), + ) + + PeriodicTask.objects.get_or_create( + name="Expire Last Calls", + task="ietf.doc.tasks.expire_last_calls_task", + defaults=dict( + enabled=False, + crontab=self.crontabs["daily"], + description="Move docs whose last call has expired to their next states", + ), + ) + + PeriodicTask.objects.get_or_create( + name="Sync with IANA changes", + task="ietf.sync.tasks.iana_changes_update_task", + defaults=dict( + enabled=False, + crontab=self.crontabs["hourly"], + description="Fetch change list from IANA and apply to documents", + ), + ) + + PeriodicTask.objects.get_or_create( + name="Sync with IANA protocols page", + task="ietf.sync.tasks.iana_protocols_update_task", + defaults=dict( + enabled=False, + crontab=self.crontabs["hourly"], + description="Fetch protocols page from IANA and update document event logs", + ), + ) + + PeriodicTask.objects.get_or_create( + name="Update I-D index files", + task="ietf.idindex.tasks.idindex_update_task", + defaults=dict( + enabled=False, + crontab=self.crontabs["hourly"], + description="Update I-D index files", + ), + ) + + PeriodicTask.objects.get_or_create( + name="Send expiration notifications", + task="ietf.doc.tasks.notify_expirations_task", + defaults=dict( + enabled=False, + crontab=self.crontabs["weekly"], + description="Send notifications about I-Ds that will expire in the next 14 days", + ) + ) + + PeriodicTask.objects.get_or_create( + name="Generate idnits2 rfcs-obsoleted blob", + task="ietf.doc.tasks.generate_idnits2_rfcs_obsoleted_task", + defaults=dict( + enabled=False, + crontab=self.crontabs["hourly"], + description="Generate the rfcs-obsoleted file used by idnits", + ), + ) + + PeriodicTask.objects.get_or_create( + name="Generate idnits2 rfc-status blob", + task="ietf.doc.tasks.generate_idnits2_rfc_status_task", + defaults=dict( + enabled=False, + crontab=self.crontabs["hourly"], + description="Generate the rfc_status blob used by idnits", + ), + ) + + PeriodicTask.objects.get_or_create( + name="Send NomCom reminders", + task="ietf.nomcom.tasks.send_nomcom_reminders_task", + defaults=dict( + enabled=False, + crontab=self.crontabs["daily"], + description="Send acceptance and questionnaire reminders to nominees", + ), + ) + + PeriodicTask.objects.get_or_create( + name="Generate WG charter files", + task="ietf.group.tasks.generate_wg_charters_files_task", + defaults=dict( + enabled=False, + crontab=self.crontabs["hourly"], + description="Update 1wg-charters.txt and 1wg-charters-by-acronym.txt", + ), + ) + + PeriodicTask.objects.get_or_create( + name="Generate WG summary files", + task="ietf.group.tasks.generate_wg_summary_files_task", + defaults=dict( + enabled=False, + crontab=self.crontabs["hourly"], + description="Update 1wg-summary.txt and 1wg-summary-by-acronym.txt", + ), + ) + + PeriodicTask.objects.get_or_create( + name="Generate I-D bibxml files", + task="ietf.doc.tasks.generate_draft_bibxml_files_task", + defaults=dict( + enabled=False, + crontab=self.crontabs["hourly"], + description="Generate draft bibxml files for the last week's drafts", + ), + ) + + PeriodicTask.objects.get_or_create( + name="Send personal API key usage emails", + task="ietf.person.tasks.send_apikey_usage_emails_task", + kwargs=json.dumps(dict(days=7)), + defaults=dict( + enabled=False, + crontab=self.crontabs["weekly"], + description="Send personal API key usage summary emails for the past week", + ), + ) + + PeriodicTask.objects.get_or_create( + name="Purge old personal API key events", + task="ietf.person.tasks.purge_personal_api_key_events_task", + kwargs=json.dumps(dict(keep_days=14)), + defaults=dict( + enabled=False, + crontab=self.crontabs["daily"], + description="Purge PersonApiKeyEvent instances older than 14 days", + ), + ) + + PeriodicTask.objects.get_or_create( + name="Run Yang model checks", + task="ietf.submit.tasks.run_yang_model_checks_task", + defaults=dict( + enabled=False, + crontab=self.crontabs["daily"], + description="Re-run Yang model checks on all active drafts", + ), + ) + + def show_tasks(self): + for label, crontab in self.crontabs.items(): + tasks = PeriodicTask.objects.filter(crontab=crontab).order_by( + "task", "name" + ) + self.stdout.write(f"\n{label} ({crontab.human_readable})\n") + if tasks: + for task in tasks: + desc = f" {task.id:-3d}: {task.task} - {task.name}" + if task.enabled: + self.stdout.write(desc) + else: + self.stdout.write(self.style.NOTICE(f"{desc} - disabled")) + else: + self.stdout.write(" Nothing scheduled") + + def enable_tasks(self, pks): + PeriodicTask.objects.filter( + crontab__in=self.crontabs.values(), pk__in=pks + ).update(enabled=True) + + def disable_tasks(self, pks): + PeriodicTask.objects.filter( + crontab__in=self.crontabs.values(), pk__in=pks + ).update(enabled=False) diff --git a/ietf/utils/management/commands/populate_yang_model_dirs.py b/ietf/utils/management/commands/populate_yang_model_dirs.py deleted file mode 100644 index 1a6e1422cbc..00000000000 --- a/ietf/utils/management/commands/populate_yang_model_dirs.py +++ /dev/null @@ -1,172 +0,0 @@ -# Copyright The IETF Trust 2016-2020, All Rights Reserved -# -*- coding: utf-8 -*- - - -import io -import os -import sys -import time - -from pathlib import Path -from textwrap import dedent -from xym import xym - -from django.conf import settings -from django.core.management.base import BaseCommand - -import debug # pyflakes:ignore - -class Command(BaseCommand): - """ - Populate the yang module repositories from drafts and RFCs. - - Extracts yang models from RFCs (found in settings.RFC_PATH and places - them in settings.SUBMIT_YANG_RFC_MODEL_DIR, and from active drafts, placed in - settings.SUBMIT_YANG_DRAFT_MODEL_DIR. - - """ - - help = dedent(__doc__).strip() - - def add_arguments(self, parser): - parser.add_argument('--clean', - action='store_true', dest='clean', default=False, - help='Remove the current directory content before writing new models.') - - - def handle(self, *filenames, **options): - """ - - * All yang modules from published RFCs should be extracted and be - available in an rfc-yang repository. - - * All valid yang modules from active, not replaced, internet drafts - should be extracted and be available in a draft-valid-yang repository. - - * All, valid and invalid, yang modules from active, not replaced, - internet drafts should be available in a draft-all-yang repository. - (Actually, given precedence ordering, it would be enough to place - non-validating modules in a draft-invalid-yang repository instead). - - * In all cases, example modules should be excluded. - - * Precedence is established by the search order of the repository as - provided to pyang. - - * As drafts expire, models should be removed in order to catch cases - where a module being worked on depends on one which has slipped out - of the work queue. - - """ - - verbosity = int(options.get('verbosity')) - - def extract_from(file, dir, strict=True): - saved_stdout = sys.stdout - saved_stderr = sys.stderr - xymerr = io.StringIO() - xymout = io.StringIO() - sys.stderr = xymerr - sys.stdout = xymout - model_list = [] - try: - model_list = xym.xym(str(file), str(file.parent), str(dir), strict=strict, debug_level=verbosity-2) - for name in model_list: - modfile = moddir / name - mtime = file.stat().st_mtime - os.utime(str(modfile), (mtime, mtime)) - if '"' in name: - name = name.replace('"', '') - modfile.rename(str(moddir/name)) - model_list = [ n.replace('"','') for n in model_list ] - except Exception as e: - self.stderr.write("** Error when extracting from %s: %s" % (file, str(e))) - finally: - sys.stdout = saved_stdout - sys.stderr = saved_stderr - # - if verbosity > 1: - outmsg = xymout.getvalue() - if outmsg.strip(): - self.stdout.write(outmsg) - if verbosity>2: - errmsg = xymerr.getvalue() - if errmsg.strip(): - self.stderr.write(errmsg) - return model_list - - # Extract from new RFCs - - rfcdir = Path(settings.RFC_PATH) - - moddir = Path(settings.SUBMIT_YANG_RFC_MODEL_DIR) - if not moddir.exists(): - moddir.mkdir(parents=True) - - latest = 0 - for item in moddir.iterdir(): - if item.stat().st_mtime > latest: - latest = item.stat().st_mtime - - if verbosity > 0: - self.stdout.write("Extracting to %s ..." % moddir) - for item in rfcdir.iterdir(): - if item.is_file() and item.name.startswith('rfc') and item.name.endswith('.txt') and item.name[3:-4].isdigit(): - if item.stat().st_mtime > latest: - model_list = extract_from(item, moddir) - for name in model_list: - if name.startswith('ietf') or name.startswith('iana'): - if verbosity > 1: - self.stdout.write(" Extracted from %s: %s" % (item, name)) - elif verbosity > 0: - self.stdout.write('.', ending='') - self.stdout.flush() - else: - modfile = moddir / name - modfile.unlink() - if verbosity > 1: - self.stdout.write(" Skipped module from %s: %s" % (item, name)) - if verbosity > 0: - self.stdout.write("") - - # Extract valid modules from drafts - - six_months_ago = time.time() - 6*31*24*60*60 - def active(item): - return item.stat().st_mtime > six_months_ago - - draftdir = Path(settings.INTERNET_DRAFT_PATH) - - moddir = Path(settings.SUBMIT_YANG_DRAFT_MODEL_DIR) - if not moddir.exists(): - moddir.mkdir(parents=True) - if verbosity > 0: - self.stdout.write("Emptying %s ..." % moddir) - for item in moddir.iterdir(): - item.unlink() - - if verbosity > 0: - self.stdout.write("Extracting to %s ..." % moddir) - for item in draftdir.iterdir(): - try: - if item.is_file() and item.name.startswith('draft') and item.name.endswith('.txt') and active(item): - model_list = extract_from(item, moddir, strict=False) - for name in model_list: - if not name.startswith('example'): - if verbosity > 1: - self.stdout.write(" Extracted module from %s: %s" % (item, name)) - elif verbosity > 0: - self.stdout.write('.', ending='') - self.stdout.flush() - else: - modfile = moddir / name - modfile.unlink() - if verbosity > 1: - self.stdout.write(" Skipped module from %s: %s" % (item, name)) - except UnicodeDecodeError as e: - self.stderr.write('\nError: %s' % (e, )) - self.stderr.write(item.name) - self.stderr.write('') - if verbosity > 0: - self.stdout.write('') - diff --git a/ietf/utils/management/commands/run_yang_model_checks.py b/ietf/utils/management/commands/run_yang_model_checks.py deleted file mode 100644 index 13fb61c46b9..00000000000 --- a/ietf/utils/management/commands/run_yang_model_checks.py +++ /dev/null @@ -1,85 +0,0 @@ -# Copyright The IETF Trust 2017-2020, All Rights Reserved -# -*- coding: utf-8 -*- - - -import json - -from textwrap import dedent - -from django.core.management.base import BaseCommand - -import debug # pyflakes:ignore - -from ietf.doc.models import Document, State, DocAlias -from ietf.submit.models import Submission -from ietf.submit.checkers import DraftYangChecker - - -class Command(BaseCommand): - """ - Run yang model checks on active drafts. - - Repeats the yang checks in ietf/submit/checkers.py for active drafts, in - order to catch changes in status due to new modules becoming available in - the module directories. - - """ - - help = dedent(__doc__).strip() - - def add_arguments(self, parser): - parser.add_argument('draftnames', nargs="*", help="drafts to check, or none to check all active yang drafts") - parser.add_argument('--clean', - action='store_true', dest='clean', default=False, - help='Remove the current directory content before writing new models.') - - - def check_yang(self, checker, draft, force=False): - if self.verbosity > 1: - self.stdout.write("Checking %s-%s" % (draft.name, draft.rev)) - elif self.verbosity > 0: - self.stderr.write('.', ending='') - submission = Submission.objects.filter(name=draft.name, rev=draft.rev).order_by('-id').first() - if submission or force: - check = submission.checks.filter(checker=checker.name).order_by('-id').first() - if check or force: - result = checker.check_file_txt(draft.get_file_name()) - passed, message, errors, warnings, items = result - if self.verbosity > 2: - self.stdout.write(" Errors: %s\n" - " Warnings: %s\n" - " Message:\n%s\n" % (errors, warnings, message)) - items = json.loads(json.dumps(items)) - new_res = (passed, errors, warnings, message) - old_res = (check.passed, check.errors, check.warnings, check.message) if check else () - if new_res != old_res: - if self.verbosity > 1: - self.stdout.write(" Saving new yang checker results for %s-%s" % (draft.name, draft.rev)) - qs = submission.checks.filter(checker=checker.name).order_by('time') - submission.checks.filter(checker=checker.name).exclude(pk=qs.first().pk).delete() - submission.checks.create(submission=submission, checker=checker.name, passed=passed, - message=message, errors=errors, warnings=warnings, items=items, - symbol=checker.symbol) - else: - self.stderr.write("Error: did not find any submission object for %s-%s" % (draft.name, draft.rev)) - - def handle(self, *filenames, **options): - """ - """ - - self.verbosity = int(options.get('verbosity')) - drafts = options.get('draftnames') - - active_state = State.objects.get(type="draft", slug="active") - - checker = DraftYangChecker() - if drafts: - for name in drafts: - parts = name.rsplit('-',1) - if len(parts)==2 and len(parts[1])==2 and parts[1].isdigit(): - name = parts[0] - draft = DocAlias.objects.get(name=name).document - self.check_yang(checker, draft, force=True) - else: - for draft in Document.objects.filter(states=active_state, type_id='draft'): - self.check_yang(checker, draft) diff --git a/ietf/utils/management/commands/send_gdpr_consent_request.py b/ietf/utils/management/commands/send_gdpr_consent_request.py deleted file mode 100644 index 2bb08eed1b3..00000000000 --- a/ietf/utils/management/commands/send_gdpr_consent_request.py +++ /dev/null @@ -1,103 +0,0 @@ -# Copyright The IETF Trust 2018-2020, All Rights Reserved -# -*- coding: utf-8 -*- - - -import datetime -import time - -from django.conf import settings -from django.core.management.base import BaseCommand, CommandError - -import debug # pyflakes:ignore - -from ietf.person.models import Person, PersonEvent -from ietf.utils.mail import send_mail - -class Command(BaseCommand): - help = (""" - Send GDPR consent request emails to persons who have not indicated consent - to having their personal information stored. Each send is logged as a - PersonEvent. - - By default email sending happens at a rate of 1 message per second; the - rate can be adjusted with the -r option. At the start of a run, an estimate - is given of how many persons to send to, and how long the run will take. - - By default, emails are not sent out if there is less than 6 days since the - previous consent request email. The interval can be adjusted with the -m - option. One effect of this is that it is possible to break of a run and - re-start it with for instance a different rate, without having duplicate - messages go out to persons that were handled in the interrupted run. - """) - - def add_arguments(self, parser): - parser.add_argument('-n', '--dry-run', action='store_true', default=False, - help="Don't send email, just list recipients") - parser.add_argument('-d', '--date', help="Date of deletion (mentioned in message)") - parser.add_argument('-m', '--minimum-interval', type=int, default=6, - help="Minimum interval between re-sending email messages, default: %(default)s days") - parser.add_argument('-r', '--rate', type=float, default=1.0, - help='Rate of sending mail, default: %(default)s/s') - parser.add_argument('-R', '--reminder', action='store_true', default=False, - help='Preface the subject with "Reminder:"') - parser.add_argument('user', nargs='*') - - - def handle(self, *args, **options): - # Don't send copies of the whole bulk mailing to the debug mailbox - if settings.SERVER_MODE == 'production': - settings.EMAIL_COPY_TO = "Email Debug Copy " - # - event_type = 'gdpr_notice_email' - # Arguments - # --date - if 'date' in options and options['date'] != None: - try: - date = datetime.datetime.strptime(options['date'], "%Y-%m-%d").date() - except ValueError as e: - raise CommandError('%s' % e) - else: - date = datetime.date.today() + datetime.timedelta(days=30) - days = (date - datetime.date.today()).days - if days <= 1: - raise CommandError('date must be more than 1 day in the future') - # --rate - delay = 1.0/options['rate'] - # --minimum_interval - minimum_interval = options['minimum_interval'] - latest_previous = datetime.datetime.now() - datetime.timedelta(days=minimum_interval) - # user - self.stdout.write('Querying the database for matching person records ...') - if 'user' in options and options['user']: - persons = Person.objects.filter(user__username__in=options['user']) - else: - exclude = PersonEvent.objects.filter(time__gt=latest_previous, type=event_type) - persons = Person.objects.exclude(consent=True).exclude(personevent__in=exclude) - # Report the size of the run - runtime = persons.count() * delay - self.stdout.write('Sending to %d users; estimated time a bit more than %d:%02d hours' % (persons.count(), runtime//3600, runtime%3600//60)) - subject='Personal Information in the IETF Datatracker' - if options['reminder']: - subject = "Reminder: " + subject - for person in persons: - fields = ', '.join(person.needs_consent()) - if fields and person.email_set.exists(): - if options['dry_run']: - print(("%-32s %-32s %-32s %-32s %s" % (person.email(), person.name_from_draft or '', person.name, person.ascii, fields)).encode('utf8')) - else: - to = [ e.address for e in person.email_set.filter(active=True) ] # pyflakes:ignore - if not to: - to = [ e.address for e in person.email_set.all() ] # pyflakes:ignore - self.stdout.write("Sendimg email to %s" % to) - send_mail(None, to, "", - subject=subject, - template='utils/personal_information_notice.txt', - context={ - 'date': date, 'days': days, 'fields': fields, - 'person': person, 'settings': settings, - }, - ) - PersonEvent.objects.create(person=person, type='gdpr_notice_email', - desc="Sent GDPR notice email to %s with confirmation deadline %s" % (to, date)) - time.sleep(delay) - diff --git a/ietf/utils/management/commands/showloggers.py b/ietf/utils/management/commands/showloggers.py index 3de9db0c061..b79da9ce267 100644 --- a/ietf/utils/management/commands/showloggers.py +++ b/ietf/utils/management/commands/showloggers.py @@ -11,18 +11,7 @@ import debug # pyflakes:ignore class Command(BaseCommand): - """ - Display a list or tree representation of python loggers. - - Add a UTILS_LOGGER_LEVELS setting in settings_local.py to configure - non-default logging levels for any registered logger, for instance: - - UTILS_LOGGER_LEVELS = { - 'oicd_provider': 'DEBUG', - 'urllib3.connection': 'DEBUG', - } - - """ + """Display a list or tree representation of python loggers""" help = dedent(__doc__).strip() diff --git a/ietf/utils/management/commands/tests.py b/ietf/utils/management/commands/tests.py index 6619cb819e2..d684b31f7bf 100644 --- a/ietf/utils/management/commands/tests.py +++ b/ietf/utils/management/commands/tests.py @@ -15,7 +15,7 @@ class CoverageChangeTestCase(TestCase): def test_coverage_change(self): - master_txt ="""{ + main_txt ="""{ "5.12.0": { "code": { "coverage": 0.5921474057048117, @@ -81,16 +81,16 @@ def test_coverage_change(self): "version":"latest" } """ - mfh, master = tempfile.mkstemp(suffix='.json') - with io.open(master, "w") as file: - file.write(master_txt) + mfh, main = tempfile.mkstemp(suffix='.json') + with io.open(main, "w") as file: + file.write(main_txt) lfh, latest = tempfile.mkstemp(suffix='.json') with io.open(latest, "w") as file: file.write(latest_txt) output = io.StringIO() - call_command('coverage_changes', master, latest, stdout=output) + call_command('coverage_changes', main, latest, stdout=output) text = output.getvalue() - os.unlink(master) + os.unlink(main) os.unlink(latest) for l in [ diff --git a/ietf/utils/management/commands/update_community_list_index.py b/ietf/utils/management/commands/update_community_list_index.py index 609577763e4..7f4951fd6e2 100644 --- a/ietf/utils/management/commands/update_community_list_index.py +++ b/ietf/utils/management/commands/update_community_list_index.py @@ -32,7 +32,7 @@ def handle(self, *args, **options): person = rule.person if not person and not group: try: - person = rule.community_list.user.person + person = rule.community_list.person except: pass name = ((group and group.acronym) or (person and person.email_address())) or '?' diff --git a/ietf/utils/management/commands/update_external_command_info.py b/ietf/utils/management/commands/update_external_command_info.py deleted file mode 100644 index 9cc1d1ba497..00000000000 --- a/ietf/utils/management/commands/update_external_command_info.py +++ /dev/null @@ -1,41 +0,0 @@ -# Copyright The IETF Trust 2017-2020, All Rights Reserved -# -*- coding: utf-8 -*- - - -import sys - -from textwrap import dedent - -from django.core.management.base import BaseCommand - -import debug # pyflakes:ignore - -from ietf.utils.models import VersionInfo -from ietf.utils.pipe import pipe - -class Command(BaseCommand): - """ - Update the version information for external commands used by the datatracker. - - Iterates through the entries in the VersionInfo table, runs the relevant - command, and updates the version string with the result. - - """ - - help = dedent(__doc__).strip() - - def handle(self, *filenames, **options): - for c in VersionInfo.objects.filter(used=True): - cmd = "%s %s" % (c.command, c.switch) - code, out, err = pipe(cmd) - out = out.decode('utf-8') - err = err.decode('utf-8') - if code != 0: - sys.stderr.write("Command '%s' retuned %s: \n%s\n%s\n" % (cmd, code, out, err)) - else: - c.version = (out.strip()+'\n'+err.strip()).strip() - if options.get('verbosity', 1) > 1: - sys.stdout.write( - "Command: %s\n" - " Version: %s\n" % (cmd, c.version)) - c.save() diff --git a/ietf/utils/management/tests.py b/ietf/utils/management/tests.py index e94c39354f0..38be464c7f6 100644 --- a/ietf/utils/management/tests.py +++ b/ietf/utils/management/tests.py @@ -1,7 +1,7 @@ # Copyright The IETF Trust 2013-2020, All Rights Reserved # -*- coding: utf-8 -*- -import mock +from unittest import mock from django.core.management import call_command, CommandError from django.test import override_settings @@ -12,7 +12,7 @@ from ietf.utils.test_utils import TestCase -@mock.patch.object(EmailOnFailureCommand, 'handle') +@mock.patch.object(EmailOnFailureCommand, 'handle', return_value=None) class EmailOnFailureCommandTests(TestCase): def test_calls_handle(self, handle_method): call_command(EmailOnFailureCommand()) diff --git a/ietf/utils/markdown.py b/ietf/utils/markdown.py index 3b7c60cae04..0b522685b2f 100644 --- a/ietf/utils/markdown.py +++ b/ietf/utils/markdown.py @@ -6,22 +6,64 @@ the datatracker. """ import markdown as python_markdown +from markdown.extensions import Extension +from markdown.postprocessors import Postprocessor from django.utils.safestring import mark_safe from ietf.doc.templatetags.ietf_filters import urlize_ietf_docs -from ietf.utils.text import bleach_cleaner, bleach_linker +from .html import clean_html, liberal_clean_html +from .text import linkify + + + +class LinkifyExtension(Extension): + """ + Simple Markdown extension inspired by https://github.com/daGrevis/mdx_linkify, + but using our own linker directly. Doing the linkification on the converted + Markdown output introduces artifacts. + """ + + def extendMarkdown(self, md): + md.postprocessors.register(LinkifyPostprocessor(md), "linkify", 50) + # disable automatic links via angle brackets for email addresses + md.inlinePatterns.deregister("automail") + # "autolink" for URLs does not seem to cause issues, so leave it on + + +class LinkifyPostprocessor(Postprocessor): + def run(self, text): + return urlize_ietf_docs(linkify(text)) def markdown(text): return mark_safe( - bleach_linker.linkify( - urlize_ietf_docs( - bleach_cleaner.clean( - python_markdown.markdown( - text, extensions=["extra", "nl2br", "sane_lists", "toc"] - ) - ) + clean_html( + python_markdown.markdown( + text, + extensions=[ + "extra", + "nl2br", + "sane_lists", + "toc", + LinkifyExtension(), + ], + ) + ) + ) + +def liberal_markdown(text): + return mark_safe( + liberal_clean_html( + python_markdown.markdown( + text, + extensions=[ + "extra", + "nl2br", + "sane_lists", + "toc", + LinkifyExtension(), + ], ) ) ) diff --git a/ietf/utils/meetecho.py b/ietf/utils/meetecho.py index 26ae93f03d8..943f3789efa 100644 --- a/ietf/utils/meetecho.py +++ b/ietf/utils/meetecho.py @@ -1,9 +1,10 @@ -# Copyright The IETF Trust 2021, All Rights Reserved +# Copyright The IETF Trust 2021-2024, All Rights Reserved # """Meetecho interim meeting scheduling API Implements the v1 API described in email from alex@meetecho.com -on 2021-12-09. +on 2021-12-09, plus additional slide management API discussed via +IM in 2024 Feb. API methods return Python objects equivalent to the JSON structures specified in the API documentation. Times and durations are represented @@ -13,29 +14,36 @@ import debug # pyflakes: ignore -from datetime import datetime, timedelta +import datetime from json import JSONDecodeError -from pytz import utc -from typing import Dict, Sequence, Union +from pprint import pformat +from typing import Sequence, TypedDict, TYPE_CHECKING, Union from urllib.parse import urljoin +# Guard against hypothetical cyclical import problems +if TYPE_CHECKING: + from ietf.doc.models import Document + from ietf.meeting.models import Session + class MeetechoAPI: - timezone = utc + timezone = datetime.UTC - def __init__(self, api_base: str, client_id: str, client_secret: str, request_timeout=3.01): + def __init__( + self, api_base: str, client_id: str, client_secret: str, request_timeout=3.01 + ): self.client_id = client_id self.client_secret = client_secret self.request_timeout = request_timeout # python-requests doc recommend slightly > a multiple of 3 seconds self._session = requests.Session() # if needed, add a trailing slash so urljoin won't eat the trailing path component - self.api_base = api_base if api_base.endswith('/') else f'{api_base}/' + self.api_base = api_base if api_base.endswith("/") else f"{api_base}/" def _request(self, method, url, api_token=None, json=None): """Execute an API request""" - headers = {'Accept': 'application/json'} + headers = {"Accept": "application/json"} if api_token is not None: - headers['Authorization'] = f'bearer {api_token}' + headers["Authorization"] = f"bearer {api_token}" try: response = self._session.request( @@ -47,28 +55,31 @@ def _request(self, method, url, api_token=None, json=None): ) except requests.RequestException as err: raise MeetechoAPIError(str(err)) from err - if response.status_code != 200: - raise MeetechoAPIError(f'API request failed (HTTP status code = {response.status_code})') + if response.status_code not in (200, 202): + # Could be more selective about status codes, but not seeing an immediate need + raise MeetechoAPIError( + f"API request failed (HTTP status code = {response.status_code})" + ) # try parsing the result as JSON in case the server failed to set the Content-Type header try: return response.json() except JSONDecodeError as err: - if response.headers['Content-Type'].startswith('application/json'): + if response.headers.get("Content-Type", "").startswith("application/json"): # complain if server told us to expect JSON and it was invalid - raise MeetechoAPIError('Error decoding response as JSON') from err + raise MeetechoAPIError("Error decoding response as JSON") from err return None - def _deserialize_time(self, s: str) -> datetime: - return self.timezone.localize(datetime.strptime(s, '%Y-%m-%d %H:%M:%S')) + def _deserialize_time(self, s: str) -> datetime.datetime: + return datetime.datetime.strptime(s, "%Y-%m-%d %H:%M:%S").replace(tzinfo=self.timezone) - def _serialize_time(self, dt: datetime) -> str: - return dt.astimezone(self.timezone).strftime('%Y-%m-%d %H:%M:%S') + def _serialize_time(self, dt: datetime.datetime) -> str: + return dt.astimezone(self.timezone).strftime("%Y-%m-%d %H:%M:%S") - def _deserialize_duration(self, minutes: int) -> timedelta: - return timedelta(minutes=minutes) + def _deserialize_duration(self, minutes: int) -> datetime.timedelta: + return datetime.timedelta(minutes=minutes) - def _serialize_duration(self, td: timedelta) -> int: + def _serialize_duration(self, td: datetime.timedelta) -> int: return int(td.total_seconds() // 60) def _deserialize_meetings_response(self, response): @@ -76,30 +87,42 @@ def _deserialize_meetings_response(self, response): Deserializes data in the structure where needed (currently, that's time-related structures) """ - for session_data in response['rooms'].values(): - session_data['room']['start_time'] = self._deserialize_time(session_data['room']['start_time']) - session_data['room']['duration'] = self._deserialize_duration(session_data['room']['duration']) + for session_data in response["rooms"].values(): + session_data["room"]["start_time"] = self._deserialize_time( + session_data["room"]["start_time"] + ) + session_data["room"]["duration"] = self._deserialize_duration( + session_data["room"]["duration"] + ) return response def retrieve_wg_tokens(self, acronyms: Union[str, Sequence[str]]): """Retrieve API tokens for one or more WGs - :param acronyms: list of WG acronyms for which tokens are requested + :param acronyms: list of WG acronyms for which tokens are requested :return: {'tokens': {acronym0: token0, acronym1: token1, ...}} """ return self._request( - 'POST', 'auth/ietfservice/tokens', + "POST", + "auth/ietfservice/tokens", json={ - 'client': self.client_id, - 'secret': self.client_secret, - 'wgs': [acronyms] if isinstance(acronyms, str) else acronyms, - } + "client": self.client_id, + "secret": self.client_secret, + "wgs": [acronyms] if isinstance(acronyms, str) else acronyms, + }, ) - def schedule_meeting(self, wg_token: str, description: str, start_time: datetime, duration: timedelta, - extrainfo=''): + def schedule_meeting( + self, + wg_token: str, + room_id: int, + description: str, + start_time: datetime.datetime, + duration: datetime.timedelta, + extrainfo="", + ): """Schedule a meeting session - + Return structure is: { "rooms": { @@ -115,8 +138,9 @@ def schedule_meeting(self, wg_token: str, description: str, start_time: datetime } } } - - :param wg_token: token retrieved via retrieve_wg_tokens() + + :param wg_token: token retrieved via retrieve_wg_tokens() + :param room_id: int id to identify the room (will be echoed as room.id) :param description: str describing the meeting :param start_time: starting time as a datetime :param duration: duration as a timedelta @@ -125,13 +149,15 @@ def schedule_meeting(self, wg_token: str, description: str, start_time: datetime """ return self._deserialize_meetings_response( self._request( - 'POST', 'meeting/interim/createRoom', + "POST", + "meeting/interim/createRoom", api_token=wg_token, json={ - 'description': description, - 'start_time': self._serialize_time(start_time), - 'duration': self._serialize_duration(duration), - 'extrainfo': extrainfo, + "room_id": room_id, + "description": description, + "start_time": self._serialize_time(start_time), + "duration": self._serialize_duration(duration), + "extrainfo": extrainfo, }, ) ) @@ -154,7 +180,7 @@ def fetch_meetings(self, wg_token: str): } } } - + As of 2022-01-31, the return structure also includes a 'group' key whose value is the group acronym. This is not shown in the documentation. @@ -162,7 +188,7 @@ def fetch_meetings(self, wg_token: str): :return: meeting data dict """ return self._deserialize_meetings_response( - self._request('GET', 'meeting/interim/fetchRooms', api_token=wg_token) + self._request("GET", "meeting/interim/fetchRooms", api_token=wg_token) ) def delete_meeting(self, deletion_token: str): @@ -171,7 +197,166 @@ def delete_meeting(self, deletion_token: str): :param deletion_token: deletion_key from fetch_meetings() or schedule_meeting() return data :return: {} """ - return self._request('POST', 'meeting/interim/deleteRoom', api_token=deletion_token) + return self._request( + "POST", "meeting/interim/deleteRoom", api_token=deletion_token + ) + + class SlideDeckDict(TypedDict): + id: int + title: str + url: str + rev: str + order: int + + def add_slide_deck( + self, + wg_token: str, + session: str, # unique identifier + deck: SlideDeckDict, + ): + """Add a slide deck for the specified session + + API spec: + ⠀POST /materials + + Authentication -> same as interim scheduler + + content application/json + + body + { + "session": String, // Unique session identifier + "title": String, + "id": Number, + "url": String, + "rev": String, + "order": Number + } + + + Results + 202 Accepted + {4xx} + """ + self._request( + "POST", + "materials", + api_token=wg_token, + json={ + "session": session, + "title": deck["title"], + "id": deck["id"], + "url": deck["url"], + "rev": deck["rev"], + "order": deck["order"], + }, + ) + + def delete_slide_deck( + self, + wg_token: str, + session: str, # unique identifier + id: int, + ): + """Delete a slide deck from the specified session + + API spec: + DELETE /materials + + Authentication -> same as interim scheduler + + content application/json + + body + { + "session": String, + "id": Number + } + + + Results + 202 Accepted + {4xx} + """ + self._request( + "DELETE", + "materials", + api_token=wg_token, + json={ + "session": session, + "id": id, + }, + ) + + def update_slide_decks( + self, + wg_token: str, + session: str, # unique id + decks: list[SlideDeckDict], + ): + """Update/reorder decks for specified session + + PUT /materials + + Authentication -> same as interim scheduler + + content application/json + + body + { + "session": String, + "decks": [ + { + "id": Number, + "title": String, + "url": String, + "rev": String, + "order": Number + }, + { + "id": Number, + "title": String, + "url": String, + "rev": String, + "order": Number + }, + ... + ] + } + + + Results + 202 Accepted + """ + self._request( + "PUT", + "materials", + api_token=wg_token, + json={ + "session": session, + "decks": decks, + } + ) + + +class DebugMeetechoAPI(MeetechoAPI): + """Meetecho API stand-in that writes to stdout instead of making requests""" + def _request(self, method, url, api_token=None, json=None): + json_lines = pformat(json, width=60).split("\n") + debug.say( + "\n" + + "\n".join( + [ + f">> MeetechoAPI: request(method={method},", + f">> MeetechoAPI: url={url},", + f">> MeetechoAPI: api_token={api_token},", + ">> MeetechoAPI: json=" + json_lines[0], + ( + ">> MeetechoAPI: " + + "\n>> MeetechoAPI: ".join(l for l in json_lines[1:]) + ), + ">> MeetechoAPI: )" + ] + ) + ) + + def retrieve_wg_tokens(self, acronyms: Union[str, Sequence[str]]): + super().retrieve_wg_tokens(acronyms) # so that we capture the outgoing request + acronyms = [acronyms] if isinstance(acronyms, str) else acronyms + return { + "tokens": { + acro: f"{acro}-token" + for acro in acronyms + } + } class MeetechoAPIError(Exception): @@ -180,7 +365,18 @@ class MeetechoAPIError(Exception): class Conference: """Scheduled session/room representation""" - def __init__(self, manager, id, public_id, description, start_time, duration, url, deletion_token): + + def __init__( + self, + manager, + id, + public_id, + description, + start_time, + duration, + url, + deletion_token, + ): self._manager = manager self.id = id # Meetecho system ID self.public_id = public_id # public session UUID @@ -195,22 +391,23 @@ def from_api_dict(cls, manager, api_dict): # Returns a list of Conferences return [ cls( - **val['room'], + **val["room"], public_id=public_id, - url=val['url'], - deletion_token=val['deletion_token'], + url=val["url"], + deletion_token=val["deletion_token"], manager=manager, - ) for public_id, val in api_dict.items() + ) + for public_id, val in api_dict.items() ] def __str__(self): - return f'Meetecho conference {self.description}' + return f"Meetecho conference {self.description}" def __repr__(self): props = [ f'description="{self.description}"', - f'start_time={repr(self.start_time)}', - f'duration={repr(self.duration)}', + f"start_time={repr(self.start_time)}", + f"duration={repr(self.duration)}", ] return f'Conference({", ".join(props)})' @@ -218,8 +415,13 @@ def __eq__(self, other): return isinstance(other, type(self)) and all( getattr(self, attr) == getattr(other, attr) for attr in [ - 'id', 'public_id', 'description', 'start_time', - 'duration', 'url', 'deletion_token' + "id", + "public_id", + "description", + "start_time", + "duration", + "url", + "deletion_token", ] ) @@ -227,37 +429,182 @@ def delete(self): self._manager.delete_conference(self) -class ConferenceManager: - def __init__(self, api_config: dict): - self.api = MeetechoAPI(**api_config) - self.wg_tokens: Dict[str, str] = {} - +class Manager: + def __init__(self, api_config): + api_kwargs = dict( + api_base=api_config["api_base"], + client_id=api_config["client_id"], + client_secret=api_config["client_secret"], + ) + if "request_timeout" in api_config: + api_kwargs["request_timeout"] = api_config["request_timeout"] + if api_config.get("debug", False): + self.api = DebugMeetechoAPI(**api_kwargs) + else: + self.api = MeetechoAPI(**api_kwargs) + self.wg_tokens = {} + def wg_token(self, group): - group_acronym = group.acronym if hasattr(group, 'acronym') else group + group_acronym = group.acronym if hasattr(group, "acronym") else group if group_acronym not in self.wg_tokens: - self.wg_tokens[group_acronym] = self.api.retrieve_wg_tokens( - group_acronym - )['tokens'][group_acronym] + self.wg_tokens[group_acronym] = self.api.retrieve_wg_tokens(group_acronym)[ + "tokens" + ][group_acronym] return self.wg_tokens[group_acronym] + +class ConferenceManager(Manager): def fetch(self, group): response = self.api.fetch_meetings(self.wg_token(group)) - return Conference.from_api_dict(self, response['rooms']) + return Conference.from_api_dict(self, response["rooms"]) - def create(self, group, description, start_time, duration, extrainfo=''): + def create(self, group, session_id, description, start_time, duration, extrainfo=""): response = self.api.schedule_meeting( wg_token=self.wg_token(group), + room_id=int(session_id), description=description, start_time=start_time, duration=duration, extrainfo=extrainfo, ) - return Conference.from_api_dict(self, response['rooms']) - + return Conference.from_api_dict(self, response["rooms"]) + def delete_by_url(self, group, url): for conf in self.fetch(group): if conf.url == url: self.api.delete_meeting(conf.deletion_token) def delete_conference(self, conf: Conference): - self.api.delete_meeting(conf.deletion_token) \ No newline at end of file + self.api.delete_meeting(conf.deletion_token) + + +class SlidesManager(Manager): + """Interface between Datatracker models and Meetecho API + + Note: the URL sent for a slide deck comes from DocumentInfo.get_href() and includes the revision + of the slides being sent. Be sure that 1) the URL matches what api_get_session_materials() returns + for the slides; and 2) the URL is valid if it is fetched immediately - possibly even before the call + to SlidesManager.add() or send_update() returns. + """ + + def __init__(self, api_config): + super().__init__(api_config) + slides_notify_time = api_config.get("slides_notify_time", 15) + if slides_notify_time is None: + self.slides_notify_time = None + else: + self.slides_notify_time = datetime.timedelta(minutes=slides_notify_time) + + def _should_send_update(self, session): + if self.slides_notify_time is None: + return False + timeslot = session.official_timeslotassignment().timeslot + if timeslot is None: + return False + if self.slides_notify_time < datetime.timedelta(0): + return True # < 0 means "always" for a scheduled session + else: + now = datetime.datetime.now(tz=datetime.UTC) + return (timeslot.time - self.slides_notify_time) < now < (timeslot.end_time() + self.slides_notify_time) + + def add(self, session: "Session", slides: "Document", order: int): + """Add a slide deck to the session + + Returns True if the update was sent, False if it was not sent because the + current time is outside the update window for the session. + """ + if not self._should_send_update(session): + return False + + # Would like to confirm that session.presentations includes the slides Document, but we can't + # (same problem regarding unsaved Documents discussed in the docstring) + self.api.add_slide_deck( + wg_token=self.wg_token(session.group), + session=str(session.pk), + deck={ + "id": slides.pk, + "title": slides.title, + "url": slides.get_href(), + "rev": slides.rev, + "order": order, + } + ) + return True + + def delete(self, session: "Session", slides: "Document"): + """Delete a slide deck from the session + + Returns True if the update was sent, False if it was not sent because the + current time is outside the update window for the session. + """ + if not self._should_send_update(session): + return False + + if session.presentations.filter(document=slides).exists(): + # "order" problems are very likely to result if we delete slides that are actually still + # linked to the session + raise MeetechoAPIError( + f"Slides {slides.pk} are still linked to session {session.pk}." + ) + # remove, leaving a hole + self.api.delete_slide_deck( + wg_token=self.wg_token(session.group), + session=str(session.pk), + id=slides.pk, + ) + if session.presentations.filter(document__type_id="slides").exists(): + self._send_update(session) # adjust order to fill in the hole + return True + + def revise(self, session: "Session", slides: "Document"): + """Replace existing deck with its current state + + Returns True if the update was sent, False if it was not sent because the + current time is outside the update window for the session. + """ + if not self._should_send_update(session): + return False + + sp = session.presentations.filter(document=slides).first() + if sp is None: + raise MeetechoAPIError(f"Slides {slides.pk} not in session {session.pk}") + order = sp.order + # remove, leaving a hole in the order on Meetecho's side + self.api.delete_slide_deck( + wg_token=self.wg_token(session.group), + session=str(session.pk), + id=slides.pk, + ) + self.add(session, slides, order) # fill in the hole + return True + + def _send_update(self, session: "Session"): + """Notify of the current state of the session's slides (no time window check) + + This is a private helper - use send_update() (no leading underscore) instead. + """ + self.api.update_slide_decks( + wg_token=self.wg_token(session.group), + session=str(session.pk), + decks=[ + { + "id": deck.document.pk, + "title": deck.document.title, + "url": deck.document.get_href(), + "rev": deck.document.rev, + "order": deck.order, + } + for deck in session.presentations.filter(document__type="slides") + ] + ) + + def send_update(self, session: "Session"): + """Notify of the current state of the session's slides + + Returns True if the update was sent, False if it was not sent because the + current time is outside the update window for the session. + """ + if not self._should_send_update(session): + return False + self._send_update(session) + return True diff --git a/ietf/utils/migrations/0001_initial.py b/ietf/utils/migrations/0001_initial.py index 87cb7528733..877e75f971d 100644 --- a/ietf/utils/migrations/0001_initial.py +++ b/ietf/utils/migrations/0001_initial.py @@ -1,10 +1,6 @@ -# Copyright The IETF Trust 2018-2020, All Rights Reserved -# -*- coding: utf-8 -*- -# Generated by Django 1.11.10 on 2018-02-20 10:52 - - -from typing import List, Tuple # pyflakes:ignore +# Generated by Django 2.2.28 on 2023-03-20 19:22 +from typing import List, Tuple from django.db import migrations, models @@ -12,8 +8,8 @@ class Migration(migrations.Migration): initial = True - dependencies = [ - ] # type: List[Tuple[str]] + dependencies: List[Tuple[str, str]] = [ + ] operations = [ migrations.CreateModel( diff --git a/ietf/utils/migrations/0002_delete_versioninfo.py b/ietf/utils/migrations/0002_delete_versioninfo.py new file mode 100644 index 00000000000..2835bb017b5 --- /dev/null +++ b/ietf/utils/migrations/0002_delete_versioninfo.py @@ -0,0 +1,16 @@ +# Generated by Django 4.2.11 on 2024-05-03 21:03 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ("utils", "0001_initial"), + ] + + operations = [ + migrations.DeleteModel( + name="VersionInfo", + ), + ] diff --git a/ietf/utils/migrations/0003_dirtybits.py b/ietf/utils/migrations/0003_dirtybits.py new file mode 100644 index 00000000000..11f6ed09f6f --- /dev/null +++ b/ietf/utils/migrations/0003_dirtybits.py @@ -0,0 +1,37 @@ +# Copyright The IETF Trust 2026, All Rights Reserved + +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("utils", "0002_delete_versioninfo"), + ] + + operations = [ + migrations.CreateModel( + name="DirtyBits", + fields=[ + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "slug", + models.CharField( + choices=[("rfcindex", "RFC Index")], max_length=40, unique=True + ), + ), + ("dirty_time", models.DateTimeField(blank=True, null=True)), + ("processed_time", models.DateTimeField(blank=True, null=True)), + ], + options={ + "verbose_name_plural": "dirty bits", + }, + ), + ] diff --git a/ietf/utils/migrations/0004_alter_dirtybits_slug.py b/ietf/utils/migrations/0004_alter_dirtybits_slug.py new file mode 100644 index 00000000000..e17ea6cadd3 --- /dev/null +++ b/ietf/utils/migrations/0004_alter_dirtybits_slug.py @@ -0,0 +1,21 @@ +# Copyright The IETF Trust 2026, All Rights Reserved + +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("utils", "0003_dirtybits"), + ] + + operations = [ + migrations.AlterField( + model_name="dirtybits", + name="slug", + field=models.CharField( + choices=[("rfcindex", "RFC Index"), ("errata", "Errata Tags")], + max_length=40, + unique=True, + ), + ), + ] diff --git a/ietf/utils/mime.py b/ietf/utils/mime.py index ab21cfe5c62..1f9b75b4dfa 100644 --- a/ietf/utils/mime.py +++ b/ietf/utils/mime.py @@ -5,6 +5,7 @@ import magic import re + def get_mime_type(content): # try to fixup encoding if hasattr(magic, "open"): @@ -13,15 +14,17 @@ def get_mime_type(content): filetype = m.buffer(content) else: m = magic.Magic() - m.cookie = magic.magic_open(magic.MAGIC_NONE | magic.MAGIC_MIME | magic.MAGIC_MIME_ENCODING) + m.cookie = magic.magic_open( + magic.MAGIC_NONE | magic.MAGIC_MIME | magic.MAGIC_MIME_ENCODING + ) magic.magic_load(m.cookie, None) filetype = m.from_buffer(content) # Work around silliness in libmagic on OpenSUSE 15.1 - filetype = filetype.replace('text/x-Algol68;', 'text/plain;') - if ';' in filetype and 'charset=' in filetype: - mimetype, charset = re.split('; *charset=', filetype) + filetype = filetype.replace("text/x-Algol68;", "text/plain;") + filetype = filetype.replace("application/vnd.hp-HPGL;", "text/plain;") + if ";" in filetype and "charset=" in filetype: + mimetype, charset = re.split("; *charset=", filetype) else: - mimetype = re.split(';', filetype)[0] - charset = 'utf-8' + mimetype = re.split(";", filetype)[0] + charset = "utf-8" return mimetype, charset - diff --git a/ietf/utils/models.py b/ietf/utils/models.py index 0915537fd83..64f7f253f29 100644 --- a/ietf/utils/models.py +++ b/ietf/utils/models.py @@ -1,22 +1,35 @@ -# Copyright The IETF Trust 2015-2020, All Rights Reserved +# Copyright The IETF Trust 2015-2026, All Rights Reserved import itertools from django.db import models + +class DirtyBits(models.Model): + """A weak semaphore mechanism for coordination with celery beat tasks + + Web workers will set the "dirty_time" value for a given dirtybit slug. + Celery workers will do work if "processed_time" < "dirty_time" and update + "processed_time". + """ + + class Slugs(models.TextChoices): + RFCINDEX = "rfcindex", "RFC Index" + ERRATA = "errata", "Errata Tags" + + # next line can become `...choices=Slugs)` when we get to Django 5.x + slug = models.CharField(max_length=40, blank=False, choices=Slugs.choices, unique=True) + dirty_time = models.DateTimeField(null=True, blank=True) + processed_time = models.DateTimeField(null=True, blank=True) + + class Meta: + verbose_name_plural = "dirty bits" + + class DumpInfo(models.Model): date = models.DateTimeField() host = models.CharField(max_length=128) tz = models.CharField(max_length=32, default='UTC') - -class VersionInfo(models.Model): - time = models.DateTimeField(auto_now=True) - command = models.CharField(max_length=32) - switch = models.CharField(max_length=16) - version = models.CharField(max_length=64) - used = models.BooleanField(default=True) - class Meta: - verbose_name_plural = 'VersionInfo' class ForeignKey(models.ForeignKey): "A local ForeignKey proxy which provides the on_delete value required under Django 2.0." diff --git a/ietf/utils/patch.py b/ietf/utils/patch.py index d14a3400541..fd3e4a165d4 100644 --- a/ietf/utils/patch.py +++ b/ietf/utils/patch.py @@ -87,8 +87,7 @@ def createLock(self): debugmode = False def setdebug(): - global debugmode, streamhandler - + global debugmode debugmode = True loglevel = logging.DEBUG logformat = "%(levelname)8s %(message)s" @@ -185,7 +184,7 @@ def fromstring(s): def fromurl(url): """ Parse patch from an URL, return False - if an error occured. Note that this also + if an error occurred. Note that this also can throw urlopen() exceptions. """ ps = PatchSet( urllib_request.urlopen(url) ) @@ -749,7 +748,7 @@ def _normalize_filenames(self): def diffstat(self): """ calculate diffstat and return as a string Notes: - - original diffstat ouputs target filename + - original diffstat outputs target filename - single + or - shouldn't escape histogram """ names = [] @@ -1181,7 +1180,7 @@ def main(): patch.apply(options.strip, root=options.directory.encode()) or sys.exit(-1) # todo: document and test line ends handling logic - patch.py detects proper line-endings - # for inserted hunks and issues a warning if patched file has incosistent line ends + # for inserted hunks and issues a warning if patched file has inconsistent line ends if __name__ == "__main__": diff --git a/ietf/utils/pipe.py b/ietf/utils/pipe.py index 907e4af5fca..b3ac1cebf3e 100644 --- a/ietf/utils/pipe.py +++ b/ietf/utils/pipe.py @@ -12,23 +12,23 @@ def pipe(cmd, str=None): if str and len(str) > 4096: # XXX: Hardcoded Linux 2.4, 2.6 pipe buffer size bufsize = len(str) - pipe = Popen(cmd, stdin=PIPE, stdout=PIPE, stderr=PIPE, bufsize=bufsize, shell=True) - if not str is None: - pipe.stdin.write(str) - pipe.stdin.close() + with Popen(cmd, stdin=PIPE, stdout=PIPE, stderr=PIPE, bufsize=bufsize, shell=True) as pipe: + if not str is None: + pipe.stdin.write(str) + pipe.stdin.close() - out = b"" - err = b"" - while True: - str = pipe.stdout.read() - if str: - out += str - code = pipe.poll() - if code != None: - err = pipe.stderr.read() - break - if len(out) >= MAX: - err = "Output exceeds %s bytes and has been truncated" % MAX - break + out = b"" + err = b"" + while True: + str = pipe.stdout.read() + if str: + out += str + code = pipe.poll() + if code != None: + err = pipe.stderr.read() + break + if len(out) >= MAX: + err = "Output exceeds %s bytes and has been truncated" % MAX + break return (code, out, err) diff --git a/ietf/utils/reports.py b/ietf/utils/reports.py new file mode 100755 index 00000000000..9a969a52178 --- /dev/null +++ b/ietf/utils/reports.py @@ -0,0 +1,49 @@ +# Copyright The IETF Trust 2023-2026, All Rights Reserved + +from typing import List, Set, Tuple +from django.db.models import QuerySet + +from email.utils import parseaddr + +from ietf.person.models import Person +from ietf.submit.models import Submission + + +def authors_by_year(year: int) -> Set[str]: + """Email addresses provided by I-D authors for drafts that were submitted in the given year.""" + addresses = set() + for submission in Submission.objects.filter( + submission_date__year=year, state="posted" + ): + addresses.update([a["email"] for a in submission.authors]) + return addresses + + +def submitters_by_year(year: int) -> Set[str]: + """Email addresses provided by I-D submitters for drafts that were submitted in the given year.""" + return set( + [ + parseaddr(a)[1] + for a in Submission.objects.filter( + submitter__contains="@", submission_date__year=year, state="posted" + ).values_list("submitter", flat=True) + ] + ) + + +def unique_people(addresses: List[str]) -> Tuple["QuerySet[Person]", Set]: + """Identify Person records matching email addresses and email addresses with no Person record. + + Given a list of email addresses, return + ( + a list of unique Person records with a matching email address, + a list of unique email addresses with no matching Person record + ) + The sum of the lengths of these lists is a best-approximation for how + many unique people the list of addresses belong to. + """ + persons = Person.objects.filter(email__address__in=addresses).distinct() + known_email = set(persons.values_list("email__address", flat=True)) + return (persons, set(addresses) - set(known_email)) + + diff --git a/ietf/utils/resources.py b/ietf/utils/resources.py index 6d61c5e2ed5..63206eb33a7 100644 --- a/ietf/utils/resources.py +++ b/ietf/utils/resources.py @@ -1,6 +1,4 @@ -# Copyright The IETF Trust 2014-2019, All Rights Reserved -# -*- coding: utf-8 -*- -# Autogenerated by the mkresources management command 2014-11-13 05:39 +# Copyright The IETF Trust 2014-2026, All Rights Reserved from ietf.api import ModelResource @@ -12,7 +10,7 @@ from django.contrib.contenttypes.models import ContentType from ietf import api -from ietf.utils.models import DumpInfo, VersionInfo +from ietf.utils.models import DirtyBits, DumpInfo class UserResource(ModelResource): @@ -45,19 +43,7 @@ class Meta: api.utils.register(DumpInfoResource()) -class VersionInfoResource(ModelResource): +class DirtyBitsResource(ModelResource): class Meta: - queryset = VersionInfo.objects.all() - serializer = api.Serializer() - cache = SimpleCache() - #resource_name = 'versioninfo' - ordering = ['id', ] - filtering = { - "id": ALL, - "time": ALL, - "command": ALL, - "switch": ALL, - "version": ALL, - "used": ALL, - } -api.utils.register(VersionInfoResource()) + queryset = DirtyBits.objects.none() +api.utils.register(DirtyBitsResource()) diff --git a/ietf/utils/searchindex.py b/ietf/utils/searchindex.py new file mode 100644 index 00000000000..0565b50272f --- /dev/null +++ b/ietf/utils/searchindex.py @@ -0,0 +1,425 @@ +# Copyright The IETF Trust 2026, All Rights Reserved +"""Search indexing utilities""" + +import re +from itertools import batched +from math import floor +from typing import Iterable +from urllib.parse import urljoin + +import httpx # just for exceptions +import requests +import typesense +import typesense.exceptions +from django.conf import settings +from typesense.types.document import DocumentSchema + +from ietf.doc.models import Document, StoredObject +from ietf.doc.storage_utils import retrieve_str +from ietf.utils.log import log + +# Error classes that might succeed just by retrying a failed attempt. +# Must be a tuple for use with isinstance() +RETRYABLE_ERROR_CLASSES = ( + httpx.ConnectError, + httpx.ConnectTimeout, + typesense.exceptions.Timeout, + typesense.exceptions.ServerError, + typesense.exceptions.ServiceUnavailable, +) + +DEFAULT_SETTINGS = { + "TYPESENSE_API_URL": "", + "TYPESENSE_API_KEY": "", + "TYPESENSE_COLLECTION_NAME": "docs", + "TASK_RETRY_DELAY": 10, + "TASK_MAX_RETRIES": 12, +} + + +def get_settings(): + return DEFAULT_SETTINGS | getattr(settings, "SEARCHINDEX_CONFIG", {}) + + +def enabled(): + _settings = get_settings() + return _settings["TYPESENSE_API_URL"] != "" + + +def get_typesense_client() -> typesense.Client: + _settings = get_settings() + client = typesense.Client( + { + "api_key": _settings["TYPESENSE_API_KEY"], + "nodes": [_settings["TYPESENSE_API_URL"]], + } + ) + return client + + +def get_collection_name() -> str: + _settings = get_settings() + collection_name = _settings["TYPESENSE_COLLECTION_NAME"] + assert isinstance(collection_name, str) + return collection_name + + +def _sanitize_text(content: str): + """Sanitize content text for search + + Aggressively simplifies whitespace, removes most punctuation + """ + # REs (with approximate names) + RE_DOT_OR_BANG_SPACE = r"\. |! " # -> " " (space) + RE_COMMENT_OR_TOC_CRUD = r"<--|-->|--+|\+|\.\.+" # -> "" + RE_BRACKETED_REF = r"\[[a-zA-Z0-9 -]+\]" # -> "" + RE_DOTTED_NUMBERS = r"[0-9]+\.[0-9]+(\.[0-9]+)?" # -> "" + RE_MULTIPLE_WHITESPACE = r"\s+" # -> " " (space) + # Replacement values (for clarity of intent) + SPACE = " " + EMPTY = "" + # Sanitizing begins here, order is significant! + content = re.sub(RE_DOT_OR_BANG_SPACE, SPACE, content.strip()) + content = re.sub(RE_COMMENT_OR_TOC_CRUD, EMPTY, content) + content = re.sub(RE_BRACKETED_REF, EMPTY, content) + content = re.sub(RE_DOTTED_NUMBERS, EMPTY, content) + content = re.sub(RE_MULTIPLE_WHITESPACE, SPACE, content) + return content.strip() + + +def _sanitize_abstract(abstract: str): + """Sanitize abstract text for search + + Simplifies whitespace but mostly leaves text intact. Abstract text will be + displayed in search results, so a light touch is needed. + """ + abstract = abstract.strip() + abstract = re.sub("\r\n|\n\r|\r", "\n", abstract) # normalize on \n + abstract = "\n".join(line.strip() for line in abstract.split("\n")) # strip by line + return abstract + + +def typesense_doc_from_rfc(rfc: Document) -> DocumentSchema: + assert rfc.type_id == "rfc" + assert rfc.rfc_number is not None + assert rfc.pages is not None + + keywords: list[str] = rfc.keywords # help type checking + + subseries = rfc.part_of() + if len(subseries) > 1: + log( + f"RFC {rfc.rfc_number} is in multiple subseries. " + f"Indexing as {subseries[0].name}" + ) + subseries = subseries[0] if len(subseries) > 0 else None + obsoleted_by = rfc.related_that("obs") + is_obsoleted = len(obsoleted_by) > 0 + updated_by = rfc.related_that("updates") + is_updated = len(updated_by) > 0 + is_historic = rfc.std_level.slug == "hist" + + stored_txt = ( + StoredObject.objects.exclude_deleted() + .filter(store="rfc", doc_name=rfc.name, name__startswith="txt/") + .first() + ) + content = "" + if stored_txt is not None: + # Should be available in the blobdb, but be cautious... + try: + content = retrieve_str(kind=stored_txt.store, name=stored_txt.name) + except Exception as err: + log(f"Unable to retrieve {stored_txt} from storage: {err}") + + ts_document = { + "id": f"doc-{rfc.pk}", + "rfcNumber": rfc.rfc_number, + "rfc": str(rfc.rfc_number), + "filename": rfc.name, + "title": rfc.title, + "abstract": _sanitize_abstract(rfc.abstract), + "pages": rfc.pages, + "keywords": keywords, + "type": "rfc", + "state": [state.name for state in rfc.states.all()], + "status": {"slug": rfc.std_level.slug, "name": rfc.std_level.name}, + "date": floor(rfc.time.timestamp()), + "publicationDate": floor(rfc.pub_datetime().timestamp()), + "stream": {"slug": rfc.stream.slug, "name": rfc.stream.name}, + "authors": [ + {"name": rfc_author.titlepage_name, "affiliation": rfc_author.affiliation} + for rfc_author in rfc.rfcauthor_set.all() + ], + "flags": { + "hiddenDefault": is_obsoleted or is_historic, + "obsoleted": is_obsoleted, + "updated": is_updated, + }, + "obsoletedBy": [str(doc.rfc_number) for doc in obsoleted_by], + "updatedBy": [str(doc.rfc_number) for doc in updated_by], + "ranking": rfc.rfc_number, + } + if subseries is not None: + ts_document["subseries"] = { + "acronym": subseries.type.slug, + "number": int(subseries.name[len(subseries.type.slug):]), + "total": len(subseries.contains()), + } + if rfc.group is not None: + ts_document["group"] = { + "acronym": rfc.group.acronym, + "name": rfc.group.name, + "full": f"{rfc.group.acronym} - {rfc.group.name}", + "type": rfc.group.type.slug, + } + if ( + rfc.group.parent is not None + and rfc.stream_id not in ["ise", "irtf", "iab"] # exclude editorial? + ): + ts_document["area"] = { + "acronym": rfc.group.parent.acronym, + "name": rfc.group.parent.name, + "full": f"{rfc.group.parent.acronym} - {rfc.group.parent.name}", + } + if rfc.ad is not None: + ts_document["adName"] = rfc.ad.name + if content != "": + ts_document["content"] = _sanitize_text(content) + return ts_document + + +def update_or_create_rfc_entry(rfc: Document): + """Update/create index entries for one RFC""" + ts_document = typesense_doc_from_rfc(rfc) + client = get_typesense_client() + client.collections[get_collection_name()].documents.upsert(ts_document) + + +def update_or_create_rfc_entries( + rfcs: Iterable[Document], batchsize: int | None = None +): + """Update/create index entries for RFCs in bulk + + If batchsize is set, computes index data in batches of batchsize and adds to the + index. Will make a total of (len(rfcs) // batchsize) + 1 API calls. + + N.b. that typesense has a server-side batch size that defaults to 40, which should + "almost never be changed from the default." This does not change that. Further, + the python client library's import_ method has a batch_size parameter that does + client-side batching. We don't use that, either. + """ + success_count = 0 + fail_count = 0 + client = get_typesense_client() + batches = [rfcs] if batchsize is None else batched(rfcs, batchsize) + for batch in batches: + tdoc_batch = [typesense_doc_from_rfc(rfc) for rfc in batch] + results = client.collections[get_collection_name()].documents.import_( + tdoc_batch, {"action": "upsert"} + ) + for tdoc, result in zip(tdoc_batch, results): + if result["success"]: + success_count += 1 + else: + fail_count += 1 + log(f"Failed to index RFC {tdoc['rfcNumber']}: {result['error']}") + log(f"Added {success_count} RFCs to the index, failed to add {fail_count}") + + +DOCS_SCHEMA = { + "enable_nested_fields": True, + "default_sorting_field": "ranking", + "fields": [ + # RFC number in integer form, for sorting asc/desc in search results + # Omit field for drafts + { + "name": "rfcNumber", + "type": "int32", + "facet": False, + "optional": True, + "sort": True, + }, + # RFC number in string form, for direct matching with ranking + # Omit field for drafts + {"name": "rfc", "type": "string", "facet": False, "optional": True}, + # For drafts that correspond to an RFC, insert the RFC number + # Omit field for rfcs or if not relevant + {"name": "ref", "type": "string", "facet": False, "optional": True}, + # Filename of the document (without the extension, e.g. "rfc1234" + # or "draft-ietf-abc-def-02") + {"name": "filename", "type": "string", "facet": False, "infix": True}, + # Title of the draft / rfc + {"name": "title", "type": "string", "facet": False}, + # Abstract of the draft / rfc + {"name": "abstract", "type": "string", "facet": False}, + # Number of pages + {"name": "pages", "type": "int32", "facet": False}, + # A list of search keywords if relevant, set to empty array otherwise + {"name": "keywords", "type": "string[]", "facet": True}, + # Type of the document + # Accepted values: "draft" or "rfc" + {"name": "type", "type": "string", "facet": True}, + # State(s) of the document (e.g. "Published", "Adopted by a WG", etc.) + # Use the full name, not the slug + {"name": "state", "type": "string[]", "facet": True, "optional": True}, + # Status (Standard Level Name) + # Object with properties "slug" and "name" + # e.g.: { slug: "std", "name": "Internet Standard" } + {"name": "status", "type": "object", "facet": True, "optional": True}, + # The subseries it is part of. (e.g. "BCP") + # Omit otherwise. + { + "name": "subseries.acronym", + "type": "string", + "facet": True, + "optional": True, + }, + # The subseries number it is part of. (e.g. 123) + # Omit otherwise. + { + "name": "subseries.number", + "type": "int32", + "facet": True, + "sort": True, + "optional": True, + }, + # The total of RFCs in the subseries + # Omit if not part of a subseries + { + "name": "subseries.total", + "type": "int32", + "facet": False, + "sort": False, + "optional": True, + }, + # Date of the document, in unix epoch seconds (can be negative for < 1970) + {"name": "date", "type": "int64", "facet": False}, + # Expiration date of the document, in unix epoch seconds (can be negative + # for < 1970). Omit field for RFCs + {"name": "expires", "type": "int64", "facet": False, "optional": True}, + # Publication date of the RFC, in unix epoch seconds (can be negative + # for < 1970). Omit field for drafts + { + "name": "publicationDate", + "type": "int64", + "facet": True, + "optional": True, + }, + # Working Group + # Object with properties "acronym", "name" and "full" + # e.g.: + # { + # "acronym": "ntp", + # "name": "Network Time Protocols", + # "full": "ntp - Network Time Protocols", + # } + {"name": "group", "type": "object", "facet": True, "optional": True}, + # Area + # Object with properties "acronym", "name" and "full" + # e.g.: + # { + # "acronym": "mpls", + # "name": "Multiprotocol Label Switching", + # "full": "mpls - Multiprotocol Label Switching", + # } + {"name": "area", "type": "object", "facet": True, "optional": True}, + # Stream + # Object with properties "slug" and "name" + # e.g.: { slug: "ietf", "name": "IETF" } + {"name": "stream", "type": "object", "facet": True, "optional": True}, + # List of authors + # Array of objects with properties "name" and "affiliation" + # e.g.: + # [ + # {"name": "John Doe", "affiliation": "ACME Inc."}, + # {"name": "Ada Lovelace", "affiliation": "Babbage Corps."}, + # ] + {"name": "authors", "type": "object[]", "facet": True, "optional": True}, + # Area Director Name (e.g. "Leonardo DaVinci") + {"name": "adName", "type": "string", "facet": True, "optional": True}, + # Whether the document should be hidden by default in search results or not. + {"name": "flags.hiddenDefault", "type": "bool", "facet": True}, + # Whether the document is obsoleted by another document or not. + {"name": "flags.obsoleted", "type": "bool", "facet": True}, + # Whether the document is updated by another document or not. + {"name": "flags.updated", "type": "bool", "facet": True}, + # List of documents that obsolete this document. + # Array of strings. Use RFC number for RFCs. (e.g. ["123", "456"]) + # Omit if none. Must be provided if "flags.obsoleted" is set to True. + { + "name": "obsoletedBy", + "type": "string[]", + "facet": False, + "optional": True, + }, + # List of documents that update this document. + # Array of strings. Use RFC number for RFCs. (e.g. ["123", "456"]) + # Omit if none. Must be provided if "flags.updated" is set to True. + {"name": "updatedBy", "type": "string[]", "facet": False, "optional": True}, + # Sanitized content of the document. + # Make sure to remove newlines, double whitespaces, symbols and tags. + { + "name": "content", + "type": "string", + "facet": False, + "optional": True, + "store": False, + }, + # Ranking value to use when no explicit sorting is used during search + # Set to the RFC number for RFCs and the revision number for drafts + # This ensures newer RFCs get listed first in the default search results + # (without a query) + {"name": "ranking", "type": "int32", "facet": False}, + ], +} + +SEARCH_PRESETS = { + "red": { + "collection": "docs", + "infix": "off,always,off,off,off,off,off,off", + "query_by": "rfc,filename,title,abstract,keywords,authors,group,area", + "query_by_weights": "127,50,50,20,20,5,2,1" + }, + "red-content": { + "collection": "docs", + "infix": "off,always,off,off,off,off,off,off,off", + "query_by": "rfc,filename,title,abstract,keywords,authors,group,area,content", + "query_by_weights": "127,50,50,20,20,5,2,1,1" + }, +} + + +def create_collection(): + collection_name = get_collection_name() + log(f"Creating '{collection_name}' collection") + client = get_typesense_client() + client.collections.create({"name": get_collection_name()} | DOCS_SCHEMA) + + +def delete_collection(): + collection_name = get_collection_name() + log(f"Deleting '{collection_name}' collection") + client = get_typesense_client() + try: + client.collections[collection_name].delete() + except typesense.exceptions.ObjectNotFound: + pass + + +def upsert_presets(): + # typesense-python does not support presets, so use requests + _settings = get_settings() + api_base = _settings["TYPESENSE_API_URL"] + api_key = _settings["TYPESENSE_API_KEY"] + for preset_name, payload in SEARCH_PRESETS.items(): + log(f"Upserting '{preset_name}' preset") + response = requests.put( + urljoin(api_base, f"/presets/{preset_name}"), + json={"value": payload}, + headers={ + "X-TYPESENSE-API-KEY": api_key, + }, + timeout=3, + ) + response.raise_for_status() diff --git a/ietf/utils/serialize.py b/ietf/utils/serialize.py index 64254300a82..77f97942cbe 100644 --- a/ietf/utils/serialize.py +++ b/ietf/utils/serialize.py @@ -1,3 +1,5 @@ +import datetime + from django.db import models def object_as_shallow_dict(obj): @@ -14,7 +16,7 @@ def object_as_shallow_dict(obj): if isinstance(f, models.ManyToManyField): v = list(v.values_list("pk", flat=True)) elif isinstance(f, models.DateTimeField): - v = v.strftime('%Y-%m-%d %H:%M:%S') + v = v.astimezone(datetime.UTC).isoformat() elif isinstance(f, models.DateField): v = v.strftime('%Y-%m-%d') diff --git a/ietf/utils/storage.py b/ietf/utils/storage.py index 0aa02cab868..bad5af51786 100644 --- a/ietf/utils/storage.py +++ b/ietf/utils/storage.py @@ -1,8 +1,95 @@ +# Copyright The IETF Trust 2020-2025, All Rights Reserved +"""Django Storage classes""" +import datetime +from hashlib import sha384 +from pathlib import Path +from typing import Optional + +from django.conf import settings +from django.core.files.base import File from django.core.files.storage import FileSystemStorage +from ietf.doc.storage_utils import store_file +from .log import log + class NoLocationMigrationFileSystemStorage(FileSystemStorage): - def deconstruct(obj): # pylint: disable=no-self-argument - path, args, kwargs = FileSystemStorage.deconstruct(obj) - kwargs["location"] = None - return (path, args, kwargs) + def deconstruct(self): + path, args, kwargs = super().deconstruct() + kwargs["location"] = None # don't record location in migrations + return path, args, kwargs + + +class BlobShadowFileSystemStorage(NoLocationMigrationFileSystemStorage): + """FileSystemStorage that shadows writes to the blob store as well + + Strips directories from the filename when naming the blob. + """ + + def __init__( + self, + *, # disallow positional arguments + kind: str, + location=None, + base_url=None, + file_permissions_mode=None, + directory_permissions_mode=None, + ): + self.kind = kind + super().__init__( + location, base_url, file_permissions_mode, directory_permissions_mode + ) + + def save(self, name, content, max_length=None): + # Write content to the filesystem - this deals with chunks, etc... + saved_name = super().save(name, content, max_length) + + if settings.ENABLE_BLOBSTORAGE: + try: + # Retrieve the content and write to the blob store + blob_name = Path(saved_name).name # strips path + with self.open(saved_name, "rb") as f: + store_file(self.kind, blob_name, f, allow_overwrite=True) + except Exception as err: + log(f"Blobstore Error: Failed to shadow {saved_name} at {self.kind}:{blob_name}: {repr(err)}") + if settings.SERVER_MODE == "development": + raise + return saved_name # includes the path! + + def deconstruct(self): + path, args, kwargs = super().deconstruct() + kwargs["kind"] = "" # don't record "kind" in migrations + return path, args, kwargs + + +class MetadataFile(File): + """File that includes metadata""" + + def __init__(self, file, name=None, mtime: Optional[datetime.datetime]=None, content_type=""): + super().__init__(file=file, name=name) + self.mtime = mtime + self.content_type = content_type + self._custom_metadata = None + + @property + def custom_metadata(self): + if self._custom_metadata is None: + self._custom_metadata = self._compute_custom_metadata() + return self._custom_metadata + + def _compute_custom_metadata(self): + try: + self.file.seek(0) + except AttributeError: # TODO-BLOBSTORE + raise NotImplementedError("cannot handle unseekable content") + content_bytes = self.file.read() + if not isinstance( + content_bytes, bytes + ): # TODO-BLOBSTORE: This is sketch-development only -remove before committing + raise Exception(f"Expected bytes - got {type(content_bytes)}") + self.file.seek(0) + return { + "len": f"{len(content_bytes)}", + "sha384": f"{sha384(content_bytes).hexdigest()}", + "mtime": None if self.mtime is None else self.mtime.isoformat(), + } diff --git a/ietf/utils/templatetags/htmlfilters.py b/ietf/utils/templatetags/htmlfilters.py index a0f9232c575..1e399e2d727 100644 --- a/ietf/utils/templatetags/htmlfilters.py +++ b/ietf/utils/templatetags/htmlfilters.py @@ -7,6 +7,7 @@ from django.template.defaultfilters import stringfilter from ietf.utils.html import remove_tags +from ietf.utils.markdown import markdown as utils_markdown register = Library() @@ -16,3 +17,9 @@ def removetags(value, tags): """Removes a comma-separated list of [X]HTML tags from the output.""" return remove_tags(value, re.split(r"\s*,\s*", tags)) + +@register.filter(name="markdown", is_safe=True) +def markdown(string): + # One issue is that the string is enclosed in

    ... Let's remove the leading/trailing ones... + return utils_markdown(string)[3:-4] + diff --git a/ietf/utils/templatetags/tests.py b/ietf/utils/templatetags/tests.py index a93bf2d94d6..859319be3dc 100644 --- a/ietf/utils/templatetags/tests.py +++ b/ietf/utils/templatetags/tests.py @@ -3,6 +3,7 @@ from django.template import Context, Origin, Template from django.test import override_settings +from ietf.utils.templatetags.textfilters import linkify from ietf.utils.test_utils import TestCase import debug # pyflakes: ignore @@ -39,3 +40,68 @@ def test_origin_outside_base_dir(self): output = template.render(Context()) self.assertNotIn(component, output, 'Full path components should not be revealed in html') + + +class TextfiltersTests(TestCase): + def test_linkify(self): + # Cases with autoescape = True (the default) + self.assertEqual( + linkify("plain string"), + "plain string", + ) + self.assertEqual( + linkify("https://www.ietf.org"), + 'https://www.ietf.org', + ) + self.assertEqual( + linkify('IETF'), + ( + '<a href="https://www.ietf.org">IETF</a>' + ), + ) + self.assertEqual( + linkify("somebody@example.com"), + 'somebody@example.com', + ) + self.assertEqual( + linkify("Some Body "), + ( + 'Some Body <' + 'somebody@example.com>' + ), + ) + self.assertEqual( + linkify(""), + "<script>alert('h4x0r3d');</script>", + ) + + # Cases with autoescape = False (these are dangerous and assume the caller + # has sanitized already) + self.assertEqual( + linkify("plain string", autoescape=False), + "plain string", + ) + self.assertEqual( + linkify("https://www.ietf.org", autoescape=False), + 'https://www.ietf.org', + ) + self.assertEqual( + linkify('IETF', autoescape=False), + 'IETF', + ) + self.assertEqual( + linkify("somebody@example.com", autoescape=False), + 'somebody@example.com', + ) + # bleach.Linkifier translates the < -> < and > -> > on this one + self.assertEqual( + linkify("Some Body ", autoescape=False), + ( + 'Some Body <' + 'somebody@example.com>' + ), + ) + self.assertEqual( + linkify("", autoescape=False), + "", + ) diff --git a/ietf/utils/templatetags/textfilters.py b/ietf/utils/templatetags/textfilters.py index 70b94cf6739..e3bfbe0c562 100644 --- a/ietf/utils/templatetags/textfilters.py +++ b/ietf/utils/templatetags/textfilters.py @@ -7,11 +7,12 @@ from django import template from django.conf import settings from django.template.defaultfilters import stringfilter +from django.utils.html import conditional_escape from django.utils.safestring import mark_safe import debug # pyflakes:ignore -from ietf.utils.text import xslugify as _xslugify, texescape, bleach_linker +from ietf.utils.text import linkify as _linkify, xslugify as _xslugify, texescape register = template.Library() @@ -71,10 +72,13 @@ def texescape_filter(value): "A TeX escape filter" return texescape(value) -@register.filter +@register.filter(needs_autoescape=True) @stringfilter -def linkify(value): - text = mark_safe(bleach_linker.linkify(value)) +def linkify(value, autoescape=True): + if autoescape: + # Escape unless the input was already a SafeString + value = conditional_escape(value) + text = mark_safe(_linkify(value)) # _linkify is a safe operation return text @register.filter diff --git a/ietf/utils/test_data.py b/ietf/utils/test_data.py index 7a7a77af49b..c5d34727511 100644 --- a/ietf/utils/test_data.py +++ b/ietf/utils/test_data.py @@ -6,20 +6,23 @@ from django.conf import settings from django.contrib.auth.models import User -from django.utils.encoding import smart_text +from django.utils import timezone +from django.utils.encoding import smart_str import debug # pyflakes:ignore -from ietf.doc.models import Document, DocAlias, State, DocumentAuthor, DocEvent, RelatedDocument, NewRevisionDocEvent +from ietf.doc.models import Document, State, DocumentAuthor, DocEvent, RelatedDocument, NewRevisionDocEvent +from ietf.doc.factories import IndividualDraftFactory, ConflictReviewFactory, StatusChangeFactory, WgDraftFactory, WgRfcFactory from ietf.group.models import Group, GroupHistory, Role, RoleHistory from ietf.iesg.models import TelechatDate from ietf.ipr.models import HolderIprDisclosure, IprDocRel, IprDisclosureStateName, IprLicenseTypeName from ietf.meeting.models import Meeting, ResourceAssociation -from ietf.name.models import StreamName, DocRelationshipName, RoomResourceName, ConstraintName +from ietf.name.models import DocRelationshipName, RoomResourceName, ConstraintName from ietf.person.models import Person, Email from ietf.group.utils import setup_default_community_list_for_group from ietf.review.models import (ReviewRequest, ReviewerSettings, ReviewResultName, ReviewTypeName, ReviewTeamSettings ) from ietf.person.name import unidecode_name +from ietf.utils.timezone import date_today def create_person(group, role_name, name=None, username=None, email_address=None, password=None, is_staff=False, is_superuser=False): @@ -36,7 +39,7 @@ def create_person(group, role_name, name=None, username=None, email_address=None user = User.objects.create(username=username,is_staff=is_staff,is_superuser=is_superuser) user.set_password(password) user.save() - person = Person.objects.create(name=name, ascii=unidecode_name(smart_text(name)), user=user) + person = Person.objects.create(name=name, ascii=unidecode_name(smart_str(name)), user=user) email = Email.objects.create(address=email_address, person=person, origin=user.username) Role.objects.create(group=group, name_id=role_name, person=person, email=email) return person @@ -51,7 +54,7 @@ def make_immutable_base_data(): all tests in a run.""" # telechat dates - t = datetime.date.today() + datetime.timedelta(days=1) + t = date_today() + datetime.timedelta(days=1) old = TelechatDate.objects.create(date=t - datetime.timedelta(days=14)).date # pyflakes:ignore date1 = TelechatDate.objects.create(date=t).date # pyflakes:ignore date2 = TelechatDate.objects.create(date=t + datetime.timedelta(days=14)).date # pyflakes:ignore @@ -70,6 +73,10 @@ def make_immutable_base_data(): irtf = create_group(name="IRTF", acronym="irtf", type_id="irtf") create_person(irtf, "chair") + rsab = create_group(name="RSAB", acronym="rsab", type_id="edappr") + p = create_person(rsab, "chair") + p.role_set.create(group=rsab, name_id="member", email=p.email()) + secretariat = create_group(name="IETF Secretariat", acronym="secretariat", type_id="ietf") create_person(secretariat, "secr", name="Sec Retary", username="secretary", is_staff=True, is_superuser=True) @@ -77,7 +84,7 @@ def make_immutable_base_data(): create_person(iab, "chair") create_person(iab, "member") - ise = create_group(name="Independent Submission Editor", acronym="ise", type_id="rfcedtyp") + ise = create_group(name="Independent Submission Editor", acronym="ise", type_id="ise") create_person(ise, "chair") rsoc = create_group(name="RFC Series Oversight Committee", acronym="rsoc", type_id="rfcedtyp") @@ -170,7 +177,6 @@ def make_test_data(): charter.set_state(State.objects.get(used=True, slug="approved", type="charter")) group.charter = charter group.save() - DocAlias.objects.create(name=charter.name).docs.add(charter) setup_default_community_list_for_group(group) # ames WG @@ -192,7 +198,6 @@ def make_test_data(): rev="00", ) charter.set_state(State.objects.get(used=True, slug="infrev", type="charter")) - DocAlias.objects.create(name=charter.name).docs.add(charter) group.charter = charter group.save() setup_default_community_list_for_group(group) @@ -237,7 +242,6 @@ def make_test_data(): # rev="00", # ) #charter.set_state(State.objects.get(used=True, slug="infrev", type="charter")) - #DocAlias.objects.create(name=charter.name).docs.add(charter) #group.charter = charter #group.save() @@ -271,23 +275,21 @@ def make_test_data(): # old draft old_draft = Document.objects.create( name="draft-foo-mars-test", - time=datetime.datetime.now() - datetime.timedelta(days=settings.INTERNET_DRAFT_DAYS_TO_EXPIRE), + time=timezone.now() - datetime.timedelta(days=settings.INTERNET_DRAFT_DAYS_TO_EXPIRE), type_id="draft", title="Optimizing Martian Network Topologies", stream_id="ietf", abstract="Techniques for achieving near-optimal Martian networks.", rev="00", pages=2, - expires=datetime.datetime.now(), + expires=timezone.now(), ) old_draft.set_state(State.objects.get(used=True, type="draft", slug="expired")) - old_alias = DocAlias.objects.create(name=old_draft.name) - old_alias.docs.add(old_draft) # draft draft = Document.objects.create( name="draft-ietf-mars-test", - time=datetime.datetime.now(), + time=timezone.now(), type_id="draft", title="Optimizing Martian Network Topologies", stream_id="ietf", @@ -298,19 +300,15 @@ def make_test_data(): intended_std_level_id="ps", shepherd=email, ad=ad, - expires=datetime.datetime.now() + datetime.timedelta(days=settings.INTERNET_DRAFT_DAYS_TO_EXPIRE), + expires=timezone.now() + datetime.timedelta(days=settings.INTERNET_DRAFT_DAYS_TO_EXPIRE), notify="aliens@example.mars", - note="", ) draft.set_state(State.objects.get(used=True, type="draft", slug="active")) draft.set_state(State.objects.get(used=True, type="draft-iesg", slug="pub-req")) draft.set_state(State.objects.get(used=True, type="draft-stream-%s" % draft.stream_id, slug="wg-doc")) - doc_alias = DocAlias.objects.create(name=draft.name) - doc_alias.docs.add(draft) - - RelatedDocument.objects.create(source=draft, target=old_alias, relationship=DocRelationshipName.objects.get(slug='replaces')) + RelatedDocument.objects.create(source=draft, target=old_draft, relationship=DocRelationshipName.objects.get(slug='replaces')) old_draft.set_state(State.objects.get(type='draft', slug='repl')) DocumentAuthor.objects.create( @@ -345,7 +343,7 @@ def make_test_data(): title="Statement regarding rights", holder_legal_name="Native Martians United", state=IprDisclosureStateName.objects.get(slug='posted'), - patent_info='Number: US12345\nTitle: A method of transfering bits\nInventor: A. Nonymous\nDate: 2000-01-01', + patent_info='Number: US12345\nTitle: A method of transferring bits\nInventor: A. Nonymous\nDate: 2000-01-01', holder_contact_name='George', holder_contact_email='george@acme.com', holder_contact_info='14 Main Street\nEarth', @@ -356,7 +354,7 @@ def make_test_data(): IprDocRel.objects.create( disclosure=ipr, - document=doc_alias, + document=draft, revisions='00', ) @@ -364,7 +362,7 @@ def make_test_data(): ietf72 = Meeting.objects.create( number="72", type_id="ietf", - date=datetime.date.today() + datetime.timedelta(days=180), + date=date_today() + datetime.timedelta(days=180), city="New York", country="US", time_zone="US/Eastern", @@ -385,37 +383,27 @@ def make_test_data(): ) # an independent submission before review - doc = Document.objects.create(name='draft-imaginary-independent-submission',type_id='draft',rev='00', - title="Some Independent Notes on Imagination") - doc.set_state(State.objects.get(used=True, type="draft", slug="active")) - DocAlias.objects.create(name=doc.name).docs.add(doc) + IndividualDraftFactory(title="Some Independent Notes on Imagination") # an irtf submission mid review - doc = Document.objects.create(name='draft-imaginary-irtf-submission', type_id='draft',rev='00', - stream=StreamName.objects.get(slug='irtf'), title="The Importance of Research Imagination") - docalias = DocAlias.objects.create(name=doc.name) - docalias.docs.add(doc) - doc.set_state(State.objects.get(type="draft", slug="active")) - crdoc = Document.objects.create(name='conflict-review-imaginary-irtf-submission', type_id='conflrev', - rev='00', notify="fsm@ietf.org", title="Conflict Review of IRTF Imagination Document") - DocAlias.objects.create(name=crdoc.name).docs.add(crdoc) - crdoc.set_state(State.objects.get(name='Needs Shepherd', type__slug='conflrev')) - crdoc.relateddocument_set.create(target=docalias,relationship_id='conflrev') + doc = IndividualDraftFactory(name="draft-imaginary-irtf-submission", stream_id="irtf", title="The Importance of Research Imagination") + ConflictReviewFactory(name="conflict-review-imaginary-irtf-submission", review_of=doc, notify="fsm@ietf.org", title="Conflict Review of IRTF Imagination Document") # A status change mid review iesg = Group.objects.get(acronym='iesg') - doc = Document.objects.create(name='status-change-imaginary-mid-review',type_id='statchg', rev='00', - notify="fsm@ietf.org", group=iesg, title="Status Change Review without Imagination") - doc.set_state(State.objects.get(slug='needshep',type__slug='statchg')) - docalias = DocAlias.objects.create(name='status-change-imaginary-mid-review') - docalias.docs.add(doc) + doc = StatusChangeFactory( + name='status-change-imaginary-mid-review', + notify="fsm@ietf.org", + group=iesg, + title="Status Change Review without Imagination", + states= [State.objects.get(type_id="statchg",slug="needshep")] + ) # Some things for a status change to affect def rfc_for_status_change_test_factory(name,rfc_num,std_level_id): - target_rfc = Document.objects.create(name=name, type_id='draft', std_level_id=std_level_id, notify="%s@ietf.org"%name) - target_rfc.set_state(State.objects.get(slug='rfc',type__slug='draft')) - DocAlias.objects.create(name=name).docs.add(target_rfc) - DocAlias.objects.create(name='rfc%d'%rfc_num).docs.add(target_rfc) + target_rfc = WgRfcFactory(rfc_number=rfc_num, std_level_id=std_level_id) + source_draft = WgDraftFactory(name=name, states=[("draft","rfc")], notify=f"{name}@ietf.org") + source_draft.relateddocument_set.create(relationship_id="became_rfc", target=target_rfc) return target_rfc rfc_for_status_change_test_factory('draft-ietf-random-thing',9999,'ps') rfc_for_status_change_test_factory('draft-ietf-random-otherthing',9998,'inf') @@ -458,7 +446,7 @@ def make_review_data(doc): doc=doc, team=team1, type_id="early", - deadline=datetime.datetime.now() + datetime.timedelta(days=20), + deadline=timezone.now() + datetime.timedelta(days=20), state_id="accepted", requested_by=reviewer, reviewer=email, diff --git a/ietf/utils/test_draft_with_references_v3.xml b/ietf/utils/test_draft_with_references_v3.xml index a04880d1db6..ad9b2b280a4 100644 --- a/ietf/utils/test_draft_with_references_v3.xml +++ b/ietf/utils/test_draft_with_references_v3.xml @@ -1,6 +1,6 @@ - + Test Draft with References @@ -37,9 +37,25 @@ + + + Cloud Software + + + + + + + + Informative References + + + + + Status of network hosts @@ -51,6 +67,34 @@ + + + Key Consistency and Discovery + + Brave Software + + + The Tor Project + + + Mozilla + + + Cloudflare + + + + This document describes the key consistency and correctness + requirements of protocols such as Privacy Pass, Oblivious DoH, and + Oblivious HTTP for user privacy. It discusses several mechanisms and + proposals for enabling user privacy in varying threat models. In + concludes with discussion of open problems in this area. + + + + + + @@ -191,4 +235,4 @@ - \ No newline at end of file + diff --git a/ietf/utils/test_runner.py b/ietf/utils/test_runner.py index 129b2e842f7..0a46fdf807a 100644 --- a/ietf/utils/test_runner.py +++ b/ietf/utils/test_runner.py @@ -1,4 +1,4 @@ -# Copyright The IETF Trust 2009-2020, All Rights Reserved +# Copyright The IETF Trust 2009-2026, All Rights Reserved # -*- coding: utf-8 -*- # # Portion Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). @@ -40,27 +40,24 @@ import sys import time import json -import pytz import importlib import socket -import datetime import gzip import unittest import pathlib import subprocess import tempfile import copy +from contextlib import contextmanager + +import boto3 +import botocore.config import factory.random import urllib3 import warnings -from urllib.parse import urlencode -from fnmatch import fnmatch -from pathlib import Path - -from coverage.report import Reporter -from coverage.results import Numbers -from coverage.misc import NotPython +from typing import Callable, Optional +from urllib.parse import urlencode import django from django.conf import settings @@ -73,10 +70,11 @@ from django.template.loaders.filesystem import Loader as BaseLoader from django.test.runner import DiscoverRunner from django.core.management import call_command -from django.urls import URLResolver # type: ignore +from django.urls import URLResolver, resolve, Resolver404 # type: ignore from django.template.backends.django import DjangoTemplates from django.template.backends.django import Template # type: ignore[attr-defined] -# from django.utils.safestring import mark_safe +from django.utils import timezone +from django.views.generic import RedirectView, TemplateView import debug # pyflakes:ignore debug.debug = True @@ -84,19 +82,45 @@ import ietf import ietf.utils.mail from ietf.utils.management.commands import pyflakes -from ietf.utils.test_smtpserver import SMTPTestServerDriver +from ietf.utils.aiosmtpd import SMTPTestServerDriver from ietf.utils.test_utils import TestCase +from mypy_boto3_s3.service_resource import Bucket + + +class UrlCoverageWarning(UserWarning): + """Warning category for URL coverage-related warnings""" + # URLs for which we don't expect patterns to match + IGNORE_URLS = ( + "/_doesnotexist/", + "/sitemap.xml.", + ) -loaded_templates = set() -visited_urls = set() -test_database_name = None -old_destroy = None -old_create = None -template_coverage_collection = None -code_coverage_collection = None -url_coverage_collection = None +class UninterestingPatternWarning(UrlCoverageWarning): + """Warning category for unexpected URL match patterns + + These are common, caused by tests that hit a URL that is not selected for + coverage checking. The warning is in place to help with a putative future + review of whether we're selecting the right patterns to check for coverage. + """ + pass + + +# Configure warnings for reasonable output quantity +warnings.simplefilter("once", UrlCoverageWarning) +warnings.simplefilter("ignore", UninterestingPatternWarning) + + +loaded_templates: set[str] = set() +visited_urls: set[str] = set() +test_database_name: Optional[str] = None +old_destroy: Optional[Callable] = None +old_create: Optional[Callable] = None + +template_coverage_collection = False +url_coverage_collection = False +validation_settings = {"validate_html": None, "validate_html_harder": None, "show_logging": False} def start_vnu_server(port=8888): @@ -176,14 +200,22 @@ def vnu_fmt_message(file, msg, content): def vnu_filter_message(msg, filter_db_issues, filter_test_issues): "True if the vnu message is a known false positive" - if filter_db_issues and re.search( - r"""^Forbidden\ code\ point\ U\+| - Illegal\ character\ in\ query:\ '\['| - 'href'\ on\ element\ 'a':\ Percentage\ \("%"\)\ is\ not\ followed| - ^Saw\ U\+\d+\ in\ stream| - ^Document\ uses\ the\ Unicode\ Private\ Use\ Area""", + if re.search( + r"""^Document\ uses\ the\ Unicode\ Private\ Use\ Area| + ^Trailing\ slash\ on\ void\ elements\ has\ no\ effect| + ^Element\ 'h.'\ not\ allowed\ as\ child\ of\ element\ 'pre'""", msg["message"], flags=re.VERBOSE, + ) or ( + filter_db_issues + and re.search( + r"""^Forbidden\ code\ point\ U\+| + Illegal\ character\ in\ query:\ '\['| + 'href'\ on\ element\ 'a':\ Percentage\ \("%"\)\ is\ not| + ^Saw\ U\+\d+\ in\ stream""", + msg["message"], + flags=re.VERBOSE, + ) ): return True @@ -220,13 +252,12 @@ def load_and_run_fixtures(verbosity): fn() def safe_create_test_db(self, verbosity, *args, **kwargs): - global test_database_name, old_create + if old_create is None: + raise RuntimeError("old_create has not been set, cannot proceed") keepdb = kwargs.get('keepdb', False) if not keepdb: print(" Creating test database...") - if settings.DATABASES["default"]["ENGINE"] == 'django.db.backends.mysql': - settings.DATABASES["default"]["OPTIONS"] = settings.DATABASE_TEST_OPTIONS - print(" Using OPTIONS: %s" % settings.DATABASES["default"]["OPTIONS"]) + global test_database_name test_database_name = old_create(self, 0, *args, **kwargs) if settings.GLOBAL_TEST_FIXTURES: @@ -236,8 +267,9 @@ def safe_create_test_db(self, verbosity, *args, **kwargs): return test_database_name def safe_destroy_test_db(*args, **kwargs): + if old_destroy is None: + raise RuntimeError("old_destroy has not been set, cannot proceed") sys.stdout.write('\n') - global test_database_name, old_destroy keepdb = kwargs.get('keepdb', False) if not keepdb: if settings.DATABASES["default"]["NAME"] != test_database_name: @@ -256,7 +288,14 @@ def pyflakes_test(self): path = os.path.join(settings.BASE_DIR) warnings = [] warnings = pyflakes.checkPaths([path], verbosity=0) - self.assertEqual([], [str(w) for w in warnings]) + + # Filter out warnings about unused global variables + filtered_warnings = [ + w for w in warnings + if not re.search(r"`global \w+` is unused: name is never assigned in scope", str(w)) + ] + + self.assertEqual([], [str(w) for w in filtered_warnings]) class MyPyTest(TestCase): @@ -279,7 +318,7 @@ class ValidatingTemplates(DjangoTemplates): def __init__(self, params): super().__init__(params) - if not settings.validate_html: + if not validation_settings["validate_html"]: return self.validation_cache = set() self.cwd = str(pathlib.Path.cwd()) @@ -295,7 +334,7 @@ def __init__(self, template, backend): def render(self, context=None, request=None): content = super().render(context, request) - if not settings.validate_html: + if not validation_settings["validate_html"]: return content if not self.origin.name.endswith("html"): @@ -307,7 +346,7 @@ def render(self, context=None, request=None): return content fingerprint = hash(content) + sys.maxsize + 1 # make hash positive - if not settings.validate_html_harder and fingerprint in self.backend.validation_cache: + if not validation_settings["validate_html_harder"] and fingerprint in self.backend.validation_cache: # already validated this HTML fragment, skip it # as an optimization, make page a bit smaller by not returning HTML for the menus # FIXME: figure out why this still includes base/menu.html @@ -323,29 +362,34 @@ def render(self, context=None, request=None): # don't validate each template by itself, causes too much overhead # instead, save a batch of them and then validate them all in one go # this delays error detection a bit, but is MUCH faster - settings.validate_html.batches[kind].append( + validation_settings["validate_html"].batches[kind].append( (self.origin.name, content, fingerprint) ) - # FWIW, a batch size of 30 seems to result in less than 10% runtime overhead - if len(settings.validate_html.batches[kind]) >= 30: - settings.validate_html.validate(kind) - return content +class TemplateValidationTests(unittest.TestCase): + def __init__(self, test_runner, validate_html, **kwargs): + self.runner = test_runner + self.validate_html = validate_html + super().__init__(**kwargs) + + def run_template_validation(self): + if self.validate_html: + self.validate_html.validate(self) + + class TemplateCoverageLoader(BaseLoader): is_usable = True def get_template(self, template_name, skip=None): - global template_coverage_collection, loaded_templates - if template_coverage_collection == True: + if template_coverage_collection: loaded_templates.add(str(template_name)) raise TemplateDoesNotExist(template_name) def record_urls_middleware(get_response): def record_urls(request): - global url_coverage_collection, visited_urls - if url_coverage_collection == True: + if url_coverage_collection: visited_urls.add(request.path) return get_response(request) return record_urls @@ -391,8 +435,9 @@ def do_append(res, p0, p1, item): res.append((str(item.pattern), item)) return res + _all_templates = None -def get_template_paths(apps=None): +def get_template_paths(apps=None) -> list[str]: global _all_templates if not _all_templates: # TODO: Add app templates to the full list, if we are using @@ -401,28 +446,33 @@ def get_template_paths(apps=None): templatepaths = settings.TEMPLATES[0]['DIRS'] for templatepath in templatepaths: for dirpath, dirs, files in os.walk(templatepath): - if ".svn" in dirs: - dirs.remove(".svn") - relative_path = dirpath[len(templatepath)+1:] - for file in files: - ignore = False - for pattern in settings.TEST_TEMPLATE_IGNORE: - if fnmatch(file, pattern): - ignore = True - break - if ignore: - continue - if relative_path != "": - file = os.path.join(relative_path, file) - templates.add(file) - if apps: - templates = [ t for t in templates if t.split(os.path.sep)[0] in apps ] - _all_templates = templates + # glob against path from PROJECT_DIR + project_path = pathlib.Path( + dirpath.removeprefix(settings.PROJECT_DIR).lstrip("/") + ) + # label entries with name relative to templatepath + relative_path = pathlib.Path( + dirpath.removeprefix(templatepath).lstrip("/") + ) + if ( + apps + and len(relative_path.parts) > 0 + and relative_path.parts[0] not in apps + ): + continue # skip uninteresting apps + for filename in files: + file_path = project_path / filename + if not any( + file_path.match(pat) for pat in settings.TEST_TEMPLATE_IGNORE + ): + templates.add(relative_path / filename) + _all_templates = [str(t) for t in templates] return _all_templates + def save_test_results(failures, test_labels): # Record the test result in a file, in order to be able to check the - # results and avoid re-running tests if we've alread run them with OK + # results and avoid re-running tests if we've already run them with OK # result after the latest code changes: tfile = io.open(".testresult", "a", encoding='utf-8') timestr = time.strftime("%Y-%m-%d %H:%M:%S") @@ -435,50 +485,29 @@ def save_test_results(failures, test_labels): tfile.write("%s OK\n" % (timestr, )) tfile.close() -def set_coverage_checking(flag=True): + +def set_template_coverage(flag): global template_coverage_collection - global code_coverage_collection + orig = template_coverage_collection + template_coverage_collection = flag + return orig + + +def set_url_coverage(flag): global url_coverage_collection - if settings.SERVER_MODE == 'test': - if flag: - settings.TEST_CODE_COVERAGE_CHECKER.collector.resume() - template_coverage_collection = True - code_coverage_collection = True - url_coverage_collection = True - else: - settings.TEST_CODE_COVERAGE_CHECKER.collector.pause() - template_coverage_collection = False - code_coverage_collection = False - url_coverage_collection = False - -class CoverageReporter(Reporter): - def report(self): - self.find_file_reporters(None) - - total = Numbers() - result = {"coverage": 0.0, "covered": {}, "format": 5, } - for fr in self.file_reporters: - try: - analysis = self.coverage._analyze(fr) - nums = analysis.numbers - missing_nums = sorted(analysis.missing) - with io.open(analysis.filename, encoding='utf-8') as file: - lines = file.read().splitlines() - missing_lines = [ lines[l-1] for l in missing_nums ] - result["covered"][fr.relative_filename()] = (nums.n_statements, nums.pc_covered/100.0, missing_nums, missing_lines) - total += nums - except KeyboardInterrupt: # pragma: not covered - raise - except Exception: - report_it = not self.config.ignore_errors - if report_it: - typ, msg = sys.exc_info()[:2] - if typ is NotPython and not fr.should_be_python(): - report_it = False - if report_it: - raise - result["coverage"] = total.pc_covered/100.0 - return result + orig = url_coverage_collection + url_coverage_collection = flag + return orig + + +@contextmanager +def disable_coverage(): + """Context manager/decorator that disables template/url coverage""" + orig_template = set_template_coverage(False) + orig_url = set_url_coverage(False) + yield + set_template_coverage(orig_template) + set_url_coverage(orig_url) class CoverageTest(unittest.TestCase): @@ -501,16 +530,16 @@ def report_test_result(self, test): # Assert coverage failure only if we're running the full test suite -- if we're # only running some tests, then of course the coverage is going to be low. if self.runner.run_full_test_suite: - # Permit 0.02% variation in results -- otherwise small code changes become a pain - fudge_factor = 0.0002 + # Permit a small variation in results -- otherwise small code changes become a pain + fudge_factor = 0.0004 self.assertLessEqual(len(test_missing), len(master_missing), msg = "New %s without test coverage since %s: %s" % (test, latest_coverage_version, list(set(test_missing) - set(master_missing)))) - self.assertGreaterEqual(test_coverage, master_coverage - fudge_factor, - msg = "The %s coverage percentage is now lower (%.2f%%) than for version %s (%.2f%%)" % - ( test, test_coverage*100, latest_coverage_version, master_coverage*100, )) + if not self.runner.ignore_lower_coverage: + self.assertGreaterEqual(test_coverage, master_coverage - fudge_factor, + msg = "The %s coverage percentage is now lower (%.2f%%) than for version %s (%.2f%%)" % + ( test, test_coverage*100, latest_coverage_version, master_coverage*100, )) def template_coverage_test(self): - global loaded_templates if self.runner.check_coverage: apps = [ app.split('.')[-1] for app in self.runner.test_apps ] all = get_template_paths(apps) @@ -539,48 +568,68 @@ def ignore_pattern(regex, pattern): return (regex in ("^_test500/$", "^accounts/testemail/$") or regex.startswith("^admin/") or re.search('^api/v1/[^/]+/[^/]+/', regex) - or getattr(pattern.callback, "__name__", "") == "RedirectView" - or getattr(pattern.callback, "__name__", "") == "TemplateView" + or ( + hasattr(pattern.callback, "view_class") + and issubclass(pattern.callback.view_class, (RedirectView, TemplateView)) + ) or pattern.callback == django.views.static.serve) - patterns = [(regex, re.compile(regex, re.U), obj) for regex, obj in url_patterns - if not ignore_pattern(regex, obj)] + patterns ={ + regex: obj + for regex, obj in url_patterns + if not ignore_pattern(regex, obj) + } covered = set() for url in visited_urls: - for regex, compiled, obj in patterns: - if regex not in covered and compiled.match(url[1:]): # strip leading / - covered.add(regex) - break + try: + resolved = resolve(url) # let Django resolve the URL for us + except Resolver404: + if url not in UrlCoverageWarning.IGNORE_URLS: + warnings.warn( + f"Unable to resolve visited URL {url}", UrlCoverageWarning + ) + continue + if resolved.route not in patterns: + warnings.warn( + f"WARNING: url resolved to an unexpected pattern (url='{url}', " + f"resolved to r'{resolved.route}'", + UninterestingPatternWarning, + ) + continue + covered.add(resolved.route) self.runner.coverage_data["url"] = { - "coverage": 1.0*len(covered)/len(patterns), - "covered": dict( (k, (o.lookup_str, k in covered)) for k,p,o in patterns ), + "coverage": 1.0 * len(covered) / len(patterns), + "covered": dict( + (k, (o.lookup_str, k in covered)) for k, o in patterns.items() + ), "format": 4, - } + } self.report_test_result("url") else: self.skipTest("Coverage switched off with --skip-coverage") def code_coverage_test(self): - if self.runner.check_coverage: - include = [ os.path.join(path, '*') for path in self.runner.test_paths ] - checker = self.runner.code_coverage_checker - checker.stop() + if ( + self.runner.check_coverage + and settings.TEST_CODE_COVERAGE_CHECKER is not None + ): + coverage_manager = settings.TEST_CODE_COVERAGE_CHECKER + coverage_manager.stop() # Save to the .coverage file - checker.save() - # Apply the configured and requested omit and include data - checker.config.from_args(ignore_errors=None, omit=settings.TEST_CODE_COVERAGE_EXCLUDE_FILES, - include=include, file=None) - for pattern in settings.TEST_CODE_COVERAGE_EXCLUDE_LINES: - checker.exclude(pattern) + coverage_manager.save() + # Apply the configured and requested omit and include data # Maybe output an HTML report if self.runner.run_full_test_suite and self.runner.html_report: - checker.html_report(directory=settings.TEST_CODE_COVERAGE_REPORT_DIR) - # In any case, build a dictionary with per-file data for this run - reporter = CoverageReporter(checker, checker.config) - self.runner.coverage_data["code"] = reporter.report() + coverage_manager.checker.html_report( + directory=settings.TEST_CODE_COVERAGE_REPORT_DIR + ) + # Generate the output report data + self.runner.coverage_data["code"] = coverage_manager.report( + include=[str(pathlib.Path(p) / "*") for p in self.runner.test_paths] + ) self.report_test_result("code") else: self.skipTest("Coverage switched off with --skip-coverage") @@ -679,6 +728,9 @@ class IetfTestRunner(DiscoverRunner): @classmethod def add_arguments(cls, parser): super(IetfTestRunner, cls).add_arguments(parser) + parser.add_argument('--ignore-lower-coverage', + action= 'store_true', dest='ignore_lower_coverage', default=False, + help='Do not treat lower coverage as a failure. Useful for building a new coverage file to reset the coverage baseline.') parser.add_argument('--skip-coverage', action='store_true', dest='skip_coverage', default=False, help='Skip test coverage measurements for code, templates, and URLs. ' ) @@ -703,20 +755,42 @@ def add_arguments(cls, parser): parser.add_argument('--validate-html-harder', action='store_true', dest="validate_html_harder", default=False, help='Validate all generated HTML with additional validators (slow)') - - def __init__(self, skip_coverage=False, save_version_coverage=None, html_report=None, permit_mixed_migrations=None, show_logging=None, validate_html=None, validate_html_harder=None, **kwargs): - # + parser.add_argument('--rerun-until-failure', + action='store_true', dest='rerun', default=False, + help='Run the indicated tests in a loop until a failure occurs. ' ) + parser.add_argument('--no-manage-blobstore', action='store_false', dest='manage_blobstore', + help='Disable creating/deleting test buckets in the blob store.' + 'When this argument is used, a set of buckets with "test-" prefixed to their ' + 'names must already exist.') + + def __init__( + self, + ignore_lower_coverage=False, + skip_coverage=False, + save_version_coverage=None, + html_report=None, + permit_mixed_migrations=None, + show_logging=None, + validate_html=None, + validate_html_harder=None, + rerun=None, + manage_blobstore=True, + **kwargs + ): # + self.ignore_lower_coverage = ignore_lower_coverage self.check_coverage = not skip_coverage self.save_version_coverage = save_version_coverage self.html_report = html_report self.permit_mixed_migrations = permit_mixed_migrations self.show_logging = show_logging - settings.validate_html = self if validate_html else None - settings.validate_html_harder = self if validate_html and validate_html_harder else None - settings.show_logging = show_logging + self.rerun = rerun + self.test_labels = None + validation_settings["validate_html"] = self if validate_html else None + validation_settings["validate_html_harder"] = self if validate_html and validate_html_harder else None + validation_settings["show_logging"] = show_logging # self.root_dir = os.path.dirname(settings.BASE_DIR) - self.coverage_file = os.path.join(self.root_dir, settings.TEST_COVERAGE_MASTER_FILE) + self.coverage_file = os.path.join(self.root_dir, settings.TEST_COVERAGE_MAIN_FILE) super(IetfTestRunner, self).__init__(**kwargs) if self.parallel > 1: if self.html_report == True: @@ -724,11 +798,15 @@ def __init__(self, skip_coverage=False, save_version_coverage=None, html_report= "as the collection of test coverage data isn't currently threadsafe.") sys.exit(1) self.check_coverage = False + from ietf.doc.tests import TemplateTagTest # import here to prevent circular imports + # Ensure that the coverage tests come last. Specifically list TemplateTagTest before CoverageTest. If this list + # contains parent classes to later subclasses, the parent classes will determine the ordering, so use the most + # specific classes necessary to get the right ordering: + self.reorder_by = (PyFlakesTestCase, MyPyTest,) + self.reorder_by + (StaticLiveServerTestCase, TemplateTagTest, CoverageTest,) + #self.buckets = set() + self.blobstoremanager = TestBlobstoreManager() if manage_blobstore else None def setup_test_environment(self, **kwargs): - global template_coverage_collection - global url_coverage_collection - ietf.utils.mail.test_mode = True ietf.utils.mail.SMTP_ADDR['ip4'] = '127.0.0.1' ietf.utils.mail.SMTP_ADDR['port'] = 2025 @@ -739,7 +817,7 @@ def setup_test_environment(self, **kwargs): print(" Datatracker %s test suite, %s:" % (ietf.__version__, time.strftime("%d %B %Y %H:%M:%S %Z"))) print(" Python %s." % sys.version.replace('\n', ' ')) print(" Django %s, settings '%s'" % (django.get_version(), settings.SETTINGS_MODULE)) - + settings.TEMPLATES[0]['BACKEND'] = 'ietf.utils.test_runner.ValidatingTemplates' if self.check_coverage: if self.coverage_file.endswith('.gz'): @@ -749,39 +827,28 @@ def setup_test_environment(self, **kwargs): with io.open(self.coverage_file, encoding='utf-8') as file: self.coverage_master = json.load(file) self.coverage_data = { - "time": datetime.datetime.now(pytz.utc).strftime("%Y-%m-%dT%H:%M:%SZ"), + "time": timezone.now().strftime("%Y-%m-%dT%H:%M:%SZ"), "template": { - "coverage": 0.0, + "coverage": 0.0, "covered": {}, "format": 1, # default format, coverage data in 'covered' are just fractions }, "url": { - "coverage": 0.0, + "coverage": 0.0, "covered": {}, "format": 4, }, "code": { - "coverage": 0.0, + "coverage": 0.0, "covered": {}, "format": 1, }, - "migration": { - "present": {}, - "format": 3, - } } settings.TEMPLATES[0]['OPTIONS']['loaders'] = ('ietf.utils.test_runner.TemplateCoverageLoader',) + settings.TEMPLATES[0]['OPTIONS']['loaders'] settings.MIDDLEWARE = ('ietf.utils.test_runner.record_urls_middleware',) + tuple(settings.MIDDLEWARE) - self.code_coverage_checker = settings.TEST_CODE_COVERAGE_CHECKER - if not self.code_coverage_checker._started: - sys.stderr.write(" ** Warning: In %s: Expected the coverage checker to have\n" - " been started already, but it wasn't. Doing so now. Coverage numbers\n" - " will be off, though.\n" % __name__) - self.code_coverage_checker.start() - if settings.SITE_ID != 1: print(" Changing SITE_ID to '1' during testing.") settings.SITE_ID = 1 @@ -808,8 +875,8 @@ def setup_test_environment(self, **kwargs): for offset in range(10): try: # remember the value so ietf.utils.mail.send_smtp() will use the same - ietf.utils.mail.SMTP_ADDR['port'] = base + offset - self.smtpd_driver = SMTPTestServerDriver((ietf.utils.mail.SMTP_ADDR['ip4'],ietf.utils.mail.SMTP_ADDR['port']),None) + ietf.utils.mail.SMTP_ADDR['port'] = base + offset + self.smtpd_driver = SMTPTestServerDriver(ietf.utils.mail.SMTP_ADDR['ip4'],ietf.utils.mail.SMTP_ADDR['port'], None) self.smtpd_driver.start() print((" Running an SMTP test server on %(ip4)s:%(port)s to catch outgoing email." % ietf.utils.mail.SMTP_ADDR)) break @@ -828,7 +895,7 @@ def setup_test_environment(self, **kwargs): s[1] = tuple(s[1]) # random.setstate() won't accept a list in lieu of a tuple factory.random.set_random_state(s) - if not settings.validate_html: + if not validation_settings["validate_html"]: print(" Not validating any generated HTML; " "please do so at least once before committing changes") else: @@ -854,9 +921,19 @@ def setup_test_environment(self, **kwargs): # django-bootstrap5 seems to still generate 'checked="checked"', ignore: "attribute-boolean-style": "off", # self-closing style tags are valid in HTML5. Both self-closing and non-self-closing tags are accepted. (vite generates self-closing link tags) - # "void-style": "off", + "void-style": "off", # Both attributes without value and empty strings are equal and valid. (vite generates empty value attributes) - # "attribute-empty-style": "off" + "attribute-empty-style": "off", + # For fragments, don't check that elements are in the proper ancestor element + "element-required-ancestor": "off", + # This is allowed by the HTML spec + "form-dup-name": "off", + # Don't trip over unused disable blocks + "no-unused-disable": "off", + # Ignore focusable elements in aria-hidden elements + "hidden-focusable": "off", + # Ignore missing unique identifier for page "landmarks" + "unique-landmark": "off", }, } @@ -865,34 +942,42 @@ def setup_test_environment(self, **kwargs): config["doc"]["extends"].append("html-validate:document") # FIXME: we should find a way to use SRI, but ignore for now: config["doc"]["rules"]["require-sri"] = "off" - # permit discontinuous heading numbering in cards, modals and dialogs: + # Turn "element-required-ancestor" back on + del config["doc"]["rules"]["element-required-ancestor"] config["doc"]["rules"]["heading-level"] = [ "error", { + # permit discontinuous heading numbering in cards, modals and dialogs: "sectioningRoots": [ ".card-body", ".modal-content", '[role="dialog"]', - ] + ], + # permit multiple H1 elements in a single document + "allowMultipleH1": True, }, ] self.config_file = {} for kind in self.batches: self.config_file[kind] = tempfile.NamedTemporaryFile( - prefix="html-validate-config-" + prefix="html-validate-config-", + suffix=".json" ) self.config_file[kind].write(json.dumps(config[kind]).encode()) self.config_file[kind].flush() - Path(self.config_file[kind].name).chmod(0o644) + pathlib.Path(self.config_file[kind].name).chmod(0o644) - if not settings.validate_html_harder: + if not validation_settings["validate_html_harder"]: print("") self.vnu = None else: print(" (extra pedantically)") self.vnu = start_vnu_server() + if self.blobstoremanager is not None: + self.blobstoremanager.createTestBlobstores() + super(IetfTestRunner, self).setup_test_environment(**kwargs) def teardown_test_environment(self, **kwargs): @@ -915,98 +1000,92 @@ def teardown_test_environment(self, **kwargs): with open(self.coverage_file, "w") as file: json.dump(self.coverage_master, file, indent=2, sort_keys=True) - if settings.validate_html: + if validation_settings["validate_html"]: for kind in self.batches: - try: - self.validate(kind) - except Exception: - pass + if len(self.batches[kind]): + print(f" WARNING: not all templates of kind '{kind}' were validated") self.config_file[kind].close() if self.vnu: self.vnu.terminate() - super(IetfTestRunner, self).teardown_test_environment(**kwargs) + if self.blobstoremanager is not None: + self.blobstoremanager.destroyTestBlobstores() - def validate(self, kind): - if not self.batches[kind]: - return + super(IetfTestRunner, self).teardown_test_environment(**kwargs) - testcase = TestCase() + def validate(self, testcase): cwd = pathlib.Path.cwd() - tmpdir = tempfile.TemporaryDirectory(prefix="html-validate-") - Path(tmpdir.name).chmod(0o777) - for (name, content, fingerprint) in self.batches[kind]: - path = pathlib.Path(tmpdir.name).joinpath( - hex(fingerprint)[2:], - pathlib.Path(name).relative_to(cwd) - ) - pathlib.Path(path.parent).mkdir(parents=True, exist_ok=True) - with path.open(mode="w") as file: - file.write(content) - self.batches[kind] = [] - - validation_results = None - with tempfile.NamedTemporaryFile() as stdout: - subprocess.run( - [ - "yarn", - "html-validate", - "--formatter=json", - "--config=" + self.config_file[kind].name, - tmpdir.name, - ], - stdout=stdout, - stderr=stdout, - ) - - stdout.seek(0) - try: - validation_results = json.load(stdout) - except json.decoder.JSONDecodeError: - stdout.seek(0) - testcase.fail(stdout.read()) - - errors = "" - for result in validation_results: - source_lines = result["source"].splitlines(keepends=True) - for msg in result["messages"]: - line = msg["line"] - errors += ( - f'\n{result["filePath"]}:\n' - + "".join(source_lines[line - 5 : line]) - + " " * (msg["column"] - 1) - + "^" * msg["size"] + "\n" - + " " * (msg["column"] - 1) - + f'{msg["ruleId"]}: {msg["message"]} ' - + f'on line {line}:{msg["column"]}\n' - + "".join(source_lines[line : line + 5]) - + "\n" - ) - + errors = [] + with tempfile.TemporaryDirectory(prefix="html-validate-") as tmpdir_name: + tmppath = pathlib.Path(tmpdir_name) + tmppath.chmod(0o777) + for kind in self.batches: + if not self.batches[kind]: + return + for (name, content, fingerprint) in self.batches[kind]: + path = tmppath.joinpath( + hex(fingerprint)[2:], + pathlib.Path(name).relative_to(cwd) + ) + pathlib.Path(path.parent).mkdir(parents=True, exist_ok=True) + with path.open(mode="w") as file: + file.write(content) + self.batches[kind] = [] + + validation_results = None + with tempfile.NamedTemporaryFile() as stdout: + subprocess.run( + [ + "npx", + "html-validate", + "--formatter=json", + "--config=" + self.config_file[kind].name, + tmpdir_name, + ], + stdout=stdout, + stderr=stdout, + ) + + stdout.seek(0) + try: + validation_results = json.load(stdout) + except json.decoder.JSONDecodeError: + stdout.seek(0) + testcase.fail(stdout.read()) + + for result in validation_results: + source_lines = result["source"].splitlines(keepends=True) + for msg in result["messages"]: + line = msg["line"] + errors.append( + f'\n{result["filePath"]}:\n' + + "".join(source_lines[line - 5 : line]) + + " " * (msg["column"] - 1) + + "^" * msg["size"] + "\n" + + " " * (msg["column"] - 1) + + f'{msg["ruleId"]}: {msg["message"]} ' + + f'on line {line}:{msg["column"]}\n' + + "".join(source_lines[line : line + 5]) + + "\n" + ) + + if validation_settings["validate_html_harder"] and kind != "frag": + files = [ + os.path.join(d, f) + for d, dirs, files in os.walk(tmppath) + for f in files + ] + for file in files: + with open(file, "rb") as f: + content = f.read() + result = vnu_validate(content) + assert result + for msg in json.loads(result)["messages"]: + if vnu_filter_message(msg, False, True): + continue + errors.append(vnu_fmt_message(file, msg, content.decode("utf-8"))) if errors: - testcase.fail(errors) - - if settings.validate_html_harder: - if kind == "frag": - return - files = [ - os.path.join(d, f) - for d, dirs, files in os.walk(tmpdir.name) - for f in files - ] - for file in files: - with open(file, "rb") as f: - content = f.read() - result = vnu_validate(content) - assert result - for msg in json.loads(result)["messages"]: - if vnu_filter_message(msg, False, True): - continue - errors = vnu_fmt_message(file, msg, content.decode("utf-8")) - if errors: - testcase.fail(errors) - - tmpdir.cleanup() + testcase.fail('\n'.join(errors)) def get_test_paths(self, test_labels): """Find the apps and paths matching the test labels, so we later can limit @@ -1041,20 +1120,63 @@ def get_test_paths(self, test_labels): test_paths = [ os.path.join(*app.split('.')) for app in test_apps ] return test_apps, test_paths - def run_tests(self, test_labels, extra_tests=None, **kwargs): - global old_destroy, old_create, test_database_name, template_coverage_collection, code_coverage_collection, url_coverage_collection - from django.db import connection - from ietf.doc.tests import TemplateTagTest + # Django 5 will drop the extra_tests mechanism for the test runner. Work around + # by adding a special label to the test suite, then injecting our extra tests + # in load_tests_for_label() + def build_suite(self, test_labels=None, extra_tests=None, **kwargs): + if test_labels is None: + # Base class sets test_labels to ["."] if it was None. The label we're + # adding will interfere with that, so replicate that behavior here. + test_labels = ["."] + test_labels = ("_ietf_extra_tests",) + tuple(test_labels) + return super().build_suite(test_labels, extra_tests, **kwargs) + + def load_tests_for_label(self, label, discover_kwargs): + if label == "_ietf_extra_tests": + return self._extra_tests() or None + return super().load_tests_for_label(label, discover_kwargs) + + def _extra_tests(self): + """Get extra tests that should be added to the test suite""" + tests = [] + if validation_settings["validate_html"]: + tests += [ + TemplateValidationTests( + test_runner=self, + validate_html=self, + methodName='run_template_validation', + ), + ] + if self.check_coverage: + global template_coverage_collection, url_coverage_collection + template_coverage_collection = True + url_coverage_collection = True + tests += [ + PyFlakesTestCase(test_runner=self, methodName='pyflakes_test'), + MyPyTest(test_runner=self, methodName='mypy_test'), + #CoverageTest(test_runner=self, methodName='interleaved_migrations_test'), + CoverageTest(test_runner=self, methodName='url_coverage_test'), + CoverageTest(test_runner=self, methodName='template_coverage_test'), + CoverageTest(test_runner=self, methodName='code_coverage_test'), + ] + return tests - if extra_tests is None: - extra_tests=[] + def run_suite(self, suite, **kwargs): + failures = super(IetfTestRunner, self).run_suite(suite, **kwargs) + while self.rerun and not failures.errors and not failures.failures: + suite = self.build_suite(self.test_labels) + failures = super(IetfTestRunner, self).run_suite(suite, **kwargs) + return failures + def run_tests(self, test_labels, extra_tests=None, **kwargs): # Tests that involve switching back and forth between the real # database and the test database are way too dangerous to run # against the production database if socket.gethostname().split('.')[0] in ['core3', 'ietfa', 'ietfb', 'ietfc', ]: raise EnvironmentError("Refusing to run tests on production server") + from django.db import connection + global old_destroy, old_create old_create = connection.creation.__class__.create_test_db connection.creation.__class__.create_test_db = safe_create_test_db old_destroy = connection.creation.__class__.destroy_test_db @@ -1067,26 +1189,7 @@ def run_tests(self, test_labels, extra_tests=None, **kwargs): self.test_apps, self.test_paths = self.get_test_paths(test_labels) - if self.check_coverage: - template_coverage_collection = True - code_coverage_collection = True - url_coverage_collection = True - extra_tests += [ - PyFlakesTestCase(test_runner=self, methodName='pyflakes_test'), - MyPyTest(test_runner=self, methodName='mypy_test'), - CoverageTest(test_runner=self, methodName='interleaved_migrations_test'), - CoverageTest(test_runner=self, methodName='url_coverage_test'), - CoverageTest(test_runner=self, methodName='template_coverage_test'), - CoverageTest(test_runner=self, methodName='code_coverage_test'), - ] - - # ensure that the coverage tests come last. Specifically list - # TemplateTagTest before CoverageTest. If this list contains - # parent classes to later subclasses, the parent classes will - # determine the ordering, so use the most specific classes - # necessary to get the right ordering: - self.reorder_by = (PyFlakesTestCase, MyPyTest, ) + self.reorder_by + (StaticLiveServerTestCase, TemplateTagTest, CoverageTest, ) - + self.test_labels = test_labels # these are used in our run_suite() and not available to it otherwise failures = super(IetfTestRunner, self).run_tests(test_labels, extra_tests=extra_tests, **kwargs) if self.check_coverage: @@ -1110,10 +1213,10 @@ def run_tests(self, test_labels, extra_tests=None, **kwargs): if self.run_full_test_suite: print((" %8s coverage: %6.2f%% (%s: %6.2f%%)" % - (test.capitalize(), test_coverage*100, latest_coverage_version, master_coverage*100, ))) + (test.capitalize(), test_coverage*100, latest_coverage_version, master_coverage*100, ))) else: print((" %8s coverage: %6.2f%%" % - (test.capitalize(), test_coverage*100, ))) + (test.capitalize(), test_coverage*100, ))) print((""" Per-file code and template coverage and per-url-pattern url coverage data @@ -1130,34 +1233,43 @@ def run_tests(self, test_labels, extra_tests=None, **kwargs): return failures -class IetfLiveServerTestCase(StaticLiveServerTestCase): - @classmethod - def setUpClass(cls): - set_coverage_checking(False) - super(IetfLiveServerTestCase, cls).setUpClass() - - def setUp(self): - super(IetfLiveServerTestCase, self).setUp() - # LiveServerTestCase uses TransactionTestCase which seems to - # somehow interfere with the fixture loading process in - # IetfTestRunner when running multiple tests (the first test - # is fine, in the next ones the fixtures have been wiped) - - # this is no doubt solvable somehow, but until then we simply - # recreate them here - from ietf.person.models import Person - if not Person.objects.exists(): - load_and_run_fixtures(verbosity=0) - self.replaced_settings = dict() - if hasattr(settings, 'IDTRACKER_BASE_URL'): - self.replaced_settings['IDTRACKER_BASE_URL'] = settings.IDTRACKER_BASE_URL - settings.IDTRACKER_BASE_URL = self.live_server_url - @classmethod - def tearDownClass(cls): - super(IetfLiveServerTestCase, cls).tearDownClass() - set_coverage_checking(True) - - def tearDown(self): - for k, v in self.replaced_settings.items(): - setattr(settings, k, v) - super().tearDown() +class TestBlobstoreManager(): + # N.B. buckets and blobstore are intentional Class-level attributes + buckets: set[Bucket] = set() + + blobstore = boto3.resource("s3", + endpoint_url="http://blobstore:9000", + aws_access_key_id="minio_root", + aws_secret_access_key="minio_pass", + aws_session_token=None, + config = botocore.config.Config( + request_checksum_calculation="when_required", + response_checksum_validation="when_required", + signature_version="s3v4", + ), + #config=botocore.config.Config(signature_version=botocore.UNSIGNED), + verify=False + ) + + def createTestBlobstores(self): + for storagename in settings.ARTIFACT_STORAGE_NAMES: + bucketname = f"test-{storagename}" + try: + bucket = self.blobstore.create_bucket(Bucket=bucketname) + self.buckets.add(bucket) + except self.blobstore.meta.client.exceptions.BucketAlreadyOwnedByYou: + bucket = self.blobstore.Bucket(bucketname) + self.buckets.add(bucket) + + def destroyTestBlobstores(self): + self.emptyTestBlobstores(destroy=True) + + def emptyTestBlobstores(self, destroy=False): + # debug.show('f"Asked to empty test blobstores with destroy={destroy}"') + for bucket in self.buckets: + bucket.objects.delete() + if destroy: + bucket.delete() + if destroy: + self.buckets = set() diff --git a/ietf/utils/test_smtpserver.py b/ietf/utils/test_smtpserver.py deleted file mode 100644 index 66675aa0b15..00000000000 --- a/ietf/utils/test_smtpserver.py +++ /dev/null @@ -1,92 +0,0 @@ -# Copyright The IETF Trust 2014-2020, All Rights Reserved -# -*- coding: utf-8 -*- - - -import smtpd -import threading -import asyncore - -import debug # pyflakes:ignore - -class AsyncCoreLoopThread(object): - - def wrap_loop(self, exit_condition, timeout=1.0, use_poll=False, map=None): - if map is None: - map = asyncore.socket_map - while map and not exit_condition: - asyncore.loop(timeout=1.0, use_poll=False, map=map, count=1) - - def start(self): - """Start the listening service""" - self.exit_condition = [] - kwargs={'exit_condition':self.exit_condition,'timeout':1.0} - self.thread = threading.Thread(target=self.wrap_loop, kwargs=kwargs) - self.thread.daemon = True - self.thread.daemon = True - self.thread.start() - - def stop(self): - """Stop the listening service""" - self.exit_condition.append(True) - self.thread.join() - - -class SMTPTestChannel(smtpd.SMTPChannel): - -# mail_options = ['BODY=8BITMIME', 'SMTPUTF8'] - - def smtp_RCPT(self, arg): - if not self.mailfrom: - self.push(str('503 Error: need MAIL command')) - return - arg = self._strip_command_keyword('TO:', arg) - address, __ = self._getaddr(arg) - if not address: - self.push(str('501 Syntax: RCPT TO:
    ')) - return - if "poison" in address: - self.push(str('550 Error: Not touching that')) - return - self.rcpt_options = [] - self.rcpttos.append(address) - self.push(str('250 Ok')) - -class SMTPTestServer(smtpd.SMTPServer): - - def __init__(self,localaddr,remoteaddr,inbox): - if inbox is not None: - self.inbox=inbox - else: - self.inbox = [] - smtpd.SMTPServer.__init__(self,localaddr,remoteaddr) - - def handle_accept(self): - pair = self.accept() - if pair is not None: - conn, addr = pair - #channel = SMTPTestChannel(self, conn, addr) - SMTPTestChannel(self, conn, addr) - - def process_message(self, peer, mailfrom, rcpttos, data, mail_options=None, rcpt_options=None): - self.inbox.append(data) - - -class SMTPTestServerDriver(object): - def __init__(self, localaddr, remoteaddr, inbox=None): - self.localaddr=localaddr - self.remoteaddr=remoteaddr - if inbox is not None: - self.inbox = inbox - else: - self.inbox = [] - self.thread_driver = None - - def start(self): - self.smtpserver = SMTPTestServer(self.localaddr,self.remoteaddr,self.inbox) - self.thread_driver = AsyncCoreLoopThread() - self.thread_driver.start() - - def stop(self): - if self.thread_driver: - self.thread_driver.stop() - diff --git a/ietf/utils/test_utils.py b/ietf/utils/test_utils.py index 1647eeac0fb..5faf83d93ff 100644 --- a/ietf/utils/test_utils.py +++ b/ietf/utils/test_utils.py @@ -34,10 +34,11 @@ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -import os +import tempfile import re import email import html5lib +import rest_framework.test import requests_mock import shutil import sys @@ -118,7 +119,7 @@ def assert_ical_response_is_valid(test_inst, response, expected_event_summaries= expected_event_uids=None, expected_event_count=None): """Validate an HTTP response containing iCal data - Based on RFC2445, but not exhaustive by any means. Assumes a single iCalendar object. Checks that + Based on RFC5545, but not exhaustive by any means. Assumes a single iCalendar object. Checks that expected_event_summaries/_uids are found, but other events are allowed to be present. Specify the expected_event_count if you want to reject additional events. If any of these are None, the check for that property is skipped. @@ -132,19 +133,48 @@ def assert_ical_response_is_valid(test_inst, response, expected_event_summaries= test_inst.assertContains(response, 'VERSION', count=1) # Validate event objects + event_count = 0 + uids_found = set() + summaries_found = set() + got_begin = False + cur_event_props = set() + for line_num, line in enumerate(response.content.decode().split("\n")): + line = line.rstrip() + if line == 'BEGIN:VEVENT': + test_inst.assertFalse(got_begin, f"Nested BEGIN:VEVENT found on line {line_num + 1}") + got_begin = True + elif line == 'END:VEVENT': + test_inst.assertTrue(got_begin, f"Unexpected END:VEVENT on line {line_num + 1}") + test_inst.assertIn("uid", cur_event_props, f"Found END:VEVENT without UID on line {line_num + 1}") + got_begin = False + cur_event_props.clear() + event_count += 1 + elif got_begin: + # properties in an event + if line.startswith("UID:"): + # mandatory, not more than once + test_inst.assertNotIn("uid", cur_event_props, f"Two UID properties in single event on line {line_num + 1}") + cur_event_props.add("uid") + uids_found.add(line.split(":", 1)[1]) + elif line.startswith("SUMMARY:"): + # optional, not more than once + test_inst.assertNotIn("summary", cur_event_props, f"Two SUMMARY properties in single event on line {line_num + 1}") + cur_event_props.add("summary") + summaries_found.add(line.split(":", 1)[1]) + if expected_event_summaries is not None: - for summary in expected_event_summaries: - test_inst.assertContains(response, 'SUMMARY:' + summary) + test_inst.assertCountEqual(summaries_found, set(expected_event_summaries)) if expected_event_uids is not None: - for uid in expected_event_uids: - test_inst.assertContains(response, 'UID:' + uid) + test_inst.assertCountEqual(uids_found, set(expected_event_uids)) if expected_event_count is not None: - test_inst.assertContains(response, 'BEGIN:VEVENT', count=expected_event_count) - test_inst.assertContains(response, 'END:VEVENT', count=expected_event_count) - test_inst.assertContains(response, 'UID', count=expected_event_count) + test_inst.assertEqual(event_count, expected_event_count) + # make sure no doubled colons after timestamp properties + test_inst.assertNotContains(response, 'DTSTART::') + test_inst.assertNotContains(response, 'DTEND::') + test_inst.assertNotContains(response, 'DTSTAMP::') class ReverseLazyTest(django.test.TestCase): @@ -181,6 +211,8 @@ class TestCase(django.test.TestCase): 'INTERNET_ALL_DRAFTS_ARCHIVE_DIR', 'INTERNET_DRAFT_ARCHIVE_DIR', 'INTERNET_DRAFT_PATH', + 'BIBXML_BASE_PATH', + 'FTP_DIR', ] parser = html5lib.HTMLParser(strict=True) @@ -208,13 +240,8 @@ def normalize(x): def tempdir(self, label): slug = slugify(self.__class__.__name__.replace('.','-')) - dirname = "tmp-{label}-{slug}-dir".format(**locals()) - if 'VIRTUAL_ENV' in os.environ: - dirname = os.path.join(os.environ['VIRTUAL_ENV'], dirname) - path = os.path.abspath(dirname) - if not os.path.exists(path): - os.mkdir(path) - return path + suffix = "-{label}-{slug}-dir".format(**locals()) + return tempfile.mkdtemp(suffix=suffix) def assertNoFormPostErrors(self, response, error_css_selector=".is-invalid"): """Try to fish out form errors, if none found at least check the @@ -254,7 +281,7 @@ def assertMailboxContains(self, mailbox, subject=None, text=None, count=None): assert isinstance(text, str) mlist = [ m for m in mlist if text in get_payload_text(m) ] if count and len(mlist) != count: - sys.stderr.write("Wrong count in assertMailboxContains(). The complete mailbox contains %s emails:\n\n" % len(mailbox)) + sys.stderr.write("Wrong count in assertMailboxContains(). The complete mailbox contains %s messages, only %s of them contain the searched-for text:\n\n" % (len(mailbox), len(mlist))) for m in mailbox: sys.stderr.write(m.as_string()) sys.stderr.write('\n\n') @@ -275,7 +302,7 @@ def setUp(self): # Replace settings paths with temporary directories. self._ietf_temp_dirs = {} # trashed during tearDown, DO NOT put paths you care about in this - for setting in self.settings_temp_path_overrides: + for setting in set(self.settings_temp_path_overrides): self._ietf_temp_dirs[setting] = self.tempdir(slugify(setting)) self._ietf_saved_context = django.test.utils.override_settings(**self._ietf_temp_dirs) self._ietf_saved_context.enable() @@ -285,4 +312,12 @@ def tearDown(self): for dir in self._ietf_temp_dirs.values(): shutil.rmtree(dir) self.requests_mock.stop() - super().tearDown() \ No newline at end of file + super().tearDown() + + +class APITestCase(TestCase): + """Test case that uses rest_framework's APIClient + + This is equivalent to rest_framework.test.APITestCase, but picks up our + """ + client_class = rest_framework.test.APIClient diff --git a/ietf/utils/tests.py b/ietf/utils/tests.py index 41679a48bae..99c33f34b33 100644 --- a/ietf/utils/tests.py +++ b/ietf/utils/tests.py @@ -1,51 +1,73 @@ -# Copyright The IETF Trust 2014-2020, All Rights Reserved +# Copyright The IETF Trust 2014-2025, All Rights Reserved # -*- coding: utf-8 -*- +import datetime import io import json +import lxml.etree import os.path +import pytz import shutil import types +from unittest.mock import call, patch from pyquery import PyQuery from typing import Dict, List # pyflakes:ignore +from email.message import Message from email.mime.image import MIMEImage from email.mime.multipart import MIMEMultipart from email.mime.text import MIMEText -from fnmatch import fnmatch from importlib import import_module from textwrap import dedent from tempfile import mkdtemp +from xml2rfc import log as xml2rfc_log +from xml2rfc.util.date import extract_date as xml2rfc_extract_date from django.apps import apps from django.contrib.auth.models import User from django.conf import settings +from django.forms import Form from django.template import Context from django.template import Template # pyflakes:ignore from django.template.defaulttags import URLNode from django.template.loader import get_template, render_to_string from django.templatetags.static import StaticNode +from django.test import RequestFactory from django.urls import reverse as urlreverse import debug # pyflakes:ignore +from ietf.admin.sites import AdminSite from ietf.person.name import name_parts, unidecode_name from ietf.submit.tests import submission_file from ietf.utils.draft import PlaintextDraft, getmeta +from ietf.utils.fields import SearchableField from ietf.utils.log import unreachable, assertion -from ietf.utils.mail import send_mail_preformatted, send_mail_text, send_mail_mime, outbox, get_payload_text -from ietf.utils.test_runner import get_template_paths, set_coverage_checking +from ietf.utils.mail import ( + send_mail_preformatted, + send_mail_text, + send_mail_mime, + outbox, + get_payload_text, + decode_header_value, + show_that_mail_was_sent, +) +from ietf.utils.test_runner import ( + get_template_paths, + set_template_coverage, + set_url_coverage, +) from ietf.utils.test_utils import TestCase, unicontent -from ietf.utils.text import parse_unicode -from ietf.utils.xmldraft import XMLDraft +from ietf.utils.timezone import timezone_not_near_midnight +from ietf.utils.xmldraft import XMLDraft, InvalidMetadataError, capture_xml2rfc_output class SendingMail(TestCase): def test_send_mail_preformatted(self): msg = """To: to1@example.com, to2@example.com -From: from1@ietf.org, from2@ietf.org +From: from1@ietf.org Cc: cc1@example.com, cc2@example.com Bcc: bcc1@example.com, bcc2@example.com Subject: subject @@ -55,7 +77,7 @@ def test_send_mail_preformatted(self): send_mail_preformatted(None, msg, {}, {}) recv = outbox[-1] self.assertSameEmail(recv['To'], ', ') - self.assertSameEmail(recv['From'], 'from1@ietf.org, from2@ietf.org') + self.assertSameEmail(recv['From'], 'from1@ietf.org') self.assertSameEmail(recv['Cc'], 'cc1@example.com, cc2@example.com') self.assertSameEmail(recv['Bcc'], None) self.assertEqual(recv['Subject'], 'subject') @@ -63,14 +85,14 @@ def test_send_mail_preformatted(self): override = { 'To': 'oto1@example.net, oto2@example.net', - 'From': 'ofrom1@ietf.org, ofrom2@ietf.org', + 'From': 'ofrom1@ietf.org', 'Cc': 'occ1@example.net, occ2@example.net', 'Subject': 'osubject', } send_mail_preformatted(request=None, preformatted=msg, extra={}, override=override) recv = outbox[-1] self.assertSameEmail(recv['To'], ', ') - self.assertSameEmail(recv['From'], 'ofrom1@ietf.org, ofrom2@ietf.org') + self.assertSameEmail(recv['From'], 'ofrom1@ietf.org') self.assertSameEmail(recv['Cc'], 'occ1@example.net, occ2@example.net') self.assertSameEmail(recv['Bcc'], None) self.assertEqual(recv['Subject'], 'osubject') @@ -78,14 +100,14 @@ def test_send_mail_preformatted(self): override = { 'To': ['', 'oto2@example.net'], - 'From': ['', 'ofrom2@ietf.org'], + 'From': [''], 'Cc': ['', 'occ2@example.net'], 'Subject': 'osubject', } send_mail_preformatted(request=None, preformatted=msg, extra={}, override=override) recv = outbox[-1] self.assertSameEmail(recv['To'], ', ') - self.assertSameEmail(recv['From'], ', ofrom2@ietf.org') + self.assertSameEmail(recv['From'], '') self.assertSameEmail(recv['Cc'], ', occ2@example.net') self.assertSameEmail(recv['Bcc'], None) self.assertEqual(recv['Subject'], 'osubject') @@ -101,6 +123,135 @@ def test_send_mail_preformatted(self): recv = outbox[-1] self.assertEqual(recv['Fuzz'], 'bucket, monger') + +class MailUtilsTests(TestCase): + def test_decode_header_value(self): + self.assertEqual( + decode_header_value("cake"), + "cake", + "decodes simple string value", + ) + self.assertEqual( + decode_header_value("=?utf-8?b?8J+Ogg==?="), + "\U0001f382", + "decodes single utf-8-encoded part", + ) + self.assertEqual( + decode_header_value("=?utf-8?b?8J+Ogg==?= = =?macintosh?b?jYxrjg==?="), + "\U0001f382 = çåké", + "decodes a value with non-utf-8 encodings", + ) + + # Patch in a side_effect so we can distinguish values that came from decode_header_value. + @patch("ietf.utils.mail.decode_header_value", side_effect=lambda s: f"decoded-{s}") + @patch("ietf.utils.mail.messages") + def test_show_that_mail_was_sent(self, mock_messages, mock_decode_header_value): + request = RequestFactory().get("/some/path") + request.user = object() # just needs to exist + msg = Message() + msg["To"] = "to-value" + msg["Subject"] = "subject-value" + msg["Cc"] = "cc-value" + with patch("ietf.ietfauth.utils.has_role", return_value=True): + show_that_mail_was_sent(request, "mail was sent", msg, "bcc-value") + self.assertCountEqual( + mock_decode_header_value.call_args_list, + [call("to-value"), call("subject-value"), call("cc-value"), call("bcc-value")], + ) + self.assertEqual(mock_messages.info.call_args[0][0], request) + self.assertIn("mail was sent", mock_messages.info.call_args[0][1]) + self.assertIn("decoded-subject-value", mock_messages.info.call_args[0][1]) + self.assertIn("decoded-to-value", mock_messages.info.call_args[0][1]) + self.assertIn("decoded-cc-value", mock_messages.info.call_args[0][1]) + self.assertIn("decoded-bcc-value", mock_messages.info.call_args[0][1]) + mock_messages.reset_mock() + mock_decode_header_value.reset_mock() + + # no bcc + with patch("ietf.ietfauth.utils.has_role", return_value=True): + show_that_mail_was_sent(request, "mail was sent", msg, None) + self.assertCountEqual( + mock_decode_header_value.call_args_list, + [call("to-value"), call("subject-value"), call("cc-value")], + ) + self.assertEqual(mock_messages.info.call_args[0][0], request) + self.assertIn("mail was sent", mock_messages.info.call_args[0][1]) + self.assertIn("decoded-subject-value", mock_messages.info.call_args[0][1]) + self.assertIn("decoded-to-value", mock_messages.info.call_args[0][1]) + self.assertIn("decoded-cc-value", mock_messages.info.call_args[0][1]) + # Note: here and below - when using assertNotIn(), leaving off the "decoded-" prefix + # proves that neither the original value nor the decoded value appear. + self.assertNotIn("bcc-value", mock_messages.info.call_args[0][1]) + mock_messages.reset_mock() + mock_decode_header_value.reset_mock() + + # no cc + del msg["Cc"] + with patch("ietf.ietfauth.utils.has_role", return_value=True): + show_that_mail_was_sent(request, "mail was sent", msg, None) + self.assertCountEqual( + mock_decode_header_value.call_args_list, + [call("to-value"), call("subject-value")], + ) + self.assertEqual(mock_messages.info.call_args[0][0], request) + self.assertIn("mail was sent", mock_messages.info.call_args[0][1]) + self.assertIn("decoded-subject-value", mock_messages.info.call_args[0][1]) + self.assertIn("decoded-to-value", mock_messages.info.call_args[0][1]) + self.assertNotIn("cc-value", mock_messages.info.call_args[0][1]) + self.assertNotIn("bcc-value", mock_messages.info.call_args[0][1]) + mock_messages.reset_mock() + mock_decode_header_value.reset_mock() + + # no to + del msg["To"] + with patch("ietf.ietfauth.utils.has_role", return_value=True): + show_that_mail_was_sent(request, "mail was sent", msg, None) + self.assertCountEqual( + mock_decode_header_value.call_args_list, + [call("[no to]"), call("subject-value")], + ) + self.assertEqual(mock_messages.info.call_args[0][0], request) + self.assertIn("mail was sent", mock_messages.info.call_args[0][1]) + self.assertIn("decoded-subject-value", mock_messages.info.call_args[0][1]) + self.assertIn("decoded-[no to]", mock_messages.info.call_args[0][1]) + self.assertNotIn("to-value", mock_messages.info.call_args[0][1]) + self.assertNotIn("cc-value", mock_messages.info.call_args[0][1]) + self.assertNotIn("bcc-value", mock_messages.info.call_args[0][1]) + mock_messages.reset_mock() + mock_decode_header_value.reset_mock() + + # no subject + del msg["Subject"] + with patch("ietf.ietfauth.utils.has_role", return_value=True): + show_that_mail_was_sent(request, "mail was sent", msg, None) + self.assertCountEqual( + mock_decode_header_value.call_args_list, + [call("[no to]"), call("[no subject]")], + ) + self.assertEqual(mock_messages.info.call_args[0][0], request) + self.assertIn("mail was sent", mock_messages.info.call_args[0][1]) + self.assertIn("decoded-[no subject]", mock_messages.info.call_args[0][1]) + self.assertNotIn("subject-value", mock_messages.info.call_args[0][1]) + self.assertIn("decoded-[no to]", mock_messages.info.call_args[0][1]) + self.assertNotIn("to-value", mock_messages.info.call_args[0][1]) + self.assertNotIn("cc-value", mock_messages.info.call_args[0][1]) + self.assertNotIn("bcc-value", mock_messages.info.call_args[0][1]) + mock_messages.reset_mock() + mock_decode_header_value.reset_mock() + + # user does not have role + with patch("ietf.ietfauth.utils.has_role", return_value=False): + show_that_mail_was_sent(request, "mail was sent", msg, None) + self.assertFalse(mock_messages.called) + + # no user + request.user = None + with patch("ietf.ietfauth.utils.has_role", return_value=True) as mock_has_role: + show_that_mail_was_sent(request, "mail was sent", msg, None) + self.assertFalse(mock_messages.called) + self.assertFalse(mock_has_role.called) + + class TestSMTPServer(TestCase): def test_address_rejected(self): @@ -158,20 +309,21 @@ def qualified(name): callbacks.add(qualified(entry.name)) if hasattr(entry, 'lookup_str') and entry.lookup_str: callbacks.add(qualified(entry.lookup_str)) - # There are some entries we don't handle here, mostly clases + # There are some entries we don't handle here, mostly classes # (such as Feed subclasses) return list(callbacks) -class TemplateChecksTestCase(TestCase): +class TemplateChecksTestCase(TestCase): # pragma: no cover paths = [] # type: List[str] templates = {} # type: Dict[str, Template] def setUp(self): super().setUp() - set_coverage_checking(False) - self.paths = list(get_template_paths()) + set_template_coverage(False) + set_url_coverage(False) + self.paths = get_template_paths() # already filtered ignores self.paths.sort() for path in self.paths: try: @@ -180,17 +332,14 @@ def setUp(self): pass def tearDown(self): - set_coverage_checking(True) + set_template_coverage(True) + set_url_coverage(True) super().tearDown() def test_parse_templates(self): errors = [] for path in self.paths: - for pattern in settings.TEST_TEMPLATE_IGNORE: - if fnmatch(path, pattern): - continue - if not path in self.templates: - + if path not in self.templates: try: get_template(path) except Exception as e: @@ -203,7 +352,7 @@ def apply_template_test(self, func, node_type, msg, *args, **kwargs): errors = [] for path, template in self.templates.items(): origin = str(template.origin).replace(settings.BASE_DIR, '') - for node in template: + for node in template.nodelist: for child in node.get_nodes_by_type(node_type): errors += func(child, origin, *args, **kwargs) if errors: @@ -318,7 +467,7 @@ def test_all_model_admins_exist(self): User.objects.create_superuser('admin', 'admin@example.org', 'admin+password') self.client.login(username='admin', password='admin+password') rtop = self.client.get("/admin/") - self.assertContains(rtop, 'Django administration') + self.assertContains(rtop, AdminSite.site_header()) for name in self.apps: app_name = self.apps[name] self.assertContains(rtop, name) @@ -368,10 +517,17 @@ def test_get_refs_v3(self): draft.get_refs(), { 'rfc1': XMLDraft.REF_TYPE_NORMATIVE, + 'rfc2': XMLDraft.REF_TYPE_NORMATIVE, + 'draft-wood-key-consistency-03': XMLDraft.REF_TYPE_INFORMATIVE, 'rfc255': XMLDraft.REF_TYPE_INFORMATIVE, 'bcp6': XMLDraft.REF_TYPE_INFORMATIVE, + 'bcp14': XMLDraft.REF_TYPE_INFORMATIVE, 'rfc1207': XMLDraft.REF_TYPE_UNKNOWN, 'rfc4086': XMLDraft.REF_TYPE_NORMATIVE, + 'draft-ietf-teas-pcecc-use-cases-00': XMLDraft.REF_TYPE_INFORMATIVE, + 'draft-ietf-teas-pcecc-use-cases': XMLDraft.REF_TYPE_INFORMATIVE, + 'draft-ietf-sipcore-multiple-reasons-00': XMLDraft.REF_TYPE_INFORMATIVE, + 'draft-ietf-sipcore-multiple-reasons': XMLDraft.REF_TYPE_INFORMATIVE, } ) @@ -387,6 +543,262 @@ def test_get_refs_v2(self): } ) + def test_parse_creation_date(self): + # override date_today to avoid skew when test runs around midnight + today = datetime.date.today() + with capture_xml2rfc_output(), patch("ietf.utils.xmldraft.date_today", return_value=today): + # Note: using a dict as a stand-in for XML elements, which rely on the get() method + self.assertEqual( + XMLDraft.parse_creation_date({"year": "2022", "month": "11", "day": "24"}), + datetime.date(2022, 11, 24), + "Fully specified date should be parsed", + ) + self.assertEqual( + XMLDraft.parse_creation_date(None), None, "return None if input is None" + ) + # Cases where the date is empty - missing fields or fields filled in with blank strings. + self.assertEqual(XMLDraft.parse_creation_date({}), today) + self.assertEqual(XMLDraft.parse_creation_date({"day": ""}), today) + self.assertEqual(XMLDraft.parse_creation_date({}), today) + self.assertEqual(XMLDraft.parse_creation_date({"year": ""}), today) + self.assertEqual(XMLDraft.parse_creation_date({"month": ""}), today) + self.assertEqual(XMLDraft.parse_creation_date({"day": ""}), today) + self.assertEqual(XMLDraft.parse_creation_date({"year": "", "month": ""}), today) + self.assertEqual(XMLDraft.parse_creation_date({"year": "", "day": ""}), today) + self.assertEqual(XMLDraft.parse_creation_date({"month": "", "day": ""}), today) + self.assertEqual( + XMLDraft.parse_creation_date({"year": "", "month": "", "day": ""}), today + ) + self.assertEqual( + XMLDraft.parse_creation_date( + {"year": str(today.year), "month": str(today.month), "day": ""} + ), + today, + ) + # When year/month do not match, day should be 15th of the month + self.assertEqual( + XMLDraft.parse_creation_date( + {"year": str(today.year - 1), "month": str(today.month), "day": ""} + ), + datetime.date(today.year - 1, today.month, 15), + ) + self.assertEqual( + XMLDraft.parse_creation_date( + { + "year": str(today.year), + "month": "1" if today.month != 1 else "2", + "day": "", + } + ), + datetime.date(today.year, 1 if today.month != 1 else 2, 15), + ) + # Some exeception-inducing conditions + with self.assertRaises( + InvalidMetadataError, + msg="raise an InvalidMetadataError if a year-only date is not current", + ): + XMLDraft.parse_creation_date( + { + "year": str(today.year - 1), + "month": "", + "day": "", + } + ) + with self.assertRaises( + InvalidMetadataError, + msg="raise an InvalidMetadataError for a non-numeric year" + ): + XMLDraft.parse_creation_date( + { + "year": "two thousand twenty-five", + "month": "2", + "day": "28", + } + ) + with self.assertRaises( + InvalidMetadataError, + msg="raise an InvalidMetadataError for an invalid month" + ): + XMLDraft.parse_creation_date( + { + "year": "2024", + "month": "13", + "day": "28", + } + ) + with self.assertRaises( + InvalidMetadataError, + msg="raise an InvalidMetadataError for a misspelled month" + ): + XMLDraft.parse_creation_date( + { + "year": "2024", + "month": "Oktobur", + "day": "28", + } + ) + with self.assertRaises( + InvalidMetadataError, + msg="raise an InvalidMetadataError for an invalid day" + ): + XMLDraft.parse_creation_date( + { + "year": "2024", + "month": "feb", + "day": "31", + } + ) + with self.assertRaises( + InvalidMetadataError, + msg="raise an InvalidMetadataError for a non-numeric day" + ): + XMLDraft.parse_creation_date( + { + "year": "2024", + "month": "feb", + "day": "twenty-four", + } + ) + + + def test_parse_docname(self): + with self.assertRaises(ValueError) as cm: + XMLDraft.parse_docname(lxml.etree.Element("xml")) # no docName + self.assertIn("Missing docName attribute", str(cm.exception)) + + # There to be more invalid docNames, but we use XMLDraft in places where we don't + # actually care about the validation, so for now just test what has long been the + # implementation. + with self.assertRaises(ValueError) as cm: + XMLDraft.parse_docname(lxml.etree.Element("xml", docName="")) # not a valid docName + self.assertIn("Unable to parse docName", str(cm.exception)) + + self.assertEqual( + XMLDraft.parse_docname(lxml.etree.Element("xml", docName="draft-foo-bar-baz-01")), + ("draft-foo-bar-baz", "01"), + ) + + self.assertEqual( + XMLDraft.parse_docname(lxml.etree.Element("xml", docName="draft-foo-bar-baz")), + ("draft-foo-bar-baz", None), + ) + + self.assertEqual( + XMLDraft.parse_docname(lxml.etree.Element("xml", docName="draft-foo-bar-baz-")), + ("draft-foo-bar-baz-", None), + ) + + # This is awful, but is how we've been running for some time. The missing rev will trigger + # validation errors for submissions, so we're at least somewhat guarded against this + # property. + self.assertEqual( + XMLDraft.parse_docname(lxml.etree.Element("xml", docName="-01")), + ("-01", None), + ) + + def test_render_author_name(self): + self.assertEqual( + XMLDraft.render_author_name(lxml.etree.Element("author", fullname="Joanna Q. Public")), + "Joanna Q. Public", + ) + self.assertEqual( + XMLDraft.render_author_name(lxml.etree.Element( + "author", + fullname="Joanna Q. Public", + asciiFullname="Not the Same at All", + )), + "Joanna Q. Public", + ) + self.assertEqual( + XMLDraft.render_author_name(lxml.etree.Element( + "author", + fullname=chr(340)+"ich", + asciiFullname="Rich UTF-8", + )), + chr(340)+"ich (Rich UTF-8)", + ) + self.assertEqual( + XMLDraft.render_author_name(lxml.etree.Element( + "author", + fullname="Joanna Q. Public", + initials="J. Q.", + surname="Public-Private", + )), + "Joanna Q. Public", + ) + self.assertEqual( + XMLDraft.render_author_name(lxml.etree.Element( + "author", + initials="J. Q.", + surname="Public", + )), + "J. Q. Public", + ) + self.assertEqual( + XMLDraft.render_author_name(lxml.etree.Element( + "author", + surname="Public", + )), + "Public", + ) + self.assertEqual( + XMLDraft.render_author_name(lxml.etree.Element( + "author", + initials="J. Q.", + )), + "J. Q.", + ) + + @patch("ietf.utils.xmldraft.XMLDraft.__init__", return_value=None) + def test_get_title(self, mock_init): + xmldraft = XMLDraft("fake") + self.assertTrue(mock_init.called) + # Stub XML that does not have a front/title element + xmldraft.xmlroot = lxml.etree.XML( + "" # no title + ) + self.assertEqual(xmldraft.get_title(), "") + + # Stub XML that has a front/title element + xmldraft.xmlroot = lxml.etree.XML( + "This Is the Title" + ) + self.assertEqual(xmldraft.get_title(), "This Is the Title") + + + def test_capture_xml2rfc_output(self): + """capture_xml2rfc_output reroutes and captures xml2rfc logs""" + orig_write_out = xml2rfc_log.write_out + orig_write_err = xml2rfc_log.write_err + with capture_xml2rfc_output() as outer_log_streams: # ensure no output + # such meta! very Inception! + with capture_xml2rfc_output() as inner_log_streams: + # arbitrary xml2rfc method that triggers a log, nothing special otherwise + xml2rfc_extract_date({"year": "fish"}, datetime.date(2025,3,1)) + self.assertNotEqual(inner_log_streams, outer_log_streams) + self.assertEqual(xml2rfc_log.write_out, outer_log_streams["stdout"], "out stream should be restored") + self.assertEqual(xml2rfc_log.write_err, outer_log_streams["stderr"], "err stream should be restored") + self.assertEqual(xml2rfc_log.write_out, orig_write_out, "original out stream should be restored") + self.assertEqual(xml2rfc_log.write_err, orig_write_err, "original err stream should be restored") + + # don't happen to get any output on stdout and not paranoid enough to force some, just test stderr + self.assertGreater(len(inner_log_streams["stderr"].getvalue()), 0, "want output on inner streams") + self.assertEqual(len(outer_log_streams["stdout"].getvalue()), 0, "no output on outer streams") + self.assertEqual(len(outer_log_streams["stderr"].getvalue()), 0, "no output on outer streams") + + def test_capture_xml2rfc_output_exception_handling(self): + """capture_xml2rfc_output restores streams after an exception""" + orig_write_out = xml2rfc_log.write_out + orig_write_err = xml2rfc_log.write_err + with capture_xml2rfc_output() as outer_log_streams: # ensure no output + with self.assertRaises(RuntimeError), capture_xml2rfc_output() as inner_log_streams: + raise RuntimeError("nooo") + self.assertNotEqual(inner_log_streams, outer_log_streams) + self.assertEqual(xml2rfc_log.write_out, outer_log_streams["stdout"], "out stream should be restored") + self.assertEqual(xml2rfc_log.write_err, outer_log_streams["stderr"], "err stream should be restored") + self.assertEqual(xml2rfc_log.write_out, orig_write_out, "original out stream should be restored") + self.assertEqual(xml2rfc_log.write_err, orig_write_err, "original err stream should be restored") + class NameTests(TestCase): @@ -451,24 +863,6 @@ def test_assertion(self): assertion('False') settings.SERVER_MODE = 'test' -class TestRFC2047Strings(TestCase): - def test_parse_unicode(self): - names = ( - ('=?utf-8?b?4Yuz4YuK4Ym1IOGJoOGJgOGIiA==?=', 'ዳዊት በቀለ'), - ('=?utf-8?b?5Li9IOmDnA==?=', '丽 郜'), - ('=?utf-8?b?4KSV4KSu4KWN4KSs4KWL4KScIOCkoeCkvuCksA==?=', 'कम्बोज डार'), - ('=?utf-8?b?zpfPgc6szrrOu861zrnOsSDOm865z4zOvc+Ezrc=?=', 'Ηράκλεια Λιόντη'), - ('=?utf-8?b?15nXqdeo15DXnCDXqNeV15bXoNek15zXkw==?=', 'ישראל רוזנפלד'), - ('=?utf-8?b?5Li95Y2OIOeahw==?=', '丽华 皇'), - ('=?utf-8?b?77ul77qu766V77qzIO+tlu+7ru+vvu+6ju+7pw==?=', 'ﻥﺮﮕﺳ ﭖﻮﯾﺎﻧ'), - ('=?utf-8?b?77uh77uu77qz77uu76++IO+6su+7tO+7p++6jSDvurDvu6Pvuo7vu6jvr74=?=', 'ﻡﻮﺳﻮﯾ ﺲﻴﻧﺍ ﺰﻣﺎﻨﯾ'), - ('=?utf-8?b?ScOxaWdvIFNhbsOnIEliw6HDsWV6IGRlIGxhIFBlw7Fh?=', 'Iñigo Sanç Ibáñez de la Peña'), - ('Mart van Oostendorp', 'Mart van Oostendorp'), - ('', ''), - ) - for encoded_str, unicode in names: - self.assertEqual(unicode, parse_unicode(encoded_str)) - class TestAndroidSiteManifest(TestCase): def test_manifest(self): r = self.client.get(urlreverse('site.webmanifest')) @@ -476,3 +870,71 @@ def test_manifest(self): manifest = json.loads(unicontent(r)) self.assertTrue('name' in manifest) self.assertTrue('theme_color' in manifest) + + +class TimezoneTests(TestCase): + """Tests of the timezone utilities""" + @patch( + 'ietf.utils.timezone.timezone.now', + return_value=pytz.timezone('America/Chicago').localize(datetime.datetime(2022, 7, 1, 23, 15, 0)), # 23:15:00 + ) + def test_timezone_not_near_midnight(self, mock): + # give it several choices that should be rejected and one that should be accepted + with patch( + 'ietf.utils.timezone.available_timezones', + return_value=set([ + 'America/Chicago', # time is 23:15, should be rejected + 'America/Lima', # time is 23:15, should be rejected + 'America/New_York', # time is 00:15, should be rejected + 'Europe/Riga', # time is 07:15, acceptable + ]), + ): + # check a few times (will pass by chance < 0.1% of the time) + self.assertEqual(timezone_not_near_midnight(), 'Europe/Riga') + self.assertEqual(timezone_not_near_midnight(), 'Europe/Riga') + self.assertEqual(timezone_not_near_midnight(), 'Europe/Riga') + self.assertEqual(timezone_not_near_midnight(), 'Europe/Riga') + self.assertEqual(timezone_not_near_midnight(), 'Europe/Riga') + + # now give it no valid choice + with patch( + 'ietf.utils.timezone.available_timezones', + return_value=set([ + 'America/Chicago', # time is 23:15, should be rejected + 'America/Lima', # time is 23:15, should be rejected + 'America/New_York', # time is 00:15, should be rejected + ]), + ): + with self.assertRaises(RuntimeError): + timezone_not_near_midnight() + + +class SearchableFieldTests(TestCase): + def test_has_changed_single_value(self): + """Should work with initial as a single value or list when max_entries == 1""" + class TestSearchableField(SearchableField): + model = "fake model" # needs to be not-None to allow field init + + class TestForm(Form): + test_field = TestSearchableField(max_entries=1) + + # single value in initial (e.g., when used as a single-valued field in a formset) + changed_form = TestForm(initial={'test_field': 1}, data={'test_field': [2]}) + self.assertTrue(changed_form.has_changed()) + unchanged_form = TestForm(initial={'test_field': 1}, data={'test_field': [1]}) + self.assertFalse(unchanged_form.has_changed()) + + # list value in initial (usual situation for a MultipleChoiceField subclass like SearchableField) + changed_form = TestForm(initial={'test_field': [1]}, data={'test_field': [2]}) + self.assertTrue(changed_form.has_changed()) + unchanged_form = TestForm(initial={'test_field': [1]}, data={'test_field': [1]}) + self.assertFalse(unchanged_form.has_changed()) + + +class HealthTests(TestCase): + def test_health(self): + self.assertEqual( + self.client.get("/health/").status_code, + 200, + ) + diff --git a/ietf/utils/tests_coverage.py b/ietf/utils/tests_coverage.py new file mode 100644 index 00000000000..68795994a7e --- /dev/null +++ b/ietf/utils/tests_coverage.py @@ -0,0 +1,56 @@ +# Copyright The IETF Trust 2025, All Rights Reserved +"""Tests of the coverage.py module""" + +from unittest import mock + +from django.test import override_settings + +from .coverage import CoverageManager +from .test_utils import TestCase + + +class CoverageManagerTests(TestCase): + @override_settings( + BASE_DIR="/path/to/project/ietf", + TEST_CODE_COVERAGE_EXCLUDE_FILES=["a.py"], + TEST_CODE_COVERAGE_EXCLUDE_LINES=["some-regex"], + ) + @mock.patch("ietf.utils.coverage.Coverage") + def test_coverage_manager(self, mock_coverage): + """CoverageManager managed coverage correctly in non-production mode + + Presumes we're not running tests in production mode. + """ + cm = CoverageManager() + self.assertFalse(cm.started) + + cm.start() + self.assertTrue(cm.started) + self.assertEqual(cm.checker, mock_coverage.return_value) + self.assertTrue(mock_coverage.called) + coverage_kwargs = mock_coverage.call_args.kwargs + self.assertEqual(coverage_kwargs["source"], ["/path/to/project/ietf"]) + self.assertEqual(coverage_kwargs["omit"], ["a.py"]) + self.assertTrue(isinstance(cm.checker.exclude, mock.Mock)) + assert isinstance(cm.checker.exclude, mock.Mock) # for type checker + self.assertEqual(cm.checker.exclude.call_count, 1) + cm.checker.exclude.assert_called_with("some-regex") + + @mock.patch("ietf.utils.coverage.Coverage") + def test_coverage_manager_is_defanged_in_production(self, mock_coverage): + """CoverageManager is a no-op in production mode""" + # Be careful faking settings.SERVER_MODE, but there's really no other way to + # test this. + with override_settings(SERVER_MODE="production"): + cm = CoverageManager() + cm.start() + + # Check that nothing actually happened + self.assertFalse(mock_coverage.called) + self.assertIsNone(cm.checker) + self.assertFalse(cm.started) + + # Check that other methods are guarded appropriately + cm.stop() + cm.save() + self.assertIsNone(cm.report()) diff --git a/ietf/utils/tests_markdown.py b/ietf/utils/tests_markdown.py new file mode 100644 index 00000000000..c8c07b50c7d --- /dev/null +++ b/ietf/utils/tests_markdown.py @@ -0,0 +1,60 @@ +# Copyright The IETF Trust 2023, All Rights Reserved +"""Markdown API utilities tests""" + +from textwrap import dedent + +from ietf.utils.tests import TestCase +from ietf.utils.markdown import markdown + + +class MarkdownTests(TestCase): + SAMPLE_MARKDOWN = dedent( + """ + # IETF Markdown Test File + + This file contains a bunch of constructs to test our markdown converter in + `ietf/utils/markdown.py`. + + ## Links + + * https://example.com + * + * [Example](https://example.com) + * user@example.com + * + * [User](mailto:user@example.com) + * RFC2119 + * BCP 3 + * STD 1 + * FYI2 + * draft-ietf-opsec-indicators-of-compromise + * draft-ietf-opsec-indicators-of-compromise-01 + """ + ) + + SAMPLE_MARKDOWN_OUTPUT = dedent( + """ +

    IETF Markdown Test File

    +

    This file contains a bunch of constructs to test our markdown converter in
    + ietf/utils/markdown.py.

    + + + """ + ).strip() + + def test_markdown(self): + result = markdown(self.SAMPLE_MARKDOWN) + self.assertEqual(result, self.SAMPLE_MARKDOWN_OUTPUT) diff --git a/ietf/utils/tests_meetecho.py b/ietf/utils/tests_meetecho.py index d40e013f826..c076a3df745 100644 --- a/ietf/utils/tests_meetecho.py +++ b/ietf/utils/tests_meetecho.py @@ -4,15 +4,18 @@ import requests import requests_mock -from pytz import timezone, utc -from unittest.mock import patch +from unittest.mock import call, patch from urllib.parse import urljoin +from zoneinfo import ZoneInfo from django.conf import settings from django.test import override_settings +from django.utils import timezone +from ietf.doc.factories import DocumentFactory +from ietf.meeting.factories import SessionFactory, SessionPresentationFactory from ietf.utils.tests import TestCase -from .meetecho import Conference, ConferenceManager, MeetechoAPI, MeetechoAPIError +from .meetecho import Conference, ConferenceManager, MeetechoAPI, MeetechoAPIError, SlidesManager API_BASE = 'https://meetecho-api.example.com' CLIENT_ID = 'datatracker' @@ -21,6 +24,7 @@ 'api_base': API_BASE, 'client_id': CLIENT_ID, 'client_secret': CLIENT_SECRET, + 'slides_notify_time': -1, # always send notification } @@ -30,6 +34,7 @@ class APITests(TestCase): schedule_meeting_url = urljoin(API_BASE, 'meeting/interim/createRoom') fetch_meetings_url = urljoin(API_BASE, 'meeting/interim/fetchRooms') delete_meetings_url = urljoin(API_BASE, 'meeting/interim/deleteRoom') + slide_deck_url = urljoin(API_BASE, "materials") def setUp(self): super().setUp() @@ -77,7 +82,7 @@ def test_schedule_meeting(self): 'rooms': { '3d55bce0-535e-4ba8-bb8e-734911cf3c32': { 'room': { - 'id': 18, + 'id': 18, # should match room_id in api.schedule_meeting() below 'start_time': '2021-09-14 10:00:00', 'duration': 130, 'description': 'interim-2021-wgname-01', @@ -92,7 +97,8 @@ def test_schedule_meeting(self): api = MeetechoAPI(API_BASE, CLIENT_ID, CLIENT_SECRET) api_response = api.schedule_meeting( wg_token='my-token', - start_time=utc.localize(datetime.datetime(2021, 9, 14, 10, 0, 0)), + room_id=18, + start_time=datetime.datetime(2021, 9, 14, 10, 0, 0, tzinfo=datetime.UTC), duration=datetime.timedelta(minutes=130), description='interim-2021-wgname-01', extrainfo='message for staff', @@ -111,6 +117,7 @@ def test_schedule_meeting(self): self.assertEqual( request.json(), { + 'room_id': 18, 'duration': 130, 'start_time': '2021-09-14 10:00:00', 'extrainfo': 'message for staff', @@ -120,11 +127,11 @@ def test_schedule_meeting(self): ) # same time in different time zones for start_time in [ - utc.localize(datetime.datetime(2021, 9, 14, 10, 0, 0)), - timezone('america/halifax').localize(datetime.datetime(2021, 9, 14, 7, 0, 0)), - timezone('europe/kiev').localize(datetime.datetime(2021, 9, 14, 13, 0, 0)), - timezone('pacific/easter').localize(datetime.datetime(2021, 9, 14, 5, 0, 0)), - timezone('africa/porto-novo').localize(datetime.datetime(2021, 9, 14, 11, 0, 0)), + datetime.datetime(2021, 9, 14, 10, 0, 0, tzinfo=datetime.UTC), + datetime.datetime(2021, 9, 14, 7, 0, 0, tzinfo=ZoneInfo('America/Halifax')), + datetime.datetime(2021, 9, 14, 13, 0, 0, tzinfo=ZoneInfo('Europe/Kiev')), + datetime.datetime(2021, 9, 14, 5, 0, 0, tzinfo=ZoneInfo('Pacific/Easter')), + datetime.datetime(2021, 9, 14, 11, 0, 0, tzinfo=ZoneInfo('Africa/Porto-Novo')), ]: self.assertEqual( api_response, @@ -142,7 +149,7 @@ def test_schedule_meeting(self): }, } }, - f'Incorrect time conversion for {start_time.tzinfo.zone}', + f'Incorrect time conversion for {start_time.tzinfo}', ) def test_fetch_meetings(self): @@ -191,7 +198,7 @@ def test_fetch_meetings(self): '3d55bce0-535e-4ba8-bb8e-734911cf3c32': { 'room': { 'id': 18, - 'start_time': utc.localize(datetime.datetime(2021, 9, 14, 10, 0, 0)), + 'start_time': datetime.datetime(2021, 9, 14, 10, 0, 0, tzinfo=datetime.UTC), 'duration': datetime.timedelta(minutes=130), 'description': 'interim-2021-wgname-01', }, @@ -201,7 +208,7 @@ def test_fetch_meetings(self): 'e68e96d4-d38f-475b-9073-ecab46ca96a5': { 'room': { 'id': 23, - 'start_time': utc.localize(datetime.datetime(2021, 9, 15, 14, 30, 0)), + 'start_time': datetime.datetime(2021, 9, 15, 14, 30, 0, tzinfo=datetime.UTC), 'duration': datetime.timedelta(minutes=30), 'description': 'interim-2021-wgname-02', }, @@ -227,6 +234,136 @@ def test_delete_meeting(self): self.assertIsNone(request.body, 'Delete meeting request has no body') self.assertCountEqual(api_response, data_to_fetch) + def test_add_slide_deck(self): + self.requests_mock.post(self.slide_deck_url, status_code=202) + + api = MeetechoAPI(API_BASE, CLIENT_ID, CLIENT_SECRET) + api_response = api.add_slide_deck( + wg_token="my-token", + session="1234", + deck={ + "title": "A Slide Deck", + "id": 17, + "url": "https://example.com/decks/17", + "rev": "00", + "order": 0, + } + ) + self.assertIsNone(api_response) # no return value from this call + + self.assertTrue(self.requests_mock.called) + request = self.requests_mock.last_request + self.assertIn("Authorization", request.headers) + self.assertEqual( + request.headers["Content-Type"], + "application/json", + "Incorrect request content-type", + ) + self.assertEqual(request.headers["Authorization"], "bearer my-token", + "Incorrect request authorization header") + self.assertEqual( + request.json(), + { + "session": "1234", + "title": "A Slide Deck", + "id": 17, + "url": "https://example.com/decks/17", + "rev": "00", + "order": 0, + }, + "Incorrect request content" + ) + + def test_delete_slide_deck(self): + self.requests_mock.delete(self.slide_deck_url, status_code=202) + + api = MeetechoAPI(API_BASE, CLIENT_ID, CLIENT_SECRET) + api_response = api.delete_slide_deck( + wg_token="my-token", + session="1234", + id=17, + ) + self.assertIsNone(api_response) # no return value from this call + + self.assertTrue(self.requests_mock.called) + request = self.requests_mock.last_request + self.assertIn("Authorization", request.headers) + self.assertEqual( + request.headers["Content-Type"], + "application/json", + "Incorrect request content-type", + ) + self.assertEqual(request.headers["Authorization"], "bearer my-token", + "Incorrect request authorization header") + self.assertEqual( + request.json(), + { + "session": "1234", + "id": 17, + }, + "Incorrect request content" + ) + + def test_update_slide_decks(self): + self.requests_mock.put(self.slide_deck_url, status_code=202) + + api = MeetechoAPI(API_BASE, CLIENT_ID, CLIENT_SECRET) + api_response = api.update_slide_decks( + wg_token="my-token", + session="1234", + decks=[ + { + "title": "A Slide Deck", + "id": 17, + "url": "https://example.com/decks/17", + "rev": "00", + "order": 0, + }, + { + "title": "Another Slide Deck", + "id": 23, + "url": "https://example.com/decks/23", + "rev": "03", + "order": 1, + } + ] + ) + self.assertIsNone(api_response) # no return value from this call + + self.assertTrue(self.requests_mock.called) + request = self.requests_mock.last_request + self.assertIn("Authorization", request.headers) + self.assertEqual( + request.headers["Content-Type"], + "application/json", + "Incorrect request content-type", + ) + self.assertEqual(request.headers["Authorization"], "bearer my-token", + "Incorrect request authorization header") + self.assertEqual( + request.json(), + { + "session": "1234", + "decks": [ + { + "title": "A Slide Deck", + "id": 17, + "url": "https://example.com/decks/17", + "rev": "00", + "order": 0, + }, + { + "title": "Another Slide Deck", + "id": 23, + "url": "https://example.com/decks/23", + "rev": "03", + "order": 1, + }, + ], + }, + "Incorrect request content" + ) + def test_request_helper_failed_requests(self): self.requests_mock.register_uri(requests_mock.ANY, urljoin(API_BASE, 'unauthorized/url/endpoint'), status_code=401) self.requests_mock.register_uri(requests_mock.ANY, urljoin(API_BASE, 'forbidden/url/endpoint'), status_code=403) @@ -249,7 +386,7 @@ def test_request_helper_exception(self): def test_time_serialization(self): """Time de/serialization should be consistent""" - time = datetime.datetime.now(utc).replace(microsecond=0) # cut off to 0 microseconds + time = timezone.now().astimezone(datetime.UTC).replace(microsecond=0) # cut off to 0 microseconds api = MeetechoAPI(API_BASE, CLIENT_ID, CLIENT_SECRET) self.assertEqual(api._deserialize_time(api._serialize_time(time)), time) @@ -263,7 +400,7 @@ def test_conference_from_api_dict(self): 'session-1-uuid': { 'room': { 'id': 1, - 'start_time': utc.localize(datetime.datetime(2022,2,4,1,2,3)), + 'start_time': datetime.datetime(2022,2,4,1,2,3, tzinfo=datetime.UTC), 'duration': datetime.timedelta(minutes=45), 'description': 'some-description', }, @@ -273,7 +410,7 @@ def test_conference_from_api_dict(self): 'session-2-uuid': { 'room': { 'id': 2, - 'start_time': utc.localize(datetime.datetime(2022,2,5,4,5,6)), + 'start_time': datetime.datetime(2022,2,5,4,5,6, tzinfo=datetime.UTC), 'duration': datetime.timedelta(minutes=90), 'description': 'another-description', }, @@ -290,7 +427,7 @@ def test_conference_from_api_dict(self): id=1, public_id='session-1-uuid', description='some-description', - start_time=utc.localize(datetime.datetime(2022, 2, 4, 1, 2, 3)), + start_time=datetime.datetime(2022, 2, 4, 1, 2, 3, tzinfo=datetime.UTC), duration=datetime.timedelta(minutes=45), url='https://example.com/some/url', deletion_token='delete-me', @@ -300,7 +437,7 @@ def test_conference_from_api_dict(self): id=2, public_id='session-2-uuid', description='another-description', - start_time=utc.localize(datetime.datetime(2022, 2, 5, 4, 5, 6)), + start_time=datetime.datetime(2022, 2, 5, 4, 5, 6, tzinfo=datetime.UTC), duration=datetime.timedelta(minutes=90), url='https://example.com/another/url', deletion_token='delete-me-too', @@ -316,7 +453,7 @@ def test_fetch(self, mock_fetch, _): 'session-1-uuid': { 'room': { 'id': 1, - 'start_time': utc.localize(datetime.datetime(2022,2,4,1,2,3)), + 'start_time': datetime.datetime(2022,2,4,1,2,3, tzinfo=datetime.UTC), 'duration': datetime.timedelta(minutes=45), 'description': 'some-description', }, @@ -335,7 +472,7 @@ def test_fetch(self, mock_fetch, _): id=1, public_id='session-1-uuid', description='some-description', - start_time=utc.localize(datetime.datetime(2022,2,4,1,2,3)), + start_time=datetime.datetime(2022,2,4,1,2,3, tzinfo=datetime.UTC), duration=datetime.timedelta(minutes=45), url='https://example.com/some/url', deletion_token='delete-me', @@ -350,8 +487,8 @@ def test_create(self, mock_schedule, _): 'rooms': { 'session-1-uuid': { 'room': { - 'id': 1, - 'start_time': utc.localize(datetime.datetime(2022,2,4,1,2,3)), + 'id': 1, # value should match session_id param to cm.create() below + 'start_time': datetime.datetime(2022,2,4,1,2,3, tzinfo=datetime.UTC), 'duration': datetime.timedelta(minutes=45), 'description': 'some-description', }, @@ -361,7 +498,7 @@ def test_create(self, mock_schedule, _): }, } cm = ConferenceManager(settings.MEETECHO_API_CONFIG) - result = cm.create('group', 'desc', 'starttime', 'dur', 'extra') + result = cm.create('group', '1', 'desc', 'starttime', 'dur', 'extra') self.assertEqual( result, [Conference( @@ -369,7 +506,7 @@ def test_create(self, mock_schedule, _): id=1, public_id='session-1-uuid', description='some-description', - start_time=utc.localize(datetime.datetime(2022,2,4,1,2,3)), + start_time=datetime.datetime(2022,2,4,1,2,3, tzinfo=datetime.UTC), duration=datetime.timedelta(minutes=45), url='https://example.com/some/url', deletion_token='delete-me', @@ -380,6 +517,7 @@ def test_create(self, mock_schedule, _): kwargs, { 'wg_token': 'atoken', + 'room_id': 1, 'description': 'desc', 'start_time': 'starttime', 'duration': 'dur', @@ -393,10 +531,176 @@ def test_delete_conference(self, mock_delete): args, kwargs = mock_delete.call_args self.assertEqual(args, ('delete-this',)) - @patch('ietf.utils.meetecho.MeetechoAPI.delete_meeting') def test_delete_by_url(self, mock_delete): cm = ConferenceManager(settings.MEETECHO_API_CONFIG) cm.delete_conference(Conference(None, None, None, None, None, None, 'the-url', 'delete-this')) args, kwargs = mock_delete.call_args self.assertEqual(args, ('delete-this',)) + + +@patch.object(SlidesManager, 'wg_token', return_value='atoken') +@override_settings(MEETECHO_API_CONFIG=API_CONFIG) +class SlidesManagerTests(TestCase): + @patch("ietf.utils.meetecho.MeetechoAPI.add_slide_deck") + def test_add(self, mock_add, mock_wg_token): + sm = SlidesManager(settings.MEETECHO_API_CONFIG) + session = SessionFactory() + slides_doc = DocumentFactory(type_id="slides") + retval = sm.add(session, slides_doc, 13) + self.assertIs(retval, True) + self.assertTrue(mock_wg_token.called) + self.assertTrue(mock_add.called) + self.assertEqual( + mock_add.call_args, + call( + wg_token="atoken", + session=str(session.pk), + deck={ + "id": slides_doc.pk, + "title": slides_doc.title, + "url": slides_doc.get_href(session.meeting), + "rev": slides_doc.rev, + "order": 13, + }, + ), + ) + + # Test return value when no update is sent. Really ought to do a more + # careful test of the _should_send_update() method. + sm = SlidesManager( + settings.MEETECHO_API_CONFIG | {"slides_notify_time": None} + ) + retval = sm.add(session, slides_doc, 14) + self.assertIs(retval, False) + + @patch("ietf.utils.meetecho.MeetechoAPI.update_slide_decks") + @patch("ietf.utils.meetecho.MeetechoAPI.delete_slide_deck") + def test_delete(self, mock_delete, mock_update, mock_wg_token): + sm = SlidesManager(settings.MEETECHO_API_CONFIG) + # Test scenario: we had a session with two slide decks and we already deleted the SessionPresentation + # for one and are now updating Meetecho + slides = SessionPresentationFactory(document__type_id="slides", order=1) # still attached to the session + session = slides.session + slides_doc = slides.document + removed_slides_doc = DocumentFactory(type_id="slides") + + with self.assertRaises(MeetechoAPIError): + sm.delete(session, slides_doc) # can't remove slides still attached to the session + self.assertFalse(any([mock_wg_token.called, mock_delete.called, mock_update.called])) + + retval = sm.delete(session, removed_slides_doc) + self.assertIs(retval, True) + self.assertTrue(mock_wg_token.called) + self.assertTrue(mock_delete.called) + self.assertEqual( + mock_delete.call_args, + call(wg_token="atoken", session=str(session.pk), id=removed_slides_doc.pk), + ) + self.assertTrue(mock_update.called) + self.assertEqual( + mock_update.call_args, + call( + wg_token="atoken", + session=str(session.pk), + decks=[ + { + "id": slides_doc.pk, + "title": slides_doc.title, + "url": slides_doc.get_href(session.meeting), + "rev": slides_doc.rev, + "order": 1, + }, + ] + ) + ) + mock_delete.reset_mock() + mock_update.reset_mock() + + # Delete the other session and check that we don't make the update call + slides.delete() + retval = sm.delete(session, slides_doc) + self.assertIs(retval, True) + self.assertTrue(mock_delete.called) + self.assertFalse(mock_update.called) + + # Test return value when no update is sent. Really ought to do a more + # careful test of the _should_send_update() method. + sm = SlidesManager( + settings.MEETECHO_API_CONFIG | {"slides_notify_time": None} + ) + retval = sm.delete(session, slides_doc) + self.assertIs(retval, False) + + @patch("ietf.utils.meetecho.MeetechoAPI.delete_slide_deck") + @patch("ietf.utils.meetecho.MeetechoAPI.add_slide_deck") + def test_revise(self, mock_add, mock_delete, mock_wg_token): + sm = SlidesManager(settings.MEETECHO_API_CONFIG) + slides = SessionPresentationFactory(document__type_id="slides", order=23) + slides_doc = slides.document + retval = sm.revise(slides.session, slides_doc) + self.assertIs(retval, True) + self.assertTrue(mock_wg_token.called) + self.assertTrue(mock_delete.called) + self.assertEqual( + mock_delete.call_args, + call(wg_token="atoken", session=str(slides.session.pk), id=slides_doc.pk), + ) + self.assertTrue(mock_add.called) + self.assertEqual( + mock_add.call_args, + call( + wg_token="atoken", + session=str(slides.session.pk), + deck={ + "id": slides_doc.pk, + "title": slides_doc.title, + "url": slides_doc.get_href(slides.session.meeting), + "rev": slides_doc.rev, + "order": 23, + }, + ), + ) + + # Test return value when no update is sent. Really ought to do a more + # careful test of the _should_send_update() method. + sm = SlidesManager( + settings.MEETECHO_API_CONFIG | {"slides_notify_time": None} + ) + retval = sm.revise(slides.session, slides_doc) + self.assertIs(retval, False) + + + @patch("ietf.utils.meetecho.MeetechoAPI.update_slide_decks") + def test_send_update(self, mock_send_update, mock_wg_token): + sm = SlidesManager(settings.MEETECHO_API_CONFIG) + slides = SessionPresentationFactory(document__type_id="slides") + SessionPresentationFactory(session=slides.session, document__type_id="agenda") + retval = sm.send_update(slides.session) + self.assertIs(retval, True) + self.assertTrue(mock_wg_token.called) + self.assertTrue(mock_send_update.called) + self.assertEqual( + mock_send_update.call_args, + call( + wg_token="atoken", + session=str(slides.session_id), + decks=[ + { + "id": slides.document_id, + "title": slides.document.title, + "url": slides.document.get_href(slides.session.meeting), + "rev": slides.document.rev, + "order": 0, + } + ] + ) + ) + + # Test return value when no update is sent. Really ought to do a more + # careful test of the _should_send_update() method. + sm = SlidesManager( + settings.MEETECHO_API_CONFIG | {"slides_notify_time": None} + ) + retval = sm.send_update(slides.session) + self.assertIs(retval, False) diff --git a/ietf/utils/tests_reports.py b/ietf/utils/tests_reports.py new file mode 100755 index 00000000000..83daa15cc14 --- /dev/null +++ b/ietf/utils/tests_reports.py @@ -0,0 +1,189 @@ +# Copyright The IETF Trust 2026, All Rights Reserved + +import datetime + +import debug # pyflakes:ignore + +from ietf.doc.factories import IndividualDraftFactory +from ietf.person.factories import EmailFactory +from ietf.person.models import Person, Email +from ietf.submit.factories import SubmissionFactory +from ietf.utils.reports import authors_by_year, submitters_by_year, unique_people +from ietf.utils.test_utils import TestCase + + +class ReportTests(TestCase): + def setUp(self): + super().setUp() + + # Build 5 drafts submitted across two years, with 6 unique authors, + # one of which has more than one email address (author0@example.com and + # author0@example.net). The drafts are submitted by two of the six authors, + # again using multiple addresses for author0, and two identities that are not authors. + # Then build a draft where the submission's submitter info doesn't contain an email + # address (we have those in the production database) to make sure that submitter isn't + # counted. + + self.make_draft_submission( + year=2020, + month=1, + day=1, + submitter_name="Author 0", + submitter_email="author0@example.net", + author_nameaddrs=[ + ("Author 0", "author0@example.net"), + ("Author 1", "author1@example.net"), + ], + ) + + self.make_draft_submission( + year=2020, + month=3, + day=3, + submitter_name="NotanAuthor 0", + submitter_email="notanauthor0@example.net", + author_nameaddrs=[ + ("Author 0", "author0@example.com"), # Note alternate email + ("Author 3", "author3@example.net"), + ], + ) + + self.make_draft_submission( + year=2020, + month=12, + day=31, + submitter_name="Author 3", + submitter_email="author3@example.net", + author_nameaddrs=[("Author 3", "author3@example.net")], + ) + + self.make_draft_submission( + year=2021, + month=1, + day=1, + submitter_name="Author 0", + submitter_email="author0@example.com", # Note alternate email + author_nameaddrs=[ + ("Author 0", "author0@example.com"), # Again, alternate email + ("Author 4", "author4@example.net"), + ], + ) + + self.make_draft_submission( + year=2021, + month=12, + day=31, + submitter_name="NoatanAuthor 2", + submitter_email="notanauthor2@example.net", + author_nameaddrs=[ + ("Author 0", "author0@example.net"), + ("Author 3", "author3@example.net"), + ("Author 5", "author5@example.net"), + ], + ) + + self.make_draft_submission( + year=2021, + month=12, + day=31, + submitter_name="Trouble Maker", + submitter_email="", + author_nameaddrs=[ + ("Author 0", "author0@example.net"), + ("Author 2", "author2@example.net"), + ], + ) + + def make_draft_submission( + self, year, month, day, submitter_name, submitter_email, author_nameaddrs + ): + + authors = [] + for name, addr in author_nameaddrs: + person = Person.objects.filter(name=name).first() + if not person: + person = EmailFactory(person__name=name, address=addr).person + elif not Email.objects.filter(address=addr).exists(): + EmailFactory(person=person, address=addr) + authors.append(person) + + submission = SubmissionFactory( + submission_date=datetime.date(year, month, day), + submitter_name=submitter_name, + submitter_email=submitter_email, + state_id="posted", + ) + submission.authors = [ + { + "name": f"{name}", + "email": f"{addr}", + "affiliation": "", + "country": "", + "errors": [], + } + for name, addr in author_nameaddrs + ] + + submission.save() + IndividualDraftFactory(submission=submission, authors=authors) + + def test_authors_by_year(self): + authors2020 = authors_by_year(2020) + self.assertEqual( + authors2020, + set( + [ + "author0@example.net", + "author0@example.com", + "author1@example.net", + "author3@example.net", + ] + ), + ) + authors2021 = authors_by_year(2021) + self.assertEqual( + authors2021, + set( + [ + "author0@example.net", + "author0@example.com", + "author2@example.net", + "author3@example.net", + "author4@example.net", + "author5@example.net", + ] + ), + ) + + def test_submitters_by_year(self): + sub2020 = submitters_by_year(2020) + self.assertEqual( + sub2020, + set( + [ + "author0@example.net", + "author3@example.net", + "notanauthor0@example.net", + ] + ), + ) + sub2021 = submitters_by_year(2021) + self.assertEqual( + sub2021, set(["author0@example.com", "notanauthor2@example.net"]) + ) + + def test_unique_people(self): + persons, addrs = unique_people( + [ + "notanauthor0@example.com", + "author0@example.net", + "author0@example.com", + "author1@example.net", + "notanauthor0@example.com", + ] + ) + self.assertEqual(addrs, set(["notanauthor0@example.com"])) + self.assertEqual( + set(persons), set(Person.objects.filter(name__in=("Author 0", "Author 1"))) + ) + self.assertEqual(len(persons) + len(addrs), 3) diff --git a/ietf/utils/tests_searchindex.py b/ietf/utils/tests_searchindex.py new file mode 100644 index 00000000000..b97bc2e266c --- /dev/null +++ b/ietf/utils/tests_searchindex.py @@ -0,0 +1,325 @@ +# Copyright The IETF Trust 2026, All Rights Reserved +from unittest import mock + +import requests.exceptions +import typesense.exceptions +from django.conf import settings +from django.test.utils import override_settings + +from . import searchindex +from .test_utils import TestCase +from ..blobdb.models import Blob +from ..doc.factories import ( + WgDraftFactory, + WgRfcFactory, + PublishedRfcDocEventFactory, + BcpFactory, + StdFactory, +) +from ..doc.models import Document, RelatedDocument +from ..doc.storage_utils import store_str +from ..person.factories import PersonFactory + + +class SearchindexTests(TestCase): + def test_enabled(self): + with override_settings(): + try: + del settings.SEARCHINDEX_CONFIG + except AttributeError: + pass + self.assertFalse(searchindex.enabled()) + with override_settings( + SEARCHINDEX_CONFIG={"TYPESENSE_API_KEY": "this-is-not-a-key"} + ): + self.assertFalse(searchindex.enabled()) + with override_settings( + SEARCHINDEX_CONFIG={"TYPESENSE_API_URL": "http://example.com"} + ): + self.assertTrue(searchindex.enabled()) + + def test_sanitize_text(self): + dirty_text = """ + + This is text. It + is <---- full of \tprobl.....ems! Fix it. + """ + sanitized = "This is text It is full of problems Fix it." + self.assertEqual(searchindex._sanitize_text(dirty_text), sanitized) + + def test_sanitize_abstract(self): + dirty_abstract = ( + "Mixed\n" + "Newlines\r" + "And\r\n" + "Things\n\r" + " Sometimes\n" + "\n" + "With\r\n" + "\r\n" + "Double \n\r" + "\n\r" + " Newlines\r" + "\r" + "Whee!" + ) + sanitized = ( + "Mixed\n" + "Newlines\n" + "And\n" + "Things\n" + "Sometimes\n" + "\n" + "With\n" + "\n" + "Double\n" + "\n" + "Newlines\n" + "\n" + "Whee!" + ) + self.assertEqual(searchindex._sanitize_abstract(dirty_abstract), sanitized) + + def test_typesense_doc_from_rfc(self): + not_rfc = WgDraftFactory() + assert isinstance(not_rfc, Document) + with self.assertRaises(AssertionError): + searchindex.typesense_doc_from_rfc(not_rfc) + + invalid_rfc = WgRfcFactory(name="rfc1000000", rfc_number=None) + assert isinstance(invalid_rfc, Document) + with self.assertRaises(AssertionError): + searchindex.typesense_doc_from_rfc(invalid_rfc) + + rfc = PublishedRfcDocEventFactory().doc + assert isinstance(rfc, Document) + result = searchindex.typesense_doc_from_rfc(rfc) + # Check a few values, not exhaustive + self.assertEqual(result["id"], f"doc-{rfc.pk}") + self.assertEqual(result["rfcNumber"], rfc.rfc_number) + self.assertEqual(result["abstract"], searchindex._sanitize_abstract(rfc.abstract)) + self.assertEqual(result["pages"], rfc.pages) + self.assertNotIn("adName", result) + self.assertNotIn("content", result) # no blob + self.assertNotIn("subseries", result) + + # repeat, this time with contents, an AD, and subseries docs + store_str( + kind="rfc", + name=f"txt/{rfc.name}.txt", + content="The contents of this RFC", + doc_name=rfc.name, + doc_rev=rfc.rev, # expected to be None + ) + rfc.ad = PersonFactory(name="Alfred D. Rector") + # Put it in two Subseries docs to be sure this does not break things + # (the typesense schema does not support this for real at the moment) + BcpFactory(contains=[rfc], name="bcp1234") + StdFactory(contains=[rfc], name="std1234") + result = searchindex.typesense_doc_from_rfc(rfc) + # Check a few values, not exhaustive + self.assertEqual( + result["content"], + searchindex._sanitize_text("The contents of this RFC"), + ) + self.assertEqual(result["adName"], "Alfred D. Rector") + self.assertIn("subseries", result) + ss_dict = result["subseries"] + # We should get one of the two subseries docs, but neither is more correct + # than the other... + self.assertTrue( + any( + ss_dict == {"acronym": ss_type, "number": 1234, "total": 1} + for ss_type in ["bcp", "std"] + ) + ) + + # Finally, delete the contents blob and make sure things don't blow up + Blob.objects.get(bucket="rfc", name=f"txt/{rfc.name}.txt").delete() + result = searchindex.typesense_doc_from_rfc(rfc) + self.assertNotIn("content", result) + + def test_typesense_doc_from_rfc_flags_obsoleted(self): + """typesense docs should set correct flags for obsoleted RFC""" + rfc = PublishedRfcDocEventFactory().doc + assert isinstance(rfc, Document) + self.assertEqual(len(rfc.related_that("obs")), 0) + self.assertEqual(len(rfc.related_that("updates")), 0) + self.assertNotEqual(rfc.std_level.slug, "hist") + result = searchindex.typesense_doc_from_rfc(rfc) + self.assertFalse(result["flags"]["hiddenDefault"]) + self.assertFalse(result["flags"]["obsoleted"]) + self.assertFalse(result["flags"]["updated"]) + + RelatedDocument.objects.create( + source=(PublishedRfcDocEventFactory().doc), + target=rfc, + relationship_id="obs", + ) + result = searchindex.typesense_doc_from_rfc(rfc) + self.assertTrue(result["flags"]["hiddenDefault"]) + self.assertTrue(result["flags"]["obsoleted"]) + self.assertFalse(result["flags"]["updated"]) + + def test_typesense_doc_from_rfc_flags_updated(self): + """typesense docs should set flags correctly for updated RFC""" + rfc = PublishedRfcDocEventFactory().doc + assert isinstance(rfc, Document) + self.assertEqual(len(rfc.related_that("obs")), 0) + self.assertEqual(len(rfc.related_that("updates")), 0) + self.assertNotEqual(rfc.std_level.slug, "hist") + result = searchindex.typesense_doc_from_rfc(rfc) + self.assertFalse(result["flags"]["hiddenDefault"]) + self.assertFalse(result["flags"]["obsoleted"]) + self.assertFalse(result["flags"]["updated"]) + + RelatedDocument.objects.create( + source=(PublishedRfcDocEventFactory().doc), + target=rfc, + relationship_id="updates", + ) + result = searchindex.typesense_doc_from_rfc(rfc) + self.assertFalse(result["flags"]["hiddenDefault"]) + self.assertFalse(result["flags"]["obsoleted"]) + self.assertTrue(result["flags"]["updated"]) + + def test_typesense_doc_from_rfc_flags_historic(self): + """typesense docs should set flags correctly for historic RFC""" + rfc = PublishedRfcDocEventFactory(doc__std_level_id="hist").doc + assert isinstance(rfc, Document) + result = searchindex.typesense_doc_from_rfc(rfc) + self.assertTrue(result["flags"]["hiddenDefault"]) + self.assertFalse(result["flags"]["obsoleted"]) + self.assertFalse(result["flags"]["updated"]) + + + @override_settings( + SEARCHINDEX_CONFIG={ + "TYPESENSE_API_URL": "http://ts.example.com", + "TYPESENSE_API_KEY": "test-api-key", + "TYPESENSE_COLLECTION_NAME": "frogs", + } + ) + @mock.patch("ietf.utils.searchindex.typesense_doc_from_rfc") + @mock.patch("ietf.utils.searchindex.typesense.Client") + def test_update_or_create_rfc_entry( + self, mock_ts_client_constructor, mock_tdoc_from_rfc + ): + fake_tdoc = object() + mock_tdoc_from_rfc.return_value = fake_tdoc + rfc = WgRfcFactory() + assert isinstance(rfc, Document) + searchindex.update_or_create_rfc_entry(rfc) + self.assertTrue(mock_ts_client_constructor.called) + # walk the tree down to the method we expected to be called... + mock_upsert = mock_ts_client_constructor.return_value.collections[ + "frogs" # matches value in override_settings above + ].documents.upsert + self.assertTrue(mock_upsert.called) + self.assertEqual(mock_upsert.call_args, mock.call(fake_tdoc)) + + @override_settings( + SEARCHINDEX_CONFIG={ + "TYPESENSE_API_URL": "http://ts.example.com", + "TYPESENSE_API_KEY": "test-api-key", + "TYPESENSE_COLLECTION_NAME": "frogs", + } + ) + @mock.patch("ietf.utils.searchindex.typesense_doc_from_rfc") + @mock.patch("ietf.utils.searchindex.typesense.Client") + def test_update_or_create_rfc_entries( + self, mock_ts_client_constructor, mock_tdoc_from_rfc + ): + fake_tdoc = object() + mock_tdoc_from_rfc.return_value = fake_tdoc + rfc = WgRfcFactory() + assert isinstance(rfc, Document) + searchindex.update_or_create_rfc_entries([rfc] * 50) # list of docs... + self.assertEqual(mock_ts_client_constructor.call_count, 1) + # walk the tree down to the method we expected to be called... + mock_import_ = mock_ts_client_constructor.return_value.collections[ + "frogs" # matches value in override_settings above + ].documents.import_ + self.assertEqual(mock_import_.call_count, 1) + self.assertEqual( + mock_import_.call_args, mock.call([fake_tdoc] * 50, {"action": "upsert"}) + ) + + mock_import_.reset_mock() + searchindex.update_or_create_rfc_entries([rfc] * 50, batchsize=20) + self.assertEqual(mock_ts_client_constructor.call_count, 2) # one more + # walk the tree down to the method we expected to be called... + mock_import_ = mock_ts_client_constructor.return_value.collections[ + "frogs" # matches value in override_settings above + ].documents.import_ + self.assertEqual(mock_import_.call_count, 3) + self.assertEqual( + mock_import_.call_args_list, + [ + mock.call([fake_tdoc] * 20, {"action": "upsert"}), + mock.call([fake_tdoc] * 20, {"action": "upsert"}), + mock.call([fake_tdoc] * 10, {"action": "upsert"}), + ], + ) + + @override_settings( + SEARCHINDEX_CONFIG={ + "TYPESENSE_API_URL": "http://ts.example.com", + "TYPESENSE_API_KEY": "test-api-key", + "TYPESENSE_COLLECTION_NAME": "frogs", + } + ) + @mock.patch("ietf.utils.searchindex.typesense.Client") + def test_create_collection(self, mock_ts_client_constructor): + searchindex.create_collection() + self.assertEqual(mock_ts_client_constructor.call_count, 1) + mock_collections = mock_ts_client_constructor.return_value.collections + self.assertTrue(mock_collections.create.called) + self.assertEqual(mock_collections.create.call_args[0][0]["name"], "frogs") + + @override_settings( + SEARCHINDEX_CONFIG={ + "TYPESENSE_API_URL": "http://ts.example.com", + "TYPESENSE_API_KEY": "test-api-key", + "TYPESENSE_COLLECTION_NAME": "frogs", + } + ) + @mock.patch("ietf.utils.searchindex.typesense.Client") + def test_delete_collection(self, mock_ts_client_constructor): + searchindex.delete_collection() + self.assertEqual(mock_ts_client_constructor.call_count, 1) + mock_collections = mock_ts_client_constructor.return_value.collections + self.assertTrue(mock_collections["frogs"].delete.called) + + mock_collections["frogs"].side_effect = typesense.exceptions.ObjectNotFound + searchindex.delete_collection() # should ignore the exception + + @override_settings( + SEARCHINDEX_CONFIG={ + "TYPESENSE_API_URL": "http://ts.example.com", + "TYPESENSE_API_KEY": "test-api-key", + "TYPESENSE_COLLECTION_NAME": "frogs", + } + ) + def test_upsert_presets(self): + self.requests_mock.put( + "http://ts.example.com/presets/red", text="ok", status_code=201 + ) + self.requests_mock.put( + "http://ts.example.com/presets/red-content", text="ok", status_code=202 + ) + searchindex.upsert_presets() + + self.requests_mock.put( + "http://ts.example.com/presets/red", text="not ok", status_code=400 + ) + with self.assertRaises(requests.exceptions.HTTPError): + searchindex.upsert_presets() + + self.requests_mock.put( + "http://ts.example.com/presets/red", text="ok", status_code=200 + ) + self.requests_mock.put( + "http://ts.example.com/presets/red-content", text="not ok", status_code=400 + ) + with self.assertRaises(requests.exceptions.HTTPError): + searchindex.upsert_presets() diff --git a/ietf/utils/tests_text.py b/ietf/utils/tests_text.py new file mode 100644 index 00000000000..51aa2eff132 --- /dev/null +++ b/ietf/utils/tests_text.py @@ -0,0 +1,71 @@ +# Copyright The IETF Trust 2021-2026, All Rights Reserved +from ietf.utils.test_utils import TestCase +from ietf.utils.text import parse_unicode, decode_document_content + + +class TestDecoders(TestCase): + def test_parse_unicode(self): + names = ( + ("=?utf-8?b?4Yuz4YuK4Ym1IOGJoOGJgOGIiA==?=", "ዳዊት በቀለ"), + ("=?utf-8?b?5Li9IOmDnA==?=", "丽 郜"), + ("=?utf-8?b?4KSV4KSu4KWN4KSs4KWL4KScIOCkoeCkvuCksA==?=", "कम्बोज डार"), + ("=?utf-8?b?zpfPgc6szrrOu861zrnOsSDOm865z4zOvc+Ezrc=?=", "Ηράκλεια Λιόντη"), + ("=?utf-8?b?15nXqdeo15DXnCDXqNeV15bXoNek15zXkw==?=", "ישראל רוזנפלד"), + ("=?utf-8?b?5Li95Y2OIOeahw==?=", "丽华 皇"), + ("=?utf-8?b?77ul77qu766V77qzIO+tlu+7ru+vvu+6ju+7pw==?=", "ﻥﺮﮕﺳ ﭖﻮﯾﺎﻧ"), + ( + "=?utf-8?b?77uh77uu77qz77uu76++IO+6su+7tO+7p++6jSDvurDvu6Pvuo7vu6jvr74=?=", + "ﻡﻮﺳﻮﯾ ﺲﻴﻧﺍ ﺰﻣﺎﻨﯾ", + ), + ( + "=?utf-8?b?ScOxaWdvIFNhbsOnIEliw6HDsWV6IGRlIGxhIFBlw7Fh?=", + "Iñigo Sanç Ibáñez de la Peña", + ), + ("Mart van Oostendorp", "Mart van Oostendorp"), + ("", ""), + ) + for encoded_str, unicode in names: + self.assertEqual(unicode, parse_unicode(encoded_str)) + + def test_decode_document_content(self): + utf8_bytes = "𒀭𒊩𒌆𒄈𒋢".encode("utf-8") # ends with 4-byte character + latin1_bytes = "àéîøü".encode("latin-1") + other_bytes = "àéîøü".encode("macintosh") # different from its latin-1 encoding + assert other_bytes.decode("macintosh") != other_bytes.decode("latin-1"),\ + "test broken: other_bytes must decode differently as latin-1" + + # simplest case + self.assertEqual( + decode_document_content(utf8_bytes), + utf8_bytes.decode(), + ) + # losing 1-4 bytes from the end leave the last character incomplete; the + # decoder should decode all but that last character + self.assertEqual( + decode_document_content(utf8_bytes[:-1]), + utf8_bytes.decode()[:-1], + ) + self.assertEqual( + decode_document_content(utf8_bytes[:-2]), + utf8_bytes.decode()[:-1], + ) + self.assertEqual( + decode_document_content(utf8_bytes[:-3]), + utf8_bytes.decode()[:-1], + ) + self.assertEqual( + decode_document_content(utf8_bytes[:-4]), + utf8_bytes.decode()[:-1], + ) + + # latin-1 is also simple + self.assertEqual( + decode_document_content(latin1_bytes), + latin1_bytes.decode("latin-1"), + ) + + # other character sets are just treated as latin1 (bug? feature? you decide) + self.assertEqual( + decode_document_content(other_bytes), + other_bytes.decode("latin-1"), + ) diff --git a/ietf/utils/text.py b/ietf/utils/text.py index 39989d5e0e0..2763056e1a9 100644 --- a/ietf/utils/text.py +++ b/ietf/utils/text.py @@ -1,17 +1,15 @@ # Copyright The IETF Trust 2016-2020, All Rights Reserved # -*- coding: utf-8 -*- - -import bleach # type: ignore -import copy +import bleach import email import re import textwrap import tlds import unicodedata -from django.core.validators import URLValidator from django.core.exceptions import ValidationError +from django.core.validators import URLValidator from django.utils.functional import keep_lazy from django.utils.safestring import mark_safe @@ -19,56 +17,58 @@ from .texescape import init as texescape_init, tex_escape_map -tlds_sorted = sorted(tlds.tld_set, key=len, reverse=True) -protocols = copy.copy(bleach.sanitizer.ALLOWED_PROTOCOLS) -protocols.append("ftp") # we still have some ftp links -protocols.append("xmpp") # we still have some xmpp links - -tags = set(copy.copy(bleach.sanitizer.ALLOWED_TAGS)).union( - { - # fmt: off - 'a', 'abbr', 'acronym', 'address', 'b', 'big', - 'blockquote', 'body', 'br', 'caption', 'center', 'cite', 'code', 'col', - 'colgroup', 'dd', 'del', 'dfn', 'dir', 'div', 'dl', 'dt', 'em', 'font', - 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'head', 'hr', 'html', 'i', 'ins', 'kbd', - 'li', 'ol', 'p', 'pre', 'q', 's', 'samp', 'small', 'span', 'strike', 'style', - 'strong', 'sub', 'sup', 'table', 'title', 'tbody', 'td', 'tfoot', 'th', 'thead', - 'tr', 'tt', 'u', 'ul', 'var' - # fmt: on - } -) +# Sort in reverse so substrings are considered later - e.g., so ".co" comes after ".com". +tlds_sorted = sorted(tlds.tld_set, reverse=True) -attributes = copy.copy(bleach.sanitizer.ALLOWED_ATTRIBUTES) -attributes["*"] = ["id"] -attributes["ol"] = ["start"] +# Protocols we're interested in auto-linking. See also ietf.utils.html.acceptable_protocols, +# which is protocols we allow people to include explicitly in sanitized html. +linkable_protocols = ["http", "https", "mailto", "ftp", "xmpp"] -bleach_cleaner = bleach.sanitizer.Cleaner( - tags=tags, attributes=attributes, protocols=protocols, strip=True -) -validate_url = URLValidator() +_validate_url = URLValidator() def check_url_validity(attrs, new=False): + """Callback for bleach linkify + + :param attrs: dict of attributes of the tag + :param new: boolean - True if the link is new; False if was found in text + :return: new dict of attributes for the link, or None to block link creation + + Attributes are namespaced, so normally look like `(None, "SomeAttribute")`. + This includes as the keys in the `attrs` argument, so `attrs[(None, "href")]` + would be the value of the href attribute. + """ if (None, "href") not in attrs: - return None + # rfc2html creates a tags without href + return attrs url = attrs[(None, "href")] try: if url.startswith("http"): - validate_url(url) + _validate_url(url) except ValidationError: return None return attrs -bleach_linker = bleach.Linker( +_bleach_linker = bleach.Linker( callbacks=[check_url_validity], - url_re=bleach.linkifier.build_url_re(tlds=tlds_sorted, protocols=protocols), + url_re=bleach.linkifier.build_url_re(tlds=tlds_sorted, protocols=linkable_protocols), email_re=bleach.linkifier.build_email_re(tlds=tlds_sorted), # type: ignore parse_email=True, ) +def linkify(text): + """Convert URL-ish substrings into HTML links + + This does no sanitization whatsoever. Caller must sanitize the input or output as + contextually appropriate. Do not call `mark_safe()` on the output if the input is + user-provided unless it has been sanitized or escaped. + """ + return _bleach_linker.linkify(text) + + @keep_lazy(str) def xslugify(value): """ @@ -111,7 +111,7 @@ def fill(text, width): return "\n\n".join(wrapped) def wordwrap(text, width=80): - """Wraps long lines without loosing the formatting and indentation + """Wraps long lines without losing the formatting and indentation of short lines""" if not isinstance(text, str): return text @@ -248,6 +248,7 @@ def unwrap(s): return s.replace('\n', ' ') def normalize_text(s): + """Normalize various unicode whitespaces to ordinary spaces""" return re.sub(r'[\s\n\r\u2028\u2029]+', ' ', s, flags=re.U).strip() def parse_unicode(text): @@ -262,3 +263,21 @@ def parse_unicode(text): else: text = decoded_string return text + + +def decode_document_content(content: bytes) -> str: + """Decode document contents as utf-8 or latin1 + + Method was developed in DocumentInfo.text() where it gave acceptable results + for existing documents / RFCs. + """ + try: + return content.decode("utf-8") + except UnicodeDecodeError: + pass + for back in range(1, 4): + try: + return content[:-back].decode("utf-8") + except UnicodeDecodeError: + pass + return content.decode("latin-1") # everything is legal in latin-1 diff --git a/ietf/utils/timezone.py b/ietf/utils/timezone.py index 723512efeb6..c0568365eb3 100644 --- a/ietf/utils/timezone.py +++ b/ietf/utils/timezone.py @@ -1,39 +1,106 @@ -import pytz -import email.utils import datetime +import random + +from typing import Union +from zoneinfo import available_timezones, ZoneInfo from django.conf import settings +from django.utils import timezone + + +# Timezone constants - tempting to make these settings, but changing them will +# require code changes. +# +# Default time zone for deadlines / expiration dates. +DEADLINE_TZINFO = ZoneInfo('America/Los_Angeles') + +# Time zone for dates from the RPC. This value is baked into the timestamps on DocEvents +# of type="published_rfc" - see Document.pub_date() and the rfc publication workflow +# for more information about how that works. +RPC_TZINFO = ZoneInfo('America/Los_Angeles') + + +def _tzinfo(tz: Union[str, datetime.tzinfo, None]): + """Helper to convert a tz param into a tzinfo + + Accepts a tzinfo or string containing a timezone name. Defaults to UTC if tz is None. + """ + if tz is None: + return datetime.UTC + elif isinstance(tz, datetime.tzinfo): + return tz + else: + return ZoneInfo(tz) + + +def make_aware(dt, tz): + """Assign timezone to a naive datetime + + Helper to deal with both pytz and zoneinfo type time zones. Can go away when pytz is removed. + """ + tzinfo = _tzinfo(tz) + if hasattr(tzinfo, 'localize'): + return tzinfo.localize(dt) # pytz-style + else: + return dt.replace(tzinfo=tzinfo) # zoneinfo- / datetime.timezone-style + + +def datetime_from_date(date, tz=None): + """Get datetime at midnight on a given date""" + # accept either pytz or zoneinfo tzinfos until we get rid of pytz + return make_aware(datetime.datetime(date.year, date.month, date.day), _tzinfo(tz)) + -def local_timezone_to_utc(d): - """Takes a naive datetime in the local timezone and returns a - naive datetime with the corresponding UTC time.""" - local_timezone = pytz.timezone(settings.TIME_ZONE) +def datetime_today(tz=None): + """Get a timezone-aware datetime representing midnight today - d = local_timezone.localize(d).astimezone(pytz.utc) + By default, uses settings.TIME_ZONE + For use with datetime fields representing a date. + """ + if tz is None: + tz = settings.TIME_ZONE + return timezone.now().astimezone(_tzinfo(tz)).replace(hour=0, minute=0, second=0, microsecond=0) - return d.replace(tzinfo=None) -def utc_to_local_timezone(d): - """Takes a naive datetime UTC and returns a naive datetime in the - local time zone.""" - local_timezone = pytz.timezone(settings.TIME_ZONE) +def date_today(tz=None): + """Get the date corresponding to the current moment - d = local_timezone.normalize(d.replace(tzinfo=pytz.utc).astimezone(local_timezone)) + By default, uses settings.TIME_ZONE + Note that Dates are not themselves timezone aware. + """ + if tz is None: + tz = settings.TIME_ZONE + return timezone.now().astimezone(_tzinfo(tz)).date() - return d.replace(tzinfo=None) -def email_time_to_local_timezone(date_string): - """Takes a time string from an email and returns a naive datetime - in the local time zone.""" +def time_now(tz=None): + """Get the "wall clock" time corresponding to the current moment - t = email.utils.parsedate_tz(date_string) - d = datetime.datetime(*t[:6]) + The value returned by this data is a Time with no tzinfo attached. (Time + objects have only limited timezone support, even if tzinfo is filled in, + and may not behave correctly when daylight savings time shifts are relevant.) + """ + return timezone.now().astimezone(_tzinfo(tz)).time() - if t[7] != None: - d += datetime.timedelta(seconds=t[9]) - return utc_to_local_timezone(d) +def timezone_not_near_midnight(): + """Get the name of a random timezone where it's not close to midnight -def date2datetime(date, tz=pytz.utc): - return datetime.datetime(*(date.timetuple()[:6]), tzinfo=tz) - + Avoids midnight +/- 1 hour. Raises RuntimeError if it is unable to find + a time zone satisfying this constraint. + """ + timezone_options = list( + available_timezones().difference(['Factory', 'localtime']) # these two are not known to pytz + ) + tzname = random.choice(timezone_options) + right_now = timezone.now().astimezone(ZoneInfo(tzname)) + # Avoid the remote possibility of an infinite loop (might come up + # if there is a problem with the time zone library) + tries_left = 50 + while right_now.hour < 1 or right_now.hour >= 23: + tzname = random.choice(timezone_options) + right_now = right_now.astimezone(ZoneInfo(tzname)) + tries_left -= 1 + if tries_left <= 0: + raise RuntimeError('Unable to find a time zone not near midnight') + return tzname diff --git a/ietf/utils/unicodenormalize.py b/ietf/utils/unicodenormalize.py new file mode 100644 index 00000000000..8644dbdb79f --- /dev/null +++ b/ietf/utils/unicodenormalize.py @@ -0,0 +1,9 @@ +# Copyright The IETF Trust 2025, All Rights Reserved +import unicodedata + +def normalize_for_sorting(text): + """Normalize text for proper accent-aware sorting.""" + # Normalize the text to NFD (decomposed form) + decomposed = unicodedata.normalize('NFD', text) + # Filter out combining diacritical marks + return ''.join(char for char in decomposed if not unicodedata.combining(char)) diff --git a/ietf/utils/urls.py b/ietf/utils/urls.py index 7f46d9c4316..6abda9b9732 100644 --- a/ietf/utils/urls.py +++ b/ietf/utils/urls.py @@ -6,12 +6,14 @@ from inspect import isclass -from django.conf.urls import url as django_url -from django.views.generic import View +from django.urls import re_path from django.utils.encoding import force_str +from django.views.generic import View def url(regex, view, kwargs=None, name=None): - if callable(view) and hasattr(view, '__name__'): + if hasattr(view, "view_class"): + view_name = "%s.%s" % (view.__module__, view.view_class.__name__) + elif callable(view) and hasattr(view, '__name__'): view_name = "%s.%s" % (view.__module__, view.__name__) else: view_name = regex @@ -42,5 +44,5 @@ def url(regex, view, kwargs=None, name=None): #debug.show('branch') #debug.show('name') pass - return django_url(regex, view, kwargs=kwargs, name=name) + return re_path(regex, view, kwargs=kwargs, name=name) diff --git a/ietf/utils/validators.py b/ietf/utils/validators.py index 7b599b74369..a99de72724e 100644 --- a/ietf/utils/validators.py +++ b/ietf/utils/validators.py @@ -4,6 +4,8 @@ import os import re +from email.utils import parseaddr + from pyquery import PyQuery from urllib.parse import urlparse, urlsplit, urlunsplit @@ -11,10 +13,17 @@ from django.apps import apps from django.conf import settings from django.core.exceptions import ObjectDoesNotExist, ValidationError -from django.core.validators import RegexValidator, URLValidator, EmailValidator, _lazy_re_compile, BaseValidator +from django.core.validators import ( + RegexValidator, + URLValidator, + BaseValidator, + validate_email, + ProhibitNullCharactersValidator, +) from django.template.defaultfilters import filesizeformat from django.utils.deconstruct import deconstructible from django.utils.ipv6 import is_valid_ipv6_address +from django.utils.regex_helper import _lazy_re_compile # type: ignore from django.utils.translation import gettext_lazy as _ import debug # pyflakes:ignore @@ -24,8 +33,9 @@ # Note that this is an instantiation of the regex validator, _not_ the # regex-string validator defined right below validate_no_control_chars = RegexValidator( - regex="^[^\x00-\x1f]*$", - message="Please enter a string without control characters." ) + regex="^[^\x01-\x1f]*$", + message="Please enter a string without control characters.", +) @deconstructible @@ -59,6 +69,7 @@ def __ne__(self, other): validate_regular_expression_string = RegexStringValidator() + def validate_file_size(file, missing_ok=False): try: size = file.size @@ -68,12 +79,18 @@ def validate_file_size(file, missing_ok=False): else: raise - if size > settings.SECR_MAX_UPLOAD_SIZE: - raise ValidationError('Please keep filesize under %s. Requested upload size was %s' % (filesizeformat(settings.SECR_MAX_UPLOAD_SIZE), filesizeformat(file.size))) + if size > settings.DATATRACKER_MAX_UPLOAD_SIZE: + raise ValidationError( + "Please keep filesize under {}. Requested upload size was {}".format( + filesizeformat(settings.DATATRACKER_MAX_UPLOAD_SIZE), + filesizeformat(file.size) + ) + ) + def validate_mime_type(file, valid, missing_ok=False): try: - file.open() + file.open() # Callers expect this to remain open. Consider refactoring. except FileNotFoundError: if missing_ok: return None, None @@ -128,8 +145,17 @@ def validate_no_html_frame(file): # instantiations of sub-validiators used by the external_resource validator validate_url = URLValidator() -validate_http_url = URLValidator(schemes=['http','https']) -validate_email = EmailValidator() +validate_http_url = URLValidator(schemes=["http", "https"]) +validate_no_nulls = ProhibitNullCharactersValidator() + + +def validate_mailbox_address(s): + """Validate an RFC 5322 'mailbox' (e.g., "Some Person" )""" + # parseaddr() returns ("", "") on err; validate_email() will reject that for us + name, addr = parseaddr(s) + validate_no_nulls(name) # could be stricter... + validate_email(addr) + def validate_ipv6_address(value): if not is_valid_ipv6_address(value): diff --git a/ietf/utils/xmldraft.py b/ietf/utils/xmldraft.py index 8b637292d7c..325b8499a96 100644 --- a/ietf/utils/xmldraft.py +++ b/ietf/utils/xmldraft.py @@ -1,20 +1,39 @@ -# Copyright The IETF Trust 2022, All Rights Reserved +# Copyright The IETF Trust 2022-2025, All Rights Reserved # -*- coding: utf-8 -*- -import os +import datetime +import io +import re import xml2rfc import debug # pyflakes: ignore -from contextlib import ExitStack +from contextlib import contextmanager +from lxml.etree import XMLSyntaxError +from xml2rfc.util.date import augment_date, extract_date +from ietf.utils.timezone import date_today from .draft import Draft +@contextmanager +def capture_xml2rfc_output(): + orig_write_out = xml2rfc.log.write_out + orig_write_err = xml2rfc.log.write_err + parser_out = io.StringIO() + parser_err = io.StringIO() + xml2rfc.log.write_out = parser_out + xml2rfc.log.write_err = parser_err + try: + yield {"stdout": parser_out, "stderr": parser_err} + finally: + xml2rfc.log.write_out = orig_write_out + xml2rfc.log.write_err = orig_write_err + + class XMLDraft(Draft): """Draft from XML source - Currently just a holding place for get_refs() for an XML file. Can eventually expand - to implement the other public methods of Draft as need arises. + Not all methods from the superclass are implemented yet. """ def __init__(self, xml_file): """Initialize XMLDraft instance @@ -23,42 +42,89 @@ def __init__(self, xml_file): """ super().__init__() # cast xml_file to str so, e.g., this will work with a Path - self.xmltree = self.parse_xml(str(xml_file)) + self.xmltree, self.xml_version = self.parse_xml(str(xml_file)) self.xmlroot = self.xmltree.getroot() + self.filename, self.revision = self.parse_docname(self.xmlroot) @staticmethod def parse_xml(filename): - orig_write_out = xml2rfc.log.write_out - orig_write_err = xml2rfc.log.write_err - tree = None - with ExitStack() as stack: - @stack.callback - def cleanup(): # called when context exited, even if there's an exception - xml2rfc.log.write_out = orig_write_out - xml2rfc.log.write_err = orig_write_err - - xml2rfc.log.write_out = open(os.devnull, 'w') - xml2rfc.log.write_err = open(os.devnull, 'w') + """Parse XML draft + Converts to xml2rfc v3 schema, then returns the root of the v3 tree and the original + xml version. + """ + + with capture_xml2rfc_output() as parser_logs: parser = xml2rfc.XmlRfcParser(filename, quiet=True) - tree = parser.parse() + try: + tree = parser.parse() + except XMLSyntaxError: + raise InvalidXMLError() + except Exception as e: + raise XMLParseError( + parser_logs["stdout"].getvalue(), + parser_logs["stderr"].getvalue(), + ) from e + xml_version = tree.getroot().get('version', '2') if xml_version == '2': v2v3 = xml2rfc.V2v3XmlWriter(tree) tree.tree = v2v3.convert2to3() - return tree + return tree, xml_version - def _document_name(self, anchor): - """Guess document name from reference anchor + def _document_name(self, ref): + """Get document name from reference.""" + series = ["rfc", "bcp", "fyi", "std"] + # handle xinclude first + # FIXME: this assumes the xinclude is a bibxml href; if it isn't, there can + # still be false negatives. it would be better to expand the xinclude and parse + # its seriesInfo. + if ref.tag.endswith("}include"): + name = re.search( + rf"reference\.({'|'.join(series).upper()})\.(\d{{4}})\.xml", + ref.attrib["href"], + ) + if name: + return f"{name.group(1)}{int(name.group(2))}".lower() + name = re.search( + r"reference\.I-D\.(?:draft-)?(.*)\.xml", ref.attrib["href"] + ) + if name: + return f"draft-{name.group(1)}" + # can't extract the name, give up + return "" - Looks for series numbers and removes leading 0s from the number. - """ - anchor = anchor.lower() # always give back lowercase - label = anchor.rstrip('0123456789') # remove trailing digits - if label in ['rfc', 'bcp', 'fyi', 'std']: - number = int(anchor[len(label):]) - return f'{label}{number}' - return anchor + # check the anchor next + anchor = ref.get("anchor").lower() # always give back lowercase + label = anchor.rstrip("0123456789") # remove trailing digits + maybe_number = anchor[len(label) :] + if label in series and maybe_number.isdigit(): + number = int(maybe_number) + return f"{label}{number}" + + target = ref.get("target") + if isinstance(target, str): + target = target.lower() + if target.startswith("https://datatracker.ietf.org/doc/"): + # len("https://datatracker.ietf.org/doc/")==33 + m = re.match(r"^(draft-[a-z0-9-]*[a-z0-9])([/-]\d{2})?/?$",target[33:]) + if m: + name = m.group(1) + return name + + + # if we couldn't find a match so far, try the seriesInfo + series_query = " or ".join(f"@name='{x.upper()}'" for x in series) + for info in ref.xpath( + f"./seriesInfo[{series_query} or @name='Internet-Draft']" + ): + if not info.attrib["value"]: + continue + if info.attrib["name"] == "Internet-Draft": + return info.attrib["value"] + else: + return f'{info.attrib["name"].lower()}{info.attrib["value"]}' + return "" def _reference_section_type(self, section_name): """Determine reference type from name of references section""" @@ -76,12 +142,191 @@ def _reference_section_name(self, section_elt): section_name = section_elt.get('title') # fall back to title if we have it return section_name + @staticmethod + def parse_docname(xmlroot): + docname = xmlroot.attrib.get('docName') + if docname is None: + raise ValueError("Missing docName attribute in the XML root element") + revmatch = re.match( + r'^(?P.+?)(?:-(?P[0-9][0-9]))?$', + docname, + + ) + if revmatch is None: + raise ValueError('Unable to parse docName') + # If a group had no match it is None + return revmatch.group('filename'), revmatch.group('rev') + + def get_title(self): + title_text = self.xmlroot.findtext('front/title') + return "" if title_text is None else title_text.strip() + + @staticmethod + def parse_creation_date(date_elt): + if date_elt is None: + return None + + today = date_today() + + # Outright reject non-numeric year / day (xml2rfc's extract_date does not do this) + # (n.b., "year" can be non-numeric in a section per RFC 7991) + year = date_elt.get("year") + day = date_elt.get("day") + non_numeric_year = year and not year.isdigit() + non_numeric_day = day and not day.isdigit() + if non_numeric_day or non_numeric_year: + raise InvalidMetadataError( + "Unable to parse the element in the section: " + "year and day must be numeric values if specified." + ) + + try: + # ths mimics handling of date elements in the xml2rfc text/html writers + year, month, day = extract_date(date_elt, today) + year, month, day = augment_date(year, month, day, today) + except Exception as err: + # Give a generic error if anything goes wrong so far... + raise InvalidMetadataError( + "Unable to parse the element in the section." + ) from err + + if not day: + # Must choose a day for a datetime.date. Per RFC 7991 sect 2.17, we use + # today's date if it is consistent with the rest of the date. Otherwise, + # arbitrariy (and consistent with the text parser) assume the 15th. + if year == today.year and month == today.month: + day = today.day + else: + day = 15 + + try: + creation_date = datetime.date(year, month, day) + except Exception: + # If everything went well, we should have had a valid datetime, but we didn't. + # The parsing _worked_ but not in a way that we can go forward with. + raise InvalidMetadataError( + "The element in the section specified an incomplete date " + "that was not consistent with today's date. If you specify only a year, " + "it must be the four-digit current year. To use today's date, omit the " + "date tag or use ." + ) + return creation_date + + def get_creation_date(self): + return self.parse_creation_date(self.xmlroot.find("front/date")) + + # todo fix the implementation of XMLDraft.get_abstract() + # + # This code was pulled from ietf.submit.forms where it existed for some time. + # It does not work, at least with modern xml2rfc. This assumes that the abstract + # is simply text in the front/abstract node, but the XML schema wraps the actual + # abstract text in elements (and allows
    ,
      , and
        as well). As a + # result, this method normally returns an empty string, which is later replaced by + # the abstract parsed from the rendered text. For now, I a commenting this out + # and making it explicit that the abstract always comes from the text format. + # + # def get_abstract(self): + # """Extract the abstract""" + # abstract = self.xmlroot.findtext('front/abstract') + # return abstract.strip() if abstract else '' + + @staticmethod + def render_author_name(author_elt): + """Get a displayable name for an author, if possible + + Based on TextWriter.render_author_name() from xml2rfc. If fullname is present, uses that. + If not, uses either initials + surname or just surname. Finally, returns None because this + author is evidently an organization, not a person. + + Does not involve ascii* attributes because rfc7991 requires fullname if any of those are + present. + """ + # Use fullname attribute, if present + fullname = author_elt.attrib.get("fullname", "").strip() + if fullname: + # If any 8bit chars in the fullname, try to append the author's + # name in ascii. + if any([x >= 0x80 for x in fullname.encode('utf8')]): + asciifullname = author_elt.attrib.get("asciiFullname", "").strip() + if asciifullname: + fullname = fullname + ' (' + asciifullname + ')' + return fullname + surname = author_elt.attrib.get("surname", "").strip() + initials = author_elt.attrib.get("initials", "").strip() + if surname or initials: + # This allows the possibility that only initials are used, which is a bit nonsensical + # but seems to be technically allowed by RFC 7991. + return f"{initials} {surname}".strip() + return None + + def get_author_list(self): + """Get detailed author list + + Returns a list of dicts with the following keys: + name, first_name, middle_initial, last_name, + name_suffix, email, country, affiliation + Values will be None if not available + """ + result = [] + empty_author = { + k: None for k in [ + 'name', 'first_name', 'middle_initial', 'last_name', + 'name_suffix', 'email', 'country', 'affiliation', + ] + } + + for author in self.xmlroot.findall('front/author'): + info = { + 'name': self.render_author_name(author), + 'email': author.findtext('address/email'), + 'affiliation': author.findtext('organization'), + } + elem = author.find('address/postal/country') + if elem is not None: + ascii_country = elem.get('ascii', None) + info['country'] = ascii_country if ascii_country else elem.text + for item in info: + if info[item]: + info[item] = info[item].strip() + result.append(empty_author | info) # merge, preferring info + return result + def get_refs(self): """Extract references from the draft""" refs = {} # accept nested sections - for section in self.xmlroot.findall('back//references'): - ref_type = self._reference_section_type(self._reference_section_name(section)) - for ref in (section.findall('./reference') + section.findall('./referencegroup')): - refs[self._document_name(ref.get('anchor'))] = ref_type + for section in self.xmlroot.findall("back//references"): + ref_type = self._reference_section_type( + self._reference_section_name(section) + ) + for ref in ( + section.findall("./reference") + + section.findall("./referencegroup") + + section.findall( + "./xi:include", {"xi": "http://www.w3.org/2001/XInclude"} + ) + ): + name = self._document_name(ref) + if name: + refs[name] = ref_type return refs + + +class XMLParseError(Exception): + """An error occurred while parsing""" + def __init__(self, out: str, err: str, *args): + super().__init__(*args) + self._out = out + self._err = err + + def parser_msgs(self): + return self._out.splitlines() + self._err.splitlines() + + +class InvalidXMLError(Exception): + """File is not valid XML""" + pass + + +class InvalidMetadataError(Exception): + """XML is well-formed but has invalid metadata""" diff --git a/ietf/wsgi.py b/ietf/wsgi.py index c43334874b3..bd17da5ba0d 100644 --- a/ietf/wsgi.py +++ b/ietf/wsgi.py @@ -1,23 +1,17 @@ -# Copyright The IETF Trust 2013-2021, All Rights Reserved +# Copyright The IETF Trust 2013-2024, All Rights Reserved # -*- coding: utf-8 -*- - import os import sys -import syslog path = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) -syslog.openlog(str("datatracker"), syslog.LOG_PID, syslog.LOG_USER) - if not path in sys.path: sys.path.insert(0, path) os.environ.setdefault("DJANGO_SETTINGS_MODULE", "ietf.settings") -syslog.syslog("Starting datatracker wsgi instance") - from django.core.wsgi import get_wsgi_application -application = get_wsgi_application() +application = get_wsgi_application() diff --git a/jsconfig.json b/jsconfig.json new file mode 100644 index 00000000000..9a7ad675646 --- /dev/null +++ b/jsconfig.json @@ -0,0 +1,20 @@ +{ + "compilerOptions": { + "target": "ES6", + }, + "exclude": [ + "node_modules", + ".yarn", + ".vite" + ], + "include": [ + "client/**/*", + "playwright/**/*" + ], + "vueCompilerOptions": { + "target": 3, + "plugins": [ + "@vue/language-plugin-pug" + ] + } +} diff --git a/k8s/README.md b/k8s/README.md new file mode 100644 index 00000000000..3966101ab80 --- /dev/null +++ b/k8s/README.md @@ -0,0 +1,5 @@ +# Kustomize deployment + +## Run locally + +The `secrets.yaml` file is provided as a reference only and must be referenced manually in the `kustomization.yaml` file. \ No newline at end of file diff --git a/k8s/auth.yaml b/k8s/auth.yaml new file mode 100644 index 00000000000..ef8c259933b --- /dev/null +++ b/k8s/auth.yaml @@ -0,0 +1,156 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: auth +spec: + replicas: 1 + revisionHistoryLimit: 2 + selector: + matchLabels: + app: auth + template: + metadata: + labels: + app: auth + spec: + securityContext: + runAsNonRoot: true + containers: + # ----------------------------------------------------- + # Auth Container + # ----------------------------------------------------- + - name: auth + image: "ghcr.io/ietf-tools/datatracker:$APP_IMAGE_TAG" + imagePullPolicy: Always + volumeMounts: + - name: dt-vol + mountPath: /a + - name: dt-tmp + mountPath: /tmp + - name: dt-home + mountPath: /home/datatracker + - name: dt-xml2rfc-cache + mountPath: /var/cache/xml2rfc + - name: dt-cfg + mountPath: /workspace/ietf/settings_local.py + subPath: settings_local.py + env: + - name: "CONTAINER_ROLE" + value: "datatracker" + # ensures the pod gets recreated on every deploy: + - name: "DEPLOY_UID" + value: "$DEPLOY_UID" + envFrom: + - secretRef: + name: dt-secrets-env + startupProbe: + httpGet: + port: 8000 + path: /health/ + initialDelaySeconds: 10 + periodSeconds: 5 + failureThreshold: 30 + timeoutSeconds: 3 + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + runAsUser: 1000 + runAsGroup: 1000 + resources: + requests: + cpu: 250m + memory: 4Gi + # ----------------------------------------------------- + # Nginx Container + # ----------------------------------------------------- + - name: nginx + image: "ghcr.io/nginx/nginx-unprivileged:1.30" + imagePullPolicy: IfNotPresent + ports: + - containerPort: 8080 + name: http + protocol: TCP + livenessProbe: + httpGet: + port: 8080 + path: /health/nginx + securityContext: + readOnlyRootFilesystem: true + volumeMounts: + - name: nginx-tmp + mountPath: /tmp + - name: dt-cfg + mountPath: /etc/nginx/conf.d/00logging.conf + subPath: nginx-logging.conf + - name: dt-cfg + mountPath: /etc/nginx/conf.d/default.conf + subPath: nginx-auth.conf + resources: + requests: + cpu: 10m + memory: 10Mi + # ----------------------------------------------------- + # ScoutAPM Container + # ----------------------------------------------------- + - name: scoutapm + image: "scoutapp/scoutapm:version-1.4.0" + imagePullPolicy: IfNotPresent + # Replace command with one that will shut down on a TERM signal + # The ./core-agent start command line is from the scoutapm docker image + command: + - "sh" + - "-c" + - >- + trap './core-agent shutdown --tcp 0.0.0.0:6590' TERM; + ./core-agent start --daemonize false --log-level debug --tcp 0.0.0.0:6590 & + wait $! + livenessProbe: + exec: + command: + - "sh" + - "-c" + - "./core-agent probe --tcp 0.0.0.0:6590 | grep -q 'Agent found'" + securityContext: + readOnlyRootFilesystem: true + runAsUser: 65534 # "nobody" user by default + runAsGroup: 65534 # "nogroup" group by default + resources: + requests: + cpu: 10m + memory: 50Mi + volumes: + # To be overriden with the actual shared volume + - name: dt-vol + - name: dt-tmp + emptyDir: + sizeLimit: "2Gi" + - name: dt-xml2rfc-cache + emptyDir: + sizeLimit: "2Gi" + - name: dt-home + emptyDir: + sizeLimit: "2Gi" + - name: dt-cfg + configMap: + name: files-cfgmap + - name: nginx-tmp + emptyDir: + sizeLimit: "500Mi" + terminationGracePeriodSeconds: 60 +--- +apiVersion: v1 +kind: Service +metadata: + name: auth +spec: + type: ClusterIP + ports: + - port: 80 + targetPort: http + protocol: TCP + name: http + selector: + app: auth diff --git a/k8s/beat.yaml b/k8s/beat.yaml new file mode 100644 index 00000000000..cc171fb7d1c --- /dev/null +++ b/k8s/beat.yaml @@ -0,0 +1,66 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: beat + labels: + deleteBeforeUpgrade: yes +spec: + replicas: 1 + revisionHistoryLimit: 2 + selector: + matchLabels: + app: beat + strategy: + type: Recreate + template: + metadata: + labels: + app: beat + spec: + securityContext: + runAsNonRoot: true + containers: + # ----------------------------------------------------- + # Beat Container + # ----------------------------------------------------- + - name: beat + image: "ghcr.io/ietf-tools/datatracker:$APP_IMAGE_TAG" + imagePullPolicy: Always + volumeMounts: + - name: dt-vol + mountPath: /a + - name: dt-tmp + mountPath: /tmp + - name: dt-cfg + mountPath: /workspace/ietf/settings_local.py + subPath: settings_local.py + env: + - name: "CONTAINER_ROLE" + value: "beat" + envFrom: + - secretRef: + name: dt-secrets-env + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + runAsUser: 1000 + runAsGroup: 1000 + resources: + requests: + cpu: 100m + memory: 250Mi + volumes: + # To be overridden with the actual shared volume + - name: dt-vol + - name: dt-tmp + emptyDir: + sizeLimit: "2Gi" + - name: dt-cfg + configMap: + name: files-cfgmap + dnsPolicy: ClusterFirst + restartPolicy: Always + terminationGracePeriodSeconds: 10 diff --git a/k8s/celery.yaml b/k8s/celery.yaml new file mode 100644 index 00000000000..f6cea2acc7a --- /dev/null +++ b/k8s/celery.yaml @@ -0,0 +1,105 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: celery + labels: + deleteBeforeUpgrade: yes +spec: + replicas: 1 + revisionHistoryLimit: 2 + selector: + matchLabels: + app: celery + strategy: + type: Recreate + template: + metadata: + labels: + app: celery + spec: + securityContext: + runAsNonRoot: true + containers: + # ----------------------------------------------------- + # Celery Container + # ----------------------------------------------------- + - name: celery + image: "ghcr.io/ietf-tools/datatracker:$APP_IMAGE_TAG" + imagePullPolicy: Always + volumeMounts: + - name: dt-vol + mountPath: /a + - name: dt-tmp + mountPath: /tmp + - name: dt-home + mountPath: /home/datatracker + - name: dt-xml2rfc-cache + mountPath: /var/cache/xml2rfc + - name: dt-cfg + mountPath: /workspace/ietf/settings_local.py + subPath: settings_local.py + env: + - name: "CONTAINER_ROLE" + value: "celery" + envFrom: + - secretRef: + name: dt-secrets-env + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + runAsUser: 1000 + runAsGroup: 1000 + resources: + requests: + cpu: 100m + memory: 1Gi + # ----------------------------------------------------- + # ScoutAPM Container + # ----------------------------------------------------- + - name: scoutapm + image: "scoutapp/scoutapm:version-1.4.0" + imagePullPolicy: IfNotPresent + # Replace command with one that will shut down on a TERM signal + # The ./core-agent start command line is from the scoutapm docker image + command: + - "sh" + - "-c" + - >- + trap './core-agent shutdown --tcp 0.0.0.0:6590' TERM; + ./core-agent start --daemonize false --log-level debug --tcp 0.0.0.0:6590 & + wait $! + livenessProbe: + exec: + command: + - "sh" + - "-c" + - "./core-agent probe --tcp 0.0.0.0:6590 | grep -q 'Agent found'" + securityContext: + readOnlyRootFilesystem: true + runAsUser: 65534 # "nobody" user by default + runAsGroup: 65534 # "nogroup" group by default + resources: + requests: + cpu: 10m + memory: 50Mi + volumes: + # To be overridden with the actual shared volume + - name: dt-vol + - name: dt-tmp + emptyDir: + sizeLimit: "2Gi" + - name: dt-xml2rfc-cache + emptyDir: + sizeLimit: "2Gi" + - name: dt-home + emptyDir: + sizeLimit: "2Gi" + - name: dt-cfg + configMap: + name: files-cfgmap + dnsPolicy: ClusterFirst + restartPolicy: Always + terminationGracePeriodSeconds: 600 diff --git a/k8s/datatracker.yaml b/k8s/datatracker.yaml new file mode 100644 index 00000000000..2a96ab63bce --- /dev/null +++ b/k8s/datatracker.yaml @@ -0,0 +1,187 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: datatracker +spec: + replicas: 2 + revisionHistoryLimit: 2 + selector: + matchLabels: + app: datatracker + template: + metadata: + labels: + app: datatracker + spec: + securityContext: + runAsNonRoot: true + containers: + # ----------------------------------------------------- + # Datatracker Container + # ----------------------------------------------------- + - name: datatracker + image: "ghcr.io/ietf-tools/datatracker:$APP_IMAGE_TAG" + imagePullPolicy: Always + volumeMounts: + - name: dt-vol + mountPath: /a + - name: dt-tmp + mountPath: /tmp + - name: dt-home + mountPath: /home/datatracker + - name: dt-xml2rfc-cache + mountPath: /var/cache/xml2rfc + - name: dt-cfg + mountPath: /workspace/ietf/settings_local.py + subPath: settings_local.py + env: + - name: "CONTAINER_ROLE" + value: "datatracker" + # ensures the pod gets recreated on every deploy: + - name: "DEPLOY_UID" + value: "$DEPLOY_UID" + envFrom: + - secretRef: + name: dt-secrets-env + startupProbe: + httpGet: + port: 8000 + path: /health/ + initialDelaySeconds: 10 + periodSeconds: 5 + failureThreshold: 30 + timeoutSeconds: 3 + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + runAsUser: 1000 + runAsGroup: 1000 + resources: + requests: + cpu: 250m + memory: 4Gi + # ----------------------------------------------------- + # Nginx Container + # ----------------------------------------------------- + - name: nginx + image: "ghcr.io/nginx/nginx-unprivileged:1.30" + imagePullPolicy: IfNotPresent + ports: + - containerPort: 8080 + name: http + protocol: TCP + livenessProbe: + httpGet: + port: 8080 + path: /health/nginx + securityContext: + readOnlyRootFilesystem: true + volumeMounts: + - name: nginx-tmp + mountPath: /tmp + - name: dt-cfg + mountPath: /etc/nginx/conf.d/00logging.conf + subPath: nginx-logging.conf + - name: dt-cfg + # Replaces the original default.conf + mountPath: /etc/nginx/conf.d/default.conf + subPath: nginx-datatracker.conf + resources: + requests: + cpu: 10m + memory: 10Mi + # ----------------------------------------------------- + # ScoutAPM Container + # ----------------------------------------------------- + - name: scoutapm + image: "scoutapp/scoutapm:version-1.4.0" + imagePullPolicy: IfNotPresent + # Replace command with one that will shut down on a TERM signal + # The ./core-agent start command line is from the scoutapm docker image + command: + - "sh" + - "-c" + - >- + trap './core-agent shutdown --tcp 0.0.0.0:6590' TERM; + ./core-agent start --daemonize false --log-level debug --tcp 0.0.0.0:6590 & + wait $! + livenessProbe: + exec: + command: + - "sh" + - "-c" + - "./core-agent probe --tcp 0.0.0.0:6590 | grep -q 'Agent found'" + securityContext: + readOnlyRootFilesystem: true + runAsUser: 65534 # "nobody" user by default + runAsGroup: 65534 # "nogroup" group by default + resources: + requests: + cpu: 10m + memory: 50Mi + initContainers: + - name: migration + image: "ghcr.io/ietf-tools/datatracker:$APP_IMAGE_TAG" + imagePullPolicy: Always + env: + - name: "CONTAINER_ROLE" + value: "migrations" + envFrom: + - secretRef: + name: dt-secrets-env + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + runAsUser: 1000 + runAsGroup: 1000 + volumeMounts: + - name: dt-vol + mountPath: /a + - name: dt-tmp + mountPath: /tmp + - name: dt-home + mountPath: /home/datatracker + - name: dt-xml2rfc-cache + mountPath: /var/cache/xml2rfc + - name: dt-cfg + mountPath: /workspace/ietf/settings_local.py + subPath: settings_local.py + volumes: + # To be overriden with the actual shared volume + - name: dt-vol + - name: dt-tmp + emptyDir: + sizeLimit: "2Gi" + - name: dt-xml2rfc-cache + emptyDir: + sizeLimit: "2Gi" + - name: dt-home + emptyDir: + sizeLimit: "2Gi" + - name: dt-cfg + configMap: + name: files-cfgmap + - name: nginx-tmp + emptyDir: + sizeLimit: "500Mi" + terminationGracePeriodSeconds: 60 +--- +apiVersion: v1 +kind: Service +metadata: + name: datatracker +spec: + type: ClusterIP + ports: + - port: 80 + targetPort: http + protocol: TCP + name: http + selector: + app: datatracker diff --git a/k8s/kustomization.yaml b/k8s/kustomization.yaml new file mode 100644 index 00000000000..769cb03517e --- /dev/null +++ b/k8s/kustomization.yaml @@ -0,0 +1,17 @@ +namespace: datatracker +namePrefix: dt- +configMapGenerator: + - name: files-cfgmap + files: + - nginx-logging.conf + - nginx-auth.conf + - nginx-datatracker.conf + - settings_local.py +resources: + - auth.yaml + - beat.yaml + - celery.yaml + - datatracker.yaml + - memcached.yaml + - rabbitmq.yaml + - replicator.yaml diff --git a/k8s/memcached.yaml b/k8s/memcached.yaml new file mode 100644 index 00000000000..68b732d7459 --- /dev/null +++ b/k8s/memcached.yaml @@ -0,0 +1,88 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: memcached +spec: + replicas: 1 + revisionHistoryLimit: 2 + selector: + matchLabels: + app: memcached + template: + metadata: + labels: + app: memcached + spec: + securityContext: + runAsNonRoot: true + containers: + # ----------------------------------------------------- + # Memcached + # ----------------------------------------------------- + - image: "memcached:1.6-alpine" + imagePullPolicy: IfNotPresent + args: ["-m", "1024"] + name: memcached + ports: + - name: memcached + containerPort: 11211 + protocol: TCP + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + # memcached image sets up uid/gid 11211 + runAsUser: 11211 + runAsGroup: 11211 + resources: + requests: + cpu: 100m + memory: 100Mi + # ----------------------------------------------------- + # Memcached Exporter for Prometheus + # ----------------------------------------------------- + - image: "quay.io/prometheus/memcached-exporter:v0.14.3" + imagePullPolicy: IfNotPresent + name: memcached-exporter + ports: + - name: metrics + containerPort: 9150 + protocol: TCP + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + runAsUser: 65534 # nobody + runAsGroup: 65534 # nobody + resources: + requests: + cpu: 10m + memory: 20Mi + dnsPolicy: ClusterFirst + restartPolicy: Always + terminationGracePeriodSeconds: 30 +--- +apiVersion: v1 +kind: Service +metadata: + name: memcached + annotations: + k8s.grafana.com/scrape: "true" # this is not a bool + k8s.grafana.com/metrics.portName: "metrics" +spec: + type: ClusterIP + ports: + - port: 11211 + targetPort: memcached + protocol: TCP + name: memcached + - port: 9150 + targetPort: metrics + protocol: TCP + name: metrics + selector: + app: memcached diff --git a/k8s/nginx-auth.conf b/k8s/nginx-auth.conf new file mode 100644 index 00000000000..cdb5c665e22 --- /dev/null +++ b/k8s/nginx-auth.conf @@ -0,0 +1,47 @@ +upstream datatracker_backend { + server 127.0.0.1:8000; + keepalive 0; # default = 32 since nginx 1.29.7 +} + +server { + listen 8080 default_server; + server_name _; + + # Replace default "main" formatter with the ietfjson formatter from nginx-logging.conf + access_log /var/log/nginx/access.log ietfjson; + + # Note that regex location matches take priority over non-regex "prefix" matches. Use regexes so that + # our deny all rule does not squelch the other locations. + location ~ ^/health/nginx$ { + access_log off; + return 200; + } + + location ~ ^/robots.txt$ { + add_header Content-Type text/plain; + return 200 "User-agent: *\nDisallow: /\n"; + } + + location ~ ^/accounts/create.* { + return 302 https://datatracker.ietf.org/accounts/create; + } + + # n.b. (?!...) is a negative lookahead group + location ~ ^(/(?!(api/openid/|accounts/login/|accounts/logout/|accounts/reset/|person/.*/photo|group/groupmenu.json)).*) { + return 302 https://datatracker.ietf.org$${keepempty}request_uri; + } + + location / { + add_header Content-Security-Policy "default-src 'self' 'unsafe-inline' data: https://datatracker.ietf.org/ https://www.ietf.org/ http://ietf.org/ https://analytics.ietf.org https://static.ietf.org; frame-ancestors 'self' ietf.org *.ietf.org meetecho.com *.meetecho.com gather.town *.gather.town"; + proxy_set_header Host $${keepempty}host; + proxy_set_header Connection close; + proxy_set_header X-Request-Start "t=$${keepempty}msec"; + proxy_set_header X-Forwarded-For $${keepempty}proxy_add_x_forwarded_for; + proxy_hide_header X-Datatracker-Is-Authenticated; # hide this from the outside world + proxy_pass http://datatracker_backend; + # Set timeouts longer than Cloudflare proxy limits + proxy_connect_timeout 60; # nginx default (Cf = 15) + proxy_read_timeout 120; # nginx default = 60 (Cf = 100) + proxy_send_timeout 60; # nginx default = 60 (Cf = 30) + } +} diff --git a/k8s/nginx-datatracker.conf b/k8s/nginx-datatracker.conf new file mode 100644 index 00000000000..77ce902b17a --- /dev/null +++ b/k8s/nginx-datatracker.conf @@ -0,0 +1,37 @@ +upstream datatracker_backend { + server 127.0.0.1:8000; + keepalive 0; # default = 32 since nginx 1.29.7 +} + +server { + listen 8080 default_server; + server_name _; + + # Replace default "main" formatter with the ietfjson formatter from nginx-logging.conf + access_log /var/log/nginx/access.log ietfjson; + + location /health/nginx { + access_log off; + return 200; + } + + location /robots.txt { + add_header Content-Type text/plain; + return 200 "User-agent: *\nDisallow: /doc/pdf/\n"; + } + + location / { + add_header Content-Security-Policy "default-src 'self' 'unsafe-inline' data: https://datatracker.ietf.org/ https://www.ietf.org/ http://ietf.org/ https://analytics.ietf.org https://static.ietf.org; frame-ancestors 'self' ietf.org *.ietf.org meetecho.com *.meetecho.com"; + proxy_set_header Host $${keepempty}host; + proxy_set_header Connection close; + proxy_set_header X-Request-Start "t=$${keepempty}msec"; + proxy_set_header X-Forwarded-For $${keepempty}proxy_add_x_forwarded_for; + proxy_hide_header X-Datatracker-Is-Authenticated; # hide this from the outside world + proxy_pass http://datatracker_backend; + # Set timeouts longer than Cloudflare proxy limits + proxy_connect_timeout 60; # nginx default (Cf = 15) + proxy_read_timeout 120; # nginx default = 60 (Cf = 100) + proxy_send_timeout 60; # nginx default = 60 (Cf = 30) + client_max_body_size 0; # disable size check + } +} diff --git a/k8s/nginx-logging.conf b/k8s/nginx-logging.conf new file mode 100644 index 00000000000..673d7a29abb --- /dev/null +++ b/k8s/nginx-logging.conf @@ -0,0 +1,22 @@ +# Define JSON log format - must be loaded before config that references it. +# Note that each line is fully enclosed in single quotes. Commas in arrays are +# intentionally inside the single quotes. +log_format ietfjson escape=json + '{' + '"time":"$${keepempty}time_iso8601",' + '"remote_ip":"$${keepempty}remote_addr",' + '"request":"$${keepempty}request",' + '"host":"$${keepempty}host",' + '"path":"$${keepempty}request_uri",' + '"method":"$${keepempty}request_method",' + '"status":"$${keepempty}status",' + '"len_bytes":"$${keepempty}body_bytes_sent",' + '"duration_s":"$${keepempty}request_time",' + '"referer":"$${keepempty}http_referer",' + '"user_agent":"$${keepempty}http_user_agent",' + '"x_forwarded_for":"$${keepempty}http_x_forwarded_for",' + '"x_forwarded_proto":"$${keepempty}http_x_forwarded_proto",' + '"cf_connecting_ip":"$${keepempty}http_cf_connecting_ip",' + '"cf_ray":"$${keepempty}http_cf_ray",' + '"asn":"$${keepempty}http_x_ip_src_asnum"' + '}'; diff --git a/k8s/rabbitmq.yaml b/k8s/rabbitmq.yaml new file mode 100644 index 00000000000..e69aa7a1aa1 --- /dev/null +++ b/k8s/rabbitmq.yaml @@ -0,0 +1,182 @@ +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: rabbitmq +spec: + replicas: 1 + revisionHistoryLimit: 2 + selector: + matchLabels: + app: rabbitmq + template: + metadata: + labels: + app: rabbitmq + spec: + securityContext: + runAsNonRoot: true + containers: + # ----------------------------------------------------- + # RabbitMQ Container + # ----------------------------------------------------- + - image: "ghcr.io/ietf-tools/datatracker-mq:3.13-alpine" + imagePullPolicy: Always + name: rabbitmq + ports: + - name: amqp + containerPort: 5672 + protocol: TCP + volumeMounts: + - name: rabbitmq-data + mountPath: /var/lib/rabbitmq + subPath: "rabbitmq" + - name: rabbitmq-tmp + mountPath: /tmp + - name: rabbitmq-config + mountPath: "/etc/rabbitmq" + env: + - name: CELERY_PASSWORD + valueFrom: + secretKeyRef: + name: dt-secrets-env + key: CELERY_PASSWORD + livenessProbe: + exec: + command: ["rabbitmq-diagnostics", "-q", "ping", "-t", "30"] + periodSeconds: 30 + timeoutSeconds: 35 # slightly longer than ping "-t" option + startupProbe: + initialDelaySeconds: 15 + periodSeconds: 5 + timeoutSeconds: 35 # slightly longer than ping "-t" option + successThreshold: 1 + failureThreshold: 60 + exec: + command: ["rabbitmq-diagnostics", "-q", "ping", "-t", "30"] + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + # rabbitmq image sets up uid/gid 100/101 + runAsUser: 100 + runAsGroup: 101 + resources: + requests: + cpu: 100m + memory: 150Mi + initContainers: + # ----------------------------------------------------- + # Init RabbitMQ data + # ----------------------------------------------------- + - name: init-rabbitmq + image: busybox:stable + command: + - "sh" + - "-c" + - "mkdir -p -m700 /mnt/rabbitmq && chown 100:101 /mnt/rabbitmq" + securityContext: + runAsNonRoot: false + runAsUser: 0 + readOnlyRootFilesystem: true + volumeMounts: + - name: "rabbitmq-data" + mountPath: "/mnt" + volumes: + - name: rabbitmq-tmp + emptyDir: + sizeLimit: "50Mi" + - name: rabbitmq-config + configMap: + name: "rabbitmq-configmap" + dnsPolicy: ClusterFirst + restartPolicy: Always + terminationGracePeriodSeconds: 30 + volumeClaimTemplates: + - metadata: + name: rabbitmq-data + spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 8Gi + # storageClassName: "" +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: rabbitmq-configmap +data: + definitions.json: |- + { + "permissions": [ + { + "configure": ".*", + "read": ".*", + "user": "datatracker", + "vhost": "dt", + "write": ".*" + } + ], + "users": [ + { + "hashing_algorithm": "rabbit_password_hashing_sha256", + "limits": {}, + "name": "datatracker", + "password_hash": "HJxcItcpXtBN+R/CH7dUelfKBOvdUs3AWo82SBw2yLMSguzb", + "tags": [] + } + ], + "vhosts": [ + { + "limits": [], + "metadata": { + "description": "", + "tags": [] + }, + "name": "dt" + } + ] + } + rabbitmq.conf: |- + # prevent guest from logging in over tcp + loopback_users.guest = true + + # load saved definitions + load_definitions = /etc/rabbitmq/definitions.json + + # Ensure that enough disk is available to flush to disk. To do this, need to limit the + # memory available to the container to something reasonable. See + # https://www.rabbitmq.com/production-checklist.html#monitoring-and-resource-usage + # for recommendations. + + # 1-1.5 times the memory available to the container is adequate for disk limit + disk_free_limit.absolute = 6000MB + + # This should be ~40% of the memory available to the container. Use an + # absolute number because relative will be proprtional to the full machine + # memory. + vm_memory_high_watermark.absolute = 1600MB + + # Logging + log.file = false + log.console = true + log.console.level = info + log.console.formatter = json +--- +apiVersion: v1 +kind: Service +metadata: + name: rabbitmq +spec: + type: ClusterIP + clusterIP: None # headless service + ports: + - port: 5672 + targetPort: amqp + protocol: TCP + name: amqp + selector: + app: rabbitmq diff --git a/k8s/replicator.yaml b/k8s/replicator.yaml new file mode 100644 index 00000000000..0b06fe4fdc5 --- /dev/null +++ b/k8s/replicator.yaml @@ -0,0 +1,76 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: replicator + labels: + deleteBeforeUpgrade: yes +spec: + replicas: 1 + revisionHistoryLimit: 2 + selector: + matchLabels: + app: replicator + strategy: + type: Recreate + template: + metadata: + labels: + app: replicator + spec: + securityContext: + runAsNonRoot: true + containers: + # ----------------------------------------------------- + # Celery Container + # ----------------------------------------------------- + - name: celery + image: "ghcr.io/ietf-tools/datatracker:$APP_IMAGE_TAG" + imagePullPolicy: Always + volumeMounts: + - name: dt-vol + mountPath: /a + - name: dt-tmp + mountPath: /tmp + - name: dt-home + mountPath: /home/datatracker + - name: dt-xml2rfc-cache + mountPath: /var/cache/xml2rfc + - name: dt-cfg + mountPath: /workspace/ietf/settings_local.py + subPath: settings_local.py + env: + - name: "CONTAINER_ROLE" + value: "replicator" + envFrom: + - secretRef: + name: dt-secrets-env + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + runAsUser: 1000 + runAsGroup: 1000 + resources: + requests: + cpu: 100m + memory: 500Mi + volumes: + # To be overridden with the actual shared volume + - name: dt-vol + - name: dt-tmp + emptyDir: + sizeLimit: "2Gi" + - name: dt-xml2rfc-cache + emptyDir: + sizeLimit: "2Gi" + - name: dt-home + emptyDir: + sizeLimit: "2Gi" + - name: dt-cfg + configMap: + name: files-cfgmap + dnsPolicy: ClusterFirst + restartPolicy: Always + terminationGracePeriodSeconds: 600 diff --git a/k8s/secrets.yaml b/k8s/secrets.yaml new file mode 100644 index 00000000000..4d326521467 --- /dev/null +++ b/k8s/secrets.yaml @@ -0,0 +1,82 @@ +apiVersion: v1 +kind: Secret +metadata: + name: secrets-env +type: Opaque +stringData: + DATATRACKER_SERVER_MODE: "development" # development for staging, production for production + DATATRACKER_ADMINS: |- + Robert Sparks + Ryan Cross + Kesara Rathnayake + Jennifer Richards + Nicolas Giard + DATATRACKER_ALLOWED_HOSTS: ".ietf.org" # newline-separated list also allowed + # DATATRACKER_DATATRACKER_DEBUG: "false" + + # DB access details - needs to be filled in + # DATATRACKER_DB_HOST: "db" + # DATATRACKER_DB_PORT: "5432" + # DATATRACKER_DB_NAME: "datatracker" + # DATATRACKER_DB_USER: "django" # secret + # DATATRACKER_DB_PASS: "RkTkDPFnKpko" # secret + # DATATRACKER_DB_CONN_MAX_AGE: "0" # connection per request if not set, no limit if set to "None" + # DATATRACKER_DB_CONN_HEALTH_CHECKS: "false" + + DATATRACKER_DJANGO_SECRET_KEY: "PDwXboUq!=hPjnrtG2=ge#N$Dwy+wn@uivrugwpic8mxyPfHk" # secret + + # Set this to point testing / staging at the production statics server until we + # sort that out + # DATATRACKER_STATIC_URL: "https://static.ietf.org/dt/12.10.0/" + + # DATATRACKER_EMAIL_DEBUG: "true" + + # Outgoing email details + # DATATRACKER_EMAIL_HOST: "localhost" # defaults to localhost + # DATATRACKER_EMAIL_PORT: "2025" # defaults to 2025 + + # The value here is the default from settings.py (i.e., not actually secret) + DATATRACKER_NOMCOM_APP_SECRET_B64: "m9pzMezVoFNJfsvU9XSZxGnXnwup6P5ZgCQeEnROOoQ=" # secret + + DATATRACKER_IANA_SYNC_PASSWORD: "this-is-the-iana-sync-password" # secret + DATATRACKER_YOUTUBE_API_KEY: "this-is-the-youtube-api-key" # secret + DATATRACKER_GITHUB_BACKUP_API_KEY: "this-is-the-github-backup-api-key" # secret + + # API key configuration + DATATRACKER_API_KEY_TYPE: "ES265" + # secret - value here is the default from settings.py (i.e., not actually secret) + DATATRACKER_API_PUBLIC_KEY_PEM_B64: |- + Ci0tLS0tQkVHSU4gUFVCTElDIEtFWS0tLS0tCk1Ga3dFd1lIS29aSXpqMENBUVlJS + 29aSXpqMERBUWNEUWdBRXFWb2pzYW9mREpTY3VNSk4rdHNodW15Tk01TUUKZ2Fyel + ZQcWtWb3ZtRjZ5RTdJSi9kdjRGY1YrUUtDdEovck9TOGUzNlk4WkFFVll1dWtoZXM + weVoxdz09Ci0tLS0tRU5EIFBVQkxJQyBLRVktLS0tLQo= + # secret - value here is the default from settings.py (i.e., not actually secret) + DATATRACKER_API_PRIVATE_KEY_PEM_B64: |- + Ci0tLS0tQkVHSU4gUFJJVkFURSBLRVktLS0tLQpNSUdIQWdFQU1CTUdCeXFHU000O + UFnRUdDQ3FHU000OUF3RUhCRzB3YXdJQkFRUWdvSTZMSmtvcEtxOFhySGk5ClFxR1 + F2RTRBODNURllqcUx6KzhnVUxZZWNzcWhSQU5DQUFTcFdpT3hxaDhNbEp5NHdrMzY + yeUc2Ykkwemt3U0IKcXZOVStxUldpK1lYcklUc2duOTIvZ1Z4WDVBb0swbitzNUx4 + N2ZwanhrQVJWaTY2U0Y2elRKblgKLS0tLS1FTkQgUFJJVkFURSBLRVktLS0tLQo= + + #DATATRACKER_REGISTRATION_API_KEY: "some-key" # secret" + + # DATATRACKER_MEETECHO_API_BASE: "https://meetings.conf.meetecho.com/api/v1/" + DATATRACKER_MEETECHO_CLIENT_ID: "this-is-the-meetecho-client-id" # secret + DATATRACKER_MEETECHO_CLIENT_SECRET: "this-is-the-meetecho-client-secret" # secret + + # DATATRACKER_MATOMO_SITE_ID: "7" # must be present to enable Matomo + # DATATRACKER_MATOMO_DOMAIN_PATH: "analytics.ietf.org" + + CELERY_PASSWORD: "this-is-a-secret" # secret + + # Only one of these may be set + # DATATRACKER_APP_API_TOKENS_JSON_B64: "e30K" # secret + # DATATRACKER_APP_API_TOKENS_JSON: "{}" # secret + + # use this to override default - one entry per line + # DATATRACKER_CSRF_TRUSTED_ORIGINS: |- + # https://datatracker.staging.ietf.org + + # Scout configuration + DATATRACKER_SCOUT_KEY: "this-is-the-scout-key" + DATATRACKER_SCOUT_NAME: "StagingDatatracker" diff --git a/k8s/settings_local.py b/k8s/settings_local.py new file mode 100644 index 00000000000..e5f0a9af0f3 --- /dev/null +++ b/k8s/settings_local.py @@ -0,0 +1,534 @@ +# Copyright The IETF Trust 2007-2026, All Rights Reserved +# -*- coding: utf-8 -*- + +from base64 import b64decode +from email.utils import parseaddr +import json + +from ietf import __release_hash__ +from ietf.settings import * # pyflakes:ignore +from ietf.settings import ( + STORAGES, + ARTIFACT_STORAGE_NAMES, + BLOBSTORAGE_CONNECT_TIMEOUT, + BLOBSTORAGE_READ_TIMEOUT, + BLOBSTORAGE_MAX_ATTEMPTS, +) +import botocore.config + + +def _multiline_to_list(s): + """Helper to split at newlines and convert to list""" + return [item.strip() for item in s.split("\n")] + + +# Default to "development". Production _must_ set DATATRACKER_SERVER_MODE="production" in the env! +SERVER_MODE = os.environ.get("DATATRACKER_SERVER_MODE", "development") + +# Secrets +_SECRET_KEY = os.environ.get("DATATRACKER_DJANGO_SECRET_KEY", None) +if _SECRET_KEY is not None: + SECRET_KEY = _SECRET_KEY +else: + raise RuntimeError("DATATRACKER_DJANGO_SECRET_KEY must be set") + +_NOMCOM_APP_SECRET_B64 = os.environ.get("DATATRACKER_NOMCOM_APP_SECRET_B64", None) +if _NOMCOM_APP_SECRET_B64 is not None: + NOMCOM_APP_SECRET = b64decode(_NOMCOM_APP_SECRET_B64) +else: + raise RuntimeError("DATATRACKER_NOMCOM_APP_SECRET_B64 must be set") + +_IANA_SYNC_PASSWORD = os.environ.get("DATATRACKER_IANA_SYNC_PASSWORD", None) +if _IANA_SYNC_PASSWORD is not None: + IANA_SYNC_PASSWORD = _IANA_SYNC_PASSWORD +else: + raise RuntimeError("DATATRACKER_IANA_SYNC_PASSWORD must be set") + +_YOUTUBE_API_KEY = os.environ.get("DATATRACKER_YOUTUBE_API_KEY", None) +if _YOUTUBE_API_KEY is not None: + YOUTUBE_API_KEY = _YOUTUBE_API_KEY +else: + raise RuntimeError("DATATRACKER_YOUTUBE_API_KEY must be set") + +_GITHUB_BACKUP_API_KEY = os.environ.get("DATATRACKER_GITHUB_BACKUP_API_KEY", None) +if _GITHUB_BACKUP_API_KEY is not None: + GITHUB_BACKUP_API_KEY = _GITHUB_BACKUP_API_KEY +else: + raise RuntimeError("DATATRACKER_GITHUB_BACKUP_API_KEY must be set") + +_API_KEY_TYPE = os.environ.get("DATATRACKER_API_KEY_TYPE", None) +if _API_KEY_TYPE is not None: + API_KEY_TYPE = _API_KEY_TYPE +else: + raise RuntimeError("DATATRACKER_API_KEY_TYPE must be set") + +_API_PUBLIC_KEY_PEM_B64 = os.environ.get("DATATRACKER_API_PUBLIC_KEY_PEM_B64", None) +if _API_PUBLIC_KEY_PEM_B64 is not None: + API_PUBLIC_KEY_PEM = b64decode(_API_PUBLIC_KEY_PEM_B64) +else: + raise RuntimeError("DATATRACKER_API_PUBLIC_KEY_PEM_B64 must be set") + +_API_PRIVATE_KEY_PEM_B64 = os.environ.get("DATATRACKER_API_PRIVATE_KEY_PEM_B64", None) +if _API_PRIVATE_KEY_PEM_B64 is not None: + API_PRIVATE_KEY_PEM = b64decode(_API_PRIVATE_KEY_PEM_B64) +else: + raise RuntimeError("DATATRACKER_API_PRIVATE_KEY_PEM_B64 must be set") + +_RED_PRECOMPUTER_TRIGGER_RETRY_DELAY = os.environ.get( + "DATATRACKER_RED_PRECOMPUTER_TRIGGER_RETRY_DELAY", None +) +if _RED_PRECOMPUTER_TRIGGER_RETRY_DELAY is not None: + RED_PRECOMPUTER_TRIGGER_RETRY_DELAY = _RED_PRECOMPUTER_TRIGGER_RETRY_DELAY +_RED_PRECOMPUTER_TRIGGER_MAX_RETRIES = os.environ.get( + "DATATRACKER_RED_PRECOMPUTER_TRIGGER_MAX_RETRIES", None +) +if _RED_PRECOMPUTER_TRIGGER_MAX_RETRIES is not None: + RED_PRECOMPUTER_TRIGGER_MAX_RETRIES = _RED_PRECOMPUTER_TRIGGER_MAX_RETRIES +_TRIGGER_RED_PRECOMPUTE_MULTIPLE_URL = os.environ.get( + "DATATRACKER_TRIGGER_RED_PRECOMPUTE_MULTIPLE_URL", None +) +if _TRIGGER_RED_PRECOMPUTE_MULTIPLE_URL is not None: + TRIGGER_RED_PRECOMPUTE_MULTIPLE_URL = _TRIGGER_RED_PRECOMPUTE_MULTIPLE_URL + +# Set DEBUG if DATATRACKER_DEBUG env var is the word "true" +DEBUG = os.environ.get("DATATRACKER_DEBUG", "false").lower() == "true" + +# DATATRACKER_ALLOWED_HOSTS env var is a newline-separated list of allowed hosts +_allowed_hosts_str = os.environ.get("DATATRACKER_ALLOWED_HOSTS", None) +if _allowed_hosts_str is not None: + ALLOWED_HOSTS = _multiline_to_list(_allowed_hosts_str) + +DATABASES = { + "default": { + "HOST": os.environ.get("DATATRACKER_DB_HOST", "db"), + "PORT": os.environ.get("DATATRACKER_DB_PORT", "5432"), + "NAME": os.environ.get("DATATRACKER_DB_NAME", "datatracker"), + "ENGINE": "django.db.backends.postgresql", + "USER": os.environ.get("DATATRACKER_DB_USER", "django"), + "PASSWORD": os.environ.get("DATATRACKER_DB_PASS", ""), + "OPTIONS": json.loads(os.environ.get("DATATRACKER_DB_OPTS_JSON", "{}")), + }, + "blobdb": { + "HOST": os.environ.get("BLOBDB_DB_HOST", "blobdb"), + "PORT": os.environ.get("BLOBDB_DB_PORT", "5432"), + "NAME": os.environ.get("BLOBDB_DB_NAME", "blob"), + "ENGINE": "django.db.backends.postgresql", + "USER": os.environ.get("BLOBDB_DB_USER", "django"), + "PASSWORD": os.environ.get("BLOBDB_DB_PASS", ""), + "OPTIONS": json.loads(os.environ.get("BLOBDB_DB_OPTS_JSON", "{}")), + }, +} + +DATABASE_ROUTERS = ["ietf.blobdb.routers.BlobdbStorageRouter"] +BLOBDB_DATABASE = "blobdb" + +# Configure persistent connections. A setting of 0 is Django's default. +_conn_max_age = os.environ.get("DATATRACKER_DB_CONN_MAX_AGE", "0") +for dbname in ["default", "blobdb"]: + # A string "none" means unlimited age. + DATABASES[dbname]["CONN_MAX_AGE"] = ( + None if _conn_max_age.lower() == "none" else int(_conn_max_age) + ) +# Enable connection health checks if DATATRACKER_DB_CONN_HEALTH_CHECK is the string "true" +_conn_health_checks = bool( + os.environ.get("DATATRACKER_DB_CONN_HEALTH_CHECKS", "false").lower() == "true" +) +for dbname in ["default", "blobdb"]: + DATABASES[dbname]["CONN_HEALTH_CHECKS"] = _conn_health_checks + +# DATATRACKER_ADMINS is a newline-delimited list of addresses parseable by email.utils.parseaddr +_admins_str = os.environ.get("DATATRACKER_ADMINS", None) +if _admins_str is not None: + ADMINS = [parseaddr(admin) for admin in _multiline_to_list(_admins_str)] +else: + raise RuntimeError("DATATRACKER_ADMINS must be set") + +USING_DEBUG_EMAIL_SERVER = ( + os.environ.get("DATATRACKER_EMAIL_DEBUG", "false").lower() == "true" +) +EMAIL_HOST = os.environ.get("DATATRACKER_EMAIL_HOST", "localhost") +EMAIL_PORT = int(os.environ.get("DATATRACKER_EMAIL_PORT", "2025")) + +_broker_url = os.environ.get("DATATRACKER_BROKER_URL", None) +_celery_password = os.environ.get("CELERY_PASSWORD", None) +if _broker_url is not None: + CELERY_BROKER_URL = _broker_url +elif _celery_password is not None: + CELERY_BROKER_URL = "amqp://datatracker:{password}@{host}/{queue}".format( + host=os.environ.get("RABBITMQ_HOSTNAME", "dt-rabbitmq"), + password=_celery_password, + queue=os.environ.get("RABBITMQ_QUEUE", "dt"), + ) +else: + raise RuntimeError("DATATRACKER_BROKER_URL or CELERY_PASSWORD must be set") + +# mailarchive API key +_mailing_list_archive_api_key = os.environ.get( + "DATATRACKER_MAILING_LIST_ARCHIVE_API_KEY", None +) +if _mailing_list_archive_api_key is None: + raise RuntimeError("DATATRACKER_MAILING_LIST_ARCHIVE_API_KEY must be set") +MAILING_LIST_ARCHIVE_API_KEY = _mailing_list_archive_api_key + +IANA_SYNC_USERNAME = "ietfsync" +IANA_SYNC_CHANGES_URL = "https://datatracker.iana.org:4443/data-tracker/changes" +IANA_SYNC_PROTOCOLS_URL = "http://www.iana.org/protocols/" + +RFC_EDITOR_NOTIFICATION_URL = "http://www.rfc-editor.org/parser/parser.php" + +_registration_api_key = os.environ.get("DATATRACKER_REGISTRATION_API_KEY", None) +if _registration_api_key is None: + raise RuntimeError("DATATRACKER_REGISTRATION_API_KEY must be set") +STATS_REGISTRATION_ATTENDEES_JSON_URL = f"https://registration.ietf.org/{{number}}/attendees/?apikey={_registration_api_key}" + +# Registration Participants API config - key must be set, but the URL can be left +# to the default in settings.py +_registration_participants_api_key = os.environ.get( + "DATATRACKER_REGISTRATION_PARTICIPANTS_API_KEY", None +) +if _registration_participants_api_key is None: + raise RuntimeError("DATATRACKER_REGISTRATION_PARTICIPANTS_API_KEY must be set") +REGISTRATION_PARTICIPANTS_API_KEY = _registration_participants_api_key + +_registration_participants_api_url = os.environ.get( + "DATATRACKER_REGISTRATION_PARTICIPANTS_API_URL", None +) +if _registration_participants_api_url is not None: + REGISTRATION_PARTICIPANTS_API_URL = _registration_participants_api_url + +# FIRST_CUTOFF_DAYS = 12 +# SECOND_CUTOFF_DAYS = 12 +# SUBMISSION_CUTOFF_DAYS = 26 +# SUBMISSION_CORRECTION_DAYS = 57 +MEETING_MATERIALS_SUBMISSION_CUTOFF_DAYS = 26 +MEETING_MATERIALS_SUBMISSION_CORRECTION_DAYS = 54 + +# disable htpasswd by setting to a do-nothing command +HTPASSWD_COMMAND = "/bin/true" + +_MEETECHO_CLIENT_ID = os.environ.get("DATATRACKER_MEETECHO_CLIENT_ID", None) +_MEETECHO_CLIENT_SECRET = os.environ.get("DATATRACKER_MEETECHO_CLIENT_SECRET", None) +if _MEETECHO_CLIENT_ID is not None and _MEETECHO_CLIENT_SECRET is not None: + MEETECHO_API_CONFIG = { + "api_base": os.environ.get( + "DATATRACKER_MEETECHO_API_BASE", + "https://meetings.conf.meetecho.com/api/v1/", + ), + "client_id": _MEETECHO_CLIENT_ID, + "client_secret": _MEETECHO_CLIENT_SECRET, + "request_timeout": 3.01, # python-requests doc recommend slightly > a multiple of 3 seconds + "slides_notify_time": int( + os.environ.get("DATATRACKER_MEETECHO_SLIDES_NOTIFY_TIME_MINUTES", "15") + ), + } +else: + raise RuntimeError( + "DATATRACKER_MEETECHO_CLIENT_ID and DATATRACKER_MEETECHO_CLIENT_SECRET must be set" + ) + +# For APP_API_TOKENS, accept either base64-encoded JSON or raw JSON, but not both. +# To decode / pretty-print the encoded form, run: +# base64 -d | jq . +# paste the encoded secret into stdin. Copy/paste that into an editor you trust not +# to leave a copy lying around. When done editing, copy/paste the final JSON through +# jq -c | base64 +# and copy/paste the output into the secret store. +if "DATATRACKER_APP_API_TOKENS_JSON_B64" in os.environ: + if "DATATRACKER_APP_API_TOKENS_JSON" in os.environ: + raise RuntimeError( + "Only one of DATATRACKER_APP_API_TOKENS_JSON and DATATRACKER_APP_API_TOKENS_JSON_B64 may be set" + ) + _APP_API_TOKENS_JSON = b64decode( + os.environ.get("DATATRACKER_APP_API_TOKENS_JSON_B64") + ) +else: + _APP_API_TOKENS_JSON = os.environ.get("DATATRACKER_APP_API_TOKENS_JSON", None) + +if _APP_API_TOKENS_JSON is not None: + APP_API_TOKENS = json.loads(_APP_API_TOKENS_JSON) +else: + APP_API_TOKENS = {} + +EMAIL_COPY_TO = "" + +# I-D Submission settings + +# Until we teach the datatracker to look beyond cloudflare for this check, it needs +# to be very large. 5000 has been working without complaint. +IDSUBMIT_MAX_DAILY_SAME_SUBMITTER = int( + os.environ.get("DATATRACKER_IDSUBMIT_MAX_DAILY_SAME_SUBMITTER", "5000") +) + +# Default is 20 minutes. Allow override via environment. +if "DATATRACKER_IDSUBMIT_MAX_VALIDATION_TIME" in os.environ: + IDSUBMIT_MAX_VALIDATION_TIME = datetime.timedelta( + minutes=int(os.environ.get("DATATRACKER_IDSUBMIT_MAX_VALIDATION_TIME")) + ) + +# Leave DATATRACKER_MATOMO_SITE_ID unset to disable Matomo reporting +if "DATATRACKER_MATOMO_SITE_ID" in os.environ: + MATOMO_DOMAIN_PATH = os.environ.get( + "DATATRACKER_MATOMO_DOMAIN_PATH", "analytics.ietf.org" + ) + MATOMO_SITE_ID = os.environ.get("DATATRACKER_MATOMO_SITE_ID") + MATOMO_DISABLE_COOKIES = True + +# Leave DATATRACKER_SCOUT_KEY unset to disable Scout APM agent +_SCOUT_KEY = os.environ.get("DATATRACKER_SCOUT_KEY", None) +if _SCOUT_KEY is not None: + if SERVER_MODE == "production": + PROD_PRE_APPS = [ + "scout_apm.django", + ] + else: + DEV_PRE_APPS = [ + "scout_apm.django", + ] + SCOUT_MONITOR = True + SCOUT_KEY = _SCOUT_KEY + SCOUT_NAME = os.environ.get("DATATRACKER_SCOUT_NAME", "Datatracker") + SCOUT_ERRORS_ENABLED = True + SCOUT_SHUTDOWN_MESSAGE_ENABLED = False + SCOUT_CORE_AGENT_SOCKET_PATH = "tcp://{host}:{port}".format( + host=os.environ.get("DATATRACKER_SCOUT_CORE_AGENT_HOST", "localhost"), + port=os.environ.get("DATATRACKER_SCOUT_CORE_AGENT_PORT", "6590"), + ) + SCOUT_CORE_AGENT_DOWNLOAD = False + SCOUT_CORE_AGENT_LAUNCH = False + SCOUT_REVISION_SHA = __release_hash__[:7] + +STATIC_URL = os.environ.get("DATATRACKER_STATIC_URL", None) +if STATIC_URL is None: + from ietf import __version__ + + STATIC_URL = f"https://static.ietf.org/dt/{__version__}/" + +# Set these to the same as "production" in settings.py, whether production mode or not +MEDIA_ROOT = "/a/www/www6s/lib/dt/media/" +MEDIA_URL = "https://www.ietf.org/lib/dt/media/" +PHOTOS_DIRNAME = "photo" +PHOTOS_DIR = MEDIA_ROOT + PHOTOS_DIRNAME + +# Normally only set for debug, but needed until we have a real FS +DJANGO_VITE["default"]["manifest_path"] = os.path.join( + BASE_DIR, "static/dist-neue/manifest.json" +) + +# Binaries that are different in the docker image +DE_GFM_BINARY = "/usr/local/bin/de-gfm" +IDSUBMIT_IDNITS_BINARY = "/usr/local/bin/idnits" + +# Duplicating production cache from settings.py and using it whether we're in production mode or not +MEMCACHED_HOST = os.environ.get("DT_MEMCACHED_SERVICE_HOST", "127.0.0.1") +MEMCACHED_PORT = os.environ.get("DT_MEMCACHED_SERVICE_PORT", "11211") +from ietf import __version__ + +CACHES = { + "default": { + "BACKEND": "ietf.utils.cache.LenientMemcacheCache", + "LOCATION": f"{MEMCACHED_HOST}:{MEMCACHED_PORT}", + "VERSION": __version__, + "KEY_PREFIX": "ietf:dt", + # Key function is default except with sha384-encoded key + "KEY_FUNCTION": lambda key, key_prefix, version: ( + f"{key_prefix}:{version}:{sha384(str(key).encode('utf8')).hexdigest()}" + ), + }, + "agenda": { + "BACKEND": "ietf.utils.cache.LenientMemcacheCache", + "LOCATION": f"{MEMCACHED_HOST}:{MEMCACHED_PORT}", + # No release-specific VERSION setting. + "KEY_PREFIX": "ietf:dt:agenda", + # Key function is default except with sha384-encoded key + "KEY_FUNCTION": lambda key, key_prefix, version: ( + f"{key_prefix}:{version}:{sha384(str(key).encode('utf8')).hexdigest()}" + ), + }, + "proceedings": { + "BACKEND": "ietf.utils.cache.LenientMemcacheCache", + "LOCATION": f"{MEMCACHED_HOST}:{MEMCACHED_PORT}", + # No release-specific VERSION setting. + "KEY_PREFIX": "ietf:dt:proceedings", + # Key function is default except with sha384-encoded key + "KEY_FUNCTION": lambda key, key_prefix, version: ( + f"{key_prefix}:{version}:{sha384(str(key).encode('utf8')).hexdigest()}" + ), + }, + "sessions": { + "BACKEND": "ietf.utils.cache.LenientMemcacheCache", + "LOCATION": f"{MEMCACHED_HOST}:{MEMCACHED_PORT}", + # No release-specific VERSION setting. + "KEY_PREFIX": "ietf:dt", + }, + "htmlized": { + "BACKEND": "django.core.cache.backends.filebased.FileBasedCache", + "LOCATION": "/a/cache/datatracker/htmlized", + "OPTIONS": { + "MAX_ENTRIES": 100000, # 100,000 + }, + }, + "pdfized": { + "BACKEND": "django.core.cache.backends.filebased.FileBasedCache", + "LOCATION": "/a/cache/datatracker/pdfized", + "OPTIONS": { + "MAX_ENTRIES": 100000, # 100,000 + }, + }, + "slowpages": { + "BACKEND": "django.core.cache.backends.filebased.FileBasedCache", + "LOCATION": "/a/cache/datatracker/slowpages", + "OPTIONS": { + "MAX_ENTRIES": 5000, + }, + }, + "celery-results": { + "BACKEND": "django.core.cache.backends.memcached.PyMemcacheCache", + "LOCATION": f"{MEMCACHED_HOST}:{MEMCACHED_PORT}", + "KEY_PREFIX": "ietf:celery", + }, +} + +_csrf_trusted_origins_str = os.environ.get("DATATRACKER_CSRF_TRUSTED_ORIGINS") +if _csrf_trusted_origins_str is not None: + CSRF_TRUSTED_ORIGINS = _multiline_to_list(_csrf_trusted_origins_str) + +# Console logs as JSON instead of plain when running in k8s +LOGGING["handlers"]["console"]["formatter"] = "json" + +# Configure storages for the replica blob store +_blob_store_endpoint_url = os.environ.get("DATATRACKER_BLOB_STORE_ENDPOINT_URL") +_blob_store_access_key = os.environ.get("DATATRACKER_BLOB_STORE_ACCESS_KEY") +_blob_store_secret_key = os.environ.get("DATATRACKER_BLOB_STORE_SECRET_KEY") +if None in (_blob_store_endpoint_url, _blob_store_access_key, _blob_store_secret_key): + raise RuntimeError( + "All of DATATRACKER_BLOB_STORE_ENDPOINT_URL, DATATRACKER_BLOB_STORE_ACCESS_KEY, " + "and DATATRACKER_BLOB_STORE_SECRET_KEY must be set" + ) +_blob_store_bucket_prefix = os.environ.get("DATATRACKER_BLOB_STORE_BUCKET_PREFIX", "") +_blob_store_bucket_suffix = os.environ.get("DATATRACKER_BLOB_STORE_BUCKET_SUFFIX", "") +_blob_store_enable_profiling = ( + os.environ.get("DATATRACKER_BLOB_STORE_ENABLE_PROFILING", "false").lower() == "true" +) +_blob_store_max_attempts = int( + os.environ.get("DATATRACKER_BLOB_STORE_MAX_ATTEMPTS", BLOBSTORAGE_MAX_ATTEMPTS) +) +_blob_store_connect_timeout = float( + os.environ.get( + "DATATRACKER_BLOB_STORE_CONNECT_TIMEOUT", BLOBSTORAGE_CONNECT_TIMEOUT + ) +) +_blob_store_read_timeout = float( + os.environ.get("DATATRACKER_BLOB_STORE_READ_TIMEOUT", BLOBSTORAGE_READ_TIMEOUT) +) + +for storagename in ARTIFACT_STORAGE_NAMES: + if storagename in ["staging"]: + continue + replica_storagename = f"r2-{storagename}" + adjusted_bucket_name = ( + _blob_store_bucket_prefix + storagename + _blob_store_bucket_suffix + ).strip() + STORAGES[replica_storagename] = { + "BACKEND": "ietf.doc.storage.MetadataS3Storage", + "OPTIONS": dict( + endpoint_url=_blob_store_endpoint_url, + access_key=_blob_store_access_key, + secret_key=_blob_store_secret_key, + security_token=None, + client_config=botocore.config.Config( + request_checksum_calculation="when_required", + response_checksum_validation="when_required", + signature_version="s3v4", + connect_timeout=_blob_store_connect_timeout, + read_timeout=_blob_store_read_timeout, + retries={"total_max_attempts": _blob_store_max_attempts}, + ), + verify=False, + bucket_name=adjusted_bucket_name, + ietf_log_blob_timing=_blob_store_enable_profiling, + ), + } + +# Configure storage for the red bucket - assume it uses the same credentials as +# other blobs +_red_bucket_name = os.environ.get("DATATRACKER_BLOB_STORE_RED_BUCKET_NAME", "").strip() +if _red_bucket_name == "": + raise RuntimeError("DATATRACKER_BLOB_STORE_RED_BUCKET_NAME must be set") + +STORAGES["red_bucket"] = { + "BACKEND": "storages.backends.s3.S3Storage", + "OPTIONS": dict( + endpoint_url=_blob_store_endpoint_url, + access_key=_blob_store_access_key, + secret_key=_blob_store_secret_key, + security_token=None, + client_config=botocore.config.Config( + request_checksum_calculation="when_required", + response_checksum_validation="when_required", + signature_version="s3v4", + connect_timeout=_blob_store_connect_timeout, + read_timeout=_blob_store_read_timeout, + retries={"total_max_attempts": _blob_store_max_attempts}, + ), + verify=False, + bucket_name=_red_bucket_name, + ), +} +RFCINDEX_DELETE_THEN_WRITE = False # S3Storage allows file_overwrite by default +if "DATATRACKER_RFCINDEX_OUTPUT_PATH" in os.environ: + RFCINDEX_OUTPUT_PATH = os.environ.get("DATATRACKER_RFCINDEX_OUTPUT_PATH") +if "DATATRACKER_RFCINDEX_INPUT_PATH" in os.environ: + RFCINDEX_INPUT_PATH = os.environ.get("DATATRACKER_RFCINDEX_INPUT_PATH") + +# Configure the blobdb app for artifact storage +_blobdb_replication_enabled = ( + os.environ.get("DATATRACKER_BLOBDB_REPLICATION_ENABLED", "true").lower() == "true" +) +_blobdb_replication_verbose_logging = ( + os.environ.get("DATATRACKER_BLOBDB_REPLICATION_VERBOSE_LOGGING", "false").lower() + == "true" +) + +BLOBDB_REPLICATION = { + "ENABLED": _blobdb_replication_enabled, + "DEST_STORAGE_PATTERN": "r2-{bucket}", + "INCLUDE_BUCKETS": ARTIFACT_STORAGE_NAMES, + "EXCLUDE_BUCKETS": ["staging"], + "VERBOSE_LOGGING": _blobdb_replication_verbose_logging, +} + +# Optionally disable password strength enforcement at login (on by default) +PASSWORD_POLICY_ENFORCE_AT_LOGIN = ( + os.environ.get("DATATRACKER_ENFORCE_PW_POLICY", "true").lower() != "false" +) + +# Typesense search indexing +SEARCHINDEX_CONFIG = { + "TYPESENSE_API_URL": os.environ.get("DATATRACKER_TYPESENSE_API_URL", ""), + "TYPESENSE_API_KEY": os.environ.get("DATATRACKER_TYPESENSE_API_KEY", ""), + "TASK_RETRY_DELAY": int( + os.environ.get("DATATRACKER_SEARCHINDEX_TASK_RETRY_DELAY", "10") + ), + "TASK_MAX_RETRIES": int( + os.environ.get("DATATRACKER_SEARCHINDEX_TASK_MAX_RETRIES", "12") + ), +} + +# Errata system api configuration +ERRATA_METADATA_NOTIFICATION_API_KEY = os.environ.get( + "DATATRACKER_ERRATA_METADATA_NOTIFICATION_API_KEY", None +) +if ERRATA_METADATA_NOTIFICATION_API_KEY is not None: + ERRATA_METADATA_NOTIFICATION_URL = os.environ.get( + "DATATRACKER_ERRATA_METADATA_NOTIFICATION_URL", None + ) + if ERRATA_METADATA_NOTIFICATION_URL is None: + raise RuntimeError( + "DATATRACKER_ERRATA_METADATA_NOTIFICATION_URL must be set if " + "DATATRACKER_ERRATA_METADATA_NOTIFICATION_API_KEY is provided" + ) + +# name (with path) of errata.json in the red bucket +ERRATA_JSON_BLOB_NAME = os.environ.get( + "DATATRACKER_ERRATA_JSON_BLOB_NAME", "other/errata.json" +) diff --git a/media/.gitignore b/media/.gitignore deleted file mode 100644 index dfa8ca37ce9..00000000000 --- a/media/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/floor diff --git a/media/photo/nopictureavailable.jpg b/media/photo/nopictureavailable.jpg deleted file mode 100644 index 0895f9f57c7..00000000000 Binary files a/media/photo/nopictureavailable.jpg and /dev/null differ diff --git a/media/photo/profile-default.jpg b/media/photo/profile-default.jpg deleted file mode 100644 index d6b03e10041..00000000000 Binary files a/media/photo/profile-default.jpg and /dev/null differ diff --git a/mypy.ini b/mypy.ini index 825bf03169d..4acaf98c950 100644 --- a/mypy.ini +++ b/mypy.ini @@ -1,20 +1,12 @@ [mypy] -#mypy_path = ./stubs/ - ignore_missing_imports = True +# allow PEP 695 type aliases (flag needed until mypy >= 1.13) +enable_incomplete_feature = NewGenericSyntax + plugins = mypy_django_plugin.main [mypy.plugins.django-stubs] django_settings_module = ietf.settings - -[mypy-ietf.group.migrations.0004_add_group_feature_fields] -ignore_errors = True - -[mypy-ietf.group.migrations.0002_groupfeatures_historicalgroupfeatures] -ignore_errors = True - -[mypy-ietf.doc.migrations.0001_initial] -ignore_errors = True diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 00000000000..7e3d2c27b91 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,8483 @@ +{ + "name": "workspace", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "dependencies": { + "@fullcalendar/bootstrap5": "6.1.21", + "@fullcalendar/core": "6.1.21", + "@fullcalendar/daygrid": "6.1.21", + "@fullcalendar/icalendar": "6.1.21", + "@fullcalendar/interaction": "6.1.21", + "@fullcalendar/list": "6.1.21", + "@fullcalendar/luxon3": "6.1.21", + "@fullcalendar/timegrid": "6.1.21", + "@fullcalendar/vue3": "6.1.21", + "@kurkle/color": "0.3.1", + "@popperjs/core": "2.11.8", + "@twuni/emojify": "1.0.2", + "bootstrap": "5.3.8", + "bootstrap-icons": "1.13.1", + "browser-fs-access": "0.38.0", + "caniuse-lite": "1.0.30001803", + "chart.js": "^4.5.1", + "chartjs-plugin-autocolors": "0.3.1", + "chartjs-plugin-zoom": "2.2.0", + "d3": "7.9.0", + "file-saver": "2.0.5", + "highcharts": "11.4.0", + "ical.js": "1.5.0", + "jquery": "3.7.1", + "js-cookie": "3.0.8", + "list.js": "2.3.1", + "lodash": "4.18.1", + "lodash-es": "4.18.1", + "luxon": "3.7.2", + "moment": "2.30.1", + "moment-timezone": "0.6.2", + "ms": "2.1.3", + "murmurhash-js": "1.0.0", + "naive-ui": "2.38.1", + "pinia": "2.1.7", + "pinia-plugin-persist": "1.0.0", + "select2": "4.1.0", + "select2-bootstrap-5-theme": "1.3.0", + "send": "1.2.1", + "shepherd.js": "11.2.0", + "slugify": "1.6.9", + "sortablejs": "1.15.7", + "vanillajs-datepicker": "1.3.4", + "vue": "3.4.21", + "vue-router": "4.3.0", + "zxcvbn": "4.4.2" + }, + "devDependencies": { + "@parcel/optimizer-data-url": "2.16.4", + "@parcel/transformer-inline-string": "2.16.4", + "@parcel/transformer-sass": "2.16.4", + "@rollup/pluginutils": "5.4.0", + "@vitejs/plugin-vue": "4.6.2", + "@vue/language-plugin-pug": "2.0.7", + "browserlist": "latest", + "c8": "9.1.0", + "html-validate": "8.18.1", + "jquery-migrate": "3.4.1", + "oxfmt": "0.58.0", + "oxlint": "1.73.0", + "parcel": "2.16.4", + "pug": "3.0.4", + "sass": "1.101.0", + "seedrandom": "3.0.5", + "vite": "4.5.3" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.7.tgz", + "integrity": "sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.29.7", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.29.7.tgz", + "integrity": "sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.29.7.tgz", + "integrity": "sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.7.tgz", + "integrity": "sha512-hnORnjP/1P/zFEndoeX+n+t1RwWRJiJpM/jO7FW32Kn9r5+sJB2JWOdYo4L6k78j15eCwY3Gm/7364B1EMwtNg==", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.29.7" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/runtime": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.29.7.tgz", + "integrity": "sha512-Nq8OhGWiZIZGV6hLHoyAKLLcJihP/xFeBMGJoUrxTX2psI8dCifzLhZISFb+VWS3wFMRDmCGw5R+dOySCqPLhw==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.7.tgz", + "integrity": "sha512-4zBIxpPzowiZpusoFkyGVwakdRJUyuH5PxQ/PrqghfdFWWasvnCdPfQXHrenDai+gyLARulZjZowCOj6fjT4pA==", + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.29.7", + "@babel/helper-validator-identifier": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@bcoe/v8-coverage": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", + "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@css-render/plugin-bem": { + "version": "0.15.14", + "resolved": "https://registry.npmjs.org/@css-render/plugin-bem/-/plugin-bem-0.15.14.tgz", + "integrity": "sha512-QK513CJ7yEQxm/P3EwsI+d+ha8kSOcjGvD6SevM41neEMxdULE+18iuQK6tEChAWMOQNQPLG/Rw3Khb69r5neg==", + "license": "MIT", + "peerDependencies": { + "css-render": "~0.15.14" + } + }, + "node_modules/@css-render/vue3-ssr": { + "version": "0.15.14", + "resolved": "https://registry.npmjs.org/@css-render/vue3-ssr/-/vue3-ssr-0.15.14.tgz", + "integrity": "sha512-//8027GSbxE9n3QlD73xFY6z4ZbHbvrOVB7AO6hsmrEzGbg+h2A09HboUyDgu+xsmj7JnvJD39Irt+2D0+iV8g==", + "license": "MIT", + "peerDependencies": { + "vue": "^3.0.11" + } + }, + "node_modules/@emotion/hash": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.8.0.tgz", + "integrity": "sha512-kBJtf7PH6aWwZ6fka3zQ0p6SBYzx4fl1LoZXE2RrnYST9Xljm7WfKJrU4g/Xr3Beg72MLrp1AWNUmuYJTL7Cow==", + "license": "MIT" + }, + "node_modules/@esbuild/android-arm": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.20.tgz", + "integrity": "sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz", + "integrity": "sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.20.tgz", + "integrity": "sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz", + "integrity": "sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.20.tgz", + "integrity": "sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.20.tgz", + "integrity": "sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.20.tgz", + "integrity": "sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.20.tgz", + "integrity": "sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.20.tgz", + "integrity": "sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.20.tgz", + "integrity": "sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.20.tgz", + "integrity": "sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.20.tgz", + "integrity": "sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.20.tgz", + "integrity": "sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.20.tgz", + "integrity": "sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.20.tgz", + "integrity": "sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz", + "integrity": "sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.20.tgz", + "integrity": "sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.20.tgz", + "integrity": "sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz", + "integrity": "sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.20.tgz", + "integrity": "sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.20.tgz", + "integrity": "sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz", + "integrity": "sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@floating-ui/core": { + "version": "1.7.5", + "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.7.5.tgz", + "integrity": "sha512-1Ih4WTWyw0+lKyFMcBHGbb5U5FtuHJuujoyyr5zTaWS5EYMeT6Jb2AuDeftsCsEuchO+mM2ij5+q9crhydzLhQ==", + "license": "MIT", + "dependencies": { + "@floating-ui/utils": "^0.2.11" + } + }, + "node_modules/@floating-ui/dom": { + "version": "1.7.6", + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.7.6.tgz", + "integrity": "sha512-9gZSAI5XM36880PPMm//9dfiEngYoC6Am2izES1FF406YFsjvyBMmeJ2g4SAju3xWwtuynNRFL2s9hgxpLI5SQ==", + "license": "MIT", + "dependencies": { + "@floating-ui/core": "^1.7.5", + "@floating-ui/utils": "^0.2.11" + } + }, + "node_modules/@floating-ui/utils": { + "version": "0.2.11", + "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.11.tgz", + "integrity": "sha512-RiB/yIh78pcIxl6lLMG0CgBXAZ2Y0eVHqMPYugu+9U0AeT6YBeiJpf7lbdJNIugFP5SIjwNRgo4DhR1Qxi26Gg==", + "license": "MIT" + }, + "node_modules/@fullcalendar/bootstrap5": { + "version": "6.1.21", + "resolved": "https://registry.npmjs.org/@fullcalendar/bootstrap5/-/bootstrap5-6.1.21.tgz", + "integrity": "sha512-dbWHhZ7Ih6PeoFcmsEbrI1nwia1mksD8xp0hqPEzCNDS/Yd3MXM/XxQSPYLlQZPRpHJABc+HjBxIOmdq35ZwmA==", + "license": "MIT", + "peerDependencies": { + "@fullcalendar/core": "~6.1.21" + } + }, + "node_modules/@fullcalendar/core": { + "version": "6.1.21", + "resolved": "https://registry.npmjs.org/@fullcalendar/core/-/core-6.1.21.tgz", + "integrity": "sha512-t3u/+sqh3Iq7TWtUnVLcGDUE6OWZh0UD3c04bI/l7lSLAgAKr3kngBmhHiQD1QXpwC8ZN5iNqG7a7gOVixhSKQ==", + "license": "MIT", + "dependencies": { + "preact": "~10.12.1" + } + }, + "node_modules/@fullcalendar/daygrid": { + "version": "6.1.21", + "resolved": "https://registry.npmjs.org/@fullcalendar/daygrid/-/daygrid-6.1.21.tgz", + "integrity": "sha512-QYb1y40RGYLlOxKpYWg8O+7njEnKnFG8Tt7qjnubJGR35s1phQg67E+81y2TyAbbm59p2JFOCXGDk9t6KDujIA==", + "license": "MIT", + "peerDependencies": { + "@fullcalendar/core": "~6.1.21" + } + }, + "node_modules/@fullcalendar/icalendar": { + "version": "6.1.21", + "resolved": "https://registry.npmjs.org/@fullcalendar/icalendar/-/icalendar-6.1.21.tgz", + "integrity": "sha512-YSk7YL7zOp6EWNI50SJTxKuy1uaHr/N2yXBq4VQZFOiDsQ25SNxeO+NFRGERZJyoJ/c70fjOdnW89VnK/3cq/w==", + "license": "MIT", + "peerDependencies": { + "@fullcalendar/core": "~6.1.21", + "ical.js": "^1.4.0" + } + }, + "node_modules/@fullcalendar/interaction": { + "version": "6.1.21", + "resolved": "https://registry.npmjs.org/@fullcalendar/interaction/-/interaction-6.1.21.tgz", + "integrity": "sha512-WPYpqtljDWmU0Xm2cOtFrLlocgxv7cgkOppj34Q6OUUat8a6Cnd6kYo2JR+irP223PE5lBYHFNp1qh7SIpJc0w==", + "license": "MIT", + "peerDependencies": { + "@fullcalendar/core": "~6.1.21" + } + }, + "node_modules/@fullcalendar/list": { + "version": "6.1.21", + "resolved": "https://registry.npmjs.org/@fullcalendar/list/-/list-6.1.21.tgz", + "integrity": "sha512-2rpIhs5pJmV7jyk4oX4bckNqurt6iHcsweE3FDYDdNpmRukPrARnyQYcaVFNVw2bnBFeR/jQW/St2MlauxF3GQ==", + "license": "MIT", + "peerDependencies": { + "@fullcalendar/core": "~6.1.21" + } + }, + "node_modules/@fullcalendar/luxon3": { + "version": "6.1.21", + "resolved": "https://registry.npmjs.org/@fullcalendar/luxon3/-/luxon3-6.1.21.tgz", + "integrity": "sha512-jlRhmxyut94fH7RbdsAexkmR9eJsVeavjVTk94M8GKPiAgEf2q3urFe4rFI5+ThwSTkOX8MPcfFIg8+uvKKZCQ==", + "license": "MIT", + "peerDependencies": { + "@fullcalendar/core": "~6.1.21", + "luxon": "^3.0.0" + } + }, + "node_modules/@fullcalendar/timegrid": { + "version": "6.1.21", + "resolved": "https://registry.npmjs.org/@fullcalendar/timegrid/-/timegrid-6.1.21.tgz", + "integrity": "sha512-2DnShx/jallGmb8QCkr6pAOu/zuPhJrP7+uTrAtSnbqsX7GF3lTxqSeNGkTQwsgF5g/ia8udhQ+JNYaE+TN1cQ==", + "license": "MIT", + "dependencies": { + "@fullcalendar/daygrid": "~6.1.21" + }, + "peerDependencies": { + "@fullcalendar/core": "~6.1.21" + } + }, + "node_modules/@fullcalendar/vue3": { + "version": "6.1.21", + "resolved": "https://registry.npmjs.org/@fullcalendar/vue3/-/vue3-6.1.21.tgz", + "integrity": "sha512-OGt6WSC+/zz/ej6a0KfIBNl7BYuGchpZU49SsedYyv3WZWbghAE+D8YD6nhH1ia/I4p5Gcsv/nEXgEkT/I8aYQ==", + "license": "MIT", + "peerDependencies": { + "@fullcalendar/core": "~6.1.21", + "vue": "^3.0.11" + } + }, + "node_modules/@html-validate/stylish": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/@html-validate/stylish/-/stylish-4.3.0.tgz", + "integrity": "sha512-eUfvKpRJg5TvzSfTf2EovrQoTKjkRnPUOUnXVJ2cQ4GbC/bQw98oxN+DdSf+HxOBK00YOhsP52xWdJPV1o4n5w==", + "dev": true, + "license": "MIT", + "dependencies": { + "kleur": "^4.0.0" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-regex": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/strip-ansi": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz", + "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.2.2" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/@istanbuljs/schema": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.6.tgz", + "integrity": "sha512-+Sg6GCR/wy1oSmQDFq4LQDAhm3ETKnorxN+y5nbLULOR3P0c14f2Wurzj3/xqPXtasLFfHd5iRFQ7AJt4KH2cw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@juggle/resize-observer": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/@juggle/resize-observer/-/resize-observer-3.4.0.tgz", + "integrity": "sha512-dfLbk+PwWvFzSxwk3n5ySL0hfBog779o8h68wK/7/APo/7cgyWp5jcXockbxdk5kFRkbeXWm4Fbi9FrdN381sA==", + "license": "Apache-2.0" + }, + "node_modules/@kurkle/color": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@kurkle/color/-/color-0.3.1.tgz", + "integrity": "sha512-hW0GwZj06z/ZFUW2Espl7toVDjghJN+EKqyXzPSV8NV89d5BYp5rRMBJoc+aUN0x5OXDMeRQHazejr2Xmqj2tw==", + "license": "MIT" + }, + "node_modules/@lezer/common": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/@lezer/common/-/common-1.5.2.tgz", + "integrity": "sha512-sxQE460fPZyU3sdc8lafxiPwJHBzZRy/udNFynGQky1SePYBdhkBl1kOagA9uT3pxR8K09bOrmTUqA9wb/PjSQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@lezer/lr": { + "version": "1.4.10", + "resolved": "https://registry.npmjs.org/@lezer/lr/-/lr-1.4.10.tgz", + "integrity": "sha512-rnCpTIBafOx4mRp43xOxDJbFipJm/c0cia/V5TiGlhmMa+wsSdoGmUN3w5Bqrks/09Q/D4tNAmWaT8p6NRi77A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@lezer/common": "^1.0.0" + } + }, + "node_modules/@lmdb/lmdb-darwin-arm64": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/@lmdb/lmdb-darwin-arm64/-/lmdb-darwin-arm64-2.8.5.tgz", + "integrity": "sha512-KPDeVScZgA1oq0CiPBcOa3kHIqU+pTOwRFDIhxvmf8CTNvqdZQYp5cCKW0bUk69VygB2PuTiINFWbY78aR2pQw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@lmdb/lmdb-darwin-x64": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/@lmdb/lmdb-darwin-x64/-/lmdb-darwin-x64-2.8.5.tgz", + "integrity": "sha512-w/sLhN4T7MW1nB3R/U8WK5BgQLz904wh+/SmA2jD8NnF7BLLoUgflCNxOeSPOWp8geP6nP/+VjWzZVip7rZ1ug==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@lmdb/lmdb-linux-arm": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/@lmdb/lmdb-linux-arm/-/lmdb-linux-arm-2.8.5.tgz", + "integrity": "sha512-c0TGMbm2M55pwTDIfkDLB6BpIsgxV4PjYck2HiOX+cy/JWiBXz32lYbarPqejKs9Flm7YVAKSILUducU9g2RVg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@lmdb/lmdb-linux-arm64": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/@lmdb/lmdb-linux-arm64/-/lmdb-linux-arm64-2.8.5.tgz", + "integrity": "sha512-vtbZRHH5UDlL01TT5jB576Zox3+hdyogvpcbvVJlmU5PdL3c5V7cj1EODdh1CHPksRl+cws/58ugEHi8bcj4Ww==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@lmdb/lmdb-linux-x64": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/@lmdb/lmdb-linux-x64/-/lmdb-linux-x64-2.8.5.tgz", + "integrity": "sha512-Xkc8IUx9aEhP0zvgeKy7IQ3ReX2N8N1L0WPcQwnZweWmOuKfwpS3GRIYqLtK5za/w3E60zhFfNdS+3pBZPytqQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@lmdb/lmdb-win32-x64": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/@lmdb/lmdb-win32-x64/-/lmdb-win32-x64-2.8.5.tgz", + "integrity": "sha512-4wvrf5BgnR8RpogHhtpCPJMKBmvyZPhhUtEwMJbXh0ni2BucpfF07jlmyM11zRqQ2XIq6PbC2j7W7UCCcm1rRQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@mischnic/json-sourcemap": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@mischnic/json-sourcemap/-/json-sourcemap-0.1.1.tgz", + "integrity": "sha512-iA7+tyVqfrATAIsIRWQG+a7ZLLD0VaOCKV2Wd/v4mqIU3J9c4jx9p7S0nw1XH3gJCKNBOOwACOPYYSUu9pgT+w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@lezer/common": "^1.0.0", + "@lezer/lr": "^1.0.0", + "json5": "^2.2.1" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/@msgpackr-extract/msgpackr-extract-darwin-arm64": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-darwin-arm64/-/msgpackr-extract-darwin-arm64-3.0.4.tgz", + "integrity": "sha512-LCkGo6JDfaBhgST7UpPWgNgLINpcpabaHfyz5OBx75nUYxBsaEPxjnyNjWpeb/xBup/682QnBfRBy2/LvPutZQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@msgpackr-extract/msgpackr-extract-darwin-x64": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-darwin-x64/-/msgpackr-extract-darwin-x64-3.0.4.tgz", + "integrity": "sha512-zExlW9zUJKZH/tOtVMttwjKa4Xm/3KcNjnE3dPN92uCktwavMxpgCA3MoJK/DOnTWsQgo224OaST27/mPNAf+w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@msgpackr-extract/msgpackr-extract-linux-arm": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-arm/-/msgpackr-extract-linux-arm-3.0.4.tgz", + "integrity": "sha512-Tg3yX65f5GbtXLkrYEHE5oibZG9epyYWas7FogTTEJeDEF9JlXJzKgXaNhT3UXlTOeA+AfZpYZYZ0uPj7Cfquw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@msgpackr-extract/msgpackr-extract-linux-arm64": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-arm64/-/msgpackr-extract-linux-arm64-3.0.4.tgz", + "integrity": "sha512-dgX0P/9wGPJeHFBG+ZmhgE6bmtMt7NP5CRBGyyktpopdk/mW4POnrpQsSLtKI1dwpc+pPLuXHDh6vvskyQE/sw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@msgpackr-extract/msgpackr-extract-linux-x64": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-x64/-/msgpackr-extract-linux-x64-3.0.4.tgz", + "integrity": "sha512-8TNXMEjJc3QEy7R/x1INhgiU+XakDAFUzBhaz7+Rbrs8NH5UQeHQxxmzsSBJGyV6I1jW79undiQm8tOI+D+8FQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@msgpackr-extract/msgpackr-extract-win32-x64": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-win32-x64/-/msgpackr-extract-win32-x64-3.0.4.tgz", + "integrity": "sha512-CmCXPQrkbwExx3j946/PtHWHbYJiCRBRDl4BlkRQcJB/YOwQxJRTpoo7aTsortjgoJ1x7opzTSxn7C+ASSLVjQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@oxfmt/binding-android-arm-eabi": { + "version": "0.58.0", + "resolved": "https://registry.npmjs.org/@oxfmt/binding-android-arm-eabi/-/binding-android-arm-eabi-0.58.0.tgz", + "integrity": "sha512-Uz62sHduGGPftXtILGyxdSW4PX82rUg+rfdNqhsgxe881g4rIoXlIqmZQ6HVKcF4f+F8qMhdD03Bx5u7gmeTdg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@oxfmt/binding-android-arm64": { + "version": "0.58.0", + "resolved": "https://registry.npmjs.org/@oxfmt/binding-android-arm64/-/binding-android-arm64-0.58.0.tgz", + "integrity": "sha512-rD0lRaJp1b+9vw6X4A2dJWKukd6X8yxiicN4JxXcXayolmUypRZxk+lKR+fVOu5q/iYc0fh5fR4bgmfOfVlbaA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@oxfmt/binding-darwin-arm64": { + "version": "0.58.0", + "resolved": "https://registry.npmjs.org/@oxfmt/binding-darwin-arm64/-/binding-darwin-arm64-0.58.0.tgz", + "integrity": "sha512-uzbPPk7O6M+w2K65vcQ1woga3wgP8zghjL1KOG5b6qJ8dvYHZJ1VShaslg2KOK6yQIwCQtcMCXqLBM6sqXUNTg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@oxfmt/binding-darwin-x64": { + "version": "0.58.0", + "resolved": "https://registry.npmjs.org/@oxfmt/binding-darwin-x64/-/binding-darwin-x64-0.58.0.tgz", + "integrity": "sha512-L0nKYDxU32oxeQqJj21W9SlIMnf81VZEhyah6iDvFhf5q0oynq498Fopth7blErUJVBpVtxQ98RMCfMPqpJX6w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@oxfmt/binding-freebsd-x64": { + "version": "0.58.0", + "resolved": "https://registry.npmjs.org/@oxfmt/binding-freebsd-x64/-/binding-freebsd-x64-0.58.0.tgz", + "integrity": "sha512-woNwfD58dC5PGS9LSLSD5JYfo/EFK5iG9vhDWkcCg3q78ag7KC8bpDqgvPHrMoXpx83OLXxoSOhu6z8FsVTHlg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@oxfmt/binding-linux-arm-gnueabihf": { + "version": "0.58.0", + "resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-0.58.0.tgz", + "integrity": "sha512-Sqs8nMLxuQpY21NKJ1u4stPDmO5hskBCNNh2E3AdCfI1QqWtf4m+Qn4mGEIUO4KGmuq3SWc/SZ80uy5IiwTCDw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@oxfmt/binding-linux-arm-musleabihf": { + "version": "0.58.0", + "resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-arm-musleabihf/-/binding-linux-arm-musleabihf-0.58.0.tgz", + "integrity": "sha512-Vd4exzBI5B5hB9m22JiTQzIL23WvHo/Pe+sNXPNeBLXSP9swCBPKCEBRwKpmpQzYhlgYaCgfPcGXPKAJBRIiZQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@oxfmt/binding-linux-arm64-gnu": { + "version": "0.58.0", + "resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-0.58.0.tgz", + "integrity": "sha512-bUWi5mHV+4Vi56RLHE1h6q/HHfwAIT3XoB9vJAVeRzfu5NriXM8y6eeJu0vlKa0C9kq2rq1sOWRClhdLHPocrg==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@oxfmt/binding-linux-arm64-musl": { + "version": "0.58.0", + "resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-arm64-musl/-/binding-linux-arm64-musl-0.58.0.tgz", + "integrity": "sha512-2ZHxemzgHcjtktAuVUwSoyXmGo/t+aF5tS1ciPpPei4rhSyrz3JOqDosXXrmhN/yLUSzJjtuW7ToTWqfQpCj2w==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@oxfmt/binding-linux-ppc64-gnu": { + "version": "0.58.0", + "resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-0.58.0.tgz", + "integrity": "sha512-AwKkVwjVmFQ3bcO7j0McGYAqCKH2a326fswfofng/E8VewCT/raeeGQr4huVhY704deK8AWASSTlxzMj0eZc6Q==", + "cpu": [ + "ppc64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@oxfmt/binding-linux-riscv64-gnu": { + "version": "0.58.0", + "resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-riscv64-gnu/-/binding-linux-riscv64-gnu-0.58.0.tgz", + "integrity": "sha512-xsRpTxfUnJF8D3AUKko/qyWdjw4GZVHlCVFuGlzSCTeewLmykKINW8em1+wx+axsDVtJJcMtvsiaXggXxrlHgw==", + "cpu": [ + "riscv64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@oxfmt/binding-linux-riscv64-musl": { + "version": "0.58.0", + "resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-riscv64-musl/-/binding-linux-riscv64-musl-0.58.0.tgz", + "integrity": "sha512-Z4AYOTcy7nYEIiXwD62PlerimyYRcfJOgUbQAEBjXz098kxKuERBlRntofGy69HHhe9E0TLVNMl1yspVNu+efw==", + "cpu": [ + "riscv64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@oxfmt/binding-linux-s390x-gnu": { + "version": "0.58.0", + "resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-0.58.0.tgz", + "integrity": "sha512-A3nhhtZPC/TKVWOPj9q/H3p2znJDCcHWYlJBhWL8hGq/bFmBaNBHC8Np6E581yVq1w9Mi3rMDNzDalWvtUfJtQ==", + "cpu": [ + "s390x" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@oxfmt/binding-linux-x64-gnu": { + "version": "0.58.0", + "resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-x64-gnu/-/binding-linux-x64-gnu-0.58.0.tgz", + "integrity": "sha512-2g+tVkgwqphw8R4hgo+kF4oz8+P5RwVOtr9+irsC7uwEp0e9j7Crw8kDGKL20uYlLPD7g02DqA61mC/UNYx98A==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@oxfmt/binding-linux-x64-musl": { + "version": "0.58.0", + "resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-x64-musl/-/binding-linux-x64-musl-0.58.0.tgz", + "integrity": "sha512-rc15P6AbyyB7426aN8AakLd02Trb3a6ML/mmfAQeVHJEfVofWLcWIrBdy6zDEY+DIaL/s8E4GGPboVw+oP3+EA==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@oxfmt/binding-openharmony-arm64": { + "version": "0.58.0", + "resolved": "https://registry.npmjs.org/@oxfmt/binding-openharmony-arm64/-/binding-openharmony-arm64-0.58.0.tgz", + "integrity": "sha512-ZWoTM27/HYPOh9iq86DAbhPu9nXb8qKvvGU/h8OfliyVUFAMMNTLDkGsWDKKnDqIkqvZ9+dXlgUOsH1LYO3O7g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@oxfmt/binding-win32-arm64-msvc": { + "version": "0.58.0", + "resolved": "https://registry.npmjs.org/@oxfmt/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-0.58.0.tgz", + "integrity": "sha512-LHZnqFXe2dEfkRI4XdZS/57nEOT/I4UCRX5IyM9v4GYW9XwQCjGe1IUK59SuKw3POwvcgWQ4pme2cYXmNqTNPg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@oxfmt/binding-win32-ia32-msvc": { + "version": "0.58.0", + "resolved": "https://registry.npmjs.org/@oxfmt/binding-win32-ia32-msvc/-/binding-win32-ia32-msvc-0.58.0.tgz", + "integrity": "sha512-mZKpg20TpheCJym1rarcZCUJeW1sSruw8zAAaCYWvuVfwIUDN1CXdrPU/JgCWReXTCTrEfCB8Wyo3hh9jSZ2EA==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@oxfmt/binding-win32-x64-msvc": { + "version": "0.58.0", + "resolved": "https://registry.npmjs.org/@oxfmt/binding-win32-x64-msvc/-/binding-win32-x64-msvc-0.58.0.tgz", + "integrity": "sha512-N/wUU4N5PZ2orBtI+Ko7MnMfYLfE7K91UrGMY/c/pYyHR3lA9kwst1XugkZx+92YcRh/Eo+iv2eTESSWXfiZPA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@oxlint/binding-android-arm-eabi": { + "version": "1.73.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-android-arm-eabi/-/binding-android-arm-eabi-1.73.0.tgz", + "integrity": "sha512-HZQRN/UMBu+Ut+/9MiAChkbP4qZqrNOWBcNI45vOT40GVhbGR0JgHB87L48D4iAqFQIdVmeQYtV9RF89AjTKkg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@oxlint/binding-android-arm64": { + "version": "1.73.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-android-arm64/-/binding-android-arm64-1.73.0.tgz", + "integrity": "sha512-Gp+KJRylv2aW7thRpG5p1KTxZq4ZJFbWowrKzufNq9d3ssl3r3JviYV45/+p+7CN1Nv0zDd1e8Ex0b/HUDq4TQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@oxlint/binding-darwin-arm64": { + "version": "1.73.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-darwin-arm64/-/binding-darwin-arm64-1.73.0.tgz", + "integrity": "sha512-3de96NdtXhxERMjIz7wsp2HYMY6pMQycGxFWac2mFecAx6VeARF/IqFb1QIaqiCRIdfzBwzTed+pCTCoiS+CYA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@oxlint/binding-darwin-x64": { + "version": "1.73.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-darwin-x64/-/binding-darwin-x64-1.73.0.tgz", + "integrity": "sha512-5zx/uPW32TiaOeVY1dQ/H5iOf0K1HOdFKOJhLqGl4o63+i1fpzoqqu/mKtd7OFgFjNCdhlyTGgjVkQTZm1ELcg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@oxlint/binding-freebsd-x64": { + "version": "1.73.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-freebsd-x64/-/binding-freebsd-x64-1.73.0.tgz", + "integrity": "sha512-qNe4gKHaGnLuZJ8toUg90JAa0S2vTVvDw+0bRi3q1avXZXDT4u5mMeECf3nD4HYrbdn1O7dXqWut4onY/yx/Xg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@oxlint/binding-linux-arm-gnueabihf": { + "version": "1.73.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.73.0.tgz", + "integrity": "sha512-cCehYh5hTbfShm/fxTD6wwrGUWIpvX+N5OxmAMhFhDeTGXvw+BeNj889tpxsFQ9ZLatQ6wImuY8tsKLZ+FMz7w==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@oxlint/binding-linux-arm-musleabihf": { + "version": "1.73.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-arm-musleabihf/-/binding-linux-arm-musleabihf-1.73.0.tgz", + "integrity": "sha512-d5j5GDU/2dMgjVhw7TQT9ITrsIr1Y02KEXKyVGIXUkD+KiaxE9TP65FS2ZdgTBemQvoRL+gSBdbrIm3cQIeacg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@oxlint/binding-linux-arm64-gnu": { + "version": "1.73.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.73.0.tgz", + "integrity": "sha512-Eyf1SrP3+yR1DI3OJgOY2Pvrr9dWP9TK37xPaDYycwTtlGlI45erJAVIfH5/m/xosDt6BupJYEFi47bvbTuuyw==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@oxlint/binding-linux-arm64-musl": { + "version": "1.73.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.73.0.tgz", + "integrity": "sha512-IlT/OJApEDKaMmCooHuncgJZbbCe7T5QIWmTZBEtYscWvzPQuuEinVcid6kwQRVQOUdb7PUCz4jQHnaYXdfJXw==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@oxlint/binding-linux-ppc64-gnu": { + "version": "1.73.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.73.0.tgz", + "integrity": "sha512-L+JYcb/vdg5fmcH08V6o0YYLU28cTH1SPNulwJdvK9NK49aXSkYy6oNpKBmddArVOXYqNepriDGiZ04G54kh1Q==", + "cpu": [ + "ppc64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@oxlint/binding-linux-riscv64-gnu": { + "version": "1.73.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-riscv64-gnu/-/binding-linux-riscv64-gnu-1.73.0.tgz", + "integrity": "sha512-Qtk0g3bKV6OwWjIm7R8kQN1uOZRKQt/MODK2a8QfkwhTpXBD53ozx5XLVWLGDQAVyp2otLW4D2wB98XfAfMPGA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@oxlint/binding-linux-riscv64-musl": { + "version": "1.73.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-riscv64-musl/-/binding-linux-riscv64-musl-1.73.0.tgz", + "integrity": "sha512-wX0NQKZVxltkAOVmzFcpOaMpdaUvsq1Eqpx9tkAfl71UdkTlSo1R4AdAnGccR1Fm2+TzFgZ22CyyGuZ41RDr/A==", + "cpu": [ + "riscv64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@oxlint/binding-linux-s390x-gnu": { + "version": "1.73.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.73.0.tgz", + "integrity": "sha512-vPe7UGBMWyiLTtnqS4xxgMQFSFGmtQwhwCxuiw6lXygaO6bVt0D8dFVg8Xv05eaiN3ybC0HXXHUAohFMFvqoCQ==", + "cpu": [ + "s390x" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@oxlint/binding-linux-x64-gnu": { + "version": "1.73.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.73.0.tgz", + "integrity": "sha512-2CwIWr9cemFC/CbRBWZvuk5mffz6ObmfFkfcC/9rTQ7f+icNhYr2kOjf9Rt8lLvugvkdGDOmkoVoFFHh6ClCTw==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@oxlint/binding-linux-x64-musl": { + "version": "1.73.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-x64-musl/-/binding-linux-x64-musl-1.73.0.tgz", + "integrity": "sha512-nDadfJgg7NBBxG0N560wOe7LLX5QiYp6qBaI7viuk5EUORFBktU/NfV0MbTqU3gTqQDCh4VyxKdo5VADxk9w8Q==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@oxlint/binding-openharmony-arm64": { + "version": "1.73.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-openharmony-arm64/-/binding-openharmony-arm64-1.73.0.tgz", + "integrity": "sha512-wGjJC+NLH9xP+IKGn9RDW94ojJR/wPbg5WCnQjj/oReaOtCQthr8ws1zICe77JFmo4ouUdeTHHZL/ESGiF6Pmw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@oxlint/binding-win32-arm64-msvc": { + "version": "1.73.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.73.0.tgz", + "integrity": "sha512-I7X47GPGljw225YUQ5SbC/rb1Kkdrd0yQf0x+hYxeKS6DpfjMbo9ccQPQ6LNY6BoJQ1sHhgDUGuMn5Vg5gHT6w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@oxlint/binding-win32-ia32-msvc": { + "version": "1.73.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-win32-ia32-msvc/-/binding-win32-ia32-msvc-1.73.0.tgz", + "integrity": "sha512-5lWj+3h+74Fm1jYOO9qkJA4xkAlZA099DkXppuXsk7UpnpZLttsefrZU469vChGaG6hcSqrkKXQOvMTZtbjeNg==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@oxlint/binding-win32-x64-msvc": { + "version": "1.73.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.73.0.tgz", + "integrity": "sha512-WaNRvh4f6zY9CvUQk2YoA1O90ieWrIklI84+HXFr9Isjz9CSESrdqo/RtIYt4Dll/cAchqGDMehfaZd0vqEFZw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@parcel/bundler-default": { + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/bundler-default/-/bundler-default-2.16.4.tgz", + "integrity": "sha512-Nb8peNvhfm1+660CLwssWh4weY+Mv6vEGS6GPKqzJmTMw50udi0eS1YuWFzvmhSiu1KsYcUD37mqQ1LuIDtWoA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/diagnostic": "2.16.4", + "@parcel/graph": "3.6.4", + "@parcel/plugin": "2.16.4", + "@parcel/rust": "2.16.4", + "@parcel/utils": "2.16.4", + "nullthrows": "^1.1.1" + }, + "engines": { + "node": ">= 16.0.0", + "parcel": "^2.16.4" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/codeframe": { + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/codeframe/-/codeframe-2.16.4.tgz", + "integrity": "sha512-s64aMfOJoPrXhKH+Y98ahX0O8aXWvTR+uNlOaX4yFkpr4FFDnviLcGngDe/Yo4Qq2FJZ0P6dNswbJTUH9EGxkQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.1.2" + }, + "engines": { + "node": ">= 16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/compressor-raw": { + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/compressor-raw/-/compressor-raw-2.16.4.tgz", + "integrity": "sha512-IK8IpNhw61B2HKgA1JhGhO9y+ZJFRZNTEmvhN1NdLdPqvgEXm2EunT+m6D9z7xeoeT6XnUKqM0eRckEdD0OXbA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/plugin": "2.16.4" + }, + "engines": { + "node": ">= 16.0.0", + "parcel": "^2.16.4" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/config-default": { + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/config-default/-/config-default-2.16.4.tgz", + "integrity": "sha512-kBxuTY/5trEVnvXk92l7LVkYjNuz3SaqWymFhPjEnc8GY4ZVdcWrWdXWTB9hUhpmRYJctFCyGvM0nN05JTiM2g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/bundler-default": "2.16.4", + "@parcel/compressor-raw": "2.16.4", + "@parcel/namer-default": "2.16.4", + "@parcel/optimizer-css": "2.16.4", + "@parcel/optimizer-html": "2.16.4", + "@parcel/optimizer-image": "2.16.4", + "@parcel/optimizer-svg": "2.16.4", + "@parcel/optimizer-swc": "2.16.4", + "@parcel/packager-css": "2.16.4", + "@parcel/packager-html": "2.16.4", + "@parcel/packager-js": "2.16.4", + "@parcel/packager-raw": "2.16.4", + "@parcel/packager-svg": "2.16.4", + "@parcel/packager-wasm": "2.16.4", + "@parcel/reporter-dev-server": "2.16.4", + "@parcel/resolver-default": "2.16.4", + "@parcel/runtime-browser-hmr": "2.16.4", + "@parcel/runtime-js": "2.16.4", + "@parcel/runtime-rsc": "2.16.4", + "@parcel/runtime-service-worker": "2.16.4", + "@parcel/transformer-babel": "2.16.4", + "@parcel/transformer-css": "2.16.4", + "@parcel/transformer-html": "2.16.4", + "@parcel/transformer-image": "2.16.4", + "@parcel/transformer-js": "2.16.4", + "@parcel/transformer-json": "2.16.4", + "@parcel/transformer-node": "2.16.4", + "@parcel/transformer-postcss": "2.16.4", + "@parcel/transformer-posthtml": "2.16.4", + "@parcel/transformer-raw": "2.16.4", + "@parcel/transformer-react-refresh-wrap": "2.16.4", + "@parcel/transformer-svg": "2.16.4" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "peerDependencies": { + "@parcel/core": "^2.16.4" + } + }, + "node_modules/@parcel/core": { + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/core/-/core-2.16.4.tgz", + "integrity": "sha512-a0CgrW5A5kwuSu5J1RFRoMQaMs9yagvfH2jJMYVw56+/7NRI4KOtu612SG9Y1ERWfY55ZwzyFxtLWvD6LO+Anw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@mischnic/json-sourcemap": "^0.1.1", + "@parcel/cache": "2.16.4", + "@parcel/diagnostic": "2.16.4", + "@parcel/events": "2.16.4", + "@parcel/feature-flags": "2.16.4", + "@parcel/fs": "2.16.4", + "@parcel/graph": "3.6.4", + "@parcel/logger": "2.16.4", + "@parcel/package-manager": "2.16.4", + "@parcel/plugin": "2.16.4", + "@parcel/profiler": "2.16.4", + "@parcel/rust": "2.16.4", + "@parcel/source-map": "^2.1.1", + "@parcel/types": "2.16.4", + "@parcel/utils": "2.16.4", + "@parcel/workers": "2.16.4", + "base-x": "^3.0.11", + "browserslist": "^4.24.5", + "clone": "^2.1.2", + "dotenv": "^16.5.0", + "dotenv-expand": "^11.0.7", + "json5": "^2.2.3", + "msgpackr": "^1.11.2", + "nullthrows": "^1.1.1", + "semver": "^7.7.1" + }, + "engines": { + "node": ">= 16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/core/node_modules/@parcel/cache": { + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/cache/-/cache-2.16.4.tgz", + "integrity": "sha512-+uCyeElSga2MBbmbXpIj/WVKH7TByCrKaxtHbelfKKIJpYMgEHVjO4cuc7GUfTrUAmRUS8ZGvnX7Etgq6/jQhw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/fs": "2.16.4", + "@parcel/logger": "2.16.4", + "@parcel/utils": "2.16.4", + "lmdb": "2.8.5" + }, + "engines": { + "node": ">= 16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "peerDependencies": { + "@parcel/core": "^2.16.4" + } + }, + "node_modules/@parcel/core/node_modules/@parcel/fs": { + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/fs/-/fs-2.16.4.tgz", + "integrity": "sha512-maCMOiVn7oJYZlqlfxgLne8n6tSktIT1k0AeyBp4UGWCXyeJUJ+nL7QYShFpKNLtMLeF0cEtgwRAknWzbcDS1g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/feature-flags": "2.16.4", + "@parcel/rust": "2.16.4", + "@parcel/types-internal": "2.16.4", + "@parcel/utils": "2.16.4", + "@parcel/watcher": "^2.0.7", + "@parcel/workers": "2.16.4" + }, + "engines": { + "node": ">= 16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "peerDependencies": { + "@parcel/core": "^2.16.4" + } + }, + "node_modules/@parcel/core/node_modules/@parcel/node-resolver-core": { + "version": "3.7.4", + "resolved": "https://registry.npmjs.org/@parcel/node-resolver-core/-/node-resolver-core-3.7.4.tgz", + "integrity": "sha512-b3VDG+um6IWW5CTod6M9hQsTX5mdIelKmam7mzxzgqg4j5hnycgTWqPMc9UxhYoUY/Q/PHfWepccNcKtvP5JiA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@mischnic/json-sourcemap": "^0.1.1", + "@parcel/diagnostic": "2.16.4", + "@parcel/fs": "2.16.4", + "@parcel/rust": "2.16.4", + "@parcel/utils": "2.16.4", + "nullthrows": "^1.1.1", + "semver": "^7.7.1" + }, + "engines": { + "node": ">= 16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/core/node_modules/@parcel/package-manager": { + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/package-manager/-/package-manager-2.16.4.tgz", + "integrity": "sha512-obWv9gZgdnkT3Kd+fBkKjhdNEY7zfOP5gVaox5i4nQstVCaVnDlMv5FwLEXwehL+WbwEcGyEGGxOHHkAFKk7Cg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/diagnostic": "2.16.4", + "@parcel/fs": "2.16.4", + "@parcel/logger": "2.16.4", + "@parcel/node-resolver-core": "3.7.4", + "@parcel/types": "2.16.4", + "@parcel/utils": "2.16.4", + "@parcel/workers": "2.16.4", + "@swc/core": "^1.11.24", + "semver": "^7.7.1" + }, + "engines": { + "node": ">= 16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "peerDependencies": { + "@parcel/core": "^2.16.4" + } + }, + "node_modules/@parcel/diagnostic": { + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/diagnostic/-/diagnostic-2.16.4.tgz", + "integrity": "sha512-YN5CfX7lFd6yRLxyZT4Sj3sR6t7nnve4TdXSIqapXzQwL7Bw+sj79D95wTq2rCm3mzk5SofGxFAXul2/nG6gcQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@mischnic/json-sourcemap": "^0.1.1", + "nullthrows": "^1.1.1" + }, + "engines": { + "node": ">= 16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/error-overlay": { + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/error-overlay/-/error-overlay-2.16.4.tgz", + "integrity": "sha512-e8KYKnMsfmQnqIhsUWBUZAXlDK30wkxsAGle1tZ0gOdoplaIdVq/WjGPatHLf6igLM76c3tRn2vw8jZFput0jw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/events": { + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/events/-/events-2.16.4.tgz", + "integrity": "sha512-slWQkBRAA7o0cN0BLEd+yCckPmlVRVhBZn5Pn6ktm4EzEtrqoMzMeJOxxH8TXaRzrQDYnTcnYIHFgXWd4kkUfg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/feature-flags": { + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/feature-flags/-/feature-flags-2.16.4.tgz", + "integrity": "sha512-nYdx53siKPLYikHHxfzgjzzgxdrjquK6DMnuSgOTyIdRG4VHdEN0+NqKijRLuVgiUFo/dtxc2h+amwqFENMw8w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/graph": { + "version": "3.6.4", + "resolved": "https://registry.npmjs.org/@parcel/graph/-/graph-3.6.4.tgz", + "integrity": "sha512-Cj9yV+/k88kFhE+D+gz0YuNRpvNOCVDskO9pFqkcQhGbsGq6kg2XpZ9V7HlYraih31xf8Vb589bZOwjKIiHixQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/feature-flags": "2.16.4", + "nullthrows": "^1.1.1" + }, + "engines": { + "node": ">= 16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/logger": { + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/logger/-/logger-2.16.4.tgz", + "integrity": "sha512-QR8QLlKo7xAy9JBpPDAh0RvluaixqPCeyY7Fvo2K7hrU3r85vBNNi06pHiPbWoDmB4x1+QoFwMaGnJOHR+/fMA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/diagnostic": "2.16.4", + "@parcel/events": "2.16.4" + }, + "engines": { + "node": ">= 16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/markdown-ansi": { + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/markdown-ansi/-/markdown-ansi-2.16.4.tgz", + "integrity": "sha512-0+oQApAVF3wMcQ6d1ZfZ0JsRzaMUYj9e4U+naj6YEsFsFGOPp+pQYKXBf1bobQeeB7cPKPT3SUHxFqced722Hw==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.1.2" + }, + "engines": { + "node": ">= 16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/namer-default": { + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/namer-default/-/namer-default-2.16.4.tgz", + "integrity": "sha512-CE+0lFg881sJq575EXxj2lKUn81tsS5itpNUUErHxit195m3PExyAhoXM6ed/SXxwi+uv+T5FS/jjDLBNuUFDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/diagnostic": "2.16.4", + "@parcel/plugin": "2.16.4", + "nullthrows": "^1.1.1" + }, + "engines": { + "node": ">= 16.0.0", + "parcel": "^2.16.4" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/optimizer-css": { + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/optimizer-css/-/optimizer-css-2.16.4.tgz", + "integrity": "sha512-aqdXCtmvpcXYgJFGk2DtXF34wuM2TD1fZorKMrJdKB9sSkWVRs1tq6RAXQrbi0ZPDH9wfE/9An3YdkTex7RHuQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/diagnostic": "2.16.4", + "@parcel/plugin": "2.16.4", + "@parcel/source-map": "^2.1.1", + "@parcel/utils": "2.16.4", + "browserslist": "^4.24.5", + "lightningcss": "^1.30.1", + "nullthrows": "^1.1.1" + }, + "engines": { + "node": ">= 16.0.0", + "parcel": "^2.16.4" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/optimizer-data-url": { + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/optimizer-data-url/-/optimizer-data-url-2.16.4.tgz", + "integrity": "sha512-O5ysQc9HwTBYIIfvcCd867TWza6iW5H+STe5fvKxFZHXhSKfgahH56oXX7I8Ltuell+v0dde8cI+feA3fHhDUQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/plugin": "2.16.4", + "@parcel/utils": "2.16.4", + "isbinaryfile": "^5.0.4", + "mime": "^3.0.0" + }, + "engines": { + "node": ">= 16.0.0", + "parcel": "^2.16.4" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/optimizer-html": { + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/optimizer-html/-/optimizer-html-2.16.4.tgz", + "integrity": "sha512-vg/R2uuSni+NYYUUV8m+5bz8p5zBv8wc/nNleoBnGuCDwn7uaUwTZ8Gt9CjZO8jjG0xCLILoc/TW+e2FF3pfgQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/plugin": "2.16.4", + "@parcel/rust": "2.16.4", + "@parcel/utils": "2.16.4" + }, + "engines": { + "node": ">= 16.0.0", + "parcel": "^2.16.4" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/optimizer-image": { + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/optimizer-image/-/optimizer-image-2.16.4.tgz", + "integrity": "sha512-2RV54WnvMYr18lxSx7Zlx/DXpJwMzOiPxDnoFyvaUoYutvgHO6chtcgFgh1Bvw/PoI95vYzlTkZ8QfUOk5A0JA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/diagnostic": "2.16.4", + "@parcel/plugin": "2.16.4", + "@parcel/rust": "2.16.4", + "@parcel/utils": "2.16.4", + "@parcel/workers": "2.16.4" + }, + "engines": { + "node": ">= 16.0.0", + "parcel": "^2.16.4" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "peerDependencies": { + "@parcel/core": "^2.16.4" + } + }, + "node_modules/@parcel/optimizer-svg": { + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/optimizer-svg/-/optimizer-svg-2.16.4.tgz", + "integrity": "sha512-22+BqIffCrVErg8y2XwhasbTaFNn75OKXZ3KTDBIfOSAZKLUKs1iHfDXETzTRN7cVcS+Q36/6EHd7N/RA8i1fg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/plugin": "2.16.4", + "@parcel/rust": "2.16.4", + "@parcel/utils": "2.16.4" + }, + "engines": { + "node": ">= 16.0.0", + "parcel": "^2.16.4" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/optimizer-swc": { + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/optimizer-swc/-/optimizer-swc-2.16.4.tgz", + "integrity": "sha512-+URqwnB6u1gqaLbG1O1DDApH+UVj4WCbK9No1fdxLBxQ9a84jyli25o1kK1hYB9Nb/JMyYNnEBfvYUW6RphOxw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/diagnostic": "2.16.4", + "@parcel/plugin": "2.16.4", + "@parcel/source-map": "^2.1.1", + "@parcel/utils": "2.16.4", + "@swc/core": "^1.11.24", + "nullthrows": "^1.1.1" + }, + "engines": { + "node": ">= 16.0.0", + "parcel": "^2.16.4" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/packager-css": { + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/packager-css/-/packager-css-2.16.4.tgz", + "integrity": "sha512-rWRtfiX+VVIOZvq64jpeNUKkvWAbnokfHQsk/js1s5jD4ViNQgPcNLiRaiIANjymqL6+dQqWvGUSW2a5FAZYfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/diagnostic": "2.16.4", + "@parcel/plugin": "2.16.4", + "@parcel/source-map": "^2.1.1", + "@parcel/utils": "2.16.4", + "lightningcss": "^1.30.1", + "nullthrows": "^1.1.1" + }, + "engines": { + "node": ">= 16.0.0", + "parcel": "^2.16.4" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/packager-html": { + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/packager-html/-/packager-html-2.16.4.tgz", + "integrity": "sha512-AWo5f6SSqBsg2uWOsX0gPX8hCx2iE6GYLg2Z4/cDy2mPlwDICN8/bxItEztSZFmObi+ti26eetBKRDxAUivyIQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/plugin": "2.16.4", + "@parcel/rust": "2.16.4", + "@parcel/types": "2.16.4", + "@parcel/utils": "2.16.4" + }, + "engines": { + "node": ">= 16.0.0", + "parcel": "^2.16.4" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/packager-js": { + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/packager-js/-/packager-js-2.16.4.tgz", + "integrity": "sha512-L2o39f/fhta+hxto7w8OTUKdstY+te5BmHZREckbQm0KTBg93BG7jB0bfoxLSZF0d8uuAYIVXjzeHNqha+du1g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/diagnostic": "2.16.4", + "@parcel/plugin": "2.16.4", + "@parcel/rust": "2.16.4", + "@parcel/source-map": "^2.1.1", + "@parcel/types": "2.16.4", + "@parcel/utils": "2.16.4", + "globals": "^13.24.0", + "nullthrows": "^1.1.1" + }, + "engines": { + "node": ">= 16.0.0", + "parcel": "^2.16.4" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/packager-raw": { + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/packager-raw/-/packager-raw-2.16.4.tgz", + "integrity": "sha512-A9j60G9OmbTkEeE4WRMXCiErEprHLs9NkUlC4HXCxmSrPMOVaMaMva2LdejE3A9kujZqYtYfuc8+a+jN+Nro4w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/plugin": "2.16.4" + }, + "engines": { + "node": ">= 16.0.0", + "parcel": "^2.16.4" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/packager-svg": { + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/packager-svg/-/packager-svg-2.16.4.tgz", + "integrity": "sha512-LT9l7eInFrAZJ6w3mYzAUgDq3SIzYbbQyW46Dz26M9lJQbf6uCaATUTac3BEHegW0ikDuw4OOGHK41BVqeeusg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/plugin": "2.16.4", + "@parcel/rust": "2.16.4", + "@parcel/types": "2.16.4", + "@parcel/utils": "2.16.4" + }, + "engines": { + "node": ">= 16.0.0", + "parcel": "^2.16.4" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/packager-wasm": { + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/packager-wasm/-/packager-wasm-2.16.4.tgz", + "integrity": "sha512-AY96Aqu/RpmaSZK2RGkIrZWjAperDw8DAlxLAiaP1D/RPVnikZtl5BmcUt/Wz3PrzG7/q9ZVqqKkWsLmhkjXZQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/plugin": "2.16.4" + }, + "engines": { + "node": ">=16.0.0", + "parcel": "^2.16.4" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/plugin": { + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/plugin/-/plugin-2.16.4.tgz", + "integrity": "sha512-aN2VQoRGC1eB41ZCDbPR/Sp0yKOxe31oemzPx1nJzOuebK2Q6FxSrJ9Bjj9j/YCaLzDtPwelsuLOazzVpXJ6qg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/types": "2.16.4" + }, + "engines": { + "node": ">= 16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/profiler": { + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/profiler/-/profiler-2.16.4.tgz", + "integrity": "sha512-R3JhfcnoReTv2sVFHPR2xKZvs3d3IRrBl9sWmAftbIJFwT4rU70/W7IdwfaJVkD/6PzHq9mcgOh1WKL4KAxPdA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/diagnostic": "2.16.4", + "@parcel/events": "2.16.4", + "@parcel/types-internal": "2.16.4", + "chrome-trace-event": "^1.0.2" + }, + "engines": { + "node": ">= 16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/reporter-cli": { + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/reporter-cli/-/reporter-cli-2.16.4.tgz", + "integrity": "sha512-DQx9TwcTZrDv828+tcwEi//xyW7OHTGzGX1+UEVxPp0mSzuOmDn0zfER8qNIqGr1i4D/FXhb5UJQDhGHV8mOpQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/plugin": "2.16.4", + "@parcel/types": "2.16.4", + "@parcel/utils": "2.16.4", + "chalk": "^4.1.2", + "term-size": "^2.2.1" + }, + "engines": { + "node": ">= 16.0.0", + "parcel": "^2.16.4" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/reporter-dev-server": { + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/reporter-dev-server/-/reporter-dev-server-2.16.4.tgz", + "integrity": "sha512-YWvay25htQDifpDRJ0+yFh6xUxKnbfeJxYkPYyuXdxpEUhq4T0UWW0PbPCN/wFX7StgeUTXq5Poeo/+eys9m3w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/codeframe": "2.16.4", + "@parcel/plugin": "2.16.4", + "@parcel/source-map": "^2.1.1", + "@parcel/utils": "2.16.4" + }, + "engines": { + "node": ">= 16.0.0", + "parcel": "^2.16.4" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/reporter-tracer": { + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/reporter-tracer/-/reporter-tracer-2.16.4.tgz", + "integrity": "sha512-JKnlXpPepak0/ZybmZn9JtyjJiDBWYrt7ZUlXQhQb0xzNcd/k+RqfwVkTKIwyFHsWtym0cwibkvsi2bWFzS7tw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/plugin": "2.16.4", + "@parcel/utils": "2.16.4", + "chrome-trace-event": "^1.0.3", + "nullthrows": "^1.1.1" + }, + "engines": { + "node": ">= 16.0.0", + "parcel": "^2.16.4" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/resolver-default": { + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/resolver-default/-/resolver-default-2.16.4.tgz", + "integrity": "sha512-wJe9XQS0hn/t32pntQpJbls3ZL8mGVVhK9L7s7BTmZT9ufnvP2nif1psJz/nbgnP9LF6mLSk43OdMJKpoStsjQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/node-resolver-core": "3.7.4", + "@parcel/plugin": "2.16.4" + }, + "engines": { + "node": ">= 16.0.0", + "parcel": "^2.16.4" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/resolver-default/node_modules/@parcel/fs": { + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/fs/-/fs-2.16.4.tgz", + "integrity": "sha512-maCMOiVn7oJYZlqlfxgLne8n6tSktIT1k0AeyBp4UGWCXyeJUJ+nL7QYShFpKNLtMLeF0cEtgwRAknWzbcDS1g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/feature-flags": "2.16.4", + "@parcel/rust": "2.16.4", + "@parcel/types-internal": "2.16.4", + "@parcel/utils": "2.16.4", + "@parcel/watcher": "^2.0.7", + "@parcel/workers": "2.16.4" + }, + "engines": { + "node": ">= 16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "peerDependencies": { + "@parcel/core": "^2.16.4" + } + }, + "node_modules/@parcel/resolver-default/node_modules/@parcel/node-resolver-core": { + "version": "3.7.4", + "resolved": "https://registry.npmjs.org/@parcel/node-resolver-core/-/node-resolver-core-3.7.4.tgz", + "integrity": "sha512-b3VDG+um6IWW5CTod6M9hQsTX5mdIelKmam7mzxzgqg4j5hnycgTWqPMc9UxhYoUY/Q/PHfWepccNcKtvP5JiA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@mischnic/json-sourcemap": "^0.1.1", + "@parcel/diagnostic": "2.16.4", + "@parcel/fs": "2.16.4", + "@parcel/rust": "2.16.4", + "@parcel/utils": "2.16.4", + "nullthrows": "^1.1.1", + "semver": "^7.7.1" + }, + "engines": { + "node": ">= 16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/runtime-browser-hmr": { + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/runtime-browser-hmr/-/runtime-browser-hmr-2.16.4.tgz", + "integrity": "sha512-asx7p3NjUSfibI3bC7+8+jUIGHWVk2Zuq9SjJGCGDt+auT9A4uSGljnsk1BWWPqqZ0WILubq4czSAqm0+wt4cw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/plugin": "2.16.4", + "@parcel/utils": "2.16.4" + }, + "engines": { + "node": ">= 16.0.0", + "parcel": "^2.16.4" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/runtime-js": { + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/runtime-js/-/runtime-js-2.16.4.tgz", + "integrity": "sha512-gUKmsjg+PULQBu2QbX0QKll9tXSqHPO8NrfxHwWb2lz5xDKDos1oV0I7BoMWbHhUHkoToXZrm654oGViujtVUA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/diagnostic": "2.16.4", + "@parcel/plugin": "2.16.4", + "@parcel/utils": "2.16.4", + "nullthrows": "^1.1.1" + }, + "engines": { + "node": ">= 16.0.0", + "parcel": "^2.16.4" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/runtime-rsc": { + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/runtime-rsc/-/runtime-rsc-2.16.4.tgz", + "integrity": "sha512-CHkotYE/cNiUjJmrc5FD9YhlFp1UF5wMNNJmoWaL40eBzsqcaV0sSn5V3bNapwewn3wrMYgdPgvOTHfaZaG73A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/plugin": "2.16.4", + "@parcel/rust": "2.16.4", + "@parcel/utils": "2.16.4", + "nullthrows": "^1.1.1" + }, + "engines": { + "node": ">= 12.0.0", + "parcel": "^2.16.4" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/runtime-service-worker": { + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/runtime-service-worker/-/runtime-service-worker-2.16.4.tgz", + "integrity": "sha512-FT0Q58bf5Re+dq5cL2XHbxqHHFZco6qtRijeVpT3TSPMRPlniMArypSytTeZzVNL7h/hxjWsNu7fRuC0yLB5hA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/plugin": "2.16.4", + "@parcel/utils": "2.16.4", + "nullthrows": "^1.1.1" + }, + "engines": { + "node": ">= 16.0.0", + "parcel": "^2.16.4" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/rust": { + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/rust/-/rust-2.16.4.tgz", + "integrity": "sha512-RBMKt9rCdv6jr4vXG6LmHtxzO5TuhQvXo1kSoSIF7fURRZ81D1jzBtLxwLmfxCPsofJNqWwdhy5vIvisX+TLlQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "@parcel/rust-darwin-arm64": "2.16.4", + "@parcel/rust-darwin-x64": "2.16.4", + "@parcel/rust-linux-arm-gnueabihf": "2.16.4", + "@parcel/rust-linux-arm64-gnu": "2.16.4", + "@parcel/rust-linux-arm64-musl": "2.16.4", + "@parcel/rust-linux-x64-gnu": "2.16.4", + "@parcel/rust-linux-x64-musl": "2.16.4", + "@parcel/rust-win32-x64-msvc": "2.16.4" + }, + "peerDependencies": { + "napi-wasm": "^1.1.2" + }, + "peerDependenciesMeta": { + "napi-wasm": { + "optional": true + } + } + }, + "node_modules/@parcel/rust-darwin-arm64": { + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/rust-darwin-arm64/-/rust-darwin-arm64-2.16.4.tgz", + "integrity": "sha512-P3Se36H9EO1fOlwXqQNQ+RsVKTGn5ztRSUGbLcT8ba6oOMmU1w7J4R810GgsCbwCuF10TJNUMkuD3Q2Sz15Q3Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/rust-darwin-x64": { + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/rust-darwin-x64/-/rust-darwin-x64-2.16.4.tgz", + "integrity": "sha512-8aNKNyPIx3EthYpmVJevIdHmFsOApXAEYGi3HU69jTxLgSIfyEHDdGE9lEsMvhSrd/SSo4/euAtiV+pqK04wnA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/rust-linux-arm-gnueabihf": { + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/rust-linux-arm-gnueabihf/-/rust-linux-arm-gnueabihf-2.16.4.tgz", + "integrity": "sha512-QrvqiSHaWRLc0JBHgUHVvDthfWSkA6AFN+ikV1UGENv4j2r/QgvuwJiG0VHrsL6pH5dRqj0vvngHzEgguke9DA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/rust-linux-arm64-gnu": { + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/rust-linux-arm64-gnu/-/rust-linux-arm64-gnu-2.16.4.tgz", + "integrity": "sha512-f3gBWQHLHRUajNZi3SMmDQiEx54RoRbXtZYQNuBQy7+NolfFcgb1ik3QhkT7xovuTF/LBmaqP3UFy0PxvR/iwQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/rust-linux-arm64-musl": { + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/rust-linux-arm64-musl/-/rust-linux-arm64-musl-2.16.4.tgz", + "integrity": "sha512-cwml18RNKsBwHyZnrZg4jpecXkWjaY/mCArocWUxkFXjjB97L56QWQM9W86f2/Y3HcFcnIGJwx1SDDKJrV6OIA==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/rust-linux-x64-gnu": { + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/rust-linux-x64-gnu/-/rust-linux-x64-gnu-2.16.4.tgz", + "integrity": "sha512-0xIjQaN8hiG0F9R8coPYidHslDIrbfOS/qFy5GJNbGA3S49h61wZRBMQqa7JFW4+2T8R0J9j0SKHhLXpbLXrIg==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/rust-linux-x64-musl": { + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/rust-linux-x64-musl/-/rust-linux-x64-musl-2.16.4.tgz", + "integrity": "sha512-fYn21GIecHK9RoZPKwT9NOwxwl3Gy3RYPR6zvsUi0+hpFo19Ph9EzFXN3lT8Pi5KiwQMCU4rsLb5HoWOBM1FeA==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/rust-win32-x64-msvc": { + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/rust-win32-x64-msvc/-/rust-win32-x64-msvc-2.16.4.tgz", + "integrity": "sha512-TcpWC3I1mJpfP2++018lgvM7UX0P8IrzNxceBTHUKEIDMwmAYrUKAQFiaU0j1Ldqk6yP8SPZD3cvphumsYpJOQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/source-map": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@parcel/source-map/-/source-map-2.1.1.tgz", + "integrity": "sha512-Ejx1P/mj+kMjQb8/y5XxDUn4reGdr+WyKYloBljpppUy8gs42T+BNoEOuRYqDVdgPc6NxduzIDoJS9pOFfV5Ew==", + "dev": true, + "license": "MIT", + "dependencies": { + "detect-libc": "^1.0.3" + }, + "engines": { + "node": "^12.18.3 || >=14" + } + }, + "node_modules/@parcel/transformer-babel": { + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/transformer-babel/-/transformer-babel-2.16.4.tgz", + "integrity": "sha512-CMDUOQYX7+cmeyHxHSFnoPcwvXNL7rRFE+Q06uVFzsYYiVhbwGF/1J5Bx4cW3Froumqla4YTytTsEteJEybkdA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/diagnostic": "2.16.4", + "@parcel/plugin": "2.16.4", + "@parcel/source-map": "^2.1.1", + "@parcel/utils": "2.16.4", + "browserslist": "^4.24.5", + "json5": "^2.2.3", + "nullthrows": "^1.1.1", + "semver": "^7.7.1" + }, + "engines": { + "node": ">= 16.0.0", + "parcel": "^2.16.4" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/transformer-css": { + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/transformer-css/-/transformer-css-2.16.4.tgz", + "integrity": "sha512-VG/+DbDci2HKe20GFRDs65ZQf5GUFfnmZAa1BhVl/MO+ijT3XC3eoVUy5cExRkq4VLcPY4ytL0g/1T2D6x7lBQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/diagnostic": "2.16.4", + "@parcel/plugin": "2.16.4", + "@parcel/source-map": "^2.1.1", + "@parcel/utils": "2.16.4", + "browserslist": "^4.24.5", + "lightningcss": "^1.30.1", + "nullthrows": "^1.1.1" + }, + "engines": { + "node": ">= 16.0.0", + "parcel": "^2.16.4" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/transformer-html": { + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/transformer-html/-/transformer-html-2.16.4.tgz", + "integrity": "sha512-w6JErYTeNS+KAzUAER18NHFIFFvxiLGd4Fht1UYcb/FDjJdLAMB/FljyEs0Rto/WAhZ2D0MuSL25HQh837R62g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/diagnostic": "2.16.4", + "@parcel/plugin": "2.16.4", + "@parcel/rust": "2.16.4" + }, + "engines": { + "node": ">= 16.0.0", + "parcel": "^2.16.4" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/transformer-image": { + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/transformer-image/-/transformer-image-2.16.4.tgz", + "integrity": "sha512-ZzIn3KvvRqMfcect4Dy+57C9XoQXZhpVJKBdQWMp9wM1qJEgsVgGDcaSBYCs/UYSKMRMP6Wm20pKCt408RkQzg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/plugin": "2.16.4", + "@parcel/utils": "2.16.4", + "@parcel/workers": "2.16.4", + "nullthrows": "^1.1.1" + }, + "engines": { + "node": ">= 16.0.0", + "parcel": "^2.16.4" + }, + "peerDependencies": { + "@parcel/core": "^2.16.4" + } + }, + "node_modules/@parcel/transformer-inline-string": { + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/transformer-inline-string/-/transformer-inline-string-2.16.4.tgz", + "integrity": "sha512-Kr5YZbN3xeb3asvle9+Nso/Tqxy0I/mdV2oQC30NuVVP+PXbOD4fC24QtORyt0V1UX93KqgmXKl7G75767FcVg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/plugin": "2.16.4" + }, + "engines": { + "node": ">= 16.0.0", + "parcel": "^2.16.4" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/transformer-js": { + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/transformer-js/-/transformer-js-2.16.4.tgz", + "integrity": "sha512-FD2fdO6URwAGBPidb3x1dDgLBt972mko0LelcSU05aC/pcKaV9mbCtINbPul1MlStzkxDelhuImcCYIyerheVQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/diagnostic": "2.16.4", + "@parcel/plugin": "2.16.4", + "@parcel/rust": "2.16.4", + "@parcel/source-map": "^2.1.1", + "@parcel/utils": "2.16.4", + "@parcel/workers": "2.16.4", + "@swc/helpers": "^0.5.0", + "browserslist": "^4.24.5", + "nullthrows": "^1.1.1", + "regenerator-runtime": "^0.14.1", + "semver": "^7.7.1" + }, + "engines": { + "node": ">= 16.0.0", + "parcel": "^2.16.4" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "peerDependencies": { + "@parcel/core": "^2.16.4" + } + }, + "node_modules/@parcel/transformer-json": { + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/transformer-json/-/transformer-json-2.16.4.tgz", + "integrity": "sha512-pB3ZNqgokdkBCJ+4G0BrPYcIkyM9K1HVk0GvjzcLEFDKsoAp8BGEM68FzagFM/nVq9anYTshIaoh349GK0M/bg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/plugin": "2.16.4", + "json5": "^2.2.3" + }, + "engines": { + "node": ">= 16.0.0", + "parcel": "^2.16.4" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/transformer-node": { + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/transformer-node/-/transformer-node-2.16.4.tgz", + "integrity": "sha512-7t43CPGfMJk1LqFokwxHSsRi+kKC2QvDXaMtqiMShmk50LCwn81WgzuFvNhMwf6lSiBihWupGwF3Fqksg+aisg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/plugin": "2.16.4" + }, + "engines": { + "node": ">= 16.0.0", + "parcel": "^2.16.4" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/transformer-postcss": { + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/transformer-postcss/-/transformer-postcss-2.16.4.tgz", + "integrity": "sha512-jfmh9ho03H+qwz9S1b/a/oaOmgfMovtHKYDweIGMjKULKIee3AFRqo8RZIOuUMjDuqHWK8SqQmjery4syFV3Xw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/diagnostic": "2.16.4", + "@parcel/plugin": "2.16.4", + "@parcel/rust": "2.16.4", + "@parcel/utils": "2.16.4", + "clone": "^2.1.2", + "nullthrows": "^1.1.1", + "postcss-value-parser": "^4.2.0", + "semver": "^7.7.1" + }, + "engines": { + "node": ">= 16.0.0", + "parcel": "^2.16.4" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/transformer-posthtml": { + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/transformer-posthtml/-/transformer-posthtml-2.16.4.tgz", + "integrity": "sha512-+GXsmGx1L25KQGQnwclgEuQe1t4QU+IoDkgN+Ikj+EnQCOWG4/ts2VpMBeqP5F18ZT4cCSRafj6317o/2lSGJg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/plugin": "2.16.4", + "@parcel/utils": "2.16.4" + }, + "engines": { + "node": ">= 16.0.0", + "parcel": "^2.16.4" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/transformer-raw": { + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/transformer-raw/-/transformer-raw-2.16.4.tgz", + "integrity": "sha512-7WDUPq+bW11G9jKxaQIVL+NPGolV99oq/GXhpjYip0SaGaLzRCW7gEk60cftuk0O7MsDaX5jcAJm3G/AX+LJKg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/plugin": "2.16.4" + }, + "engines": { + "node": ">= 16.0.0", + "parcel": "^2.16.4" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/transformer-react-refresh-wrap": { + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/transformer-react-refresh-wrap/-/transformer-react-refresh-wrap-2.16.4.tgz", + "integrity": "sha512-MiLNZrsGQJTANKKa4lzZyUbGj/en0Hms474mMdQkCBFg6GmjfmXwaMMgtTfPA3ZwSp2+3LeObCyca/f9B2gBZQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/error-overlay": "2.16.4", + "@parcel/plugin": "2.16.4", + "@parcel/utils": "2.16.4", + "react-refresh": "^0.16.0" + }, + "engines": { + "node": ">= 16.0.0", + "parcel": "^2.16.4" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/transformer-sass": { + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/transformer-sass/-/transformer-sass-2.16.4.tgz", + "integrity": "sha512-TvYZf7dwgtIVHcxkmOlIz0e28Ec7T6z0Jhzu+WcnFSonnhyrvKuqAxy7QV5EGc6O4qvDWwAQV1lvaLU0te+mQQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/plugin": "2.16.4", + "@parcel/source-map": "^2.1.1", + "sass": "^1.88.0" + }, + "engines": { + "node": ">= 16.0.0", + "parcel": "^2.16.4" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/transformer-svg": { + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/transformer-svg/-/transformer-svg-2.16.4.tgz", + "integrity": "sha512-0dm4cQr/WpfQP6N0xjFtwdLTxcONDfoLgTOMk4eNUWydHipSgmLtvUk/nOc/FWkwztRScfAObtZXOiPOd3Oy9A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/diagnostic": "2.16.4", + "@parcel/plugin": "2.16.4", + "@parcel/rust": "2.16.4" + }, + "engines": { + "node": ">= 16.0.0", + "parcel": "^2.16.4" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/types": { + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/types/-/types-2.16.4.tgz", + "integrity": "sha512-ctx4mBskZHXeDVHg4OjMwx18jfYH9BzI/7yqbDQVGvd5lyA+/oVVzYdpele2J2i2sSaJ87cA8nb57GDQ8kHAqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/types-internal": "2.16.4", + "@parcel/workers": "2.16.4" + } + }, + "node_modules/@parcel/types-internal": { + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/types-internal/-/types-internal-2.16.4.tgz", + "integrity": "sha512-PE6Qmt5cjzBxX+6MPLiF7r+twoC+V9Skt3zyuBQ+H1c0i9o07Bbz2NKX10nvlPukfmW6Fu/1RvTLkzBZR1bU6A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/diagnostic": "2.16.4", + "@parcel/feature-flags": "2.16.4", + "@parcel/source-map": "^2.1.1", + "utility-types": "^3.11.0" + } + }, + "node_modules/@parcel/utils": { + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/utils/-/utils-2.16.4.tgz", + "integrity": "sha512-lkmxQHcHyOWZLbV8t+h2CGZIkPiBurLm/TS5wNT7+tq0qt9KbVwL7FP2K93TbXhLMGTmpI79Bf3qKniPM167Mw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/codeframe": "2.16.4", + "@parcel/diagnostic": "2.16.4", + "@parcel/logger": "2.16.4", + "@parcel/markdown-ansi": "2.16.4", + "@parcel/rust": "2.16.4", + "@parcel/source-map": "^2.1.1", + "chalk": "^4.1.2", + "nullthrows": "^1.1.1" + }, + "engines": { + "node": ">= 16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher": { + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.5.6.tgz", + "integrity": "sha512-tmmZ3lQxAe/k/+rNnXQRawJ4NjxO2hqiOLTHvWchtGZULp4RyFeh6aU4XdOYBFe2KE1oShQTv4AblOs2iOrNnQ==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "detect-libc": "^2.0.3", + "is-glob": "^4.0.3", + "node-addon-api": "^7.0.0", + "picomatch": "^4.0.3" + }, + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "@parcel/watcher-android-arm64": "2.5.6", + "@parcel/watcher-darwin-arm64": "2.5.6", + "@parcel/watcher-darwin-x64": "2.5.6", + "@parcel/watcher-freebsd-x64": "2.5.6", + "@parcel/watcher-linux-arm-glibc": "2.5.6", + "@parcel/watcher-linux-arm-musl": "2.5.6", + "@parcel/watcher-linux-arm64-glibc": "2.5.6", + "@parcel/watcher-linux-arm64-musl": "2.5.6", + "@parcel/watcher-linux-x64-glibc": "2.5.6", + "@parcel/watcher-linux-x64-musl": "2.5.6", + "@parcel/watcher-win32-arm64": "2.5.6", + "@parcel/watcher-win32-ia32": "2.5.6", + "@parcel/watcher-win32-x64": "2.5.6" + } + }, + "node_modules/@parcel/watcher-android-arm64": { + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.5.6.tgz", + "integrity": "sha512-YQxSS34tPF/6ZG7r/Ih9xy+kP/WwediEUsqmtf0cuCV5TPPKw/PQHRhueUo6JdeFJaqV3pyjm0GdYjZotbRt/A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-darwin-arm64": { + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.5.6.tgz", + "integrity": "sha512-Z2ZdrnwyXvvvdtRHLmM4knydIdU9adO3D4n/0cVipF3rRiwP+3/sfzpAwA/qKFL6i1ModaabkU7IbpeMBgiVEA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-darwin-x64": { + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-x64/-/watcher-darwin-x64-2.5.6.tgz", + "integrity": "sha512-HgvOf3W9dhithcwOWX9uDZyn1lW9R+7tPZ4sug+NGrGIo4Rk1hAXLEbcH1TQSqxts0NYXXlOWqVpvS1SFS4fRg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-freebsd-x64": { + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/@parcel/watcher-freebsd-x64/-/watcher-freebsd-x64-2.5.6.tgz", + "integrity": "sha512-vJVi8yd/qzJxEKHkeemh7w3YAn6RJCtYlE4HPMoVnCpIXEzSrxErBW5SJBgKLbXU3WdIpkjBTeUNtyBVn8TRng==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm-glibc": { + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-glibc/-/watcher-linux-arm-glibc-2.5.6.tgz", + "integrity": "sha512-9JiYfB6h6BgV50CCfasfLf/uvOcJskMSwcdH1PHH9rvS1IrNy8zad6IUVPVUfmXr+u+Km9IxcfMLzgdOudz9EQ==", + "cpu": [ + "arm" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm-musl": { + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-musl/-/watcher-linux-arm-musl-2.5.6.tgz", + "integrity": "sha512-Ve3gUCG57nuUUSyjBq/MAM0CzArtuIOxsBdQ+ftz6ho8n7s1i9E1Nmk/xmP323r2YL0SONs1EuwqBp2u1k5fxg==", + "cpu": [ + "arm" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm64-glibc": { + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-glibc/-/watcher-linux-arm64-glibc-2.5.6.tgz", + "integrity": "sha512-f2g/DT3NhGPdBmMWYoxixqYr3v/UXcmLOYy16Bx0TM20Tchduwr4EaCbmxh1321TABqPGDpS8D/ggOTaljijOA==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm64-musl": { + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-musl/-/watcher-linux-arm64-musl-2.5.6.tgz", + "integrity": "sha512-qb6naMDGlbCwdhLj6hgoVKJl2odL34z2sqkC7Z6kzir8b5W65WYDpLB6R06KabvZdgoHI/zxke4b3zR0wAbDTA==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-x64-glibc": { + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-glibc/-/watcher-linux-x64-glibc-2.5.6.tgz", + "integrity": "sha512-kbT5wvNQlx7NaGjzPFu8nVIW1rWqV780O7ZtkjuWaPUgpv2NMFpjYERVi0UYj1msZNyCzGlaCWEtzc+exjMGbQ==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-x64-musl": { + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-musl/-/watcher-linux-x64-musl-2.5.6.tgz", + "integrity": "sha512-1JRFeC+h7RdXwldHzTsmdtYR/Ku8SylLgTU/reMuqdVD7CtLwf0VR1FqeprZ0eHQkO0vqsbvFLXUmYm/uNKJBg==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-win32-arm64": { + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-arm64/-/watcher-win32-arm64-2.5.6.tgz", + "integrity": "sha512-3ukyebjc6eGlw9yRt678DxVF7rjXatWiHvTXqphZLvo7aC5NdEgFufVwjFfY51ijYEWpXbqF5jtrK275z52D4Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-win32-ia32": { + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-ia32/-/watcher-win32-ia32-2.5.6.tgz", + "integrity": "sha512-k35yLp1ZMwwee3Ez/pxBi5cf4AoBKYXj00CZ80jUz5h8prpiaQsiRPKQMxoLstNuqe2vR4RNPEAEcjEFzhEz/g==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-win32-x64": { + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-x64/-/watcher-win32-x64-2.5.6.tgz", + "integrity": "sha512-hbQlYcCq5dlAX9Qx+kFb0FHue6vbjlf0FrNzSKdYK2APUf7tGfGxQCk2ihEREmbR6ZMc0MVAD5RIX/41gpUzTw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher/node_modules/detect-libc": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", + "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=8" + } + }, + "node_modules/@parcel/workers": { + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/workers/-/workers-2.16.4.tgz", + "integrity": "sha512-dkBEWqnHXDZnRbTZouNt4uEGIslJT+V0c8OH1MPOfjISp1ucD6/u9ET8k9d/PxS9h1hL53og0SpBuuSEPLDl6A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/diagnostic": "2.16.4", + "@parcel/logger": "2.16.4", + "@parcel/profiler": "2.16.4", + "@parcel/types-internal": "2.16.4", + "@parcel/utils": "2.16.4", + "nullthrows": "^1.1.1" + }, + "engines": { + "node": ">= 16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "peerDependencies": { + "@parcel/core": "^2.16.4" + } + }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/@popperjs/core": { + "version": "2.11.8", + "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz", + "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/popperjs" + } + }, + "node_modules/@rollup/pluginutils": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.4.0.tgz", + "integrity": "sha512-MfPp06CjRLfXQ3wY0R8vJDYBy/MvVcc9OulEfR0B8Iv9ko+GCNaRZ+EpJYFl27LhKsZK0o420sYCRHCjfCgeUg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "estree-walker": "^2.0.2", + "picomatch": "^4.0.2" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@sidvind/better-ajv-errors": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@sidvind/better-ajv-errors/-/better-ajv-errors-2.1.3.tgz", + "integrity": "sha512-lWuod/rh7Xz5uXiEGSfm2Sd5PG7K/6yJfoAZVqzsEswjPJhUz15R7Gn/o8RczA041QS15hBd/BCSeu9vwPArkA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@babel/code-frame": "^7.16.0", + "chalk": "^4.1.0" + }, + "engines": { + "node": ">= 16.14" + }, + "peerDependencies": { + "ajv": "4.11.8 - 8" + } + }, + "node_modules/@swc/core": { + "version": "1.15.43", + "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.15.43.tgz", + "integrity": "sha512-1CuKjFkPxIgGdeHVuNbkxmBxkcbdc08u0aiI43pFq6yY1tTVKmXT9hFEooyyKs/sJ3xf1GPHyEwTtk9Xl8dvQw==", + "dev": true, + "hasInstallScript": true, + "license": "Apache-2.0", + "dependencies": { + "@swc/counter": "^0.1.3", + "@swc/types": "^0.1.27" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/swc" + }, + "optionalDependencies": { + "@swc/core-darwin-arm64": "1.15.43", + "@swc/core-darwin-x64": "1.15.43", + "@swc/core-linux-arm-gnueabihf": "1.15.43", + "@swc/core-linux-arm64-gnu": "1.15.43", + "@swc/core-linux-arm64-musl": "1.15.43", + "@swc/core-linux-ppc64-gnu": "1.15.43", + "@swc/core-linux-s390x-gnu": "1.15.43", + "@swc/core-linux-x64-gnu": "1.15.43", + "@swc/core-linux-x64-musl": "1.15.43", + "@swc/core-win32-arm64-msvc": "1.15.43", + "@swc/core-win32-ia32-msvc": "1.15.43", + "@swc/core-win32-x64-msvc": "1.15.43" + }, + "peerDependencies": { + "@swc/helpers": ">=0.5.17" + }, + "peerDependenciesMeta": { + "@swc/helpers": { + "optional": true + } + } + }, + "node_modules/@swc/core-darwin-arm64": { + "version": "1.15.43", + "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.15.43.tgz", + "integrity": "sha512-v1aVuvXdo/BHxJzco9V2xpHrvwWmhfS8t6gziY5wJxd+Z2h8AeJRnAwPD8itCDaGXVBwJ/CaKfxEzTkG0Va0OA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-darwin-x64": { + "version": "1.15.43", + "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.15.43.tgz", + "integrity": "sha512-lp3d4Lamc8dt5huYdGLSR+9hLxmfr1jb0l+4XXG2zPqZwYWRN9R0U2qYoTrggiU2RWW0oV9VbWM3kBnqIc2kdQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-arm-gnueabihf": { + "version": "1.15.43", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.15.43.tgz", + "integrity": "sha512-JWTQQELtsG5GgphDrr/XqqmM2pDN3cZqbMS0Mrg+iTiXL3F74sn/S2IyYE/5u4h2KLkTf9qQ7dXyxsbx7YzkeA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-arm64-gnu": { + "version": "1.15.43", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.15.43.tgz", + "integrity": "sha512-B4otJRdPWIsmiSBf0uG7Z/+vMWmkufjz5MmYxubwKuZazDW14Zd3symga1N62QR4RT+kEFeHEgsXfZGyn/w0hw==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-arm64-musl": { + "version": "1.15.43", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.15.43.tgz", + "integrity": "sha512-6zB6OnpViBxYy4tgY3v2i6AZY9fwkcHZ032UOwtwUuW1d19sdT07qF0kZe6/3UR1tUaK6jjg2rmVcUIBCEYVjQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-ppc64-gnu": { + "version": "1.15.43", + "resolved": "https://registry.npmjs.org/@swc/core-linux-ppc64-gnu/-/core-linux-ppc64-gnu-1.15.43.tgz", + "integrity": "sha512-coxE1ZWdB3uSDVNoEtYNrRi/1epvckZx9cTJ8ICUxTMTxGk+yvQ/Twacp3ruZSaMPGCriUjP86C37VhaT6nyRg==", + "cpu": [ + "ppc64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-s390x-gnu": { + "version": "1.15.43", + "resolved": "https://registry.npmjs.org/@swc/core-linux-s390x-gnu/-/core-linux-s390x-gnu-1.15.43.tgz", + "integrity": "sha512-lXfLhs+LpBsD5inuYx+YDH5WsPPBQ95KPUiy8P5wq9ob9xKDZFqwNfU2QW6bGO8NqRO/H9JQomTSt5Yyh+FGfA==", + "cpu": [ + "s390x" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-x64-gnu": { + "version": "1.15.43", + "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.15.43.tgz", + "integrity": "sha512-07XnKwTmKy8TGOZG3D9fRnLWGynxPjwQnZLVmBFbo6F+7vHYzBIOuwXEhemrChBWb6yDNZsVCcMWCPX6FDD2xg==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-x64-musl": { + "version": "1.15.43", + "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.15.43.tgz", + "integrity": "sha512-TJc+bsSIaBh+hZvZ5GRtW/K1bw66TJ9vsUwvVIsZdiWxU5ObLwZvfcnZ3UpgVfMnFibRes9uriJrQNBHEEogRQ==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-win32-arm64-msvc": { + "version": "1.15.43", + "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.15.43.tgz", + "integrity": "sha512-jfd7s2/bUQYkOHLs+LWQNKZdmDa8+sufKLllhpWAhVQ2GDCwsHe3vR/j+OSiItZNtkzFuaawa3+SAKz9y5gYfw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-win32-ia32-msvc": { + "version": "1.15.43", + "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.15.43.tgz", + "integrity": "sha512-rLAE8JvucqEW1ZGohxPQrQWPBQeJG4+ypKbWfdlU/qmKScvCkxf9/Jxnzki1dkUQCQ7P5Enp13RlvqOlvx/32g==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-win32-x64-msvc": { + "version": "1.15.43", + "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.15.43.tgz", + "integrity": "sha512-h8MLDHZcfIukwQWj03rIJZx1I0E81AYj2X7J/nGErG4nz+QAv6G1Z+peotvinL3lqpbo32tLYSMFo32/ySzxKg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/counter": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@swc/counter/-/counter-0.1.3.tgz", + "integrity": "sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/@swc/helpers": { + "version": "0.5.23", + "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.23.tgz", + "integrity": "sha512-5lSsMOTXURePglDfvuAQUqkGek9Hg2kksOYay2m0+XR++b2NWYL/4sWyuvVBIs8oKnJaxkdi9whaL/sqN13afw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.8.0" + } + }, + "node_modules/@swc/types": { + "version": "0.1.27", + "resolved": "https://registry.npmjs.org/@swc/types/-/types-0.1.27.tgz", + "integrity": "sha512-K6h3iUlqeM946U4sXFYeahefR1YBbXJvko+hv8WS8/0BNJ4OHiHRywMnQUJCqkR7Y9+hqQ1TvEpiKqUhz7NEFg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@swc/counter": "^0.1.3" + } + }, + "node_modules/@twuni/emojify": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@twuni/emojify/-/emojify-1.0.2.tgz", + "integrity": "sha512-glI5e+K7HFdJ7ntwdDsVW3hneMxt2+FoTisphorL+3SXpYvRQ0CV2wIMsdzAp+SotBK6ONkRLTiGy+8SN86eHg==", + "license": "MIT" + }, + "node_modules/@types/estree": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.9.tgz", + "integrity": "sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/hammerjs": { + "version": "2.0.46", + "resolved": "https://registry.npmjs.org/@types/hammerjs/-/hammerjs-2.0.46.tgz", + "integrity": "sha512-ynRvcq6wvqexJ9brDMS4BnBLzmr0e14d6ZJTEShTBWKymQiHwlAyGu0ZPEFI2Fh1U53F7tN9ufClWM5KvqkKOw==", + "license": "MIT" + }, + "node_modules/@types/istanbul-lib-coverage": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", + "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/katex": { + "version": "0.16.8", + "resolved": "https://registry.npmjs.org/@types/katex/-/katex-0.16.8.tgz", + "integrity": "sha512-trgaNyfU+Xh2Tc+ABIb44a5AYUpicB3uwirOioeOkNPPbmgRNtcWyDeeFRzjPZENO9Vq8gvVqfhaaXWLlevVwg==", + "license": "MIT" + }, + "node_modules/@types/lodash": { + "version": "4.17.24", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.24.tgz", + "integrity": "sha512-gIW7lQLZbue7lRSWEFql49QJJWThrTFFeIMJdp3eH4tKoxm1OvEPg02rm4wCCSHS0cL3/Fizimb35b7k8atwsQ==", + "license": "MIT" + }, + "node_modules/@types/lodash-es": { + "version": "4.17.12", + "resolved": "https://registry.npmjs.org/@types/lodash-es/-/lodash-es-4.17.12.tgz", + "integrity": "sha512-0NgftHUcV4v34VhXm8QBSftKVXtbkBG3ViCjs6+eJ5a6y6Mi/jiFGPc1sC7QK+9BFhWrURE3EOggmWaSxL9OzQ==", + "license": "MIT", + "dependencies": { + "@types/lodash": "*" + } + }, + "node_modules/@vitejs/plugin-vue": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-4.6.2.tgz", + "integrity": "sha512-kqf7SGFoG+80aZG6Pf+gsZIVvGSCKE98JbiWqcCV9cThtg91Jav0yvYFC9Zb+jKetNGF6ZKeoaxgZfND21fWKw==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "peerDependencies": { + "vite": "^4.0.0 || ^5.0.0", + "vue": "^3.2.25" + } + }, + "node_modules/@volar/language-core": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/@volar/language-core/-/language-core-2.1.6.tgz", + "integrity": "sha512-pAlMCGX/HatBSiDFMdMyqUshkbwWbLxpN/RL7HCQDOo2gYBE+uS+nanosLc1qR6pTQ/U8q00xt8bdrrAFPSC0A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@volar/source-map": "2.1.6" + } + }, + "node_modules/@volar/language-service": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/@volar/language-service/-/language-service-2.1.6.tgz", + "integrity": "sha512-1OpbbPQ6wUIumwMP5r45y8utVEmvq1n6BC8JHqGKsuFr9RGFIldDBlvA/xuO3MDKhjmmPGPHKb54kg1/YN78ow==", + "dev": true, + "license": "MIT", + "dependencies": { + "@volar/language-core": "2.1.6", + "vscode-languageserver-protocol": "^3.17.5", + "vscode-languageserver-textdocument": "^1.0.11", + "vscode-uri": "^3.0.8" + } + }, + "node_modules/@volar/source-map": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/@volar/source-map/-/source-map-2.1.6.tgz", + "integrity": "sha512-TeyH8pHHonRCHYI91J7fWUoxi0zWV8whZTVRlsWHSYfjm58Blalkf9LrZ+pj6OiverPTmrHRkBsG17ScQyWECw==", + "dev": true, + "license": "MIT", + "dependencies": { + "muggle-string": "^0.4.0" + } + }, + "node_modules/@vscode/l10n": { + "version": "0.0.18", + "resolved": "https://registry.npmjs.org/@vscode/l10n/-/l10n-0.0.18.tgz", + "integrity": "sha512-KYSIHVmslkaCDyw013pphY+d7x1qV8IZupYfeIfzNA+nsaWHbn5uPuQRvdRFsa9zFzGeudPuoGoZ1Op4jrJXIQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@vue/compiler-core": { + "version": "3.4.21", + "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.4.21.tgz", + "integrity": "sha512-MjXawxZf2SbZszLPYxaFCjxfibYrzr3eYbKxwpLR9EQN+oaziSu3qKVbwBERj1IFIB8OLUewxB5m/BFzi613og==", + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.23.9", + "@vue/shared": "3.4.21", + "entities": "^4.5.0", + "estree-walker": "^2.0.2", + "source-map-js": "^1.0.2" + } + }, + "node_modules/@vue/compiler-core/node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/@vue/compiler-dom": { + "version": "3.4.21", + "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.4.21.tgz", + "integrity": "sha512-IZC6FKowtT1sl0CR5DpXSiEB5ayw75oT2bma1BEhV7RRR1+cfwLrxc2Z8Zq/RGFzJ8w5r9QtCOvTjQgdn0IKmA==", + "license": "MIT", + "dependencies": { + "@vue/compiler-core": "3.4.21", + "@vue/shared": "3.4.21" + } + }, + "node_modules/@vue/compiler-sfc": { + "version": "3.4.21", + "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.4.21.tgz", + "integrity": "sha512-me7epoTxYlY+2CUM7hy9PCDdpMPfIwrOvAXud2Upk10g4YLv9UBW7kL798TvMeDhPthkZ0CONNrK2GoeI1ODiQ==", + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.23.9", + "@vue/compiler-core": "3.4.21", + "@vue/compiler-dom": "3.4.21", + "@vue/compiler-ssr": "3.4.21", + "@vue/shared": "3.4.21", + "estree-walker": "^2.0.2", + "magic-string": "^0.30.7", + "postcss": "^8.4.35", + "source-map-js": "^1.0.2" + } + }, + "node_modules/@vue/compiler-ssr": { + "version": "3.4.21", + "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.4.21.tgz", + "integrity": "sha512-M5+9nI2lPpAsgXOGQobnIueVqc9sisBFexh5yMIMRAPYLa7+5wEJs8iqOZc1WAa9WQbx9GR2twgznU8LTIiZ4Q==", + "license": "MIT", + "dependencies": { + "@vue/compiler-dom": "3.4.21", + "@vue/shared": "3.4.21" + } + }, + "node_modules/@vue/devtools-api": { + "version": "6.6.4", + "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-6.6.4.tgz", + "integrity": "sha512-sGhTPMuXqZ1rVOk32RylztWkfXTRhuS7vgAKv0zjqk8gbsHkJ7xfFf+jbySxt7tWObEJwyKaHMikV/WGDiQm8g==", + "license": "MIT" + }, + "node_modules/@vue/language-plugin-pug": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/@vue/language-plugin-pug/-/language-plugin-pug-2.0.7.tgz", + "integrity": "sha512-detpd6/uoz4cry1Kaal4Ho5bFdDTxjlye+xGX/yPOnNLqg94YLZymKP17/MpDUD7QgtiWOCLNUqFAuC1ovId1A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@volar/source-map": "~2.1.3", + "volar-service-pug": "0.0.34" + } + }, + "node_modules/@vue/reactivity": { + "version": "3.4.21", + "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.4.21.tgz", + "integrity": "sha512-UhenImdc0L0/4ahGCyEzc/pZNwVgcglGy9HVzJ1Bq2Mm9qXOpP8RyNTjookw/gOCUlXSEtuZ2fUg5nrHcoqJcw==", + "license": "MIT", + "dependencies": { + "@vue/shared": "3.4.21" + } + }, + "node_modules/@vue/runtime-core": { + "version": "3.4.21", + "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.4.21.tgz", + "integrity": "sha512-pQthsuYzE1XcGZznTKn73G0s14eCJcjaLvp3/DKeYWoFacD9glJoqlNBxt3W2c5S40t6CCcpPf+jG01N3ULyrA==", + "license": "MIT", + "dependencies": { + "@vue/reactivity": "3.4.21", + "@vue/shared": "3.4.21" + } + }, + "node_modules/@vue/runtime-dom": { + "version": "3.4.21", + "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.4.21.tgz", + "integrity": "sha512-gvf+C9cFpevsQxbkRBS1NpU8CqxKw0ebqMvLwcGQrNpx6gqRDodqKqA+A2VZZpQ9RpK2f9yfg8VbW/EpdFUOJw==", + "license": "MIT", + "dependencies": { + "@vue/runtime-core": "3.4.21", + "@vue/shared": "3.4.21", + "csstype": "^3.1.3" + } + }, + "node_modules/@vue/server-renderer": { + "version": "3.4.21", + "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.4.21.tgz", + "integrity": "sha512-aV1gXyKSN6Rz+6kZ6kr5+Ll14YzmIbeuWe7ryJl5muJ4uwSwY/aStXTixx76TwkZFJLm1aAlA/HSWEJ4EyiMkg==", + "license": "MIT", + "dependencies": { + "@vue/compiler-ssr": "3.4.21", + "@vue/shared": "3.4.21" + }, + "peerDependencies": { + "vue": "3.4.21" + } + }, + "node_modules/@vue/shared": { + "version": "3.4.21", + "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.4.21.tgz", + "integrity": "sha512-PuJe7vDIi6VYSinuEbUIQgMIRZGgM8e4R+G+/dQTk0X1NEdvgvvgv7m+rfmDH1gZzyA1OjjoWskvHlfRNfQf3g==", + "license": "MIT" + }, + "node_modules/ajv": { + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.15.0.tgz", + "integrity": "sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==", + "dev": true, + "license": "MIT" + }, + "node_modules/assert-never": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/assert-never/-/assert-never-1.4.0.tgz", + "integrity": "sha512-5oJg84os6NMQNl27T9LnZkvvqzvAnHu03ShCnoj6bsJwS7L8AO4lf+C/XjK/nvzEqQB744moC6V128RucQd1jA==", + "dev": true, + "license": "MIT" + }, + "node_modules/async-validator": { + "version": "4.2.5", + "resolved": "https://registry.npmjs.org/async-validator/-/async-validator-4.2.5.tgz", + "integrity": "sha512-7HhHjtERjqlNbZtqNqy2rckN/SpOOlmDliet+lP7k+eKZEjPk3DgyeU9lIXLdeLz0uBbbVp+9Qdow9wJWgwwfg==", + "license": "MIT" + }, + "node_modules/babel-walk": { + "version": "3.0.0-canary-5", + "resolved": "https://registry.npmjs.org/babel-walk/-/babel-walk-3.0.0-canary-5.tgz", + "integrity": "sha512-GAwkz0AihzY5bkwIY5QDR+LvsRQgB/B+1foMPvi0FZPMl5fjD7ICiznUiBdLYMH1QYe6vqu4gWYytZOccLouFw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.9.6" + }, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/base-x": { + "version": "3.0.11", + "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.11.tgz", + "integrity": "sha512-xz7wQ8xDhdyP7tQxwdteLYeFfS68tSMNCZ/Y37WJ4bhGfKPpqEIlmIyueQHqOyoPhE6xNUqjzRr8ra0eF9VRvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "^5.0.1" + } + }, + "node_modules/baseline-browser-mapping": { + "version": "2.10.42", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.42.tgz", + "integrity": "sha512-c/jurFrDLyui7o1J86yLkRu4LMsTYcBohveus7/I2Hzdn9KIP2bdJPTue/lR1KH46enoPbD77GKeSYNdyPoD3Q==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "baseline-browser-mapping": "dist/cli.cjs" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/bootstrap": { + "version": "5.3.8", + "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-5.3.8.tgz", + "integrity": "sha512-HP1SZDqaLDPwsNiqRqi5NcP0SSXciX2s9E+RyqJIIqGo+vJeN5AJVM98CXmW/Wux0nQ5L7jeWUdplCEf0Ee+tg==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/twbs" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/bootstrap" + } + ], + "license": "MIT", + "peerDependencies": { + "@popperjs/core": "^2.11.8" + } + }, + "node_modules/bootstrap-icons": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/bootstrap-icons/-/bootstrap-icons-1.13.1.tgz", + "integrity": "sha512-ijombt4v6bv5CLeXvRWKy7CuM3TRTuPEuGaGKvTV5cz65rQSY8RQ2JcHt6b90cBBAC7s8fsf2EkQDldzCoXUjw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/twbs" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/bootstrap" + } + ], + "license": "MIT" + }, + "node_modules/brace-expansion": { + "version": "1.1.16", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.16.tgz", + "integrity": "sha512-IDw48K2/2kRkg9LdJxurvq3lV3aBgq0REY89duEqFRthjlPdXHKMj7EnQOXVckxzgisinf3nHfrcE2FufFLXMw==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/browser-fs-access": { + "version": "0.38.0", + "resolved": "https://registry.npmjs.org/browser-fs-access/-/browser-fs-access-0.38.0.tgz", + "integrity": "sha512-JveqW2w6pEZqFEEfMgCszXzYpE89dG+nPsmOdcs741mFFAROeL+iqjGEpR07RI+s0YY0EFr+4KnOoACprJTpOw==", + "license": "Apache-2.0" + }, + "node_modules/browserlist": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/browserlist/-/browserlist-1.0.2.tgz", + "integrity": "sha512-welJSH1jwS/TcyCd/XZ9vj/2ijgDNEbcrS7YCjIB0Tc1sfFnfK9c80xCbTy/kY3oCqWWPHtBNQpVuPu55ErNEw==", + "dev": true, + "license": "MIT", + "bin": { + "browserlist": "cli.js" + } + }, + "node_modules/browserslist": { + "version": "4.28.5", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.5.tgz", + "integrity": "sha512-Cu2E6QejHWzuDMTkuwgpABFgDfZrXLQq5V13YOACZx4mFAG4IwGTbTfHPMr4WtxlHoXSM8FIuRwYYCz5XiabaQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "baseline-browser-mapping": "^2.10.42", + "caniuse-lite": "^1.0.30001800", + "electron-to-chromium": "^1.5.387", + "node-releases": "^2.0.50", + "update-browserslist-db": "^1.2.3" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/c8": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/c8/-/c8-9.1.0.tgz", + "integrity": "sha512-mBWcT5iqNir1zIkzSPyI3NCR9EZCVI3WUD+AVO17MVWTSFNyUueXE82qTeampNtTr+ilN/5Ua3j24LgbCKjDVg==", + "dev": true, + "license": "ISC", + "dependencies": { + "@bcoe/v8-coverage": "^0.2.3", + "@istanbuljs/schema": "^0.1.3", + "find-up": "^5.0.0", + "foreground-child": "^3.1.1", + "istanbul-lib-coverage": "^3.2.0", + "istanbul-lib-report": "^3.0.1", + "istanbul-reports": "^3.1.6", + "test-exclude": "^6.0.0", + "v8-to-istanbul": "^9.0.0", + "yargs": "^17.7.2", + "yargs-parser": "^21.1.1" + }, + "bin": { + "c8": "bin/c8.js" + }, + "engines": { + "node": ">=14.14.0" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001803", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001803.tgz", + "integrity": "sha512-g/uHREV2ZpK9qMalCsWaxmA6ol+DX8GYhuf3T40RKoP+oL7vhRJh8LNt73PCjpnR6l14FzfPrB5Yux4PKm2meg==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "CC-BY-4.0" + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/character-parser": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/character-parser/-/character-parser-2.2.0.tgz", + "integrity": "sha512-+UqJQjFEFaTAs3bNsF2j2kEN1baG/zghZbdqoYEDxGZtJo9LBzl1A+m0D4n3qKx8N2FNv8/Xp6yV9mQmBuptaw==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-regex": "^1.0.3" + } + }, + "node_modules/chart.js": { + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/chart.js/-/chart.js-4.5.1.tgz", + "integrity": "sha512-GIjfiT9dbmHRiYi6Nl2yFCq7kkwdkp1W/lp2J99rX0yo9tgJGn3lKQATztIjb5tVtevcBtIdICNWqlq5+E8/Pw==", + "license": "MIT", + "dependencies": { + "@kurkle/color": "^0.3.0" + }, + "engines": { + "pnpm": ">=8" + } + }, + "node_modules/chart.js/node_modules/@kurkle/color": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/@kurkle/color/-/color-0.3.4.tgz", + "integrity": "sha512-M5UknZPHRu3DEDWoipU6sE8PdkZ6Z/S+v4dD+Ke8IaNlpdSQah50lz1KtcFBa2vsdOnwbbnxJwVM4wty6udA5w==", + "license": "MIT" + }, + "node_modules/chartjs-plugin-autocolors": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/chartjs-plugin-autocolors/-/chartjs-plugin-autocolors-0.3.1.tgz", + "integrity": "sha512-8FHemt0Ef5BM7kQimh4eAkCRFPBav4seUFi7nEaShX+DjZMU9V4LqEDgXNglKbnYTTn3QmoG4v9gyiQDUAk9WQ==", + "license": "MIT", + "peerDependencies": { + "@kurkle/color": "^0.3.1", + "chart.js": ">=2" + } + }, + "node_modules/chartjs-plugin-zoom": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/chartjs-plugin-zoom/-/chartjs-plugin-zoom-2.2.0.tgz", + "integrity": "sha512-in6kcdiTlP6npIVLMd4zXZ08PDUXC52gZ4FAy5oyjk1zX3gKarXMAof7B9eFiisf9WOC3bh2saHg+J5WtLXZeA==", + "license": "MIT", + "dependencies": { + "@types/hammerjs": "^2.0.45", + "hammerjs": "^2.0.8" + }, + "peerDependencies": { + "chart.js": ">=3.2.0" + } + }, + "node_modules/chokidar": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-5.0.0.tgz", + "integrity": "sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw==", + "dev": true, + "license": "MIT", + "dependencies": { + "readdirp": "^5.0.0" + }, + "engines": { + "node": ">= 20.19.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/chrome-trace-event": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz", + "integrity": "sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0" + } + }, + "node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/cliui/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/cliui/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/clone": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", + "integrity": "sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/commander": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "license": "MIT", + "engines": { + "node": ">= 10" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true, + "license": "MIT" + }, + "node_modules/constantinople": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/constantinople/-/constantinople-4.0.1.tgz", + "integrity": "sha512-vCrqcSIq4//Gx74TXXCGnHpulY1dskqLTFGDmhrGxzeXL8lF8kvXv6mpNWlJj1uD4DW23D4ljAqbY4RRaaUZIw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.6.0", + "@babel/types": "^7.6.1" + } + }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true, + "license": "MIT" + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/css-render": { + "version": "0.15.14", + "resolved": "https://registry.npmjs.org/css-render/-/css-render-0.15.14.tgz", + "integrity": "sha512-9nF4PdUle+5ta4W5SyZdLCCmFd37uVimSjg1evcTqKJCyvCEEj12WKzOSBNak6r4im4J4iYXKH1OWpUV5LBYFg==", + "license": "MIT", + "dependencies": { + "@emotion/hash": "~0.8.0", + "csstype": "~3.0.5" + } + }, + "node_modules/css-render/node_modules/csstype": { + "version": "3.0.11", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.11.tgz", + "integrity": "sha512-sa6P2wJ+CAbgyy4KFssIb/JNMLxFvKF1pCYCSXS8ZMuqZnMsrxqI2E5sPyoTpxoPU/gVZMzr2zjOfg8GIZOMsw==", + "license": "MIT" + }, + "node_modules/csstype": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz", + "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==", + "license": "MIT" + }, + "node_modules/d3": { + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/d3/-/d3-7.9.0.tgz", + "integrity": "sha512-e1U46jVP+w7Iut8Jt8ri1YsPOvFpg46k+K8TpCb0P+zjCkjkPnV7WzfDJzMHy1LnA+wj5pLT1wjO901gLXeEhA==", + "license": "ISC", + "dependencies": { + "d3-array": "3", + "d3-axis": "3", + "d3-brush": "3", + "d3-chord": "3", + "d3-color": "3", + "d3-contour": "4", + "d3-delaunay": "6", + "d3-dispatch": "3", + "d3-drag": "3", + "d3-dsv": "3", + "d3-ease": "3", + "d3-fetch": "3", + "d3-force": "3", + "d3-format": "3", + "d3-geo": "3", + "d3-hierarchy": "3", + "d3-interpolate": "3", + "d3-path": "3", + "d3-polygon": "3", + "d3-quadtree": "3", + "d3-random": "3", + "d3-scale": "4", + "d3-scale-chromatic": "3", + "d3-selection": "3", + "d3-shape": "3", + "d3-time": "3", + "d3-time-format": "4", + "d3-timer": "3", + "d3-transition": "3", + "d3-zoom": "3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-array": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-3.2.4.tgz", + "integrity": "sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==", + "license": "ISC", + "dependencies": { + "internmap": "1 - 2" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-axis": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-axis/-/d3-axis-3.0.0.tgz", + "integrity": "sha512-IH5tgjV4jE/GhHkRV0HiVYPDtvfjHQlQfJHs0usq7M30XcSBvOotpmH1IgkcXsO/5gEQZD43B//fc7SRT5S+xw==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-brush": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-brush/-/d3-brush-3.0.0.tgz", + "integrity": "sha512-ALnjWlVYkXsVIGlOsuWH1+3udkYFI48Ljihfnh8FZPF2QS9o+PzGLBslO0PjzVoHLZ2KCVgAM8NVkXPJB2aNnQ==", + "license": "ISC", + "dependencies": { + "d3-dispatch": "1 - 3", + "d3-drag": "2 - 3", + "d3-interpolate": "1 - 3", + "d3-selection": "3", + "d3-transition": "3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-chord": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-chord/-/d3-chord-3.0.1.tgz", + "integrity": "sha512-VE5S6TNa+j8msksl7HwjxMHDM2yNK3XCkusIlpX5kwauBfXuyLAtNg9jCp/iHH61tgI4sb6R/EIMWCqEIdjT/g==", + "license": "ISC", + "dependencies": { + "d3-path": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-color": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-3.1.0.tgz", + "integrity": "sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-contour": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/d3-contour/-/d3-contour-4.0.2.tgz", + "integrity": "sha512-4EzFTRIikzs47RGmdxbeUvLWtGedDUNkTcmzoeyg4sP/dvCexO47AaQL7VKy/gul85TOxw+IBgA8US2xwbToNA==", + "license": "ISC", + "dependencies": { + "d3-array": "^3.2.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-delaunay": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/d3-delaunay/-/d3-delaunay-6.0.4.tgz", + "integrity": "sha512-mdjtIZ1XLAM8bm/hx3WwjfHt6Sggek7qH043O8KEjDXN40xi3vx/6pYSVTwLjEgiXQTbvaouWKynLBiUZ6SK6A==", + "license": "ISC", + "dependencies": { + "delaunator": "5" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-dispatch": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-3.0.1.tgz", + "integrity": "sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-drag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-drag/-/d3-drag-3.0.0.tgz", + "integrity": "sha512-pWbUJLdETVA8lQNJecMxoXfH6x+mO2UQo8rSmZ+QqxcbyA3hfeprFgIT//HW2nlHChWeIIMwS2Fq+gEARkhTkg==", + "license": "ISC", + "dependencies": { + "d3-dispatch": "1 - 3", + "d3-selection": "3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-dsv": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-dsv/-/d3-dsv-3.0.1.tgz", + "integrity": "sha512-UG6OvdI5afDIFP9w4G0mNq50dSOsXHJaRE8arAS5o9ApWnIElp8GZw1Dun8vP8OyHOZ/QJUKUJwxiiCCnUwm+Q==", + "license": "ISC", + "dependencies": { + "commander": "7", + "iconv-lite": "0.6", + "rw": "1" + }, + "bin": { + "csv2json": "bin/dsv2json.js", + "csv2tsv": "bin/dsv2dsv.js", + "dsv2dsv": "bin/dsv2dsv.js", + "dsv2json": "bin/dsv2json.js", + "json2csv": "bin/json2dsv.js", + "json2dsv": "bin/json2dsv.js", + "json2tsv": "bin/json2dsv.js", + "tsv2csv": "bin/dsv2dsv.js", + "tsv2json": "bin/dsv2json.js" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-ease": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-3.0.1.tgz", + "integrity": "sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-fetch": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-fetch/-/d3-fetch-3.0.1.tgz", + "integrity": "sha512-kpkQIM20n3oLVBKGg6oHrUchHM3xODkTzjMoj7aWQFq5QEM+R6E4WkzT5+tojDY7yjez8KgCBRoj4aEr99Fdqw==", + "license": "ISC", + "dependencies": { + "d3-dsv": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-force": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-force/-/d3-force-3.0.0.tgz", + "integrity": "sha512-zxV/SsA+U4yte8051P4ECydjD/S+qeYtnaIyAs9tgHCqfguma/aAQDjo85A9Z6EKhBirHRJHXIgJUlffT4wdLg==", + "license": "ISC", + "dependencies": { + "d3-dispatch": "1 - 3", + "d3-quadtree": "1 - 3", + "d3-timer": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-format": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-3.1.2.tgz", + "integrity": "sha512-AJDdYOdnyRDV5b6ArilzCPPwc1ejkHcoyFarqlPqT7zRYjhavcT3uSrqcMvsgh2CgoPbK3RCwyHaVyxYcP2Arg==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-geo": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/d3-geo/-/d3-geo-3.1.1.tgz", + "integrity": "sha512-637ln3gXKXOwhalDzinUgY83KzNWZRKbYubaG+fGVuc/dxO64RRljtCTnf5ecMyE1RIdtqpkVcq0IbtU2S8j2Q==", + "license": "ISC", + "dependencies": { + "d3-array": "2.5.0 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-hierarchy": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/d3-hierarchy/-/d3-hierarchy-3.1.2.tgz", + "integrity": "sha512-FX/9frcub54beBdugHjDCdikxThEqjnR93Qt7PvQTOHxyiNCAlvMrHhclk3cD5VeAaq9fxmfRp+CnWw9rEMBuA==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-interpolate": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-3.0.1.tgz", + "integrity": "sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==", + "license": "ISC", + "dependencies": { + "d3-color": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-path": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-3.1.0.tgz", + "integrity": "sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-polygon": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-polygon/-/d3-polygon-3.0.1.tgz", + "integrity": "sha512-3vbA7vXYwfe1SYhED++fPUQlWSYTTGmFmQiany/gdbiWgU/iEyQzyymwL9SkJjFFuCS4902BSzewVGsHHmHtXg==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-quadtree": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-quadtree/-/d3-quadtree-3.0.1.tgz", + "integrity": "sha512-04xDrxQTDTCFwP5H6hRhsRcb9xxv2RzkcsygFzmkSIOJy3PeRJP7sNk3VRIbKXcog561P9oU0/rVH6vDROAgUw==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-random": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-random/-/d3-random-3.0.1.tgz", + "integrity": "sha512-FXMe9GfxTxqd5D6jFsQ+DJ8BJS4E/fT5mqqdjovykEB2oFbTMDVdg1MGFxfQW+FBOGoB++k8swBrgwSHT1cUXQ==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-scale": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-4.0.2.tgz", + "integrity": "sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==", + "license": "ISC", + "dependencies": { + "d3-array": "2.10.0 - 3", + "d3-format": "1 - 3", + "d3-interpolate": "1.2.0 - 3", + "d3-time": "2.1.1 - 3", + "d3-time-format": "2 - 4" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-scale-chromatic": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-scale-chromatic/-/d3-scale-chromatic-3.1.0.tgz", + "integrity": "sha512-A3s5PWiZ9YCXFye1o246KoscMWqf8BsD9eRiJ3He7C9OBaxKhAd5TFCdEx/7VbKtxxTsu//1mMJFrEt572cEyQ==", + "license": "ISC", + "dependencies": { + "d3-color": "1 - 3", + "d3-interpolate": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-selection": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-3.0.0.tgz", + "integrity": "sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-shape": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-3.2.0.tgz", + "integrity": "sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==", + "license": "ISC", + "dependencies": { + "d3-path": "^3.1.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-time": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-3.1.0.tgz", + "integrity": "sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==", + "license": "ISC", + "dependencies": { + "d3-array": "2 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-time-format": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-4.1.0.tgz", + "integrity": "sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==", + "license": "ISC", + "dependencies": { + "d3-time": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-timer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-3.0.1.tgz", + "integrity": "sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-transition": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-transition/-/d3-transition-3.0.1.tgz", + "integrity": "sha512-ApKvfjsSR6tg06xrL434C0WydLr7JewBB3V+/39RMHsaXTOG0zmt/OAXeng5M5LBm0ojmxJrpomQVZ1aPvBL4w==", + "license": "ISC", + "dependencies": { + "d3-color": "1 - 3", + "d3-dispatch": "1 - 3", + "d3-ease": "1 - 3", + "d3-interpolate": "1 - 3", + "d3-timer": "1 - 3" + }, + "engines": { + "node": ">=12" + }, + "peerDependencies": { + "d3-selection": "2 - 3" + } + }, + "node_modules/d3-zoom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-zoom/-/d3-zoom-3.0.0.tgz", + "integrity": "sha512-b8AmV3kfQaqWAuacbPuNbL6vahnOJflOhexLzMMNLga62+/nh0JzvJ0aO/5a5MVgUFGS7Hu1P9P03o3fJkDCyw==", + "license": "ISC", + "dependencies": { + "d3-dispatch": "1 - 3", + "d3-drag": "2 - 3", + "d3-interpolate": "1 - 3", + "d3-selection": "2 - 3", + "d3-transition": "2 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/date-fns": { + "version": "2.30.0", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.30.0.tgz", + "integrity": "sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.21.0" + }, + "engines": { + "node": ">=0.11" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/date-fns" + } + }, + "node_modules/date-fns-tz": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/date-fns-tz/-/date-fns-tz-2.0.1.tgz", + "integrity": "sha512-fJCG3Pwx8HUoLhkepdsP7Z5RsucUi+ZBOxyM5d0ZZ6c4SdYustq0VMmOu6Wf7bli+yS/Jwp91TOCqn9jMcVrUA==", + "license": "MIT", + "peerDependencies": { + "date-fns": "2.x" + } + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/deepmerge": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/delaunator": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/delaunator/-/delaunator-5.1.0.tgz", + "integrity": "sha512-AGrQ4QSgssa1NGmWmLPqN5NY2KajF5MqxetNEO+o0n3ZwZZeTmt7bBnvzHWrmkZFxGgr4HdyFgelzgi06otLuQ==", + "license": "ISC", + "dependencies": { + "robust-predicates": "^3.0.2" + } + }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/detect-libc": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", + "integrity": "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "detect-libc": "bin/detect-libc.js" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/doctypes": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/doctypes/-/doctypes-1.1.0.tgz", + "integrity": "sha512-LLBi6pEqS6Do3EKQ3J0NqHWV5hhb78Pi8vvESYwyOy2c31ZEZVdtitdzsQsKb7878PEERhzUk0ftqGhG6Mz+pQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/dotenv": { + "version": "16.6.1", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.6.1.tgz", + "integrity": "sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, + "node_modules/dotenv-expand": { + "version": "11.0.7", + "resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-11.0.7.tgz", + "integrity": "sha512-zIHwmZPRshsCdpMDyVsqGmgyP0yT8GAgXUnkdAoJisxvf33k7yO6OuoKmcTGuXPWSsm8Oh88nZicRLA9Y0rUeA==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "dotenv": "^16.4.5" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true, + "license": "MIT" + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", + "license": "MIT" + }, + "node_modules/electron-to-chromium": { + "version": "1.5.389", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.389.tgz", + "integrity": "sha512-cEto7aeOqBfU1D+c5py5pE+ooscKE75JifxLBdFUZsqAxRS6y7kebtxAZvICszSl05gPjYHDTjY+lXpyGvpJbg==", + "dev": true, + "license": "ISC" + }, + "node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true, + "license": "MIT" + }, + "node_modules/encodeurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.2.tgz", + "integrity": "sha512-HWcBoN6NileqtSydK2FqHbS/LoDd2pqrnQHLyJzBj4kOp/ky2MWMN694xOfkK8/SnUsW2DH7EfyVlydKCsm1Zw==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/esbuild": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.20.tgz", + "integrity": "sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/android-arm": "0.18.20", + "@esbuild/android-arm64": "0.18.20", + "@esbuild/android-x64": "0.18.20", + "@esbuild/darwin-arm64": "0.18.20", + "@esbuild/darwin-x64": "0.18.20", + "@esbuild/freebsd-arm64": "0.18.20", + "@esbuild/freebsd-x64": "0.18.20", + "@esbuild/linux-arm": "0.18.20", + "@esbuild/linux-arm64": "0.18.20", + "@esbuild/linux-ia32": "0.18.20", + "@esbuild/linux-loong64": "0.18.20", + "@esbuild/linux-mips64el": "0.18.20", + "@esbuild/linux-ppc64": "0.18.20", + "@esbuild/linux-riscv64": "0.18.20", + "@esbuild/linux-s390x": "0.18.20", + "@esbuild/linux-x64": "0.18.20", + "@esbuild/netbsd-x64": "0.18.20", + "@esbuild/openbsd-x64": "0.18.20", + "@esbuild/sunos-x64": "0.18.20", + "@esbuild/win32-arm64": "0.18.20", + "@esbuild/win32-ia32": "0.18.20", + "@esbuild/win32-x64": "0.18.20" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", + "license": "MIT" + }, + "node_modules/estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", + "license": "MIT" + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/evtd": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/evtd/-/evtd-0.2.4.tgz", + "integrity": "sha512-qaeGN5bx63s/AXgQo8gj6fBkxge+OoLddLniox5qtLAEY5HSnuSlISXVPxnSae1dWblvTh4/HoMIB+mbMsvZzw==", + "license": "MIT" + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/fast-uri": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.3.tgz", + "integrity": "sha512-i70LwGWUduXqzicKXWshooq+sWL1K3WUU5rKZNG/0i3a1OSoX3HqhH5WbWwTmqWfor4urUakGPiRQcleRZTwOg==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/file-saver": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/file-saver/-/file-saver-2.0.5.tgz", + "integrity": "sha512-P9bmyZ3h/PRG+Nzga+rbdI4OEpNDzAVyy74uVO9ATgzLK6VtAsYybF/+TOCvrc0MO793d6+42lLyZTw7/ArVzA==", + "license": "MIT" + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/foreground-child": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", + "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==", + "dev": true, + "license": "ISC", + "dependencies": { + "cross-spawn": "^7.0.6", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/fresh": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-2.0.0.tgz", + "integrity": "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true, + "license": "ISC" + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, + "license": "ISC", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-port": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/get-port/-/get-port-4.2.0.tgz", + "integrity": "sha512-/b3jarXkH8KJoOMQc3uVGHASwGLPq3gSFJ7tgJm2diza+bydJPTGOibin2steecKeOylE8oY2JERlVWkAJO6yw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/glob": { + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz", + "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==", + "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", + "dev": true, + "license": "ISC", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob/node_modules/brace-expansion": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.2.tgz", + "integrity": "sha512-w5JZcKgdhDOgOwm8H+KgbosopHMuGcl6qbulwjtz3SM7I7P3yW1eAjzMPLrIE+NQ9vjgANKHWeMHnrT0OXW1oA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/glob/node_modules/minimatch": { + "version": "9.0.9", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz", + "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.2" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/globals": { + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hammerjs": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/hammerjs/-/hammerjs-2.0.8.tgz", + "integrity": "sha512-tSQXBXS/MWQOn/RKckawJ61vvsDpCom87JgxiYdGwHdOa0ht0vzUWDlfioofFCRU0L+6NGDt6XzbgoJvZkMeRQ==", + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.4.tgz", + "integrity": "sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==", + "dev": true, + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/highcharts": { + "version": "11.4.0", + "resolved": "https://registry.npmjs.org/highcharts/-/highcharts-11.4.0.tgz", + "integrity": "sha512-f5POJz2WdHW6SNT4P2CoMjsgcX5F5sJXtdfWLQCaNP9JG0nG5TSGG7+A6vzHGzcDkTPM72EQbRQofNZHaRTUPg==", + "license": "https://www.highcharts.com/license" + }, + "node_modules/highlight.js": { + "version": "11.11.1", + "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-11.11.1.tgz", + "integrity": "sha512-Xwwo44whKBVCYoliBQwaPvtd/2tYFkRQtXDWj1nackaV2JPXx3L0+Jvd8/qCJ2p+ML0/XVkJ2q+Mr+UVdpJK5w==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "dev": true, + "license": "MIT" + }, + "node_modules/html-validate": { + "version": "8.18.1", + "resolved": "https://registry.npmjs.org/html-validate/-/html-validate-8.18.1.tgz", + "integrity": "sha512-6NYRciFBQhVZH29fwDQxofPil0qm7MMSEDzDpZWu2U23Fnmv1WTuompP7fbzHYj6+CIJ4T/Q4hyWRCe0CCrsMg==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/html-validate" + } + ], + "license": "MIT", + "workspaces": [ + "docs", + "tests/vitest" + ], + "dependencies": { + "@babel/code-frame": "^7.10.0", + "@html-validate/stylish": "^4.1.0", + "@sidvind/better-ajv-errors": "2.1.3", + "ajv": "^8.0.0", + "deepmerge": "4.3.1", + "glob": "^10.0.0", + "ignore": "5.3.1", + "kleur": "^4.1.0", + "minimist": "^1.2.0", + "prompts": "^2.0.0", + "semver": "^7.0.0" + }, + "bin": { + "html-validate": "bin/html-validate.js" + }, + "engines": { + "node": ">= 16.14" + }, + "peerDependencies": { + "jest": "^27.1 || ^28.1.3 || ^29.0.3", + "jest-diff": "^27.1 || ^28.1.3 || ^29.0.3", + "jest-snapshot": "^27.1 || ^28.1.3 || ^29.0.3", + "vitest": "^0.34 || ^1" + }, + "peerDependenciesMeta": { + "jest": { + "optional": true + }, + "jest-diff": { + "optional": true + }, + "jest-snapshot": { + "optional": true + }, + "vitest": { + "optional": true + } + } + }, + "node_modules/html-validate/node_modules/ajv": { + "version": "8.20.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.20.0.tgz", + "integrity": "sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/html-validate/node_modules/ignore": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", + "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/html-validate/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true, + "license": "MIT" + }, + "node_modules/http-errors": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz", + "integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==", + "license": "MIT", + "dependencies": { + "depd": "~2.0.0", + "inherits": "~2.0.4", + "setprototypeof": "~1.2.0", + "statuses": "~2.0.2", + "toidentifier": "~1.0.1" + }, + "engines": { + "node": ">= 0.8" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/ical.js": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/ical.js/-/ical.js-1.5.0.tgz", + "integrity": "sha512-7ZxMkogUkkaCx810yp0ZGKvq1ZpRgJeornPttpoxe6nYZ3NLesZe1wWMXDdwTkj/b5NtXT+Y16Aakph/ao98ZQ==", + "license": "MPL-2.0" + }, + "node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/immutable": { + "version": "5.1.9", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-5.1.9.tgz", + "integrity": "sha512-m8nVez3rwrgmWxtLMt1ZYXB2Lv7OKYn/disyxAlSDYAlKSlFoPPfIAmAM/M5xqL4m4C/wAPw7S2/CNaUii1Hxg==", + "dev": true, + "license": "MIT" + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", + "dev": true, + "license": "ISC", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "license": "ISC" + }, + "node_modules/internmap": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/internmap/-/internmap-2.0.3.tgz", + "integrity": "sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/is-core-module": { + "version": "2.16.2", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.2.tgz", + "integrity": "sha512-evOr8xfXKxE6qSR0hSXL2r3sd7ALj8+7jQEUvPYcm5sgZFdJ+AYzT6yNmJenvIYQBgIGwfwz08sL8zoL7yq2BA==", + "dev": true, + "license": "MIT", + "dependencies": { + "hasown": "^2.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-expression": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-expression/-/is-expression-4.0.0.tgz", + "integrity": "sha512-zMIXX63sxzG3XrkHkrAPvm/OVZVSCPNkwMHU8oTX7/U3AL78I0QXCEICXUM13BIa8TYGZ68PiTKfQz3yaTNr4A==", + "dev": true, + "license": "MIT", + "dependencies": { + "acorn": "^7.1.1", + "object-assign": "^4.1.1" + } + }, + "node_modules/is-expression/node_modules/acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-promise": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz", + "integrity": "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/is-regex": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz", + "integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/isbinaryfile": { + "version": "5.0.7", + "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-5.0.7.tgz", + "integrity": "sha512-gnWD14Jh3FzS3CPhF0AxNOJ8CxqeblPTADzI38r0wt8ZyQl5edpy75myt08EG2oKvpyiqSqsx+Wkz9vtkbTqYQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 18.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/gjtorikian/" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true, + "license": "ISC" + }, + "node_modules/istanbul-lib-coverage": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", + "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-report": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", + "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^4.0.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-reports": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.2.0.tgz", + "integrity": "sha512-HGYWWS/ehqTV3xN10i23tkPkpH46MLCIMFNCaaKNavAXTF1RkqxawEPtnjnGZ6XKSInBKkiOA5BKS+aZiY3AvA==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jackspeak": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, + "node_modules/jquery": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.7.1.tgz", + "integrity": "sha512-m4avr8yL8kmFN8psrbFFFmB/If14iN5o9nw/NgnnM+kybDJpRsAynV2BsfpTYrTRysYUdADVD7CkUUizgkpLfg==", + "license": "MIT" + }, + "node_modules/jquery-migrate": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/jquery-migrate/-/jquery-migrate-3.4.1.tgz", + "integrity": "sha512-6RaV23lLAYccu8MtLfy2sIxOvx+bulnWHm/pvffAi7KOzPk1sN9IYglpkl1ZNCj1FSgSNDPS2fSZ1hWsXc200Q==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "jquery": ">=3 <4" + } + }, + "node_modules/js-cookie": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/js-cookie/-/js-cookie-3.0.8.tgz", + "integrity": "sha512-yeJd4aNAdYZQjaon2bpD/Gb0B/omw7HQOsynXXcOiWVCacbBcPlgn8S/d1X6blFSaHao7ozqtW7NZW19xpCtIw==", + "license": "MIT" + }, + "node_modules/js-stringify": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/js-stringify/-/js-stringify-1.0.2.tgz", + "integrity": "sha512-rtS5ATOo2Q5k1G+DADISilDA6lv79zIiwFd6CcjuIxGKLFm5C+RLImRscVap9k55i+MOZwgliw+NejvkLuGD5g==", + "dev": true, + "license": "MIT" + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "license": "MIT", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/jstransformer": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/jstransformer/-/jstransformer-1.0.0.tgz", + "integrity": "sha512-C9YK3Rf8q6VAPDCCU9fnqo3mAfOH6vUGnMcP4AQAYIEpWtfGLpwOTmZ+igtdK5y+VvI2n3CyYSzy4Qh34eq24A==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-promise": "^2.0.0", + "promise": "^7.0.1" + } + }, + "node_modules/kleur": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz", + "integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/lightningcss": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.32.0.tgz", + "integrity": "sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "detect-libc": "^2.0.3" + }, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "lightningcss-android-arm64": "1.32.0", + "lightningcss-darwin-arm64": "1.32.0", + "lightningcss-darwin-x64": "1.32.0", + "lightningcss-freebsd-x64": "1.32.0", + "lightningcss-linux-arm-gnueabihf": "1.32.0", + "lightningcss-linux-arm64-gnu": "1.32.0", + "lightningcss-linux-arm64-musl": "1.32.0", + "lightningcss-linux-x64-gnu": "1.32.0", + "lightningcss-linux-x64-musl": "1.32.0", + "lightningcss-win32-arm64-msvc": "1.32.0", + "lightningcss-win32-x64-msvc": "1.32.0" + } + }, + "node_modules/lightningcss-android-arm64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.32.0.tgz", + "integrity": "sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-arm64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.32.0.tgz", + "integrity": "sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-x64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.32.0.tgz", + "integrity": "sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-freebsd-x64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.32.0.tgz", + "integrity": "sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm-gnueabihf": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.32.0.tgz", + "integrity": "sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-gnu": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.32.0.tgz", + "integrity": "sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-musl": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.32.0.tgz", + "integrity": "sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-gnu": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.32.0.tgz", + "integrity": "sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-musl": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.32.0.tgz", + "integrity": "sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-arm64-msvc": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.32.0.tgz", + "integrity": "sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-x64-msvc": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.32.0.tgz", + "integrity": "sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss/node_modules/detect-libc": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", + "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=8" + } + }, + "node_modules/list.js": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/list.js/-/list.js-2.3.1.tgz", + "integrity": "sha512-jnmm7DYpKtH3DxtO1E2VNCC9Gp7Wrp/FWA2JxQrZUhVJ2RCQBd57pCN6W5w6jpsfWZV0PCAbTX2NOPgyFeeZZg==", + "license": "MIT", + "dependencies": { + "string-natural-compare": "^2.0.2" + }, + "engines": { + "node": "^6.0 || ^8.0 || ^10.0 || ^12.0 || >=14" + } + }, + "node_modules/lmdb": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/lmdb/-/lmdb-2.8.5.tgz", + "integrity": "sha512-9bMdFfc80S+vSldBmG3HOuLVHnxRdNTlpzR6QDnzqCQtCzGUEAGTzBKYMeIM+I/sU4oZfgbcbS7X7F65/z/oxQ==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "msgpackr": "^1.9.5", + "node-addon-api": "^6.1.0", + "node-gyp-build-optional-packages": "5.1.1", + "ordered-binary": "^1.4.1", + "weak-lru-cache": "^1.2.2" + }, + "bin": { + "download-lmdb-prebuilds": "bin/download-prebuilds.js" + }, + "optionalDependencies": { + "@lmdb/lmdb-darwin-arm64": "2.8.5", + "@lmdb/lmdb-darwin-x64": "2.8.5", + "@lmdb/lmdb-linux-arm": "2.8.5", + "@lmdb/lmdb-linux-arm64": "2.8.5", + "@lmdb/lmdb-linux-x64": "2.8.5", + "@lmdb/lmdb-win32-x64": "2.8.5" + } + }, + "node_modules/lmdb/node_modules/node-addon-api": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-6.1.0.tgz", + "integrity": "sha512-+eawOlIgy680F0kBzPUNFhMZGtJ1YmqM6l4+Crf4IkImjYrO/mqPwRMh352g23uIaQKFItcQ64I7KMaJxHgAVA==", + "dev": true, + "license": "MIT" + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash": { + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.18.1.tgz", + "integrity": "sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==", + "license": "MIT" + }, + "node_modules/lodash-es": { + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.18.1.tgz", + "integrity": "sha512-J8xewKD/Gk22OZbhpOVSwcs60zhd95ESDwezOFuA3/099925PdHJ7OFHNTGtajL3AlZkykD32HykiMo+BIBI8A==", + "license": "MIT" + }, + "node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/luxon": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/luxon/-/luxon-3.7.2.tgz", + "integrity": "sha512-vtEhXh/gNjI9Yg1u4jX/0YVPMvxzHuGgCm6tC5kZyb08yjGWGnqAjGJvcXbqQR2P3MyMEFnRbpcdFS6PBcLqew==", + "license": "MIT", + "engines": { + "node": ">=12" + } + }, + "node_modules/magic-string": { + "version": "0.30.21", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", + "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==", + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.5" + } + }, + "node_modules/make-dir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", + "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^7.5.3" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/mime": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-3.0.0.tgz", + "integrity": "sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==", + "dev": true, + "license": "MIT", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/mime-db": { + "version": "1.54.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", + "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.2.tgz", + "integrity": "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==", + "license": "MIT", + "dependencies": { + "mime-db": "^1.54.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/minimatch": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/minipass": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.3.tgz", + "integrity": "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/moment": { + "version": "2.30.1", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.30.1.tgz", + "integrity": "sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==", + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/moment-timezone": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.6.2.tgz", + "integrity": "sha512-lDsQv8FoGdBUdf0+TjGsq2orxKuXdwFlQ6Zw6TX3xIcTwTfEpCLyKqvEauvCHJ8iu3KBV8+uPhlv70YsNGdUBQ==", + "license": "MIT", + "dependencies": { + "moment": "^2.29.4" + }, + "engines": { + "node": "*" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, + "node_modules/msgpackr": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/msgpackr/-/msgpackr-1.12.1.tgz", + "integrity": "sha512-4EUH9tQHnMmEgzW/MdAP0KIfa1T9AF+htl0ffe2n5vb2EKn9y2co8ccpgWko6S52Jy1PQZKwRnx5/KkYjtd9MQ==", + "dev": true, + "license": "MIT", + "optionalDependencies": { + "msgpackr-extract": "^3.0.2" + } + }, + "node_modules/msgpackr-extract": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/msgpackr-extract/-/msgpackr-extract-3.0.4.tgz", + "integrity": "sha512-4kmO/MdyUIkLIvTPr8VHLil4AtoKIoniWPIEk5+CDy0xnWC84azhSFmuJ7PxZdsYtiP5kEeQsORAVIeMgxT+Hw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "dependencies": { + "node-gyp-build-optional-packages": "5.2.2" + }, + "bin": { + "download-msgpackr-prebuilds": "bin/download-prebuilds.js" + }, + "optionalDependencies": { + "@msgpackr-extract/msgpackr-extract-darwin-arm64": "3.0.4", + "@msgpackr-extract/msgpackr-extract-darwin-x64": "3.0.4", + "@msgpackr-extract/msgpackr-extract-linux-arm": "3.0.4", + "@msgpackr-extract/msgpackr-extract-linux-arm64": "3.0.4", + "@msgpackr-extract/msgpackr-extract-linux-x64": "3.0.4", + "@msgpackr-extract/msgpackr-extract-win32-x64": "3.0.4" + } + }, + "node_modules/msgpackr-extract/node_modules/detect-libc": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", + "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", + "dev": true, + "license": "Apache-2.0", + "optional": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/msgpackr-extract/node_modules/node-gyp-build-optional-packages": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/node-gyp-build-optional-packages/-/node-gyp-build-optional-packages-5.2.2.tgz", + "integrity": "sha512-s+w+rBWnpTMwSFbaE0UXsRlg7hU4FjekKU4eyAih5T8nJuNZT1nNsskXpxmeqSK9UzkBl6UgRlnKc8hz8IEqOw==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "detect-libc": "^2.0.1" + }, + "bin": { + "node-gyp-build-optional-packages": "bin.js", + "node-gyp-build-optional-packages-optional": "optional.js", + "node-gyp-build-optional-packages-test": "build-test.js" + } + }, + "node_modules/muggle-string": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/muggle-string/-/muggle-string-0.4.1.tgz", + "integrity": "sha512-VNTrAak/KhO2i8dqqnqnAHOa3cYBwXEZe9h+D5h/1ZqFSTEFHdM65lR7RoIqq3tBBYavsOXV84NoHXZ0AkPyqQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/murmurhash-js": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/murmurhash-js/-/murmurhash-js-1.0.0.tgz", + "integrity": "sha512-TvmkNhkv8yct0SVBSy+o8wYzXjE4Zz3PCesbfs8HiCXXdcTuocApFv11UWlNFWKYsP2okqrhb7JNlSm9InBhIw==", + "license": "MIT" + }, + "node_modules/naive-ui": { + "version": "2.38.1", + "resolved": "https://registry.npmjs.org/naive-ui/-/naive-ui-2.38.1.tgz", + "integrity": "sha512-AnU1FQ7K/CbhguAX++V4kCFjk7h7RvWt4nvZPRjORMpq+fUIlzD+EcQ5Cv1VqDloNF8+eMv4Akc2Ogacc9S+5A==", + "license": "MIT", + "dependencies": { + "@css-render/plugin-bem": "^0.15.12", + "@css-render/vue3-ssr": "^0.15.12", + "@types/katex": "^0.16.2", + "@types/lodash": "^4.14.198", + "@types/lodash-es": "^4.17.9", + "async-validator": "^4.2.5", + "css-render": "^0.15.12", + "csstype": "^3.1.3", + "date-fns": "^2.30.0", + "date-fns-tz": "^2.0.0", + "evtd": "^0.2.4", + "highlight.js": "^11.8.0", + "lodash": "^4.17.21", + "lodash-es": "^4.17.21", + "seemly": "^0.3.8", + "treemate": "^0.3.11", + "vdirs": "^0.1.8", + "vooks": "^0.2.12", + "vueuc": "^0.4.58" + }, + "peerDependencies": { + "vue": "^3.0.0" + } + }, + "node_modules/nanoid": { + "version": "3.3.15", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.15.tgz", + "integrity": "sha512-y7Wygv/7mEOvxTuEQDB8StXdMRBWf1kR/tlhAzBRUFkB2jfcLOAxO/SHmOO2zgz1pVgK29/kyupn059/bCHdjA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/node-addon-api": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.1.1.tgz", + "integrity": "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/node-gyp-build-optional-packages": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/node-gyp-build-optional-packages/-/node-gyp-build-optional-packages-5.1.1.tgz", + "integrity": "sha512-+P72GAjVAbTxjjwUmwjVrqrdZROD4nf8KgpBoDxqXXTiYZZt/ud60dE5yvCSr9lRO8e8yv6kgJIC0K0PfZFVQw==", + "dev": true, + "license": "MIT", + "dependencies": { + "detect-libc": "^2.0.1" + }, + "bin": { + "node-gyp-build-optional-packages": "bin.js", + "node-gyp-build-optional-packages-optional": "optional.js", + "node-gyp-build-optional-packages-test": "build-test.js" + } + }, + "node_modules/node-gyp-build-optional-packages/node_modules/detect-libc": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", + "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=8" + } + }, + "node_modules/node-releases": { + "version": "2.0.50", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.50.tgz", + "integrity": "sha512-J6l92tKHX6w8Jy5nO1Vuc01NoIiRGi/d6qBKVxh+IQ8Cr3b6HbVNfKiF8ZpFKufTwpwxMmce2W3iQZ861ZRyTg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/nullthrows": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/nullthrows/-/nullthrows-1.1.1.tgz", + "integrity": "sha512-2vPPEi+Z7WqML2jZYddDIfy5Dqb0r2fze2zTxNNknZaFpVHU3mFB3R+DWeJWGVx0ecvttSGlJTI+WG+8Z4cDWw==", + "dev": true, + "license": "MIT" + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "license": "MIT", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/ordered-binary": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/ordered-binary/-/ordered-binary-1.6.1.tgz", + "integrity": "sha512-QkCdPooczexPLiXIrbVOPYkR3VO3T6v2OyKRkR1Xbhpy7/LAVXwahnRCgRp78Oe/Ehf0C/HATAxfSr6eA1oX+w==", + "dev": true, + "license": "MIT" + }, + "node_modules/oxfmt": { + "version": "0.58.0", + "resolved": "https://registry.npmjs.org/oxfmt/-/oxfmt-0.58.0.tgz", + "integrity": "sha512-8feG/7NVEHDVwc1OUpP6Pks+TnaDFUw2jLLFIMi5bcmmwxAX2wBQvjSzj62RRTYBf2Op1Wt8xbkmagmPTR5ETg==", + "dev": true, + "license": "MIT", + "dependencies": { + "tinypool": "2.1.0" + }, + "bin": { + "oxfmt": "bin/oxfmt" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "funding": { + "url": "https://github.com/sponsors/Boshen" + }, + "optionalDependencies": { + "@oxfmt/binding-android-arm-eabi": "0.58.0", + "@oxfmt/binding-android-arm64": "0.58.0", + "@oxfmt/binding-darwin-arm64": "0.58.0", + "@oxfmt/binding-darwin-x64": "0.58.0", + "@oxfmt/binding-freebsd-x64": "0.58.0", + "@oxfmt/binding-linux-arm-gnueabihf": "0.58.0", + "@oxfmt/binding-linux-arm-musleabihf": "0.58.0", + "@oxfmt/binding-linux-arm64-gnu": "0.58.0", + "@oxfmt/binding-linux-arm64-musl": "0.58.0", + "@oxfmt/binding-linux-ppc64-gnu": "0.58.0", + "@oxfmt/binding-linux-riscv64-gnu": "0.58.0", + "@oxfmt/binding-linux-riscv64-musl": "0.58.0", + "@oxfmt/binding-linux-s390x-gnu": "0.58.0", + "@oxfmt/binding-linux-x64-gnu": "0.58.0", + "@oxfmt/binding-linux-x64-musl": "0.58.0", + "@oxfmt/binding-openharmony-arm64": "0.58.0", + "@oxfmt/binding-win32-arm64-msvc": "0.58.0", + "@oxfmt/binding-win32-ia32-msvc": "0.58.0", + "@oxfmt/binding-win32-x64-msvc": "0.58.0" + }, + "peerDependencies": { + "svelte": "^5.0.0", + "vite-plus": "*" + }, + "peerDependenciesMeta": { + "svelte": { + "optional": true + }, + "vite-plus": { + "optional": true + } + } + }, + "node_modules/oxlint": { + "version": "1.73.0", + "resolved": "https://registry.npmjs.org/oxlint/-/oxlint-1.73.0.tgz", + "integrity": "sha512-u91G9TJzU6yqKWNZUYprQB07W7YvntZXaRxQ6CkoytepYhLWUXWsr1M8zUJ34VatNPuUAr3Z8GH+O2A331CluQ==", + "dev": true, + "license": "MIT", + "bin": { + "oxlint": "bin/oxlint" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "funding": { + "url": "https://github.com/sponsors/Boshen" + }, + "optionalDependencies": { + "@oxlint/binding-android-arm-eabi": "1.73.0", + "@oxlint/binding-android-arm64": "1.73.0", + "@oxlint/binding-darwin-arm64": "1.73.0", + "@oxlint/binding-darwin-x64": "1.73.0", + "@oxlint/binding-freebsd-x64": "1.73.0", + "@oxlint/binding-linux-arm-gnueabihf": "1.73.0", + "@oxlint/binding-linux-arm-musleabihf": "1.73.0", + "@oxlint/binding-linux-arm64-gnu": "1.73.0", + "@oxlint/binding-linux-arm64-musl": "1.73.0", + "@oxlint/binding-linux-ppc64-gnu": "1.73.0", + "@oxlint/binding-linux-riscv64-gnu": "1.73.0", + "@oxlint/binding-linux-riscv64-musl": "1.73.0", + "@oxlint/binding-linux-s390x-gnu": "1.73.0", + "@oxlint/binding-linux-x64-gnu": "1.73.0", + "@oxlint/binding-linux-x64-musl": "1.73.0", + "@oxlint/binding-openharmony-arm64": "1.73.0", + "@oxlint/binding-win32-arm64-msvc": "1.73.0", + "@oxlint/binding-win32-ia32-msvc": "1.73.0", + "@oxlint/binding-win32-x64-msvc": "1.73.0" + }, + "peerDependencies": { + "oxlint-tsgolint": ">=0.24.0", + "vite-plus": "*" + }, + "peerDependenciesMeta": { + "oxlint-tsgolint": { + "optional": true + }, + "vite-plus": { + "optional": true + } + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/package-json-from-dist": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", + "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", + "dev": true, + "license": "BlueOak-1.0.0" + }, + "node_modules/parcel": { + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/parcel/-/parcel-2.16.4.tgz", + "integrity": "sha512-RQlrqs4ujYNJpTQi+dITqPKNhRWEqpjPd1YBcGp50Wy3FcJHpwu0/iRm7XWz2dKU/Bwp2qCcVYPIeEDYi2uOUw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/config-default": "2.16.4", + "@parcel/core": "2.16.4", + "@parcel/diagnostic": "2.16.4", + "@parcel/events": "2.16.4", + "@parcel/feature-flags": "2.16.4", + "@parcel/fs": "2.16.4", + "@parcel/logger": "2.16.4", + "@parcel/package-manager": "2.16.4", + "@parcel/reporter-cli": "2.16.4", + "@parcel/reporter-dev-server": "2.16.4", + "@parcel/reporter-tracer": "2.16.4", + "@parcel/utils": "2.16.4", + "chalk": "^4.1.2", + "commander": "^12.1.0", + "get-port": "^4.2.0" + }, + "bin": { + "parcel": "lib/bin.js" + }, + "engines": { + "node": ">= 16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/parcel/node_modules/@parcel/fs": { + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/fs/-/fs-2.16.4.tgz", + "integrity": "sha512-maCMOiVn7oJYZlqlfxgLne8n6tSktIT1k0AeyBp4UGWCXyeJUJ+nL7QYShFpKNLtMLeF0cEtgwRAknWzbcDS1g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/feature-flags": "2.16.4", + "@parcel/rust": "2.16.4", + "@parcel/types-internal": "2.16.4", + "@parcel/utils": "2.16.4", + "@parcel/watcher": "^2.0.7", + "@parcel/workers": "2.16.4" + }, + "engines": { + "node": ">= 16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "peerDependencies": { + "@parcel/core": "^2.16.4" + } + }, + "node_modules/parcel/node_modules/@parcel/node-resolver-core": { + "version": "3.7.4", + "resolved": "https://registry.npmjs.org/@parcel/node-resolver-core/-/node-resolver-core-3.7.4.tgz", + "integrity": "sha512-b3VDG+um6IWW5CTod6M9hQsTX5mdIelKmam7mzxzgqg4j5hnycgTWqPMc9UxhYoUY/Q/PHfWepccNcKtvP5JiA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@mischnic/json-sourcemap": "^0.1.1", + "@parcel/diagnostic": "2.16.4", + "@parcel/fs": "2.16.4", + "@parcel/rust": "2.16.4", + "@parcel/utils": "2.16.4", + "nullthrows": "^1.1.1", + "semver": "^7.7.1" + }, + "engines": { + "node": ">= 16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/parcel/node_modules/@parcel/package-manager": { + "version": "2.16.4", + "resolved": "https://registry.npmjs.org/@parcel/package-manager/-/package-manager-2.16.4.tgz", + "integrity": "sha512-obWv9gZgdnkT3Kd+fBkKjhdNEY7zfOP5gVaox5i4nQstVCaVnDlMv5FwLEXwehL+WbwEcGyEGGxOHHkAFKk7Cg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/diagnostic": "2.16.4", + "@parcel/fs": "2.16.4", + "@parcel/logger": "2.16.4", + "@parcel/node-resolver-core": "3.7.4", + "@parcel/types": "2.16.4", + "@parcel/utils": "2.16.4", + "@parcel/workers": "2.16.4", + "@swc/core": "^1.11.24", + "semver": "^7.7.1" + }, + "engines": { + "node": ">= 16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "peerDependencies": { + "@parcel/core": "^2.16.4" + } + }, + "node_modules/parcel/node_modules/commander": { + "version": "12.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz", + "integrity": "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true, + "license": "MIT" + }, + "node_modules/path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.5.tgz", + "integrity": "sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pinia": { + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/pinia/-/pinia-2.1.7.tgz", + "integrity": "sha512-+C2AHFtcFqjPih0zpYuvof37SFxMQ7OEG2zV9jRI12i9BOy3YQVAHwdKtyyc8pDcDyIc33WCIsZaCFWU7WWxGQ==", + "license": "MIT", + "dependencies": { + "@vue/devtools-api": "^6.5.0", + "vue-demi": ">=0.14.5" + }, + "funding": { + "url": "https://github.com/sponsors/posva" + }, + "peerDependencies": { + "@vue/composition-api": "^1.4.0", + "typescript": ">=4.4.4", + "vue": "^2.6.14 || ^3.3.0" + }, + "peerDependenciesMeta": { + "@vue/composition-api": { + "optional": true + }, + "typescript": { + "optional": true + } + } + }, + "node_modules/pinia-plugin-persist": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/pinia-plugin-persist/-/pinia-plugin-persist-1.0.0.tgz", + "integrity": "sha512-M4hBBd8fz/GgNmUPaaUsC29y1M09lqbXrMAHcusVoU8xlQi1TqgkWnnhvMikZwr7Le/hVyMx8KUcumGGrR6GVw==", + "license": "MIT", + "dependencies": { + "vue-demi": "^0.12.1" + }, + "peerDependencies": { + "@vue/composition-api": "^1.0.0", + "pinia": "^2.0.0", + "vue": "^2.0.0 || >=3.0.0" + }, + "peerDependenciesMeta": { + "@vue/composition-api": { + "optional": true + } + } + }, + "node_modules/pinia-plugin-persist/node_modules/vue-demi": { + "version": "0.12.5", + "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.12.5.tgz", + "integrity": "sha512-BREuTgTYlUr0zw0EZn3hnhC3I6gPWv+Kwh4MCih6QcAeaTlaIX0DwOVN0wHej7hSvDPecz4jygy/idsgKfW58Q==", + "hasInstallScript": true, + "license": "MIT", + "bin": { + "vue-demi-fix": "bin/vue-demi-fix.js", + "vue-demi-switch": "bin/vue-demi-switch.js" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + }, + "peerDependencies": { + "@vue/composition-api": "^1.0.0-rc.1", + "vue": "^3.0.0-0 || ^2.6.0" + }, + "peerDependenciesMeta": { + "@vue/composition-api": { + "optional": true + } + } + }, + "node_modules/pinia/node_modules/vue-demi": { + "version": "0.14.10", + "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.10.tgz", + "integrity": "sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==", + "hasInstallScript": true, + "license": "MIT", + "bin": { + "vue-demi-fix": "bin/vue-demi-fix.js", + "vue-demi-switch": "bin/vue-demi-switch.js" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + }, + "peerDependencies": { + "@vue/composition-api": "^1.0.0-rc.1", + "vue": "^3.0.0-0 || ^2.6.0" + }, + "peerDependenciesMeta": { + "@vue/composition-api": { + "optional": true + } + } + }, + "node_modules/postcss": { + "version": "8.5.16", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.16.tgz", + "integrity": "sha512-vuwillviilfKZsg0VGj5R/YwwcHx4SLsIOI/7K6mQkWx+l5cUHTjj5g0AasTBcyXsbfTgrwsUNmVUb5xVwyPwg==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.12", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postcss-value-parser": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/preact": { + "version": "10.12.1", + "resolved": "https://registry.npmjs.org/preact/-/preact-10.12.1.tgz", + "integrity": "sha512-l8386ixSsBdbreOAkqtrwqHwdvR35ID8c3rKPa8lCWuO86dBi32QWHV4vfsZK1utLLFMvw+Z5Ad4XLkZzchscg==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/preact" + } + }, + "node_modules/promise": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz", + "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==", + "dev": true, + "license": "MIT", + "dependencies": { + "asap": "~2.0.3" + } + }, + "node_modules/prompts": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", + "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/prompts/node_modules/kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/pug": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/pug/-/pug-3.0.4.tgz", + "integrity": "sha512-kFfq5mMzrS7+wrl5pLJzZEzemx34OQ0w4SARfhy/3yxTlhbstsudDwJzhf1hP02yHzbjoVMSXUj/Sz6RNfMyXg==", + "dev": true, + "license": "MIT", + "dependencies": { + "pug-code-gen": "^3.0.4", + "pug-filters": "^4.0.0", + "pug-lexer": "^5.0.1", + "pug-linker": "^4.0.0", + "pug-load": "^3.0.0", + "pug-parser": "^6.0.0", + "pug-runtime": "^3.0.1", + "pug-strip-comments": "^2.0.0" + } + }, + "node_modules/pug-attrs": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pug-attrs/-/pug-attrs-3.0.0.tgz", + "integrity": "sha512-azINV9dUtzPMFQktvTXciNAfAuVh/L/JCl0vtPCwvOA21uZrC08K/UnmrL+SXGEVc1FwzjW62+xw5S/uaLj6cA==", + "dev": true, + "license": "MIT", + "dependencies": { + "constantinople": "^4.0.1", + "js-stringify": "^1.0.2", + "pug-runtime": "^3.0.0" + } + }, + "node_modules/pug-code-gen": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/pug-code-gen/-/pug-code-gen-3.0.4.tgz", + "integrity": "sha512-6okWYIKdasTyXICyEtvobmTZAVX57JkzgzIi4iRJlin8kmhG+Xry2dsus+Mun/nGCn6F2U49haHI5mkELXB14g==", + "dev": true, + "license": "MIT", + "dependencies": { + "constantinople": "^4.0.1", + "doctypes": "^1.1.0", + "js-stringify": "^1.0.2", + "pug-attrs": "^3.0.0", + "pug-error": "^2.1.0", + "pug-runtime": "^3.0.1", + "void-elements": "^3.1.0", + "with": "^7.0.0" + } + }, + "node_modules/pug-error": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/pug-error/-/pug-error-2.1.0.tgz", + "integrity": "sha512-lv7sU9e5Jk8IeUheHata6/UThZ7RK2jnaaNztxfPYUY+VxZyk/ePVaNZ/vwmH8WqGvDz3LrNYt/+gA55NDg6Pg==", + "dev": true, + "license": "MIT" + }, + "node_modules/pug-filters": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/pug-filters/-/pug-filters-4.0.0.tgz", + "integrity": "sha512-yeNFtq5Yxmfz0f9z2rMXGw/8/4i1cCFecw/Q7+D0V2DdtII5UvqE12VaZ2AY7ri6o5RNXiweGH79OCq+2RQU4A==", + "dev": true, + "license": "MIT", + "dependencies": { + "constantinople": "^4.0.1", + "jstransformer": "1.0.0", + "pug-error": "^2.0.0", + "pug-walk": "^2.0.0", + "resolve": "^1.15.1" + } + }, + "node_modules/pug-filters/node_modules/resolve": { + "version": "1.22.12", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.12.tgz", + "integrity": "sha512-TyeJ1zif53BPfHootBGwPRYT1RUt6oGWsaQr8UyZW/eAm9bKoijtvruSDEmZHm92CwS9nj7/fWttqPCgzep8CA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "is-core-module": "^2.16.1", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/pug-lexer": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/pug-lexer/-/pug-lexer-5.0.1.tgz", + "integrity": "sha512-0I6C62+keXlZPZkOJeVam9aBLVP2EnbeDw3An+k0/QlqdwH6rv8284nko14Na7c0TtqtogfWXcRoFE4O4Ff20w==", + "dev": true, + "license": "MIT", + "dependencies": { + "character-parser": "^2.2.0", + "is-expression": "^4.0.0", + "pug-error": "^2.0.0" + } + }, + "node_modules/pug-linker": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/pug-linker/-/pug-linker-4.0.0.tgz", + "integrity": "sha512-gjD1yzp0yxbQqnzBAdlhbgoJL5qIFJw78juN1NpTLt/mfPJ5VgC4BvkoD3G23qKzJtIIXBbcCt6FioLSFLOHdw==", + "dev": true, + "license": "MIT", + "dependencies": { + "pug-error": "^2.0.0", + "pug-walk": "^2.0.0" + } + }, + "node_modules/pug-load": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pug-load/-/pug-load-3.0.0.tgz", + "integrity": "sha512-OCjTEnhLWZBvS4zni/WUMjH2YSUosnsmjGBB1An7CsKQarYSWQ0GCVyd4eQPMFJqZ8w9xgs01QdiZXKVjk92EQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "object-assign": "^4.1.1", + "pug-walk": "^2.0.0" + } + }, + "node_modules/pug-parser": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/pug-parser/-/pug-parser-6.0.0.tgz", + "integrity": "sha512-ukiYM/9cH6Cml+AOl5kETtM9NR3WulyVP2y4HOU45DyMim1IeP/OOiyEWRr6qk5I5klpsBnbuHpwKmTx6WURnw==", + "dev": true, + "license": "MIT", + "dependencies": { + "pug-error": "^2.0.0", + "token-stream": "1.0.0" + } + }, + "node_modules/pug-runtime": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/pug-runtime/-/pug-runtime-3.0.1.tgz", + "integrity": "sha512-L50zbvrQ35TkpHwv0G6aLSuueDRwc/97XdY8kL3tOT0FmhgG7UypU3VztfV/LATAvmUfYi4wNxSajhSAeNN+Kg==", + "dev": true, + "license": "MIT" + }, + "node_modules/pug-strip-comments": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pug-strip-comments/-/pug-strip-comments-2.0.0.tgz", + "integrity": "sha512-zo8DsDpH7eTkPHCXFeAk1xZXJbyoTfdPlNR0bK7rpOMuhBYb0f5qUVCO1xlsitYd3w5FQTK7zpNVKb3rZoUrrQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "pug-error": "^2.0.0" + } + }, + "node_modules/pug-walk": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pug-walk/-/pug-walk-2.0.0.tgz", + "integrity": "sha512-yYELe9Q5q9IQhuvqsZNwA5hfPkMJ8u92bQLIMcsMxf/VADjNtEYptU+inlufAFYcWdHlwNfZOEnOOQrZrcyJCQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/react-refresh": { + "version": "0.16.0", + "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.16.0.tgz", + "integrity": "sha512-FPvF2XxTSikpJxcr+bHut2H4gJ17+18Uy20D5/F+SKzFap62R3cM5wH6b8WN3LyGSYeQilLEcJcR1fjBSI2S1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/readdirp": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-5.0.0.tgz", + "integrity": "sha512-9u/XQ1pvrQtYyMpZe7DXKv2p5CNvyVwzUB6uhLAnQwHMSgKMBR62lc7AHljaeteeHXn11XTAaLLUVZYVZyuRBQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 20.19.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/regenerator-runtime": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==", + "dev": true, + "license": "MIT" + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/robust-predicates": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/robust-predicates/-/robust-predicates-3.0.3.tgz", + "integrity": "sha512-NS3levdsRIUOmiJ8FZWCP7LG3QpJyrs/TE0Zpf1yvZu8cAJJ6QMW92H1c7kWpdIHo8RvmLxN/o2JXTKHp74lUA==", + "license": "Unlicense" + }, + "node_modules/rollup": { + "version": "3.30.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.30.0.tgz", + "integrity": "sha512-kQvGasUgN+AlWGliFn2POSajRQEsULVYFGTvOZmK06d7vCD+YhZztt70kGk3qaeAXeWYL5eO7zx+rAubBc55eA==", + "dev": true, + "license": "MIT", + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=14.18.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/rw": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/rw/-/rw-1.3.3.tgz", + "integrity": "sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==", + "license": "BSD-3-Clause" + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "license": "MIT" + }, + "node_modules/sass": { + "version": "1.101.0", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.101.0.tgz", + "integrity": "sha512-OL3GoQyoUdDt843DpVmDO6y2k1sc5IhUDSpu8XucEI+35neq5QivZ1iuegnpraEVTJXlQGK1gl27zKcTLEPbQw==", + "dev": true, + "license": "MIT", + "dependencies": { + "chokidar": "^5.0.0", + "immutable": "^5.1.5", + "source-map-js": ">=0.6.2 <2.0.0" + }, + "bin": { + "sass": "sass.js" + }, + "engines": { + "node": ">=20.19.0" + }, + "optionalDependencies": { + "@parcel/watcher": "^2.4.1" + } + }, + "node_modules/seedrandom": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/seedrandom/-/seedrandom-3.0.5.tgz", + "integrity": "sha512-8OwmbklUNzwezjGInmZ+2clQmExQPvomqjL7LFqOYqtmuxRgQYqOD3mHaU+MvZn5FLUeVxVfQjwLZW/n/JFuqg==", + "dev": true, + "license": "MIT" + }, + "node_modules/seemly": { + "version": "0.3.10", + "resolved": "https://registry.npmjs.org/seemly/-/seemly-0.3.10.tgz", + "integrity": "sha512-2+SMxtG1PcsL0uyhkumlOU6Qo9TAQ/WyH7tthnPIOQB05/12jz9naq6GZ6iZ6ApVsO3rr2gsnTf3++OV63kE1Q==", + "license": "MIT" + }, + "node_modules/select2": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/select2/-/select2-4.1.0.tgz", + "integrity": "sha512-i9KalWOP4/LRRGc8+rj2krNm0ZqP14cV+j1TRCEBSsOhCPkKH8rYZ2MCRXcgvqIqN+llqGci0hj9aVkCMvL0+g==", + "license": "MIT", + "engines": { + "node": ">=24" + } + }, + "node_modules/select2-bootstrap-5-theme": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/select2-bootstrap-5-theme/-/select2-bootstrap-5-theme-1.3.0.tgz", + "integrity": "sha512-uEJDruP4tmwyKcs3V0oP7CIsyC45PGF5ddo8unwTp8OucJ1PSuTOBr+xbWaHTQPGnvp7N96psVQ5UBMQvFCcHA==", + "license": "MIT", + "dependencies": { + "bootstrap": "^5.1.3" + } + }, + "node_modules/semver": { + "version": "7.8.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz", + "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/send": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/send/-/send-1.2.1.tgz", + "integrity": "sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ==", + "license": "MIT", + "dependencies": { + "debug": "^4.4.3", + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "etag": "^1.8.1", + "fresh": "^2.0.0", + "http-errors": "^2.0.1", + "mime-types": "^3.0.2", + "ms": "^2.1.3", + "on-finished": "^2.4.1", + "range-parser": "^1.2.1", + "statuses": "^2.0.2" + }, + "engines": { + "node": ">= 18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", + "license": "ISC" + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/shepherd.js": { + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/shepherd.js/-/shepherd.js-11.2.0.tgz", + "integrity": "sha512-2hbz3N7GuuTjI7y3sfnoqKnH0cNhExx67IJtCTGQI2KhBEyvegsDYW5qjj5BlvvVtQjmL/O/J1GQEciwfoZWpw==", + "license": "MIT", + "dependencies": { + "@floating-ui/dom": "^1.5.1", + "deepmerge": "^4.3.1" + }, + "engines": { + "node": "16.* || >= 18" + }, + "funding": { + "type": "individual", + "url": "https://github.com/sponsors/RobbieTheWagner" + } + }, + "node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", + "dev": true, + "license": "MIT" + }, + "node_modules/slugify": { + "version": "1.6.9", + "resolved": "https://registry.npmjs.org/slugify/-/slugify-1.6.9.tgz", + "integrity": "sha512-vZ7rfeehZui7wQs438JXBckYLkIIdfHOXsaVEUMyS5fHo1483l1bMdo0EDSWYclY0yZKFOipDy4KHuKs6ssvdg==", + "license": "MIT", + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/sortablejs": { + "version": "1.15.7", + "resolved": "https://registry.npmjs.org/sortablejs/-/sortablejs-1.15.7.tgz", + "integrity": "sha512-Kk8wLQPlS+yi1ZEf48a4+fzHa4yxjC30M/Sr2AnQu+f/MPwvvX9XjZ6OWejiz8crBsLwSq8GHqaxaET7u6ux0A==", + "license": "MIT" + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/statuses": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz", + "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/string-natural-compare": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/string-natural-compare/-/string-natural-compare-2.0.3.tgz", + "integrity": "sha512-4Kcl12rNjc+6EKhY8QyDVuQTAlMWwRiNbsxnVwBUKFr7dYPQuXVrtNU4sEkjF9LHY0AY6uVbB3ktbkIH4LC+BQ==", + "license": "MIT" + }, + "node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/string-width/node_modules/ansi-regex": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/string-width/node_modules/strip-ansi": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz", + "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.2.2" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/term-size": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/term-size/-/term-size-2.2.1.tgz", + "integrity": "sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/test-exclude": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", + "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", + "dev": true, + "license": "ISC", + "dependencies": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/test-exclude/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/tinypool": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-2.1.0.tgz", + "integrity": "sha512-Pugqs6M0m7Lv1I7FtxN4aoyToKg1C4tu+/381vH35y8oENM/Ai7f7C4StcoK4/+BSw9ebcS8jRiVrORFKCALLw==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^20.0.0 || >=22.0.0" + } + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "license": "MIT", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/token-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/token-stream/-/token-stream-1.0.0.tgz", + "integrity": "sha512-VSsyNPPW74RpHwR8Fc21uubwHY7wMDeJLys2IX5zJNih+OnAnaifKHo+1LHT7DAdloQ7apeaaWg8l7qnf/TnEg==", + "dev": true, + "license": "MIT" + }, + "node_modules/treemate": { + "version": "0.3.11", + "resolved": "https://registry.npmjs.org/treemate/-/treemate-0.3.11.tgz", + "integrity": "sha512-M8RGFoKtZ8dF+iwJfAJTOH/SM4KluKOKRJpjCMhI8bG3qB74zrFoArKZ62ll0Fr3mqkMJiQOmWYkdYgDeITYQg==", + "license": "MIT" + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "dev": true, + "license": "0BSD" + }, + "node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz", + "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "escalade": "^3.2.0", + "picocolors": "^1.1.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "license": "BSD-2-Clause", + "peer": true, + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/utility-types": { + "version": "3.11.0", + "resolved": "https://registry.npmjs.org/utility-types/-/utility-types-3.11.0.tgz", + "integrity": "sha512-6Z7Ma2aVEWisaL6TvBCy7P8rm2LQoPv6dJ7ecIaIixHcwfbJ0x7mWdbcwlIM5IGQxPZSFYeqRCqlOOeKoJYMkw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/v8-to-istanbul": { + "version": "9.3.0", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.3.0.tgz", + "integrity": "sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA==", + "dev": true, + "license": "ISC", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.12", + "@types/istanbul-lib-coverage": "^2.0.1", + "convert-source-map": "^2.0.0" + }, + "engines": { + "node": ">=10.12.0" + } + }, + "node_modules/vanillajs-datepicker": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/vanillajs-datepicker/-/vanillajs-datepicker-1.3.4.tgz", + "integrity": "sha512-waOyp2Ay+K1VA/B5cNlFgSNzFR9efCVKaoyMyNEAhAwmKLzMB9nCJs6Vqmo6HuHWA98VEHXbgz5thZ7hH/uohA==", + "license": "MIT" + }, + "node_modules/vdirs": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/vdirs/-/vdirs-0.1.8.tgz", + "integrity": "sha512-H9V1zGRLQZg9b+GdMk8MXDN2Lva0zx72MPahDKc30v+DtwKjfyOSXWRIX4t2mhDubM1H09gPhWeth/BJWPHGUw==", + "license": "MIT", + "dependencies": { + "evtd": "^0.2.2" + }, + "peerDependencies": { + "vue": "^3.0.11" + } + }, + "node_modules/vite": { + "version": "4.5.3", + "resolved": "https://registry.npmjs.org/vite/-/vite-4.5.3.tgz", + "integrity": "sha512-kQL23kMeX92v3ph7IauVkXkikdDRsYMGTVl5KY2E9OY4ONLvkHf04MDTbnfo6NKxZiDLWzVpP5oTa8hQD8U3dg==", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "^0.18.10", + "postcss": "^8.4.27", + "rollup": "^3.27.1" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + }, + "peerDependencies": { + "@types/node": ">= 14", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.4.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + } + } + }, + "node_modules/void-elements": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-3.1.0.tgz", + "integrity": "sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/volar-service-html": { + "version": "0.0.34", + "resolved": "https://registry.npmjs.org/volar-service-html/-/volar-service-html-0.0.34.tgz", + "integrity": "sha512-kMEneea1tQbiRcyKavqdrSVt8zV06t+0/3pGkjO3gV6sikXTNShIDkdtB4Tq9vE2cQdM50TuS7utVV7iysUxHw==", + "dev": true, + "license": "MIT", + "dependencies": { + "vscode-html-languageservice": "^5.1.0", + "vscode-languageserver-textdocument": "^1.0.11", + "vscode-uri": "^3.0.8" + }, + "peerDependencies": { + "@volar/language-service": "~2.1.0" + }, + "peerDependenciesMeta": { + "@volar/language-service": { + "optional": true + } + } + }, + "node_modules/volar-service-pug": { + "version": "0.0.34", + "resolved": "https://registry.npmjs.org/volar-service-pug/-/volar-service-pug-0.0.34.tgz", + "integrity": "sha512-h0DSnQXkvweXKaBmCYJaDbmmsatp9KIxsTxZD0SVKFyVixHSUjrVJP6eu9o3pGuDNIy2135XBNryUP/Lv7/3oA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@volar/language-service": "~2.1.0", + "pug-lexer": "^5.0.1", + "pug-parser": "^6.0.0", + "volar-service-html": "0.0.34", + "vscode-html-languageservice": "^5.1.0", + "vscode-languageserver-textdocument": "^1.0.11" + } + }, + "node_modules/vooks": { + "version": "0.2.12", + "resolved": "https://registry.npmjs.org/vooks/-/vooks-0.2.12.tgz", + "integrity": "sha512-iox0I3RZzxtKlcgYaStQYKEzWWGAduMmq+jS7OrNdQo1FgGfPMubGL3uGHOU9n97NIvfFDBGnpSvkWyb/NSn/Q==", + "license": "MIT", + "dependencies": { + "evtd": "^0.2.2" + }, + "peerDependencies": { + "vue": "^3.0.0" + } + }, + "node_modules/vscode-html-languageservice": { + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/vscode-html-languageservice/-/vscode-html-languageservice-5.6.2.tgz", + "integrity": "sha512-ulCrSnFnfQ16YzvwnYUgEbUEl/ZG7u2eV27YhvLObSHKkb8fw1Z9cgsnUwjTEeDIdJDoTDTDpxuhQwoenoLNMg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vscode/l10n": "^0.0.18", + "vscode-languageserver-textdocument": "^1.0.12", + "vscode-languageserver-types": "^3.17.5", + "vscode-uri": "^3.1.0" + } + }, + "node_modules/vscode-jsonrpc": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-9.0.1.tgz", + "integrity": "sha512-rfuA6T75H6m5EkbhtEPzre9pT0HPcDI2MMy4+nPFIBks5J8JBAUHD4tRYSgaBOijIEC7SRkC1kKyXTLqbmh9jw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/vscode-languageserver-protocol": { + "version": "3.18.2", + "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.18.2.tgz", + "integrity": "sha512-XRyDbT0Pp3sSNti3JmxVEUMySWCSi1hhM+/KUlCy1hV1zmrqpM1OwO12EAki8blhmLuIMpaJrYbo0OzGVfK2Qg==", + "dev": true, + "license": "MIT", + "dependencies": { + "vscode-jsonrpc": "9.0.1", + "vscode-languageserver-types": "3.18.0" + } + }, + "node_modules/vscode-languageserver-textdocument": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.12.tgz", + "integrity": "sha512-cxWNPesCnQCcMPeenjKKsOCKQZ/L6Tv19DTRIGuLWe32lyzWhihGVJ/rcckZXJxfdKCFvRLS3fpBIsV/ZGX4zA==", + "dev": true, + "license": "MIT" + }, + "node_modules/vscode-languageserver-types": { + "version": "3.18.0", + "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.18.0.tgz", + "integrity": "sha512-8TsGPNMIMiiBdkORgRSvLjuiEIiAFtO+KssmYWxQ+uSVvlf7RjK8YKCOjPzZ+YA04jXEV7+7LvkSmHkhpNS99g==", + "dev": true, + "license": "MIT" + }, + "node_modules/vscode-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-3.1.0.tgz", + "integrity": "sha512-/BpdSx+yCQGnCvecbyXdxHDkuk55/G3xwnC0GqY4gmQ3j+A+g8kzzgB4Nk/SINjqn6+waqw3EgbVF2QKExkRxQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/vue": { + "version": "3.4.21", + "resolved": "https://registry.npmjs.org/vue/-/vue-3.4.21.tgz", + "integrity": "sha512-5hjyV/jLEIKD/jYl4cavMcnzKwjMKohureP8ejn3hhEjwhWIhWeuzL2kJAjzl/WyVsgPY56Sy4Z40C3lVshxXA==", + "license": "MIT", + "dependencies": { + "@vue/compiler-dom": "3.4.21", + "@vue/compiler-sfc": "3.4.21", + "@vue/runtime-dom": "3.4.21", + "@vue/server-renderer": "3.4.21", + "@vue/shared": "3.4.21" + }, + "peerDependencies": { + "typescript": "*" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/vue-router": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-4.3.0.tgz", + "integrity": "sha512-dqUcs8tUeG+ssgWhcPbjHvazML16Oga5w34uCUmsk7i0BcnskoLGwjpa15fqMr2Fa5JgVBrdL2MEgqz6XZ/6IQ==", + "license": "MIT", + "dependencies": { + "@vue/devtools-api": "^6.5.1" + }, + "funding": { + "url": "https://github.com/sponsors/posva" + }, + "peerDependencies": { + "vue": "^3.2.0" + } + }, + "node_modules/vueuc": { + "version": "0.4.65", + "resolved": "https://registry.npmjs.org/vueuc/-/vueuc-0.4.65.tgz", + "integrity": "sha512-lXuMl+8gsBmruudfxnMF9HW4be8rFziylXFu1VHVNbLVhRTXXV4njvpRuJapD/8q+oFEMSfQMH16E/85VoWRyQ==", + "license": "MIT", + "dependencies": { + "@css-render/vue3-ssr": "^0.15.10", + "@juggle/resize-observer": "^3.3.1", + "css-render": "^0.15.10", + "evtd": "^0.2.4", + "seemly": "^0.3.6", + "vdirs": "^0.1.4", + "vooks": "^0.2.4" + }, + "peerDependencies": { + "vue": "^3.0.11" + } + }, + "node_modules/weak-lru-cache": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/weak-lru-cache/-/weak-lru-cache-1.2.2.tgz", + "integrity": "sha512-DEAoo25RfSYMuTGc9vPJzZcZullwIqRDSI9LOy+fkCJPi6hykCnfKaXTuPBDuXAUcqHXyOgFtHNp/kB2FjYHbw==", + "dev": true, + "license": "MIT" + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/with": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/with/-/with-7.0.2.tgz", + "integrity": "sha512-RNGKj82nUPg3g5ygxkQl0R937xLyho1J24ItRCBTr/m1YnZkzJy1hUiHUJrc/VlsDQzsCnInEGSg3bci0Lmd4w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.9.6", + "@babel/types": "^7.9.6", + "assert-never": "^1.2.1", + "babel-walk": "3.0.0-canary-5" + }, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/wrap-ansi-cjs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-regex": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/strip-ansi": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz", + "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.2.2" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs": { + "version": "17.7.3", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.3.tgz", + "integrity": "sha512-GZtjxm/J/4TSxuL3FNYjCmLktBTnIw/rVmKSIyKeYAZpmJB2ig9VauCC5xsa82GNKVKDAqpOn3KVzNt0zmrU0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/yargs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/zxcvbn": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/zxcvbn/-/zxcvbn-4.4.2.tgz", + "integrity": "sha512-Bq0B+ixT/DMyG8kgX2xWcI5jUvCwqrMxSFam7m0lAf78nf04hv6lNCsyLYdyYTrCVMqNDY/206K7eExYCeSyUQ==", + "license": "MIT" + } + } +} diff --git a/package.json b/package.json index de056df04cb..008fd57e7fb 100644 --- a/package.json +++ b/package.json @@ -2,86 +2,104 @@ "scripts": { "dev": "vite", "build": "vite build", - "preview": "vite preview", + "preview": "vite build --mode test && vite preview --mode test", "legacy:dev": "parcel", - "legacy:build": "parcel build", - "cypress": "cypress run", - "cypress:open": "cypress open", - "test": "vitest", - "coverage": "vitest run --coverage" + "legacy:build": "parcel build" }, "dependencies": { - "@fullcalendar/bootstrap5": "5.11.0", - "@fullcalendar/core": "5.11.0", - "@fullcalendar/daygrid": "5.11.0", - "@fullcalendar/interaction": "5.11.0", - "@fullcalendar/list": "5.11.0", - "@fullcalendar/luxon2": "5.11.0", - "@fullcalendar/timegrid": "5.11.0", - "@fullcalendar/vue3": "5.11.1", - "@popperjs/core": "2.11.5", - "bootstrap": "5.2.0", - "bootstrap-icons": "1.9.1", - "browser-fs-access": "0.31.0", - "caniuse-lite": "1.0.30001368", - "d3": "7.6.1", + "@fullcalendar/bootstrap5": "6.1.21", + "@fullcalendar/core": "6.1.21", + "@fullcalendar/daygrid": "6.1.21", + "@fullcalendar/icalendar": "6.1.21", + "@fullcalendar/interaction": "6.1.21", + "@fullcalendar/list": "6.1.21", + "@fullcalendar/luxon3": "6.1.21", + "@fullcalendar/timegrid": "6.1.21", + "@fullcalendar/vue3": "6.1.21", + "@kurkle/color": "0.3.1", + "@popperjs/core": "2.11.8", + "@twuni/emojify": "1.0.2", + "bootstrap": "5.3.8", + "bootstrap-icons": "1.13.1", + "browser-fs-access": "0.38.0", + "caniuse-lite": "1.0.30001803", + "chart.js": "^4.5.1", + "chartjs-plugin-autocolors": "0.3.1", + "chartjs-plugin-zoom": "2.2.0", + "d3": "7.9.0", "file-saver": "2.0.5", - "highcharts": "10.2.0", - "jquery": "3.6.0", - "jquery-ui-dist": "1.13.1", - "js-cookie": "3.0.1", + "highcharts": "11.4.0", + "ical.js": "1.5.0", + "jquery": "3.7.1", + "js-cookie": "3.0.8", "list.js": "2.3.1", - "lodash": "4.17.21", - "luxon": "3.0.1", - "moment": "2.29.4", - "moment-timezone": "0.5.34", + "lodash": "4.18.1", + "lodash-es": "4.18.1", + "luxon": "3.7.2", + "moment": "2.30.1", + "moment-timezone": "0.6.2", + "ms": "2.1.3", "murmurhash-js": "1.0.0", - "naive-ui": "2.31.0", - "pinia": "2.0.16", + "naive-ui": "2.38.1", + "pinia": "2.1.7", "pinia-plugin-persist": "1.0.0", - "select2": "4.1.0-rc.0", + "select2": "4.1.0", "select2-bootstrap-5-theme": "1.3.0", - "slugify": "1.6.5", - "sortablejs": "1.15.0", - "vue": "3.2.37", - "vue-router": "4.1.2", + "send": "1.2.1", + "shepherd.js": "11.2.0", + "slugify": "1.6.9", + "sortablejs": "1.15.7", + "vanillajs-datepicker": "1.3.4", + "vue": "3.4.21", + "vue-router": "4.3.0", "zxcvbn": "4.4.2" }, "devDependencies": { - "@parcel/transformer-sass": "2.6.2", - "@vitejs/plugin-vue": "2.3.3", - "@vue/test-utils": "2.0.2", + "@parcel/optimizer-data-url": "2.16.4", + "@parcel/transformer-inline-string": "2.16.4", + "@parcel/transformer-sass": "2.16.4", + "@rollup/pluginutils": "5.4.0", + "@vitejs/plugin-vue": "4.6.2", + "@vue/language-plugin-pug": "2.0.7", "browserlist": "latest", - "c8": "7.12.0", - "cypress": "10.3.1", - "cypress-real-events": "1.7.1", - "eslint": "8.20.0", - "eslint-config-standard": "17.0.0", - "eslint-plugin-cypress": "2.12.1", - "eslint-plugin-import": "2.26.0", - "eslint-plugin-node": "11.1.0", - "eslint-plugin-promise": "6.0.0", - "eslint-plugin-vue": "9.2.0", - "html-validate": "7.1.2", - "jquery-migrate": "3.4.0", - "parcel": "2.6.2", - "pug": "3.0.2", - "sass": "1.53.0", - "vite": "2.9.14", - "vitest": "0.18.1" + "c8": "9.1.0", + "html-validate": "8.18.1", + "jquery-migrate": "3.4.1", + "oxfmt": "0.58.0", + "oxlint": "1.73.0", + "parcel": "2.16.4", + "pug": "3.0.4", + "sass": "1.101.0", + "seedrandom": "3.0.5", + "vite": "4.5.3" + }, + "resolutions": { + "lightningcss": "1.17.1" + }, + "allowScripts": { + "@parcel/watcher": false, + "@swc/core": false, + "esbuild": false, + "lmdb": false, + "msgpackr-extract": false, + "vue-demi": false }, "targets": { "ietf": { "distDir": "ietf/static/dist/ietf", "source": [ "ietf/static/css/datepicker.scss", + "ietf/static/css/document_html_inline.scss", + "ietf/static/css/document_html_referenced.scss", + "ietf/static/css/document_html_txt.scss", + "ietf/static/css/highcharts.scss", "ietf/static/css/ietf.scss", - "ietf/static/css/jquery-ui.scss", "ietf/static/css/liaisons.css", "ietf/static/css/list.scss", "ietf/static/css/select2.scss", - "ietf/static/images/arrow-ani.webp", "ietf/static/images/iab-logo-card.png", + "ietf/static/images/iab-logo.svg", + "ietf/static/images/iab-logo-white.svg", "ietf/static/images/iesg-draft-state-diagram.png", "ietf/static/images/ietf-logo-card.png", "ietf/static/images/ietf-logo-nor-16-dev.png", @@ -97,18 +115,24 @@ "ietf/static/images/ietf-logo-nor-mask.svg", "ietf/static/images/ietf-logo-nor-white.svg", "ietf/static/images/ietf-logo-nor.svg", + "ietf/static/images/ietf-logo-white.svg", "ietf/static/images/ietf-logo.svg", "ietf/static/images/irtf-logo-card.png", + "ietf/static/images/irtf-logo-white.svg", + "ietf/static/images/irtf-logo.svg", + "ietf/static/js/add_session_recordings.js", + "ietf/static/js/attendees-chart.js", "ietf/static/js/agenda_filter.js", "ietf/static/js/agenda_materials.js", - "ietf/static/js/agenda_personalize.js", - "ietf/static/js/agenda_timezone.js", + "ietf/static/js/announcement.js", "ietf/static/js/complete-review.js", "ietf/static/js/create_timeslot.js", "ietf/static/js/create_timeslot.js", + "ietf/static/js/custom_striped.js", "ietf/static/js/d3.js", "ietf/static/js/datepicker.js", "ietf/static/js/doc-search.js", + "ietf/static/js/document_html.js", "ietf/static/js/document_relations.js", "ietf/static/js/document_timeline.js", "ietf/static/js/draft-submit.js", @@ -121,29 +145,37 @@ "ietf/static/js/highcharts.js", "ietf/static/js/highstock.js", "ietf/static/js/ietf.js", + "ietf/static/js/investigate.js", "ietf/static/js/ipr-edit.js", "ietf/static/js/ipr-search.js", - "ietf/static/js/jquery-ui.js", "ietf/static/js/js-cookie.js", "ietf/static/js/liaisons.js", "ietf/static/js/list.js", + "ietf/static/js/login.js", "ietf/static/js/manage-community-list.js", "ietf/static/js/manage-review-requests.js", "ietf/static/js/meeting-interim-request.js", + "ietf/static/js/meeting_stats.js", + "ietf/static/js/meeting_timeline.js", "ietf/static/js/moment.js", + "ietf/static/js/navbar-doc-search.js", "ietf/static/js/password_strength.js", - "ietf/static/js/room_params.js", "ietf/static/js/select2.js", + "ietf/static/js/session_details.js", "ietf/static/js/session_details_form.js", + "ietf/static/js/session_form.js", + "ietf/static/js/session_request.js", "ietf/static/js/sortable.js", "ietf/static/js/stats.js", "ietf/static/js/status-change-edit-relations.js", + "ietf/static/js/theme.js", "ietf/static/js/timeslot_edit.js", "ietf/static/js/timezone.js", "ietf/static/js/upcoming.js", "ietf/static/js/upload-material.js", + "ietf/static/js/upload-session-agenda.js", "ietf/static/js/upload_bofreq.js", - "ietf/static/js/week-view.js", + "ietf/static/js/upload_statement.js", "ietf/static/js/zxcvbn.js" ] }, @@ -193,11 +225,8 @@ "ietf/secr/static/images/tooltag-arrowright.webp", "ietf/secr/static/images/tooltag-arrowright_over.webp", "ietf/secr/static/js/dynamic_inlines.js", - "ietf/secr/static/js/session_form.js", - "ietf/secr/static/js/sessions.js", "ietf/secr/static/js/utils.js" ] } - }, - "packageManager": "yarn@3.2.2" + } } diff --git a/patch/add-django-cprofile-filter.patch b/patch/add-django-cprofile-filter.patch index 128d5a9f095..bf684a0b33e 100644 --- a/patch/add-django-cprofile-filter.patch +++ b/patch/add-django-cprofile-filter.patch @@ -1,15 +1,9 @@ ---- django_cprofile_middleware/middleware.py.old 2018-04-04 06:32:29.282187502 -0700 -+++ django_cprofile_middleware/middleware.py 2018-04-06 10:11:18.936855634 -0700 -@@ -1,4 +1,5 @@ - import pstats -+import re - - try: - import cProfile as profile -@@ -14,6 +15,15 @@ - from django.utils.deprecation import MiddlewareMixin - - +--- django_cprofile_middleware/middleware.py.old 2024-06-27 21:03:56.975128007 +0000 ++++ django_cprofile_middleware/middleware.py 2024-06-27 23:45:59.421683008 +0000 +@@ -19,6 +19,16 @@ + from django_cprofile_middleware.utils import MiddlewareMixin + + +class Stats(pstats.Stats): + def filter_stats(self, regex): + oldstats = self.stats @@ -18,17 +12,64 @@ + for func, (cc, nc, tt, ct, callers) in oldstats.iteritems(): + if filter.search(pstats.func_std_string(func)): + newstats[func] = (cc, nc, tt, ct, callers) ++ + class ProfilerMiddleware(MiddlewareMixin): """ Simple profile middleware to profile django views. To run it, add ?prof to -@@ -62,8 +72,13 @@ +@@ -38,9 +48,11 @@ + ?download => Download profile file suitable for visualization. For example + in snakeviz or RunSnakeRun + +- This is adapted from an example found here: +- http://www.slideshare.net/zeeg/django-con-high-performance-django-presentation. ++ Patched with https://github.com/omarish/django-cprofile-middleware/pull/23 ++ for operation with Django 4.2.5+ + """ ++ PROFILER_REQUEST_ATTR_NAME = '_django_cprofile_middleware_profiler' ++ + def can(self, request): + requires_staff = getattr( + settings, "DJANGO_CPROFILE_MIDDLEWARE_REQUIRE_STAFF", True) +@@ -52,10 +64,11 @@ + + def process_view(self, request, callback, callback_args, callback_kwargs): + if self.can(request): +- self.profiler = profile.Profile() ++ profiler = profile.Profile() ++ setattr(request, self.PROFILER_REQUEST_ATTR_NAME, profiler) + args = (request,) + callback_args + try: +- return self.profiler.runcall( ++ return profiler.runcall( + callback, *args, **callback_kwargs) + except Exception: + # we want the process_exception middleware to fire +@@ -63,12 +76,13 @@ + return + + def process_response(self, request, response): +- if self.can(request): +- self.profiler.create_stats() ++ if hasattr(request, self.PROFILER_REQUEST_ATTR_NAME): ++ profiler = getattr(request, self.PROFILER_REQUEST_ATTR_NAME) ++ profiler.create_stats() + if 'download' in request.GET: + import marshal + +- output = marshal.dumps(self.profiler.stats) ++ output = marshal.dumps(profiler.stats) + response = HttpResponse( + output, content_type='application/octet-stream') + response['Content-Disposition'] = 'attachment;' \ +@@ -76,9 +90,14 @@ response['Content-Length'] = len(output) else: io = StringIO() - stats = pstats.Stats(self.profiler, stream=io) ++ stats = Stats(profiler, stream=io) + - stats.strip_dirs().sort_stats(request.GET.get('sort', 'time')) -+ stats = Stats(self.profiler, stream=io) + if request.GET.get('stripdirs', False): + stats = stats.strip_dirs() + filter = request.GET.get('filter', None) @@ -36,5 +77,5 @@ + stats.filter_stats(filter) + stats.sort_stats(request.GET.get('psort') or 'time') stats.print_stats(int(request.GET.get('count', 100))) + response = HttpResponse('
        %s
        ' % io.getvalue()) - return response diff --git a/patch/add-django-http-cookie-value-none.patch b/patch/add-django-http-cookie-value-none.patch deleted file mode 100644 index ab75235f2e7..00000000000 --- a/patch/add-django-http-cookie-value-none.patch +++ /dev/null @@ -1,13 +0,0 @@ ---- django/http/response.py.orig 2020-07-08 14:34:42.776562458 +0200 -+++ django/http/response.py 2020-07-08 14:35:56.454687322 +0200 -@@ -197,8 +197,8 @@ - if httponly: - self.cookies[key]['httponly'] = True - if samesite: -- if samesite.lower() not in ('lax', 'strict'): -- raise ValueError('samesite must be "lax" or "strict".') -+ if samesite.lower() not in ('lax', 'strict', 'none'): -+ raise ValueError('samesite must be "lax", "strict", or "none", not "%s".' % samesite) - self.cookies[key]['samesite'] = samesite - - def setdefault(self, key, value): diff --git a/patch/change-oidc-provider-field-sizes-228.patch b/patch/change-oidc-provider-field-sizes-228.patch index 11dce45bb3e..0a96fbc4147 100644 --- a/patch/change-oidc-provider-field-sizes-228.patch +++ b/patch/change-oidc-provider-field-sizes-228.patch @@ -143,16 +143,7 @@ diff -ur oidc_provider.orig/migrations/0015_change_client_code.py oidc_provider/ diff -ur oidc_provider.orig/migrations/0016_userconsent_and_verbosenames.py oidc_provider/migrations/0016_userconsent_and_verbosenames.py --- oidc_provider.orig/migrations/0016_userconsent_and_verbosenames.py 2018-04-13 21:43:28.000000000 +0200 +++ oidc_provider/migrations/0016_userconsent_and_verbosenames.py 2020-06-07 13:34:26.826716519 +0200 -@@ -20,7 +20,7 @@ - model_name='userconsent', - name='date_given', - field=models.DateTimeField( -- default=datetime.datetime(2016, 6, 10, 17, 53, 48, 889808, tzinfo=utc), verbose_name='Date Given'), -+ default=datetime.datetime(2016, 6, 10, 17, 53, 48, 889808), verbose_name='Date Given'), - preserve_default=False, - ), - migrations.AlterField( -@@ -32,12 +32,12 @@ +@@ -31,12 +31,12 @@ migrations.AlterField( model_name='client', name='client_id', @@ -167,7 +158,7 @@ diff -ur oidc_provider.orig/migrations/0016_userconsent_and_verbosenames.py oidc ), migrations.AlterField( model_name='client', -@@ -84,17 +84,17 @@ +@@ -83,17 +83,17 @@ migrations.AlterField( model_name='code', name='code', @@ -188,7 +179,7 @@ diff -ur oidc_provider.orig/migrations/0016_userconsent_and_verbosenames.py oidc ), migrations.AlterField( model_name='code', -@@ -109,7 +109,7 @@ +@@ -108,7 +108,7 @@ migrations.AlterField( model_name='code', name='nonce', @@ -197,7 +188,7 @@ diff -ur oidc_provider.orig/migrations/0016_userconsent_and_verbosenames.py oidc ), migrations.AlterField( model_name='code', -@@ -135,7 +135,7 @@ +@@ -134,7 +134,7 @@ migrations.AlterField( model_name='token', name='access_token', @@ -206,7 +197,7 @@ diff -ur oidc_provider.orig/migrations/0016_userconsent_and_verbosenames.py oidc ), migrations.AlterField( model_name='token', -@@ -151,7 +151,7 @@ +@@ -150,7 +150,7 @@ migrations.AlterField( model_name='token', name='refresh_token', @@ -290,7 +281,7 @@ diff -ur oidc_provider.orig/migrations/0021_refresh_token_not_unique.py oidc_pro diff -ur oidc_provider.orig/models.py oidc_provider/models.py --- oidc_provider.orig/models.py 2018-09-14 21:34:52.000000000 +0200 +++ oidc_provider/models.py 2020-06-07 13:34:26.830716635 +0200 -@@ -67,8 +67,8 @@ +@@ -66,8 +66,8 @@ verbose_name=_(u'Client Type'), help_text=_(u'Confidential clients are capable of maintaining the confidentiality' u' of their credentials. Public clients are incapable.')) @@ -301,7 +292,7 @@ diff -ur oidc_provider.orig/models.py oidc_provider/models.py response_types = models.ManyToManyField(ResponseType) jwt_alg = models.CharField( max_length=10, -@@ -78,15 +78,15 @@ +@@ -77,15 +77,15 @@ help_text=_(u'Algorithm used to encode ID Tokens.')) date_created = models.DateField(auto_now_add=True, verbose_name=_(u'Date Created')) website_url = models.CharField( @@ -320,7 +311,7 @@ diff -ur oidc_provider.orig/models.py oidc_provider/models.py logo = models.FileField( blank=True, default='', upload_to='oidc_provider/clients', verbose_name=_(u'Logo Image')) reuse_consent = models.BooleanField( -@@ -186,12 +186,12 @@ +@@ -185,12 +185,12 @@ user = models.ForeignKey( settings.AUTH_USER_MODEL, verbose_name=_(u'User'), on_delete=models.CASCADE) @@ -337,7 +328,7 @@ diff -ur oidc_provider.orig/models.py oidc_provider/models.py class Meta: verbose_name = _(u'Authorization Code') -@@ -205,8 +205,8 @@ +@@ -204,8 +204,8 @@ user = models.ForeignKey( settings.AUTH_USER_MODEL, null=True, verbose_name=_(u'User'), on_delete=models.CASCADE) diff --git a/patch/django-cookie-delete-settings-and-CVE-2026-35192.patch b/patch/django-cookie-delete-settings-and-CVE-2026-35192.patch new file mode 100644 index 00000000000..3f625c33bb9 --- /dev/null +++ b/patch/django-cookie-delete-settings-and-CVE-2026-35192.patch @@ -0,0 +1,76 @@ +--- django/contrib/messages/storage/cookie.py.orig 2020-08-13 11:10:36.719177122 +0200 ++++ django/contrib/messages/storage/cookie.py 2020-08-13 11:45:23.503463150 +0200 +@@ -109,6 +109,8 @@ + response.delete_cookie( + self.cookie_name, + domain=settings.SESSION_COOKIE_DOMAIN, ++ secure=settings.SESSION_COOKIE_SECURE or None, ++ httponly=settings.SESSION_COOKIE_HTTPONLY or None, + samesite=settings.SESSION_COOKIE_SAMESITE, + ) + +--- django/http/response.py.orig 2025-12-02 22:12:05.197283001 +0000 ++++ django/http/response.py 2025-12-02 22:26:01.396576013 +0000 +@@ -286,20 +286,28 @@ + value = signing.get_cookie_signer(salt=key + salt).sign(value) + return self.set_cookie(key, value, **kwargs) + +- def delete_cookie(self, key, path="/", domain=None, samesite=None): ++ def delete_cookie(self, key, path="/", domain=None, secure=False, httponly=False, samesite=None): + # Browsers can ignore the Set-Cookie header if the cookie doesn't use + # the secure flag and: + # - the cookie name starts with "__Host-" or "__Secure-", or + # - the samesite is "none". +- secure = key.startswith(("__Secure-", "__Host-")) or ( +- samesite and samesite.lower() == "none" +- ) ++ if key in self.cookies: ++ domain = self.cookies[key].get("domain", domain) ++ secure = self.cookies[key].get("secure", secure) ++ httponly = self.cookies[key].get("httponly", httponly) ++ samesite = self.cookies[key].get("samesite", samesite) ++ else: ++ secure = secure or ( ++ key.startswith(("__Secure-", "__Host-")) or ++ (samesite and samesite.lower() == "none") ++ ) + self.set_cookie( + key, + max_age=0, + path=path, + domain=domain, + secure=secure, ++ httponly=httponly, + expires="Thu, 01 Jan 1970 00:00:00 GMT", + samesite=samesite, + ) +--- django/contrib/sessions/middleware.py.old 2026-05-12 15:18:07.673997003 +0000 ++++ django/contrib/sessions/middleware.py 2026-05-12 15:18:15.770997007 +0000 +@@ -38,12 +38,15 @@ + settings.SESSION_COOKIE_NAME, + path=settings.SESSION_COOKIE_PATH, + domain=settings.SESSION_COOKIE_DOMAIN, ++ secure=settings.SESSION_COOKIE_SECURE or None, ++ httponly=settings.SESSION_COOKIE_HTTPONLY or None, + samesite=settings.SESSION_COOKIE_SAMESITE, + ) +- patch_vary_headers(response, ("Cookie",)) ++ need_vary_cookie = True + else: +- if accessed: +- patch_vary_headers(response, ("Cookie",)) ++ # If the session was accessed, it must be varied on, regardless of ++ # whether it was modified or will be saved. ++ need_vary_cookie = accessed + if (modified or settings.SESSION_SAVE_EVERY_REQUEST) and not empty: + if request.session.get_expire_at_browser_close(): + max_age = None +@@ -74,4 +77,8 @@ + httponly=settings.SESSION_COOKIE_HTTPONLY or None, + samesite=settings.SESSION_COOKIE_SAMESITE, + ) ++ # With a session cookie set, it must be varied on. ++ need_vary_cookie = True ++ if need_vary_cookie: ++ patch_vary_headers(response, ("Cookie",)) + return response diff --git a/patch/django-cookie-delete-with-all-settings.patch b/patch/django-cookie-delete-with-all-settings.patch deleted file mode 100644 index 830f031d7fa..00000000000 --- a/patch/django-cookie-delete-with-all-settings.patch +++ /dev/null @@ -1,46 +0,0 @@ ---- django/contrib/messages/storage/cookie.py.orig 2020-08-13 11:10:36.719177122 +0200 -+++ django/contrib/messages/storage/cookie.py 2020-08-13 11:45:23.503463150 +0200 -@@ -92,6 +92,8 @@ - response.delete_cookie( - self.cookie_name, - domain=settings.SESSION_COOKIE_DOMAIN, -+ secure=settings.SESSION_COOKIE_SECURE or None, -+ httponly=settings.SESSION_COOKIE_HTTPONLY or None, - samesite=settings.SESSION_COOKIE_SAMESITE, - ) - ---- django/http/response.py.orig 2020-08-13 11:16:04.060627793 +0200 -+++ django/http/response.py 2020-08-13 11:54:03.482476973 +0200 -@@ -210,12 +210,18 @@ - value = signing.get_cookie_signer(salt=key + salt).sign(value) - return self.set_cookie(key, value, **kwargs) - -- def delete_cookie(self, key, path='/', domain=None, samesite=None): -+ def delete_cookie(self, key, path='/', domain=None, secure=False, httponly=False, samesite=None): - # Most browsers ignore the Set-Cookie header if the cookie name starts - # with __Host- or __Secure- and the cookie doesn't use the secure flag. -- secure = key.startswith(('__Secure-', '__Host-')) -+ if key in self.cookies: -+ domain = self.cookies[key].get('domain', domain) -+ secure = self.cookies[key].get('secure', secure) -+ httponly = self.cookies[key].get('httponly', httponly) -+ samesite = self.cookies[key].get('samesite', samesite) -+ else: -+ secure = secure or key.startswith(('__Secure-', '__Host-')) - self.set_cookie( -- key, max_age=0, path=path, domain=domain, secure=secure, -+ key, max_age=0, path=path, domain=domain, secure=secure, httponly=httponly, - expires='Thu, 01 Jan 1970 00:00:00 GMT', samesite=samesite, - ) - ---- django/contrib/sessions/middleware.py.orig 2020-08-13 12:12:12.401898114 +0200 -+++ django/contrib/sessions/middleware.py 2020-08-13 12:14:52.690520659 +0200 -@@ -39,6 +39,8 @@ - settings.SESSION_COOKIE_NAME, - path=settings.SESSION_COOKIE_PATH, - domain=settings.SESSION_COOKIE_DOMAIN, -+ secure=settings.SESSION_COOKIE_SECURE or None, -+ httponly=settings.SESSION_COOKIE_HTTPONLY or None, - samesite=settings.SESSION_COOKIE_SAMESITE, - ) - else: diff --git a/patch/fix-django-password-strength-kwargs.patch b/patch/fix-django-password-strength-kwargs.patch deleted file mode 100644 index 9f24ce932a9..00000000000 --- a/patch/fix-django-password-strength-kwargs.patch +++ /dev/null @@ -1,36 +0,0 @@ ---- django_password_strength/widgets.py.orig 2020-06-24 16:07:28.479533134 +0200 -+++ django_password_strength/widgets.py 2020-06-24 16:08:09.540714290 +0200 -@@ -8,7 +8,7 @@ - Form widget to show the user how strong his/her password is. - """ - -- def render(self, name, value, attrs=None): -+ def render(self, name, value, **kwargs): - strength_markup = """ -
        -
        -@@ -30,7 +30,7 @@ - except KeyError: - self.attrs['class'] = 'password_strength' - -- return mark_safe( super(PasswordInput, self).render(name, value, attrs) + strength_markup ) -+ return mark_safe( super(PasswordInput, self).render(name, value, **kwargs) + strength_markup ) - - class Media: - js = ( -@@ -48,7 +48,7 @@ - super(PasswordConfirmationInput, self).__init__(attrs, render_value) - self.confirm_with=confirm_with - -- def render(self, name, value, attrs=None): -+ def render(self, name, value, **kwargs): - if self.confirm_with: - self.attrs['data-confirm-with'] = 'id_%s' % self.confirm_with - -@@ -68,4 +68,4 @@ - except KeyError: - self.attrs['class'] = 'password_confirmation' - -- return mark_safe( super(PasswordInput, self).render(name, value, attrs) + confirmation_markup ) -+ return mark_safe( super(PasswordInput, self).render(name, value, **kwargs) + confirmation_markup ) - diff --git a/patch/fix-oidc-access-token-post.patch b/patch/fix-oidc-access-token-post.patch index 4234fdf61d2..00271633e7b 100644 --- a/patch/fix-oidc-access-token-post.patch +++ b/patch/fix-oidc-access-token-post.patch @@ -11,12 +11,10 @@ diff -ur oidc_provider.orig/lib/utils/common.py oidc_provider/lib/utils/common.p --- oidc_provider.orig/lib/utils/oauth2.py 2020-05-22 15:09:21.009044320 +0200 +++ oidc_provider/lib/utils/oauth2.py 2020-06-05 17:05:23.271285858 +0200 -@@ -21,10 +21,14 @@ - """ +@@ -22,9 +22,13 @@ auth_header = request.META.get('HTTP_AUTHORIZATION', '') -- if re.compile('^[Bb]earer\s{1}.+$').match(auth_header): -+ if re.compile(r'^[Bb]earer\s{1}.+$').match(auth_header): + if re.compile(r'^[Bb]earer\s{1}.+$').match(auth_header): access_token = auth_header.split()[1] - else: + elif request.method == 'GET': @@ -27,13 +25,4 @@ diff -ur oidc_provider.orig/lib/utils/common.py oidc_provider/lib/utils/common.p + access_token = '' return access_token - -@@ -39,7 +43,7 @@ - """ - auth_header = request.META.get('HTTP_AUTHORIZATION', '') - -- if re.compile('^Basic\s{1}.+$').match(auth_header): -+ if re.compile(r'^Basic\s{1}.+$').match(auth_header): - b64_user_pass = auth_header.split()[1] - try: - user_pass = b64decode(b64_user_pass).decode('utf-8').split(':') + diff --git a/patch/tastypie-django22-fielderror-response.patch b/patch/tastypie-django22-fielderror-response.patch index bb4decd7561..3b4418fc66b 100644 --- a/patch/tastypie-django22-fielderror-response.patch +++ b/patch/tastypie-django22-fielderror-response.patch @@ -1,26 +1,26 @@ ---- tastypie/resources.py.orig 2020-08-24 13:14:25.463166100 +0200 -+++ tastypie/resources.py 2020-08-24 13:15:55.133759224 +0200 -@@ -15,7 +15,7 @@ +--- tastypie/resources.py.orig 2025-07-29 19:00:01.526948002 +0000 ++++ tastypie/resources.py 2025-07-29 19:07:15.324127008 +0000 +@@ -12,7 +12,7 @@ ObjectDoesNotExist, MultipleObjectsReturned, ValidationError, FieldDoesNotExist ) from django.core.signals import got_request_exception -from django.core.exceptions import ImproperlyConfigured +from django.core.exceptions import ImproperlyConfigured, FieldError from django.db.models.fields.related import ForeignKey - try: - from django.contrib.gis.db.models.fields import GeometryField -@@ -2207,6 +2207,8 @@ + from django.urls.conf import re_path + from tastypie.utils.timezone import make_naive_utc +@@ -2216,6 +2216,8 @@ return self.authorized_read_list(objects, bundle) except ValueError: raise BadRequest("Invalid resource lookup data provided (mismatched type).") + except FieldError as e: + raise BadRequest("Invalid resource lookup: %s." % e) - + def obj_get(self, bundle, **kwargs): """ --- tastypie/paginator.py.orig 2020-08-25 15:24:46.391588425 +0200 +++ tastypie/paginator.py 2020-08-25 15:24:53.591797122 +0200 -@@ -128,6 +128,8 @@ +@@ -124,6 +124,8 @@ except (AttributeError, TypeError): # If it's not a QuerySet (or it's ilk), fallback to ``len``. return len(self.objects) diff --git a/playwright/.gitignore b/playwright/.gitignore new file mode 100644 index 00000000000..f38d036a792 --- /dev/null +++ b/playwright/.gitignore @@ -0,0 +1,5 @@ +node_modules/ +/test-results/ +/playwright-report/ +/playwright/.cache/ +auth.json \ No newline at end of file diff --git a/playwright/.npmrc b/playwright/.npmrc new file mode 100644 index 00000000000..fcbbb678280 --- /dev/null +++ b/playwright/.npmrc @@ -0,0 +1,5 @@ +audit = false +fund = false +save-exact = true +save-prefix = "" +update-notifier = false diff --git a/playwright/README.md b/playwright/README.md new file mode 100644 index 00000000000..78580f21ede --- /dev/null +++ b/playwright/README.md @@ -0,0 +1,57 @@ +# Playwright +##### Frontend testing automation tool + +- [Playwright Website](https://playwright.dev/) +- [Playwright Docs](https://playwright.dev/docs/intro) +- [Playwright API Reference](https://playwright.dev/docs/api/class-test) +- [Online Trace Viewer](https://trace.playwright.dev/) + +## Install + +Make sure you run all commands from the `/playwright` directory, not the project root. + +``` +npm install +npx playwright install --with-deps +``` + +## Usage + +Running all tests headless: +``` +npm test +``` + +Running all tests serially in visual mode (headed): +``` +npm run test:visual +``` + +Running all tests in debug mode: +``` +npm run test:debug +``` + +## Advanced Usage + +> Refer to the [CLI Reference](https://playwright.dev/docs/test-cli#reference) for all possible options. + +Running a single test file: +``` +npx playwright test foo.spec.ts +``` + +Running test files that have `foo` or `bar` in the filename: +``` +npx playwright test foo bar +``` + +Running tests in a specific browser *(e.g. chromium)*: +``` +npx playwright test --project=chromium +``` + +Running tests in headed mode: +``` +npx playwright test --headed +``` diff --git a/playwright/data/agenda-settings.json b/playwright/data/agenda-settings.json new file mode 100644 index 00000000000..971dc10a7f6 --- /dev/null +++ b/playwright/data/agenda-settings.json @@ -0,0 +1,32 @@ +{ + "areaIndicatorsShown": true, + "bolderText": false, + "colorLegendShown": true, + "colors": [ + { + "hex": "#0d6efd", + "tag": "Interesting" + }, + { + "hex": "#6f42c1", + "tag": "Might Attend" + }, + { + "hex": "#d63384", + "tag": "Important" + }, + { + "hex": "#ffc107", + "tag": "Food" + }, + { + "hex": "#20c997", + "tag": "Attended" + } + ], + "defaultCalendarView": "week", + "eventIconsShown": true, + "floorIndicatorsShown": true, + "listDayCollapse": false, + "redhandShown": true +} \ No newline at end of file diff --git a/playwright/data/floor-plan-images/meeting-floor-1.png b/playwright/data/floor-plan-images/meeting-floor-1.png new file mode 100644 index 00000000000..c747755758b Binary files /dev/null and b/playwright/data/floor-plan-images/meeting-floor-1.png differ diff --git a/playwright/data/floor-plan-images/meeting-floor-2.png b/playwright/data/floor-plan-images/meeting-floor-2.png new file mode 100644 index 00000000000..3c2cefc6326 Binary files /dev/null and b/playwright/data/floor-plan-images/meeting-floor-2.png differ diff --git a/playwright/data/floor-plan-images/meeting-floor-3.png b/playwright/data/floor-plan-images/meeting-floor-3.png new file mode 100644 index 00000000000..c5ce2ba8bf3 Binary files /dev/null and b/playwright/data/floor-plan-images/meeting-floor-3.png differ diff --git a/playwright/data/floor-plan-images/meeting-floor-4.jpg b/playwright/data/floor-plan-images/meeting-floor-4.jpg new file mode 100644 index 00000000000..5b641f3f3db Binary files /dev/null and b/playwright/data/floor-plan-images/meeting-floor-4.jpg differ diff --git a/playwright/data/floor-plan-images/meeting-floor-5.jpg b/playwright/data/floor-plan-images/meeting-floor-5.jpg new file mode 100644 index 00000000000..9edfcebb509 Binary files /dev/null and b/playwright/data/floor-plan-images/meeting-floor-5.jpg differ diff --git a/playwright/data/floor-plan-images/meeting-floor-6.jpg b/playwright/data/floor-plan-images/meeting-floor-6.jpg new file mode 100644 index 00000000000..cacbfe27c1d Binary files /dev/null and b/playwright/data/floor-plan-images/meeting-floor-6.jpg differ diff --git a/playwright/data/meeting-floors.json b/playwright/data/meeting-floors.json new file mode 100644 index 00000000000..83f1c661a00 --- /dev/null +++ b/playwright/data/meeting-floors.json @@ -0,0 +1,38 @@ +[ + { + "id": 1, + "path": "meeting-floor-1.png", + "width": 2094, + "height": 1650 + }, + { + "id": 2, + "path": "meeting-floor-2.png", + "width": 2496, + "height": 1142 + }, + { + "id": 3, + "path": "meeting-floor-3.png", + "width": 800, + "height": 575 + }, + { + "id": 4, + "path": "meeting-floor-4.jpg", + "width": 900, + "height": 720 + }, + { + "id": 5, + "path": "meeting-floor-5.jpg", + "width": 900, + "height": 720 + }, + { + "id": 6, + "path": "meeting-floor-6.jpg", + "width": 1175, + "height": 1075 + } +] diff --git a/playwright/helpers/common.js b/playwright/helpers/common.js new file mode 100644 index 00000000000..c4dd7e2640c --- /dev/null +++ b/playwright/helpers/common.js @@ -0,0 +1,41 @@ +module.exports = { + /** + * Validate whether a selector is visible in viewport + * + * @param {Object} page Page object + * @param {String} selector Selector to validate + * @returns Boolean + */ + isIntersectingViewport: async (page, selector) => { + return page.$eval(selector, async el => { + const bottom = window.innerHeight + const rect = el.getBoundingClientRect() + + return rect.top < bottom && rect.top > 0 - rect.height + }) + }, + /** + * Override page DateTime with a new value + * + * @param {Object} page Page object + * @param {Object} dateTimeOverride New DateTime object + */ + overridePageDateTime: async (page, dateTimeOverride) => { + await page.addInitScript(`{ + // Extend Date constructor to default to fixed time + Date = class extends Date { + constructor(...args) { + if (args.length === 0) { + super(${dateTimeOverride.toMillis()}); + } else { + super(...args); + } + } + } + // Override Date.now() to start from fixed time + const __DateNowOffset = ${dateTimeOverride.toMillis()} - Date.now(); + const __DateNow = Date.now; + Date.now = () => __DateNow() + __DateNowOffset; + }`) + } +} diff --git a/playwright/helpers/meeting.js b/playwright/helpers/meeting.js new file mode 100644 index 00000000000..634ca2e8c68 --- /dev/null +++ b/playwright/helpers/meeting.js @@ -0,0 +1,677 @@ +const { DateTime } = require('luxon') +const { faker } = require('@faker-js/faker') +const seedrandom = require('seedrandom') +const _ = require('lodash') +const slugify = require('slugify') +const ms = require('ms') + +const floorsMeta = require('../data/meeting-floors') + +const urlRe = /http[s]?:\/\/(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*(),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+/ +const conferenceDomains = ['webex.com', 'zoom.us', 'jitsi.org', 'meetecho.com', 'gather.town'] + +const xslugify = (str) => slugify(str.replace('/', '-'), { lower: true, strict: true }) + +const TEST_SEED = 123 +const sessionsWithNotes = [3, 6, 20, 48, 49, 60] +const sessionsCancelled = [29, 93] +const sessionsRescheduled = [76] +const sessionsMissingAgenda = [5, 10] +const sessionsWithWebex = [3, 4] + +// Use constant randomness seed +seedrandom(TEST_SEED.toString(), { global: true }) +faker.seed(TEST_SEED) +const { random, sample, sampleSize } = _.runInContext() + +/** + * Generate area response from label + children + */ +function createArea ({ label, children = [] }) { + return { + label, + keyword: xslugify(label), + toggled_by: [], + is_bof: false, + children: children.map(gr => { + gr.toggled_by.push(xslugify(label)) + return gr + }) + } +} + +/** + * Generate group response from label + */ +const uniqueGroupNames = [] +function createGroup ({ label, mayBeBof = false, toggledBy = [] }) { + // make sure group name is unique + while (!label) { + const nameAttempt = faker.word.verb() + if (!uniqueGroupNames.includes(nameAttempt)) { + label = nameAttempt + uniqueGroupNames.push(nameAttempt) + } + } + + // Set toggledBy + if (!toggledBy) { + toggledBy = [] + } + + // 10% chance of BoF, if enabled + const isBof = mayBeBof && random(0, 100) < 10 + if (isBof) { + toggledBy.push('bof') + } + + return { + label, + keyword: xslugify(label), + toggled_by: toggledBy, + is_bof: isBof + } +} + +/** + * Find area and group based on group slug + */ +function findAreaGroup (slug, areas) { + for (const area of areas) { + for (const group of area.children) { + if (group.keyword === slug) { + return { area, group } + } + } + } + throw new Error('Requested group does not exist!') +} + +/** + * Reverse areas and groups mapping + */ +function reverseAreaGroupsMapping (areas) { + const groups = [] + for (const area of areas) { + for (const group of area.children) { + groups.push({ + ...group, + area + }) + } + } + return groups +} + +function getEventStatus (idx) { + if (sessionsCancelled.includes(idx)) { + return 'canceled' + } else if (sessionsRescheduled.includes(idx)) { + return 'resched' + } else { + return 'sched' + } +} + +/** + * Generate event + */ +let lastEventId = 100000 +let lastSessionId = 25000 +let lastRecordingId = 150000 +function createEvent ({ + name = '', + slotName = '', + startDateTime, + duration = '1h', + area, + group, + type = 'other', + status = 'sched', + hasLocation = true, + hasNote = false, + hasAgenda = false, + showAgenda = false, + hasRecordings = false, + hasVideoStream = true, + hasWebex = false, + isBoF = false +}, floors) { + const floor = sample(floors) + const room = hasLocation ? sample(floor.rooms) : { name: 'Somewhere' } + const eventName = name ?? faker.lorem.sentence(random(2, 5)) + return { + id: ++lastEventId, + sessionId: ++lastSessionId, + room: room.name, + location: hasLocation + ? { + short: floor.short, + name: floor.name + } + : {}, + acronym: group.keyword, + duration: typeof duration === 'string' ? ms(duration) / 1000 : duration, + name: eventName, + slotName: slotName, + startDateTime: startDateTime.toISO({ includeOffset: false, suppressMilliseconds: true }), + status, + type, + isBoF, + filterKeywords: [ + 'coding', + 'hackathon', + 'hackathon-sessc' + ], + groupAcronym: group.keyword, + groupName: faker.lorem.sentence(random(2, 5)), + groupParent: { + acronym: area.keyword + }, + note: (hasNote || status === 'resched') ? faker.lorem.sentence(4) : '', + remoteInstructions: '', + flags: { + agenda: hasAgenda, + showAgenda + }, + agenda: { + url: hasAgenda ? 'https://datatracker.ietf.org/meeting/123/materials/agenda-123-ietf-sessa-00' : null + }, + orderInMeeting: 1, + short: eventName, + sessionToken: 'sessa', + links: { + chat: `https://zulip.ietf.org/#narrow/stream/${group.keyword}`, + chatArchive: `https://zulip.ietf.org/#narrow/stream/${group.keyword}`, + recordings: hasRecordings + ? [ + { + id: ++lastRecordingId, + name: `recording-123-${group.keyword}-1`, + title: `Video recording for ${group.keyword} on ${startDateTime.toFormat('yyyy-LL-dd \'at\' HH:mm:ss')}`, + url: 'https://www.youtube.com/watch?v=1eq_5xvacl0' + } + ] + : [], + videoStream: showAgenda && hasVideoStream ? 'https://meetings.conf.meetecho.com/ietf{meeting.number}/?group={group.acronym}&short={short}&item={order_number}' : null, + audioStream: hasAgenda ? 'https://mp3.conf.meetecho.com/ietf123/{group.acronym}/{order_number}.m3u' : null, + webex: hasWebex ? 'https://webex.com/123' : null, + onsiteTool: hasAgenda ? 'https://meetings.conf.meetecho.com/onsite{meeting.number}/?group={group.acronym}&short={short}&item={order_number}' : null, + calendar: `/meeting/123/session/${lastSessionId}.ics` + } + } +} + +module.exports = { + /** + * Generate a standard agenda data reponse + */ + generateAgendaResponse ({ dateMode = 'past', skipSchedule = false } = {}) { + // Get random date but always start on a saturday + let startDate = null + switch (dateMode) { + case 'current': { + startDate = DateTime.fromISO('2022-02-01T13:45:15', { zone: 'Asia/Tokyo' }).startOf('week').minus({ days: 2 }) + break + } + case 'future': { + startDate = DateTime.fromISO(faker.date.future({ years: 1 }).toISOString(), { zone: 'Asia/Tokyo' }).startOf('week').minus({ days: 2 }) + break + } + default: { + startDate = DateTime.fromISO(faker.date.past({ years: 5, refDate: DateTime.utc().minus({ months: 3 }) }).toISOString(), { zone: 'Asia/Tokyo' }).startOf('week').minus({ days: 2 }) + break + } + } + const endDate = startDate.plus({ days: 7 }) + + // Generate floors + const floors = _.times(6, (idx) => { + const floorIdx = idx + 1 + const floor = floorsMeta[idx] + return { + id: floorIdx, + image: `/media/floor/${floor.path}`, + name: `Level ${_.startCase(faker.color.human())} ${floorIdx}`, + short: `L${floorIdx}`, + width: floor.width, + height: floor.height, + rooms: _.times(random(5, 10), (ridx) => { + const roomName = `${faker.science.chemicalElement().name} ${floorIdx}-${ridx + 1}` + // Keep 10% margin on each side + const roomXUnit = Math.round(floor.width / 10) + const roomYUnit = Math.round(floor.height / 10) + const roomX = random(roomXUnit, roomXUnit * 8) + const roomY = random(roomYUnit, roomYUnit * 8) + return { + id: floorIdx * 100 + ridx, + name: roomName, + functionalName: _.startCase(faker.lorem.words(2)), + slug: xslugify(roomName), + left: roomX, + right: roomX + roomXUnit, + top: roomY, + bottom: roomY + roomYUnit + } + }) + } + }) + + // Generate categories (groups/areas) + + const categories = [] + + if (!skipSchedule) { + // Generate first group of areas + // ----------------------------- + const firstAreas = [] + const firstAreasNames = ['ABC', 'DEF', 'GHI', 'JKL', 'MNO', 'PQR', 'STU'] + for (const area of firstAreasNames) { + firstAreas.push(createArea({ + label: area, + children: _.times(random(2, 25), (idx) => { + return createGroup({ mayBeBof: true }) + }) + })) + } + categories.push(firstAreas) + + // Generate second group of areas + // ------------------------------ + const secondAreas = [] + for (const area of ['UVW', 'XYZ0']) { + secondAreas.push(createArea({ + label: area, + children: _.times(random(2, 25), (idx) => { + return createGroup({ mayBeBof: true }) + }) + })) + } + categories.push(secondAreas) + + // Generate last group of areas + // ---------------------------- + categories.push( + [ + createArea({ + label: 'Administrative', + children: [ + createGroup({ label: 'IETF Registration' }) + ] + }), + createArea({ + label: 'Coding', + children: [ + createGroup({ label: 'Hackathon', toggledBy: ['hackathon'] }), + createGroup({ label: 'Code Sprint', toggledBy: ['tools'] }) + ] + }), + createArea({ + label: 'Office hours', + children: firstAreasNames.map(n => createGroup({ label: `${n} Office Hours` })) + }), + createArea({ + label: 'Open meeting', + children: [ + createGroup({ label: 'WG Chairs Forum' }), + createGroup({ label: 'Newcomers\' Feedback Session' }) + ] + }), + createArea({ + label: 'Plenary', + children: [ + createGroup({ label: 'IETF Plenary', toggledBy: ['ietf'] }) + ] + }), + createArea({ + label: 'Presentation', + children: [ + createGroup({ label: 'Hackathon Kickoff', toggledBy: ['hackathon'] }), + createGroup({ label: 'Hackathon Project Results Presentations', toggledBy: ['hackathon'] }), + createGroup({ label: 'Host Speaker Series', toggledBy: ['ietf'] }) + ] + }), + createArea({ + label: 'Social', + children: [ + createGroup({ label: 'Newcomers\' Quick Connections' }), + createGroup({ label: 'Welcome Reception', toggledBy: ['ietf'] }), + createGroup({ label: 'Break', toggledBy: ['secretariat'] }), + createGroup({ label: 'Beverage and Snack Break', toggledBy: ['secretariat'] }), + createGroup({ label: 'Hackdemo Happy Hour', toggledBy: ['hackathon'] }) + ] + }), + createArea({ + label: 'Tutorial', + children: [ + createGroup({ label: 'Tutorial: Newcomers\' Overview' }) + ] + }), + createArea({ + label: '', + children: [ + createGroup({ label: 'BoF' }), + createGroup({ label: 'qwerty', toggledBy: ['abc'] }), + createGroup({ label: 'azerty', toggledBy: ['def'] }), + createGroup({ label: 'Tools' }) + ] + }) + ] + ) + } + + // Generate schedule + + const schedule = [] + + if (!skipSchedule) { + let sessionIdx = 0 + const daySessions = [] + const regGroups = reverseAreaGroupsMapping([...categories[0], ...categories[1]]) + + // DAY 1 - No regular sessions + // --------------------------- + const day1 = startDate + + schedule.push(createEvent({ + name: 'Hackathon', + startDateTime: day1.set({ hour: 9, minute: 30 }), + duration: '11.5h', + ...findAreaGroup('hackathon', categories[2]), + showAgenda: true, + hasAgenda: true, + hasRecordings: true, + hasVideoStream: false + }, floors)) + + schedule.push(createEvent({ + name: 'Code Sprint', + startDateTime: day1.set({ hour: 10 }), + duration: '12h', + ...findAreaGroup('code-sprint', categories[2]) + }, floors)) + + schedule.push(createEvent({ + name: 'Hackathon Kickoff', + startDateTime: day1.set({ hour: 10, minute: 30 }), + duration: '30m', + ...findAreaGroup('hackathon', categories[2]), + showAgenda: true, + hasAgenda: true, + hasRecordings: true, + hasVideoStream: false + }, floors)) + + // DAY 2 - No regular sessions + // --------------------------- + const day2 = startDate.plus({ days: 1 }) + + schedule.push(createEvent({ + name: 'Hackathon', + startDateTime: day2.set({ hour: 9, minute: 30 }), + duration: '6.5h', + ...findAreaGroup('hackathon', categories[2]), + showAgenda: true, + hasAgenda: true, + hasVideoStream: false + }, floors)) + + schedule.push(createEvent({ + name: 'IETF Registration', + startDateTime: day2.set({ hour: 10 }), + duration: '8h', + ...findAreaGroup('ietf-registration', categories[2]) + }, floors)) + + schedule.push(createEvent({ + name: 'Tutorial: Newcomers', + startDateTime: day2.set({ hour: 12, minute: 30 }), + duration: '1h', + ...findAreaGroup('tutorial-newcomers-overview', categories[2]), + showAgenda: true, + hasRecordings: true, + hasVideoStream: true + }, floors)) + + schedule.push(createEvent({ + name: 'Hackathon Results Presentations', + startDateTime: day2.set({ hour: 14 }), + duration: '2h', + ...findAreaGroup('hackathon-project-results-presentations', categories[2]) + }, floors)) + + schedule.push(createEvent({ + name: 'Newcomers\' Quick Connections (Note that pre-registration is required)', + startDateTime: day2.set({ hour: 16 }), + duration: '1h', + ...findAreaGroup('newcomers-quick-connections', categories[2]), + hasLocation: false + }, floors)) + + schedule.push(createEvent({ + name: 'ABC AD Office Hours', + startDateTime: day2.set({ hour: 16 }), + duration: '1h', + ...findAreaGroup('abc-office-hours', categories[2]) + }, floors)) + + schedule.push(createEvent({ + name: 'DEF AD Office Hours', + startDateTime: day2.set({ hour: 16, minute: 15 }), + duration: '45m', + ...findAreaGroup('def-office-hours', categories[2]) + }, floors)) + + schedule.push(createEvent({ + name: 'Welcome Reception', + startDateTime: day2.set({ hour: 17 }), + duration: '2h', + ...findAreaGroup('welcome-reception', categories[2]) + }, floors)) + + // DAY 3-7 - Regular Sessions + // -------------------------- + for (let dayIdx = 2; dayIdx < 7; dayIdx++) { + const curDay = startDate.plus({ days: dayIdx }) + daySessions.push(...sampleSize(regGroups, 24)) + + schedule.push(createEvent({ + name: 'Continental Breakfast', + startDateTime: curDay.set({ hour: 8, minute: 30 }), + duration: '1.5h', + type: 'break', + ...findAreaGroup('beverage-and-snack-break', categories[2]) + }, floors)) + + schedule.push(createEvent({ + name: 'ABC AD Office Hours', + startDateTime: curDay.set({ hour: 8, minute: 30 }), + duration: '8.5h', + ...findAreaGroup('abc-office-hours', categories[2]) + }, floors)) + + schedule.push(createEvent({ + name: 'IETF Registration', + startDateTime: curDay.set({ hour: 8, minute: 30 }), + duration: '8h', + ...findAreaGroup('ietf-registration', categories[2]) + }, floors)) + + schedule.push(createEvent({ + name: 'DEF AD Office Hours', + startDateTime: curDay.set({ hour: 9 }), + duration: '8.5h', + ...findAreaGroup('def-office-hours', categories[2]) + }, floors)) + + schedule.push(createEvent({ + name: 'GHI AD Office Hours', + startDateTime: curDay.set({ hour: 9 }), + duration: '30m', + ...findAreaGroup('ghi-office-hours', categories[2]), + hasLocation: false + }, floors)) + + // -> Session I + _.times(8, () => { // 8 lanes per session time + const { area, ...group } = daySessions.pop() + schedule.push(createEvent({ + slotName: 'Session I', + startDateTime: curDay.set({ hour: 10 }), + duration: '2h', + type: 'regular', + group, + area, + status: getEventStatus(sessionIdx), + hasNote: sessionsWithNotes.includes(sessionIdx), + isBoF: group.is_bof, + showAgenda: true, + hasAgenda: !sessionsMissingAgenda.includes(sessionIdx), + hasRecordings: !sessionsMissingAgenda.includes(sessionIdx), + hasWebex: sessionsWithWebex.includes(sessionIdx) + }, floors)) + sessionIdx++ + }) + + schedule.push(createEvent({ + name: 'Break', + startDateTime: curDay.set({ hour: 12 }), + duration: '1.5h', + type: 'break', + ...findAreaGroup('beverage-and-snack-break', categories[2]) + }, floors)) + + // -> Session II + _.times(8, () => { // 8 lanes per session time + const { area, ...group } = daySessions.pop() + schedule.push(createEvent({ + slotName: 'Session II', + startDateTime: curDay.set({ hour: 13, minute: 30 }), + duration: '1h', + type: 'regular', + group, + area, + status: getEventStatus(sessionIdx), + hasNote: sessionsWithNotes.includes(sessionIdx), + isBoF: group.is_bof, + showAgenda: true, + hasAgenda: !sessionsMissingAgenda.includes(sessionIdx), + hasRecordings: !sessionsMissingAgenda.includes(sessionIdx), + hasWebex: sessionsWithWebex.includes(sessionIdx) + }, floors)) + sessionIdx++ + }) + + // -> No 3rd session on last day + if (dayIdx < 6) { + schedule.push(createEvent({ + name: 'Beverage and Snack Break', + startDateTime: curDay.set({ hour: 14, minute: 30 }), + duration: '30m', + type: 'break', + ...findAreaGroup('beverage-and-snack-break', categories[2]) + }, floors)) + + // -> Session III + _.times(8, () => { // 8 lanes per session time + const { area, ...group } = daySessions.pop() + schedule.push(createEvent({ + slotName: 'Session III', + startDateTime: curDay.set({ hour: 15 }), + duration: '2h', + type: 'regular', + group, + area, + status: getEventStatus(sessionIdx), + hasNote: sessionsWithNotes.includes(sessionIdx), + isBoF: group.is_bof, + showAgenda: true, + hasAgenda: !sessionsMissingAgenda.includes(sessionIdx), + hasRecordings: !sessionsMissingAgenda.includes(sessionIdx), + hasWebex: sessionsWithWebex.includes(sessionIdx) + }, floors)) + sessionIdx++ + }) + } + + // -> Plenary + if (dayIdx === 4) { + schedule.push(createEvent({ + name: 'Beverage and Snack Break', + startDateTime: curDay.set({ hour: 17 }), + duration: '30m', + type: 'break', + ...findAreaGroup('beverage-and-snack-break', categories[2]) + }, floors)) + + schedule.push(createEvent({ + name: 'IETF Plenary', + startDateTime: curDay.set({ hour: 17, minute: 30 }), + duration: '2h', + type: 'plenary', + showAgenda: true, + hasAgenda: true, + hasRecordings: true, + ...findAreaGroup('ietf-plenary', categories[2]) + }, floors)) + } + } + } + + // Return response object + + return { + meeting: { + number: '123', + city: faker.location.city(), + startDate: startDate.toISODate(), + endDate: endDate.toISODate(), + updated: faker.date.between({ from: startDate.toISO(), to: endDate.toISO() }).toISOString(), + timezone: 'Asia/Tokyo', + infoNote: faker.lorem.paragraph(4), + warningNote: '' + }, + categories, + isCurrentMeeting: dateMode !== 'past', + usesNotes: true, + schedule, + floors + } + }, + + /** + * Format URL by replacing inline variables + * + * @param {String} url Raw URL + * @param {Object} session Session Object + * @param {String} meetingNumber Meeting Number + * @returns Formatted URL + */ + formatLinkUrl: (url, session, meetingNumber) => { + return url + ? url.replace('{meeting.number}', meetingNumber) + .replace('{group.acronym}', session.groupAcronym) + .replace('{short}', session.short) + .replace('{order_number}', session.orderInMeeting) + : url + }, + + /** + * Find the first URL in text matching a conference domain + * + * @param {String} txt Raw Text + * @returns First URL found + */ + findFirstConferenceUrl: (txt) => { + try { + const fUrl = txt.match(urlRe) + if (fUrl && fUrl[0].length > 0) { + const pUrl = new URL(fUrl[0]) + if (conferenceDomains.some(d => pUrl.hostname.endsWith(d))) { + return fUrl[0] + } + } + } catch (err) { } + return null + } +} diff --git a/playwright/helpers/viewports.js b/playwright/helpers/viewports.js new file mode 100644 index 00000000000..0067af17233 --- /dev/null +++ b/playwright/helpers/viewports.js @@ -0,0 +1,6 @@ +module.exports = { + desktop: [1536, 960], + smallDesktop: [1280, 800], + tablet: [768, 1024], + mobile: [360, 760] +} diff --git a/playwright/package-lock.json b/playwright/package-lock.json new file mode 100644 index 00000000000..3f354187450 --- /dev/null +++ b/playwright/package-lock.json @@ -0,0 +1,215 @@ +{ + "name": "playwright", + "version": "1.0.0", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "dependencies": { + "@faker-js/faker": "10.5.0", + "lodash": "4.18.1", + "luxon": "3.7.2", + "ms": "2.1.3", + "seedrandom": "3.0.5", + "slugify": "1.6.9" + }, + "devDependencies": { + "@playwright/test": "1.62.1", + "npm-check-updates": "23.0.1" + } + }, + "node_modules/@faker-js/faker": { + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/@faker-js/faker/-/faker-10.5.0.tgz", + "integrity": "sha512-bsxD8WLS5lIj7aaoCx1YJkktqYj5vlBUE6HWzu2Q51ksrGJ0H737ECCKlFU7Yf8Br45z9t99frBp/J7kzbMPAg==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/fakerjs" + } + ], + "license": "MIT", + "engines": { + "node": "^20.19.0 || ^22.13.0 || ^23.5.0 || >=24.0.0", + "npm": ">=10" + } + }, + "node_modules/@playwright/test": { + "version": "1.62.1", + "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.62.1.tgz", + "integrity": "sha512-DTcUc8qii+cpHvtOwggMtBRMjKZHXYWdw8syRYu2vtzuq4Wxphqq4NfCs5Zt44L6mA8rfDfj+PHnxFc/FeK6mQ==", + "dev": true, + "dependencies": { + "playwright": "1.62.1" + }, + "bin": { + "playwright": "cli.js" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/lodash": { + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.18.1.tgz", + "integrity": "sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==", + "license": "MIT" + }, + "node_modules/luxon": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/luxon/-/luxon-3.7.2.tgz", + "integrity": "sha512-vtEhXh/gNjI9Yg1u4jX/0YVPMvxzHuGgCm6tC5kZyb08yjGWGnqAjGJvcXbqQR2P3MyMEFnRbpcdFS6PBcLqew==", + "license": "MIT", + "engines": { + "node": ">=12" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "node_modules/npm-check-updates": { + "version": "23.0.1", + "resolved": "https://registry.npmjs.org/npm-check-updates/-/npm-check-updates-23.0.1.tgz", + "integrity": "sha512-e4hu3Rq4waj7SnhzvqAc5UG557mfP5e3JIFFQd7Fg3RiRkJl8yR90NFoZ1GSWUT3S/QacJndJb+7dLQBPeH+iA==", + "dev": true, + "bin": { + "ncu": "build/cli.js", + "npm-check-updates": "build/cli.js" + }, + "engines": { + "node": "^22.22.2 || ^24.15.0 || >=26.0.0", + "npm": ">=10.0.0" + } + }, + "node_modules/playwright": { + "version": "1.62.1", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.62.1.tgz", + "integrity": "sha512-0M+L3LAD8/nm554LOla9Ayx0j0tmFZ0FBcoQ7F1VuVHpM/XpiC8RcDzBQB8W5+hA8L22THxELzeF+2WcUzvcLg==", + "dev": true, + "dependencies": { + "playwright-core": "1.62.1" + }, + "bin": { + "playwright": "cli.js" + }, + "engines": { + "node": ">=20" + }, + "optionalDependencies": { + "fsevents": "2.3.2" + } + }, + "node_modules/playwright-core": { + "version": "1.62.1", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.62.1.tgz", + "integrity": "sha512-wPYSwEBJY9GHraISXqyqtx0na0LpO3XEX7jNDhntbex7tzUS7kLnZsOlFruFJB4Hi/rhDMjXGqHewDZ68nYZVw==", + "dev": true, + "bin": { + "playwright-core": "cli.js" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/seedrandom": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/seedrandom/-/seedrandom-3.0.5.tgz", + "integrity": "sha512-8OwmbklUNzwezjGInmZ+2clQmExQPvomqjL7LFqOYqtmuxRgQYqOD3mHaU+MvZn5FLUeVxVfQjwLZW/n/JFuqg==" + }, + "node_modules/slugify": { + "version": "1.6.9", + "resolved": "https://registry.npmjs.org/slugify/-/slugify-1.6.9.tgz", + "integrity": "sha512-vZ7rfeehZui7wQs438JXBckYLkIIdfHOXsaVEUMyS5fHo1483l1bMdo0EDSWYclY0yZKFOipDy4KHuKs6ssvdg==", + "license": "MIT", + "engines": { + "node": ">=8.0.0" + } + } + }, + "dependencies": { + "@faker-js/faker": { + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/@faker-js/faker/-/faker-10.5.0.tgz", + "integrity": "sha512-bsxD8WLS5lIj7aaoCx1YJkktqYj5vlBUE6HWzu2Q51ksrGJ0H737ECCKlFU7Yf8Br45z9t99frBp/J7kzbMPAg==" + }, + "@playwright/test": { + "version": "1.62.1", + "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.62.1.tgz", + "integrity": "sha512-DTcUc8qii+cpHvtOwggMtBRMjKZHXYWdw8syRYu2vtzuq4Wxphqq4NfCs5Zt44L6mA8rfDfj+PHnxFc/FeK6mQ==", + "dev": true, + "requires": { + "playwright": "1.62.1" + } + }, + "fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "optional": true + }, + "lodash": { + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.18.1.tgz", + "integrity": "sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==" + }, + "luxon": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/luxon/-/luxon-3.7.2.tgz", + "integrity": "sha512-vtEhXh/gNjI9Yg1u4jX/0YVPMvxzHuGgCm6tC5kZyb08yjGWGnqAjGJvcXbqQR2P3MyMEFnRbpcdFS6PBcLqew==" + }, + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "npm-check-updates": { + "version": "23.0.1", + "resolved": "https://registry.npmjs.org/npm-check-updates/-/npm-check-updates-23.0.1.tgz", + "integrity": "sha512-e4hu3Rq4waj7SnhzvqAc5UG557mfP5e3JIFFQd7Fg3RiRkJl8yR90NFoZ1GSWUT3S/QacJndJb+7dLQBPeH+iA==", + "dev": true + }, + "playwright": { + "version": "1.62.1", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.62.1.tgz", + "integrity": "sha512-0M+L3LAD8/nm554LOla9Ayx0j0tmFZ0FBcoQ7F1VuVHpM/XpiC8RcDzBQB8W5+hA8L22THxELzeF+2WcUzvcLg==", + "dev": true, + "requires": { + "fsevents": "2.3.2", + "playwright-core": "1.62.1" + } + }, + "playwright-core": { + "version": "1.62.1", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.62.1.tgz", + "integrity": "sha512-wPYSwEBJY9GHraISXqyqtx0na0LpO3XEX7jNDhntbex7tzUS7kLnZsOlFruFJB4Hi/rhDMjXGqHewDZ68nYZVw==", + "dev": true + }, + "seedrandom": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/seedrandom/-/seedrandom-3.0.5.tgz", + "integrity": "sha512-8OwmbklUNzwezjGInmZ+2clQmExQPvomqjL7LFqOYqtmuxRgQYqOD3mHaU+MvZn5FLUeVxVfQjwLZW/n/JFuqg==" + }, + "slugify": { + "version": "1.6.9", + "resolved": "https://registry.npmjs.org/slugify/-/slugify-1.6.9.tgz", + "integrity": "sha512-vZ7rfeehZui7wQs438JXBckYLkIIdfHOXsaVEUMyS5fHo1483l1bMdo0EDSWYclY0yZKFOipDy4KHuKs6ssvdg==" + } + } +} diff --git a/playwright/package.json b/playwright/package.json new file mode 100644 index 00000000000..d33dca96930 --- /dev/null +++ b/playwright/package.json @@ -0,0 +1,22 @@ +{ + "scripts": { + "install-deps": "playwright install --with-deps", + "test": "playwright test", + "test:legacy": "playwright test -c playwright-legacy.config.js", + "test:legacy:visual": "playwright test -c playwright-legacy.config.js --headed --workers=1", + "test:visual": "playwright test --headed --workers=1", + "test:debug": "playwright test --debug" + }, + "dependencies": { + "@faker-js/faker": "10.5.0", + "lodash": "4.18.1", + "luxon": "3.7.2", + "ms": "2.1.3", + "seedrandom": "3.0.5", + "slugify": "1.6.9" + }, + "devDependencies": { + "@playwright/test": "1.62.1", + "npm-check-updates": "23.0.1" + } +} diff --git a/playwright/playwright-legacy.config.js b/playwright/playwright-legacy.config.js new file mode 100644 index 00000000000..df51f9377bd --- /dev/null +++ b/playwright/playwright-legacy.config.js @@ -0,0 +1,107 @@ +// @ts-check +const { devices } = require('@playwright/test') + +/** + * Read environment variables from file. + * https://github.com/motdotla/dotenv + */ +// require('dotenv').config(); + +/** + * @see https://playwright.dev/docs/test-configuration + * @type {import('@playwright/test').PlaywrightTestConfig} + */ +const config = { + testDir: './tests-legacy', + /* Maximum time one test can run for. */ + timeout: 120 * 1000, + expect: { + /** + * Maximum time expect() should wait for the condition to be met. + * For example in `await expect(locator).toHaveText();` + */ + timeout: 5000 + }, + /* Run tests in files in parallel */ + fullyParallel: true, + /* Fail the build on CI if you accidentally left test.only in the source code. */ + forbidOnly: !!process.env.CI, + /* Retry on CI only */ + retries: process.env.CI ? 2 : 0, + /* Opt out of parallel tests on CI. */ + workers: process.env.CI ? 1 : undefined, + /* Reporter to use. See https://playwright.dev/docs/test-reporters */ + reporter: process.env.CI ? 'github' : 'list', + /* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */ + use: { + /* Maximum time each action such as `click()` can take. Defaults to 0 (no limit). */ + actionTimeout: 0, + /* Base URL to use in actions like `await page.goto('/')`. */ + baseURL: 'http://localhost:8000', + + locale: 'en-US', + timezoneId: 'America/Toronto', + + screenshot: 'only-on-failure', + + /* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */ + trace: 'on-first-retry' + }, + + /* Configure projects for major browsers */ + projects: [ + { + name: 'chromium', + use: { + ...devices['Desktop Chrome'] + } + }, + + { + name: 'firefox', + use: { + ...devices['Desktop Firefox'] + } + } + + // { + // name: 'webkit', + // use: { + // ...devices['Desktop Safari'] + // } + // } + + /* Test against mobile viewports. */ + // { + // name: 'Mobile Chrome', + // use: { + // ...devices['Pixel 5'], + // }, + // }, + // { + // name: 'Mobile Safari', + // use: { + // ...devices['iPhone 12'], + // }, + // }, + + /* Test against branded browsers. */ + // { + // name: 'Microsoft Edge', + // use: { + // channel: 'msedge', + // }, + // }, + // { + // name: 'Google Chrome', + // use: { + // channel: 'chrome', + // }, + // }, + ] + + /* Folder for test artifacts such as screenshots, videos, traces, etc. */ + // outputDir: 'test-results/' +} + +module.exports = config diff --git a/playwright/playwright.config.js b/playwright/playwright.config.js new file mode 100644 index 00000000000..dd172a1b8d1 --- /dev/null +++ b/playwright/playwright.config.js @@ -0,0 +1,116 @@ +// @ts-check +const { devices } = require('@playwright/test') + +/** + * Read environment variables from file. + * https://github.com/motdotla/dotenv + */ +// require('dotenv').config(); + +/** + * @see https://playwright.dev/docs/test-configuration + * @type {import('@playwright/test').PlaywrightTestConfig} + */ +const config = { + testDir: './tests', + /* Maximum time one test can run for. */ + timeout: 120 * 1000, + expect: { + /** + * Maximum time expect() should wait for the condition to be met. + * For example in `await expect(locator).toHaveText();` + */ + timeout: 5000 + }, + /* Run tests in files in parallel */ + fullyParallel: true, + /* Fail the build on CI if you accidentally left test.only in the source code. */ + forbidOnly: !!process.env.CI, + /* Retry on CI only */ + retries: process.env.CI ? 2 : 0, + /* Opt out of parallel tests on CI. */ + workers: process.env.CI ? 1 : undefined, + /* Reporter to use. See https://playwright.dev/docs/test-reporters */ + reporter: process.env.CI ? 'github' : 'list', + /* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */ + use: { + /* Maximum time each action such as `click()` can take. Defaults to 0 (no limit). */ + actionTimeout: 0, + /* Base URL to use in actions like `await page.goto('/')`. */ + baseURL: 'http://localhost:3000', + + locale: 'en-US', + timezoneId: 'America/Toronto', + + screenshot: 'only-on-failure', + + /* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */ + trace: 'on-first-retry' + }, + + /* Configure projects for major browsers */ + projects: [ + { + name: 'chromium', + use: { + ...devices['Desktop Chrome'] + } + }, + + { + name: 'firefox', + use: { + ...devices['Desktop Firefox'] + } + } + + // { + // name: 'webkit', + // use: { + // ...devices['Desktop Safari'] + // } + // } + + /* Test against mobile viewports. */ + // { + // name: 'Mobile Chrome', + // use: { + // ...devices['Pixel 5'], + // }, + // }, + // { + // name: 'Mobile Safari', + // use: { + // ...devices['iPhone 12'], + // }, + // }, + + /* Test against branded browsers. */ + // { + // name: 'Microsoft Edge', + // use: { + // channel: 'msedge', + // }, + // }, + // { + // name: 'Google Chrome', + // use: { + // channel: 'chrome', + // }, + // }, + ], + + /* Folder for test artifacts such as screenshots, videos, traces, etc. */ + // outputDir: 'test-results/', + + /* Run your local dev server before starting the tests */ + ...process.env.CI && { + webServer: { + command: 'cd .. && npm run preview', + port: 3000, + reuseExistingServer: false + } + } +} + +module.exports = config diff --git a/playwright/tests-legacy/docs/ad.spec.js b/playwright/tests-legacy/docs/ad.spec.js new file mode 100644 index 00000000000..80b8b27cda4 --- /dev/null +++ b/playwright/tests-legacy/docs/ad.spec.js @@ -0,0 +1,26 @@ +const { test, expect } = require('@playwright/test') +const viewports = require('../../helpers/viewports') + +// ==================================================================== +// IESG Dashboard +// ==================================================================== + +test.describe('/doc/ad/', () => { + test.beforeEach(async ({ page }) => { + await page.setViewportSize({ + width: viewports.desktop[0], + height: viewports.desktop[1] + }) + + await page.goto('/doc/ad/') + }) + + test('Pre pubreq', async ({ page }) => { + const tablesLocator = page.locator('table') + const tablesCount = await tablesLocator.count() + expect(tablesCount).toBeGreaterThan(0) + const firstTable = tablesLocator.nth(0) + const theadTexts = await firstTable.locator('thead').allInnerTexts() + expect(theadTexts.join('')).toContain('Pre pubreq') + }) +}) diff --git a/playwright/tests-legacy/nomcom/expertise.spec.js b/playwright/tests-legacy/nomcom/expertise.spec.js new file mode 100644 index 00000000000..ff04426edf6 --- /dev/null +++ b/playwright/tests-legacy/nomcom/expertise.spec.js @@ -0,0 +1,52 @@ +const { test, expect } = require('@playwright/test') +const viewports = require('../../helpers/viewports') + +// ==================================================================== +// NOMCOM - EXPERTISE +// ==================================================================== + +test.describe('expertise', () => { + test.beforeEach(async ({ page }) => { + await page.setViewportSize({ + width: viewports.desktop[0], + height: viewports.desktop[1] + }) + + await page.goto('/nomcom/2021/expertise/') + }) + + test('expertises with expandable panels should expand', async ({ page }) => { + const tabsLocator = page.locator('.nomcom-req-positions-tabs > li > button') + const tabsCount = await tabsLocator.count() + + expect(tabsCount).toBeGreaterThan(0) + + for (let idx = 0; idx < tabsCount; idx++) { + await tabsLocator.nth(idx).click() + await expect(tabsLocator.nth(idx)).toHaveClass(/active/) + + const targetId = await tabsLocator.nth(idx).getAttribute('data-bs-target') + + const paneLocator = page.locator(targetId) + + await expect(paneLocator).toBeVisible() + await expect(paneLocator).toHaveClass(/tab-pane/) + await expect(paneLocator).toHaveClass(/active/) + + // Check accordion + const accordionHeadsLocator = paneLocator.locator('.accordion-header > button') + const accordionHeadsCount = await accordionHeadsLocator.count() + + if (accordionHeadsCount > 0) { + for (let aIdx = 0; aIdx < accordionHeadsCount; aIdx++) { + await accordionHeadsLocator.nth(aIdx).click() + const expandPaneId = await accordionHeadsLocator.nth(aIdx).getAttribute('data-bs-target') + + const sectionLocator = page.locator(expandPaneId) + + await expect(sectionLocator).toBeVisible() + } + } + } + }) +}) diff --git a/playwright/tests-legacy/nomcom/questionnaires.spec.js b/playwright/tests-legacy/nomcom/questionnaires.spec.js new file mode 100644 index 00000000000..662000e4dee --- /dev/null +++ b/playwright/tests-legacy/nomcom/questionnaires.spec.js @@ -0,0 +1,37 @@ +const { test, expect } = require('@playwright/test') +const viewports = require('../../helpers/viewports') + +// ==================================================================== +// NOMCOM - QUESTIONNAIRES +// ==================================================================== + +test.describe('expertise', () => { + test.beforeEach(async ({ page }) => { + await page.setViewportSize({ + width: viewports.desktop[0], + height: viewports.desktop[1] + }) + + await page.goto('/nomcom/2021/questionnaires/') + }) + + test('position tabs should display the appropriate panel on click', async ({ page }) => { + const tabsLocator = page.locator('.nomcom-questnr-positions-tabs > li > button') + const tabsCount = await tabsLocator.count() + + expect(tabsCount).toBeGreaterThan(0) + + for (let idx = 0; idx < tabsCount; idx++) { + await tabsLocator.nth(idx).click() + await expect(tabsLocator.nth(idx)).toHaveClass(/active/) + + const targetId = await tabsLocator.nth(idx).getAttribute('data-bs-target') + + const paneLocator = page.locator(targetId) + + await expect(paneLocator).toBeVisible() + await expect(paneLocator).toHaveClass(/tab-pane/) + await expect(paneLocator).toHaveClass(/active/) + } + }) +}) diff --git a/playwright/tests-legacy/secr/announcement.spec.js b/playwright/tests-legacy/secr/announcement.spec.js new file mode 100644 index 00000000000..4dbbc25a813 --- /dev/null +++ b/playwright/tests-legacy/secr/announcement.spec.js @@ -0,0 +1,77 @@ +const { test, expect } = require('@playwright/test') +const viewports = require('../../helpers/viewports') +const { setTimeout } = require('timers/promises') + +// ==================================================================== +// ANNOUNCEMENT | DESKTOP viewport +// ==================================================================== + +test.describe('desktop', () => { + + test.beforeAll(async ({ browser }) => { + const context = await browser.newContext(); + const page = await context.newPage(); + + await page.goto('/accounts/login/'); + + await page.fill('input#id_username', 'glen'); + await page.fill('input#id_password', 'password'); + + await page.click('button[type="submit"]'); + await page.waitForURL('/accounts/profile/'); + + await context.storageState({ path: 'auth.json' }); + + await context.close(); + }); + + test.beforeEach(async ({ browser }) => { + // Reuse the authentication state in each test + const context = await browser.newContext({ storageState: 'auth.json' }); + const page = await context.newPage(); + await page.setViewportSize({ + width: viewports.desktop[0], + height: viewports.desktop[1] + }) + await page.goto(`/secr/announcement/`); + await page.locator('h1:text("Announcement")').waitFor({ state: 'visible' }) + await setTimeout(500) + // Attach the page to the test context + test.info().page = page; + }) + + test('show to custom', async () => { + const page = test.info().page; + + // to_custom should initially be hidden + const element = page.locator('#id_to_custom'); + await expect(element).toBeHidden(); + await page.selectOption('select#id_to', 'Other...'); + await expect(element).toBeVisible(); + }) + + test('back button', async () => { + const page = test.info().page; + + const element = page.locator('#id_to_custom'); + await page.selectOption('select#id_to', 'Other...'); + await expect(element).toBeVisible(); + await page.fill('input#id_to_custom', 'custom@example.com'); + await page.selectOption('select#id_frm', 'IETF Chair '); + await page.fill('input#id_reply_to', 'greg@example.com'); + await page.fill('input#id_subject', 'About Stuff'); + await page.fill('textarea#id_body', 'This is the stuff'); + + await page.click('text="Continue"'); + const h2Locator = page.locator('h2:text("Confirm Announcement")'); + await h2Locator.waitFor({ state: 'visible' }); + + // click back button and check to_custom + await page.click('text="Back"'); + const subjectLocator = page.locator('input#id_subject'); + await subjectLocator.waitFor({ state: 'visible' }); + await expect(element).toBeVisible(); + await expect(element).toHaveValue('custom@example.com'); + }) + +}) \ No newline at end of file diff --git a/playwright/tests/meeting/agenda.spec.js b/playwright/tests/meeting/agenda.spec.js new file mode 100644 index 00000000000..2248027a38a --- /dev/null +++ b/playwright/tests/meeting/agenda.spec.js @@ -0,0 +1,1558 @@ +const { test, expect } = require('@playwright/test') +const { DateTime } = require('luxon') +const { faker } = require('@faker-js/faker') +const seedrandom = require('seedrandom') +const slugify = require('slugify') +const commonHelper = require('../../helpers/common') +const meetingHelper = require('../../helpers/meeting.js') +const viewports = require('../../helpers/viewports') +const _ = require('lodash') +const fs = require('fs/promises') +const { setTimeout } = require('timers/promises') + +const xslugify = (str) => slugify(str.replace('/', '-'), { lower: true, strict: true }) + +const TEST_SEED = 123 +const BROWSER_LOCALE = 'en-US' +const BROWSER_TIMEZONE = 'America/Toronto' + +// Set randomness seed +seedrandom(TEST_SEED.toString(), { global: true }) +faker.seed(TEST_SEED) +const { random, shuffle } = _.runInContext() + +// ==================================================================== +// AGENDA (past meeting) | DESKTOP viewport +// ==================================================================== + +test.describe('past - desktop', () => { + let meetingData + + test.beforeAll(async () => { + // Generate meeting data + meetingData = meetingHelper.generateAgendaResponse({ dateMode: 'past' }) + }) + + test.beforeEach(async ({ page }) => { + // Intercept Meeting Data API + await page.route(`**/api/meeting/${meetingData.meeting.number}/agenda-data`, route => { + route.fulfill({ + status: 200, + contentType: 'application/json', + body: JSON.stringify(meetingData) + }) + }) + + await page.setViewportSize({ + width: viewports.desktop[0], + height: viewports.desktop[1] + }) + + // Visit agenda page and await Meeting Data API call to complete + await Promise.all([ + page.waitForResponse(`**/api/meeting/${meetingData.meeting.number}/agenda-data`), + page.goto(`/meeting/${meetingData.meeting.number}/agenda`) + ]) + + // Wait for page to be ready + await page.locator('.agenda h1').waitFor({ state: 'visible' }) + await setTimeout(500) + }) + + test('agenda header section', async ({ page }) => { + // HEADER + await expect(page.locator('.agenda h1'), 'should have agenda title').toContainText(`IETF ${meetingData.meeting.number} Meeting Agenda`) + await expect(page.locator('.agenda h4').first(), 'should have meeting city subtitle').toContainText(meetingData.meeting.city) + await expect(page.locator('.agenda h4').first(), 'should have meeting date subtitle').toContainText(/[a-zA-Z] [0-9]{1,2} - ([a-zA-Z]+ )?[0-9]{1,2}, [0-9]{4}/i) + + const updatedDateTime = DateTime.fromISO(meetingData.meeting.updated) + .setZone(meetingData.meeting.timezone) + .setLocale(BROWSER_LOCALE) + .toFormat('DD \'at\' T ZZZZ') + await expect(page.locator('.agenda h6').first(), 'should have meeting last updated datetime').toContainText(updatedDateTime) + + // NAV + + await test.step('has the correct navigation items', async () => { + const navLocator = page.locator('.agenda .meeting-nav > li') + await expect(navLocator).toHaveCount(3) + await expect(navLocator.first()).toContainText('Agenda') + await expect(navLocator.nth(1)).toContainText('Floor plan') + await expect(navLocator.last()).toContainText('Plaintext') + }) + + // RIGHT-SIDE BUTTONS + + await test.step('has the correct right side buttons', async () => { + const btnsLocator = page.locator('.agenda .agenda-topnav-right > button') + await expect(btnsLocator).toHaveCount(3) + await expect(btnsLocator.first()).toContainText('Help') + await expect(btnsLocator.nth(1)).toContainText('Share') + await expect(btnsLocator.last()).toContainText('Settings') + }) + }) + + test('agenda schedule list header', async ({ page }) => { + const infonoteLocator = page.locator('.agenda .agenda-infonote') + const infonoteToggleLocator = page.locator('.agenda h2 + button') + const tzMeetingBtnLocator = page.locator('.agenda .agenda-tz-selector > button:nth-child(1)') + const tzLocalBtnLocator = page.locator('.agenda .agenda-tz-selector > button:nth-child(2)') + const tzUtcBtnLocator = page.locator('.agenda .agenda-tz-selector > button:nth-child(3)') + + await expect(page.locator('.agenda h2')).toContainText('Schedule') + await expect(infonoteLocator).toBeVisible() + await expect(infonoteLocator).toContainText(meetingData.meeting.infoNote) + + // INFO-NOTE TOGGLE + + await test.step('info note can be dismissed / reopened', async () => { + await page.locator('.agenda .agenda-infonote > button').click() + await expect(infonoteLocator).not.toBeVisible() + await expect(infonoteToggleLocator).toBeVisible() + await infonoteToggleLocator.click() + await expect(infonoteLocator).toBeVisible() + await expect(infonoteToggleLocator).not.toBeVisible() + }) + + // TIMEZONE SELECTOR + + await test.step('has timezone selector', async () => { + await expect(page.locator('.agenda .agenda-tz-selector')).toBeVisible() + await expect(page.locator('small:left-of(.agenda .agenda-tz-selector)')).toContainText('Timezone:') + await expect(page.locator('.agenda .agenda-tz-selector > button')).toHaveCount(3) + await expect(tzMeetingBtnLocator).toContainText('Meeting') + await expect(tzLocalBtnLocator).toContainText('Local') + await expect(tzUtcBtnLocator).toContainText('UTC') + await expect(page.locator('.agenda .agenda-timezone-ddn')).toBeVisible() + }) + + // CHANGE TIMEZONE + + await test.step('can change timezone', async () => { + // Switch to local timezone + await tzLocalBtnLocator.click() + await expect(tzLocalBtnLocator).toHaveClass(/n-button--primary-type/) + await expect(tzMeetingBtnLocator).not.toHaveClass(/n-button--primary-type/) + const localDateTime = DateTime.fromISO(meetingData.meeting.updated) + .setZone(BROWSER_TIMEZONE) + .setLocale(BROWSER_LOCALE) + .toFormat('DD \'at\' T ZZZZ') + await expect(page.locator('.agenda h6').first()).toContainText(localDateTime) + await expect(page.locator('.agenda .agenda-table-display-session-head .agenda-table-cell-name').first()).toContainText('Monday Session I') + // Switch to UTC + await tzUtcBtnLocator.click() + await expect(tzUtcBtnLocator).toHaveClass(/n-button--primary-type/) + await expect(tzLocalBtnLocator).not.toHaveClass(/n-button--primary-type/) + const utcDateTime = DateTime.fromISO(meetingData.meeting.updated) + .setZone('utc') + .setLocale(BROWSER_LOCALE) + .toFormat('DD \'at\' T ZZZZ') + await expect(page.locator('.agenda h6').first()).toContainText(utcDateTime) + await expect(page.locator('.agenda .agenda-timezone-ddn')).toContainText('UTC') + await expect(page.locator('.agenda .agenda-table-display-session-head .agenda-table-cell-name').first()).toContainText('Monday Session I') + // Switch back to meeting timezone + await tzMeetingBtnLocator.click() + await expect(tzMeetingBtnLocator).toHaveClass(/n-button--primary-type/) + await expect(page.locator('.agenda .agenda-timezone-ddn')).toContainText('Tokyo') + await expect(page.locator('.agenda .agenda-table-display-session-head .agenda-table-cell-name').first()).toContainText('Monday Session I') + }) + }) + + test('agenda schedule list table', async ({ page }) => { + const dayHeadersLocator = page.locator('.agenda-table-display-day') + + // TABLE HEADERS + + await expect(page.locator('.agenda-table-head-time')).toContainText('Time') + await expect(page.locator('.agenda-table-head-location')).toContainText('Location') + await expect(page.locator('.agenda-table-head-event')).toContainText('Event') + + // DAY HEADERS + + await expect(dayHeadersLocator).toHaveCount(7) + for (let idx = 0; idx < 7; idx++) { + const localDateTime = DateTime.fromISO(meetingData.meeting.startDate, { zone: BROWSER_TIMEZONE }) + .setZone(BROWSER_TIMEZONE) + .setLocale(BROWSER_LOCALE) + .plus({ days: idx }) + .toLocaleString(DateTime.DATE_HUGE) + await expect(dayHeadersLocator.nth(idx)).toContainText(localDateTime) + } + }) + + test('agenda schedule list table events', async ({ page }) => { + test.slow() // Triple the default timeout + + const eventRowsLocator = page.locator('.agenda-table .agenda-table-display-event') + + await expect(eventRowsLocator).toHaveCount(meetingData.schedule.length) + + let isFirstSession = true + for (let idx = 0; idx < meetingData.schedule.length; idx++) { + const row = eventRowsLocator.nth(idx) + const event = meetingData.schedule[idx] + const eventStart = DateTime.fromISO(event.startDateTime) + const eventEnd = eventStart.plus({ seconds: event.duration }) + const eventTimeSlot = `${eventStart.toFormat('HH:mm')} - ${eventEnd.toFormat('HH:mm')}` + // -------- + // Location + // -------- + if (event.location?.short) { + // Has floor badge + await expect(row.locator('.agenda-table-cell-room > a')).toContainText(event.room) + await expect(row.locator('.agenda-table-cell-room > a')).toHaveAttribute('href', `/meeting/${meetingData.meeting.number}/floor-plan?room=${xslugify(event.room)}`) + await expect(row.locator('.agenda-table-cell-room > .badge')).toContainText(event.location.short) + } else { + // No floor badge + await expect(row.locator('.agenda-table-cell-room > span:not(.badge)')).toContainText(event.room) + await expect(row.locator('.agenda-table-cell-room > .badge')).not.toBeVisible() + } + // --------------------------------------------------- + // Type-specific timeslot / group / name columns tests + // --------------------------------------------------- + if (event.type === 'regular') { + // First session should have header row above it + if (isFirstSession) { + const headerRow = page.locator(`#agenda-rowid-sesshd-${event.id}`) + await expect(headerRow).toBeVisible() + await expect(headerRow.locator('.agenda-table-cell-ts')).toContainText(eventTimeSlot) + await expect(headerRow.locator('.agenda-table-cell-name')).toContainText(`${DateTime.fromISO(event.startDateTime).toFormat('cccc')} ${event.slotName}`) + } + // Timeslot + await expect(row.locator('.agenda-table-cell-ts')).toContainText('—') + // Group Acronym + Parent + await expect(row.locator('.agenda-table-cell-group > .badge')).toContainText(event.groupParent.acronym) + await expect(row.locator('.agenda-table-cell-group > .badge + a')).toContainText(event.acronym) + await expect(row.locator('.agenda-table-cell-group > .badge + a')).toHaveAttribute('href', `/group/${event.acronym}/about/`) + // Group Name + await expect(row.locator('.agenda-table-cell-name')).toContainText(event.groupName) + isFirstSession = false + } else { + // Timeslot + await expect(row.locator('.agenda-table-cell-ts')).toContainText(eventTimeSlot) + // Event Name + await expect(row.locator('.agenda-table-cell-name')).toContainText(event.name) + isFirstSession = true + } + // ----------- + // Name column + // ----------- + // Event icon + if (['break', 'plenary'].includes(event.type) || (event.type === 'other' && event.name.toLowerCase().indexOf('office hours') >= 0)) { + await expect(row.locator('.agenda-table-cell-name > i.bi')).toBeVisible() + } + // Name link + if (event.flags.agenda) { + await expect(row.locator('.agenda-table-cell-name > a')).toHaveAttribute('href', event.agenda.url) + } + // BoF badge + if (event.isBoF) { + await expect(row.locator('.agenda-table-cell-name > .badge')).toContainText('BoF') + } + // Note + if (event.note) { + await expect(row.locator('.agenda-table-cell-name > .agenda-table-note')).toBeVisible() + await expect(row.locator('.agenda-table-cell-name > .agenda-table-note i.bi')).toBeVisible() + await expect(row.locator('.agenda-table-cell-name > .agenda-table-note i.bi + span')).toContainText(event.note) + } + // ----------------------- + // Buttons / Status Column + // ----------------------- + switch (event.status) { + // Cancelled + case 'canceled': { + await expect(row.locator('.agenda-table-cell-links > .badge.is-cancelled')).toContainText('Cancelled') + break + } + // Rescheduled + case 'resched': { + await expect(row.locator('.agenda-table-cell-links > .badge.is-rescheduled')).toContainText('Rescheduled') + break + } + // Scheduled + case 'sched': { + if (event.flags.showAgenda || (['regular', 'plenary', 'other'].includes(event.type) && !['admin', 'closed_meeting', 'officehours', 'social'].includes(event.purpose))) { + const eventButtons = row.locator('.agenda-table-cell-links > .agenda-table-cell-links-buttons') + if (event.flags.agenda) { + // Show meeting materials button + await expect(eventButtons.locator(`#btn-btn-${event.id}-mat`)).toBeVisible() + // ZIP materials button + await expect(eventButtons.locator(`#btn-lnk-${event.id}-tar`)).toHaveAttribute('href', `/meeting/${meetingData.meeting.number}/agenda/${event.acronym}-drafts.tgz`) + await expect(eventButtons.locator(`#btn-lnk-${event.id}-tar > i.bi`)).toBeVisible() + // PDF materials button + await expect(eventButtons.locator(`#btn-lnk-${event.id}-pdf`)).toHaveAttribute('href', `/meeting/${meetingData.meeting.number}/agenda/${event.acronym}-drafts.pdf`) + await expect(eventButtons.locator(`#btn-lnk-${event.id}-pdf > i.bi`)).toBeVisible() + } else if (event.type === 'regular') { + // No meeting materials yet warning badge + await expect(eventButtons.locator('.no-meeting-materials')).toBeVisible() + } + if (event.groupAcronym === 'hackathon') { + // Hackathon Wiki button + const hackathonWikiLink = `https://wiki.ietf.org/meeting/${meetingData.meeting.number}/hackathon` + await expect(eventButtons.locator(`#btn-lnk-${event.id}-wiki`)).toHaveAttribute('href', hackathonWikiLink) + await expect(eventButtons.locator(`#btn-lnk-${event.id}-wiki > i.bi`)).toBeVisible() + } else { + // Notepad button + const hedgeDocLink = `https://notes.ietf.org/notes-ietf-${meetingData.meeting.number}-${event.type === 'plenary' ? 'plenary' : event.acronym}` + await expect(eventButtons.locator(`#btn-lnk-${event.id}-note`)).toHaveAttribute('href', hedgeDocLink) + await expect(eventButtons.locator(`#btn-lnk-${event.id}-note > i.bi`)).toBeVisible() + } + // Chat logs + await expect(eventButtons.locator(`#btn-lnk-${event.id}-logs`)).toHaveAttribute('href', event.links.chatArchive) + await expect(eventButtons.locator(`#btn-lnk-${event.id}-logs > i.bi`)).toBeVisible() + // Recordings + for (const rec of event.links.recordings) { + if (rec.url.indexOf('audio') > 0) { + // -> Audio + await expect(eventButtons.locator(`#btn-lnk-${event.id}-audio-${rec.id}`)).toHaveAttribute('href', rec.url) + await expect(eventButtons.locator(`#btn-lnk-${event.id}-audio-${rec.id} > i.bi`)).toBeVisible() + } else if (rec.url.indexOf('youtu') > 0) { + // -> Youtube + await expect(eventButtons.locator(`#btn-lnk-${event.id}-youtube-${rec.id}`)).toHaveAttribute('href', rec.url) + await expect(eventButtons.locator(`#btn-lnk-${event.id}-youtube-${rec.id} > i.bi`)).toBeVisible() + } else { + // -> Others + await expect(eventButtons.locator(`#btn-lnk-${event.id}-video-${rec.id}`)).toHaveAttribute('href', rec.url) + await expect(eventButtons.locator(`#btn-lnk-${event.id}-video-${rec.id} > i.bi`)).toBeVisible() + } + } + // Video Stream + if (event.links.videoStream) { + const videoStreamLink = `https://www.meetecho.com/ietf${meetingData.meeting.number}/recordings#${event.acronym.toUpperCase()}` + await expect(eventButtons.locator(`#btn-lnk-${event.id}-rec`)).toHaveAttribute('href', videoStreamLink) + await expect(eventButtons.locator(`#btn-lnk-${event.id}-rec > i.bi`)).toBeVisible() + } + } else { + await expect(row.locator('.agenda-table-cell-links > .agenda-table-cell-links-buttons')).not.toBeVisible() + } + break + } + } + } + }) + + test('agenda schedule list search', async ({ page }) => { + const eventRowsLocator = page.locator('.agenda-table .agenda-table-display-event') + const searchInputLocator = page.locator('.agenda-search input[type=text]') + + await page.locator('.agenda-table > .agenda-table-search > button').click() + await expect(page.locator('.agenda-search')).toBeVisible() + + const event = _.find(meetingData.schedule, s => s.type === 'regular') + const eventWithNote = _.find(meetingData.schedule, s => s.note) + + // Search different terms + const searchTerms = [ + 'hack', // Should match hackathon events + event.groupAcronym, // Match group name + event.room.toLowerCase(), // Match room name + eventWithNote.note.substring(0, 10).toLowerCase() // Match partial note + ] + + for (const term of searchTerms) { + await searchInputLocator.fill(term) + // Let the UI update before checking each displayed row + await page.waitForTimeout(1000) + await expect(eventRowsLocator).not.toHaveCount(meetingData.schedule.length) + const rowsCount = await eventRowsLocator.count() + for (let idx = 0; idx < rowsCount; idx++) { + await expect(eventRowsLocator.nth(idx)).toContainText(term, { ignoreCase: true }) + } + } + + // Clear button + await page.locator('.agenda-search button').click() + await page.waitForTimeout(1000) + await expect(searchInputLocator).toHaveValue('') + await expect(eventRowsLocator).toHaveCount(meetingData.schedule.length) + // Invalid search + await searchInputLocator.fill(faker.vehicle.vin()) + await page.waitForTimeout(1000) + await expect(eventRowsLocator).toHaveCount(0) + await expect(page.locator('.agenda-table .agenda-table-display-noresult')).toContainText('No event matching your search query.') + // Closing search should clear search + await page.locator('.agenda-table > .agenda-table-search > button').click() + await expect(page.locator('.agenda-search')).not.toBeVisible() + await expect(eventRowsLocator).toHaveCount(meetingData.schedule.length) + }) + + test('agenda meeting materials dialog', async ({ page }) => { + const event = _.find(meetingData.schedule, s => s.flags.showAgenda && s.flags.agenda) + const eventStart = DateTime.fromISO(event.startDateTime) + const eventEnd = eventStart.plus({ seconds: event.duration }) + // Intercept meeting materials request + const materialsUrl = (new URL(event.agenda.url)).pathname + const materialsInfo = { + url: event.agenda.url, + slides: { + decks: _.times(5, idx => ({ + id: 100000 + idx, + title: faker.commerce.productName(), + url: `/meeting/${meetingData.meeting.number}/materials/slides-${meetingData.meeting.number}-${event.acronym}-${faker.internet.domainWord()}`, + ext: ['pdf', 'html', 'md', 'txt', 'pptx'][idx] + })), + actions: [{ + label: 'Propose slides', + url: `/meeting/${meetingData.meeting.number}/session/${event.sessionId}/propose_slides` + }] + }, + minutes: { + ext: 'md', + id: 123456, + title: 'Minutes IETF123 Testing', + url: `/meeting/${meetingData.meeting.number}/materials/minutes-${meetingData.meeting.number}-${event.acronym}-${faker.internet.domainWord()}` + } + } + await page.route(`**/api/meeting/session/${event.sessionId}/materials`, route => { + route.fulfill({ + status: 200, + contentType: 'application/json', + body: JSON.stringify(materialsInfo) + }) + }) + await page.route(materialsUrl, route => { + route.fulfill({ + status: 200, + contentType: 'text/plain', + body: 'The internet is a series of tubes.' + }) + }) + await page.route(materialsInfo.minutes.url, route => { + route.fulfill({ + status: 200, + contentType: 'text/plain', + body: 'One does not simply walk into mordor.' + }) + }) + // Open dialog + await page.locator(`#agenda-rowid-${event.id} #btn-btn-${event.id}-mat`).click() + await expect(page.locator('.agenda-eventdetails')).toBeVisible() + // Header + await expect(page.locator('.agenda-eventdetails .n-card-header__main > .detail-header > .bi')).toBeVisible() + await expect(page.locator('.agenda-eventdetails .n-card-header__main > .detail-header > .bi + span')).toContainText(eventStart.toFormat('DDDD')) + await expect(page.locator('.agenda-eventdetails .n-card-header__extra > .detail-header > .bi')).toBeVisible() + await expect(page.locator('.agenda-eventdetails .n-card-header__extra > .detail-header > .bi + strong')).toContainText(`${eventStart.toFormat('T')} - ${eventEnd.toFormat('T')}`) + await expect(page.locator('.agenda-eventdetails .detail-title > h6 > .bi')).toBeVisible() + await expect(page.locator('.agenda-eventdetails .detail-title > h6 > .bi + span')).toContainText(event.name) + await expect(page.locator('.agenda-eventdetails .detail-location > .bi')).toBeVisible() + await expect(page.locator('.agenda-eventdetails .detail-location > .bi + .badge')).toContainText(event.location.short) + await expect(page.locator('.agenda-eventdetails .detail-location > .bi + .badge + span')).toContainText(event.room) + // Navigation + const navLocator = await page.locator('.agenda-eventdetails .detail-nav > a') + await expect(navLocator).toHaveCount(3) + await expect(navLocator.first()).toHaveClass(/active/) + await expect(navLocator.nth(1)).not.toHaveClass(/active/) + await expect(navLocator.nth(2)).not.toHaveClass(/active/) + // Agenda Tab + await expect(page.locator('.agenda-eventdetails .detail-text > iframe')).toHaveAttribute('src', materialsUrl) + // Slides Tab + await navLocator.nth(1).click() + await expect(navLocator.nth(1)).toHaveClass(/active/) + await expect(navLocator.first()).not.toHaveClass(/active/) + const slideDecksLocator = page.locator('.agenda-eventdetails .detail-text .n-card__content > .list-group > .list-group-item') + await expect(slideDecksLocator).toHaveCount(materialsInfo.slides.decks.length) + for (let idx = 0; idx < materialsInfo.slides.decks.length; idx++) { + await expect(slideDecksLocator.nth(idx)).toHaveAttribute('href', materialsInfo.slides.decks[idx].url) + await expect(slideDecksLocator.nth(idx).locator('.bi')).toHaveClass(new RegExp(`bi-filetype-${materialsInfo.slides.decks[idx].ext}`)) + await expect(slideDecksLocator.nth(idx).locator('span')).toContainText(materialsInfo.slides.decks[idx].title) + } + const slideActionButtonLocator = page.locator('.agenda-eventdetails .detail-text .n-card__action > a') + await expect(slideActionButtonLocator).toHaveCount(1) + await expect(slideActionButtonLocator.first().locator('span')).toContainText('Propose slides') + // Minutes Tab + await navLocator.last().click() + await expect(navLocator.last()).toHaveClass(/active/) + await expect(navLocator.nth(1)).not.toHaveClass(/active/) + await expect(page.locator('.agenda-eventdetails .detail-text > iframe')).toHaveAttribute('src', materialsInfo.minutes.url) + // Footer Buttons + const hedgeDocLink = `https://notes.ietf.org/notes-ietf-${meetingData.meeting.number}-${event.type === 'plenary' ? 'plenary' : event.acronym}` + const detailsUrl = `/meeting/${meetingData.meeting.number}/session/${event.acronym}/` + const footerBtnsLocator = page.locator('.agenda-eventdetails .detail-action > a') + await expect(footerBtnsLocator).toHaveCount(4) + await expect(footerBtnsLocator.first()).toContainText('Download as tarball') + await expect(footerBtnsLocator.first()).toHaveAttribute('href', `/meeting/${meetingData.meeting.number}/agenda/${event.acronym}-drafts.tgz`) + await expect(footerBtnsLocator.nth(1)).toContainText('Download as PDF') + await expect(footerBtnsLocator.nth(1)).toHaveAttribute('href', `/meeting/${meetingData.meeting.number}/agenda/${event.acronym}-drafts.pdf`) + await expect(footerBtnsLocator.nth(2)).toContainText('Notepad') + await expect(footerBtnsLocator.nth(2)).toHaveAttribute('href', hedgeDocLink) + await expect(footerBtnsLocator.last()).toContainText(`${event.groupAcronym} materials page`) + await expect(footerBtnsLocator.last()).toHaveAttribute('href', detailsUrl) + // Clicking X should close the dialog + await page.locator('.agenda-eventdetails .n-card-header__extra > .detail-header > button').click() + }) + + // -> SCHEDULE LIST -> Show Meeting Materials dialog (EMPTY VARIANT) + + test('agenda meeting materials dialog (empty variant)', async ({ page }) => { + const event = _.find(meetingData.schedule, s => s.flags.showAgenda && s.flags.agenda) + // Intercept meeting materials request + const materialsUrl = (new URL(event.agenda.url)).pathname + const materialsInfo = { + url: event.agenda.url, + slides: [], + minutes: null + } + await page.route(`**/api/meeting/session/${event.sessionId}/materials`, route => { + route.fulfill({ + status: 200, + contentType: 'application/json', + body: JSON.stringify(materialsInfo) + }) + }) + await page.route(materialsUrl, route => { + route.fulfill({ + status: 200, + contentType: 'text/plain', + body: 'The internet is a series of tubes.' + }) + }) + // Open dialog + await page.locator(`#btn-btn-${event.id}-mat`).click() + await expect(page.locator('.agenda-eventdetails')).toBeVisible() + // Slides Tab + await page.locator('.agenda-eventdetails .detail-nav > a').nth(1).click() + await expect(page.locator('.agenda-eventdetails .detail-text .n-card__content')).toContainText('No slides submitted for this session.') + // Minutes Tab + await page.locator('.agenda-eventdetails .detail-nav > a').nth(2).click() + await expect(page.locator('.agenda-eventdetails .detail-text')).toContainText('No minutes submitted for this session.') + // Clicking X should close the dialog + await page.locator('.agenda-eventdetails .n-card-header__extra > .detail-header > button').click() + }) + + // -> FILTER BY AREA/GROUP DIALOG + + test('agenda filter by area/group', async ({ page }) => { + test.slow() // Triple the default timeout + + // Open dialog + await page.locator('#agenda-quickaccess-filterbyareagroups-btn').click() + await expect(page.locator('.agenda-personalize')).toBeVisible() + // Check header elements + await expect(page.locator('.agenda-personalize .n-drawer-header__main > span')).toContainText('Filter Areas + Groups') + const diagHeaderBtnLocator = page.locator('.agenda-personalize .agenda-personalize-actions > button') + await expect(diagHeaderBtnLocator).toHaveCount(3) + await expect(diagHeaderBtnLocator.first()).toContainText('Clear Selection') + await expect(diagHeaderBtnLocator.nth(1)).toContainText('Cancel') + await expect(diagHeaderBtnLocator.last()).toContainText('Apply') + // Check categories + const catsLocator = page.locator('.agenda-personalize .agenda-personalize-category') + await expect(catsLocator).toHaveCount(meetingData.categories.length) + // Check areas + groups + for (let idx = 0; idx < meetingData.categories.length; idx++) { + const cat = meetingData.categories[idx] + const areasLocator = catsLocator.nth(idx).locator('.agenda-personalize-area') + await expect(areasLocator).toHaveCount(cat.length) + for (let areaIdx = 0; areaIdx < cat.length; areaIdx++) { + // Area Button + const area = cat[areaIdx] + if (area.label) { + await expect(areasLocator.nth(areaIdx).locator('.agenda-personalize-areamain > button')).toBeVisible() + await expect(areasLocator.nth(areaIdx).locator('.agenda-personalize-areamain > button')).toContainText(area.label) + } else { + await expect(areasLocator.nth(areaIdx).locator('.agenda-personalize-areamain > button')).not.toBeVisible() + } + // Group Buttons + const grpBtnsLocator = areasLocator.nth(areaIdx).locator('.agenda-personalize-groups > button') + await expect(grpBtnsLocator).toHaveCount(area.children.length) + for (let groupIdx = 0; groupIdx < area.children.length; groupIdx++) { + const group = area.children[groupIdx] + await expect(grpBtnsLocator.nth(groupIdx)).toBeVisible() + await expect(grpBtnsLocator.nth(groupIdx)).toContainText(group.label) + if (group.is_bof) { + await expect(grpBtnsLocator.nth(groupIdx)).toHaveClass(/is-bof/) + await expect(grpBtnsLocator.nth(groupIdx).locator('.badge')).toBeVisible() + await expect(grpBtnsLocator.nth(groupIdx).locator('.badge')).toContainText('BoF') + } + } + // Test Area Selection + if (area.label) { + await areasLocator.nth(areaIdx).locator('.agenda-personalize-areamain > button').click() + for (let groupIdx = 0; groupIdx < area.children.length; groupIdx++) { + await expect(grpBtnsLocator.nth(groupIdx)).toHaveClass(/is-checked/) + } + await areasLocator.nth(areaIdx).locator('.agenda-personalize-areamain > button').click() + for (let groupIdx = 0; groupIdx < area.children.length; groupIdx++) { + await expect(grpBtnsLocator.nth(groupIdx)).not.toHaveClass(/is-checked/) + } + } + // Test Group Selection + const randGroupIdx = random(area.children.length - 1) + const groupLocator = areasLocator.nth(areaIdx).locator('.agenda-personalize-groups > button').nth(randGroupIdx) + await groupLocator.click() + await expect(groupLocator).toHaveClass(/is-checked/) + await groupLocator.click() + await expect(groupLocator).not.toHaveClass(/is-checked/) + } + } + // Test multi-toggled_by button trigger + const bofBtnLocator = page.locator('.agenda-personalize .agenda-personalize-category:last-child .agenda-personalize-area:last-child .agenda-personalize-groups > button', { hasText: 'BoF' }) + const bofGroupsLocator = page.locator('.agenda-personalize .agenda-personalize-group:has(.badge)') + const bofGroupsCount = await bofGroupsLocator.count() + await bofBtnLocator.click() + for (let idx = 0; idx < bofGroupsCount; idx++) { + await expect(bofGroupsLocator.nth(idx)).toHaveClass(/is-checked/) + } + await bofBtnLocator.click() + for (let idx = 0; idx < bofGroupsCount; idx++) { + await expect(bofGroupsLocator.nth(idx)).not.toHaveClass(/is-checked/) + } + // Clicking all groups from area then area button should unselect all + const areaGroupsLocator = page.locator('.agenda-personalize .agenda-personalize-area >> nth=0 >> .agenda-personalize-groups > button') + const areaGroupsCount = await areaGroupsLocator.count() + for (let idx = 0; idx < areaGroupsCount; idx++) { + await areaGroupsLocator.nth(idx).click() + } + await page.locator('.agenda-personalize .agenda-personalize-area >> nth=0 >> .agenda-personalize-areamain:first-child > button').click() + for (let idx = 0; idx < areaGroupsCount; idx++) { + await expect(areaGroupsLocator.nth(idx)).not.toHaveClass(/is-checked/) + } + // Test Clear Selection + const groupsLocator = page.locator('.agenda-personalize .agenda-personalize-group') + const groupsCount = await groupsLocator.count() + const randGroupRange = _.take(shuffle(_.range(groupsCount)), 10) + for (const idx of randGroupRange) { + await groupsLocator.nth(idx).click() + } + await page.locator('.agenda-personalize .agenda-personalize-actions > button').first().click() + await expect(page.locator('.agenda-personalize .agenda-personalize-group.is-checked')).toHaveCount(0) + // Click Cancel should hide dialog + await page.locator('.agenda-personalize .agenda-personalize-actions > button').nth(1).click() + await expect(page.locator('.agenda-personalize')).not.toBeVisible() + }) + + // -> PICK SESSIONS + + test('agenda individual sessions picker', async ({ page }) => { + const pickBtnLocator = page.locator('#agenda-quickaccess-picksessions-btn') + const applyBtnLocator = page.locator('#agenda-quickaccess-applypick-btn') + const modifyBtnLocator = page.locator('#agenda-quickaccess-modifypick-btn') + const discardBtnLocator = page.locator('#agenda-quickaccess-discardpick-btn') + const checkboxesLocator = page.locator('.agenda .agenda-table-cell-check > .n-checkbox') + const checkedboxesLocator = page.locator('.agenda .agenda-table-cell-check > .n-checkbox.n-checkbox--checked') + const uncheckedboxesLocator = page.locator('.agenda .agenda-table-cell-check > .n-checkbox:not(.n-checkbox--checked)') + const eventsLocator = page.locator('.agenda .agenda-table-display-event') + + // Enter pick mode + await expect(pickBtnLocator).toBeVisible() + await pickBtnLocator.click() + await expect(pickBtnLocator).not.toBeVisible() + await expect(applyBtnLocator).toBeVisible() + await expect(discardBtnLocator).toBeVisible() + + // Pick 10 random sessions + await expect(checkboxesLocator).toHaveCount(meetingData.schedule.length) + const randSessionsRange = _.take(shuffle(_.range(meetingData.schedule.length)), 10) + for (const idx of randSessionsRange) { + await checkboxesLocator.nth(idx).click() + } + await applyBtnLocator.click() + await expect(applyBtnLocator).not.toBeVisible() + await expect(modifyBtnLocator).toBeVisible() + await expect(discardBtnLocator).toBeVisible() + await expect(eventsLocator).toHaveCount(10) + + // Change selection (keep existing 5 + add 5 new ones) + await modifyBtnLocator.click() + await expect(modifyBtnLocator).not.toBeVisible() + await expect(applyBtnLocator).toBeVisible() + await expect(discardBtnLocator).toBeVisible() + await expect(checkboxesLocator).toHaveCount(meetingData.schedule.length) + await expect(checkedboxesLocator).toHaveCount(10) + for (let idx = 0; idx < 5; idx++) { + await checkedboxesLocator.nth(idx).click() + } + const uncheckedCount = await uncheckedboxesLocator.count() + const uncheckedRandRange = _.take(shuffle(_.range(uncheckedCount - 1)), 5) + for (const idx of uncheckedRandRange) { + await uncheckedboxesLocator.nth(idx).click() + } + await applyBtnLocator.click() + await expect(eventsLocator).toHaveCount(10) + + // Discard should clear selection + await discardBtnLocator.click() + await expect(discardBtnLocator).not.toBeVisible() + await expect(modifyBtnLocator).not.toBeVisible() + await expect(pickBtnLocator).toBeVisible() + await expect(page.locator('.agenda .agenda-table-cell-check')).toHaveCount(0) + await expect(eventsLocator).toHaveCount(meetingData.schedule.length) + }) + + // -> CALENDAR VIEW + + test('agenda calendar view', async ({ page }) => { + const diagHeaderLocator = page.locator('.agenda-calendar .agenda-calendar-actions') + const tzButtonsLocator = diagHeaderLocator.locator('.n-button-group button') + const calHintLocator = page.locator('.agenda-calendar-hint > div') + + // Open dialog + await page.locator('#agenda-quickaccess-calview-btn').click() + await expect(page.locator('.agenda-calendar')).toBeVisible() + // Check header elements + await expect(page.locator('.agenda-calendar .n-drawer-header__main > span')).toContainText('Calendar View') + await expect(diagHeaderLocator.locator('> button')).toHaveCount(2) + await expect(diagHeaderLocator.locator('> button').first()).toContainText('Filter') + await expect(diagHeaderLocator.locator('> button').last()).toContainText('Close') + // ----------------------- + // Check timezone controls + // ----------------------- + await expect(diagHeaderLocator.locator('small').first()).toContainText('Timezone') + // Switch to local timezone + await tzButtonsLocator.nth(1).click() + await expect(tzButtonsLocator.nth(1)).toHaveClass(/n-button--primary-type/) + await expect(tzButtonsLocator.first()).not.toHaveClass(/n-button--primary-type/) + const localDateTime = DateTime.fromISO(meetingData.meeting.updated) + .setZone(BROWSER_TIMEZONE) + .setLocale(BROWSER_LOCALE) + .toFormat('DD \'at\' T ZZZZ') + await expect(page.locator('.agenda h6').first()).toContainText(localDateTime) + // Switch to UTC + await tzButtonsLocator.last().click() + await expect(tzButtonsLocator.last()).toHaveClass(/n-button--primary-type/) + await expect(tzButtonsLocator.nth(1)).not.toHaveClass(/n-button--primary-type/) + const utcDateTime = DateTime.fromISO(meetingData.meeting.updated) + .setZone('utc') + .setLocale(BROWSER_LOCALE) + .toFormat('DD \'at\' T ZZZZ') + await expect(page.locator('.agenda h6').first()).toContainText(utcDateTime) + // Switch back to meeting timezone + await tzButtonsLocator.first().click() + await expect(tzButtonsLocator.first()).toHaveClass(/n-button--primary-type/) + // ---------------------- + // Check Filters Shortcut + // ---------------------- + await diagHeaderLocator.locator('> button').first().click() + // Only check whether the dialog is shown. We already tested the dialog earlier. + await expect(page.locator('.agenda-personalize')).toBeVisible() + // Close dialog + await page.locator('.agenda-personalize .agenda-personalize-actions > button').nth(1).click() + await expect(page.locator('.agenda-personalize')).not.toBeVisible() + // ------------------ + // Check Event Dialog + // ------------------ + const firstEvent = meetingData.schedule[0] + const materialsUrl = (new URL(firstEvent.agenda.url)).pathname + const materialsInfo = { + url: firstEvent.agenda.url, + slides: [], + minutes: null + } + await page.route(`**/api/meeting/session/${firstEvent.sessionId}/materials`, route => { + route.fulfill({ + status: 200, + contentType: 'application/json', + body: JSON.stringify(materialsInfo) + }) + }) + await page.route(materialsUrl, route => { + route.fulfill({ + status: 200, + contentType: 'text/plain', + body: 'The internet is a series of tubes.' + }) + }) + await page.locator('.agenda-calendar .fc-event').first().click() + // Only check whether the dialog is shown. We already tested the dialog earlier. + await expect(page.locator('.agenda-eventdetails')).toBeVisible() + // Close dialog + await page.locator('.agenda-eventdetails .n-card-header__extra > .detail-header > button').click() + // ----------- + // Event Hover + // ----------- + // First Event + let eventStart = DateTime.fromISO(firstEvent.startDateTime) + let eventEnd = eventStart.plus({ seconds: firstEvent.duration }) + let hoverDateTime = `${eventStart.toFormat('DDDD')} from ${eventStart.toFormat('T')} to ${eventEnd.toFormat('T')}` + await page.locator('.agenda-calendar .fc-event').first().hover() + await expect(calHintLocator.first()).toContainText(firstEvent.name) + await expect(calHintLocator.nth(1)).toContainText(firstEvent.location.short) + await expect(calHintLocator.nth(1)).toContainText(firstEvent.room) + await expect(calHintLocator.nth(2)).toContainText(hoverDateTime) + // Second Event + const secondEvent = meetingData.schedule[1] + eventStart = DateTime.fromISO(secondEvent.startDateTime) + eventEnd = eventStart.plus({ seconds: secondEvent.duration }) + hoverDateTime = `${eventStart.toFormat('DDDD')} from ${eventStart.toFormat('T')} to ${eventEnd.toFormat('T')}` + await page.locator('.agenda-calendar .fc-event').nth(1).hover() + await expect(calHintLocator.first()).toContainText(secondEvent.name) + await expect(calHintLocator.nth(1)).toContainText(secondEvent.location.short) + await expect(calHintLocator.nth(1)).toContainText(secondEvent.room) + await expect(calHintLocator.nth(2)).toContainText(hoverDateTime) + // ------------------------------ + // Click Close should hide dialog + // ------------------------------ + await diagHeaderLocator.locator('button').last().click() + await expect(page.locator('.agenda-calendar')).not.toBeVisible() + }) + + // -> SETTINGS DIALOG + + test('agenda settings', async ({ page, browserName }) => { + // Open dialog + await page.locator('.agenda-topnav-right > button:last-child').click() + await expect(page.locator('.agenda-settings')).toBeVisible() + // Check header elements + await expect(page.locator('.agenda-settings .n-drawer-header__main > span')).toContainText('Agenda Settings') + await expect(page.locator('.agenda-settings .agenda-settings-actions > button')).toHaveCount(2) + await expect(page.locator('.agenda-settings .agenda-settings-actions > button').first()).toBeVisible() + await expect(page.locator('.agenda-settings .agenda-settings-actions > button').last()).toContainText('Close') + + // ------------------- + // Check export config + // ------------------- + await page.locator('.agenda-settings .agenda-settings-actions > button').first().click() + const [download] = await Promise.all([ + page.waitForEvent('download'), + page.locator('.n-dropdown-option:has-text("Export Configuration")').click() + ]) + + const downloadPath = await download.path() + try { + const downloadedConfig = JSON.parse(await fs.readFile(downloadPath, 'utf8')) + const expectedConfig = JSON.parse(await fs.readFile('data/agenda-settings.json', 'utf8')) + await expect(downloadedConfig).toEqual(expectedConfig) + } catch (err) { + expect(err).toBeUndefined() + } + + // ------------------- + // Check import config + // ------------------- + await test.step('import config', async () => { + if (browserName === 'chromium') { + // Chromium use the experimental file selector API so this test won't work, skipping... + // See https://github.com/microsoft/playwright/issues/8850') + return + } + await page.locator('.agenda-settings .agenda-settings-actions > button').first().click() + const [fileChooser] = await Promise.all([ + page.waitForEvent('filechooser'), + page.locator('.n-dropdown-option:has-text("Import Configuration")').click() + ]) + await fileChooser.setFiles('data/agenda-settings.json') + await expect(page.locator('.n-message')).toContainText('Config imported successfully') + }) + + // ----------------------- + // Check timezone controls + // ----------------------- + const tzMeetingBtnLocator = page.locator('#agenda-settings-tz-btn button:first-child') + const tzLocalBtnLocator = page.locator('#agenda-settings-tz-btn button:nth-child(2)') + const tzUtcBtnLocator = page.locator('#agenda-settings-tz-btn button:last-child') + await expect(page.locator('.agenda-settings-content > .n-divider').first()).toContainText('Timezone') + // Switch to local timezone + await tzLocalBtnLocator.click() + await expect(tzLocalBtnLocator).toHaveClass(/n-button--primary-type/) + await expect(tzMeetingBtnLocator).not.toHaveClass(/n-button--primary-type/) + const localDateTime = DateTime.fromISO(meetingData.meeting.updated) + .setZone(BROWSER_TIMEZONE) + .setLocale(BROWSER_LOCALE) + .toFormat('DD \'at\' T ZZZZ') + await expect(page.locator('.agenda h6').first()).toContainText(localDateTime) + // Switch to UTC + await tzUtcBtnLocator.click() + await expect(tzUtcBtnLocator).toHaveClass(/n-button--primary-type/) + await expect(tzLocalBtnLocator).not.toHaveClass(/n-button--primary-type/) + const utcDateTime = DateTime.fromISO(meetingData.meeting.updated) + .setZone('utc') + .setLocale(BROWSER_LOCALE) + .toFormat('DD \'at\' T ZZZZ') + await expect(page.locator('.agenda h6').first()).toContainText(utcDateTime) + // Switch back to meeting timezone + await tzMeetingBtnLocator.click() + await expect(tzMeetingBtnLocator).toHaveClass(/n-button--primary-type/) + await expect(page.locator('#agenda-settings-tz-ddn')).toContainText('Tokyo') + + // ---------------------- + // Check display controls + // ---------------------- + await expect(page.locator('.agenda-settings-content > .n-divider').nth(1)).toContainText('Display') + // -> Test Current Meeting Info Note toggle + const infonoteSwitchLocator = page.locator('#agenda-settings-tgl-infonote div[role=switch]') + await infonoteSwitchLocator.click() + await expect(page.locator('.agenda .agenda-infonote')).not.toBeVisible() + await infonoteSwitchLocator.click() + await expect(page.locator('.agenda .agenda-infonote')).toBeVisible() + // -> Test Event Icons toggle + const eventiconsSwitchLocator = page.locator('#agenda-settings-tgl-eventicons div[role=switch]') + await eventiconsSwitchLocator.click() + await expect(page.locator('.agenda .agenda-event-icon')).toHaveCount(0) + await eventiconsSwitchLocator.click() + await expect(page.locator('.agenda .agenda-event-icon')).not.toHaveCount(0) + // -> Test Floor Indicators toggle + const floorindSwitchLocator = page.locator('#agenda-settings-tgl-floorind div[role=switch]') + await floorindSwitchLocator.click() + await expect(page.locator('.agenda .agenda-table-cell-room > span.badge')).toHaveCount(0) + await floorindSwitchLocator.click() + await expect(page.locator('.agenda .agenda-table-cell-room > span.badge')).not.toHaveCount(0) + // -> Test Group Area Indicators toggle + const groupindSwitchLocator = page.locator('#agenda-settings-tgl-groupind div[role=switch]') + await groupindSwitchLocator.click() + await expect(page.locator('.agenda .agenda-table-cell-group > span.badge')).toHaveCount(0) + await groupindSwitchLocator.click() + await expect(page.locator('.agenda .agenda-table-cell-group > span.badge')).not.toHaveCount(0) + // -> Test Bolder Text toggle + const boldertxtSwitchLocator = page.locator('#agenda-settings-tgl-boldertxt div[role=switch]') + await boldertxtSwitchLocator.click() + await expect(page.locator('.agenda')).toHaveClass(/bolder-text/) + await boldertxtSwitchLocator.click() + await expect(page.locator('.agenda')).not.toHaveClass(/bolder-text/) + + // ---------------------------- + // Check calendar view controls + // ---------------------------- + await expect(page.locator('.agenda-settings-content > .n-divider').nth(2)).toContainText('Calendar View') + // TODO: calendar view checks + // ---------------------------- + // Check calendar view controls + // ---------------------------- + await expect(page.locator('.agenda-settings-content > .n-divider').nth(3)).toContainText('Custom Colors / Tags') + // ------------------------------ + // Click Close should hide dialog + // ------------------------------ + await page.locator('.agenda-settings .agenda-settings-actions > button').last().click() + await expect(page.locator('.agenda-settings')).not.toBeVisible() + }) + + // -> SHARE DIALOG + + test('agenda share dialog', async ({ page }) => { + // Open dialog + await page.locator('.agenda-topnav-right > button:nth-child(2)').click() + await expect(page.locator('.agenda-share')).toBeVisible() + // Check header elements + await expect(page.locator('.agenda-share .n-card-header__main > .agenda-share-header > .bi')).toBeVisible() + await expect(page.locator('.agenda-share .n-card-header__main > .agenda-share-header > .bi + span')).toContainText('Share this view') + // Check input URL + await expect(page.locator('.agenda-share .agenda-share-content input[type=text]')).toHaveValue(`http://localhost:3000/meeting/${meetingData.meeting.number}/agenda`) + // Clicking X should close the dialog + await page.locator('.agenda-share .n-card-header__extra > .agenda-share-header > button').click() + await expect(page.locator('.agenda-share')).not.toBeVisible() + }) + + // -> ADD TO CALENDAR + + test('agenda add to calendar', async ({ page }) => { + await expect(page.locator('#agenda-quickaccess-addtocal-btn')).toContainText('Add to your calendar') + await page.locator('#agenda-quickaccess-addtocal-btn').click() + const ddnLocator = page.locator('.n-dropdown-menu > div > a.agenda-quickaccess-callinks') + await expect(ddnLocator).toHaveCount(2) + await expect(ddnLocator.first()).toContainText('Subscribe') + await expect(ddnLocator.last()).toContainText('Download') + + // Intercept Download ICS Call + await page.route(`**/meeting/${meetingData.meeting.number}/agenda.ics`, route => { + route.fulfill({ + status: 200, + contentType: 'text/calendar', + headers: { + 'Content-disposition': 'attachment; filename=agenda.ics' + }, + body: 'test' + }) + }) + + // Cannot test if webcal link works because external app handling not supported: + // See https://github.com/microsoft/playwright/issues/11014 + + // Test Download ICS + const [download] = await Promise.all([ + page.waitForEvent('download'), + ddnLocator.nth(1).click() + ]) + const downloadPath = await download.path() + try { + const testIcs = await fs.readFile(downloadPath, 'utf8') + await expect(testIcs).toEqual('test') + } catch (err) { + expect(err).toBeUndefined() + } + }) + + // -> JUMP TO DAY + + test('agenda jump to specific days', async ({ page, browserName }) => { + // -> Separator label + await expect(page.locator('div[role=separator]:above(.agenda .agenda-quickaccess-jumpto)').first()).toContainText('Jump to...') + + // -> Check nav items + const navItemLocator = page.locator('.agenda .agenda-quickaccess-jumpto > .nav-item') + await expect(navItemLocator).toHaveCount(7) + for (let idx = 0; idx < 7; idx++) { + const localDateTime = DateTime.fromISO(meetingData.meeting.startDate, { zone: BROWSER_TIMEZONE }) + .setZone(BROWSER_TIMEZONE) + .setLocale(BROWSER_LOCALE) + .plus({ days: idx }) + .toLocaleString(DateTime.DATE_HUGE) + await expect(navItemLocator.nth(idx)).toContainText(localDateTime) + } + + // -> Jump to specific days + if (browserName === 'chromium') { + // Exclude firefox as this test doesn't run reliably on it in CI + for (const idx of [6, 1, 5]) { + await navItemLocator.nth(idx).locator('a').click() + await setTimeout(2500) + await expect(await commonHelper.isIntersectingViewport(page, `.agenda-table-display-day >> nth=${idx}`)).toBeTruthy() + } + } + }) + + // -> Color Tagging + + test('agenda colors/tags assignment', async ({ page }) => { + test.slow() // Triple the default timeout + + const openBtnLocator = page.locator('.agenda .agenda-table-colorpicker') + const colorLgdLocator = page.locator('.agenda .agenda-colorlegend') + const eventRowsLocator = page.locator('.agenda .agenda-table-display-event') + const colorLgdSwitchLocator = page.locator('#agenda-settings-tgl-colorlgd div[role=switch]') + const colorNamesIptLocator = page.locator('.agenda-settings-colors-row .n-input') + const randColorNames = _.times(5, faker.music.genre) + + await expect(openBtnLocator).toBeVisible() + await openBtnLocator.click() + + // Check Legend + await expect(colorLgdLocator).toBeVisible() + await expect(colorLgdLocator.locator('> *')).toHaveCount(6) + await expect(colorLgdLocator.locator('> * >> nth=0')).toContainText('Color Legend') + + // Check color dots + await expect(page.locator('.agenda .agenda-table-display-event .agenda-table-colorindicator.is-active')).toHaveCount(meetingData.schedule.length) + + // ------------------------- + // Assign colors to sessions + // ------------------------- + + for (let idx = 0; idx < 5; idx++) { + await expect(eventRowsLocator.nth(idx).locator('.agenda-table-colorindicator')).toBeVisible() + await eventRowsLocator.nth(idx).locator('.agenda-table-colorindicator').click() + await expect(eventRowsLocator.nth(idx).locator('.agenda-table-colorchoices')).toBeVisible() + await expect(eventRowsLocator.nth(idx).locator('.agenda-table-colorchoices > .agenda-table-colorchoice')).toHaveCount(6) + await eventRowsLocator.nth(idx).locator('.agenda-table-colorchoices > .agenda-table-colorchoice').nth(idx + 1).click() + await expect(eventRowsLocator.nth(idx).locator('.agenda-table-colorchoices')).not.toBeVisible() + } + + // Exit color assignment mode + await openBtnLocator.click() + await expect(page.locator('.agenda .agenda-table-display-event .agenda-table-colorindicator')).toHaveCount(5) + await expect(page.locator('.agenda .agenda-table-display-event .agenda-table-colorindicator.is-active')).toHaveCount(0) + await expect(colorLgdLocator).toBeVisible() + + // ---------------------------------------- + // Change color legend from settings dialog + // ---------------------------------------- + // Open dialog + await page.locator('.agenda-topnav-right > button:last-child').click() + await expect(page.locator('.agenda-settings')).toBeVisible() + // Toggle color legend switch + await colorLgdSwitchLocator.click() + // Legend should be hidden + await expect(colorLgdLocator).not.toBeVisible() + // Toggle color legend back + await colorLgdSwitchLocator.click() + // Legend should be visible + await expect(colorLgdLocator).toBeVisible() + // Change color names + for (let idx = 0; idx < 5; idx++) { + await colorNamesIptLocator.nth(idx).locator('input').fill(randColorNames[idx]) + await setTimeout(1000) // Account for change debounce + await expect(colorLgdLocator.locator(`> * >> nth=${idx + 1}`)).toContainText(randColorNames[idx]) + } + // Close dialog + await page.locator('.agenda-settings .agenda-settings-actions > button').last().click() + await expect(page.locator('.agenda-settings')).not.toBeVisible() + + // --------------- + // Unassign colors + // --------------- + // Re-enter color assignment mode + await openBtnLocator.click() + // Remove color selection + for (let idx = 0; idx < 5; idx++) { + await expect(eventRowsLocator.nth(idx).locator('.agenda-table-colorindicator')).toBeVisible() + await eventRowsLocator.nth(idx).locator('.agenda-table-colorindicator').click() + await expect(eventRowsLocator.nth(idx).locator('.agenda-table-colorchoices')).toBeVisible() + await expect(eventRowsLocator.nth(idx).locator('.agenda-table-colorchoices > .agenda-table-colorchoice')).toHaveCount(6) + await eventRowsLocator.nth(idx).locator('.agenda-table-colorchoices > .agenda-table-colorchoice').first().click() + await expect(eventRowsLocator.nth(idx).locator('.agenda-table-colorchoices')).not.toBeVisible() + } + // Exit color assignment mode + await openBtnLocator.click() + // No colored dots should appear + await expect(page.locator('.agenda .agenda-table-display-event .agenda-table-colorindicator')).toHaveCount(0) + // Clear all colors from Settings menu + await page.locator('.agenda-topnav-right > button:last-child').click() + await expect(page.locator('.agenda-settings')).toBeVisible() + await page.locator('.agenda-settings .agenda-settings-actions > button').first().click() + await page.locator('.n-dropdown-option:has-text("Clear Color")').click() + // Color legend should no longer be displayed + await expect(colorLgdLocator).not.toBeVisible() + await expect(page.locator('.agenda-settings')).not.toBeVisible() + }) +}) + +// ==================================================================== +// AGENDA (future meeting) | DESKTOP viewport +// ==================================================================== + +test.describe('future - desktop', () => { + let meetingData + + test.beforeAll(async () => { + // Generate meeting data + meetingData = meetingHelper.generateAgendaResponse({ dateMode: 'future' }) + }) + + test.beforeEach(async ({ page }) => { + // Intercept Meeting Data API + await page.route(`**/api/meeting/${meetingData.meeting.number}/agenda-data`, route => { + route.fulfill({ + status: 200, + contentType: 'application/json', + body: JSON.stringify(meetingData) + }) + }) + + await page.setViewportSize({ + width: viewports.desktop[0], + height: viewports.desktop[1] + }) + + // Visit agenda page and await Meeting Data API call to complete + await Promise.all([ + page.waitForResponse(`**/api/meeting/${meetingData.meeting.number}/agenda-data`), + page.goto(`/meeting/${meetingData.meeting.number}/agenda`) + ]) + + // Wait for page to be ready + await page.locator('.agenda h1').waitFor({ state: 'visible' }) + await setTimeout(500) + }) + + // -> SCHEDULE LIST -> Warning + + test('has current meeting warning', async ({ page }) => { + await expect(page.locator('.agenda .agenda-currentwarn')).toContainText('Note: IETF agendas are subject to change, up to and during a meeting.') + }) + + // -> SCHEDULE LIST -> Table Events + + test('has schedule list table events', async ({ page }) => { + test.slow() // Triple the default timeout + + const eventRowsLocator = page.locator('.agenda-table .agenda-table-display-event') + + await expect(eventRowsLocator).toHaveCount(meetingData.schedule.length) + + for (let idx = 0; idx < meetingData.schedule.length; idx++) { + const row = eventRowsLocator.nth(idx) + const event = meetingData.schedule[idx] + + // ----------------------- + // Buttons / Status Column + // ----------------------- + if (event.status === 'sched') { + const eventButtons = row.locator('.agenda-table-cell-links > .agenda-table-cell-links-buttons') + if (event.flags.showAgenda || (['regular', 'plenary', 'other'].includes(event.type) && !['admin', 'closed_meeting', 'officehours', 'social'].includes(event.purpose))) { + if (event.flags.agenda) { + // Show meeting materials button + await expect(eventButtons.locator(`#btn-btn-${event.id}-mat`)).toBeVisible() + // ZIP materials button + await expect(eventButtons.locator(`#btn-lnk-${event.id}-tar`)).toHaveAttribute('href', `/meeting/${meetingData.meeting.number}/agenda/${event.acronym}-drafts.tgz`) + await expect(eventButtons.locator(`#btn-lnk-${event.id}-tar > i.bi`)).toBeVisible() + // PDF materials button + await expect(eventButtons.locator(`#btn-lnk-${event.id}-pdf`)).toHaveAttribute('href', `/meeting/${meetingData.meeting.number}/agenda/${event.acronym}-drafts.pdf`) + await expect(eventButtons.locator(`#btn-lnk-${event.id}-pdf > i.bi`)).toBeVisible() + } else if (event.type === 'regular') { + // No meeting materials yet warning badge + await expect(eventButtons.locator('.no-meeting-materials')).toBeVisible() + } + if (event.groupAcronym === 'hackathon') { + // Hackathon Wiki button + const hackathonWikiLink = `https://wiki.ietf.org/meeting/${meetingData.meeting.number}/hackathon` + await expect(eventButtons.locator(`#btn-lnk-${event.id}-wiki`)).toHaveAttribute('href', hackathonWikiLink) + await expect(eventButtons.locator(`#btn-lnk-${event.id}-wiki > i.bi`)).toBeVisible() + } else { + // Notepad button + const hedgeDocLink = `https://notes.ietf.org/notes-ietf-${meetingData.meeting.number}-${event.type === 'plenary' ? 'plenary' : event.acronym}` + await expect(eventButtons.locator(`#btn-lnk-${event.id}-note`)).toHaveAttribute('href', hedgeDocLink) + await expect(eventButtons.locator(`#btn-lnk-${event.id}-note > i.bi`)).toBeVisible() + } + // Chat room + await expect(eventButtons.locator(`#btn-lnk-${event.id}-room`)).toHaveAttribute('href', event.links.chat) + await expect(eventButtons.locator(`#btn-lnk-${event.id}-room > i.bi`)).toBeVisible() + // Video Stream + if (event.links.videoStream) { + await expect(eventButtons.locator(`#btn-lnk-${event.id}-video`)).toHaveAttribute('href', meetingHelper.formatLinkUrl(event.links.videoStream, event, meetingData.meeting.number)) + await expect(eventButtons.locator(`#btn-lnk-${event.id}-video > i.bi`)).toBeVisible() + } + // Onsite Tool + if (event.links.onsitetool) { + await expect(eventButtons.locator(`#btn-lnk-${event.id}-onsitetool`)).toHaveAttribute('href', meetingHelper.formatLinkUrl(event.links.onsitetool, event, meetingData.meeting.number)) + await expect(eventButtons.locator(`#btn-lnk-${event.id}-onsitetool > i.bi`)).toBeVisible() + } + // Audio Stream + if (event.links.audioStream) { + await expect(eventButtons.locator(`#btn-lnk-${event.id}-audio`)).toHaveAttribute('href', meetingHelper.formatLinkUrl(event.links.audioStream, event, meetingData.meeting.number)) + await expect(eventButtons.locator(`#btn-lnk-${event.id}-audio > i.bi`)).toBeVisible() + } + // Remote Call-In + let remoteCallInUrl = null + if (event.note) { + remoteCallInUrl = meetingHelper.findFirstConferenceUrl(event.note) + } + if (!remoteCallInUrl && event.remoteInstructions) { + remoteCallInUrl = meetingHelper.findFirstConferenceUrl(event.remoteInstructions) + } + if (!remoteCallInUrl && event.links.webex) { + remoteCallInUrl = event.links.webex + } + if (remoteCallInUrl) { + await expect(eventButtons.locator(`#btn-lnk-${event.id}-remotecallin`)).toHaveAttribute('href', remoteCallInUrl) + await expect(eventButtons.locator(`#btn-lnk-${event.id}-remotecallin > i.bi`)).toBeVisible() + } + // Calendar + if (event.links.calendar) { + await expect(eventButtons.locator(`#btn-lnk-${event.id}-calendar`)).toHaveAttribute('href', event.links.calendar) + await expect(eventButtons.locator(`#btn-lnk-${event.id}-calendar > i.bi`)).toBeVisible() + } + } else { + if (event.links.calendar) { + await expect(eventButtons.locator(`#btn-lnk-${event.id}-calendar`)).toHaveAttribute('href', event.links.calendar) + await expect(eventButtons.locator(`#btn-lnk-${event.id}-calendar > i.bi`)).toBeVisible() + } else { + await expect(eventButtons).toHaveCount(0) + } + } + } + } + }) +}) + +// ==================================================================== +// AGENDA (live meeting) | DESKTOP viewport +// ==================================================================== + +test.describe('live - desktop', () => { + let meetingData + const currentTime = DateTime.fromISO('2022-02-01T13:45:15', { zone: 'Asia/Tokyo' }) + const liveEvents = [] + let lastLiveEvent = null + + test.beforeAll(async () => { + // Generate meeting data + meetingData = meetingHelper.generateAgendaResponse({ dateMode: 'current' }) + + // Calculate live events + let lastEventStartTime = null + for (const event of meetingData.schedule) { + const eventStart = DateTime.fromISO(event.startDateTime, { zone: 'Asia/Tokyo' }) + const eventEnd = eventStart.plus({ seconds: event.duration }) + if (currentTime >= eventStart && currentTime < eventEnd) { + liveEvents.push(event) + // -> Find last event before current time + if (lastEventStartTime === eventStart.toMillis()) { + continue + } else { + lastEventStartTime = eventStart.toMillis() + lastLiveEvent = event + } + } + // -> Skip future events + if (eventStart > currentTime) { + break + } + } + }) + + test.beforeEach(async ({ page }) => { + // Intercept Meeting Data API + await page.route(`**/api/meeting/${meetingData.meeting.number}/agenda-data`, route => { + route.fulfill({ + status: 200, + contentType: 'application/json', + body: JSON.stringify(meetingData) + }) + }) + + await page.setViewportSize({ + width: viewports.desktop[0], + height: viewports.desktop[1] + }) + + // Override Date in page to fixed time + await commonHelper.overridePageDateTime(page, currentTime) + + // Visit agenda page and await Meeting Data API call to complete + await Promise.all([ + page.waitForResponse(`**/api/meeting/${meetingData.meeting.number}/agenda-data`), + page.goto(`/meeting/${meetingData.meeting.number}/agenda`) + ]) + + // Wait for page to be ready + await page.locator('.agenda h1').waitFor({ state: 'visible' }) + await setTimeout(500) + }) + + // -> LIVE MEETING ELEMENTS + + test('live meeting elements', async ({ page }) => { + const navItemsLocator = page.locator('.agenda .agenda-quickaccess-jumpto > .nav-item') + // Highlighted Live Sessions + await expect(page.locator('.agenda .agenda-table-display-event.agenda-table-live')).toHaveCount(liveEvents.length) + + // Live Red Line + await expect(page.locator('.agenda .agenda-table-redhand')).toBeVisible() + const expectedOffsetTop = await page.locator(`#agenda-rowid-${lastLiveEvent.id}`).evaluate(node => node.offsetTop) + const offsetTop = await page.locator('.agenda .agenda-table-redhand').evaluate(node => node.offsetTop) + const isCloseEnough = offsetTop >= expectedOffsetTop - 15 && offsetTop <= expectedOffsetTop + 15 + await expect(isCloseEnough).toBeTruthy() + + // Jump to Now + await expect(navItemsLocator).toHaveCount(8) + await expect(navItemsLocator.first()).toContainText('Now') + await navItemsLocator.first().click() + await setTimeout(2500) + // red line position isn't pixel perfect on CI, so accept some range + const redlineBoundingBox = await page.locator('.agenda .agenda-table-redhand').boundingBox() + await expect(redlineBoundingBox.y >= -20 && redlineBoundingBox.y <= 20).toBeTruthy() + }) + + // -> HIDE RED LINE + + test('live red line toggle', async ({ page }) => { + // Open settings dialog + await page.locator('.agenda-topnav-right > button:last-child').click() + await expect(page.locator('.agenda-settings')).toBeVisible() + // Toggle red line switch + const redlineSwitchLocator = page.locator('#agenda-settings-tgl-redline div[role=switch]') + await redlineSwitchLocator.click() + await expect(page.locator('.agenda .agenda-table-redhand')).not.toBeVisible() + await redlineSwitchLocator.click() + await expect(page.locator('.agenda .agenda-table-redhand')).toBeVisible() + // Close dialog + await page.locator('.agenda-settings .agenda-settings-actions > button').last().click() + await expect(page.locator('.agenda-settings')).not.toBeVisible() + }) +}) + +// ==================================================================== +// AGENDA (live meeting) | DESKTOP viewport | Plenary Extended Time Buttons +// ==================================================================== + +test.describe('live - desktop - plenary extended time buttons', () => { + let meetingData + let plenarySessionId + + test.beforeAll(async () => { + // Generate meeting data + meetingData = meetingHelper.generateAgendaResponse({ dateMode: 'current' }) + plenarySessionId = meetingData.schedule.find(s => s.type === 'plenary').id + }) + + test.beforeEach(async ({ page }) => { + // Intercept Meeting Data API + await page.route(`**/api/meeting/${meetingData.meeting.number}/agenda-data`, route => { + route.fulfill({ + status: 200, + contentType: 'application/json', + body: JSON.stringify(meetingData) + }) + }) + + await page.setViewportSize({ + width: viewports.desktop[0], + height: viewports.desktop[1] + }) + }) + + // -> BUTTONS PRESENT AFTER EVENT, SAME DAY + + test('same day - after event', async ({ page }) => { + // Override Date in page to fixed time + const currentTime = DateTime.fromISO('2022-02-01T13:45:15', { zone: 'Asia/Tokyo' }).plus({ days: 1 }).set({ hour: 20, minute: 30 }) + await commonHelper.overridePageDateTime(page, currentTime) + + // Visit agenda page and await Meeting Data API call to complete + await Promise.all([ + page.waitForResponse(`**/api/meeting/${meetingData.meeting.number}/agenda-data`), + page.goto(`/meeting/${meetingData.meeting.number}/agenda`) + ]) + + // Wait for page to be ready + await page.locator('.agenda h1').waitFor({ state: 'visible' }) + await setTimeout(500) + + // Check for plenary event + await expect(page.locator('.agenda .agenda-table-display-event.agenda-table-type-plenary')).toBeVisible() + await page.locator('.agenda .agenda-table-display-event.agenda-table-type-plenary').scrollIntoViewIfNeeded() + + // Check for full video client + on-site tool + await expect(page.locator(`.agenda .agenda-table-display-event.agenda-table-type-plenary .agenda-table-cell-links-buttons a#btn-lnk-${plenarySessionId}-video`)).toBeVisible() + await expect(page.locator(`.agenda .agenda-table-display-event.agenda-table-type-plenary .agenda-table-cell-links-buttons a#btn-lnk-${plenarySessionId}-onsitetool`)).toBeVisible() + }) + + // -> BUTTONS NO LONGER PRESENT AFTER EVENT, NEXT DAY + + test('next day - after event', async ({ page }) => { + // Override Date in page to fixed time + const currentTime = DateTime.fromISO('2022-02-01T13:45:15', { zone: 'Asia/Tokyo' }).plus({ days: 2 }).set({ hour: 2, minute: 30 }) + await commonHelper.overridePageDateTime(page, currentTime) + + // Visit agenda page and await Meeting Data API call to complete + await Promise.all([ + page.waitForResponse(`**/api/meeting/${meetingData.meeting.number}/agenda-data`), + page.goto(`/meeting/${meetingData.meeting.number}/agenda`) + ]) + + // Wait for page to be ready + await page.locator('.agenda h1').waitFor({ state: 'visible' }) + await setTimeout(500) + + // Check for plenary event + await expect(page.locator('.agenda .agenda-table-display-event.agenda-table-type-plenary')).toBeVisible() + await page.locator('.agenda .agenda-table-display-event.agenda-table-type-plenary').scrollIntoViewIfNeeded() + + // Check for full video client + on-site tool + await expect(page.locator(`.agenda .agenda-table-display-event.agenda-table-type-plenary .agenda-table-cell-links-buttons a#btn-lnk-${plenarySessionId}-video`)).not.toBeVisible() + await expect(page.locator(`.agenda .agenda-table-display-event.agenda-table-type-plenary .agenda-table-cell-links-buttons a#btn-lnk-${plenarySessionId}-onsitetool`)).not.toBeVisible() + }) +}) + +// ==================================================================== +// AGENDA (past meeting) | SMALL DESKTOP/TABLET/MOBILE viewports +// ==================================================================== + +test.describe('past - small screens', () => { + let meetingData + + test.beforeAll(async () => { + // Generate meeting data + meetingData = meetingHelper.generateAgendaResponse({ dateMode: 'past' }) + }) + + for (const vp of ['smallDesktop', 'tablet', 'mobile']) { + test(vp, async ({ page }) => { + // Intercept Meeting Data API + await page.route(`**/api/meeting/${meetingData.meeting.number}/agenda-data`, route => { + route.fulfill({ + status: 200, + contentType: 'application/json', + body: JSON.stringify(meetingData) + }) + }) + + await page.setViewportSize({ + width: viewports[vp][0], + height: viewports[vp][1] + }) + + // Visit agenda page and await Meeting Data API call to complete + await Promise.all([ + page.waitForResponse(`**/api/meeting/${meetingData.meeting.number}/agenda-data`), + page.goto(`/meeting/${meetingData.meeting.number}/agenda`) + ]) + + // Wait for page to be ready + await page.locator('.agenda h1').waitFor({ state: 'visible' }) + await setTimeout(500) + + // -> NARROW QUICK ACCESS PANEL (smallDesktop only) + + if (vp === 'smallDesktop') { + // Alternate labels for buttons + await expect(page.locator('#agenda-quickaccess-filterbyareagroups-btn')).toContainText('Filter...') + await expect(page.locator('#agenda-quickaccess-filterbyareagroups-btn + button')).toContainText('Pick...') + await expect(page.locator('#agenda-quickaccess-calview-btn')).toContainText('Cal View') + await expect(page.locator('#agenda-quickaccess-calview-btn + button')).toContainText('.ics') + // -> Shorter date labels for Jump to buttons + const jumpNavLocator = page.locator('.agenda .agenda-quickaccess-jumpto > .nav-item') + await expect(jumpNavLocator).toHaveCount(7) + for (let idx = 0; idx < 7; idx++) { + const localDateTime = DateTime.fromISO(meetingData.meeting.startDate, { zone: meetingData.meeting.timezone }) + .setLocale(BROWSER_LOCALE) + .plus({ days: idx }) + .toFormat('ccc LLL d') + await expect(jumpNavLocator.nth(idx)).toContainText(localDateTime) + await expect(jumpNavLocator.nth(idx).locator('i.bi')).not.toBeVisible() + } + } + + // Check for elements that should not exist on smaller screens + + if (vp === 'tablet' || vp === 'mobile') { + // has no updated date + await expect(page.locator('.agenda > h4 > h6')).not.toBeVisible() + + // has no timezone dropdown selector + await expect(page.locator('.agenda .agenda-tz-selector + .agenda-timezone-ddn')).not.toBeVisible() + + // has no floor + group indicators + const floorIndLocator = page.locator('.agenda .agenda-table-cell-room > .badge') + const floorIndCount = await floorIndLocator.count() + for (let idx = 0; idx < floorIndCount; idx++) { + await expect(floorIndLocator.nth(idx)).not.toBeVisible() + } + await expect(page.locator('.agenda .agenda-table-cell-group > .badge')).toHaveCount(0) + + // Session buttons should be hidden in a dropdown menu + const linkBtnsLocator = page.locator('.agenda .agenda-table-display-event .agenda-table-cell-links-buttons') + const linkBtnsCount = await linkBtnsLocator.count() + for (let idx; idx < linkBtnsCount; idx++) { + await expect(linkBtnsLocator.nth(idx).locator('> *')).toHaveCount(1) + } + + // TODO: Check for dropdown links once changed to a custom panel with standard links + + // Bottom Mobile Bar + const barBtnLocator = page.locator('.agenda-mobile-bar > button') + + // has no lateral quick access panel + await expect(page.locator('.agenda-quickaccess')).not.toBeVisible() + + // has a bottom mobile bar + await expect(page.locator('.agenda-mobile-bar')).toBeVisible() + await expect(barBtnLocator).toHaveCount(5) + + // can open the jump to day dropdown + await barBtnLocator.first().click() + const jumpDayDdnLocator = page.locator('.n-dropdown-menu [data-testid=mobile-link]') + await expect(jumpDayDdnLocator).toHaveCount(7) + for (let idx = 0; idx < 7; idx++) { + const localDateTime = DateTime.fromISO(meetingData.meeting.startDate, { zone: meetingData.meeting.timezone }) + .setLocale(BROWSER_LOCALE) + .plus({ days: idx }) + .toFormat('ccc LLL d') + await expect(jumpDayDdnLocator.nth(idx)).toContainText(`Jump to ${localDateTime}`) + } + + // can open the filters overlay + await barBtnLocator.nth(1).click() + await expect(page.locator('.agenda-personalize')).toBeVisible() + await page.locator('.agenda-personalize .agenda-personalize-actions > button').nth(1).click() + await expect(page.locator('.agenda-personalize')).toBeHidden() + + // can open the calendar view + await barBtnLocator.nth(2).click() + await expect(page.locator('.agenda-calendar')).toBeVisible() + await page.locator('.agenda-calendar .agenda-calendar-actions > button').nth(1).click() + await expect(page.locator('.agenda-calendar')).toBeHidden() + + // can open the ics dropdown + await barBtnLocator.nth(3).click() + const calDdnLocator = page.locator('.n-dropdown-menu > .n-dropdown-option') + await expect(calDdnLocator).toHaveCount(2) + await expect(calDdnLocator.first()).toContainText('Subscribe') + await expect(calDdnLocator.last()).toContainText('Download') + + // can open the settings overlay + await barBtnLocator.last().click() + await expect(page.locator('.agenda-settings')).toBeVisible() + await page.locator('.agenda-settings .agenda-settings-actions > button').nth(1).click() + await expect(page.locator('.agenda-settings')).toBeHidden() + } + }) + } +}) diff --git a/playwright/tests/meeting/floor-plan.spec.js b/playwright/tests/meeting/floor-plan.spec.js new file mode 100644 index 00000000000..fcaa5d4a58f --- /dev/null +++ b/playwright/tests/meeting/floor-plan.spec.js @@ -0,0 +1,129 @@ +const { test, expect } = require('@playwright/test') +const { faker } = require('@faker-js/faker') +const seedrandom = require('seedrandom') +const meetingGenerator = require('../../helpers/meeting.js') +const viewports = require('../../helpers/viewports') +const { setTimeout } = require('timers/promises') + +const TEST_SEED = 123 + +// Set randomness seed +seedrandom(TEST_SEED.toString(), { global: true }) +faker.seed(TEST_SEED) + +// ==================================================================== +// FLOOR-PLAN | All Viewports +// ==================================================================== + +test.describe('floor-plan', () => { + let meetingData + + test.beforeAll(async () => { + // Generate meeting data (without schedule data) + meetingData = meetingGenerator.generateAgendaResponse({ dateMode: 'past', skipSchedule: true }) + }) + + for (const vp of ['desktop', 'smallDesktop', 'tablet', 'mobile']) { + test(vp, async ({ page }) => { + // Intercept Meeting Data API + await page.route(`**/api/meeting/${meetingData.meeting.number}/agenda-data`, route => { + route.fulfill({ + status: 200, + contentType: 'application/json', + body: JSON.stringify(meetingData) + }) + }) + + await page.setViewportSize({ + width: viewports[vp][0], + height: viewports[vp][1] + }) + + // Visit floor plan page and await Meeting Data API call to complete + await Promise.all([ + page.waitForResponse(`**/api/meeting/${meetingData.meeting.number}/agenda-data`), + page.goto(`/meeting/${meetingData.meeting.number}/floor-plan`) + ]) + + // Wait for page to be ready + await page.locator('.floorplan h1').waitFor({ state: 'visible' }) + await setTimeout(500) + + // -> HEADER + + await test.step(`has IETF ${meetingData.meeting.number} title`, async () => { + await expect(page.locator('.floorplan h1').first()).toContainText(`IETF ${meetingData.meeting.number} Floor Plan`) + }) + await test.step('has meeting city subtitle', async () => { + await expect(page.locator('.floorplan h4').first()).toContainText(meetingData.meeting.city) + }) + await test.step('has meeting date subtitle', async () => { + await expect(page.locator('.floorplan h4').first()).toContainText(/[a-zA-Z] [0-9]{1,2} - ([a-zA-Z]+ )?[0-9]{1,2}, [0-9]{4}/i) + }) + + // -> NAV + + await test.step('has the correct navigation items', async () => { + const navItemsLocator = page.locator('.floorplan .meeting-nav > li') + await expect(navItemsLocator).toHaveCount(3) + await expect(navItemsLocator.first()).toContainText('Agenda') + await expect(navItemsLocator.nth(1)).toContainText('Floor plan') + await expect(navItemsLocator.last()).toContainText('Plaintext') + }) + + // -> FLOORS + + await test.step('can switch between floors', async () => { + const floorsLocator = page.locator('.floorplan .floorplan-floors > .nav-link') + const floorImageLocator = page.locator('.floorplan .floorplan-plan > img') + + await expect(floorsLocator).toHaveCount(meetingData.floors.length) + for (let idx = 0; idx < meetingData.floors.length; idx++) { + await expect(floorsLocator.nth(idx)).toContainText(meetingData.floors[idx].name) + await floorsLocator.nth(idx).click() + await expect(floorsLocator.nth(idx)).toHaveClass(/active/) + await expect(page.locator('.floorplan .floorplan-floors > .nav-link:not(.active)')).toHaveCount(meetingData.floors.length - 1) + // Wait for image to load + verify + await expect(floorImageLocator).toBeVisible() + await setTimeout(100) + await expect(await floorImageLocator.evaluate(node => node.naturalWidth)).toBeGreaterThan(1) + } + }) + + // -> ROOMS + + await test.step('can select rooms', async () => { + const roomsLocator = page.locator('.floorplan .floorplan-rooms > .list-group-item') + const floorImageLocator = page.locator('.floorplan .floorplan-plan > img') + const pinLocator = page.locator('.floorplan .floorplan-plan-pin') + const floor = meetingData.floors[0] + await page.locator('.floorplan .floorplan-floors > .nav-link').first().click() + await expect(roomsLocator).toHaveCount(floor.rooms.length) + for (let idx = 0; idx < floor.rooms.length; idx++) { + // Room List + const room = floor.rooms[idx] + await expect(roomsLocator.nth(idx).locator('strong')).toContainText(room.name) + await expect(roomsLocator.nth(idx).locator('strong + small')).toContainText(room.functionalName) + await expect(roomsLocator.nth(idx).locator('.badge')).toContainText(floor.short) + await roomsLocator.nth(idx).click() + await expect(roomsLocator.nth(idx)).toHaveClass(/active/) + await expect(page.locator('.floorplan .floorplan-rooms > .list-group-item:not(.active)')).toHaveCount(floor.rooms.length - 1) + // URL query segment + await expect(page.url()).toMatch(`room=${room.slug}`) + // Pin Drop + const planxRatio = (await floorImageLocator.evaluate(node => node.width)) / floor.width + const planyRatio = (await floorImageLocator.evaluate(node => node.height)) / floor.height + await expect(pinLocator).toBeVisible() + // eslint-disable-next-line no-useless-escape, quotes + const pinMarginLeft = await page.evaluate(`parseInt(window.getComputedStyle(document.querySelector('.floorplan .floorplan-plan-pin')).getPropertyValue('margin-left').match(/\\d+/))`) + const xPos = Math.round((room.left + (room.right - room.left) / 2) * planxRatio) - 25 + pinMarginLeft + const yPos = Math.round((room.top + (room.bottom - room.top) / 2) * planyRatio) - 40 + const offsetLeft = await pinLocator.evaluate(node => node.offsetLeft) + const offsetTop = await pinLocator.evaluate(node => node.offsetTop) + expect(offsetLeft).toBe(xPos) + expect(offsetTop).toBe(yPos) + } + }) + }) + } +}) diff --git a/playwright/tests/status/status.spec.js b/playwright/tests/status/status.spec.js new file mode 100644 index 00000000000..c70617e2fd6 --- /dev/null +++ b/playwright/tests/status/status.spec.js @@ -0,0 +1,66 @@ +const { + test, + expect +} = require('@playwright/test') +const { STATUS_STORAGE_KEY, generateStatusTestId } = require('../../../client/shared/status-common.js') + +test.describe('site status', () => { + const noStatus = { + hasMessage: false + } + + const status1 = { + hasMessage: true, + id: 1, + slug: '2024-7-9fdfdf-sdfsdf', + title: 'My status title', + body: 'My status body', + url: '/status/2024-7-9fdfdf-sdfsdf', + date: '2024-07-09T07:05:13+00:00', + by: 'Exile is a cool Amiga game' + } + + test.beforeEach(({ page, browserName }) => { + page.setDefaultTimeout(15 * 1000) // increase default timeout + test.skip(browserName === 'firefox', 'bypassing flaky tests on Firefox') + }) + + test('Renders server status as Notification', async ({ page }) => { + await page.route('/status/latest.json', route => { + route.fulfill({ + status: 200, + contentType: 'application/json', + body: JSON.stringify(status1) + }) + }) + await page.goto('/') + await expect(page.getByTestId(generateStatusTestId(status1.id)), 'should have status').toHaveCount(1) + }) + + test("Doesn't render dismissed server statuses", async ({ page }) => { + await page.route('/status/latest.json', route => { + route.fulfill({ + status: 200, + contentType: 'application/json', + body: JSON.stringify(status1) + }) + }) + await page.goto('/') + await page.evaluate(({ key, value }) => localStorage.setItem(key, value), { key: STATUS_STORAGE_KEY, value: JSON.stringify([status1.id]) }) + await expect(page.getByTestId(generateStatusTestId(status1.id)), 'should have status').toHaveCount(0) + }) + + test('Handles no server status', async ({ page }) => { + await page.route('/status/latest.json', route => { + route.fulfill({ + status: 200, + contentType: 'application/json', + body: JSON.stringify(noStatus) + }) + }) + + await page.goto('/') + + await expect(page.getByTestId(generateStatusTestId(status1.id)), 'should have status').toHaveCount(0) + }) +}) diff --git a/pyzmail/__init__.py b/pyzmail/__init__.py deleted file mode 100644 index f6c8854abc1..00000000000 --- a/pyzmail/__init__.py +++ /dev/null @@ -1,21 +0,0 @@ -# -# pyzmail/__init__.py -# (c) Alain Spineux -# http://www.magiksys.net/pyzmail -# Released under LGPL - -from . import utils -from .generate import compose_mail, send_mail, send_mail2 -from .parse import email_address_re, PyzMessage, PzMessage, decode_text -from .parse import message_from_string, message_from_file -from .parse import message_from_bytes, message_from_binary_file # python >= 3.2 -from .version import __version__ - -# to help epydoc to display functions available from top of the package -__all__= [ 'compose_mail', 'send_mail', 'send_mail2', 'email_address_re', \ - 'PyzMessage', 'PzMessage', 'decode_text', '__version__', - 'utils', 'generate', 'parse', 'version', - 'message_from_string','message_from_file', - 'message_from_binary_file', 'message_from_bytes', # python >= 3.2 - ] - diff --git a/pyzmail/generate.py b/pyzmail/generate.py deleted file mode 100644 index 2ad1f622462..00000000000 --- a/pyzmail/generate.py +++ /dev/null @@ -1,529 +0,0 @@ -# -# pyzmail/generate.py -# (c) Alain Spineux -# http://www.magiksys.net/pyzmail -# Released under LGPL - -""" -Useful functions to compose and send emails. - -For short: - ->>> payload, mail_from, rcpt_to, msg_id=compose_mail((u'Me', 'me@foo.com'), -... [(u'Him', 'him@bar.com')], u'the subject', 'iso-8859-1', ('Hello world', 'us-ascii'), -... attachments=[('attached', 'text', 'plain', 'text.txt', 'us-ascii')]) -... #doctest: +SKIP ->>> error=send_mail(payload, mail_from, rcpt_to, 'localhost', smtp_port=25) -... #doctest: +SKIP -""" - -import os, sys -import time -import base64 -import smtplib, socket -import email -import email.encoders -import email.header -import email.utils -import email.mime -import email.mime.base -import email.mime.text -import email.mime.image -import email.mime.multipart - -from . import utils - -def format_addresses(addresses, header_name=None, charset=None): - """ - Convert a list of addresses into a MIME-compliant header for a From, To, Cc, - or any other I{address} related field. - This mixes the use of email.utils.formataddr() and email.header.Header(). - - @type addresses: list - @param addresses: list of addresses, can be a mix of string a tuple of the form - C{[ 'address@domain', (u'Name', 'name@domain'), ...]}. - If C{u'Name'} contains non us-ascii characters, it must be a - unicode string or encoded using the I{charset} argument. - @type header_name: string or None - @keyword header_name: the name of the header. Its length is used to limit - the length of the first line of the header according the RFC's - requirements. (not very important, but it's better to match the - requirements when possible) - @type charset: str - @keyword charset: the encoding charset for non unicode I{name} and a B{hint} - for encoding of unicode string. In other words, - if the I{name} of an address in a byte string containing non - I{us-ascii} characters, then C{name.decode(charset)} - must generate the expected result. If a unicode string - is used instead, charset will be tried to encode the - string, if it fail, I{utf-8} will be used. - With B{Python 3.x} I{charset} is no more a hint and an exception will - be raised instead of using I{utf-8} has a fall back. - @rtype: str - @return: the encoded list of formated addresses separated by commas, - ready to use as I{Header} value. - - >>> print format_addresses([('John', 'john@foo.com') ], 'From', 'us-ascii').encode() - John - >>> print format_addresses([(u'l\\xe9o', 'leo@foo.com') ], 'To', 'iso-8859-1').encode() - =?iso-8859-1?q?l=E9o?= - >>> print format_addresses([(u'l\\xe9o', 'leo@foo.com') ], 'To', 'us-ascii').encode() - ... # don't work in 3.X because charset is more than a hint - ... #doctest: +SKIP - =?utf-8?q?l=C3=A9o?= - >>> # because u'l\xe9o' cannot be encoded into us-ascii, utf8 is used instead - >>> print format_addresses([('No\\xe9', 'noe@f.com'), (u'M\\u0101ori', 'maori@b.com') ], 'Cc', 'iso-8859-1').encode() - ... # don't work in 3.X because charset is more than a hint - ... #doctest: +SKIP - =?iso-8859-1?q?No=E9?= , =?utf-8?b?TcSBb3Jp?= - >>> # 'No\xe9' is already encoded into iso-8859-1, but u'M\\u0101ori' cannot be encoded into iso-8859-1 - >>> # then utf8 is used here - >>> print format_addresses(['a@bar.com', ('John', 'john@foo.com') ], 'From', 'us-ascii').encode() - a@bar.com , John - """ - header=email.header.Header(charset=charset, header_name=header_name) - for i, address in enumerate(addresses): - if i!=0: - # add separator between addresses - header.append(',', charset='us-ascii') - - try: - name, addr=address - except ValueError: - # address is not a tuple, their is no name, only email address - header.append(address, charset='us-ascii') - else: - # check if address name is a unicode or byte string in "pure" us-ascii - if utils.is_usascii(name): - # name is a us-ascii byte string, i can use formataddr - formated_addr=email.utils.formataddr((name, addr)) - # us-ascii must be used and not default 'charset' - header.append(formated_addr, charset='us-ascii') - else: - # this is not as "pure" us-ascii string - # Header will use "RFC2047" to encode the address name - # if name is byte string, charset will be used to decode it first - header.append(name) - # here us-ascii must be used and not default 'charset' - header.append('<%s>' % (addr,), charset='us-ascii') - - return header - - -def build_mail(text, html=None, attachments=None, embeddeds=None): - """ - Generate the core of the email message regarding the parameters. - The structure of the MIME email may vary, but the general one is as follow:: - - multipart/mixed (only if attachments are included) - | - +-- multipart/related (only if embedded contents are included) - | | - | +-- multipart/alternative (only if text AND html are available) - | | | - | | +-- text/plain (text version of the message) - | | +-- text/html (html version of the message) - | | - | +-- image/gif (where to include embedded contents) - | - +-- application/msword (where to add attachments) - - @param text: the text version of the message, under the form of a tuple: - C{(encoded_content, encoding)} where I{encoded_content} is a byte string - encoded using I{encoding}. - I{text} can be None if the message has no text version. - @type text: tuple or None - @keyword html: the HTML version of the message, under the form of a tuple: - C{(encoded_content, encoding)} where I{encoded_content} is a byte string - encoded using I{encoding} - I{html} can be None if the message has no HTML version. - @type html: tuple or None - @keyword attachments: the list of attachments to include into the mail, in the - form [(data, maintype, subtype, filename, charset), ..] where : - - I{data} : is the raw data, or a I{charset} encoded string for 'text' - content. - - I{maintype} : is a MIME main type like : 'text', 'image', 'application' .... - - I{subtype} : is a MIME sub type of the above I{maintype} for example : - 'plain', 'png', 'msword' for respectively 'text/plain', 'image/png', - 'application/msword'. - - I{filename} this is the filename of the attachment, it must be a - 'us-ascii' string or a tuple of the form - C{(encoding, language, encoded_filename)} - following the RFC2231 requirement, for example - C{('iso-8859-1', 'fr', u'r\\xe9pertoir.png'.encode('iso-8859-1'))} - - I{charset} : if I{maintype} is 'text', then I{data} must be encoded - using this I{charset}. It can be None for non 'text' content. - @type attachments: list - @keyword embeddeds: is a list of documents embedded inside the HTML or text - version of the message. It is similar to the I{attachments} list, - but I{filename} is replaced by I{content_id} that is related to - the B{cid} reference into the HTML or text version of the message. - @type embeddeds: list - @rtype: inherit from email.Message - @return: the message in a MIME object - - >>> mail=build_mail(('Hello world', 'us-ascii'), attachments=[('attached', 'text', 'plain', 'text.txt', 'us-ascii')]) - >>> mail.set_boundary('===limit1==') - >>> print mail.as_string(unixfrom=False) - Content-Type: multipart/mixed; boundary="===limit1==" - MIME-Version: 1.0 - - --===limit1== - Content-Type: text/plain; charset="us-ascii" - MIME-Version: 1.0 - Content-Transfer-Encoding: 7bit - - Hello world - --===limit1== - Content-Type: text/plain; charset="us-ascii" - MIME-Version: 1.0 - Content-Transfer-Encoding: 7bit - Content-Disposition: attachment; filename="text.txt" - - attached - --===limit1==-- - """ - - if attachments is None: - attachments = [] - if embeddeds is None: - embeddeds = [] - - main=text_part=html_part=None - if text: - content, charset=text - main=text_part=email.mime.text.MIMEText(content, 'plain', charset) - - if html: - content, charset=html - main=html_part=email.mime.text.MIMEText(content, 'html', charset) - - if not text_part and not html_part: - main=text_part=email.mime.text.MIMEText('', 'plain', 'us-ascii') - elif text_part and html_part: - # need to create a multipart/alternative to include text and html version - main=email.mime.multipart.MIMEMultipart('alternative', None, [text_part, html_part]) - - if embeddeds: - related=email.mime.multipart.MIMEMultipart('related') - related.attach(main) - for part in embeddeds: - if not isinstance(part, email.mime.base.MIMEBase): - data, maintype, subtype, content_id, charset=part - if (maintype=='text'): - part=email.mime.text.MIMEText(data, subtype, charset) - else: - part=email.mime.base.MIMEBase(maintype, subtype) - part.set_payload(data) - email.encoders.encode_base64(part) - part.add_header('Content-ID', '<'+content_id+'>') - part.add_header('Content-Disposition', 'inline') - related.attach(part) - main=related - - if attachments: - mixed=email.mime.multipart.MIMEMultipart('mixed') - mixed.attach(main) - for part in attachments: - if not isinstance(part, email.mime.base.MIMEBase): - data, maintype, subtype, filename, charset=part - if (maintype=='text'): - part=email.mime.text.MIMEText(data, subtype, charset) - else: - part=email.mime.base.MIMEBase(maintype, subtype) - part.set_payload(data) - email.encoders.encode_base64(part) - part.add_header('Content-Disposition', 'attachment', filename=filename) - mixed.attach(part) - main=mixed - - return main - -def complete_mail(message, sender, recipients, subject, default_charset, cc=None, bcc=None, message_id_string=None, date=None, headers=None): - """ - Fill in the From, To, Cc, Subject, Date and Message-Id I{headers} of - one existing message regarding the parameters. - - @type message:email.Message - @param message: the message to fill in - @type sender: tuple - @param sender: a tuple of the form (u'Sender Name', 'sender.address@domain.com') - @type recipients: list - @param recipients: a list of addresses. Address can be tuple or string like - expected by L{format_addresses()}, for example: C{[ 'address@dmain.com', - (u'Recipient Name', 'recipient.address@domain.com'), ... ]} - @type subject: str - @param subject: The subject of the message, can be a unicode string or a - string encoded using I{default_charset} encoding. Prefert unicode to - byte string here. - @type default_charset: str - @param default_charset: The default charset for this email. Arguments - that are non unicode string are supposed to be encoded using this charset. - This I{charset} will be used has an hint when encoding mail content. - @type cc: list - @keyword cc: The I{carbone copy} addresses. Same format as the I{recipients} - argument. - @type bcc: list - @keyword bcc: The I{blind carbone copy} addresses. Same format as the I{recipients} - argument. - @type message_id_string: str or None - @keyword message_id_string: if None, don't append any I{Message-ID} to the - mail, let the SMTP do the job, else use the string to generate a unique - I{ID} using C{email.utils.make_msgid()}. The generated value is - returned as last argument. For example use the name of your application. - @type date: int or None - @keyword date: utc time in second from the epoch or None. If None then - use curent time C{time.time()} instead. - @type headers: list of tuple - @keyword headers: a list of C{(field, value)} tuples to fill in the mail - header fields. Values are encoded using I{default_charset}. - @rtype: tuple - @return: B{(payload, mail_from, rcpt_to, msg_id)} - - I{payload} (str) is the content of the email, generated from the message - - I{mail_from} (str) is the address of the sender to pass to the SMTP host - - I{rcpt_to} (list) is a list of the recipients addresses to pass to the SMTP host - of the form C{[ 'a@b.com', c@d.com', ]}. This combine all recipients, - I{carbone copy} addresses and I{blind carbone copy} addresses. - - I{msg_id} (None or str) None if message_id_string==None else the generated value for - the message-id. If not None, this I{Message-ID} is already written - into the payload. - - >>> import email.mime.text - >>> msg=email.mime.text.MIMEText('The text.', 'plain', 'us-ascii') - >>> # I could use build_mail() instead - >>> payload, mail_from, rcpt_to, msg_id=complete_mail(msg, ('Me', 'me@foo.com'), - ... [ ('Him', 'him@bar.com'), ], 'Non unicode subject', 'iso-8859-1', - ... cc=['her@bar.com',], date=1313558269, headers=[('User-Agent', u'pyzmail'), ]) - >>> print payload - ... # 3.X encode User-Agent: using 'iso-8859-1' even if it contains only us-asccii - ... # doctest: +ELLIPSIS - Content-Type: text/plain; charset="us-ascii" - MIME-Version: 1.0 - Content-Transfer-Encoding: 7bit - From: Me - To: Him - Cc: her@bar.com - Subject: =?iso-8859-1?q?Non_unicode_subject?= - Date: ... - User-Agent: ...pyzmail... - - The text. - >>> print 'mail_from=%r rcpt_to=%r' % (mail_from, rcpt_to) - mail_from='me@foo.com' rcpt_to=['him@bar.com', 'her@bar.com'] - """ - def getaddr(address): - if isinstance(address, tuple): - return address[1] - else: - return address - - if cc is None: - cc=[] - if bcc is None: - bcc=[] - if headers is None: - headers=[] - - mail_from=getaddr(sender[1]) - rcpt_to=list(map(getaddr, recipients)) - rcpt_to.extend(list(map(getaddr, cc))) - rcpt_to.extend(list(map(getaddr, bcc))) - - message['From'] = format_addresses([ sender, ], header_name='from', charset=default_charset) - if recipients: - message['To'] = format_addresses(recipients, header_name='to', charset=default_charset) - if cc: - message['Cc'] = format_addresses(cc, header_name='cc', charset=default_charset) - message['Subject'] = email.header.Header(subject, default_charset) - if date: - utc_from_epoch=date - else: - utc_from_epoch=time.time() - message['Date'] = email.utils.formatdate(utc_from_epoch, localtime=True) - - if message_id_string: - msg_id=message['Message-Id']=email.utils.make_msgid(message_id_string) - else: - msg_id=None - - for field, value in headers: - message[field]=email.header.Header(value, default_charset) - - payload=message.as_string() - - return payload, mail_from, rcpt_to, msg_id - -def compose_mail(sender, recipients, subject, default_charset, text, html=None, attachments=None, embeddeds=None, cc=None, bcc=None, message_id_string=None, date=None, headers=None): - """ - Compose an email regarding the arguments. Call L{build_mail()} and - L{complete_mail()} at once. - - Read the B{parameters} descriptions of both functions L{build_mail()} and L{complete_mail()}. - - Returned value is the same as for L{build_mail()} and L{complete_mail()}. - You can pass the returned values to L{send_mail()} or L{send_mail2()}. - - @rtype: tuple - @return: B{(payload, mail_from, rcpt_to, msg_id)} - - >>> payload, mail_from, rcpt_to, msg_id=compose_mail((u'Me', 'me@foo.com'), [(u'Him', 'him@bar.com')], u'the subject', 'iso-8859-1', ('Hello world', 'us-ascii'), attachments=[('attached', 'text', 'plain', 'text.txt', 'us-ascii')]) - """ - if attachments is None: - attachments=[] - if embeddeds is None: - embeddeds=[] - if cc is None: - cc=[] - if bcc is None: - bcc = [] - if headers is None: - headers=[] - - message=build_mail(text, html, attachments, embeddeds) - return complete_mail(message, sender, recipients, subject, default_charset, cc, bcc, message_id_string, date, headers) - - -def send_mail2(payload, mail_from, rcpt_to, smtp_host, smtp_port=25, smtp_mode='normal', smtp_login=None, smtp_password=None): - """ - Send the message to a SMTP host. Look at the L{send_mail()} documentation. - L{send_mail()} call this function and catch all exceptions to convert them - into a user friendly error message. The returned value - is always a dictionary. It can be empty if all recipients have been - accepted. - - @rtype: dict - @return: This function return the value returnd by C{smtplib.SMTP.sendmail()} - or raise the same exceptions. - - This method will return normally if the mail is accepted for at least one - recipient. Otherwise it will raise an exception. That is, if this - method does not raise an exception, then someone should get your mail. - If this method does not raise an exception, it returns a dictionary, - with one entry for each recipient that was refused. Each entry contains a - tuple of the SMTP error code and the accompanying error message sent by the server. - - @raise smtplib.SMTPException: Look at the standard C{smtplib.SMTP.sendmail()} documentation. - - """ - if smtp_mode=='ssl': - smtp=smtplib.SMTP_SSL(smtp_host, smtp_port) - else: - smtp=smtplib.SMTP(smtp_host, smtp_port) - if smtp_mode=='tls': - smtp.starttls() - - if smtp_login and smtp_password: - if sys.version_info<(3, 0): - # python 2.x - # login and password must be encoded - # because HMAC used in CRAM_MD5 require non unicode string - smtp.login(smtp_login.encode('utf-8'), smtp_password.encode('utf-8')) - else: - #python 3.x - smtp.login(smtp_login, smtp_password) - try: - ret=smtp.sendmail(mail_from, rcpt_to, payload) - finally: - try: - smtp.quit() - except Exception as e: - pass - - return ret - -def send_mail(payload, mail_from, rcpt_to, smtp_host, smtp_port=25, smtp_mode='normal', smtp_login=None, smtp_password=None): - """ - Send the message to a SMTP host. Handle SSL, TLS and authentication. - I{payload}, I{mail_from} and I{rcpt_to} can come from values returned by - L{complete_mail()}. This function call L{send_mail2()} but catch all - exceptions and return friendly error message instead. - - @type payload: str - @param payload: the mail content. - @type mail_from: str - @param mail_from: the sender address, for example: C{'me@domain.com'}. - @type rcpt_to: list - @param rcpt_to: The list of the recipient addresses in the form - C{[ 'a@b.com', c@d.com', ]}. No names here, only email addresses. - @type smtp_host: str - @param smtp_host: the IP address or the name of the SMTP host. - @type smtp_port: int - @keyword smtp_port: the port to connect to on the SMTP host. Default is C{25}. - @type smtp_mode: str - @keyword smtp_mode: the way to connect to the SMTP host, can be: - C{'normal'}, C{'ssl'} or C{'tls'}. default is C{'normal'} - @type smtp_login: str or None - @keyword smtp_login: If authentication is required, this is the login. - Be carefull to I{UTF8} encode your login if it contains - non I{us-ascii} characters. - @type smtp_password: str or None - @keyword smtp_password: If authentication is required, this is the password. - Be carefull to I{UTF8} encode your password if it - contains non I{us-ascii} characters. - - @rtype: dict or str - @return: This function return a dictionary of failed recipients - or a string with an error message. - - If all recipients have been accepted the dictionary is empty. If the - returned value is a string, none of the recipients will get the message. - - The dictionary is exactly of the same sort as - smtplib.SMTP.sendmail() returns with one entry for each recipient that - was refused. Each entry contains a tuple of the SMTP error code and - the accompanying error message sent by the server. - - Example: - - >>> send_mail('Subject: hello\\n\\nmessage', 'a@foo.com', [ 'b@bar.com', ], 'localhost') #doctest: +SKIP - {} - - Here is how to use the returned value:: - if isinstance(ret, dict): - if ret: - print 'failed' recipients: - for recipient, (code, msg) in ret.iteritems(): - print 'code=%d recipient=%s\terror=%s' % (code, recipient, msg) - else: - print 'success' - else: - print 'Error:', ret - - To use your GMail account to send your mail:: - smtp_host='smtp.gmail.com' - smtp_port=587 - smtp_mode='tls' - smtp_login='your.gmail.addresse@gmail.com' - smtp_password='your.gmail.password' - - Use your GMail address for the sender ! - - """ - - error=dict() - try: - ret=send_mail2(payload, mail_from, rcpt_to, smtp_host, smtp_port, smtp_mode, smtp_login, smtp_password) - except (socket.error, ) as e: - error='server %s:%s not responding: %s' % (smtp_host, smtp_port, e) - except smtplib.SMTPAuthenticationError as e: - error='authentication error: %s' % (e, ) - except smtplib.SMTPRecipientsRefused as e: - # code, error=e.recipients[recipient_addr] - error='all recipients refused: '+', '.join(list(e.recipients.keys())) - except smtplib.SMTPSenderRefused as e: - # e.sender, e.smtp_code, e.smtp_error - error='sender refused: %s' % (e.sender, ) - except smtplib.SMTPDataError as e: - error='SMTP protocol mismatch: %s' % (e, ) - except smtplib.SMTPHeloError as e: - error="server didn't reply properly to the HELO greeting: %s" % (e, ) - except smtplib.SMTPException as e: - error='SMTP error: %s' % (e, ) -# except Exception, e: -# raise # unknown error - else: - # failed addresses and error messages - error=ret - - return error - diff --git a/pyzmail/parse.py b/pyzmail/parse.py deleted file mode 100644 index 9f86c371774..00000000000 --- a/pyzmail/parse.py +++ /dev/null @@ -1,817 +0,0 @@ -# -# pyzmail/parse.py -# (c) Alain Spineux -# http://www.magiksys.net/pyzmail -# Released under LGPL - -""" -Useful functions to parse emails - -@var email_address_re: a regex that match well formed email address (from perlfaq9) -@undocumented: atom_rfc2822 -@undocumented: atom_posfix_restricted -@undocumented: atom -@undocumented: dot_atom -@undocumented: local -@undocumented: domain_lit -@undocumented: domain -@undocumented: addr_spec -""" - -import re -import io -import email -import email.errors -import email.header -import email.message -import mimetypes - -from .utils import * - -# email address REGEX matching the RFC 2822 spec from perlfaq9 -# my $atom = qr{[a-zA-Z0-9_!#\$\%&'*+/=?\^`{}~|\-]+}; -# my $dot_atom = qr{$atom(?:\.$atom)*}; -# my $quoted = qr{"(?:\\[^\r\n]|[^\\"])*"}; -# my $local = qr{(?:$dot_atom|$quoted)}; -# my $domain_lit = qr{\[(?:\\\S|[\x21-\x5a\x5e-\x7e])*\]}; -# my $domain = qr{(?:$dot_atom|$domain_lit)}; -# my $addr_spec = qr{$local\@$domain}; -# -# Python's translation -atom_rfc2822=r"[a-zA-Z0-9_!#\$\%&'*+/=?\^`{}~|\-]+" -atom_posfix_restricted=r"[a-zA-Z0-9_#\$&'*+/=?\^`{}~|\-]+" # without '!' and '%' -atom=atom_rfc2822 -dot_atom=atom + r"(?:\." + atom + ")*" -quoted=r'"(?:\\[^\r\n]|[^\\"])*"' -local="(?:" + dot_atom + "|" + quoted + ")" -domain_lit=r"\[(?:\\\S|[\x21-\x5a\x5e-\x7e])*\]" -domain="(?:" + dot_atom + "|" + domain_lit + ")" -addr_spec=local + "@" + domain -# and the result -email_address_re=re.compile('^'+addr_spec+'$') - -class MailPart: - """ - Data related to a mail part (aka message content, attachment or - embedded content in an email) - - @type charset: str or None - @ivar charset: the encoding of the I{get_payload()} content if I{type} is 'text/*' - and charset has been specified in the message - @type content_id: str or None - @ivar content_id: the MIME Content-ID if specified in the message. - @type description: str or None - @ivar description: the MIME Content-Description if specified in the message. - @type disposition: str or None - @ivar disposition: C{None}, C{'inline'} or C{'attachment'} depending - the MIME Content-Disposition value - @type filename: unicode or None - @ivar filename: the name of the file, if specified in the message. - @type part: inherit from email.mime.base.MIMEBase - @ivar part: the related part inside the message. - @type is_body: str or None - @ivar is_body: None if this part is not the mail content itself (an - attachment or embedded content), C{'text/plain'} if this part is the - text content or C{'text/html'} if this part is the HTML version. - @type sanitized_filename: str or None - @ivar sanitized_filename: This field is filled by L{PyzMessage} to store - a valid unique filename related or not with the original filename. - @type type: str - @ivar type: the MIME type, like 'text/plain', 'image/png', 'application/msword' ... - """ - - def __init__(self, part, filename=None, type=None, charset=None, content_id=None, description=None, disposition=None, sanitized_filename=None, is_body=None): - """ - Create an mail part and initialize all attributes - """ - self.part=part # original python part - self.filename=filename # filename in unicode (if any) - self.type=type # the mime-type - self.charset=charset # the charset (if any) - self.description=description # if any - self.disposition=disposition # 'inline', 'attachment' or None - self.sanitized_filename=sanitized_filename # cleanup your filename here (TODO) - self.is_body=is_body # usually in (None, 'text/plain' or 'text/html') - self.content_id=content_id # if any - if self.content_id: - # strip '<>' to ease search and replace in "root" content (TODO) - if self.content_id.startswith('<') and self.content_id.endswith('>'): - self.content_id=self.content_id[1:-1] - - def get_payload(self): - """ - decode and return part payload. if I{type} is 'text/*' and I{charset} - not C{None}, be careful to take care of the text encoding. Use - something like C{part.get_payload().decode(part.charset)} - """ - - payload=None - if self.type.startswith('message/'): - # I don't use msg.as_string() because I want to use mangle_from_=False - if sys.version_info<(3, 0): - # python 2.x - from email.generator import Generator - fp = io.StringIO() - g = Generator(fp, mangle_from_=False) - g.flatten(self.part, unixfrom=False) - payload=fp.getvalue() - else: - # support only for python >= 3.2 - from email.generator import BytesGenerator - import io - fp = io.BytesIO() - g = BytesGenerator(fp, mangle_from_=False) - g.flatten(self.part, unixfrom=False) - payload=fp.getvalue() - - else: - payload=self.part.get_payload(decode=True) - return payload - - def __repr__(self): - st='MailPart<' - if self.is_body: - st+='*' - st+=self.type - if self.charset: - st+=' charset='+self.charset - if self.filename: - st+=' filename='+self.filename - if self.content_id: - st+=' content_id='+self.content_id - st+=' len=%d' % (len(self.get_payload()), ) - st+='>' - return st - - - -_line_end_re=re.compile('\r\n|\n\r|\n|\r') - -def _friendly_header(header): - """ - Convert header returned by C{email.message.Message.get()} into a - user friendly string. - - Py3k C{email.message.Message.get()} return C{header.Header()} with charset - set to C{charset.UNKNOWN8BIT} when the header contains invalid characters, - else it return I{str} as Python 2.X does - - @type header: str or email.header.Header - @param header: the header to convert into a user friendly string - - @rtype: str - @returns: the converter header - """ - - save=header - if isinstance(header, email.header.Header): - header=str(header) - - return re.sub(_line_end_re, ' ', header) - -def decode_mail_header(value, default_charset='us-ascii'): - """ - Decode a header value into a unicode string. - Works like a more smarter python - C{u"".join(email.header.decode_header()} function - - @type value: str - @param value: the value of the header. - @type default_charset: str - @keyword default_charset: if one charset used in the header (multiple charset - can be mixed) is unknown, then use this charset instead. - - >>> decode_mail_header('=?iso-8859-1?q?Courrier_=E8lectronique_en_Fran=E7ais?=') - u'Courrier \\xe8lectronique en Fran\\xe7ais' - """ - -# value=_friendly_header(value) - try: - headers=email.header.decode_header(value) - except email.errors.HeaderParseError: - # this can append in email.base64mime.decode(), for example for this value: - # '=?UTF-8?B?15HXmdeh15jXqNeVINeY15DXpteUINeTJ9eV16jXlSDXkdeg15XXldeUINem15PXpywg15TXptei16bXldei15nXnSDXqdecINek15zXmdeZ?==?UTF-8?B?157XldeR15nXnCwg157Xldek16Ig157Xl9eV15wg15HXodeV15bXnyDXk9ec15DXnCDXldeh15gg157Xl9eR16rXldeqINep15wg15HXmdeQ?==?UTF-8?B?15zXmNeZ?=' - # then return a sanitized ascii string - # TODO: some improvements are possible here, but a failure here is - # unlikely - return value.encode('us-ascii', 'replace').decode('us-ascii') - else: - for i, (text, charset) in enumerate(headers): - # python 3.x - # email.header.decode_header('a') -> [('a', None)] - # email.header.decode_header('a =?ISO-8859-1?Q?foo?= b') - # --> [(b'a', None), (b'foo', 'iso-8859-1'), (b'b', None)] - # in Py3 text is sometime str and sometime byte :-( - # python 2.x - # email.header.decode_header('a') -> [('a', None)] - # email.header.decode_header('a =?ISO-8859-1?Q?foo?= b') - # --> [('a', None), ('foo', 'iso-8859-1'), ('b', None)] - if (charset is None and sys.version_info>=(3, 0)): - # Py3 - if isinstance(text, str): - # convert Py3 string into bytes string to be sure their is no - # non us-ascii chars and because next line expect byte string - text=text.encode('us-ascii', 'replace') - try: - headers[i]=text.decode(charset or 'us-ascii', 'replace') - except LookupError: - # if the charset is unknown, force default - headers[i]=text.decode(default_charset, 'replace') - - return "".join(headers) - -def get_mail_addresses(message, header_name): - """ - retrieve all email addresses from one message header - - @type message: email.message.Message - @param message: the email message - @type header_name: str - @param header_name: the name of the header, can be 'from', 'to', 'cc' or - any other header containing one or more email addresses - @rtype: list - @returns: a list of the addresses in the form of tuples - C{[(u'Name', 'addresse@domain.com'), ...]} - - >>> import email - >>> import email.mime.text - >>> msg=email.mime.text.MIMEText('The text.', 'plain', 'us-ascii') - >>> msg['From']=email.email.utils.formataddr(('Me', 'me@foo.com')) - >>> msg['To']=email.email.utils.formataddr(('A', 'a@foo.com'))+', '+email.email.utils.formataddr(('B', 'b@foo.com')) - >>> print msg.as_string(unixfrom=False) - Content-Type: text/plain; charset="us-ascii" - MIME-Version: 1.0 - Content-Transfer-Encoding: 7bit - From: Me - To: A , B - - The text. - >>> get_mail_addresses(msg, 'from') - [(u'Me', 'me@foo.com')] - >>> get_mail_addresses(msg, 'to') - [(u'A', 'a@foo.com'), (u'B', 'b@foo.com')] - """ - addrs=email.utils.getaddresses([ _friendly_header(h) for h in message.get_all(header_name, [])]) - for i, (addr_name, addr) in enumerate(addrs): - if not addr_name and addr: - # only one string! Is it the address or the address name ? - # use the same for both and see later - addr_name=addr - - if is_usascii(addr): - # address must be ascii only and must match address regex - if not email_address_re.match(addr): - addr='' - else: - addr='' - addrs[i]=(decode_mail_header(addr_name), addr) - return addrs - -def get_filename(part): - """ - Find the filename of a mail part. Many MUA send attachments with the - filename in the I{name} parameter of the I{Content-type} header instead - of in the I{filename} parameter of the I{Content-Disposition} header. - - @type part: inherit from email.mime.base.MIMEBase - @param part: the mail part - @rtype: None or unicode - @returns: the filename or None if not found - - >>> import email.mime.image - >>> attach=email.mime.image.MIMEImage('data', 'png') - >>> attach.add_header('Content-Disposition', 'attachment', filename='image.png') - >>> get_filename(attach) - u'image.png' - >>> print attach.as_string(unixfrom=False) - Content-Type: image/png - MIME-Version: 1.0 - Content-Transfer-Encoding: base64 - Content-Disposition: attachment; filename="image.png" - - ZGF0YQ== - >>> import email.mime.text - >>> attach=email.mime.text.MIMEText('The text.', 'plain', 'us-ascii') - >>> attach.add_header('Content-Disposition', 'attachment', filename=('iso-8859-1', 'fr', u'Fran\\xe7ais.txt'.encode('iso-8859-1'))) - >>> get_filename(attach) - u'Fran\\xe7ais.txt' - >>> print attach.as_string(unixfrom=False) - Content-Type: text/plain; charset="us-ascii" - MIME-Version: 1.0 - Content-Transfer-Encoding: 7bit - Content-Disposition: attachment; filename*="iso-8859-1'fr'Fran%E7ais.txt" - - The text. - """ - filename=part.get_param('filename', None, 'content-disposition') - if not filename: - filename=part.get_param('name', None) # default is 'content-type' - - if filename: - if isinstance(filename, tuple): - # RFC 2231 must be used to encode parameters inside MIME header - filename=email.utils.collapse_rfc2231_value(filename).strip() - else: - # But a lot of MUA erroneously use RFC 2047 instead of RFC 2231 - # in fact anybody missuse RFC2047 here !!! - filename=decode_mail_header(filename) - - return filename - -def _search_message_content(contents, part): - """ - recursive search of message content (text or HTML) inside - the structure of the email. Used by L{search_message_content()} - - @type contents: dict - @param contents: contents already found in parents or brothers I{parts}. - The dictionary will be completed as and when. key is the MIME type of the part. - @type part: inherit email.mime.base.MIMEBase - @param part: the part of the mail to look inside recursively. - """ - type=part.get_content_type() - if part.is_multipart(): # type.startswith('multipart/'): - # explore only True 'multipart/*' - # because 'messages/rfc822' are 'multipart/*' too but - # must not be explored here - if type=='multipart/related': - # the first part or the one pointed by start - start=part.get_param('start', None) - related_type=part.get_param('type', None) - for i, subpart in enumerate(part.get_payload()): - if (not start and i==0) or (start and start==subpart.get('Content-Id')): - _search_message_content(contents, subpart) - return - elif type=='multipart/alternative': - # all parts are candidates and latest is the best - for subpart in part.get_payload(): - _search_message_content(contents, subpart) - elif type in ('multipart/report', 'multipart/signed'): - # only the first part is candidate - try: - subpart=part.get_payload()[0] - except IndexError: - return - else: - _search_message_content(contents, subpart) - return - - elif type=='multipart/encrypted': - # the second part is the good one, but we need to de-crypt it - # using the first part. Do nothing - return - - else: - # unknown types must be handled as 'multipart/mixed' - # This is the peace of code that could probably be improved, - # I use a heuristic : if not already found, use first valid non - # 'attachment' parts found - for subpart in part.get_payload(): - tmp_contents=dict() - _search_message_content(tmp_contents, subpart) - for k, v in tmp_contents.items(): - if not subpart.get_param('attachment', None, 'content-disposition')=='': - # if not an attachment, initiate value if not already found - contents.setdefault(k, v) - return - else: - contents[part.get_content_type().lower()]=part - return - - return - -def search_message_content(mail): - """ - search of message content (text or HTML) inside - the structure of the mail. This function is used by L{get_mail_parts()} - to set the C{is_body} part of the L{MailPart}s - - @type mail: inherit from email.message.Message - @param mail: the message to search in. - @rtype: dict - @returns: a dictionary of the form C{{'text/plain': text_part, 'text/html': html_part}} - where text_part and html_part inherite from C{email.mime.text.MIMEText} - and are respectively the I{text} and I{HTML} version of the message content. - One part can be missing. The dictionay can aven be empty if none of the - parts math the requirements to be considered as the content. - """ - contents=dict() - _search_message_content(contents, mail) - return contents - -def get_mail_parts(msg): - """ - return a list of all parts of the message as a list of L{MailPart}. - Retrieve parts attributes to fill in L{MailPart} object. - - @type msg: inherit email.message.Message - @param msg: the message - @rtype: list - @returns: list of mail parts - - >>> import email.mime.multipart - >>> msg=email.mime.multipart.MIMEMultipart(boundary='===limit1==') - >>> import email.mime.text - >>> txt=email.mime.text.MIMEText('The text.', 'plain', 'us-ascii') - >>> msg.attach(txt) - >>> import email.mime.image - >>> image=email.mime.image.MIMEImage('data', 'png') - >>> image.add_header('Content-Disposition', 'attachment', filename='image.png') - >>> msg.attach(image) - >>> print msg.as_string(unixfrom=False) - Content-Type: multipart/mixed; boundary="===limit1==" - MIME-Version: 1.0 - - --===limit1== - Content-Type: text/plain; charset="us-ascii" - MIME-Version: 1.0 - Content-Transfer-Encoding: 7bit - - The text. - --===limit1== - Content-Type: image/png - MIME-Version: 1.0 - Content-Transfer-Encoding: base64 - Content-Disposition: attachment; filename="image.png" - - ZGF0YQ== - --===limit1==-- - >>> parts=get_mail_parts(msg) - >>> parts - [MailPart<*text/plain charset=us-ascii len=9>, MailPart] - >>> # the star "*" means this is the mail content, not an attachment - >>> parts[0].get_payload().decode(parts[0].charset) - u'The text.' - >>> parts[1].filename, len(parts[1].get_payload()) - (u'image.png', 4) - - """ - mailparts=[] - - # retrieve messages of the email - contents=search_message_content(msg) - # reverse contents dict - parts=dict((v,k) for k, v in contents.items()) - - # organize the stack to handle deep first search - stack=[ msg, ] - while stack: - part=stack.pop(0) - type=part.get_content_type() - if type.startswith('message/'): - # ('message/delivery-status', 'message/rfc822', 'message/disposition-notification'): - # I don't want to explore the tree deeper her and just save source using msg.as_string() - # but I don't use msg.as_string() because I want to use mangle_from_=False - filename='message.eml' - mailparts.append(MailPart(part, filename=filename, type=type, charset=part.get_param('charset'), description=part.get('Content-Description'))) - elif part.is_multipart(): - # insert new parts at the beginning of the stack (deep first search) - stack[:0]=part.get_payload() - else: - charset=part.get_param('charset') - filename=get_filename(part) - - disposition=None - if part.get_param('inline', None, 'content-disposition')=='': - disposition='inline' - elif part.get_param('attachment', None, 'content-disposition')=='': - disposition='attachment' - - mailparts.append(MailPart(part, filename=filename, type=type, charset=charset, content_id=part.get('Content-Id'), description=part.get('Content-Description'), disposition=disposition, is_body=parts.get(part, False))) - - return mailparts - - -def decode_text(payload, charset, default_charset): - """ - Try to decode text content by trying multiple charset until success. - First try I{charset}, else try I{default_charset} finally - try popular charsets in order : ascii, utf-8, utf-16, windows-1252, cp850 - If all fail then use I{default_charset} and replace wrong characters - - @type payload: str - @param payload: the content to decode - @type charset: str or None - @param charset: the first charset to try if != C{None} - @type default_charset: str or None - @param default_charset: the second charset to try if != C{None} - - @rtype: tuple - @returns: a tuple of the form C{(payload, charset)} - - I{payload}: this is the decoded payload if charset is not None and - payload is a unicode string - - I{charset}: the charset that was used to decode I{payload} If charset is - C{None} then something goes wrong: if I{payload} is unicode then - invalid characters have been replaced and the used charset is I{default_charset} - else, if I{payload} is still byte string then nothing has been done. - - - """ - for chset in [ charset, default_charset, 'ascii', 'utf-8', 'utf-16', 'windows-1252', 'cp850' ]: - if chset: - try: - return payload.decode(chset), chset - except UnicodeError: - pass - - if default_charset: - return payload.decode(chset, 'replace'), None - - return payload, None - -class PyzMessage(email.message.Message): - """ - Inherit from email.message.Message. Combine L{get_mail_parts()}, - L{get_mail_addresses()} and L{decode_mail_header()} into a - B{convenient} object to access mail contents and attributes. - This class also B{sanitize} part filenames. - - @type mailparts: list of L{MailPart} - @ivar mailparts: list of L{MailPart} objects composing the email, I{text_part} - and I{html_part} are part of this list as are other attachements and embedded - contents. - @type text_part: L{MailPart} or None - @ivar text_part: the L{MailPart} object that contains the I{text} - version of the message, None if the mail has not I{text} content. - @type html_part: L{MailPart} or None - @ivar html_part: the L{MailPart} object that contains the I{HTML} - version of the message, None if the mail has not I{HTML} content. - - @note: Sample: - - >>> raw='''Content-Type: text/plain; charset="us-ascii" - ... MIME-Version: 1.0 - ... Content-Transfer-Encoding: 7bit - ... Subject: The subject - ... From: Me - ... To: A , B - ... - ... The text. - ... ''' - >>> msg=PyzMessage.factory(raw) - >>> print 'Subject: %r' % (msg.get_subject(), ) - Subject: u'The subject' - >>> print 'From: %r' % (msg.get_address('from'), ) - From: (u'Me', 'me@foo.com') - >>> print 'To: %r' % (msg.get_addresses('to'), ) - To: [(u'A', 'a@foo.com'), (u'B', 'b@foo.com')] - >>> print 'Cc: %r' % (msg.get_addresses('cc'), ) - Cc: [] - >>> for mailpart in msg.mailparts: - ... print ' %sfilename=%r sanitized_filename=%r type=%s charset=%s desc=%s size=%d' % ('*'if mailpart.is_body else ' ', mailpart.filename, mailpart.sanitized_filename, mailpart.type, mailpart.charset, mailpart.part.get('Content-Description'), 0 if mailpart.get_payload()==None else len(mailpart.get_payload())) - ... if mailpart.is_body=='text/plain': - ... payload, used_charset=decode_text(mailpart.get_payload(), mailpart.charset, None) - ... print ' >', payload.split('\\n')[0] - ... - *filename=None sanitized_filename='text.txt' type=text/plain charset=us-ascii desc=None size=10 - > The text. - """ - - @staticmethod - def smart_parser(input): - """ - Use the appropriate parser and return a email.message.Message object - (this is not a L{PyzMessage} object) - - @type input: string, file, bytes, binary_file or email.message.Message - @param input: the source of the message - @rtype: email.message.Message - @returns: the message - """ - if isinstance(input, email.message.Message): - return input - - if sys.version_info<(3, 0): - # python 2.x - if isinstance(input, str): - return email.message_from_string(input) - elif hasattr(input, 'read') and hasattr(input, 'readline'): - return email.message_from_file(input) - else: - raise ValueError('input must be a string, a file or a Message') - else: - # python 3.x - if isinstance(input, str): - return email.message_from_string(input) - elif isinstance(input, bytes): - # python >= 3.2 only - return email.message_from_bytes(input) - elif hasattr(input, 'read') and hasattr(input, 'readline'): - if hasattr(input, 'encoding'): - # python >= 3.2 only - return email.message_from_file(input) - else: - return email.message_from_binary_file(input) - else: - raise ValueError('input must be a string a bytes, a file or a Message') - - @staticmethod - def factory(input): - """ - Use the appropriate parser and return a L{PyzMessage} object - see L{smart_parser} - @type input: string, file, bytes, binary_file or email.message.Message - @param input: the source of the message - @rtype: L{PyzMessage} - @returns: the L{PyzMessage} message - """ - return PyzMessage(PyzMessage.smart_parser(input)) - - - def __init__(self, message): - """ - Initialize the object with data coming from I{message}. - - @type message: inherit email.message.Message - @param message: The message - """ - if not isinstance(message, email.message.Message): - raise ValueError("message must inherit from email.message.Message use PyzMessage.factory() instead") - self.__dict__.update(message.__dict__) - - self.mailparts=get_mail_parts(self) - self.text_part=None - self.html_part=None - - filenames=[] - for part in self.mailparts: - ext=mimetypes.guess_extension(part.type) - if not ext: - # default to .bin - ext='.bin' - elif ext=='.ksh': - # guess_extension() is not very accurate, .txt is more - # appropriate than .ksh - ext='.txt' - - sanitized_filename=sanitize_filename(part.filename, part.type.split('/', 1)[0], ext) - sanitized_filename=handle_filename_collision(sanitized_filename, filenames) - filenames.append(sanitized_filename.lower()) - part.sanitized_filename=sanitized_filename - - if part.is_body=='text/plain': - self.text_part=part - - if part.is_body=='text/html': - self.html_part=part - - def get_addresses(self, name): - """ - return the I{name} header value as an list of addresses tuple as - returned by L{get_mail_addresses()} - - @type name: str - @param name: the name of the header to read value from: 'to', 'cc' are - valid I{name} here. - @rtype: tuple - @returns: a tuple of the form C{('Sender Name', 'sender.address@domain.com')} - or C{('', '')} if no header match that I{name}. - """ - return get_mail_addresses(self, name) - - def get_address(self, name): - """ - return the I{name} header value as an address tuple as returned by - L{get_mail_addresses()} - - @type name: str - @param name: the name of the header to read value from: : C{'from'} can - be used to return the sender address. - @rtype: list of tuple - @returns: a list of tuple of the form C{[('Recipient Name', 'recipient.address@domain.com'), ...]} - or an empty list if no header match that I{name}. - """ - value=get_mail_addresses(self, name) - if value: - return value[0] - else: - return ('', '') - - def get_subject(self, default=''): - """ - return the RFC2047 decoded subject. - - @type default: any - @param default: The value to return if the message has no I{Subject} - @rtype: unicode - @returns: the subject or C{default} - """ - return self.get_decoded_header('subject', default) - - def get_decoded_header(self, name, default=''): - """ - return decoded header I{name} using RFC2047. Always use this function - to access header, because any header can contain invalid characters - and this function sanitize the string and avoid unicode exception later - in your program. - EVEN for date, I already saw a "Center box bar horizontal" instead - of a minus character. - - @type name: str - @param name: the name of the header to read value from. - @type default: any - @param default: The value to return if the I{name} field don't exist - in this message. - @rtype: unicode - @returns: the value of the header having that I{name} or C{default} if no - header have that name. - """ - value=self.get(name) - if value==None: - value=default - else: - value=decode_mail_header(value) - return value - -class PzMessage(PyzMessage): - """ - Old name and interface for PyzMessage. - B{Deprecated} - """ - - def __init__(self, input): - """ - Initialize the object with data coming from I{input}. - - @type input: str or file or email.message.Message - @param input: used as the raw content for the email, can be a string, - a file object or an email.message.Message object. - """ - PyzMessage.__init__(self, self.smart_parser(input)) - - -def message_from_string(s, *args, **kws): - """ - Parse a string into a L{PyzMessage} object model. - @type s: str - @param s: the input string - @rtype: L{PyzMessage} - @return: the L{PyzMessage} object - """ - return PyzMessage(email.message_from_string(s, *args, **kws)) - -def message_from_file(fp, *args, **kws): - """ - Read a file and parse its contents into a L{PyzMessage} object model. - @type fp: text_file - @param fp: the input file (must be open in text mode if Python >= 3.0) - @rtype: L{PyzMessage} - @return: the L{PyzMessage} object - """ - return PyzMessage(email.message_from_file(fp, *args, **kws)) - -def message_from_bytes(s, *args, **kws): - """ - Parse a bytes string into a L{PyzMessage} object model. - B{(Python >= 3.2)} - @type s: bytes - @param s: the input bytes string - @rtype: L{PyzMessage} - @return: the L{PyzMessage} object - """ - return PyzMessage(email.message_from_bytes(s, *args, **kws)) - -def message_from_binary_file(fp, *args, **kws): - """ - Read a binary file and parse its contents into a L{PyzMessage} object model. - B{(Python >= 3.2)} - @type fp: binary_file - @param fp: the input file, must be open in binary mode - @rtype: L{PyzMessage} - @return: the L{PyzMessage} object - """ - return PyzMessage(email.message_from_binary_file(fp, *args, **kws)) - - -if __name__ == "__main__": - import sys - - if len(sys.argv)<=1: - print('usage : %s filename' % sys.argv[0]) - print('read an email from file and display a resume of its content') - sys.exit(1) - - msg=PyzMessage.factory(open(sys.argv[1], 'rb')) - - print('Subject: %r' % (msg.get_subject(), )) - print('From: %r' % (msg.get_address('from'), )) - print('To: %r' % (msg.get_addresses('to'), )) - print('Cc: %r' % (msg.get_addresses('cc'), )) - print('Date: %r' % (msg.get_decoded_header('date', ''), )) - print('Message-Id: %r' % (msg.get_decoded_header('message-id', ''), )) - - for mailpart in msg.mailparts: - # dont forget to be careful to sanitize 'filename' and be carefull - # for filename collision, to before to save : - print(' %sfilename=%r type=%s charset=%s desc=%s size=%d' % ('*'if mailpart.is_body else ' ', mailpart.filename, mailpart.type, mailpart.charset, mailpart.part.get('Content-Description'), 0 if mailpart.get_payload()==None else len(mailpart.get_payload()))) - - if mailpart.is_body=='text/plain': - # print first 3 lines - payload, used_charset=decode_text(mailpart.get_payload(), mailpart.charset, None) - for line in payload.split('\n')[:3]: - # be careful console can be unable to display unicode characters - if line: - print(' >', line) - - - diff --git a/pyzmail/tests/__init__.py b/pyzmail/tests/__init__.py deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/pyzmail/tests/test_both.py b/pyzmail/tests/test_both.py deleted file mode 100644 index 2607ed8d7fd..00000000000 --- a/pyzmail/tests/test_both.py +++ /dev/null @@ -1,99 +0,0 @@ -import unittest -import pyzmail -from pyzmail.generate import * -from pyzmail.parse import * - -class TestBoth(unittest.TestCase): - - def setUp(self): - pass - - def test_compose_and_parse(self): - """test generate and parse""" - - sender=('Me', 'me@foo.com') - recipients=[('Him', 'him@bar.com'), 'just@me.com'] - subject='Le sujet en Fran\xe7ais' - text_content='Bonjour aux Fran\xe7ais' - prefered_encoding='iso-8859-1' - text_encoding='iso-8859-1' - attachments=[('attached content', 'text', 'plain', 'textfile1.txt', 'us-ascii'), - ('Fran\xe7ais', 'text', 'plain', 'textfile2.txt', 'iso-8859-1'), - ('Fran\xe7ais', 'text', 'plain', 'textfile3.txt', 'iso-8859-1'), - (b'image', 'image', 'jpg', 'imagefile.jpg', None), - ] - embeddeds=[('embedded content', 'text', 'plain', 'embedded', 'us-ascii'), - (b'picture', 'image', 'png', 'picture', None), - ] - headers=[ ('X-extra', 'extra value'), ('X-extra2', "Seconde ent\xe8te"), ('X-extra3', 'last extra'),] - - message_id_string='pyzmail' - date=1313558269 - - payload, mail_from, rcpt_to, msg_id=pyzmail.compose_mail(\ - sender, \ - recipients, \ - subject, \ - prefered_encoding, \ - (text_content, text_encoding), \ - html=None, \ - attachments=attachments, \ - embeddeds=embeddeds, \ - headers=headers, \ - message_id_string=message_id_string, \ - date=date\ - ) - - msg=PyzMessage.factory(payload) - - self.assertEqual(sender, msg.get_address('from')) - self.assertEqual(recipients[0], msg.get_addresses('to')[0]) - self.assertEqual(recipients[1], msg.get_addresses('to')[1][1]) - self.assertEqual(subject, msg.get_subject()) - self.assertEqual(subject, msg.get_decoded_header('subject')) - - # try to handle different timezone carefully - mail_date=list(email.utils.parsedate(msg.get_decoded_header('date'))) - self.assertEqual(mail_date[:6], list(time.localtime(date))[:6]) - - self.assertNotEqual(msg.get('message-id').find(message_id_string), -1) - for name, value in headers: - self.assertEqual(value, msg.get_decoded_header(name)) - - for mailpart in msg.mailparts: - if mailpart.is_body: - self.assertEqual(mailpart.content_id, None) - self.assertEqual(mailpart.filename, None) - self.assertEqual(type(mailpart.sanitized_filename), str) - if mailpart.type=='text/plain': - self.assertEqual(mailpart.get_payload(), text_content.encode(text_encoding)) - else: - self.fail('found unknown body part') - else: - if mailpart.filename: - lst=attachments - self.assertEqual(mailpart.filename, mailpart.sanitized_filename) - self.assertEqual(mailpart.content_id, None) - elif mailpart.content_id: - lst=embeddeds - self.assertEqual(mailpart.filename, None) - else: - self.fail('found unknown part') - - found=False - for attach in lst: - found=(mailpart.filename and attach[3]==mailpart.filename) \ - or (mailpart.content_id and attach[3]==mailpart.content_id) - if found: - break - - if found: - self.assertEqual(mailpart.type, attach[1]+'/'+attach[2]) - payload=mailpart.get_payload() - if attach[1]=='text' and attach[4] and isinstance(attach[0], str): - payload=payload.decode(attach[4]) - self.assertEqual(payload, attach[0]) - else: - self.fail('found unknown attachment') - - diff --git a/pyzmail/tests/test_generate.py b/pyzmail/tests/test_generate.py deleted file mode 100644 index 7afdebc5931..00000000000 --- a/pyzmail/tests/test_generate.py +++ /dev/null @@ -1,30 +0,0 @@ -import unittest, doctest -import pyzmail -from pyzmail.generate import * - -class TestGenerate(unittest.TestCase): - - def setUp(self): - pass - - def test_format_addresses(self): - """test format_addresse""" - self.assertEqual('foo@example.com', str(format_addresses([ 'foo@example.com', ]))) - self.assertEqual('Foo ', str(format_addresses([ ('Foo', 'foo@example.com'), ]))) - # notice the space around the comma - self.assertEqual('foo@example.com , bar@example.com', str(format_addresses([ 'foo@example.com', 'bar@example.com']))) - # notice the space around the comma - self.assertEqual('Foo , Bar ', str(format_addresses([ ('Foo', 'foo@example.com'), ( 'Bar', 'bar@example.com')]))) - -# Add doctest -def load_tests(loader, tests, ignore): - # this works with python 2.7 and 3.x - tests.addTests(doctest.DocTestSuite(pyzmail.generate)) - return tests - -def additional_tests(): - # Add doctest for python 2.6 and below - if sys.version_info<(2, 7): - return doctest.DocTestSuite(pyzmail.generate) - else: - return unittest.TestSuite() diff --git a/pyzmail/tests/test_parse.py b/pyzmail/tests/test_parse.py deleted file mode 100644 index f7a5adb9e2d..00000000000 --- a/pyzmail/tests/test_parse.py +++ /dev/null @@ -1,290 +0,0 @@ -import unittest, doctest -import pyzmail -from pyzmail.parse import * - - -class Msg: - """mimic a email.Message""" - def __init__(self, value): - self.value=value - - def get_all(self, header_name, default): - if self.value: - return [self.value, ] - else: - return [] - -class TestParse(unittest.TestCase): - - def setUp(self): - pass - - def test_decode_mail_header(self): - """test decode_mail_header()""" - self.assertEqual(decode_mail_header(''), '') - self.assertEqual(decode_mail_header('hello'), 'hello') - self.assertEqual(decode_mail_header('hello '), 'hello ') - self.assertEqual(decode_mail_header('=?iso-8859-1?q?Courrier_=E8lectronique_Fran=E7ais?='), 'Courrier \xe8lectronique Fran\xe7ais') - self.assertEqual(decode_mail_header('=?utf8?q?Courrier_=C3=A8lectronique_Fran=C3=A7ais?='), 'Courrier \xe8lectronique Fran\xe7ais') - self.assertEqual(decode_mail_header('=?utf-8?b?RnJhbsOnYWlz?='), 'Fran\xe7ais') - self.assertEqual(decode_mail_header('=?iso-8859-1?q?Courrier_=E8lectronique_?= =?utf8?q?Fran=C3=A7ais?='), 'Courrier \xe8lectronique Fran\xe7ais') - self.assertEqual(decode_mail_header('=?iso-8859-1?q?Courrier_=E8lectronique_?= =?utf-8?b?RnJhbsOnYWlz?='), 'Courrier \xe8lectronique Fran\xe7ais') - self.assertEqual(decode_mail_header('h_subject_q_iso_8858_1 : =?ISO-8859-1?Q?Fran=E7ais=E20accentu=E9?= !'), 'h_subject_q_iso_8858_1 :Fran\xe7ais\xe20accentu\xe9!') - - def test_get_mail_addresses(self): - """test get_mail_addresses()""" - self.assertEqual([ ('foo@example.com', 'foo@example.com') ], get_mail_addresses(Msg('foo@example.com'), 'to')) - self.assertEqual([ ('Foo', 'foo@example.com'), ], get_mail_addresses(Msg('Foo '), 'to')) - # notice the space around the comma - self.assertEqual([ ('foo@example.com', 'foo@example.com'), ('bar@example.com', 'bar@example.com')], get_mail_addresses(Msg('foo@example.com , bar@example.com'), 'to')) - self.assertEqual([ ('Foo', 'foo@example.com'), ( 'Bar', 'bar@example.com')], get_mail_addresses(Msg('Foo , Bar '), 'to')) - self.assertEqual([ ('Foo', 'foo@example.com'), ('bar@example.com', 'bar@example.com')], get_mail_addresses(Msg('Foo , bar@example.com'), 'to')) - self.assertEqual([ ('Mr Foo', 'foo@example.com'), ('bar@example.com', 'bar@example.com')], get_mail_addresses(Msg('Mr\nFoo , bar@example.com'), 'to')) - - self.assertEqual([ ('Beno\xeet', 'benoit@example.com')], get_mail_addresses(Msg('=?utf-8?q?Beno=C3=AEt?= '), 'to')) - - # address already encoded into utf8 (bad) - address='Ant\xf3nio Foo '.encode('utf8') - if sys.version_info<(3, 0): - self.assertEqual([('Ant\ufffd\ufffdnio Foo', 'a.foo@example.com')], get_mail_addresses(Msg(address), 'to')) - else: - # Python 3.2 return header when surrogate characters are used in header - self.assertEqual([('Ant??nio Foo', 'a.foo@example.com'), ], get_mail_addresses(Msg(email.header.Header(address, charset=email.charset.UNKNOWN8BIT, header_name='to')), 'to')) - - def test_get_filename(self): - """test get_filename()""" - import email.mime.image - - filename='Fran\xe7ais.png' - if sys.version_info<(3, 0): - encoded_filename=filename.encode('iso-8859-1') - else: - encoded_filename=filename - - payload=b'data' - attach=email.mime.image.MIMEImage(payload, 'png') - attach.add_header('Content-Disposition', 'attachment', filename='image.png') - self.assertEqual('image.png', get_filename(attach)) - - attach=email.mime.image.MIMEImage(payload, 'png') - attach.add_header('Content-Disposition', 'attachment', filename=('iso-8859-1', 'fr', encoded_filename)) - self.assertEqual('Fran\xe7ais.png', get_filename(attach)) - - attach=email.mime.image.MIMEImage(payload, 'png') - attach.set_param('name', 'image.png') - self.assertEqual('image.png', get_filename(attach)) - - attach=email.mime.image.MIMEImage(payload, 'png') - attach.set_param('name', ('iso-8859-1', 'fr', encoded_filename)) - self.assertEqual('Fran\xe7ais.png', get_filename(attach)) - - attach=email.mime.image.MIMEImage(payload, 'png') - attach.add_header('Content-Disposition', 'attachment', filename='image.png') - attach.set_param('name', 'image_wrong.png') - self.assertEqual('image.png', get_filename(attach)) - - def test_get_mailparts(self): - """test get_mailparts()""" - import email.mime.multipart - import email.mime.text - import email.mime.image - msg=email.mime.multipart.MIMEMultipart(boundary='===limit1==') - txt=email.mime.text.MIMEText('The text.', 'plain', 'us-ascii') - msg.attach(txt) - image=email.mime.image.MIMEImage(b'data', 'png') - image.add_header('Content-Disposition', 'attachment', filename='image.png') - image.add_header('Content-Description', 'the description') - image.add_header('Content-ID', '') - msg.attach(image) - - raw=msg.as_string(unixfrom=False) - expected_raw="""Content-Type: multipart/mixed; boundary="===limit1==" -MIME-Version: 1.0 - ---===limit1== -Content-Type: text/plain; charset="us-ascii" -MIME-Version: 1.0 -Content-Transfer-Encoding: 7bit - -The text. ---===limit1== -Content-Type: image/png -MIME-Version: 1.0 -Content-Transfer-Encoding: base64 -Content-Disposition: attachment; filename="image.png" -Content-Description: the description -Content-ID: - -ZGF0YQ== ---===limit1==--""" - - if sys.version_info<(3, 0): - expected_raw=expected_raw.replace('','') - else: - expected_raw=expected_raw.replace('','\n') - - self.assertEqual(raw, expected_raw) - - parts=get_mail_parts(msg) - # [MailPart<*text/plain charset=us-ascii len=9>, MailPart] - - self.assertEqual(len(parts), 2) - - self.assertEqual(parts[0].type, 'text/plain') - self.assertEqual(parts[0].is_body, 'text/plain') # not a error, is_body must be type - self.assertEqual(parts[0].charset, 'us-ascii') - self.assertEqual(parts[0].get_payload().decode(parts[0].charset), 'The text.') - - self.assertEqual(parts[1].type, 'image/png') - self.assertEqual(parts[1].is_body, False) - self.assertEqual(parts[1].charset, None) - self.assertEqual(parts[1].filename, 'image.png') - self.assertEqual(parts[1].description, 'the description') - self.assertEqual(parts[1].content_id, 'this.is.the.normaly.unique.contentid') - self.assertEqual(parts[1].get_payload(), b'data') - - - raw_1='''Content-Type: text/plain; charset="us-ascii" -MIME-Version: 1.0 -Content-Transfer-Encoding: 7bit -Subject: simple test -From: Me -To: A , B -Cc: C , d@foo.com -User-Agent: pyzmail - -The text. -''' - - def check_message_1(self, msg): - self.assertEqual(msg.get_subject(), 'simple test') - self.assertEqual(msg.get_decoded_header('subject'), 'simple test') - self.assertEqual(msg.get_decoded_header('User-Agent'), 'pyzmail') - self.assertEqual(msg.get('User-Agent'), 'pyzmail') - self.assertEqual(msg.get_address('from'), ('Me', 'me@foo.com')) - self.assertEqual(msg.get_addresses('to'), [('A', 'a@foo.com'), ('B', 'b@foo.com')]) - self.assertEqual(msg.get_addresses('cc'), [('C', 'c@foo.com'), ('d@foo.com', 'd@foo.com')]) - self.assertEqual(len(msg.mailparts), 1) - self.assertEqual(msg.text_part, msg.mailparts[0]) - self.assertEqual(msg.html_part, None) - - # use 8bits encoding and 2 different charsets ! python 3.0 & 3.1 are not eable to parse this sample - raw_2=b"""From: sender@domain.com -To: recipient@domain.com -Date: Tue, 7 Jun 2011 16:32:17 +0200 -Subject: contains 8bits attachments using different encoding -Content-Type: multipart/mixed; boundary=mixed - ---mixed -Content-Type: text/plain; charset="us-ascii" -MIME-Version: 1.0 -Content-Transfer-Encoding: 7bit - -body ---mixed -Content-Type: text/plain; charset="windows-1252" -MIME-Version: 1.0 -Content-Transfer-Encoding: 8bit -Content-Disposition: attachment; filename="file1.txt" - -bo\xeete mail = mailbox ---mixed -Content-Type: text/plain; charset="utf-8" -MIME-Version: 1.0 -Content-Transfer-Encoding: 8bit -Content-Disposition: attachment; filename="file2.txt" - -bo\xc3\xaete mail = mailbox ---mixed-- -""" - - def check_message_2(self, msg): - self.assertEqual(msg.get_subject(), 'contains 8bits attachments using different encoding') - - body, file1, file2=msg.mailparts - - self.assertEqual('file1.txt', file1.filename) - self.assertEqual('file2.txt', file2.filename) - self.assertEqual('windows-1252', file1.charset) - self.assertEqual('utf-8', file2.charset) - content=b'bo\xeete mail = mailbox'.decode("windows-1252") - content1=file1.get_payload().decode(file1.charset) - content2=file2.get_payload().decode(file2.charset) - self.assertEqual(content, content1) - self.assertEqual(content, content2) - - # this one contain non us-ascii chars in the header - # py 2x and py3k return different value here - raw_3=b'Content-Type: text/plain; charset="us-ascii"\n' \ - b'MIME-Version: 1.0\n' \ - b'Content-Transfer-Encoding: 7bit\n' \ - + 'Subject: Beno\xeet & Ant\xf3nio\n'.encode('utf8') +\ - b'From: =?utf-8?q?Beno=C3=AEt?= \n' \ - + 'To: Ant\xf3nio Foo \n'.encode('utf8') \ - + 'Cc: Beno\xeet , d@foo.com\n'.encode('utf8') +\ - b'User-Agent: pyzmail\n' \ - b'\n' \ - b'The text.\n' - - def check_message_3(self, msg): - subject='Beno\ufffd\ufffdt & Ant\ufffd\ufffdnio' # if sys.version_info<(3, 0) else u'Beno??t & Ant??nio' - self.assertEqual(msg.get_subject(), subject) - self.assertEqual(msg.get_decoded_header('subject'), subject) - self.assertEqual(msg.get_decoded_header('User-Agent'), 'pyzmail') - self.assertEqual(msg.get('User-Agent'), 'pyzmail') - self.assertEqual(msg.get_address('from'), ('Beno\xeet', 'benoit@example.com')) - - to=msg.get_addresses('to') - self.assertEqual(to[0][1], 'a.foo@example.com') - self.assertEqual(to[0][0], 'Ant\ufffd\ufffdnio Foo' if sys.version_info<(3, 0) else 'Ant??nio Foo') - - cc=msg.get_addresses('cc') - self.assertEqual(cc[0][1], 'benoit@foo.com') - self.assertEqual(cc[0][0], 'Beno\ufffd\ufffdt' if sys.version_info<(3, 0) else 'Beno??t') - self.assertEqual(cc[1], ('d@foo.com', 'd@foo.com')) - - self.assertEqual(len(msg.mailparts), 1) - self.assertEqual(msg.text_part, msg.mailparts[0]) - self.assertEqual(msg.html_part, None) - - - def check_pyzmessage_factories(self, input, check): - """test PyzMessage from different sources""" - if isinstance(input, bytes) and sys.version_info>=(3, 2): - check(PyzMessage.factory(input)) - check(message_from_bytes(input)) - - import io - check(PyzMessage.factory(io.BytesIO(input))) - check(message_from_binary_file(io.BytesIO(input))) - - if isinstance(input, str): - - check(PyzMessage.factory(input)) - check(message_from_string(input)) - - import io - check(PyzMessage.factory(io.StringIO(input))) - check(message_from_file(io.StringIO(input))) - - def test_pyzmessage_factories(self): - """test PyzMessage class different sources""" - self.check_pyzmessage_factories(self.raw_1, self.check_message_1) - self.check_pyzmessage_factories(self.raw_2, self.check_message_2) - self.check_pyzmessage_factories(self.raw_3, self.check_message_3) - - -# Add doctest -def load_tests(loader, tests, ignore): - # this works with python 2.7 and 3.x - if sys.version_info<(3, 0): - tests.addTests(doctest.DocTestSuite(pyzmail.parse)) - return tests - -def additional_tests(): - # Add doctest for python 2.6 and below - if sys.version_info<(2, 7): - return doctest.DocTestSuite(pyzmail.parse) - else: - return unittest.TestSuite() - diff --git a/pyzmail/tests/test_send.py b/pyzmail/tests/test_send.py deleted file mode 100644 index 554f8549a4d..00000000000 --- a/pyzmail/tests/test_send.py +++ /dev/null @@ -1,77 +0,0 @@ -import threading, smtpd, asyncore, socket, smtplib, time -import unittest -import pyzmail -from pyzmail.generate import * - - -smtpd_addr='127.0.0.1' -smtpd_port=32525 -smtp_bad_port=smtpd_port-1 - -smtp_mode='normal' -smtp_login=None -smtp_password=None - - -class SMTPServer(smtpd.SMTPServer): - def __init__(self, localaddr, remoteaddr, received): - smtpd.SMTPServer.__init__(self, localaddr, remoteaddr) - self.set_reuse_addr() - # put the received mail into received list - self.received=received - - def process_message(self, peer, mail_from, rcpt_to, data): - ret=None - if mail_from.startswith('data_error'): - ret='552 Requested mail action aborted: exceeded storage allocation' - self.received.append((ret, peer, mail_from, rcpt_to, data)) - return ret - -class TestSend(unittest.TestCase): - - def setUp(self): - self.received=[] - self.smtp_server=SMTPServer((smtpd_addr, smtpd_port), None, self.received) - - def asyncloop(): - # check every sec if all channel are close - asyncore.loop(1) - - - self.payload, self.mail_from, self.rcpt_to, self.msg_id=compose_mail(('Me', 'me@foo.com'), [('Him', 'him@bar.com')], 'the subject', 'iso-8859-1', ('Hello world', 'us-ascii')) - - # start the server after having built the payload, to handle failure in - # the code above - self.smtpd_thread=threading.Thread(target=asyncloop) - self.smtpd_thread.daemon=True - self.smtpd_thread.start() - - - def tearDown(self): - self.smtp_server.close() - self.smtpd_thread.join() - - def test_simple_send(self): - """simple send""" - ret=send_mail(self.payload, self.mail_from, self.rcpt_to, smtpd_addr, smtpd_port, smtp_mode=smtp_mode, smtp_login=smtp_login, smtp_password=smtp_password) - self.assertEqual(ret, dict()) - (ret, peer, mail_from, rcpt_to, payload)=self.received[0] - self.assertEqual(self.payload, payload) - self.assertEqual(self.mail_from, mail_from) - self.assertEqual(self.rcpt_to, rcpt_to) - self.assertEqual('127.0.0.1', peer[0]) - - def test_send_to_a_wrong_port(self): - """send to a wrong port""" - self.smtp_server.close() - ret=send_mail(self.payload, self.mail_from, self.rcpt_to, smtpd_addr, smtpd_port, smtp_mode=smtp_mode, smtp_login=smtp_login, smtp_password=smtp_password) - self.assertEqual(type(ret), str) - - def test_send_data_error(self): - """smtp server return error code""" - ret=send_mail(self.payload, 'data_error@foo.com', self.rcpt_to, smtpd_addr, smtp_bad_port, smtp_mode=smtp_mode, smtp_login=smtp_login, smtp_password=smtp_password) - self.assertEqual(type(ret), str) - -if __name__ == '__main__': - unittest.main() - diff --git a/pyzmail/tests/test_utils.py b/pyzmail/tests/test_utils.py deleted file mode 100644 index e03d07d0d91..00000000000 --- a/pyzmail/tests/test_utils.py +++ /dev/null @@ -1,24 +0,0 @@ -import unittest, doctest -import pyzmail -from pyzmail.utils import * - -class TestUtils(unittest.TestCase): - - def setUp(self): - pass - - def test_nothing(self): - pass - -# Add doctest -def load_tests(loader, tests, ignore): - # this works with python 2.7 and 3.x - tests.addTests(doctest.DocTestSuite(pyzmail.utils)) - return tests - -def additional_tests(): - # Add doctest for python 2.6 and below - if sys.version_info<(2, 7): - return doctest.DocTestSuite(pyzmail.utils) - else: - return unittest.TestSuite() diff --git a/pyzmail/utils.py b/pyzmail/utils.py deleted file mode 100644 index 436e2a4c34f..00000000000 --- a/pyzmail/utils.py +++ /dev/null @@ -1,155 +0,0 @@ -# -# pyzmail/utils.py -# (c) Alain Spineux -# http://www.magiksys.net/pyzmail -# Released under LGPL - -""" -Various functions used by other modules -@var invalid_chars_in_filename: a mix of characters not permitted in most used filesystems -@var invalid_windows_name: a list of unauthorized filenames under Windows -""" - -import sys - -invalid_chars_in_filename=b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f' \ - b'\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f' \ - b'<>:"/\\|?*%\'' - -invalid_windows_name=[b'CON', b'PRN', b'AUX', b'NUL', b'COM1', b'COM2', b'COM3', - b'COM4', b'COM5', b'COM6', b'COM7', b'COM8', b'COM9', - b'LPT1', b'LPT2', b'LPT3', b'LPT4', b'LPT5', b'LPT6', b'LPT7', - b'LPT8', b'LPT9' ] - -def sanitize_filename(filename, alt_name, alt_ext): - """ - Convert the given filename into a name that should work on all - platform. Remove non us-ascii characters, and drop invalid filename. - Use the I{alternative} filename if needed. - - @type filename: unicode or None - @param filename: the originale filename or None. Can be unicode. - @type alt_name: str - @param alt_name: the alternative filename if filename is None or useless - @type alt_ext: str - @param alt_ext: the alternative filename extension (including the '.') - - @rtype: str - @returns: a valid filename. - - >>> sanitize_filename('document.txt', 'file', '.txt') - 'document.txt' - >>> sanitize_filename('number1.txt', 'file', '.txt') - 'number1.txt' - >>> sanitize_filename(None, 'file', '.txt') - 'file.txt' - >>> sanitize_filename(u'R\\xe9pertoir.txt', 'file', '.txt') - 'Rpertoir.txt' - >>> # the '\\xe9' has been removed - >>> sanitize_filename(u'\\xe9\\xe6.html', 'file', '.txt') - 'file.html' - >>> # all non us-ascii characters have been removed, the alternative name - >>> # has been used the replace empty string. The originale extention - >>> # is still valid - >>> sanitize_filename(u'COM1.txt', 'file', '.txt') - 'COM1A.txt' - >>> # if name match an invalid name or assimilated then a A is added - """ - - if not filename: - return alt_name+alt_ext - - if ((sys.version_info<(3, 0) and isinstance(filename, str)) or \ - (sys.version_info>=(3, 0) and isinstance(filename, str))): - filename=filename.encode('ascii', 'ignore') - - filename=filename.translate(None, invalid_chars_in_filename) - filename=filename.strip() - - upper=filename.upper() - for name in invalid_windows_name: - if upper==name: - filename=filename+b'A' - break - if upper.startswith(name+b'.'): - filename=filename[:len(name)]+b'A'+filename[len(name):] - break - - if sys.version_info>=(3, 0): - # back to string - filename=filename.decode('us-ascii') - - if filename.rfind('.')==0: - filename=alt_name+filename - - return filename - -def handle_filename_collision(filename, filenames): - """ - Avoid filename collision, add a sequence number to the name when required. - 'file.txt' will be renamed into 'file-01.txt' then 'file-02.txt' ... - until their is no more collision. The file is not added to the list. - - Windows don't make the difference between lower and upper case. To avoid - "case" collision, the function compare C{filename.lower()} to the list. - If you provide a list in lower case only, then any collisions will be avoided. - - @type filename: str - @param filename: the filename - @type filenames: list or set - @param filenames: a list of filenames. - - @rtype: str - @returns: the I{filename} or the appropriately I{indexed} I{filename} - - >>> handle_filename_collision('file.txt', [ ]) - 'file.txt' - >>> handle_filename_collision('file.txt', [ 'file.txt' ]) - 'file-01.txt' - >>> handle_filename_collision('file.txt', [ 'file.txt', 'file-01.txt',]) - 'file-02.txt' - >>> handle_filename_collision('foo', [ 'foo',]) - 'foo-01' - >>> handle_filename_collision('foo', [ 'foo', 'foo-01',]) - 'foo-02' - >>> handle_filename_collision('FOO', [ 'foo', 'foo-01',]) - 'FOO-02' - """ - if filename.lower() in filenames: - try: - basename, ext=filename.rsplit('.', 1) - ext='.'+ext - except ValueError: - basename, ext=filename, '' - - i=1 - while True: - filename='%s-%02d%s' % (basename, i, ext) - if filename.lower() not in filenames: - break - i+=1 - - return filename - -def is_usascii(value): - """" - test if string contains us-ascii characters only - - >>> is_usascii('foo') - True - >>> is_usascii(u'foo') - True - >>> is_usascii(u'Fran\xe7ais') - False - >>> is_usascii('bad\x81') - False - """ - try: - # if value is byte string, it will be decoded first using us-ascii - # and will generate UnicodeEncodeError, this is fine too - value.encode('us-ascii') - except UnicodeError: - return False - - return True - \ No newline at end of file diff --git a/pyzmail/version.py b/pyzmail/version.py deleted file mode 100644 index 03e1b0c6dcc..00000000000 --- a/pyzmail/version.py +++ /dev/null @@ -1 +0,0 @@ -__version__='1.0.3' diff --git a/requirements.txt b/requirements.txt index 4b1d22949e7..9023aa5436e 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,66 +1,95 @@ # -*- conf-mode -*- -setuptools>=51.1.0 # Require this first, to prevent later errors +setuptools>=80.9.0 # Require this first, to prevent later errors # -argon2-cffi>=21.3.0 # For the Argon2 password hasher option -beautifulsoup4>=4.11.1 # Only used in tests -bibtexparser>=1.2.0 # Only used in tests -bleach>=5.0.0 -coverage>=4.5.4,<5.0 # Coverage 5.x moves from a json database to SQLite. Moving to 5.x will require substantial rewrites in ietf.utils.test_runner and ietf.release.views -decorator>=5.1.1 +aiosmtpd>=1.4.6 +argon2-cffi>=25.1.0 # For the Argon2 password hasher option +beautifulsoup4>=4.13.4 # Only used in tests +bibtexparser>=1.4.4 # Only used in tests +bleach>=6.2.0 # project is deprecated but supported +types-bleach>=6.2.0 +boto3>=1.39.15 +boto3-stubs[s3]>=1.39.15 +botocore>=1.39.15 +celery>=5.5.3 +coverage>=7.9.2 defusedxml>=0.7.1 # for TastyPie when using xml; not a declared dependency -Django>=2.2.28,<3.0 -django-analytical>=3.1.0 -django-bootstrap5>=21.3 +Django>=4.2.30,<5 +django-admin-rangefilter>=0.13.3 +django-analytical>=3.2.0 +django-bootstrap5>=25.1 +django-celery-beat>=2.9.0 +django-celery-results>=2.6.0 django-csp>=3.7 -django-cors-headers>=3.11.0 -django-debug-toolbar>=3.2.4 -django-form-utils>=1.0.3 # Only one use, in the liaisons app. Last release was in 2015. -django-markup>=1.5 # Limited use - need to reconcile against direct use of markdown -django-oidc-provider>=0.7 -django-password-strength>=1.2.1 -django-referrer-policy>=1.0 -django-simple-history>=3.0.0 -django-stubs==1.6.0 # The django-stubs version used determines the the mypy version indicated below -django-tastypie==0.14.3 # Version must be locked in sync with version of Django -django-vite>=2.0.2 -django-webtest>=1.9.10 # Only used in tests +django-cors-headers>=4.7.0 +django-debug-toolbar>=6.0.0 +django-filter>=24.3 +django-markup>=1.10 # Limited use - need to reconcile against direct use of markdown +django-oidc-provider==0.8.2 # 0.8.3 changes logout flow and claim return +django-simple-history>=3.10.1 +django-storages>=1.14.6 +django-stubs>=4.2.7,<5 # The django-stubs version used determines the the mypy version indicated below +django-tastypie>=0.15.1 # Version must be kept in sync with Django +django-vite>=3.1.0 django-widget-tweaks>=1.4.12 -djlint>=1.0.0 # To auto-indent templates via "djlint --profile django --reformat" -docutils>=0.18.1 # Used only by dbtemplates for RestructuredText -factory-boy>=3.2.1 -github3.py>=3.2.0 -gunicorn>=20.1.0 +djangorestframework>=3.16.0 +docutils>=0.22.0 # Used only by dbtemplates for RestructuredText +types-docutils>=0.21.0 # should match docutils (0.22.0 not out yet) +drf-spectacular>=0.27 +drf-standardized-errors[openapi] >= 0.15.0 +factory-boy>=3.3.3 +gunicorn>=23.0.0 hashids>=1.3.1 -html2text>=2020.1.16 # Used only to clean comment field of secr/sreq +html2text>=2025.4.15 # Used only to clean comment field of secr/sreq html5lib>=1.1 # Only used in tests -jsonfield>=3.1.0 # for SubmissionCheck. This is https://github.com/bradjasper/django-jsonfield/. -jwcrypto>=1.2 # for signed notifications - this is aspirational, and is not really used. -logging_tree>=1.9 # Used only by the showloggers management command -lxml>=4.8.0,<5 -markdown>=3.3.6 -mock>=4.0.3 # Used only by tests, of course -mypy>=0.782,<0.790 # Version requirements determined by django-stubs. -mysqlclient>=2.1.0 -oic>=1.3 # Used only by tests -Pillow>=9.1.0 -pyang>=2.5.3 -pyflakes>=2.4.0 -pyopenssl>=22.0.0 # Used by urllib3.contrib, which is used by PyQuery but not marked as a dependency -pyquery>=1.4.3 -python-dateutil>=2.8.2 +httpx>=0.28.1 # Indirect req of typesense, but we import and refer to exceptions +icalendar>=5.0.0 +inflect>= 7.5.0 +jsonfield>=3.2.0 # deprecated - need to replace with Django's JSONField +jsonschema[format]>=4.25.0 +jwcrypto>=1.5.6 # for signed notifications - this is aspirational, and is not really used. +logging_tree>=1.10 # Used only by the showloggers management command +lxml>=6.1.0 +markdown>=3.8.0 +types-markdown>=3.8.0 +mock>=5.2.0 # should replace with unittest.mock and remove dependency +types-mock>=5.2.0 +mypy~=1.11.2 # Version requirements loosely determined by django-stubs. +oic>=1.7.0 # Used only by tests +opentelemetry-sdk>=1.38.0 +opentelemetry-instrumentation-django>=0.59b0 +opentelemetry-instrumentation-psycopg2>=0.59b0 +opentelemetry-instrumentation-pymemcache>=0.59b0 +opentelemetry-instrumentation-requests>=0.59b0 +opentelemetry-exporter-otlp-proto-http>=1.38.0 +pillow>=11.3.0 +psycopg2>=2.9.10 +pyang>=2.6.1 +pydyf>=0.12.1 +pyflakes>=3.4.0 +pyopenssl>=25.1.0 # Used by urllib3.contrib, which is used by PyQuery but not marked as a dependency +pyquery>=2.0.1 +python-dateutil>=2.9.0 +types-python-dateutil>=2.9.0 +python-json-logger>=3.3.0 python-magic==0.4.18 # Versions beyond the yanked .19 and .20 introduce form failures -python-memcached>=1.59 # for django.core.cache.backends.memcached -python-mimeparse>=1.6 # from TastyPie -pytz==2022.2.1 # Pinned as changes need to be vetted for their effect on Meeting fields -requests>=2.27.1 -requests-mock>=1.9.3 +pymemcache>=4.0.0 # for django.core.cache.backends.memcached.PyMemcacheCache +python-mimeparse>=2.0.0 # from TastyPie +pytz==2025.2 # Pinned as changes need to be vetted for their effect on Meeting fields +types-pytz==2025.2.0.20251108 # match pytz version +typesense>=2.0.0 +requests>=2.32.4 +types-requests>=2.32.4 +requests-mock>=1.12.1 rfc2html>=2.0.3 -scout-apm>=2.24.2 -selenium>=3.141.0,<4.0 -tblib>=1.7.0 # So that the django test runner provides tracebacks -tlds>=2022042700 # Used to teach bleach about which TLDs currently exist -tqdm>=4.64.0 -Unidecode>=1.3.4 -weasyprint>=52.5,<53 # Datatracker tests past on 54, but xml2rfc tests do not. -xml2rfc>=3.12.4 -xym>=0.5,<1.0 +scout-apm>=3.4.0 +selenium>=4.34.2 +tblib>=3.1.0 # So that the django test runner provides tracebacks +tlds>=2022042700 # Used to teach bleach about which TLDs currently exist +tqdm>=4.70.0 +unidecode>=1.4.0 +urllib3>=2.5.0 +weasyprint>=66.0 +xml2rfc>=3.30.0 +xym>=0.6,<0.10.0 +zxcvbn>=4.5.0 +types-zxcvbn~=4.5.0.20260518 # match zxcvbn version diff --git a/test/data/profile-default.jpg b/test/data/profile-default.jpg deleted file mode 100644 index d6b03e10041..00000000000 Binary files a/test/data/profile-default.jpg and /dev/null differ diff --git a/test/data/youtube-discovery.json b/test/data/youtube-discovery.json deleted file mode 100644 index 983e1650c20..00000000000 --- a/test/data/youtube-discovery.json +++ /dev/null @@ -1,10879 +0,0 @@ -{ - "kind": "discovery#restDescription", - "etag": "\"YWOzh2SDasdU84ArJnpYek-OMdg/f81k8b4sv9uLeywfoj2KpL2xcPg\"", - "discoveryVersion": "v1", - "id": "youtube:v3", - "name": "youtube", - "canonicalName": "YouTube", - "version": "v3", - "revision": "20170130", - "title": "YouTube Data API", - "description": "Supports core YouTube features, such as uploading videos, creating and managing playlists, searching for content, and much more.", - "ownerDomain": "google.com", - "ownerName": "Google", - "icons": { - "x16": "https://www.google.com/images/icons/product/youtube-16.png", - "x32": "https://www.google.com/images/icons/product/youtube-32.png" - }, - "documentationLink": "https://developers.google.com/youtube/v3", - "protocol": "rest", - "baseUrl": "https://www.googleapis.com/youtube/v3/", - "basePath": "/youtube/v3/", - "rootUrl": "https://www.googleapis.com/", - "servicePath": "youtube/v3/", - "batchPath": "batch", - "parameters": { - "alt": { - "type": "string", - "description": "Data format for the response.", - "default": "json", - "enum": [ - "json" - ], - "enumDescriptions": [ - "Responses with Content-Type of application/json" - ], - "location": "query" - }, - "fields": { - "type": "string", - "description": "Selector specifying which fields to include in a partial response.", - "location": "query" - }, - "key": { - "type": "string", - "description": "API key. Your API key identifies your project and provides you with API access, quota, and reports. Required unless you provide an OAuth 2.0 token.", - "location": "query" - }, - "oauth_token": { - "type": "string", - "description": "OAuth 2.0 token for the current user.", - "location": "query" - }, - "prettyPrint": { - "type": "boolean", - "description": "Returns response with indentations and line breaks.", - "default": "true", - "location": "query" - }, - "quotaUser": { - "type": "string", - "description": "Available to use for quota purposes for server-side applications. Can be any arbitrary string assigned to a user, but should not exceed 40 characters. Overrides userIp if both are provided.", - "location": "query" - }, - "userIp": { - "type": "string", - "description": "IP address of the site where the request originates. Use this if you want to enforce per-user limits.", - "location": "query" - } - }, - "auth": { - "oauth2": { - "scopes": { - "https://www.googleapis.com/auth/youtube": { - "description": "Manage your YouTube account" - }, - "https://www.googleapis.com/auth/youtube.force-ssl": { - "description": "Manage your YouTube account" - }, - "https://www.googleapis.com/auth/youtube.readonly": { - "description": "View your YouTube account" - }, - "https://www.googleapis.com/auth/youtube.upload": { - "description": "Manage your YouTube videos" - }, - "https://www.googleapis.com/auth/youtubepartner": { - "description": "View and manage your assets and associated content on YouTube" - }, - "https://www.googleapis.com/auth/youtubepartner-channel-audit": { - "description": "View private information of your YouTube channel relevant during the audit process with a YouTube partner" - } - } - } - }, - "schemas": { - "AccessPolicy": { - "id": "AccessPolicy", - "type": "object", - "description": "Rights management policy for YouTube resources.", - "properties": { - "allowed": { - "type": "boolean", - "description": "The value of allowed indicates whether the access to the policy is allowed or denied by default." - }, - "exception": { - "type": "array", - "description": "A list of region codes that identify countries where the default policy do not apply.", - "items": { - "type": "string" - } - } - } - }, - "Activity": { - "id": "Activity", - "type": "object", - "description": "An activity resource contains information about an action that a particular channel, or user, has taken on YouTube.The actions reported in activity feeds include rating a video, sharing a video, marking a video as a favorite, commenting on a video, uploading a video, and so forth. Each activity resource identifies the type of action, the channel associated with the action, and the resource(s) associated with the action, such as the video that was rated or uploaded.", - "properties": { - "contentDetails": { - "$ref": "ActivityContentDetails", - "description": "The contentDetails object contains information about the content associated with the activity. For example, if the snippet.type value is videoRated, then the contentDetails object's content identifies the rated video." - }, - "etag": { - "type": "string", - "description": "Etag of this resource." - }, - "id": { - "type": "string", - "description": "The ID that YouTube uses to uniquely identify the activity." - }, - "kind": { - "type": "string", - "description": "Identifies what kind of resource this is. Value: the fixed string \"youtube#activity\".", - "default": "youtube#activity" - }, - "snippet": { - "$ref": "ActivitySnippet", - "description": "The snippet object contains basic details about the activity, including the activity's type and group ID." - } - } - }, - "ActivityContentDetails": { - "id": "ActivityContentDetails", - "type": "object", - "description": "Details about the content of an activity: the video that was shared, the channel that was subscribed to, etc.", - "properties": { - "bulletin": { - "$ref": "ActivityContentDetailsBulletin", - "description": "The bulletin object contains details about a channel bulletin post. This object is only present if the snippet.type is bulletin." - }, - "channelItem": { - "$ref": "ActivityContentDetailsChannelItem", - "description": "The channelItem object contains details about a resource which was added to a channel. This property is only present if the snippet.type is channelItem." - }, - "comment": { - "$ref": "ActivityContentDetailsComment", - "description": "The comment object contains information about a resource that received a comment. This property is only present if the snippet.type is comment." - }, - "favorite": { - "$ref": "ActivityContentDetailsFavorite", - "description": "The favorite object contains information about a video that was marked as a favorite video. This property is only present if the snippet.type is favorite." - }, - "like": { - "$ref": "ActivityContentDetailsLike", - "description": "The like object contains information about a resource that received a positive (like) rating. This property is only present if the snippet.type is like." - }, - "playlistItem": { - "$ref": "ActivityContentDetailsPlaylistItem", - "description": "The playlistItem object contains information about a new playlist item. This property is only present if the snippet.type is playlistItem." - }, - "promotedItem": { - "$ref": "ActivityContentDetailsPromotedItem", - "description": "The promotedItem object contains details about a resource which is being promoted. This property is only present if the snippet.type is promotedItem." - }, - "recommendation": { - "$ref": "ActivityContentDetailsRecommendation", - "description": "The recommendation object contains information about a recommended resource. This property is only present if the snippet.type is recommendation." - }, - "social": { - "$ref": "ActivityContentDetailsSocial", - "description": "The social object contains details about a social network post. This property is only present if the snippet.type is social." - }, - "subscription": { - "$ref": "ActivityContentDetailsSubscription", - "description": "The subscription object contains information about a channel that a user subscribed to. This property is only present if the snippet.type is subscription." - }, - "upload": { - "$ref": "ActivityContentDetailsUpload", - "description": "The upload object contains information about the uploaded video. This property is only present if the snippet.type is upload." - } - } - }, - "ActivityContentDetailsBulletin": { - "id": "ActivityContentDetailsBulletin", - "type": "object", - "description": "Details about a channel bulletin post.", - "properties": { - "resourceId": { - "$ref": "ResourceId", - "description": "The resourceId object contains information that identifies the resource associated with a bulletin post." - } - } - }, - "ActivityContentDetailsChannelItem": { - "id": "ActivityContentDetailsChannelItem", - "type": "object", - "description": "Details about a resource which was added to a channel.", - "properties": { - "resourceId": { - "$ref": "ResourceId", - "description": "The resourceId object contains information that identifies the resource that was added to the channel." - } - } - }, - "ActivityContentDetailsComment": { - "id": "ActivityContentDetailsComment", - "type": "object", - "description": "Information about a resource that received a comment.", - "properties": { - "resourceId": { - "$ref": "ResourceId", - "description": "The resourceId object contains information that identifies the resource associated with the comment." - } - } - }, - "ActivityContentDetailsFavorite": { - "id": "ActivityContentDetailsFavorite", - "type": "object", - "description": "Information about a video that was marked as a favorite video.", - "properties": { - "resourceId": { - "$ref": "ResourceId", - "description": "The resourceId object contains information that identifies the resource that was marked as a favorite." - } - } - }, - "ActivityContentDetailsLike": { - "id": "ActivityContentDetailsLike", - "type": "object", - "description": "Information about a resource that received a positive (like) rating.", - "properties": { - "resourceId": { - "$ref": "ResourceId", - "description": "The resourceId object contains information that identifies the rated resource." - } - } - }, - "ActivityContentDetailsPlaylistItem": { - "id": "ActivityContentDetailsPlaylistItem", - "type": "object", - "description": "Information about a new playlist item.", - "properties": { - "playlistId": { - "type": "string", - "description": "The value that YouTube uses to uniquely identify the playlist." - }, - "playlistItemId": { - "type": "string", - "description": "ID of the item within the playlist." - }, - "resourceId": { - "$ref": "ResourceId", - "description": "The resourceId object contains information about the resource that was added to the playlist." - } - } - }, - "ActivityContentDetailsPromotedItem": { - "id": "ActivityContentDetailsPromotedItem", - "type": "object", - "description": "Details about a resource which is being promoted.", - "properties": { - "adTag": { - "type": "string", - "description": "The URL the client should fetch to request a promoted item." - }, - "clickTrackingUrl": { - "type": "string", - "description": "The URL the client should ping to indicate that the user clicked through on this promoted item." - }, - "creativeViewUrl": { - "type": "string", - "description": "The URL the client should ping to indicate that the user was shown this promoted item." - }, - "ctaType": { - "type": "string", - "description": "The type of call-to-action, a message to the user indicating action that can be taken.", - "enum": [ - "unspecified", - "visitAdvertiserSite" - ], - "enumDescriptions": [ - "", - "" - ] - }, - "customCtaButtonText": { - "type": "string", - "description": "The custom call-to-action button text. If specified, it will override the default button text for the cta_type." - }, - "descriptionText": { - "type": "string", - "description": "The text description to accompany the promoted item." - }, - "destinationUrl": { - "type": "string", - "description": "The URL the client should direct the user to, if the user chooses to visit the advertiser's website." - }, - "forecastingUrl": { - "type": "array", - "description": "The list of forecasting URLs. The client should ping all of these URLs when a promoted item is not available, to indicate that a promoted item could have been shown.", - "items": { - "type": "string" - } - }, - "impressionUrl": { - "type": "array", - "description": "The list of impression URLs. The client should ping all of these URLs to indicate that the user was shown this promoted item.", - "items": { - "type": "string" - } - }, - "videoId": { - "type": "string", - "description": "The ID that YouTube uses to uniquely identify the promoted video." - } - } - }, - "ActivityContentDetailsRecommendation": { - "id": "ActivityContentDetailsRecommendation", - "type": "object", - "description": "Information that identifies the recommended resource.", - "properties": { - "reason": { - "type": "string", - "description": "The reason that the resource is recommended to the user.", - "enum": [ - "unspecified", - "videoFavorited", - "videoLiked", - "videoWatched" - ], - "enumDescriptions": [ - "", - "", - "", - "" - ] - }, - "resourceId": { - "$ref": "ResourceId", - "description": "The resourceId object contains information that identifies the recommended resource." - }, - "seedResourceId": { - "$ref": "ResourceId", - "description": "The seedResourceId object contains information about the resource that caused the recommendation." - } - } - }, - "ActivityContentDetailsSocial": { - "id": "ActivityContentDetailsSocial", - "type": "object", - "description": "Details about a social network post.", - "properties": { - "author": { - "type": "string", - "description": "The author of the social network post." - }, - "imageUrl": { - "type": "string", - "description": "An image of the post's author." - }, - "referenceUrl": { - "type": "string", - "description": "The URL of the social network post." - }, - "resourceId": { - "$ref": "ResourceId", - "description": "The resourceId object encapsulates information that identifies the resource associated with a social network post." - }, - "type": { - "type": "string", - "description": "The name of the social network.", - "enum": [ - "facebook", - "googlePlus", - "twitter", - "unspecified" - ], - "enumDescriptions": [ - "", - "", - "", - "" - ] - } - } - }, - "ActivityContentDetailsSubscription": { - "id": "ActivityContentDetailsSubscription", - "type": "object", - "description": "Information about a channel that a user subscribed to.", - "properties": { - "resourceId": { - "$ref": "ResourceId", - "description": "The resourceId object contains information that identifies the resource that the user subscribed to." - } - } - }, - "ActivityContentDetailsUpload": { - "id": "ActivityContentDetailsUpload", - "type": "object", - "description": "Information about the uploaded video.", - "properties": { - "videoId": { - "type": "string", - "description": "The ID that YouTube uses to uniquely identify the uploaded video." - } - } - }, - "ActivityListResponse": { - "id": "ActivityListResponse", - "type": "object", - "properties": { - "etag": { - "type": "string", - "description": "Etag of this resource." - }, - "eventId": { - "type": "string", - "description": "Serialized EventId of the request which produced this response." - }, - "items": { - "type": "array", - "description": "A list of activities, or events, that match the request criteria.", - "items": { - "$ref": "Activity" - } - }, - "kind": { - "type": "string", - "description": "Identifies what kind of resource this is. Value: the fixed string \"youtube#activityListResponse\".", - "default": "youtube#activityListResponse" - }, - "nextPageToken": { - "type": "string", - "description": "The token that can be used as the value of the pageToken parameter to retrieve the next page in the result set." - }, - "pageInfo": { - "$ref": "PageInfo" - }, - "prevPageToken": { - "type": "string", - "description": "The token that can be used as the value of the pageToken parameter to retrieve the previous page in the result set." - }, - "tokenPagination": { - "$ref": "TokenPagination" - }, - "visitorId": { - "type": "string", - "description": "The visitorId identifies the visitor." - } - } - }, - "ActivitySnippet": { - "id": "ActivitySnippet", - "type": "object", - "description": "Basic details about an activity, including title, description, thumbnails, activity type and group.", - "properties": { - "channelId": { - "type": "string", - "description": "The ID that YouTube uses to uniquely identify the channel associated with the activity." - }, - "channelTitle": { - "type": "string", - "description": "Channel title for the channel responsible for this activity" - }, - "description": { - "type": "string", - "description": "The description of the resource primarily associated with the activity.", - "annotations": { - "required": [ - "youtube.activities.insert" - ] - } - }, - "groupId": { - "type": "string", - "description": "The group ID associated with the activity. A group ID identifies user events that are associated with the same user and resource. For example, if a user rates a video and marks the same video as a favorite, the entries for those events would have the same group ID in the user's activity feed. In your user interface, you can avoid repetition by grouping events with the same groupId value." - }, - "publishedAt": { - "type": "string", - "description": "The date and time that the video was uploaded. The value is specified in ISO 8601 (YYYY-MM-DDThh:mm:ss.sZ) format.", - "format": "date-time" - }, - "thumbnails": { - "$ref": "ThumbnailDetails", - "description": "A map of thumbnail images associated with the resource that is primarily associated with the activity. For each object in the map, the key is the name of the thumbnail image, and the value is an object that contains other information about the thumbnail." - }, - "title": { - "type": "string", - "description": "The title of the resource primarily associated with the activity." - }, - "type": { - "type": "string", - "description": "The type of activity that the resource describes.", - "enum": [ - "bulletin", - "channelItem", - "comment", - "favorite", - "like", - "playlistItem", - "promotedItem", - "recommendation", - "social", - "subscription", - "upload" - ], - "enumDescriptions": [ - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "" - ] - } - } - }, - "Caption": { - "id": "Caption", - "type": "object", - "description": "A caption resource represents a YouTube caption track. A caption track is associated with exactly one YouTube video.", - "properties": { - "etag": { - "type": "string", - "description": "Etag of this resource." - }, - "id": { - "type": "string", - "description": "The ID that YouTube uses to uniquely identify the caption track.", - "annotations": { - "required": [ - "youtube.captions.update" - ] - } - }, - "kind": { - "type": "string", - "description": "Identifies what kind of resource this is. Value: the fixed string \"youtube#caption\".", - "default": "youtube#caption" - }, - "snippet": { - "$ref": "CaptionSnippet", - "description": "The snippet object contains basic details about the caption." - } - } - }, - "CaptionListResponse": { - "id": "CaptionListResponse", - "type": "object", - "properties": { - "etag": { - "type": "string", - "description": "Etag of this resource." - }, - "eventId": { - "type": "string", - "description": "Serialized EventId of the request which produced this response." - }, - "items": { - "type": "array", - "description": "A list of captions that match the request criteria.", - "items": { - "$ref": "Caption" - } - }, - "kind": { - "type": "string", - "description": "Identifies what kind of resource this is. Value: the fixed string \"youtube#captionListResponse\".", - "default": "youtube#captionListResponse" - }, - "visitorId": { - "type": "string", - "description": "The visitorId identifies the visitor." - } - } - }, - "CaptionSnippet": { - "id": "CaptionSnippet", - "type": "object", - "description": "Basic details about a caption track, such as its language and name.", - "properties": { - "audioTrackType": { - "type": "string", - "description": "The type of audio track associated with the caption track.", - "enum": [ - "commentary", - "descriptive", - "primary", - "unknown" - ], - "enumDescriptions": [ - "", - "", - "", - "" - ] - }, - "failureReason": { - "type": "string", - "description": "The reason that YouTube failed to process the caption track. This property is only present if the state property's value is failed.", - "enum": [ - "processingFailed", - "unknownFormat", - "unsupportedFormat" - ], - "enumDescriptions": [ - "", - "", - "" - ] - }, - "isAutoSynced": { - "type": "boolean", - "description": "Indicates whether YouTube synchronized the caption track to the audio track in the video. The value will be true if a sync was explicitly requested when the caption track was uploaded. For example, when calling the captions.insert or captions.update methods, you can set the sync parameter to true to instruct YouTube to sync the uploaded track to the video. If the value is false, YouTube uses the time codes in the uploaded caption track to determine when to display captions." - }, - "isCC": { - "type": "boolean", - "description": "Indicates whether the track contains closed captions for the deaf and hard of hearing. The default value is false." - }, - "isDraft": { - "type": "boolean", - "description": "Indicates whether the caption track is a draft. If the value is true, then the track is not publicly visible. The default value is false." - }, - "isEasyReader": { - "type": "boolean", - "description": "Indicates whether caption track is formatted for \"easy reader,\" meaning it is at a third-grade level for language learners. The default value is false." - }, - "isLarge": { - "type": "boolean", - "description": "Indicates whether the caption track uses large text for the vision-impaired. The default value is false." - }, - "language": { - "type": "string", - "description": "The language of the caption track. The property value is a BCP-47 language tag.", - "annotations": { - "required": [ - "youtube.captions.insert" - ] - } - }, - "lastUpdated": { - "type": "string", - "description": "The date and time when the caption track was last updated. The value is specified in ISO 8601 (YYYY-MM-DDThh:mm:ss.sZ) format.", - "format": "date-time" - }, - "name": { - "type": "string", - "description": "The name of the caption track. The name is intended to be visible to the user as an option during playback.", - "annotations": { - "required": [ - "youtube.captions.insert" - ] - } - }, - "status": { - "type": "string", - "description": "The caption track's status.", - "enum": [ - "failed", - "serving", - "syncing" - ], - "enumDescriptions": [ - "", - "", - "" - ] - }, - "trackKind": { - "type": "string", - "description": "The caption track's type.", - "enum": [ - "ASR", - "forced", - "standard" - ], - "enumDescriptions": [ - "", - "", - "" - ] - }, - "videoId": { - "type": "string", - "description": "The ID that YouTube uses to uniquely identify the video associated with the caption track.", - "annotations": { - "required": [ - "youtube.captions.insert" - ] - } - } - } - }, - "CdnSettings": { - "id": "CdnSettings", - "type": "object", - "description": "Brief description of the live stream cdn settings.", - "properties": { - "format": { - "type": "string", - "description": "The format of the video stream that you are sending to Youtube.", - "annotations": { - "required": [ - "youtube.liveStreams.insert", - "youtube.liveStreams.update" - ] - } - }, - "frameRate": { - "type": "string", - "description": "The frame rate of the inbound video data.", - "enum": [ - "30fps", - "60fps" - ], - "enumDescriptions": [ - "", - "" - ] - }, - "ingestionInfo": { - "$ref": "IngestionInfo", - "description": "The ingestionInfo object contains information that YouTube provides that you need to transmit your RTMP or HTTP stream to YouTube." - }, - "ingestionType": { - "type": "string", - "description": "The method or protocol used to transmit the video stream.", - "enum": [ - "dash", - "rtmp" - ], - "enumDescriptions": [ - "", - "" - ], - "annotations": { - "required": [ - "youtube.liveStreams.insert", - "youtube.liveStreams.update" - ] - } - }, - "resolution": { - "type": "string", - "description": "The resolution of the inbound video data.", - "enum": [ - "1080p", - "1440p", - "2160p", - "240p", - "360p", - "480p", - "720p" - ], - "enumDescriptions": [ - "", - "", - "", - "", - "", - "", - "" - ] - } - } - }, - "Channel": { - "id": "Channel", - "type": "object", - "description": "A channel resource contains information about a YouTube channel.", - "properties": { - "auditDetails": { - "$ref": "ChannelAuditDetails", - "description": "The auditionDetails object encapsulates channel data that is relevant for YouTube Partners during the audition process." - }, - "brandingSettings": { - "$ref": "ChannelBrandingSettings", - "description": "The brandingSettings object encapsulates information about the branding of the channel." - }, - "contentDetails": { - "$ref": "ChannelContentDetails", - "description": "The contentDetails object encapsulates information about the channel's content." - }, - "contentOwnerDetails": { - "$ref": "ChannelContentOwnerDetails", - "description": "The contentOwnerDetails object encapsulates channel data that is relevant for YouTube Partners linked with the channel." - }, - "conversionPings": { - "$ref": "ChannelConversionPings", - "description": "The conversionPings object encapsulates information about conversion pings that need to be respected by the channel." - }, - "etag": { - "type": "string", - "description": "Etag of this resource." - }, - "id": { - "type": "string", - "description": "The ID that YouTube uses to uniquely identify the channel." - }, - "invideoPromotion": { - "$ref": "InvideoPromotion", - "description": "The invideoPromotion object encapsulates information about promotion campaign associated with the channel." - }, - "kind": { - "type": "string", - "description": "Identifies what kind of resource this is. Value: the fixed string \"youtube#channel\".", - "default": "youtube#channel" - }, - "localizations": { - "type": "object", - "description": "Localizations for different languages", - "additionalProperties": { - "$ref": "ChannelLocalization", - "description": "The language tag, using string since map_key require simple types." - } - }, - "snippet": { - "$ref": "ChannelSnippet", - "description": "The snippet object contains basic details about the channel, such as its title, description, and thumbnail images." - }, - "statistics": { - "$ref": "ChannelStatistics", - "description": "The statistics object encapsulates statistics for the channel." - }, - "status": { - "$ref": "ChannelStatus", - "description": "The status object encapsulates information about the privacy status of the channel." - }, - "topicDetails": { - "$ref": "ChannelTopicDetails", - "description": "The topicDetails object encapsulates information about Freebase topics associated with the channel." - } - } - }, - "ChannelAuditDetails": { - "id": "ChannelAuditDetails", - "type": "object", - "description": "The auditDetails object encapsulates channel data that is relevant for YouTube Partners during the audit process.", - "properties": { - "communityGuidelinesGoodStanding": { - "type": "boolean", - "description": "Whether or not the channel respects the community guidelines." - }, - "contentIdClaimsGoodStanding": { - "type": "boolean", - "description": "Whether or not the channel has any unresolved claims." - }, - "copyrightStrikesGoodStanding": { - "type": "boolean", - "description": "Whether or not the channel has any copyright strikes." - }, - "overallGoodStanding": { - "type": "boolean", - "description": "Describes the general state of the channel. This field will always show if there are any issues whatsoever with the channel. Currently this field represents the result of the logical and operation over the community guidelines good standing, the copyright strikes good standing and the content ID claims good standing, but this may change in the future." - } - } - }, - "ChannelBannerResource": { - "id": "ChannelBannerResource", - "type": "object", - "description": "A channel banner returned as the response to a channel_banner.insert call.", - "properties": { - "etag": { - "type": "string", - "description": "Etag of this resource." - }, - "kind": { - "type": "string", - "description": "Identifies what kind of resource this is. Value: the fixed string \"youtube#channelBannerResource\".", - "default": "youtube#channelBannerResource" - }, - "url": { - "type": "string", - "description": "The URL of this banner image." - } - } - }, - "ChannelBrandingSettings": { - "id": "ChannelBrandingSettings", - "type": "object", - "description": "Branding properties of a YouTube channel.", - "properties": { - "channel": { - "$ref": "ChannelSettings", - "description": "Branding properties for the channel view." - }, - "hints": { - "type": "array", - "description": "Additional experimental branding properties.", - "items": { - "$ref": "PropertyValue" - } - }, - "image": { - "$ref": "ImageSettings", - "description": "Branding properties for branding images." - }, - "watch": { - "$ref": "WatchSettings", - "description": "Branding properties for the watch page." - } - } - }, - "ChannelContentDetails": { - "id": "ChannelContentDetails", - "type": "object", - "description": "Details about the content of a channel.", - "properties": { - "relatedPlaylists": { - "type": "object", - "properties": { - "favorites": { - "type": "string", - "description": "The ID of the playlist that contains the channel\"s favorite videos. Use the playlistItems.insert and playlistItems.delete to add or remove items from that list." - }, - "likes": { - "type": "string", - "description": "The ID of the playlist that contains the channel\"s liked videos. Use the playlistItems.insert and playlistItems.delete to add or remove items from that list." - }, - "uploads": { - "type": "string", - "description": "The ID of the playlist that contains the channel\"s uploaded videos. Use the videos.insert method to upload new videos and the videos.delete method to delete previously uploaded videos." - }, - "watchHistory": { - "type": "string", - "description": "The ID of the playlist that contains the channel\"s watch history. Use the playlistItems.insert and playlistItems.delete to add or remove items from that list." - }, - "watchLater": { - "type": "string", - "description": "The ID of the playlist that contains the channel\"s watch later playlist. Use the playlistItems.insert and playlistItems.delete to add or remove items from that list." - } - } - } - } - }, - "ChannelContentOwnerDetails": { - "id": "ChannelContentOwnerDetails", - "type": "object", - "description": "The contentOwnerDetails object encapsulates channel data that is relevant for YouTube Partners linked with the channel.", - "properties": { - "contentOwner": { - "type": "string", - "description": "The ID of the content owner linked to the channel." - }, - "timeLinked": { - "type": "string", - "description": "The date and time of when the channel was linked to the content owner. The value is specified in ISO 8601 (YYYY-MM-DDThh:mm:ss.sZ) format.", - "format": "date-time" - } - } - }, - "ChannelConversionPing": { - "id": "ChannelConversionPing", - "type": "object", - "description": "Pings that the app shall fire (authenticated by biscotti cookie). Each ping has a context, in which the app must fire the ping, and a url identifying the ping.", - "properties": { - "context": { - "type": "string", - "description": "Defines the context of the ping.", - "enum": [ - "cview", - "subscribe", - "unsubscribe" - ], - "enumDescriptions": [ - "", - "", - "" - ] - }, - "conversionUrl": { - "type": "string", - "description": "The url (without the schema) that the player shall send the ping to. It's at caller's descretion to decide which schema to use (http vs https) Example of a returned url: //googleads.g.doubleclick.net/pagead/ viewthroughconversion/962985656/?data=path%3DtHe_path%3Btype%3D cview%3Butuid%3DGISQtTNGYqaYl4sKxoVvKA&labe=default The caller must append biscotti authentication (ms param in case of mobile, for example) to this ping." - } - } - }, - "ChannelConversionPings": { - "id": "ChannelConversionPings", - "type": "object", - "description": "The conversionPings object encapsulates information about conversion pings that need to be respected by the channel.", - "properties": { - "pings": { - "type": "array", - "description": "Pings that the app shall fire (authenticated by biscotti cookie). Each ping has a context, in which the app must fire the ping, and a url identifying the ping.", - "items": { - "$ref": "ChannelConversionPing" - } - } - } - }, - "ChannelListResponse": { - "id": "ChannelListResponse", - "type": "object", - "properties": { - "etag": { - "type": "string", - "description": "Etag of this resource." - }, - "eventId": { - "type": "string", - "description": "Serialized EventId of the request which produced this response." - }, - "items": { - "type": "array", - "description": "A list of channels that match the request criteria.", - "items": { - "$ref": "Channel" - } - }, - "kind": { - "type": "string", - "description": "Identifies what kind of resource this is. Value: the fixed string \"youtube#channelListResponse\".", - "default": "youtube#channelListResponse" - }, - "nextPageToken": { - "type": "string", - "description": "The token that can be used as the value of the pageToken parameter to retrieve the next page in the result set." - }, - "pageInfo": { - "$ref": "PageInfo" - }, - "prevPageToken": { - "type": "string", - "description": "The token that can be used as the value of the pageToken parameter to retrieve the previous page in the result set." - }, - "tokenPagination": { - "$ref": "TokenPagination" - }, - "visitorId": { - "type": "string", - "description": "The visitorId identifies the visitor." - } - } - }, - "ChannelLocalization": { - "id": "ChannelLocalization", - "type": "object", - "description": "Channel localization setting", - "properties": { - "description": { - "type": "string", - "description": "The localized strings for channel's description." - }, - "title": { - "type": "string", - "description": "The localized strings for channel's title." - } - } - }, - "ChannelProfileDetails": { - "id": "ChannelProfileDetails", - "type": "object", - "properties": { - "channelId": { - "type": "string", - "description": "The YouTube channel ID." - }, - "channelUrl": { - "type": "string", - "description": "The channel's URL." - }, - "displayName": { - "type": "string", - "description": "The channel's display name." - }, - "profileImageUrl": { - "type": "string", - "description": "The channels's avatar URL." - } - } - }, - "ChannelSection": { - "id": "ChannelSection", - "type": "object", - "properties": { - "contentDetails": { - "$ref": "ChannelSectionContentDetails", - "description": "The contentDetails object contains details about the channel section content, such as a list of playlists or channels featured in the section." - }, - "etag": { - "type": "string", - "description": "Etag of this resource." - }, - "id": { - "type": "string", - "description": "The ID that YouTube uses to uniquely identify the channel section." - }, - "kind": { - "type": "string", - "description": "Identifies what kind of resource this is. Value: the fixed string \"youtube#channelSection\".", - "default": "youtube#channelSection" - }, - "localizations": { - "type": "object", - "description": "Localizations for different languages", - "additionalProperties": { - "$ref": "ChannelSectionLocalization", - "description": "The language tag, using string since map_key require simple types." - } - }, - "snippet": { - "$ref": "ChannelSectionSnippet", - "description": "The snippet object contains basic details about the channel section, such as its type, style and title." - }, - "targeting": { - "$ref": "ChannelSectionTargeting", - "description": "The targeting object contains basic targeting settings about the channel section." - } - } - }, - "ChannelSectionContentDetails": { - "id": "ChannelSectionContentDetails", - "type": "object", - "description": "Details about a channelsection, including playlists and channels.", - "properties": { - "channels": { - "type": "array", - "description": "The channel ids for type multiple_channels.", - "items": { - "type": "string" - } - }, - "playlists": { - "type": "array", - "description": "The playlist ids for type single_playlist and multiple_playlists. For singlePlaylist, only one playlistId is allowed.", - "items": { - "type": "string" - } - } - } - }, - "ChannelSectionListResponse": { - "id": "ChannelSectionListResponse", - "type": "object", - "properties": { - "etag": { - "type": "string", - "description": "Etag of this resource." - }, - "eventId": { - "type": "string", - "description": "Serialized EventId of the request which produced this response." - }, - "items": { - "type": "array", - "description": "A list of ChannelSections that match the request criteria.", - "items": { - "$ref": "ChannelSection" - } - }, - "kind": { - "type": "string", - "description": "Identifies what kind of resource this is. Value: the fixed string \"youtube#channelSectionListResponse\".", - "default": "youtube#channelSectionListResponse" - }, - "visitorId": { - "type": "string", - "description": "The visitorId identifies the visitor." - } - } - }, - "ChannelSectionLocalization": { - "id": "ChannelSectionLocalization", - "type": "object", - "description": "ChannelSection localization setting", - "properties": { - "title": { - "type": "string", - "description": "The localized strings for channel section's title." - } - } - }, - "ChannelSectionSnippet": { - "id": "ChannelSectionSnippet", - "type": "object", - "description": "Basic details about a channel section, including title, style and position.", - "properties": { - "channelId": { - "type": "string", - "description": "The ID that YouTube uses to uniquely identify the channel that published the channel section." - }, - "defaultLanguage": { - "type": "string", - "description": "The language of the channel section's default title and description." - }, - "localized": { - "$ref": "ChannelSectionLocalization", - "description": "Localized title, read-only." - }, - "position": { - "type": "integer", - "description": "The position of the channel section in the channel.", - "format": "uint32" - }, - "style": { - "type": "string", - "description": "The style of the channel section.", - "enum": [ - "channelsectionStyleUndefined", - "horizontalRow", - "verticalList" - ], - "enumDescriptions": [ - "", - "", - "" - ] - }, - "title": { - "type": "string", - "description": "The channel section's title for multiple_playlists and multiple_channels." - }, - "type": { - "type": "string", - "description": "The type of the channel section.", - "enum": [ - "allPlaylists", - "channelsectionTypeUndefined", - "completedEvents", - "likedPlaylists", - "likes", - "liveEvents", - "multipleChannels", - "multiplePlaylists", - "popularUploads", - "postedPlaylists", - "postedVideos", - "recentActivity", - "recentPosts", - "recentUploads", - "singlePlaylist", - "subscriptions", - "upcomingEvents" - ], - "enumDescriptions": [ - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "" - ] - } - } - }, - "ChannelSectionTargeting": { - "id": "ChannelSectionTargeting", - "type": "object", - "description": "ChannelSection targeting setting.", - "properties": { - "countries": { - "type": "array", - "description": "The country the channel section is targeting.", - "items": { - "type": "string" - } - }, - "languages": { - "type": "array", - "description": "The language the channel section is targeting.", - "items": { - "type": "string" - } - }, - "regions": { - "type": "array", - "description": "The region the channel section is targeting.", - "items": { - "type": "string" - } - } - } - }, - "ChannelSettings": { - "id": "ChannelSettings", - "type": "object", - "description": "Branding properties for the channel view.", - "properties": { - "country": { - "type": "string", - "description": "The country of the channel." - }, - "defaultLanguage": { - "type": "string" - }, - "defaultTab": { - "type": "string", - "description": "Which content tab users should see when viewing the channel." - }, - "description": { - "type": "string", - "description": "Specifies the channel description." - }, - "featuredChannelsTitle": { - "type": "string", - "description": "Title for the featured channels tab." - }, - "featuredChannelsUrls": { - "type": "array", - "description": "The list of featured channels.", - "items": { - "type": "string" - } - }, - "keywords": { - "type": "string", - "description": "Lists keywords associated with the channel, comma-separated." - }, - "moderateComments": { - "type": "boolean", - "description": "Whether user-submitted comments left on the channel page need to be approved by the channel owner to be publicly visible." - }, - "profileColor": { - "type": "string", - "description": "A prominent color that can be rendered on this channel page." - }, - "showBrowseView": { - "type": "boolean", - "description": "Whether the tab to browse the videos should be displayed." - }, - "showRelatedChannels": { - "type": "boolean", - "description": "Whether related channels should be proposed." - }, - "title": { - "type": "string", - "description": "Specifies the channel title." - }, - "trackingAnalyticsAccountId": { - "type": "string", - "description": "The ID for a Google Analytics account to track and measure traffic to the channels." - }, - "unsubscribedTrailer": { - "type": "string", - "description": "The trailer of the channel, for users that are not subscribers." - } - } - }, - "ChannelSnippet": { - "id": "ChannelSnippet", - "type": "object", - "description": "Basic details about a channel, including title, description and thumbnails. Next available id: 15.", - "properties": { - "country": { - "type": "string", - "description": "The country of the channel." - }, - "customUrl": { - "type": "string", - "description": "The custom url of the channel." - }, - "defaultLanguage": { - "type": "string", - "description": "The language of the channel's default title and description." - }, - "description": { - "type": "string", - "description": "The description of the channel." - }, - "localized": { - "$ref": "ChannelLocalization", - "description": "Localized title and description, read-only." - }, - "publishedAt": { - "type": "string", - "description": "The date and time that the channel was created. The value is specified in ISO 8601 (YYYY-MM-DDThh:mm:ss.sZ) format.", - "format": "date-time" - }, - "thumbnails": { - "$ref": "ThumbnailDetails", - "description": "A map of thumbnail images associated with the channel. For each object in the map, the key is the name of the thumbnail image, and the value is an object that contains other information about the thumbnail." - }, - "title": { - "type": "string", - "description": "The channel's title." - } - } - }, - "ChannelStatistics": { - "id": "ChannelStatistics", - "type": "object", - "description": "Statistics about a channel: number of subscribers, number of videos in the channel, etc.", - "properties": { - "commentCount": { - "type": "string", - "description": "The number of comments for the channel.", - "format": "uint64" - }, - "hiddenSubscriberCount": { - "type": "boolean", - "description": "Whether or not the number of subscribers is shown for this user." - }, - "subscriberCount": { - "type": "string", - "description": "The number of subscribers that the channel has.", - "format": "uint64" - }, - "videoCount": { - "type": "string", - "description": "The number of videos uploaded to the channel.", - "format": "uint64" - }, - "viewCount": { - "type": "string", - "description": "The number of times the channel has been viewed.", - "format": "uint64" - } - } - }, - "ChannelStatus": { - "id": "ChannelStatus", - "type": "object", - "description": "JSON template for the status part of a channel.", - "properties": { - "isLinked": { - "type": "boolean", - "description": "If true, then the user is linked to either a YouTube username or G+ account. Otherwise, the user doesn't have a public YouTube identity." - }, - "longUploadsStatus": { - "type": "string", - "description": "The long uploads status of this channel. See", - "enum": [ - "allowed", - "disallowed", - "eligible", - "longUploadsUnspecified" - ], - "enumDescriptions": [ - "", - "", - "", - "" - ] - }, - "privacyStatus": { - "type": "string", - "description": "Privacy status of the channel.", - "enum": [ - "private", - "public", - "unlisted" - ], - "enumDescriptions": [ - "", - "", - "" - ] - } - } - }, - "ChannelTopicDetails": { - "id": "ChannelTopicDetails", - "type": "object", - "description": "Freebase topic information related to the channel.", - "properties": { - "topicCategories": { - "type": "array", - "description": "A list of Wikipedia URLs that describe the channel's content.", - "items": { - "type": "string" - } - }, - "topicIds": { - "type": "array", - "description": "A list of Freebase topic IDs associated with the channel. You can retrieve information about each topic using the Freebase Topic API.", - "items": { - "type": "string" - } - } - } - }, - "Comment": { - "id": "Comment", - "type": "object", - "description": "A comment represents a single YouTube comment.", - "properties": { - "etag": { - "type": "string", - "description": "Etag of this resource." - }, - "id": { - "type": "string", - "description": "The ID that YouTube uses to uniquely identify the comment." - }, - "kind": { - "type": "string", - "description": "Identifies what kind of resource this is. Value: the fixed string \"youtube#comment\".", - "default": "youtube#comment" - }, - "snippet": { - "$ref": "CommentSnippet", - "description": "The snippet object contains basic details about the comment." - } - } - }, - "CommentListResponse": { - "id": "CommentListResponse", - "type": "object", - "properties": { - "etag": { - "type": "string", - "description": "Etag of this resource." - }, - "eventId": { - "type": "string", - "description": "Serialized EventId of the request which produced this response." - }, - "items": { - "type": "array", - "description": "A list of comments that match the request criteria.", - "items": { - "$ref": "Comment" - } - }, - "kind": { - "type": "string", - "description": "Identifies what kind of resource this is. Value: the fixed string \"youtube#commentListResponse\".", - "default": "youtube#commentListResponse" - }, - "nextPageToken": { - "type": "string", - "description": "The token that can be used as the value of the pageToken parameter to retrieve the next page in the result set." - }, - "pageInfo": { - "$ref": "PageInfo" - }, - "tokenPagination": { - "$ref": "TokenPagination" - }, - "visitorId": { - "type": "string", - "description": "The visitorId identifies the visitor." - } - } - }, - "CommentSnippet": { - "id": "CommentSnippet", - "type": "object", - "description": "Basic details about a comment, such as its author and text.", - "properties": { - "authorChannelId": { - "type": "any", - "description": "The id of the author's YouTube channel, if any." - }, - "authorChannelUrl": { - "type": "string", - "description": "Link to the author's YouTube channel, if any." - }, - "authorDisplayName": { - "type": "string", - "description": "The name of the user who posted the comment." - }, - "authorProfileImageUrl": { - "type": "string", - "description": "The URL for the avatar of the user who posted the comment." - }, - "canRate": { - "type": "boolean", - "description": "Whether the current viewer can rate this comment." - }, - "channelId": { - "type": "string", - "description": "The id of the corresponding YouTube channel. In case of a channel comment this is the channel the comment refers to. In case of a video comment it's the video's channel." - }, - "likeCount": { - "type": "integer", - "description": "The total number of likes this comment has received.", - "format": "uint32" - }, - "moderationStatus": { - "type": "string", - "description": "The comment's moderation status. Will not be set if the comments were requested through the id filter.", - "enum": [ - "heldForReview", - "likelySpam", - "published", - "rejected" - ], - "enumDescriptions": [ - "", - "", - "", - "" - ] - }, - "parentId": { - "type": "string", - "description": "The unique id of the parent comment, only set for replies." - }, - "publishedAt": { - "type": "string", - "description": "The date and time when the comment was orignally published. The value is specified in ISO 8601 (YYYY-MM-DDThh:mm:ss.sZ) format.", - "format": "date-time" - }, - "textDisplay": { - "type": "string", - "description": "The comment's text. The format is either plain text or HTML dependent on what has been requested. Even the plain text representation may differ from the text originally posted in that it may replace video links with video titles etc." - }, - "textOriginal": { - "type": "string", - "description": "The comment's original raw text as initially posted or last updated. The original text will only be returned if it is accessible to the viewer, which is only guaranteed if the viewer is the comment's author." - }, - "updatedAt": { - "type": "string", - "description": "The date and time when was last updated . The value is specified in ISO 8601 (YYYY-MM-DDThh:mm:ss.sZ) format.", - "format": "date-time" - }, - "videoId": { - "type": "string", - "description": "The ID of the video the comment refers to, if any." - }, - "viewerRating": { - "type": "string", - "description": "The rating the viewer has given to this comment. For the time being this will never return RATE_TYPE_DISLIKE and instead return RATE_TYPE_NONE. This may change in the future.", - "enum": [ - "dislike", - "like", - "none", - "unspecified" - ], - "enumDescriptions": [ - "", - "", - "", - "" - ] - } - } - }, - "CommentThread": { - "id": "CommentThread", - "type": "object", - "description": "A comment thread represents information that applies to a top level comment and all its replies. It can also include the top level comment itself and some of the replies.", - "properties": { - "etag": { - "type": "string", - "description": "Etag of this resource." - }, - "id": { - "type": "string", - "description": "The ID that YouTube uses to uniquely identify the comment thread." - }, - "kind": { - "type": "string", - "description": "Identifies what kind of resource this is. Value: the fixed string \"youtube#commentThread\".", - "default": "youtube#commentThread" - }, - "replies": { - "$ref": "CommentThreadReplies", - "description": "The replies object contains a limited number of replies (if any) to the top level comment found in the snippet." - }, - "snippet": { - "$ref": "CommentThreadSnippet", - "description": "The snippet object contains basic details about the comment thread and also the top level comment." - } - } - }, - "CommentThreadListResponse": { - "id": "CommentThreadListResponse", - "type": "object", - "properties": { - "etag": { - "type": "string", - "description": "Etag of this resource." - }, - "eventId": { - "type": "string", - "description": "Serialized EventId of the request which produced this response." - }, - "items": { - "type": "array", - "description": "A list of comment threads that match the request criteria.", - "items": { - "$ref": "CommentThread" - } - }, - "kind": { - "type": "string", - "description": "Identifies what kind of resource this is. Value: the fixed string \"youtube#commentThreadListResponse\".", - "default": "youtube#commentThreadListResponse" - }, - "nextPageToken": { - "type": "string", - "description": "The token that can be used as the value of the pageToken parameter to retrieve the next page in the result set." - }, - "pageInfo": { - "$ref": "PageInfo" - }, - "tokenPagination": { - "$ref": "TokenPagination" - }, - "visitorId": { - "type": "string", - "description": "The visitorId identifies the visitor." - } - } - }, - "CommentThreadReplies": { - "id": "CommentThreadReplies", - "type": "object", - "description": "Comments written in (direct or indirect) reply to the top level comment.", - "properties": { - "comments": { - "type": "array", - "description": "A limited number of replies. Unless the number of replies returned equals total_reply_count in the snippet the returned replies are only a subset of the total number of replies.", - "items": { - "$ref": "Comment" - } - } - } - }, - "CommentThreadSnippet": { - "id": "CommentThreadSnippet", - "type": "object", - "description": "Basic details about a comment thread.", - "properties": { - "canReply": { - "type": "boolean", - "description": "Whether the current viewer of the thread can reply to it. This is viewer specific - other viewers may see a different value for this field." - }, - "channelId": { - "type": "string", - "description": "The YouTube channel the comments in the thread refer to or the channel with the video the comments refer to. If video_id isn't set the comments refer to the channel itself." - }, - "isPublic": { - "type": "boolean", - "description": "Whether the thread (and therefore all its comments) is visible to all YouTube users." - }, - "topLevelComment": { - "$ref": "Comment", - "description": "The top level comment of this thread." - }, - "totalReplyCount": { - "type": "integer", - "description": "The total number of replies (not including the top level comment).", - "format": "uint32" - }, - "videoId": { - "type": "string", - "description": "The ID of the video the comments refer to, if any. No video_id implies a channel discussion comment." - } - } - }, - "ContentRating": { - "id": "ContentRating", - "type": "object", - "description": "Ratings schemes. The country-specific ratings are mostly for movies and shows. NEXT_ID: 69", - "properties": { - "acbRating": { - "type": "string", - "description": "The video's Australian Classification Board (ACB) or Australian Communications and Media Authority (ACMA) rating. ACMA ratings are used to classify children's television programming.", - "enum": [ - "acbC", - "acbE", - "acbG", - "acbM", - "acbMa15plus", - "acbP", - "acbPg", - "acbR18plus", - "acbUnrated" - ], - "enumDescriptions": [ - "", - "", - "", - "", - "", - "", - "", - "", - "" - ] - }, - "agcomRating": { - "type": "string", - "description": "The video's rating from Italy's Autorità per le Garanzie nelle Comunicazioni (AGCOM).", - "enum": [ - "agcomT", - "agcomUnrated", - "agcomVm14", - "agcomVm18" - ], - "enumDescriptions": [ - "", - "", - "", - "" - ] - }, - "anatelRating": { - "type": "string", - "description": "The video's Anatel (Asociación Nacional de Televisión) rating for Chilean television.", - "enum": [ - "anatelA", - "anatelF", - "anatelI", - "anatelI10", - "anatelI12", - "anatelI7", - "anatelR", - "anatelUnrated" - ], - "enumDescriptions": [ - "", - "", - "", - "", - "", - "", - "", - "" - ] - }, - "bbfcRating": { - "type": "string", - "description": "The video's British Board of Film Classification (BBFC) rating.", - "enum": [ - "bbfc12", - "bbfc12a", - "bbfc15", - "bbfc18", - "bbfcPg", - "bbfcR18", - "bbfcU", - "bbfcUnrated" - ], - "enumDescriptions": [ - "", - "", - "", - "", - "", - "", - "", - "" - ] - }, - "bfvcRating": { - "type": "string", - "description": "The video's rating from Thailand's Board of Film and Video Censors.", - "enum": [ - "bfvc13", - "bfvc15", - "bfvc18", - "bfvc20", - "bfvcB", - "bfvcE", - "bfvcG", - "bfvcUnrated" - ], - "enumDescriptions": [ - "", - "", - "", - "", - "", - "", - "", - "" - ] - }, - "bmukkRating": { - "type": "string", - "description": "The video's rating from the Austrian Board of Media Classification (Bundesministerium für Unterricht, Kunst und Kultur).", - "enum": [ - "bmukk10", - "bmukk12", - "bmukk14", - "bmukk16", - "bmukk6", - "bmukk8", - "bmukkAa", - "bmukkUnrated" - ], - "enumDescriptions": [ - "", - "", - "", - "", - "", - "", - "", - "" - ] - }, - "catvRating": { - "type": "string", - "description": "Rating system for Canadian TV - Canadian TV Classification System The video's rating from the Canadian Radio-Television and Telecommunications Commission (CRTC) for Canadian English-language broadcasts. For more information, see the Canadian Broadcast Standards Council website.", - "enum": [ - "catv14plus", - "catv18plus", - "catvC", - "catvC8", - "catvG", - "catvPg", - "catvUnrated" - ], - "enumDescriptions": [ - "", - "", - "", - "", - "", - "", - "" - ] - }, - "catvfrRating": { - "type": "string", - "description": "The video's rating from the Canadian Radio-Television and Telecommunications Commission (CRTC) for Canadian French-language broadcasts. For more information, see the Canadian Broadcast Standards Council website.", - "enum": [ - "catvfr13plus", - "catvfr16plus", - "catvfr18plus", - "catvfr8plus", - "catvfrG", - "catvfrUnrated" - ], - "enumDescriptions": [ - "", - "", - "", - "", - "", - "" - ] - }, - "cbfcRating": { - "type": "string", - "description": "The video's Central Board of Film Certification (CBFC - India) rating.", - "enum": [ - "cbfcA", - "cbfcS", - "cbfcU", - "cbfcUA", - "cbfcUnrated" - ], - "enumDescriptions": [ - "", - "", - "", - "", - "" - ] - }, - "cccRating": { - "type": "string", - "description": "The video's Consejo de Calificación Cinematográfica (Chile) rating.", - "enum": [ - "ccc14", - "ccc18", - "ccc18s", - "ccc18v", - "ccc6", - "cccTe", - "cccUnrated" - ], - "enumDescriptions": [ - "", - "", - "", - "", - "", - "", - "" - ] - }, - "cceRating": { - "type": "string", - "description": "The video's rating from Portugal's Comissão de Classificação de Espect´culos.", - "enum": [ - "cceM12", - "cceM14", - "cceM16", - "cceM18", - "cceM4", - "cceM6", - "cceUnrated" - ], - "enumDescriptions": [ - "", - "", - "", - "", - "", - "", - "" - ] - }, - "chfilmRating": { - "type": "string", - "description": "The video's rating in Switzerland.", - "enum": [ - "chfilm0", - "chfilm12", - "chfilm16", - "chfilm18", - "chfilm6", - "chfilmUnrated" - ], - "enumDescriptions": [ - "", - "", - "", - "", - "", - "" - ] - }, - "chvrsRating": { - "type": "string", - "description": "The video's Canadian Home Video Rating System (CHVRS) rating.", - "enum": [ - "chvrs14a", - "chvrs18a", - "chvrsE", - "chvrsG", - "chvrsPg", - "chvrsR", - "chvrsUnrated" - ], - "enumDescriptions": [ - "", - "", - "", - "", - "", - "", - "" - ] - }, - "cicfRating": { - "type": "string", - "description": "The video's rating from the Commission de Contrôle des Films (Belgium).", - "enum": [ - "cicfE", - "cicfKntEna", - "cicfKtEa", - "cicfUnrated" - ], - "enumDescriptions": [ - "", - "", - "", - "" - ] - }, - "cnaRating": { - "type": "string", - "description": "The video's rating from Romania's CONSILIUL NATIONAL AL AUDIOVIZUALULUI (CNA).", - "enum": [ - "cna12", - "cna15", - "cna18", - "cna18plus", - "cnaAp", - "cnaUnrated" - ], - "enumDescriptions": [ - "", - "", - "", - "", - "", - "" - ] - }, - "cncRating": { - "type": "string", - "description": "Rating system in France - Commission de classification cinematographique", - "enum": [ - "cnc10", - "cnc12", - "cnc16", - "cnc18", - "cncE", - "cncT", - "cncUnrated" - ], - "enumDescriptions": [ - "", - "", - "", - "", - "", - "", - "" - ] - }, - "csaRating": { - "type": "string", - "description": "The video's rating from France's Conseil supérieur de l?audiovisuel, which rates broadcast content.", - "enum": [ - "csa10", - "csa12", - "csa16", - "csa18", - "csaInterdiction", - "csaT", - "csaUnrated" - ], - "enumDescriptions": [ - "", - "", - "", - "", - "", - "", - "" - ] - }, - "cscfRating": { - "type": "string", - "description": "The video's rating from Luxembourg's Commission de surveillance de la classification des films (CSCF).", - "enum": [ - "cscf12", - "cscf16", - "cscf18", - "cscf6", - "cscf9", - "cscfA", - "cscfAl", - "cscfUnrated" - ], - "enumDescriptions": [ - "", - "", - "", - "", - "", - "", - "", - "" - ] - }, - "czfilmRating": { - "type": "string", - "description": "The video's rating in the Czech Republic.", - "enum": [ - "czfilm12", - "czfilm14", - "czfilm18", - "czfilmU", - "czfilmUnrated" - ], - "enumDescriptions": [ - "", - "", - "", - "", - "" - ] - }, - "djctqRating": { - "type": "string", - "description": "The video's Departamento de Justiça, Classificação, Qualificação e Títulos (DJCQT - Brazil) rating.", - "enum": [ - "djctq10", - "djctq12", - "djctq14", - "djctq16", - "djctq18", - "djctqL", - "djctqUnrated" - ], - "enumDescriptions": [ - "", - "", - "", - "", - "", - "", - "" - ] - }, - "djctqRatingReasons": { - "type": "array", - "description": "Reasons that explain why the video received its DJCQT (Brazil) rating.", - "items": { - "type": "string", - "enum": [ - "djctqCriminalActs", - "djctqDrugs", - "djctqExplicitSex", - "djctqExtremeViolence", - "djctqIllegalDrugs", - "djctqImpactingContent", - "djctqInappropriateLanguage", - "djctqLegalDrugs", - "djctqNudity", - "djctqSex", - "djctqSexualContent", - "djctqViolence" - ], - "enumDescriptions": [ - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "" - ] - } - }, - "ecbmctRating": { - "type": "string", - "description": "Rating system in Turkey - Evaluation and Classification Board of the Ministry of Culture and Tourism", - "enum": [ - "ecbmct13a", - "ecbmct13plus", - "ecbmct15a", - "ecbmct15plus", - "ecbmct18plus", - "ecbmct7a", - "ecbmct7plus", - "ecbmctG", - "ecbmctUnrated" - ], - "enumDescriptions": [ - "", - "", - "", - "", - "", - "", - "", - "", - "" - ] - }, - "eefilmRating": { - "type": "string", - "description": "The video's rating in Estonia.", - "enum": [ - "eefilmK12", - "eefilmK14", - "eefilmK16", - "eefilmK6", - "eefilmL", - "eefilmMs12", - "eefilmMs6", - "eefilmPere", - "eefilmUnrated" - ], - "enumDescriptions": [ - "", - "", - "", - "", - "", - "", - "", - "", - "" - ] - }, - "egfilmRating": { - "type": "string", - "description": "The video's rating in Egypt.", - "enum": [ - "egfilm18", - "egfilmBn", - "egfilmGn", - "egfilmUnrated" - ], - "enumDescriptions": [ - "", - "", - "", - "" - ] - }, - "eirinRating": { - "type": "string", - "description": "The video's Eirin (映倫) rating. Eirin is the Japanese rating system.", - "enum": [ - "eirinG", - "eirinPg12", - "eirinR15plus", - "eirinR18plus", - "eirinUnrated" - ], - "enumDescriptions": [ - "", - "", - "", - "", - "" - ] - }, - "fcbmRating": { - "type": "string", - "description": "The video's rating from Malaysia's Film Censorship Board.", - "enum": [ - "fcbm18", - "fcbm18pa", - "fcbm18pl", - "fcbm18sg", - "fcbm18sx", - "fcbmP13", - "fcbmPg13", - "fcbmU", - "fcbmUnrated" - ], - "enumDescriptions": [ - "", - "", - "", - "", - "", - "", - "", - "", - "" - ] - }, - "fcoRating": { - "type": "string", - "description": "The video's rating from Hong Kong's Office for Film, Newspaper and Article Administration.", - "enum": [ - "fcoI", - "fcoIi", - "fcoIia", - "fcoIib", - "fcoIii", - "fcoUnrated" - ], - "enumDescriptions": [ - "", - "", - "", - "", - "", - "" - ] - }, - "fmocRating": { - "type": "string", - "description": "This property has been deprecated. Use the contentDetails.contentRating.cncRating instead.", - "enum": [ - "fmoc10", - "fmoc12", - "fmoc16", - "fmoc18", - "fmocE", - "fmocU", - "fmocUnrated" - ], - "enumDescriptions": [ - "", - "", - "", - "", - "", - "", - "" - ] - }, - "fpbRating": { - "type": "string", - "description": "The video's rating from South Africa's Film and Publication Board.", - "enum": [ - "fpb10", - "fpb1012Pg", - "fpb13", - "fpb16", - "fpb18", - "fpb79Pg", - "fpbA", - "fpbPg", - "fpbUnrated", - "fpbX18", - "fpbXx" - ], - "enumDescriptions": [ - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "" - ] - }, - "fpbRatingReasons": { - "type": "array", - "description": "Reasons that explain why the video received its FPB (South Africa) rating.", - "items": { - "type": "string", - "enum": [ - "fpbBlasphemy", - "fpbCriminalTechniques", - "fpbDrugs", - "fpbHorror", - "fpbImitativeActsTechniques", - "fpbLanguage", - "fpbNudity", - "fpbPrejudice", - "fpbSex", - "fpbSexualViolence", - "fpbViolence" - ], - "enumDescriptions": [ - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "" - ] - } - }, - "fskRating": { - "type": "string", - "description": "The video's Freiwillige Selbstkontrolle der Filmwirtschaft (FSK - Germany) rating.", - "enum": [ - "fsk0", - "fsk12", - "fsk16", - "fsk18", - "fsk6", - "fskUnrated" - ], - "enumDescriptions": [ - "", - "", - "", - "", - "", - "" - ] - }, - "grfilmRating": { - "type": "string", - "description": "The video's rating in Greece.", - "enum": [ - "grfilmE", - "grfilmK", - "grfilmK12", - "grfilmK13", - "grfilmK15", - "grfilmK17", - "grfilmK18", - "grfilmUnrated" - ], - "enumDescriptions": [ - "", - "", - "", - "", - "", - "", - "", - "" - ] - }, - "icaaRating": { - "type": "string", - "description": "The video's Instituto de la Cinematografía y de las Artes Audiovisuales (ICAA - Spain) rating.", - "enum": [ - "icaa12", - "icaa13", - "icaa16", - "icaa18", - "icaa7", - "icaaApta", - "icaaUnrated", - "icaaX" - ], - "enumDescriptions": [ - "", - "", - "", - "", - "", - "", - "", - "" - ] - }, - "ifcoRating": { - "type": "string", - "description": "The video's Irish Film Classification Office (IFCO - Ireland) rating. See the IFCO website for more information.", - "enum": [ - "ifco12", - "ifco12a", - "ifco15", - "ifco15a", - "ifco16", - "ifco18", - "ifcoG", - "ifcoPg", - "ifcoUnrated" - ], - "enumDescriptions": [ - "", - "", - "", - "", - "", - "", - "", - "", - "" - ] - }, - "ilfilmRating": { - "type": "string", - "description": "The video's rating in Israel.", - "enum": [ - "ilfilm12", - "ilfilm16", - "ilfilm18", - "ilfilmAa", - "ilfilmUnrated" - ], - "enumDescriptions": [ - "", - "", - "", - "", - "" - ] - }, - "incaaRating": { - "type": "string", - "description": "The video's INCAA (Instituto Nacional de Cine y Artes Audiovisuales - Argentina) rating.", - "enum": [ - "incaaAtp", - "incaaC", - "incaaSam13", - "incaaSam16", - "incaaSam18", - "incaaUnrated" - ], - "enumDescriptions": [ - "", - "", - "", - "", - "", - "" - ] - }, - "kfcbRating": { - "type": "string", - "description": "The video's rating from the Kenya Film Classification Board.", - "enum": [ - "kfcb16plus", - "kfcbG", - "kfcbPg", - "kfcbR", - "kfcbUnrated" - ], - "enumDescriptions": [ - "", - "", - "", - "", - "" - ] - }, - "kijkwijzerRating": { - "type": "string", - "description": "voor de Classificatie van Audiovisuele Media (Netherlands).", - "enum": [ - "kijkwijzer12", - "kijkwijzer16", - "kijkwijzer18", - "kijkwijzer6", - "kijkwijzer9", - "kijkwijzerAl", - "kijkwijzerUnrated" - ], - "enumDescriptions": [ - "", - "", - "", - "", - "", - "", - "" - ] - }, - "kmrbRating": { - "type": "string", - "description": "The video's Korea Media Rating Board (영상물등급위원회) rating. The KMRB rates videos in South Korea.", - "enum": [ - "kmrb12plus", - "kmrb15plus", - "kmrbAll", - "kmrbR", - "kmrbTeenr", - "kmrbUnrated" - ], - "enumDescriptions": [ - "", - "", - "", - "", - "", - "" - ] - }, - "lsfRating": { - "type": "string", - "description": "The video's rating from Indonesia's Lembaga Sensor Film.", - "enum": [ - "lsf13", - "lsf17", - "lsf21", - "lsfA", - "lsfBo", - "lsfD", - "lsfR", - "lsfSu", - "lsfUnrated" - ], - "enumDescriptions": [ - "", - "", - "", - "", - "", - "", - "", - "", - "" - ] - }, - "mccaaRating": { - "type": "string", - "description": "The video's rating from Malta's Film Age-Classification Board.", - "enum": [ - "mccaa12", - "mccaa12a", - "mccaa14", - "mccaa15", - "mccaa16", - "mccaa18", - "mccaaPg", - "mccaaU", - "mccaaUnrated" - ], - "enumDescriptions": [ - "", - "", - "", - "", - "", - "", - "", - "", - "" - ] - }, - "mccypRating": { - "type": "string", - "description": "The video's rating from the Danish Film Institute's (Det Danske Filminstitut) Media Council for Children and Young People.", - "enum": [ - "mccyp11", - "mccyp15", - "mccyp7", - "mccypA", - "mccypUnrated" - ], - "enumDescriptions": [ - "", - "", - "", - "", - "" - ] - }, - "mcstRating": { - "type": "string", - "description": "The video's rating system for Vietnam - MCST", - "enum": [ - "mcst0", - "mcst16plus", - "mcstC13", - "mcstC16", - "mcstC18", - "mcstGPg", - "mcstP", - "mcstUnrated" - ], - "enumDescriptions": [ - "", - "", - "", - "", - "", - "", - "", - "" - ] - }, - "mdaRating": { - "type": "string", - "description": "The video's rating from Singapore's Media Development Authority (MDA) and, specifically, it's Board of Film Censors (BFC).", - "enum": [ - "mdaG", - "mdaM18", - "mdaNc16", - "mdaPg", - "mdaPg13", - "mdaR21", - "mdaUnrated" - ], - "enumDescriptions": [ - "", - "", - "", - "", - "", - "", - "" - ] - }, - "medietilsynetRating": { - "type": "string", - "description": "The video's rating from Medietilsynet, the Norwegian Media Authority.", - "enum": [ - "medietilsynet11", - "medietilsynet12", - "medietilsynet15", - "medietilsynet18", - "medietilsynet6", - "medietilsynet7", - "medietilsynet9", - "medietilsynetA", - "medietilsynetUnrated" - ], - "enumDescriptions": [ - "", - "", - "", - "", - "", - "", - "", - "", - "" - ] - }, - "mekuRating": { - "type": "string", - "description": "The video's rating from Finland's Kansallinen Audiovisuaalinen Instituutti (National Audiovisual Institute).", - "enum": [ - "meku12", - "meku16", - "meku18", - "meku7", - "mekuS", - "mekuUnrated" - ], - "enumDescriptions": [ - "", - "", - "", - "", - "", - "" - ] - }, - "mibacRating": { - "type": "string", - "description": "The video's rating from the Ministero dei Beni e delle Attività Culturali e del Turismo (Italy).", - "enum": [ - "mibacT", - "mibacUnrated", - "mibacVap", - "mibacVm12", - "mibacVm14", - "mibacVm18" - ], - "enumDescriptions": [ - "", - "", - "", - "", - "", - "" - ] - }, - "mocRating": { - "type": "string", - "description": "The video's Ministerio de Cultura (Colombia) rating.", - "enum": [ - "moc12", - "moc15", - "moc18", - "moc7", - "mocBanned", - "mocE", - "mocT", - "mocUnrated", - "mocX" - ], - "enumDescriptions": [ - "", - "", - "", - "", - "", - "", - "", - "", - "" - ] - }, - "moctwRating": { - "type": "string", - "description": "The video's rating from Taiwan's Ministry of Culture (文化部).", - "enum": [ - "moctwG", - "moctwP", - "moctwPg", - "moctwR", - "moctwR12", - "moctwR15", - "moctwUnrated" - ], - "enumDescriptions": [ - "", - "", - "", - "", - "", - "", - "" - ] - }, - "mpaaRating": { - "type": "string", - "description": "The video's Motion Picture Association of America (MPAA) rating.", - "enum": [ - "mpaaG", - "mpaaNc17", - "mpaaPg", - "mpaaPg13", - "mpaaR", - "mpaaUnrated" - ], - "enumDescriptions": [ - "", - "", - "", - "", - "", - "" - ] - }, - "mtrcbRating": { - "type": "string", - "description": "The video's rating from the Movie and Television Review and Classification Board (Philippines).", - "enum": [ - "mtrcbG", - "mtrcbPg", - "mtrcbR13", - "mtrcbR16", - "mtrcbR18", - "mtrcbUnrated", - "mtrcbX" - ], - "enumDescriptions": [ - "", - "", - "", - "", - "", - "", - "" - ] - }, - "nbcRating": { - "type": "string", - "description": "The video's rating from the Maldives National Bureau of Classification.", - "enum": [ - "nbc12plus", - "nbc15plus", - "nbc18plus", - "nbc18plusr", - "nbcG", - "nbcPg", - "nbcPu", - "nbcUnrated" - ], - "enumDescriptions": [ - "", - "", - "", - "", - "", - "", - "", - "" - ] - }, - "nbcplRating": { - "type": "string", - "description": "The video's rating in Poland.", - "enum": [ - "nbcpl18plus", - "nbcplI", - "nbcplIi", - "nbcplIii", - "nbcplIv", - "nbcplUnrated" - ], - "enumDescriptions": [ - "", - "", - "", - "", - "", - "" - ] - }, - "nfrcRating": { - "type": "string", - "description": "The video's rating from the Bulgarian National Film Center.", - "enum": [ - "nfrcA", - "nfrcB", - "nfrcC", - "nfrcD", - "nfrcUnrated", - "nfrcX" - ], - "enumDescriptions": [ - "", - "", - "", - "", - "", - "" - ] - }, - "nfvcbRating": { - "type": "string", - "description": "The video's rating from Nigeria's National Film and Video Censors Board.", - "enum": [ - "nfvcb12", - "nfvcb12a", - "nfvcb15", - "nfvcb18", - "nfvcbG", - "nfvcbPg", - "nfvcbRe", - "nfvcbUnrated" - ], - "enumDescriptions": [ - "", - "", - "", - "", - "", - "", - "", - "" - ] - }, - "nkclvRating": { - "type": "string", - "description": "The video's rating from the Nacionãlais Kino centrs (National Film Centre of Latvia).", - "enum": [ - "nkclv12plus", - "nkclv18plus", - "nkclv7plus", - "nkclvU", - "nkclvUnrated" - ], - "enumDescriptions": [ - "", - "", - "", - "", - "" - ] - }, - "oflcRating": { - "type": "string", - "description": "The video's Office of Film and Literature Classification (OFLC - New Zealand) rating.", - "enum": [ - "oflcG", - "oflcM", - "oflcPg", - "oflcR13", - "oflcR15", - "oflcR16", - "oflcR18", - "oflcRp13", - "oflcRp16", - "oflcUnrated" - ], - "enumDescriptions": [ - "", - "", - "", - "", - "", - "", - "", - "", - "", - "" - ] - }, - "pefilmRating": { - "type": "string", - "description": "The video's rating in Peru.", - "enum": [ - "pefilm14", - "pefilm18", - "pefilmPg", - "pefilmPt", - "pefilmUnrated" - ], - "enumDescriptions": [ - "", - "", - "", - "", - "" - ] - }, - "rcnofRating": { - "type": "string", - "description": "The video's rating from the Hungarian Nemzeti Filmiroda, the Rating Committee of the National Office of Film.", - "enum": [ - "rcnofI", - "rcnofIi", - "rcnofIii", - "rcnofIv", - "rcnofUnrated", - "rcnofV", - "rcnofVi" - ], - "enumDescriptions": [ - "", - "", - "", - "", - "", - "", - "" - ] - }, - "resorteviolenciaRating": { - "type": "string", - "description": "The video's rating in Venezuela.", - "enum": [ - "resorteviolenciaA", - "resorteviolenciaB", - "resorteviolenciaC", - "resorteviolenciaD", - "resorteviolenciaE", - "resorteviolenciaUnrated" - ], - "enumDescriptions": [ - "", - "", - "", - "", - "", - "" - ] - }, - "rtcRating": { - "type": "string", - "description": "The video's General Directorate of Radio, Television and Cinematography (Mexico) rating.", - "enum": [ - "rtcA", - "rtcAa", - "rtcB", - "rtcB15", - "rtcC", - "rtcD", - "rtcUnrated" - ], - "enumDescriptions": [ - "", - "", - "", - "", - "", - "", - "" - ] - }, - "rteRating": { - "type": "string", - "description": "The video's rating from Ireland's Raidió Teilifís Éireann.", - "enum": [ - "rteCh", - "rteGa", - "rteMa", - "rtePs", - "rteUnrated" - ], - "enumDescriptions": [ - "", - "", - "", - "", - "" - ] - }, - "russiaRating": { - "type": "string", - "description": "The video's National Film Registry of the Russian Federation (MKRF - Russia) rating.", - "enum": [ - "russia0", - "russia12", - "russia16", - "russia18", - "russia6", - "russiaUnrated" - ], - "enumDescriptions": [ - "", - "", - "", - "", - "", - "" - ] - }, - "skfilmRating": { - "type": "string", - "description": "The video's rating in Slovakia.", - "enum": [ - "skfilmG", - "skfilmP2", - "skfilmP5", - "skfilmP8", - "skfilmUnrated" - ], - "enumDescriptions": [ - "", - "", - "", - "", - "" - ] - }, - "smaisRating": { - "type": "string", - "description": "The video's rating in Iceland.", - "enum": [ - "smais12", - "smais14", - "smais16", - "smais18", - "smais7", - "smaisL", - "smaisUnrated" - ], - "enumDescriptions": [ - "", - "", - "", - "", - "", - "", - "" - ] - }, - "smsaRating": { - "type": "string", - "description": "The video's rating from Statens medieråd (Sweden's National Media Council).", - "enum": [ - "smsa11", - "smsa15", - "smsa7", - "smsaA", - "smsaUnrated" - ], - "enumDescriptions": [ - "", - "", - "", - "", - "" - ] - }, - "tvpgRating": { - "type": "string", - "description": "The video's TV Parental Guidelines (TVPG) rating.", - "enum": [ - "pg14", - "tvpgG", - "tvpgMa", - "tvpgPg", - "tvpgUnrated", - "tvpgY", - "tvpgY7", - "tvpgY7Fv" - ], - "enumDescriptions": [ - "", - "", - "", - "", - "", - "", - "", - "" - ] - }, - "ytRating": { - "type": "string", - "description": "A rating that YouTube uses to identify age-restricted content.", - "enum": [ - "ytAgeRestricted" - ], - "enumDescriptions": [ - "" - ] - } - } - }, - "FanFundingEvent": { - "id": "FanFundingEvent", - "type": "object", - "description": "A fanFundingEvent resource represents a fan funding event on a YouTube channel. Fan funding events occur when a user gives one-time monetary support to the channel owner.", - "properties": { - "etag": { - "type": "string", - "description": "Etag of this resource." - }, - "id": { - "type": "string", - "description": "The ID that YouTube assigns to uniquely identify the fan funding event." - }, - "kind": { - "type": "string", - "description": "Identifies what kind of resource this is. Value: the fixed string \"youtube#fanFundingEvent\".", - "default": "youtube#fanFundingEvent" - }, - "snippet": { - "$ref": "FanFundingEventSnippet", - "description": "The snippet object contains basic details about the fan funding event." - } - } - }, - "FanFundingEventListResponse": { - "id": "FanFundingEventListResponse", - "type": "object", - "properties": { - "etag": { - "type": "string", - "description": "Etag of this resource." - }, - "eventId": { - "type": "string", - "description": "Serialized EventId of the request which produced this response." - }, - "items": { - "type": "array", - "description": "A list of fan funding events that match the request criteria.", - "items": { - "$ref": "FanFundingEvent" - } - }, - "kind": { - "type": "string", - "description": "Identifies what kind of resource this is. Value: the fixed string \"youtube#fanFundingEventListResponse\".", - "default": "youtube#fanFundingEventListResponse" - }, - "nextPageToken": { - "type": "string", - "description": "The token that can be used as the value of the pageToken parameter to retrieve the next page in the result set." - }, - "pageInfo": { - "$ref": "PageInfo" - }, - "tokenPagination": { - "$ref": "TokenPagination" - }, - "visitorId": { - "type": "string", - "description": "The visitorId identifies the visitor." - } - } - }, - "FanFundingEventSnippet": { - "id": "FanFundingEventSnippet", - "type": "object", - "properties": { - "amountMicros": { - "type": "string", - "description": "The amount of funding in micros of fund_currency. e.g., 1 is represented", - "format": "uint64" - }, - "channelId": { - "type": "string", - "description": "Channel id where the funding event occurred." - }, - "commentText": { - "type": "string", - "description": "The text contents of the comment left by the user." - }, - "createdAt": { - "type": "string", - "description": "The date and time when the funding occurred. The value is specified in ISO 8601 (YYYY-MM-DDThh:mm:ss.sZ) format.", - "format": "date-time" - }, - "currency": { - "type": "string", - "description": "The currency in which the fund was made. ISO 4217." - }, - "displayString": { - "type": "string", - "description": "A rendered string that displays the fund amount and currency (e.g., \"$1.00\"). The string is rendered for the given language." - }, - "supporterDetails": { - "$ref": "ChannelProfileDetails", - "description": "Details about the supporter. Only filled if the event was made public by the user." - } - } - }, - "GeoPoint": { - "id": "GeoPoint", - "type": "object", - "description": "Geographical coordinates of a point, in WGS84.", - "properties": { - "altitude": { - "type": "number", - "description": "Altitude above the reference ellipsoid, in meters.", - "format": "double" - }, - "latitude": { - "type": "number", - "description": "Latitude in degrees.", - "format": "double" - }, - "longitude": { - "type": "number", - "description": "Longitude in degrees.", - "format": "double" - } - } - }, - "GuideCategory": { - "id": "GuideCategory", - "type": "object", - "description": "A guideCategory resource identifies a category that YouTube algorithmically assigns based on a channel's content or other indicators, such as the channel's popularity. The list is similar to video categories, with the difference being that a video's uploader can assign a video category but only YouTube can assign a channel category.", - "properties": { - "etag": { - "type": "string", - "description": "Etag of this resource." - }, - "id": { - "type": "string", - "description": "The ID that YouTube uses to uniquely identify the guide category." - }, - "kind": { - "type": "string", - "description": "Identifies what kind of resource this is. Value: the fixed string \"youtube#guideCategory\".", - "default": "youtube#guideCategory" - }, - "snippet": { - "$ref": "GuideCategorySnippet", - "description": "The snippet object contains basic details about the category, such as its title." - } - } - }, - "GuideCategoryListResponse": { - "id": "GuideCategoryListResponse", - "type": "object", - "properties": { - "etag": { - "type": "string", - "description": "Etag of this resource." - }, - "eventId": { - "type": "string", - "description": "Serialized EventId of the request which produced this response." - }, - "items": { - "type": "array", - "description": "A list of categories that can be associated with YouTube channels. In this map, the category ID is the map key, and its value is the corresponding guideCategory resource.", - "items": { - "$ref": "GuideCategory" - } - }, - "kind": { - "type": "string", - "description": "Identifies what kind of resource this is. Value: the fixed string \"youtube#guideCategoryListResponse\".", - "default": "youtube#guideCategoryListResponse" - }, - "nextPageToken": { - "type": "string", - "description": "The token that can be used as the value of the pageToken parameter to retrieve the next page in the result set." - }, - "pageInfo": { - "$ref": "PageInfo" - }, - "prevPageToken": { - "type": "string", - "description": "The token that can be used as the value of the pageToken parameter to retrieve the previous page in the result set." - }, - "tokenPagination": { - "$ref": "TokenPagination" - }, - "visitorId": { - "type": "string", - "description": "The visitorId identifies the visitor." - } - } - }, - "GuideCategorySnippet": { - "id": "GuideCategorySnippet", - "type": "object", - "description": "Basic details about a guide category.", - "properties": { - "channelId": { - "type": "string", - "default": "UCBR8-60-B28hp2BmDPdntcQ" - }, - "title": { - "type": "string", - "description": "Description of the guide category." - } - } - }, - "I18nLanguage": { - "id": "I18nLanguage", - "type": "object", - "description": "An i18nLanguage resource identifies a UI language currently supported by YouTube.", - "properties": { - "etag": { - "type": "string", - "description": "Etag of this resource." - }, - "id": { - "type": "string", - "description": "The ID that YouTube uses to uniquely identify the i18n language." - }, - "kind": { - "type": "string", - "description": "Identifies what kind of resource this is. Value: the fixed string \"youtube#i18nLanguage\".", - "default": "youtube#i18nLanguage" - }, - "snippet": { - "$ref": "I18nLanguageSnippet", - "description": "The snippet object contains basic details about the i18n language, such as language code and human-readable name." - } - } - }, - "I18nLanguageListResponse": { - "id": "I18nLanguageListResponse", - "type": "object", - "properties": { - "etag": { - "type": "string", - "description": "Etag of this resource." - }, - "eventId": { - "type": "string", - "description": "Serialized EventId of the request which produced this response." - }, - "items": { - "type": "array", - "description": "A list of supported i18n languages. In this map, the i18n language ID is the map key, and its value is the corresponding i18nLanguage resource.", - "items": { - "$ref": "I18nLanguage" - } - }, - "kind": { - "type": "string", - "description": "Identifies what kind of resource this is. Value: the fixed string \"youtube#i18nLanguageListResponse\".", - "default": "youtube#i18nLanguageListResponse" - }, - "visitorId": { - "type": "string", - "description": "The visitorId identifies the visitor." - } - } - }, - "I18nLanguageSnippet": { - "id": "I18nLanguageSnippet", - "type": "object", - "description": "Basic details about an i18n language, such as language code and human-readable name.", - "properties": { - "hl": { - "type": "string", - "description": "A short BCP-47 code that uniquely identifies a language." - }, - "name": { - "type": "string", - "description": "The human-readable name of the language in the language itself." - } - } - }, - "I18nRegion": { - "id": "I18nRegion", - "type": "object", - "description": "A i18nRegion resource identifies a region where YouTube is available.", - "properties": { - "etag": { - "type": "string", - "description": "Etag of this resource." - }, - "id": { - "type": "string", - "description": "The ID that YouTube uses to uniquely identify the i18n region." - }, - "kind": { - "type": "string", - "description": "Identifies what kind of resource this is. Value: the fixed string \"youtube#i18nRegion\".", - "default": "youtube#i18nRegion" - }, - "snippet": { - "$ref": "I18nRegionSnippet", - "description": "The snippet object contains basic details about the i18n region, such as region code and human-readable name." - } - } - }, - "I18nRegionListResponse": { - "id": "I18nRegionListResponse", - "type": "object", - "properties": { - "etag": { - "type": "string", - "description": "Etag of this resource." - }, - "eventId": { - "type": "string", - "description": "Serialized EventId of the request which produced this response." - }, - "items": { - "type": "array", - "description": "A list of regions where YouTube is available. In this map, the i18n region ID is the map key, and its value is the corresponding i18nRegion resource.", - "items": { - "$ref": "I18nRegion" - } - }, - "kind": { - "type": "string", - "description": "Identifies what kind of resource this is. Value: the fixed string \"youtube#i18nRegionListResponse\".", - "default": "youtube#i18nRegionListResponse" - }, - "visitorId": { - "type": "string", - "description": "The visitorId identifies the visitor." - } - } - }, - "I18nRegionSnippet": { - "id": "I18nRegionSnippet", - "type": "object", - "description": "Basic details about an i18n region, such as region code and human-readable name.", - "properties": { - "gl": { - "type": "string", - "description": "The region code as a 2-letter ISO country code." - }, - "name": { - "type": "string", - "description": "The human-readable name of the region." - } - } - }, - "ImageSettings": { - "id": "ImageSettings", - "type": "object", - "description": "Branding properties for images associated with the channel.", - "properties": { - "backgroundImageUrl": { - "$ref": "LocalizedProperty", - "description": "The URL for the background image shown on the video watch page. The image should be 1200px by 615px, with a maximum file size of 128k." - }, - "bannerExternalUrl": { - "type": "string", - "description": "This is used only in update requests; if it's set, we use this URL to generate all of the above banner URLs." - }, - "bannerImageUrl": { - "type": "string", - "description": "Banner image. Desktop size (1060x175)." - }, - "bannerMobileExtraHdImageUrl": { - "type": "string", - "description": "Banner image. Mobile size high resolution (1440x395)." - }, - "bannerMobileHdImageUrl": { - "type": "string", - "description": "Banner image. Mobile size high resolution (1280x360)." - }, - "bannerMobileImageUrl": { - "type": "string", - "description": "Banner image. Mobile size (640x175)." - }, - "bannerMobileLowImageUrl": { - "type": "string", - "description": "Banner image. Mobile size low resolution (320x88)." - }, - "bannerMobileMediumHdImageUrl": { - "type": "string", - "description": "Banner image. Mobile size medium/high resolution (960x263)." - }, - "bannerTabletExtraHdImageUrl": { - "type": "string", - "description": "Banner image. Tablet size extra high resolution (2560x424)." - }, - "bannerTabletHdImageUrl": { - "type": "string", - "description": "Banner image. Tablet size high resolution (2276x377)." - }, - "bannerTabletImageUrl": { - "type": "string", - "description": "Banner image. Tablet size (1707x283)." - }, - "bannerTabletLowImageUrl": { - "type": "string", - "description": "Banner image. Tablet size low resolution (1138x188)." - }, - "bannerTvHighImageUrl": { - "type": "string", - "description": "Banner image. TV size high resolution (1920x1080)." - }, - "bannerTvImageUrl": { - "type": "string", - "description": "Banner image. TV size extra high resolution (2120x1192)." - }, - "bannerTvLowImageUrl": { - "type": "string", - "description": "Banner image. TV size low resolution (854x480)." - }, - "bannerTvMediumImageUrl": { - "type": "string", - "description": "Banner image. TV size medium resolution (1280x720)." - }, - "largeBrandedBannerImageImapScript": { - "$ref": "LocalizedProperty", - "description": "The image map script for the large banner image." - }, - "largeBrandedBannerImageUrl": { - "$ref": "LocalizedProperty", - "description": "The URL for the 854px by 70px image that appears below the video player in the expanded video view of the video watch page." - }, - "smallBrandedBannerImageImapScript": { - "$ref": "LocalizedProperty", - "description": "The image map script for the small banner image." - }, - "smallBrandedBannerImageUrl": { - "$ref": "LocalizedProperty", - "description": "The URL for the 640px by 70px banner image that appears below the video player in the default view of the video watch page." - }, - "trackingImageUrl": { - "type": "string", - "description": "The URL for a 1px by 1px tracking pixel that can be used to collect statistics for views of the channel or video pages." - }, - "watchIconImageUrl": { - "type": "string", - "description": "The URL for the image that appears above the top-left corner of the video player. This is a 25-pixel-high image with a flexible width that cannot exceed 170 pixels." - } - } - }, - "IngestionInfo": { - "id": "IngestionInfo", - "type": "object", - "description": "Describes information necessary for ingesting an RTMP or an HTTP stream.", - "properties": { - "backupIngestionAddress": { - "type": "string", - "description": "The backup ingestion URL that you should use to stream video to YouTube. You have the option of simultaneously streaming the content that you are sending to the ingestionAddress to this URL." - }, - "ingestionAddress": { - "type": "string", - "description": "The primary ingestion URL that you should use to stream video to YouTube. You must stream video to this URL.\n\nDepending on which application or tool you use to encode your video stream, you may need to enter the stream URL and stream name separately or you may need to concatenate them in the following format:\n\nSTREAM_URL/STREAM_NAME" - }, - "streamName": { - "type": "string", - "description": "The HTTP or RTMP stream name that YouTube assigns to the video stream." - } - } - }, - "InvideoBranding": { - "id": "InvideoBranding", - "type": "object", - "properties": { - "imageBytes": { - "type": "string", - "format": "byte" - }, - "imageUrl": { - "type": "string" - }, - "position": { - "$ref": "InvideoPosition" - }, - "targetChannelId": { - "type": "string" - }, - "timing": { - "$ref": "InvideoTiming" - } - } - }, - "InvideoPosition": { - "id": "InvideoPosition", - "type": "object", - "description": "Describes the spatial position of a visual widget inside a video. It is a union of various position types, out of which only will be set one.", - "properties": { - "cornerPosition": { - "type": "string", - "description": "Describes in which corner of the video the visual widget will appear.", - "enum": [ - "bottomLeft", - "bottomRight", - "topLeft", - "topRight" - ], - "enumDescriptions": [ - "", - "", - "", - "" - ] - }, - "type": { - "type": "string", - "description": "Defines the position type.", - "enum": [ - "corner" - ], - "enumDescriptions": [ - "" - ] - } - } - }, - "InvideoPromotion": { - "id": "InvideoPromotion", - "type": "object", - "description": "Describes an invideo promotion campaign consisting of multiple promoted items. A campaign belongs to a single channel_id.", - "properties": { - "defaultTiming": { - "$ref": "InvideoTiming", - "description": "The default temporal position within the video where the promoted item will be displayed. Can be overriden by more specific timing in the item." - }, - "items": { - "type": "array", - "description": "List of promoted items in decreasing priority.", - "items": { - "$ref": "PromotedItem" - } - }, - "position": { - "$ref": "InvideoPosition", - "description": "The spatial position within the video where the promoted item will be displayed." - }, - "useSmartTiming": { - "type": "boolean", - "description": "Indicates whether the channel's promotional campaign uses \"smart timing.\" This feature attempts to show promotions at a point in the video when they are more likely to be clicked and less likely to disrupt the viewing experience. This feature also picks up a single promotion to show on each video." - } - } - }, - "InvideoTiming": { - "id": "InvideoTiming", - "type": "object", - "description": "Describes a temporal position of a visual widget inside a video.", - "properties": { - "durationMs": { - "type": "string", - "description": "Defines the duration in milliseconds for which the promotion should be displayed. If missing, the client should use the default.", - "format": "uint64" - }, - "offsetMs": { - "type": "string", - "description": "Defines the time at which the promotion will appear. Depending on the value of type the value of the offsetMs field will represent a time offset from the start or from the end of the video, expressed in milliseconds.", - "format": "uint64" - }, - "type": { - "type": "string", - "description": "Describes a timing type. If the value is offsetFromStart, then the offsetMs field represents an offset from the start of the video. If the value is offsetFromEnd, then the offsetMs field represents an offset from the end of the video.", - "enum": [ - "offsetFromEnd", - "offsetFromStart" - ], - "enumDescriptions": [ - "", - "" - ] - } - } - }, - "LanguageTag": { - "id": "LanguageTag", - "type": "object", - "properties": { - "value": { - "type": "string" - } - } - }, - "LiveBroadcast": { - "id": "LiveBroadcast", - "type": "object", - "description": "A liveBroadcast resource represents an event that will be streamed, via live video, on YouTube.", - "properties": { - "contentDetails": { - "$ref": "LiveBroadcastContentDetails", - "description": "The contentDetails object contains information about the event's video content, such as whether the content can be shown in an embedded video player or if it will be archived and therefore available for viewing after the event has concluded." - }, - "etag": { - "type": "string", - "description": "Etag of this resource." - }, - "id": { - "type": "string", - "description": "The ID that YouTube assigns to uniquely identify the broadcast.", - "annotations": { - "required": [ - "youtube.liveBroadcasts.update" - ] - } - }, - "kind": { - "type": "string", - "description": "Identifies what kind of resource this is. Value: the fixed string \"youtube#liveBroadcast\".", - "default": "youtube#liveBroadcast" - }, - "snippet": { - "$ref": "LiveBroadcastSnippet", - "description": "The snippet object contains basic details about the event, including its title, description, start time, and end time." - }, - "statistics": { - "$ref": "LiveBroadcastStatistics", - "description": "The statistics object contains info about the event's current stats. These include concurrent viewers and total chat count. Statistics can change (in either direction) during the lifetime of an event. Statistics are only returned while the event is live." - }, - "status": { - "$ref": "LiveBroadcastStatus", - "description": "The status object contains information about the event's status." - }, - "topicDetails": { - "$ref": "LiveBroadcastTopicDetails" - } - } - }, - "LiveBroadcastContentDetails": { - "id": "LiveBroadcastContentDetails", - "type": "object", - "description": "Detailed settings of a broadcast.", - "properties": { - "boundStreamId": { - "type": "string", - "description": "This value uniquely identifies the live stream bound to the broadcast." - }, - "boundStreamLastUpdateTimeMs": { - "type": "string", - "description": "The date and time that the live stream referenced by boundStreamId was last updated.", - "format": "date-time" - }, - "closedCaptionsType": { - "type": "string", - "enum": [ - "closedCaptionsDisabled", - "closedCaptionsEmbedded", - "closedCaptionsHttpPost" - ], - "enumDescriptions": [ - "", - "", - "" - ] - }, - "enableClosedCaptions": { - "type": "boolean", - "description": "This setting indicates whether HTTP POST closed captioning is enabled for this broadcast. The ingestion URL of the closed captions is returned through the liveStreams API. This is mutually exclusive with using the closed_captions_type property, and is equivalent to setting closed_captions_type to CLOSED_CAPTIONS_HTTP_POST." - }, - "enableContentEncryption": { - "type": "boolean", - "description": "This setting indicates whether YouTube should enable content encryption for the broadcast.", - "annotations": { - "required": [ - "youtube.liveBroadcasts.update" - ] - } - }, - "enableDvr": { - "type": "boolean", - "description": "This setting determines whether viewers can access DVR controls while watching the video. DVR controls enable the viewer to control the video playback experience by pausing, rewinding, or fast forwarding content. The default value for this property is true.\n\n\n\nImportant: You must set the value to true and also set the enableArchive property's value to true if you want to make playback available immediately after the broadcast ends.", - "annotations": { - "required": [ - "youtube.liveBroadcasts.update" - ] - } - }, - "enableEmbed": { - "type": "boolean", - "description": "This setting indicates whether the broadcast video can be played in an embedded player. If you choose to archive the video (using the enableArchive property), this setting will also apply to the archived video.", - "annotations": { - "required": [ - "youtube.liveBroadcasts.update" - ] - } - }, - "enableLowLatency": { - "type": "boolean", - "description": "Indicates whether this broadcast has low latency enabled." - }, - "monitorStream": { - "$ref": "MonitorStreamInfo", - "description": "The monitorStream object contains information about the monitor stream, which the broadcaster can use to review the event content before the broadcast stream is shown publicly." - }, - "projection": { - "type": "string", - "description": "The projection format of this broadcast. This defaults to rectangular.", - "enum": [ - "360", - "rectangular" - ], - "enumDescriptions": [ - "", - "" - ] - }, - "recordFromStart": { - "type": "boolean", - "description": "Automatically start recording after the event goes live. The default value for this property is true.\n\n\n\nImportant: You must also set the enableDvr property's value to true if you want the playback to be available immediately after the broadcast ends. If you set this property's value to true but do not also set the enableDvr property to true, there may be a delay of around one day before the archived video will be available for playback.", - "annotations": { - "required": [ - "youtube.liveBroadcasts.update" - ] - } - }, - "startWithSlate": { - "type": "boolean", - "description": "This setting indicates whether the broadcast should automatically begin with an in-stream slate when you update the broadcast's status to live. After updating the status, you then need to send a liveCuepoints.insert request that sets the cuepoint's eventState to end to remove the in-stream slate and make your broadcast stream visible to viewers.", - "annotations": { - "required": [ - "youtube.liveBroadcasts.update" - ] - } - } - } - }, - "LiveBroadcastListResponse": { - "id": "LiveBroadcastListResponse", - "type": "object", - "properties": { - "etag": { - "type": "string", - "description": "Etag of this resource." - }, - "eventId": { - "type": "string", - "description": "Serialized EventId of the request which produced this response." - }, - "items": { - "type": "array", - "description": "A list of broadcasts that match the request criteria.", - "items": { - "$ref": "LiveBroadcast" - } - }, - "kind": { - "type": "string", - "description": "Identifies what kind of resource this is. Value: the fixed string \"youtube#liveBroadcastListResponse\".", - "default": "youtube#liveBroadcastListResponse" - }, - "nextPageToken": { - "type": "string", - "description": "The token that can be used as the value of the pageToken parameter to retrieve the next page in the result set." - }, - "pageInfo": { - "$ref": "PageInfo" - }, - "prevPageToken": { - "type": "string", - "description": "The token that can be used as the value of the pageToken parameter to retrieve the previous page in the result set." - }, - "tokenPagination": { - "$ref": "TokenPagination" - }, - "visitorId": { - "type": "string", - "description": "The visitorId identifies the visitor." - } - } - }, - "LiveBroadcastSnippet": { - "id": "LiveBroadcastSnippet", - "type": "object", - "properties": { - "actualEndTime": { - "type": "string", - "description": "The date and time that the broadcast actually ended. This information is only available once the broadcast's state is complete. The value is specified in ISO 8601 (YYYY-MM-DDThh:mm:ss.sZ) format.", - "format": "date-time" - }, - "actualStartTime": { - "type": "string", - "description": "The date and time that the broadcast actually started. This information is only available once the broadcast's state is live. The value is specified in ISO 8601 (YYYY-MM-DDThh:mm:ss.sZ) format.", - "format": "date-time" - }, - "channelId": { - "type": "string", - "description": "The ID that YouTube uses to uniquely identify the channel that is publishing the broadcast." - }, - "description": { - "type": "string", - "description": "The broadcast's description. As with the title, you can set this field by modifying the broadcast resource or by setting the description field of the corresponding video resource." - }, - "isDefaultBroadcast": { - "type": "boolean" - }, - "liveChatId": { - "type": "string", - "description": "The id of the live chat for this broadcast." - }, - "publishedAt": { - "type": "string", - "description": "The date and time that the broadcast was added to YouTube's live broadcast schedule. The value is specified in ISO 8601 (YYYY-MM-DDThh:mm:ss.sZ) format.", - "format": "date-time" - }, - "scheduledEndTime": { - "type": "string", - "description": "The date and time that the broadcast is scheduled to end. The value is specified in ISO 8601 (YYYY-MM-DDThh:mm:ss.sZ) format.", - "format": "date-time" - }, - "scheduledStartTime": { - "type": "string", - "description": "The date and time that the broadcast is scheduled to start. The value is specified in ISO 8601 (YYYY-MM-DDThh:mm:ss.sZ) format.", - "format": "date-time", - "annotations": { - "required": [ - "youtube.liveBroadcasts.insert", - "youtube.liveBroadcasts.update" - ] - } - }, - "thumbnails": { - "$ref": "ThumbnailDetails", - "description": "A map of thumbnail images associated with the broadcast. For each nested object in this object, the key is the name of the thumbnail image, and the value is an object that contains other information about the thumbnail." - }, - "title": { - "type": "string", - "description": "The broadcast's title. Note that the broadcast represents exactly one YouTube video. You can set this field by modifying the broadcast resource or by setting the title field of the corresponding video resource.", - "annotations": { - "required": [ - "youtube.liveBroadcasts.insert", - "youtube.liveBroadcasts.update" - ] - } - } - } - }, - "LiveBroadcastStatistics": { - "id": "LiveBroadcastStatistics", - "type": "object", - "description": "Statistics about the live broadcast. These represent a snapshot of the values at the time of the request. Statistics are only returned for live broadcasts.", - "properties": { - "concurrentViewers": { - "type": "string", - "description": "The number of viewers currently watching the broadcast. The property and its value will be present if the broadcast has current viewers and the broadcast owner has not hidden the viewcount for the video. Note that YouTube stops tracking the number of concurrent viewers for a broadcast when the broadcast ends. So, this property would not identify the number of viewers watching an archived video of a live broadcast that already ended.", - "format": "uint64" - }, - "totalChatCount": { - "type": "string", - "description": "The total number of live chat messages currently on the broadcast. The property and its value will be present if the broadcast is public, has the live chat feature enabled, and has at least one message. Note that this field will not be filled after the broadcast ends. So this property would not identify the number of chat messages for an archived video of a completed live broadcast.", - "format": "uint64" - } - } - }, - "LiveBroadcastStatus": { - "id": "LiveBroadcastStatus", - "type": "object", - "properties": { - "lifeCycleStatus": { - "type": "string", - "description": "The broadcast's status. The status can be updated using the API's liveBroadcasts.transition method.", - "enum": [ - "abandoned", - "complete", - "completeStarting", - "created", - "live", - "liveStarting", - "ready", - "reclaimed", - "revoked", - "testStarting", - "testing" - ], - "enumDescriptions": [ - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "" - ] - }, - "liveBroadcastPriority": { - "type": "string", - "description": "Priority of the live broadcast event (internal state).", - "enum": [ - "high", - "low", - "normal" - ], - "enumDescriptions": [ - "", - "", - "" - ] - }, - "privacyStatus": { - "type": "string", - "description": "The broadcast's privacy status. Note that the broadcast represents exactly one YouTube video, so the privacy settings are identical to those supported for videos. In addition, you can set this field by modifying the broadcast resource or by setting the privacyStatus field of the corresponding video resource.", - "enum": [ - "private", - "public", - "unlisted" - ], - "enumDescriptions": [ - "", - "", - "" - ], - "annotations": { - "required": [ - "youtube.liveBroadcasts.insert", - "youtube.liveBroadcasts.update" - ] - } - }, - "recordingStatus": { - "type": "string", - "description": "The broadcast's recording status.", - "enum": [ - "notRecording", - "recorded", - "recording" - ], - "enumDescriptions": [ - "", - "", - "" - ] - } - } - }, - "LiveBroadcastTopic": { - "id": "LiveBroadcastTopic", - "type": "object", - "properties": { - "snippet": { - "$ref": "LiveBroadcastTopicSnippet", - "description": "Information about the topic matched." - }, - "type": { - "type": "string", - "description": "The type of the topic.", - "enum": [ - "videoGame" - ], - "enumDescriptions": [ - "" - ] - }, - "unmatched": { - "type": "boolean", - "description": "If this flag is set it means that we have not been able to match the topic title and type provided to a known entity." - } - } - }, - "LiveBroadcastTopicDetails": { - "id": "LiveBroadcastTopicDetails", - "type": "object", - "properties": { - "topics": { - "type": "array", - "items": { - "$ref": "LiveBroadcastTopic" - } - } - } - }, - "LiveBroadcastTopicSnippet": { - "id": "LiveBroadcastTopicSnippet", - "type": "object", - "properties": { - "name": { - "type": "string", - "description": "The name of the topic." - }, - "releaseDate": { - "type": "string", - "description": "The date at which the topic was released. Filled for types: videoGame" - } - } - }, - "LiveChatBan": { - "id": "LiveChatBan", - "type": "object", - "description": "A liveChatBan resource represents a ban for a YouTube live chat.", - "properties": { - "etag": { - "type": "string", - "description": "Etag of this resource." - }, - "id": { - "type": "string", - "description": "The ID that YouTube assigns to uniquely identify the ban." - }, - "kind": { - "type": "string", - "description": "Identifies what kind of resource this is. Value: the fixed string \"youtube#liveChatBan\".", - "default": "youtube#liveChatBan" - }, - "snippet": { - "$ref": "LiveChatBanSnippet", - "description": "The snippet object contains basic details about the ban." - } - } - }, - "LiveChatBanSnippet": { - "id": "LiveChatBanSnippet", - "type": "object", - "properties": { - "banDurationSeconds": { - "type": "string", - "description": "The duration of a ban, only filled if the ban has type TEMPORARY.", - "format": "uint64" - }, - "bannedUserDetails": { - "$ref": "ChannelProfileDetails" - }, - "liveChatId": { - "type": "string", - "description": "The chat this ban is pertinent to." - }, - "type": { - "type": "string", - "description": "The type of ban.", - "enum": [ - "permanent", - "temporary" - ], - "enumDescriptions": [ - "", - "" - ] - } - } - }, - "LiveChatFanFundingEventDetails": { - "id": "LiveChatFanFundingEventDetails", - "type": "object", - "properties": { - "amountDisplayString": { - "type": "string", - "description": "A rendered string that displays the fund amount and currency to the user." - }, - "amountMicros": { - "type": "string", - "description": "The amount of the fund.", - "format": "uint64" - }, - "currency": { - "type": "string", - "description": "The currency in which the fund was made." - }, - "userComment": { - "type": "string", - "description": "The comment added by the user to this fan funding event." - } - } - }, - "LiveChatMessage": { - "id": "LiveChatMessage", - "type": "object", - "description": "A liveChatMessage resource represents a chat message in a YouTube Live Chat.", - "properties": { - "authorDetails": { - "$ref": "LiveChatMessageAuthorDetails", - "description": "The authorDetails object contains basic details about the user that posted this message." - }, - "etag": { - "type": "string", - "description": "Etag of this resource." - }, - "id": { - "type": "string", - "description": "The ID that YouTube assigns to uniquely identify the message." - }, - "kind": { - "type": "string", - "description": "Identifies what kind of resource this is. Value: the fixed string \"youtube#liveChatMessage\".", - "default": "youtube#liveChatMessage" - }, - "snippet": { - "$ref": "LiveChatMessageSnippet", - "description": "The snippet object contains basic details about the message." - } - } - }, - "LiveChatMessageAuthorDetails": { - "id": "LiveChatMessageAuthorDetails", - "type": "object", - "properties": { - "channelId": { - "type": "string", - "description": "The YouTube channel ID." - }, - "channelUrl": { - "type": "string", - "description": "The channel's URL." - }, - "displayName": { - "type": "string", - "description": "The channel's display name." - }, - "isChatModerator": { - "type": "boolean", - "description": "Whether the author is a moderator of the live chat." - }, - "isChatOwner": { - "type": "boolean", - "description": "Whether the author is the owner of the live chat." - }, - "isChatSponsor": { - "type": "boolean", - "description": "Whether the author is a sponsor of the live chat." - }, - "isVerified": { - "type": "boolean", - "description": "Whether the author's identity has been verified by YouTube." - }, - "profileImageUrl": { - "type": "string", - "description": "The channels's avatar URL." - } - } - }, - "LiveChatMessageDeletedDetails": { - "id": "LiveChatMessageDeletedDetails", - "type": "object", - "properties": { - "deletedMessageId": { - "type": "string" - } - } - }, - "LiveChatMessageListResponse": { - "id": "LiveChatMessageListResponse", - "type": "object", - "properties": { - "etag": { - "type": "string", - "description": "Etag of this resource." - }, - "eventId": { - "type": "string", - "description": "Serialized EventId of the request which produced this response." - }, - "items": { - "type": "array", - "description": "A list of live chat messages.", - "items": { - "$ref": "LiveChatMessage" - } - }, - "kind": { - "type": "string", - "description": "Identifies what kind of resource this is. Value: the fixed string \"youtube#liveChatMessageListResponse\".", - "default": "youtube#liveChatMessageListResponse" - }, - "nextPageToken": { - "type": "string", - "description": "The token that can be used as the value of the pageToken parameter to retrieve the next page in the result set." - }, - "offlineAt": { - "type": "string", - "description": "The date and time when the underlying stream went offline. The value is specified in ISO 8601 (YYYY-MM-DDThh:mm:ss.sZ) format.", - "format": "date-time" - }, - "pageInfo": { - "$ref": "PageInfo" - }, - "pollingIntervalMillis": { - "type": "integer", - "description": "The amount of time the client should wait before polling again.", - "format": "uint32" - }, - "tokenPagination": { - "$ref": "TokenPagination" - }, - "visitorId": { - "type": "string", - "description": "The visitorId identifies the visitor." - } - } - }, - "LiveChatMessageRetractedDetails": { - "id": "LiveChatMessageRetractedDetails", - "type": "object", - "properties": { - "retractedMessageId": { - "type": "string" - } - } - }, - "LiveChatMessageSnippet": { - "id": "LiveChatMessageSnippet", - "type": "object", - "properties": { - "authorChannelId": { - "type": "string", - "description": "The ID of the user that authored this message, this field is not always filled. textMessageEvent - the user that wrote the message fanFundingEvent - the user that funded the broadcast newSponsorEvent - the user that just became a sponsor messageDeletedEvent - the moderator that took the action messageRetractedEvent - the author that retracted their message userBannedEvent - the moderator that took the action superChatEvent - the user that made the purchase" - }, - "displayMessage": { - "type": "string", - "description": "Contains a string that can be displayed to the user. If this field is not present the message is silent, at the moment only messages of type TOMBSTONE and CHAT_ENDED_EVENT are silent." - }, - "fanFundingEventDetails": { - "$ref": "LiveChatFanFundingEventDetails", - "description": "Details about the funding event, this is only set if the type is 'fanFundingEvent'." - }, - "hasDisplayContent": { - "type": "boolean", - "description": "Whether the message has display content that should be displayed to users." - }, - "liveChatId": { - "type": "string" - }, - "messageDeletedDetails": { - "$ref": "LiveChatMessageDeletedDetails" - }, - "messageRetractedDetails": { - "$ref": "LiveChatMessageRetractedDetails" - }, - "pollClosedDetails": { - "$ref": "LiveChatPollClosedDetails" - }, - "pollEditedDetails": { - "$ref": "LiveChatPollEditedDetails" - }, - "pollOpenedDetails": { - "$ref": "LiveChatPollOpenedDetails" - }, - "pollVotedDetails": { - "$ref": "LiveChatPollVotedDetails" - }, - "publishedAt": { - "type": "string", - "description": "The date and time when the message was orignally published. The value is specified in ISO 8601 (YYYY-MM-DDThh:mm:ss.sZ) format.", - "format": "date-time" - }, - "superChatDetails": { - "$ref": "LiveChatSuperChatDetails", - "description": "Details about the Super Chat event, this is only set if the type is 'superChatEvent'." - }, - "textMessageDetails": { - "$ref": "LiveChatTextMessageDetails", - "description": "Details about the text message, this is only set if the type is 'textMessageEvent'." - }, - "type": { - "type": "string", - "description": "The type of message, this will always be present, it determines the contents of the message as well as which fields will be present.", - "enum": [ - "chatEndedEvent", - "fanFundingEvent", - "messageDeletedEvent", - "messageRetractedEvent", - "newSponsorEvent", - "pollClosedEvent", - "pollEditedEvent", - "pollOpenedEvent", - "pollVotedEvent", - "sponsorOnlyModeEndedEvent", - "sponsorOnlyModeStartedEvent", - "superChatEvent", - "textMessageEvent", - "tombstone", - "userBannedEvent" - ], - "enumDescriptions": [ - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "" - ] - }, - "userBannedDetails": { - "$ref": "LiveChatUserBannedMessageDetails" - } - } - }, - "LiveChatModerator": { - "id": "LiveChatModerator", - "type": "object", - "description": "A liveChatModerator resource represents a moderator for a YouTube live chat. A chat moderator has the ability to ban/unban users from a chat, remove message, etc.", - "properties": { - "etag": { - "type": "string", - "description": "Etag of this resource." - }, - "id": { - "type": "string", - "description": "The ID that YouTube assigns to uniquely identify the moderator." - }, - "kind": { - "type": "string", - "description": "Identifies what kind of resource this is. Value: the fixed string \"youtube#liveChatModerator\".", - "default": "youtube#liveChatModerator" - }, - "snippet": { - "$ref": "LiveChatModeratorSnippet", - "description": "The snippet object contains basic details about the moderator." - } - } - }, - "LiveChatModeratorListResponse": { - "id": "LiveChatModeratorListResponse", - "type": "object", - "properties": { - "etag": { - "type": "string", - "description": "Etag of this resource." - }, - "eventId": { - "type": "string", - "description": "Serialized EventId of the request which produced this response." - }, - "items": { - "type": "array", - "description": "A list of moderators that match the request criteria.", - "items": { - "$ref": "LiveChatModerator" - } - }, - "kind": { - "type": "string", - "description": "Identifies what kind of resource this is. Value: the fixed string \"youtube#liveChatModeratorListResponse\".", - "default": "youtube#liveChatModeratorListResponse" - }, - "nextPageToken": { - "type": "string", - "description": "The token that can be used as the value of the pageToken parameter to retrieve the next page in the result set." - }, - "pageInfo": { - "$ref": "PageInfo" - }, - "prevPageToken": { - "type": "string", - "description": "The token that can be used as the value of the pageToken parameter to retrieve the previous page in the result set." - }, - "tokenPagination": { - "$ref": "TokenPagination" - }, - "visitorId": { - "type": "string", - "description": "The visitorId identifies the visitor." - } - } - }, - "LiveChatModeratorSnippet": { - "id": "LiveChatModeratorSnippet", - "type": "object", - "properties": { - "liveChatId": { - "type": "string", - "description": "The ID of the live chat this moderator can act on." - }, - "moderatorDetails": { - "$ref": "ChannelProfileDetails", - "description": "Details about the moderator." - } - } - }, - "LiveChatPollClosedDetails": { - "id": "LiveChatPollClosedDetails", - "type": "object", - "properties": { - "pollId": { - "type": "string", - "description": "The id of the poll that was closed." - } - } - }, - "LiveChatPollEditedDetails": { - "id": "LiveChatPollEditedDetails", - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "items": { - "type": "array", - "items": { - "$ref": "LiveChatPollItem" - } - }, - "prompt": { - "type": "string" - } - } - }, - "LiveChatPollItem": { - "id": "LiveChatPollItem", - "type": "object", - "properties": { - "description": { - "type": "string", - "description": "Plain text description of the item." - }, - "itemId": { - "type": "string" - } - } - }, - "LiveChatPollOpenedDetails": { - "id": "LiveChatPollOpenedDetails", - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "items": { - "type": "array", - "items": { - "$ref": "LiveChatPollItem" - } - }, - "prompt": { - "type": "string" - } - } - }, - "LiveChatPollVotedDetails": { - "id": "LiveChatPollVotedDetails", - "type": "object", - "properties": { - "itemId": { - "type": "string", - "description": "The poll item the user chose." - }, - "pollId": { - "type": "string", - "description": "The poll the user voted on." - } - } - }, - "LiveChatSuperChatDetails": { - "id": "LiveChatSuperChatDetails", - "type": "object", - "properties": { - "amountDisplayString": { - "type": "string", - "description": "A rendered string that displays the fund amount and currency to the user." - }, - "amountMicros": { - "type": "string", - "description": "The amount purchased by the user, in micros (1,750,000 micros = 1.75).", - "format": "uint64" - }, - "currency": { - "type": "string", - "description": "The currency in which the purchase was made." - }, - "tier": { - "type": "integer", - "description": "The tier in which the amount belongs to. Lower amounts belong to lower tiers. Starts at 1.", - "format": "uint32" - }, - "userComment": { - "type": "string", - "description": "The comment added by the user to this Super Chat event." - } - } - }, - "LiveChatTextMessageDetails": { - "id": "LiveChatTextMessageDetails", - "type": "object", - "properties": { - "messageText": { - "type": "string", - "description": "The user's message." - } - } - }, - "LiveChatUserBannedMessageDetails": { - "id": "LiveChatUserBannedMessageDetails", - "type": "object", - "properties": { - "banDurationSeconds": { - "type": "string", - "description": "The duration of the ban. This property is only present if the banType is temporary.", - "format": "uint64" - }, - "banType": { - "type": "string", - "description": "The type of ban.", - "enum": [ - "permanent", - "temporary" - ], - "enumDescriptions": [ - "", - "" - ] - }, - "bannedUserDetails": { - "$ref": "ChannelProfileDetails", - "description": "The details of the user that was banned." - } - } - }, - "LiveStream": { - "id": "LiveStream", - "type": "object", - "description": "A live stream describes a live ingestion point.", - "properties": { - "cdn": { - "$ref": "CdnSettings", - "description": "The cdn object defines the live stream's content delivery network (CDN) settings. These settings provide details about the manner in which you stream your content to YouTube." - }, - "contentDetails": { - "$ref": "LiveStreamContentDetails", - "description": "The content_details object contains information about the stream, including the closed captions ingestion URL." - }, - "etag": { - "type": "string", - "description": "Etag of this resource." - }, - "id": { - "type": "string", - "description": "The ID that YouTube assigns to uniquely identify the stream.", - "annotations": { - "required": [ - "youtube.liveStreams.update" - ] - } - }, - "kind": { - "type": "string", - "description": "Identifies what kind of resource this is. Value: the fixed string \"youtube#liveStream\".", - "default": "youtube#liveStream" - }, - "snippet": { - "$ref": "LiveStreamSnippet", - "description": "The snippet object contains basic details about the stream, including its channel, title, and description." - }, - "status": { - "$ref": "LiveStreamStatus", - "description": "The status object contains information about live stream's status." - } - } - }, - "LiveStreamConfigurationIssue": { - "id": "LiveStreamConfigurationIssue", - "type": "object", - "properties": { - "description": { - "type": "string", - "description": "The long-form description of the issue and how to resolve it." - }, - "reason": { - "type": "string", - "description": "The short-form reason for this issue." - }, - "severity": { - "type": "string", - "description": "How severe this issue is to the stream.", - "enum": [ - "error", - "info", - "warning" - ], - "enumDescriptions": [ - "", - "", - "" - ] - }, - "type": { - "type": "string", - "description": "The kind of error happening.", - "enum": [ - "audioBitrateHigh", - "audioBitrateLow", - "audioBitrateMismatch", - "audioCodec", - "audioCodecMismatch", - "audioSampleRate", - "audioSampleRateMismatch", - "audioStereoMismatch", - "audioTooManyChannels", - "badContainer", - "bitrateHigh", - "bitrateLow", - "frameRateHigh", - "framerateMismatch", - "gopMismatch", - "gopSizeLong", - "gopSizeOver", - "gopSizeShort", - "interlacedVideo", - "multipleAudioStreams", - "multipleVideoStreams", - "noAudioStream", - "noVideoStream", - "openGop", - "resolutionMismatch", - "videoBitrateMismatch", - "videoCodec", - "videoCodecMismatch", - "videoIngestionStarved", - "videoInterlaceMismatch", - "videoProfileMismatch", - "videoResolutionSuboptimal", - "videoResolutionUnsupported" - ], - "enumDescriptions": [ - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "" - ] - } - } - }, - "LiveStreamContentDetails": { - "id": "LiveStreamContentDetails", - "type": "object", - "description": "Detailed settings of a stream.", - "properties": { - "closedCaptionsIngestionUrl": { - "type": "string", - "description": "The ingestion URL where the closed captions of this stream are sent." - }, - "isReusable": { - "type": "boolean", - "description": "Indicates whether the stream is reusable, which means that it can be bound to multiple broadcasts. It is common for broadcasters to reuse the same stream for many different broadcasts if those broadcasts occur at different times.\n\nIf you set this value to false, then the stream will not be reusable, which means that it can only be bound to one broadcast. Non-reusable streams differ from reusable streams in the following ways: \n- A non-reusable stream can only be bound to one broadcast. \n- A non-reusable stream might be deleted by an automated process after the broadcast ends. \n- The liveStreams.list method does not list non-reusable streams if you call the method and set the mine parameter to true. The only way to use that method to retrieve the resource for a non-reusable stream is to use the id parameter to identify the stream." - } - } - }, - "LiveStreamHealthStatus": { - "id": "LiveStreamHealthStatus", - "type": "object", - "properties": { - "configurationIssues": { - "type": "array", - "description": "The configurations issues on this stream", - "items": { - "$ref": "LiveStreamConfigurationIssue" - } - }, - "lastUpdateTimeSeconds": { - "type": "string", - "description": "The last time this status was updated (in seconds)", - "format": "uint64" - }, - "status": { - "type": "string", - "description": "The status code of this stream", - "enum": [ - "bad", - "good", - "noData", - "ok", - "revoked" - ], - "enumDescriptions": [ - "", - "", - "", - "", - "" - ] - } - } - }, - "LiveStreamListResponse": { - "id": "LiveStreamListResponse", - "type": "object", - "properties": { - "etag": { - "type": "string", - "description": "Etag of this resource." - }, - "eventId": { - "type": "string", - "description": "Serialized EventId of the request which produced this response." - }, - "items": { - "type": "array", - "description": "A list of live streams that match the request criteria.", - "items": { - "$ref": "LiveStream" - } - }, - "kind": { - "type": "string", - "description": "Identifies what kind of resource this is. Value: the fixed string \"youtube#liveStreamListResponse\".", - "default": "youtube#liveStreamListResponse" - }, - "nextPageToken": { - "type": "string", - "description": "The token that can be used as the value of the pageToken parameter to retrieve the next page in the result set." - }, - "pageInfo": { - "$ref": "PageInfo" - }, - "prevPageToken": { - "type": "string", - "description": "The token that can be used as the value of the pageToken parameter to retrieve the previous page in the result set." - }, - "tokenPagination": { - "$ref": "TokenPagination" - }, - "visitorId": { - "type": "string", - "description": "The visitorId identifies the visitor." - } - } - }, - "LiveStreamSnippet": { - "id": "LiveStreamSnippet", - "type": "object", - "properties": { - "channelId": { - "type": "string", - "description": "The ID that YouTube uses to uniquely identify the channel that is transmitting the stream." - }, - "description": { - "type": "string", - "description": "The stream's description. The value cannot be longer than 10000 characters." - }, - "isDefaultStream": { - "type": "boolean" - }, - "publishedAt": { - "type": "string", - "description": "The date and time that the stream was created. The value is specified in ISO 8601 (YYYY-MM-DDThh:mm:ss.sZ) format.", - "format": "date-time" - }, - "title": { - "type": "string", - "description": "The stream's title. The value must be between 1 and 128 characters long.", - "annotations": { - "required": [ - "youtube.liveStreams.insert", - "youtube.liveStreams.update" - ] - } - } - } - }, - "LiveStreamStatus": { - "id": "LiveStreamStatus", - "type": "object", - "description": "Brief description of the live stream status.", - "properties": { - "healthStatus": { - "$ref": "LiveStreamHealthStatus", - "description": "The health status of the stream." - }, - "streamStatus": { - "type": "string", - "enum": [ - "active", - "created", - "error", - "inactive", - "ready" - ], - "enumDescriptions": [ - "", - "", - "", - "", - "" - ] - } - } - }, - "LocalizedProperty": { - "id": "LocalizedProperty", - "type": "object", - "properties": { - "default": { - "type": "string" - }, - "defaultLanguage": { - "$ref": "LanguageTag", - "description": "The language of the default property." - }, - "localized": { - "type": "array", - "items": { - "$ref": "LocalizedString" - } - } - } - }, - "LocalizedString": { - "id": "LocalizedString", - "type": "object", - "properties": { - "language": { - "type": "string" - }, - "value": { - "type": "string" - } - } - }, - "MonitorStreamInfo": { - "id": "MonitorStreamInfo", - "type": "object", - "description": "Settings and Info of the monitor stream", - "properties": { - "broadcastStreamDelayMs": { - "type": "integer", - "description": "If you have set the enableMonitorStream property to true, then this property determines the length of the live broadcast delay.", - "format": "uint32", - "annotations": { - "required": [ - "youtube.liveBroadcasts.update" - ] - } - }, - "embedHtml": { - "type": "string", - "description": "HTML code that embeds a player that plays the monitor stream." - }, - "enableMonitorStream": { - "type": "boolean", - "description": "This value determines whether the monitor stream is enabled for the broadcast. If the monitor stream is enabled, then YouTube will broadcast the event content on a special stream intended only for the broadcaster's consumption. The broadcaster can use the stream to review the event content and also to identify the optimal times to insert cuepoints.\n\nYou need to set this value to true if you intend to have a broadcast delay for your event.\n\nNote: This property cannot be updated once the broadcast is in the testing or live state.", - "annotations": { - "required": [ - "youtube.liveBroadcasts.update" - ] - } - } - } - }, - "PageInfo": { - "id": "PageInfo", - "type": "object", - "description": "Paging details for lists of resources, including total number of items available and number of resources returned in a single page.", - "properties": { - "resultsPerPage": { - "type": "integer", - "description": "The number of results included in the API response.", - "format": "int32" - }, - "totalResults": { - "type": "integer", - "description": "The total number of results in the result set.", - "format": "int32" - } - } - }, - "Playlist": { - "id": "Playlist", - "type": "object", - "description": "A playlist resource represents a YouTube playlist. A playlist is a collection of videos that can be viewed sequentially and shared with other users. A playlist can contain up to 200 videos, and YouTube does not limit the number of playlists that each user creates. By default, playlists are publicly visible to other users, but playlists can be public or private.\n\nYouTube also uses playlists to identify special collections of videos for a channel, such as: \n- uploaded videos \n- favorite videos \n- positively rated (liked) videos \n- watch history \n- watch later To be more specific, these lists are associated with a channel, which is a collection of a person, group, or company's videos, playlists, and other YouTube information. You can retrieve the playlist IDs for each of these lists from the channel resource for a given channel.\n\nYou can then use the playlistItems.list method to retrieve any of those lists. You can also add or remove items from those lists by calling the playlistItems.insert and playlistItems.delete methods.", - "properties": { - "contentDetails": { - "$ref": "PlaylistContentDetails", - "description": "The contentDetails object contains information like video count." - }, - "etag": { - "type": "string", - "description": "Etag of this resource." - }, - "id": { - "type": "string", - "description": "The ID that YouTube uses to uniquely identify the playlist." - }, - "kind": { - "type": "string", - "description": "Identifies what kind of resource this is. Value: the fixed string \"youtube#playlist\".", - "default": "youtube#playlist" - }, - "localizations": { - "type": "object", - "description": "Localizations for different languages", - "additionalProperties": { - "$ref": "PlaylistLocalization", - "description": "The language tag, using string since map_key require simple types." - } - }, - "player": { - "$ref": "PlaylistPlayer", - "description": "The player object contains information that you would use to play the playlist in an embedded player." - }, - "snippet": { - "$ref": "PlaylistSnippet", - "description": "The snippet object contains basic details about the playlist, such as its title and description." - }, - "status": { - "$ref": "PlaylistStatus", - "description": "The status object contains status information for the playlist." - } - } - }, - "PlaylistContentDetails": { - "id": "PlaylistContentDetails", - "type": "object", - "properties": { - "itemCount": { - "type": "integer", - "description": "The number of videos in the playlist.", - "format": "uint32" - } - } - }, - "PlaylistItem": { - "id": "PlaylistItem", - "type": "object", - "description": "A playlistItem resource identifies another resource, such as a video, that is included in a playlist. In addition, the playlistItem resource contains details about the included resource that pertain specifically to how that resource is used in that playlist.\n\nYouTube uses playlists to identify special collections of videos for a channel, such as: \n- uploaded videos \n- favorite videos \n- positively rated (liked) videos \n- watch history \n- watch later To be more specific, these lists are associated with a channel, which is a collection of a person, group, or company's videos, playlists, and other YouTube information.\n\nYou can retrieve the playlist IDs for each of these lists from the channel resource for a given channel. You can then use the playlistItems.list method to retrieve any of those lists. You can also add or remove items from those lists by calling the playlistItems.insert and playlistItems.delete methods. For example, if a user gives a positive rating to a video, you would insert that video into the liked videos playlist for that user's channel.", - "properties": { - "contentDetails": { - "$ref": "PlaylistItemContentDetails", - "description": "The contentDetails object is included in the resource if the included item is a YouTube video. The object contains additional information about the video." - }, - "etag": { - "type": "string", - "description": "Etag of this resource." - }, - "id": { - "type": "string", - "description": "The ID that YouTube uses to uniquely identify the playlist item." - }, - "kind": { - "type": "string", - "description": "Identifies what kind of resource this is. Value: the fixed string \"youtube#playlistItem\".", - "default": "youtube#playlistItem" - }, - "snippet": { - "$ref": "PlaylistItemSnippet", - "description": "The snippet object contains basic details about the playlist item, such as its title and position in the playlist." - }, - "status": { - "$ref": "PlaylistItemStatus", - "description": "The status object contains information about the playlist item's privacy status." - } - } - }, - "PlaylistItemContentDetails": { - "id": "PlaylistItemContentDetails", - "type": "object", - "properties": { - "endAt": { - "type": "string", - "description": "The time, measured in seconds from the start of the video, when the video should stop playing. (The playlist owner can specify the times when the video should start and stop playing when the video is played in the context of the playlist.) By default, assume that the video.endTime is the end of the video." - }, - "note": { - "type": "string", - "description": "A user-generated note for this item." - }, - "startAt": { - "type": "string", - "description": "The time, measured in seconds from the start of the video, when the video should start playing. (The playlist owner can specify the times when the video should start and stop playing when the video is played in the context of the playlist.) The default value is 0." - }, - "videoId": { - "type": "string", - "description": "The ID that YouTube uses to uniquely identify a video. To retrieve the video resource, set the id query parameter to this value in your API request." - }, - "videoPublishedAt": { - "type": "string", - "description": "The date and time that the video was published to YouTube. The value is specified in ISO 8601 (YYYY-MM-DDThh:mm:ss.sZ) format.", - "format": "date-time" - } - } - }, - "PlaylistItemListResponse": { - "id": "PlaylistItemListResponse", - "type": "object", - "properties": { - "etag": { - "type": "string", - "description": "Etag of this resource." - }, - "eventId": { - "type": "string", - "description": "Serialized EventId of the request which produced this response." - }, - "items": { - "type": "array", - "description": "A list of playlist items that match the request criteria.", - "items": { - "$ref": "PlaylistItem" - } - }, - "kind": { - "type": "string", - "description": "Identifies what kind of resource this is. Value: the fixed string \"youtube#playlistItemListResponse\".", - "default": "youtube#playlistItemListResponse" - }, - "nextPageToken": { - "type": "string", - "description": "The token that can be used as the value of the pageToken parameter to retrieve the next page in the result set." - }, - "pageInfo": { - "$ref": "PageInfo" - }, - "prevPageToken": { - "type": "string", - "description": "The token that can be used as the value of the pageToken parameter to retrieve the previous page in the result set." - }, - "tokenPagination": { - "$ref": "TokenPagination" - }, - "visitorId": { - "type": "string", - "description": "The visitorId identifies the visitor." - } - } - }, - "PlaylistItemSnippet": { - "id": "PlaylistItemSnippet", - "type": "object", - "description": "Basic details about a playlist, including title, description and thumbnails.", - "properties": { - "channelId": { - "type": "string", - "description": "The ID that YouTube uses to uniquely identify the user that added the item to the playlist." - }, - "channelTitle": { - "type": "string", - "description": "Channel title for the channel that the playlist item belongs to." - }, - "description": { - "type": "string", - "description": "The item's description." - }, - "playlistId": { - "type": "string", - "description": "The ID that YouTube uses to uniquely identify the playlist that the playlist item is in.", - "annotations": { - "required": [ - "youtube.playlistItems.insert", - "youtube.playlistItems.update" - ] - } - }, - "position": { - "type": "integer", - "description": "The order in which the item appears in the playlist. The value uses a zero-based index, so the first item has a position of 0, the second item has a position of 1, and so forth.", - "format": "uint32" - }, - "publishedAt": { - "type": "string", - "description": "The date and time that the item was added to the playlist. The value is specified in ISO 8601 (YYYY-MM-DDThh:mm:ss.sZ) format.", - "format": "date-time" - }, - "resourceId": { - "$ref": "ResourceId", - "description": "The id object contains information that can be used to uniquely identify the resource that is included in the playlist as the playlist item.", - "annotations": { - "required": [ - "youtube.playlistItems.insert", - "youtube.playlistItems.update" - ] - } - }, - "thumbnails": { - "$ref": "ThumbnailDetails", - "description": "A map of thumbnail images associated with the playlist item. For each object in the map, the key is the name of the thumbnail image, and the value is an object that contains other information about the thumbnail." - }, - "title": { - "type": "string", - "description": "The item's title." - } - } - }, - "PlaylistItemStatus": { - "id": "PlaylistItemStatus", - "type": "object", - "description": "Information about the playlist item's privacy status.", - "properties": { - "privacyStatus": { - "type": "string", - "description": "This resource's privacy status.", - "enum": [ - "private", - "public", - "unlisted" - ], - "enumDescriptions": [ - "", - "", - "" - ] - } - } - }, - "PlaylistListResponse": { - "id": "PlaylistListResponse", - "type": "object", - "properties": { - "etag": { - "type": "string", - "description": "Etag of this resource." - }, - "eventId": { - "type": "string", - "description": "Serialized EventId of the request which produced this response." - }, - "items": { - "type": "array", - "description": "A list of playlists that match the request criteria.", - "items": { - "$ref": "Playlist" - } - }, - "kind": { - "type": "string", - "description": "Identifies what kind of resource this is. Value: the fixed string \"youtube#playlistListResponse\".", - "default": "youtube#playlistListResponse" - }, - "nextPageToken": { - "type": "string", - "description": "The token that can be used as the value of the pageToken parameter to retrieve the next page in the result set." - }, - "pageInfo": { - "$ref": "PageInfo" - }, - "prevPageToken": { - "type": "string", - "description": "The token that can be used as the value of the pageToken parameter to retrieve the previous page in the result set." - }, - "tokenPagination": { - "$ref": "TokenPagination" - }, - "visitorId": { - "type": "string", - "description": "The visitorId identifies the visitor." - } - } - }, - "PlaylistLocalization": { - "id": "PlaylistLocalization", - "type": "object", - "description": "Playlist localization setting", - "properties": { - "description": { - "type": "string", - "description": "The localized strings for playlist's description." - }, - "title": { - "type": "string", - "description": "The localized strings for playlist's title." - } - } - }, - "PlaylistPlayer": { - "id": "PlaylistPlayer", - "type": "object", - "properties": { - "embedHtml": { - "type": "string", - "description": "An \u003ciframe\u003e tag that embeds a player that will play the playlist." - } - } - }, - "PlaylistSnippet": { - "id": "PlaylistSnippet", - "type": "object", - "description": "Basic details about a playlist, including title, description and thumbnails.", - "properties": { - "channelId": { - "type": "string", - "description": "The ID that YouTube uses to uniquely identify the channel that published the playlist." - }, - "channelTitle": { - "type": "string", - "description": "The channel title of the channel that the video belongs to." - }, - "defaultLanguage": { - "type": "string", - "description": "The language of the playlist's default title and description." - }, - "description": { - "type": "string", - "description": "The playlist's description." - }, - "localized": { - "$ref": "PlaylistLocalization", - "description": "Localized title and description, read-only." - }, - "publishedAt": { - "type": "string", - "description": "The date and time that the playlist was created. The value is specified in ISO 8601 (YYYY-MM-DDThh:mm:ss.sZ) format.", - "format": "date-time" - }, - "tags": { - "type": "array", - "description": "Keyword tags associated with the playlist.", - "items": { - "type": "string" - } - }, - "thumbnails": { - "$ref": "ThumbnailDetails", - "description": "A map of thumbnail images associated with the playlist. For each object in the map, the key is the name of the thumbnail image, and the value is an object that contains other information about the thumbnail." - }, - "title": { - "type": "string", - "description": "The playlist's title.", - "annotations": { - "required": [ - "youtube.playlists.insert", - "youtube.playlists.update" - ] - } - } - } - }, - "PlaylistStatus": { - "id": "PlaylistStatus", - "type": "object", - "properties": { - "privacyStatus": { - "type": "string", - "description": "The playlist's privacy status.", - "enum": [ - "private", - "public", - "unlisted" - ], - "enumDescriptions": [ - "", - "", - "" - ] - } - } - }, - "PromotedItem": { - "id": "PromotedItem", - "type": "object", - "description": "Describes a single promoted item.", - "properties": { - "customMessage": { - "type": "string", - "description": "A custom message to display for this promotion. This field is currently ignored unless the promoted item is a website." - }, - "id": { - "$ref": "PromotedItemId", - "description": "Identifies the promoted item." - }, - "promotedByContentOwner": { - "type": "boolean", - "description": "If true, the content owner's name will be used when displaying the promotion. This field can only be set when the update is made on behalf of the content owner." - }, - "timing": { - "$ref": "InvideoTiming", - "description": "The temporal position within the video where the promoted item will be displayed. If present, it overrides the default timing." - } - } - }, - "PromotedItemId": { - "id": "PromotedItemId", - "type": "object", - "description": "Describes a single promoted item id. It is a union of various possible types.", - "properties": { - "recentlyUploadedBy": { - "type": "string", - "description": "If type is recentUpload, this field identifies the channel from which to take the recent upload. If missing, the channel is assumed to be the same channel for which the invideoPromotion is set." - }, - "type": { - "type": "string", - "description": "Describes the type of the promoted item.", - "enum": [ - "recentUpload", - "video", - "website" - ], - "enumDescriptions": [ - "", - "", - "" - ] - }, - "videoId": { - "type": "string", - "description": "If the promoted item represents a video, this field represents the unique YouTube ID identifying it. This field will be present only if type has the value video." - }, - "websiteUrl": { - "type": "string", - "description": "If the promoted item represents a website, this field represents the url pointing to the website. This field will be present only if type has the value website." - } - } - }, - "PropertyValue": { - "id": "PropertyValue", - "type": "object", - "description": "A pair Property / Value.", - "properties": { - "property": { - "type": "string", - "description": "A property." - }, - "value": { - "type": "string", - "description": "The property's value." - } - } - }, - "ResourceId": { - "id": "ResourceId", - "type": "object", - "description": "A resource id is a generic reference that points to another YouTube resource.", - "properties": { - "channelId": { - "type": "string", - "description": "The ID that YouTube uses to uniquely identify the referred resource, if that resource is a channel. This property is only present if the resourceId.kind value is youtube#channel." - }, - "kind": { - "type": "string", - "description": "The type of the API resource." - }, - "playlistId": { - "type": "string", - "description": "The ID that YouTube uses to uniquely identify the referred resource, if that resource is a playlist. This property is only present if the resourceId.kind value is youtube#playlist." - }, - "videoId": { - "type": "string", - "description": "The ID that YouTube uses to uniquely identify the referred resource, if that resource is a video. This property is only present if the resourceId.kind value is youtube#video." - } - } - }, - "SearchListResponse": { - "id": "SearchListResponse", - "type": "object", - "properties": { - "etag": { - "type": "string", - "description": "Etag of this resource." - }, - "eventId": { - "type": "string", - "description": "Serialized EventId of the request which produced this response." - }, - "items": { - "type": "array", - "description": "A list of results that match the search criteria.", - "items": { - "$ref": "SearchResult" - } - }, - "kind": { - "type": "string", - "description": "Identifies what kind of resource this is. Value: the fixed string \"youtube#searchListResponse\".", - "default": "youtube#searchListResponse" - }, - "nextPageToken": { - "type": "string", - "description": "The token that can be used as the value of the pageToken parameter to retrieve the next page in the result set." - }, - "pageInfo": { - "$ref": "PageInfo" - }, - "prevPageToken": { - "type": "string", - "description": "The token that can be used as the value of the pageToken parameter to retrieve the previous page in the result set." - }, - "regionCode": { - "type": "string" - }, - "tokenPagination": { - "$ref": "TokenPagination" - }, - "visitorId": { - "type": "string", - "description": "The visitorId identifies the visitor." - } - } - }, - "SearchResult": { - "id": "SearchResult", - "type": "object", - "description": "A search result contains information about a YouTube video, channel, or playlist that matches the search parameters specified in an API request. While a search result points to a uniquely identifiable resource, like a video, it does not have its own persistent data.", - "properties": { - "etag": { - "type": "string", - "description": "Etag of this resource." - }, - "id": { - "$ref": "ResourceId", - "description": "The id object contains information that can be used to uniquely identify the resource that matches the search request." - }, - "kind": { - "type": "string", - "description": "Identifies what kind of resource this is. Value: the fixed string \"youtube#searchResult\".", - "default": "youtube#searchResult" - }, - "snippet": { - "$ref": "SearchResultSnippet", - "description": "The snippet object contains basic details about a search result, such as its title or description. For example, if the search result is a video, then the title will be the video's title and the description will be the video's description." - } - } - }, - "SearchResultSnippet": { - "id": "SearchResultSnippet", - "type": "object", - "description": "Basic details about a search result, including title, description and thumbnails of the item referenced by the search result.", - "properties": { - "channelId": { - "type": "string", - "description": "The value that YouTube uses to uniquely identify the channel that published the resource that the search result identifies." - }, - "channelTitle": { - "type": "string", - "description": "The title of the channel that published the resource that the search result identifies." - }, - "description": { - "type": "string", - "description": "A description of the search result." - }, - "liveBroadcastContent": { - "type": "string", - "description": "It indicates if the resource (video or channel) has upcoming/active live broadcast content. Or it's \"none\" if there is not any upcoming/active live broadcasts.", - "enum": [ - "live", - "none", - "upcoming" - ], - "enumDescriptions": [ - "", - "", - "" - ] - }, - "publishedAt": { - "type": "string", - "description": "The creation date and time of the resource that the search result identifies. The value is specified in ISO 8601 (YYYY-MM-DDThh:mm:ss.sZ) format.", - "format": "date-time" - }, - "thumbnails": { - "$ref": "ThumbnailDetails", - "description": "A map of thumbnail images associated with the search result. For each object in the map, the key is the name of the thumbnail image, and the value is an object that contains other information about the thumbnail." - }, - "title": { - "type": "string", - "description": "The title of the search result." - } - } - }, - "Sponsor": { - "id": "Sponsor", - "type": "object", - "description": "A sponsor resource represents a sponsor for a YouTube channel. A sponsor provides recurring monetary support to a creator and receives special benefits.", - "properties": { - "etag": { - "type": "string", - "description": "Etag of this resource." - }, - "id": { - "type": "string", - "description": "The ID that YouTube assigns to uniquely identify the sponsor." - }, - "kind": { - "type": "string", - "description": "Identifies what kind of resource this is. Value: the fixed string \"youtube#sponsor\".", - "default": "youtube#sponsor" - }, - "snippet": { - "$ref": "SponsorSnippet", - "description": "The snippet object contains basic details about the sponsor." - } - } - }, - "SponsorListResponse": { - "id": "SponsorListResponse", - "type": "object", - "properties": { - "etag": { - "type": "string", - "description": "Etag of this resource." - }, - "eventId": { - "type": "string", - "description": "Serialized EventId of the request which produced this response." - }, - "items": { - "type": "array", - "description": "A list of sponsors that match the request criteria.", - "items": { - "$ref": "Sponsor" - } - }, - "kind": { - "type": "string", - "description": "Identifies what kind of resource this is. Value: the fixed string \"youtube#sponsorListResponse\".", - "default": "youtube#sponsorListResponse" - }, - "nextPageToken": { - "type": "string", - "description": "The token that can be used as the value of the pageToken parameter to retrieve the next page in the result set." - }, - "pageInfo": { - "$ref": "PageInfo" - }, - "tokenPagination": { - "$ref": "TokenPagination" - }, - "visitorId": { - "type": "string", - "description": "The visitorId identifies the visitor." - } - } - }, - "SponsorSnippet": { - "id": "SponsorSnippet", - "type": "object", - "properties": { - "channelId": { - "type": "string", - "description": "The id of the channel being sponsored." - }, - "sponsorDetails": { - "$ref": "ChannelProfileDetails", - "description": "Details about the sponsor." - }, - "sponsorSince": { - "type": "string", - "description": "The date and time when the user became a sponsor. The value is specified in ISO 8601 (YYYY-MM-DDThh:mm:ss.sZ) format.", - "format": "date-time" - } - } - }, - "Subscription": { - "id": "Subscription", - "type": "object", - "description": "A subscription resource contains information about a YouTube user subscription. A subscription notifies a user when new videos are added to a channel or when another user takes one of several actions on YouTube, such as uploading a video, rating a video, or commenting on a video.", - "properties": { - "contentDetails": { - "$ref": "SubscriptionContentDetails", - "description": "The contentDetails object contains basic statistics about the subscription." - }, - "etag": { - "type": "string", - "description": "Etag of this resource." - }, - "id": { - "type": "string", - "description": "The ID that YouTube uses to uniquely identify the subscription." - }, - "kind": { - "type": "string", - "description": "Identifies what kind of resource this is. Value: the fixed string \"youtube#subscription\".", - "default": "youtube#subscription" - }, - "snippet": { - "$ref": "SubscriptionSnippet", - "description": "The snippet object contains basic details about the subscription, including its title and the channel that the user subscribed to." - }, - "subscriberSnippet": { - "$ref": "SubscriptionSubscriberSnippet", - "description": "The subscriberSnippet object contains basic details about the sbuscriber." - } - } - }, - "SubscriptionContentDetails": { - "id": "SubscriptionContentDetails", - "type": "object", - "description": "Details about the content to witch a subscription refers.", - "properties": { - "activityType": { - "type": "string", - "description": "The type of activity this subscription is for (only uploads, everything).", - "enum": [ - "all", - "uploads" - ], - "enumDescriptions": [ - "", - "" - ] - }, - "newItemCount": { - "type": "integer", - "description": "The number of new items in the subscription since its content was last read.", - "format": "uint32" - }, - "totalItemCount": { - "type": "integer", - "description": "The approximate number of items that the subscription points to.", - "format": "uint32" - } - } - }, - "SubscriptionListResponse": { - "id": "SubscriptionListResponse", - "type": "object", - "properties": { - "etag": { - "type": "string", - "description": "Etag of this resource." - }, - "eventId": { - "type": "string", - "description": "Serialized EventId of the request which produced this response." - }, - "items": { - "type": "array", - "description": "A list of subscriptions that match the request criteria.", - "items": { - "$ref": "Subscription" - } - }, - "kind": { - "type": "string", - "description": "Identifies what kind of resource this is. Value: the fixed string \"youtube#subscriptionListResponse\".", - "default": "youtube#subscriptionListResponse" - }, - "nextPageToken": { - "type": "string", - "description": "The token that can be used as the value of the pageToken parameter to retrieve the next page in the result set." - }, - "pageInfo": { - "$ref": "PageInfo" - }, - "prevPageToken": { - "type": "string", - "description": "The token that can be used as the value of the pageToken parameter to retrieve the previous page in the result set." - }, - "tokenPagination": { - "$ref": "TokenPagination" - }, - "visitorId": { - "type": "string", - "description": "The visitorId identifies the visitor." - } - } - }, - "SubscriptionSnippet": { - "id": "SubscriptionSnippet", - "type": "object", - "description": "Basic details about a subscription, including title, description and thumbnails of the subscribed item.", - "properties": { - "channelId": { - "type": "string", - "description": "The ID that YouTube uses to uniquely identify the subscriber's channel." - }, - "channelTitle": { - "type": "string", - "description": "Channel title for the channel that the subscription belongs to." - }, - "description": { - "type": "string", - "description": "The subscription's details." - }, - "publishedAt": { - "type": "string", - "description": "The date and time that the subscription was created. The value is specified in ISO 8601 (YYYY-MM-DDThh:mm:ss.sZ) format.", - "format": "date-time" - }, - "resourceId": { - "$ref": "ResourceId", - "description": "The id object contains information about the channel that the user subscribed to.", - "annotations": { - "required": [ - "youtube.subscriptions.insert" - ] - } - }, - "thumbnails": { - "$ref": "ThumbnailDetails", - "description": "A map of thumbnail images associated with the video. For each object in the map, the key is the name of the thumbnail image, and the value is an object that contains other information about the thumbnail." - }, - "title": { - "type": "string", - "description": "The subscription's title." - } - } - }, - "SubscriptionSubscriberSnippet": { - "id": "SubscriptionSubscriberSnippet", - "type": "object", - "description": "Basic details about a subscription's subscriber including title, description, channel ID and thumbnails.", - "properties": { - "channelId": { - "type": "string", - "description": "The channel ID of the subscriber." - }, - "description": { - "type": "string", - "description": "The description of the subscriber." - }, - "thumbnails": { - "$ref": "ThumbnailDetails", - "description": "Thumbnails for this subscriber." - }, - "title": { - "type": "string", - "description": "The title of the subscriber." - } - } - }, - "SuperChatEvent": { - "id": "SuperChatEvent", - "type": "object", - "description": "A superChatEvent resource represents a Super Chat purchase on a YouTube channel.", - "properties": { - "etag": { - "type": "string", - "description": "Etag of this resource." - }, - "id": { - "type": "string", - "description": "The ID that YouTube assigns to uniquely identify the Super Chat event." - }, - "kind": { - "type": "string", - "description": "Identifies what kind of resource this is. Value: the fixed string \"youtube#superChatEvent\".", - "default": "youtube#superChatEvent" - }, - "snippet": { - "$ref": "SuperChatEventSnippet", - "description": "The snippet object contains basic details about the Super Chat event." - } - } - }, - "SuperChatEventListResponse": { - "id": "SuperChatEventListResponse", - "type": "object", - "properties": { - "etag": { - "type": "string", - "description": "Etag of this resource." - }, - "eventId": { - "type": "string", - "description": "Serialized EventId of the request which produced this response." - }, - "items": { - "type": "array", - "description": "A list of Super Chat purchases that match the request criteria.", - "items": { - "$ref": "SuperChatEvent" - } - }, - "kind": { - "type": "string", - "description": "Identifies what kind of resource this is. Value: the fixed string \"youtube#superChatEventListResponse\".", - "default": "youtube#superChatEventListResponse" - }, - "nextPageToken": { - "type": "string", - "description": "The token that can be used as the value of the pageToken parameter to retrieve the next page in the result set." - }, - "pageInfo": { - "$ref": "PageInfo" - }, - "tokenPagination": { - "$ref": "TokenPagination" - }, - "visitorId": { - "type": "string", - "description": "The visitorId identifies the visitor." - } - } - }, - "SuperChatEventSnippet": { - "id": "SuperChatEventSnippet", - "type": "object", - "properties": { - "amountMicros": { - "type": "string", - "description": "The purchase amount, in micros of the purchase currency. e.g., 1 is represented as 1000000.", - "format": "uint64" - }, - "channelId": { - "type": "string", - "description": "Channel id where the event occurred." - }, - "commentText": { - "type": "string", - "description": "The text contents of the comment left by the user." - }, - "createdAt": { - "type": "string", - "description": "The date and time when the event occurred. The value is specified in ISO 8601 (YYYY-MM-DDThh:mm:ss.sZ) format.", - "format": "date-time" - }, - "currency": { - "type": "string", - "description": "The currency in which the purchase was made. ISO 4217." - }, - "displayString": { - "type": "string", - "description": "A rendered string that displays the purchase amount and currency (e.g., \"$1.00\"). The string is rendered for the given language." - }, - "messageType": { - "type": "integer", - "description": "The tier for the paid message, which is based on the amount of money spent to purchase the message.", - "format": "uint32" - }, - "supporterDetails": { - "$ref": "ChannelProfileDetails", - "description": "Details about the supporter." - } - } - }, - "Thumbnail": { - "id": "Thumbnail", - "type": "object", - "description": "A thumbnail is an image representing a YouTube resource.", - "properties": { - "height": { - "type": "integer", - "description": "(Optional) Height of the thumbnail image.", - "format": "uint32" - }, - "url": { - "type": "string", - "description": "The thumbnail image's URL." - }, - "width": { - "type": "integer", - "description": "(Optional) Width of the thumbnail image.", - "format": "uint32" - } - } - }, - "ThumbnailDetails": { - "id": "ThumbnailDetails", - "type": "object", - "description": "Internal representation of thumbnails for a YouTube resource.", - "properties": { - "default": { - "$ref": "Thumbnail", - "description": "The default image for this resource." - }, - "high": { - "$ref": "Thumbnail", - "description": "The high quality image for this resource." - }, - "maxres": { - "$ref": "Thumbnail", - "description": "The maximum resolution quality image for this resource." - }, - "medium": { - "$ref": "Thumbnail", - "description": "The medium quality image for this resource." - }, - "standard": { - "$ref": "Thumbnail", - "description": "The standard quality image for this resource." - } - } - }, - "ThumbnailSetResponse": { - "id": "ThumbnailSetResponse", - "type": "object", - "properties": { - "etag": { - "type": "string", - "description": "Etag of this resource." - }, - "eventId": { - "type": "string", - "description": "Serialized EventId of the request which produced this response." - }, - "items": { - "type": "array", - "description": "A list of thumbnails.", - "items": { - "$ref": "ThumbnailDetails" - } - }, - "kind": { - "type": "string", - "description": "Identifies what kind of resource this is. Value: the fixed string \"youtube#thumbnailSetResponse\".", - "default": "youtube#thumbnailSetResponse" - }, - "visitorId": { - "type": "string", - "description": "The visitorId identifies the visitor." - } - } - }, - "TokenPagination": { - "id": "TokenPagination", - "type": "object", - "description": "Stub token pagination template to suppress results." - }, - "Video": { - "id": "Video", - "type": "object", - "description": "A video resource represents a YouTube video.", - "properties": { - "ageGating": { - "$ref": "VideoAgeGating", - "description": "Age restriction details related to a video. This data can only be retrieved by the video owner." - }, - "contentDetails": { - "$ref": "VideoContentDetails", - "description": "The contentDetails object contains information about the video content, including the length of the video and its aspect ratio." - }, - "etag": { - "type": "string", - "description": "Etag of this resource." - }, - "fileDetails": { - "$ref": "VideoFileDetails", - "description": "The fileDetails object encapsulates information about the video file that was uploaded to YouTube, including the file's resolution, duration, audio and video codecs, stream bitrates, and more. This data can only be retrieved by the video owner." - }, - "id": { - "type": "string", - "description": "The ID that YouTube uses to uniquely identify the video.", - "annotations": { - "required": [ - "youtube.videos.update" - ] - } - }, - "kind": { - "type": "string", - "description": "Identifies what kind of resource this is. Value: the fixed string \"youtube#video\".", - "default": "youtube#video" - }, - "liveStreamingDetails": { - "$ref": "VideoLiveStreamingDetails", - "description": "The liveStreamingDetails object contains metadata about a live video broadcast. The object will only be present in a video resource if the video is an upcoming, live, or completed live broadcast." - }, - "localizations": { - "type": "object", - "description": "List with all localizations.", - "additionalProperties": { - "$ref": "VideoLocalization", - "description": "The language tag, using string since map_key require simple types." - } - }, - "monetizationDetails": { - "$ref": "VideoMonetizationDetails", - "description": "The monetizationDetails object encapsulates information about the monetization status of the video." - }, - "player": { - "$ref": "VideoPlayer", - "description": "The player object contains information that you would use to play the video in an embedded player." - }, - "processingDetails": { - "$ref": "VideoProcessingDetails", - "description": "The processingProgress object encapsulates information about YouTube's progress in processing the uploaded video file. The properties in the object identify the current processing status and an estimate of the time remaining until YouTube finishes processing the video. This part also indicates whether different types of data or content, such as file details or thumbnail images, are available for the video.\n\nThe processingProgress object is designed to be polled so that the video uploaded can track the progress that YouTube has made in processing the uploaded video file. This data can only be retrieved by the video owner." - }, - "projectDetails": { - "$ref": "VideoProjectDetails", - "description": "The projectDetails object contains information about the project specific video metadata." - }, - "recordingDetails": { - "$ref": "VideoRecordingDetails", - "description": "The recordingDetails object encapsulates information about the location, date and address where the video was recorded." - }, - "snippet": { - "$ref": "VideoSnippet", - "description": "The snippet object contains basic details about the video, such as its title, description, and category." - }, - "statistics": { - "$ref": "VideoStatistics", - "description": "The statistics object contains statistics about the video." - }, - "status": { - "$ref": "VideoStatus", - "description": "The status object contains information about the video's uploading, processing, and privacy statuses." - }, - "suggestions": { - "$ref": "VideoSuggestions", - "description": "The suggestions object encapsulates suggestions that identify opportunities to improve the video quality or the metadata for the uploaded video. This data can only be retrieved by the video owner." - }, - "topicDetails": { - "$ref": "VideoTopicDetails", - "description": "The topicDetails object encapsulates information about Freebase topics associated with the video." - } - } - }, - "VideoAbuseReport": { - "id": "VideoAbuseReport", - "type": "object", - "properties": { - "comments": { - "type": "string", - "description": "Additional comments regarding the abuse report." - }, - "language": { - "type": "string", - "description": "The language that the content was viewed in." - }, - "reasonId": { - "type": "string", - "description": "The high-level, or primary, reason that the content is abusive. The value is an abuse report reason ID." - }, - "secondaryReasonId": { - "type": "string", - "description": "The specific, or secondary, reason that this content is abusive (if available). The value is an abuse report reason ID that is a valid secondary reason for the primary reason." - }, - "videoId": { - "type": "string", - "description": "The ID that YouTube uses to uniquely identify the video." - } - } - }, - "VideoAbuseReportReason": { - "id": "VideoAbuseReportReason", - "type": "object", - "description": "A videoAbuseReportReason resource identifies a reason that a video could be reported as abusive. Video abuse report reasons are used with video.ReportAbuse.", - "properties": { - "etag": { - "type": "string", - "description": "Etag of this resource." - }, - "id": { - "type": "string", - "description": "The ID of this abuse report reason." - }, - "kind": { - "type": "string", - "description": "Identifies what kind of resource this is. Value: the fixed string \"youtube#videoAbuseReportReason\".", - "default": "youtube#videoAbuseReportReason" - }, - "snippet": { - "$ref": "VideoAbuseReportReasonSnippet", - "description": "The snippet object contains basic details about the abuse report reason." - } - } - }, - "VideoAbuseReportReasonListResponse": { - "id": "VideoAbuseReportReasonListResponse", - "type": "object", - "properties": { - "etag": { - "type": "string", - "description": "Etag of this resource." - }, - "eventId": { - "type": "string", - "description": "Serialized EventId of the request which produced this response." - }, - "items": { - "type": "array", - "description": "A list of valid abuse reasons that are used with video.ReportAbuse.", - "items": { - "$ref": "VideoAbuseReportReason" - } - }, - "kind": { - "type": "string", - "description": "Identifies what kind of resource this is. Value: the fixed string \"youtube#videoAbuseReportReasonListResponse\".", - "default": "youtube#videoAbuseReportReasonListResponse" - }, - "visitorId": { - "type": "string", - "description": "The visitorId identifies the visitor." - } - } - }, - "VideoAbuseReportReasonSnippet": { - "id": "VideoAbuseReportReasonSnippet", - "type": "object", - "description": "Basic details about a video category, such as its localized title.", - "properties": { - "label": { - "type": "string", - "description": "The localized label belonging to this abuse report reason." - }, - "secondaryReasons": { - "type": "array", - "description": "The secondary reasons associated with this reason, if any are available. (There might be 0 or more.)", - "items": { - "$ref": "VideoAbuseReportSecondaryReason" - } - } - } - }, - "VideoAbuseReportSecondaryReason": { - "id": "VideoAbuseReportSecondaryReason", - "type": "object", - "properties": { - "id": { - "type": "string", - "description": "The ID of this abuse report secondary reason." - }, - "label": { - "type": "string", - "description": "The localized label for this abuse report secondary reason." - } - } - }, - "VideoAgeGating": { - "id": "VideoAgeGating", - "type": "object", - "properties": { - "alcoholContent": { - "type": "boolean", - "description": "Indicates whether or not the video has alcoholic beverage content. Only users of legal purchasing age in a particular country, as identified by ICAP, can view the content." - }, - "restricted": { - "type": "boolean", - "description": "Age-restricted trailers. For redband trailers and adult-rated video-games. Only users aged 18+ can view the content. The the field is true the content is restricted to viewers aged 18+. Otherwise The field won't be present." - }, - "videoGameRating": { - "type": "string", - "description": "Video game rating, if any.", - "enum": [ - "anyone", - "m15Plus", - "m16Plus", - "m17Plus" - ], - "enumDescriptions": [ - "", - "", - "", - "" - ] - } - } - }, - "VideoCategory": { - "id": "VideoCategory", - "type": "object", - "description": "A videoCategory resource identifies a category that has been or could be associated with uploaded videos.", - "properties": { - "etag": { - "type": "string", - "description": "Etag of this resource." - }, - "id": { - "type": "string", - "description": "The ID that YouTube uses to uniquely identify the video category." - }, - "kind": { - "type": "string", - "description": "Identifies what kind of resource this is. Value: the fixed string \"youtube#videoCategory\".", - "default": "youtube#videoCategory" - }, - "snippet": { - "$ref": "VideoCategorySnippet", - "description": "The snippet object contains basic details about the video category, including its title." - } - } - }, - "VideoCategoryListResponse": { - "id": "VideoCategoryListResponse", - "type": "object", - "properties": { - "etag": { - "type": "string", - "description": "Etag of this resource." - }, - "eventId": { - "type": "string", - "description": "Serialized EventId of the request which produced this response." - }, - "items": { - "type": "array", - "description": "A list of video categories that can be associated with YouTube videos. In this map, the video category ID is the map key, and its value is the corresponding videoCategory resource.", - "items": { - "$ref": "VideoCategory" - } - }, - "kind": { - "type": "string", - "description": "Identifies what kind of resource this is. Value: the fixed string \"youtube#videoCategoryListResponse\".", - "default": "youtube#videoCategoryListResponse" - }, - "nextPageToken": { - "type": "string", - "description": "The token that can be used as the value of the pageToken parameter to retrieve the next page in the result set." - }, - "pageInfo": { - "$ref": "PageInfo" - }, - "prevPageToken": { - "type": "string", - "description": "The token that can be used as the value of the pageToken parameter to retrieve the previous page in the result set." - }, - "tokenPagination": { - "$ref": "TokenPagination" - }, - "visitorId": { - "type": "string", - "description": "The visitorId identifies the visitor." - } - } - }, - "VideoCategorySnippet": { - "id": "VideoCategorySnippet", - "type": "object", - "description": "Basic details about a video category, such as its localized title.", - "properties": { - "assignable": { - "type": "boolean" - }, - "channelId": { - "type": "string", - "description": "The YouTube channel that created the video category.", - "default": "UCBR8-60-B28hp2BmDPdntcQ" - }, - "title": { - "type": "string", - "description": "The video category's title." - } - } - }, - "VideoContentDetails": { - "id": "VideoContentDetails", - "type": "object", - "description": "Details about the content of a YouTube Video.", - "properties": { - "caption": { - "type": "string", - "description": "The value of captions indicates whether the video has captions or not.", - "enum": [ - "false", - "true" - ], - "enumDescriptions": [ - "", - "" - ] - }, - "contentRating": { - "$ref": "ContentRating", - "description": "Specifies the ratings that the video received under various rating schemes." - }, - "countryRestriction": { - "$ref": "AccessPolicy", - "description": "The countryRestriction object contains information about the countries where a video is (or is not) viewable." - }, - "definition": { - "type": "string", - "description": "The value of definition indicates whether the video is available in high definition or only in standard definition.", - "enum": [ - "hd", - "sd" - ], - "enumDescriptions": [ - "", - "" - ] - }, - "dimension": { - "type": "string", - "description": "The value of dimension indicates whether the video is available in 3D or in 2D." - }, - "duration": { - "type": "string", - "description": "The length of the video. The tag value is an ISO 8601 duration in the format PT#M#S, in which the letters PT indicate that the value specifies a period of time, and the letters M and S refer to length in minutes and seconds, respectively. The # characters preceding the M and S letters are both integers that specify the number of minutes (or seconds) of the video. For example, a value of PT15M51S indicates that the video is 15 minutes and 51 seconds long." - }, - "hasCustomThumbnail": { - "type": "boolean", - "description": "Indicates whether the video uploader has provided a custom thumbnail image for the video. This property is only visible to the video uploader." - }, - "licensedContent": { - "type": "boolean", - "description": "The value of is_license_content indicates whether the video is licensed content." - }, - "projection": { - "type": "string", - "description": "Specifies the projection format of the video.", - "enum": [ - "360", - "rectangular" - ], - "enumDescriptions": [ - "", - "" - ] - }, - "regionRestriction": { - "$ref": "VideoContentDetailsRegionRestriction", - "description": "The regionRestriction object contains information about the countries where a video is (or is not) viewable. The object will contain either the contentDetails.regionRestriction.allowed property or the contentDetails.regionRestriction.blocked property." - } - } - }, - "VideoContentDetailsRegionRestriction": { - "id": "VideoContentDetailsRegionRestriction", - "type": "object", - "description": "DEPRECATED Region restriction of the video.", - "properties": { - "allowed": { - "type": "array", - "description": "A list of region codes that identify countries where the video is viewable. If this property is present and a country is not listed in its value, then the video is blocked from appearing in that country. If this property is present and contains an empty list, the video is blocked in all countries.", - "items": { - "type": "string" - } - }, - "blocked": { - "type": "array", - "description": "A list of region codes that identify countries where the video is blocked. If this property is present and a country is not listed in its value, then the video is viewable in that country. If this property is present and contains an empty list, the video is viewable in all countries.", - "items": { - "type": "string" - } - } - } - }, - "VideoFileDetails": { - "id": "VideoFileDetails", - "type": "object", - "description": "Describes original video file properties, including technical details about audio and video streams, but also metadata information like content length, digitization time, or geotagging information.", - "properties": { - "audioStreams": { - "type": "array", - "description": "A list of audio streams contained in the uploaded video file. Each item in the list contains detailed metadata about an audio stream.", - "items": { - "$ref": "VideoFileDetailsAudioStream" - } - }, - "bitrateBps": { - "type": "string", - "description": "The uploaded video file's combined (video and audio) bitrate in bits per second.", - "format": "uint64" - }, - "container": { - "type": "string", - "description": "The uploaded video file's container format." - }, - "creationTime": { - "type": "string", - "description": "The date and time when the uploaded video file was created. The value is specified in ISO 8601 format. Currently, the following ISO 8601 formats are supported: \n- Date only: YYYY-MM-DD \n- Naive time: YYYY-MM-DDTHH:MM:SS \n- Time with timezone: YYYY-MM-DDTHH:MM:SS+HH:MM" - }, - "durationMs": { - "type": "string", - "description": "The length of the uploaded video in milliseconds.", - "format": "uint64" - }, - "fileName": { - "type": "string", - "description": "The uploaded file's name. This field is present whether a video file or another type of file was uploaded." - }, - "fileSize": { - "type": "string", - "description": "The uploaded file's size in bytes. This field is present whether a video file or another type of file was uploaded.", - "format": "uint64" - }, - "fileType": { - "type": "string", - "description": "The uploaded file's type as detected by YouTube's video processing engine. Currently, YouTube only processes video files, but this field is present whether a video file or another type of file was uploaded.", - "enum": [ - "archive", - "audio", - "document", - "image", - "other", - "project", - "video" - ], - "enumDescriptions": [ - "", - "", - "", - "", - "", - "", - "" - ] - }, - "videoStreams": { - "type": "array", - "description": "A list of video streams contained in the uploaded video file. Each item in the list contains detailed metadata about a video stream.", - "items": { - "$ref": "VideoFileDetailsVideoStream" - } - } - } - }, - "VideoFileDetailsAudioStream": { - "id": "VideoFileDetailsAudioStream", - "type": "object", - "description": "Information about an audio stream.", - "properties": { - "bitrateBps": { - "type": "string", - "description": "The audio stream's bitrate, in bits per second.", - "format": "uint64" - }, - "channelCount": { - "type": "integer", - "description": "The number of audio channels that the stream contains.", - "format": "uint32" - }, - "codec": { - "type": "string", - "description": "The audio codec that the stream uses." - }, - "vendor": { - "type": "string", - "description": "A value that uniquely identifies a video vendor. Typically, the value is a four-letter vendor code." - } - } - }, - "VideoFileDetailsVideoStream": { - "id": "VideoFileDetailsVideoStream", - "type": "object", - "description": "Information about a video stream.", - "properties": { - "aspectRatio": { - "type": "number", - "description": "The video content's display aspect ratio, which specifies the aspect ratio in which the video should be displayed.", - "format": "double" - }, - "bitrateBps": { - "type": "string", - "description": "The video stream's bitrate, in bits per second.", - "format": "uint64" - }, - "codec": { - "type": "string", - "description": "The video codec that the stream uses." - }, - "frameRateFps": { - "type": "number", - "description": "The video stream's frame rate, in frames per second.", - "format": "double" - }, - "heightPixels": { - "type": "integer", - "description": "The encoded video content's height in pixels.", - "format": "uint32" - }, - "rotation": { - "type": "string", - "description": "The amount that YouTube needs to rotate the original source content to properly display the video.", - "enum": [ - "clockwise", - "counterClockwise", - "none", - "other", - "upsideDown" - ], - "enumDescriptions": [ - "", - "", - "", - "", - "" - ] - }, - "vendor": { - "type": "string", - "description": "A value that uniquely identifies a video vendor. Typically, the value is a four-letter vendor code." - }, - "widthPixels": { - "type": "integer", - "description": "The encoded video content's width in pixels. You can calculate the video's encoding aspect ratio as width_pixels / height_pixels.", - "format": "uint32" - } - } - }, - "VideoGetRatingResponse": { - "id": "VideoGetRatingResponse", - "type": "object", - "properties": { - "etag": { - "type": "string", - "description": "Etag of this resource." - }, - "eventId": { - "type": "string", - "description": "Serialized EventId of the request which produced this response." - }, - "items": { - "type": "array", - "description": "A list of ratings that match the request criteria.", - "items": { - "$ref": "VideoRating" - } - }, - "kind": { - "type": "string", - "description": "Identifies what kind of resource this is. Value: the fixed string \"youtube#videoGetRatingResponse\".", - "default": "youtube#videoGetRatingResponse" - }, - "visitorId": { - "type": "string", - "description": "The visitorId identifies the visitor." - } - } - }, - "VideoListResponse": { - "id": "VideoListResponse", - "type": "object", - "properties": { - "etag": { - "type": "string", - "description": "Etag of this resource." - }, - "eventId": { - "type": "string", - "description": "Serialized EventId of the request which produced this response." - }, - "items": { - "type": "array", - "description": "A list of videos that match the request criteria.", - "items": { - "$ref": "Video" - } - }, - "kind": { - "type": "string", - "description": "Identifies what kind of resource this is. Value: the fixed string \"youtube#videoListResponse\".", - "default": "youtube#videoListResponse" - }, - "nextPageToken": { - "type": "string", - "description": "The token that can be used as the value of the pageToken parameter to retrieve the next page in the result set." - }, - "pageInfo": { - "$ref": "PageInfo" - }, - "prevPageToken": { - "type": "string", - "description": "The token that can be used as the value of the pageToken parameter to retrieve the previous page in the result set." - }, - "tokenPagination": { - "$ref": "TokenPagination" - }, - "visitorId": { - "type": "string", - "description": "The visitorId identifies the visitor." - } - } - }, - "VideoLiveStreamingDetails": { - "id": "VideoLiveStreamingDetails", - "type": "object", - "description": "Details about the live streaming metadata.", - "properties": { - "activeLiveChatId": { - "type": "string", - "description": "The ID of the currently active live chat attached to this video. This field is filled only if the video is a currently live broadcast that has live chat. Once the broadcast transitions to complete this field will be removed and the live chat closed down. For persistent broadcasts that live chat id will no longer be tied to this video but rather to the new video being displayed at the persistent page." - }, - "actualEndTime": { - "type": "string", - "description": "The time that the broadcast actually ended. The value is specified in ISO 8601 (YYYY-MM-DDThh:mm:ss.sZ) format. This value will not be available until the broadcast is over.", - "format": "date-time" - }, - "actualStartTime": { - "type": "string", - "description": "The time that the broadcast actually started. The value is specified in ISO 8601 (YYYY-MM-DDThh:mm:ss.sZ) format. This value will not be available until the broadcast begins.", - "format": "date-time" - }, - "concurrentViewers": { - "type": "string", - "description": "The number of viewers currently watching the broadcast. The property and its value will be present if the broadcast has current viewers and the broadcast owner has not hidden the viewcount for the video. Note that YouTube stops tracking the number of concurrent viewers for a broadcast when the broadcast ends. So, this property would not identify the number of viewers watching an archived video of a live broadcast that already ended.", - "format": "uint64" - }, - "scheduledEndTime": { - "type": "string", - "description": "The time that the broadcast is scheduled to end. The value is specified in ISO 8601 (YYYY-MM-DDThh:mm:ss.sZ) format. If the value is empty or the property is not present, then the broadcast is scheduled to continue indefinitely.", - "format": "date-time" - }, - "scheduledStartTime": { - "type": "string", - "description": "The time that the broadcast is scheduled to begin. The value is specified in ISO 8601 (YYYY-MM-DDThh:mm:ss.sZ) format.", - "format": "date-time" - } - } - }, - "VideoLocalization": { - "id": "VideoLocalization", - "type": "object", - "description": "Localized versions of certain video properties (e.g. title).", - "properties": { - "description": { - "type": "string", - "description": "Localized version of the video's description." - }, - "title": { - "type": "string", - "description": "Localized version of the video's title." - } - } - }, - "VideoMonetizationDetails": { - "id": "VideoMonetizationDetails", - "type": "object", - "description": "Details about monetization of a YouTube Video.", - "properties": { - "access": { - "$ref": "AccessPolicy", - "description": "The value of access indicates whether the video can be monetized or not." - } - } - }, - "VideoPlayer": { - "id": "VideoPlayer", - "type": "object", - "description": "Player to be used for a video playback.", - "properties": { - "embedHeight": { - "type": "string", - "format": "int64" - }, - "embedHtml": { - "type": "string", - "description": "An \u003ciframe\u003e tag that embeds a player that will play the video." - }, - "embedWidth": { - "type": "string", - "description": "The embed width", - "format": "int64" - } - } - }, - "VideoProcessingDetails": { - "id": "VideoProcessingDetails", - "type": "object", - "description": "Describes processing status and progress and availability of some other Video resource parts.", - "properties": { - "editorSuggestionsAvailability": { - "type": "string", - "description": "This value indicates whether video editing suggestions, which might improve video quality or the playback experience, are available for the video. You can retrieve these suggestions by requesting the suggestions part in your videos.list() request." - }, - "fileDetailsAvailability": { - "type": "string", - "description": "This value indicates whether file details are available for the uploaded video. You can retrieve a video's file details by requesting the fileDetails part in your videos.list() request." - }, - "processingFailureReason": { - "type": "string", - "description": "The reason that YouTube failed to process the video. This property will only have a value if the processingStatus property's value is failed.", - "enum": [ - "other", - "streamingFailed", - "transcodeFailed", - "uploadFailed" - ], - "enumDescriptions": [ - "", - "", - "", - "" - ] - }, - "processingIssuesAvailability": { - "type": "string", - "description": "This value indicates whether the video processing engine has generated suggestions that might improve YouTube's ability to process the the video, warnings that explain video processing problems, or errors that cause video processing problems. You can retrieve these suggestions by requesting the suggestions part in your videos.list() request." - }, - "processingProgress": { - "$ref": "VideoProcessingDetailsProcessingProgress", - "description": "The processingProgress object contains information about the progress YouTube has made in processing the video. The values are really only relevant if the video's processing status is processing." - }, - "processingStatus": { - "type": "string", - "description": "The video's processing status. This value indicates whether YouTube was able to process the video or if the video is still being processed.", - "enum": [ - "failed", - "processing", - "succeeded", - "terminated" - ], - "enumDescriptions": [ - "", - "", - "", - "" - ] - }, - "tagSuggestionsAvailability": { - "type": "string", - "description": "This value indicates whether keyword (tag) suggestions are available for the video. Tags can be added to a video's metadata to make it easier for other users to find the video. You can retrieve these suggestions by requesting the suggestions part in your videos.list() request." - }, - "thumbnailsAvailability": { - "type": "string", - "description": "This value indicates whether thumbnail images have been generated for the video." - } - } - }, - "VideoProcessingDetailsProcessingProgress": { - "id": "VideoProcessingDetailsProcessingProgress", - "type": "object", - "description": "Video processing progress and completion time estimate.", - "properties": { - "partsProcessed": { - "type": "string", - "description": "The number of parts of the video that YouTube has already processed. You can estimate the percentage of the video that YouTube has already processed by calculating:\n100 * parts_processed / parts_total\n\nNote that since the estimated number of parts could increase without a corresponding increase in the number of parts that have already been processed, it is possible that the calculated progress could periodically decrease while YouTube processes a video.", - "format": "uint64" - }, - "partsTotal": { - "type": "string", - "description": "An estimate of the total number of parts that need to be processed for the video. The number may be updated with more precise estimates while YouTube processes the video.", - "format": "uint64" - }, - "timeLeftMs": { - "type": "string", - "description": "An estimate of the amount of time, in millseconds, that YouTube needs to finish processing the video.", - "format": "uint64" - } - } - }, - "VideoProjectDetails": { - "id": "VideoProjectDetails", - "type": "object", - "description": "Project specific details about the content of a YouTube Video.", - "properties": { - "tags": { - "type": "array", - "description": "A list of project tags associated with the video during the upload.", - "items": { - "type": "string" - } - } - } - }, - "VideoRating": { - "id": "VideoRating", - "type": "object", - "properties": { - "rating": { - "type": "string", - "enum": [ - "dislike", - "like", - "none", - "unspecified" - ], - "enumDescriptions": [ - "", - "", - "", - "" - ] - }, - "videoId": { - "type": "string" - } - } - }, - "VideoRecordingDetails": { - "id": "VideoRecordingDetails", - "type": "object", - "description": "Recording information associated with the video.", - "properties": { - "location": { - "$ref": "GeoPoint", - "description": "The geolocation information associated with the video." - }, - "locationDescription": { - "type": "string", - "description": "The text description of the location where the video was recorded." - }, - "recordingDate": { - "type": "string", - "description": "The date and time when the video was recorded. The value is specified in ISO 8601 (YYYY-MM-DDThh:mm:ss.sssZ) format.", - "format": "date-time" - } - } - }, - "VideoSnippet": { - "id": "VideoSnippet", - "type": "object", - "description": "Basic details about a video, including title, description, uploader, thumbnails and category.", - "properties": { - "categoryId": { - "type": "string", - "description": "The YouTube video category associated with the video." - }, - "channelId": { - "type": "string", - "description": "The ID that YouTube uses to uniquely identify the channel that the video was uploaded to." - }, - "channelTitle": { - "type": "string", - "description": "Channel title for the channel that the video belongs to." - }, - "defaultAudioLanguage": { - "type": "string", - "description": "The default_audio_language property specifies the language spoken in the video's default audio track." - }, - "defaultLanguage": { - "type": "string", - "description": "The language of the videos's default snippet." - }, - "description": { - "type": "string", - "description": "The video's description." - }, - "liveBroadcastContent": { - "type": "string", - "description": "Indicates if the video is an upcoming/active live broadcast. Or it's \"none\" if the video is not an upcoming/active live broadcast.", - "enum": [ - "live", - "none", - "upcoming" - ], - "enumDescriptions": [ - "", - "", - "" - ] - }, - "localized": { - "$ref": "VideoLocalization", - "description": "Localized snippet selected with the hl parameter. If no such localization exists, this field is populated with the default snippet. (Read-only)" - }, - "publishedAt": { - "type": "string", - "description": "The date and time that the video was uploaded. The value is specified in ISO 8601 (YYYY-MM-DDThh:mm:ss.sZ) format.", - "format": "date-time" - }, - "tags": { - "type": "array", - "description": "A list of keyword tags associated with the video. Tags may contain spaces.", - "items": { - "type": "string" - } - }, - "thumbnails": { - "$ref": "ThumbnailDetails", - "description": "A map of thumbnail images associated with the video. For each object in the map, the key is the name of the thumbnail image, and the value is an object that contains other information about the thumbnail." - }, - "title": { - "type": "string", - "description": "The video's title." - } - } - }, - "VideoStatistics": { - "id": "VideoStatistics", - "type": "object", - "description": "Statistics about the video, such as the number of times the video was viewed or liked.", - "properties": { - "commentCount": { - "type": "string", - "description": "The number of comments for the video.", - "format": "uint64" - }, - "dislikeCount": { - "type": "string", - "description": "The number of users who have indicated that they disliked the video by giving it a negative rating.", - "format": "uint64" - }, - "favoriteCount": { - "type": "string", - "description": "The number of users who currently have the video marked as a favorite video.", - "format": "uint64" - }, - "likeCount": { - "type": "string", - "description": "The number of users who have indicated that they liked the video by giving it a positive rating.", - "format": "uint64" - }, - "viewCount": { - "type": "string", - "description": "The number of times the video has been viewed.", - "format": "uint64" - } - } - }, - "VideoStatus": { - "id": "VideoStatus", - "type": "object", - "description": "Basic details about a video category, such as its localized title.", - "properties": { - "embeddable": { - "type": "boolean", - "description": "This value indicates if the video can be embedded on another website." - }, - "failureReason": { - "type": "string", - "description": "This value explains why a video failed to upload. This property is only present if the uploadStatus property indicates that the upload failed.", - "enum": [ - "codec", - "conversion", - "emptyFile", - "invalidFile", - "tooSmall", - "uploadAborted" - ], - "enumDescriptions": [ - "", - "", - "", - "", - "", - "" - ] - }, - "license": { - "type": "string", - "description": "The video's license.", - "enum": [ - "creativeCommon", - "youtube" - ], - "enumDescriptions": [ - "", - "" - ] - }, - "privacyStatus": { - "type": "string", - "description": "The video's privacy status.", - "enum": [ - "private", - "public", - "unlisted" - ], - "enumDescriptions": [ - "", - "", - "" - ] - }, - "publicStatsViewable": { - "type": "boolean", - "description": "This value indicates if the extended video statistics on the watch page can be viewed by everyone. Note that the view count, likes, etc will still be visible if this is disabled." - }, - "publishAt": { - "type": "string", - "description": "The date and time when the video is scheduled to publish. It can be set only if the privacy status of the video is private. The value is specified in ISO 8601 (YYYY-MM-DDThh:mm:ss.sZ) format.", - "format": "date-time" - }, - "rejectionReason": { - "type": "string", - "description": "This value explains why YouTube rejected an uploaded video. This property is only present if the uploadStatus property indicates that the upload was rejected.", - "enum": [ - "claim", - "copyright", - "duplicate", - "inappropriate", - "legal", - "length", - "termsOfUse", - "trademark", - "uploaderAccountClosed", - "uploaderAccountSuspended" - ], - "enumDescriptions": [ - "", - "", - "", - "", - "", - "", - "", - "", - "", - "" - ] - }, - "uploadStatus": { - "type": "string", - "description": "The status of the uploaded video.", - "enum": [ - "deleted", - "failed", - "processed", - "rejected", - "uploaded" - ], - "enumDescriptions": [ - "", - "", - "", - "", - "" - ] - } - } - }, - "VideoSuggestions": { - "id": "VideoSuggestions", - "type": "object", - "description": "Specifies suggestions on how to improve video content, including encoding hints, tag suggestions, and editor suggestions.", - "properties": { - "editorSuggestions": { - "type": "array", - "description": "A list of video editing operations that might improve the video quality or playback experience of the uploaded video.", - "items": { - "type": "string", - "enum": [ - "audioQuietAudioSwap", - "videoAutoLevels", - "videoCrop", - "videoStabilize" - ], - "enumDescriptions": [ - "", - "", - "", - "" - ] - } - }, - "processingErrors": { - "type": "array", - "description": "A list of errors that will prevent YouTube from successfully processing the uploaded video video. These errors indicate that, regardless of the video's current processing status, eventually, that status will almost certainly be failed.", - "items": { - "type": "string", - "enum": [ - "archiveFile", - "audioFile", - "docFile", - "imageFile", - "notAVideoFile", - "projectFile", - "unsupportedSpatialAudioLayout" - ], - "enumDescriptions": [ - "", - "", - "", - "", - "", - "", - "" - ] - } - }, - "processingHints": { - "type": "array", - "description": "A list of suggestions that may improve YouTube's ability to process the video.", - "items": { - "type": "string", - "enum": [ - "nonStreamableMov", - "sendBestQualityVideo", - "spatialAudio", - "sphericalVideo", - "vrVideo" - ], - "enumDescriptions": [ - "", - "", - "", - "", - "" - ] - } - }, - "processingWarnings": { - "type": "array", - "description": "A list of reasons why YouTube may have difficulty transcoding the uploaded video or that might result in an erroneous transcoding. These warnings are generated before YouTube actually processes the uploaded video file. In addition, they identify issues that are unlikely to cause the video processing to fail but that might cause problems such as sync issues, video artifacts, or a missing audio track.", - "items": { - "type": "string", - "enum": [ - "hasEditlist", - "inconsistentResolution", - "problematicAudioCodec", - "problematicVideoCodec", - "unknownAudioCodec", - "unknownContainer", - "unknownVideoCodec", - "unsupportedSphericalProjectionType", - "unsupportedVrStereoMode" - ], - "enumDescriptions": [ - "", - "", - "", - "", - "", - "", - "", - "", - "" - ] - } - }, - "tagSuggestions": { - "type": "array", - "description": "A list of keyword tags that could be added to the video's metadata to increase the likelihood that users will locate your video when searching or browsing on YouTube.", - "items": { - "$ref": "VideoSuggestionsTagSuggestion" - } - } - } - }, - "VideoSuggestionsTagSuggestion": { - "id": "VideoSuggestionsTagSuggestion", - "type": "object", - "description": "A single tag suggestion with it's relevance information.", - "properties": { - "categoryRestricts": { - "type": "array", - "description": "A set of video categories for which the tag is relevant. You can use this information to display appropriate tag suggestions based on the video category that the video uploader associates with the video. By default, tag suggestions are relevant for all categories if there are no restricts defined for the keyword.", - "items": { - "type": "string" - } - }, - "tag": { - "type": "string", - "description": "The keyword tag suggested for the video." - } - } - }, - "VideoTopicDetails": { - "id": "VideoTopicDetails", - "type": "object", - "description": "Freebase topic information related to the video.", - "properties": { - "relevantTopicIds": { - "type": "array", - "description": "Similar to topic_id, except that these topics are merely relevant to the video. These are topics that may be mentioned in, or appear in the video. You can retrieve information about each topic using Freebase Topic API.", - "items": { - "type": "string" - } - }, - "topicCategories": { - "type": "array", - "description": "A list of Wikipedia URLs that provide a high-level description of the video's content.", - "items": { - "type": "string" - } - }, - "topicIds": { - "type": "array", - "description": "A list of Freebase topic IDs that are centrally associated with the video. These are topics that are centrally featured in the video, and it can be said that the video is mainly about each of these. You can retrieve information about each topic using the Freebase Topic API.", - "items": { - "type": "string" - } - } - } - }, - "WatchSettings": { - "id": "WatchSettings", - "type": "object", - "description": "Branding properties for the watch. All deprecated.", - "properties": { - "backgroundColor": { - "type": "string", - "description": "The text color for the video watch page's branded area." - }, - "featuredPlaylistId": { - "type": "string", - "description": "An ID that uniquely identifies a playlist that displays next to the video player." - }, - "textColor": { - "type": "string", - "description": "The background color for the video watch page's branded area." - } - } - } - }, - "resources": { - "activities": { - "methods": { - "insert": { - "id": "youtube.activities.insert", - "path": "activities", - "httpMethod": "POST", - "description": "Posts a bulletin for a specific channel. (The user submitting the request must be authorized to act on the channel's behalf.)\n\nNote: Even though an activity resource can contain information about actions like a user rating a video or marking a video as a favorite, you need to use other API methods to generate those activity resources. For example, you would use the API's videos.rate() method to rate a video and the playlistItems.insert() method to mark a video as a favorite.", - "parameters": { - "part": { - "type": "string", - "description": "The part parameter serves two purposes in this operation. It identifies the properties that the write operation will set as well as the properties that the API response will include.", - "required": true, - "location": "query" - } - }, - "parameterOrder": [ - "part" - ], - "request": { - "$ref": "Activity" - }, - "response": { - "$ref": "Activity" - }, - "scopes": [ - "https://www.googleapis.com/auth/youtube", - "https://www.googleapis.com/auth/youtube.force-ssl" - ] - }, - "list": { - "id": "youtube.activities.list", - "path": "activities", - "httpMethod": "GET", - "description": "Returns a list of channel activity events that match the request criteria. For example, you can retrieve events associated with a particular channel, events associated with the user's subscriptions and Google+ friends, or the YouTube home page feed, which is customized for each user.", - "parameters": { - "channelId": { - "type": "string", - "description": "The channelId parameter specifies a unique YouTube channel ID. The API will then return a list of that channel's activities.", - "location": "query" - }, - "home": { - "type": "boolean", - "description": "Set this parameter's value to true to retrieve the activity feed that displays on the YouTube home page for the currently authenticated user.", - "location": "query" - }, - "maxResults": { - "type": "integer", - "description": "The maxResults parameter specifies the maximum number of items that should be returned in the result set.", - "default": "5", - "format": "uint32", - "minimum": "0", - "maximum": "50", - "location": "query" - }, - "mine": { - "type": "boolean", - "description": "Set this parameter's value to true to retrieve a feed of the authenticated user's activities.", - "location": "query" - }, - "pageToken": { - "type": "string", - "description": "The pageToken parameter identifies a specific page in the result set that should be returned. In an API response, the nextPageToken and prevPageToken properties identify other pages that could be retrieved.", - "location": "query" - }, - "part": { - "type": "string", - "description": "The part parameter specifies a comma-separated list of one or more activity resource properties that the API response will include.\n\nIf the parameter identifies a property that contains child properties, the child properties will be included in the response. For example, in an activity resource, the snippet property contains other properties that identify the type of activity, a display title for the activity, and so forth. If you set part=snippet, the API response will also contain all of those nested properties.", - "required": true, - "location": "query" - }, - "publishedAfter": { - "type": "string", - "description": "The publishedAfter parameter specifies the earliest date and time that an activity could have occurred for that activity to be included in the API response. If the parameter value specifies a day, but not a time, then any activities that occurred that day will be included in the result set. The value is specified in ISO 8601 (YYYY-MM-DDThh:mm:ss.sZ) format.", - "format": "date-time", - "location": "query" - }, - "publishedBefore": { - "type": "string", - "description": "The publishedBefore parameter specifies the date and time before which an activity must have occurred for that activity to be included in the API response. If the parameter value specifies a day, but not a time, then any activities that occurred that day will be excluded from the result set. The value is specified in ISO 8601 (YYYY-MM-DDThh:mm:ss.sZ) format.", - "format": "date-time", - "location": "query" - }, - "regionCode": { - "type": "string", - "description": "The regionCode parameter instructs the API to return results for the specified country. The parameter value is an ISO 3166-1 alpha-2 country code. YouTube uses this value when the authorized user's previous activity on YouTube does not provide enough information to generate the activity feed.", - "location": "query" - } - }, - "parameterOrder": [ - "part" - ], - "response": { - "$ref": "ActivityListResponse" - }, - "scopes": [ - "https://www.googleapis.com/auth/youtube", - "https://www.googleapis.com/auth/youtube.force-ssl", - "https://www.googleapis.com/auth/youtube.readonly" - ] - } - } - }, - "captions": { - "methods": { - "delete": { - "id": "youtube.captions.delete", - "path": "captions", - "httpMethod": "DELETE", - "description": "Deletes a specified caption track.", - "parameters": { - "id": { - "type": "string", - "description": "The id parameter identifies the caption track that is being deleted. The value is a caption track ID as identified by the id property in a caption resource.", - "required": true, - "location": "query" - }, - "onBehalfOf": { - "type": "string", - "description": "ID of the Google+ Page for the channel that the request is be on behalf of", - "location": "query" - }, - "onBehalfOfContentOwner": { - "type": "string", - "description": "Note: This parameter is intended exclusively for YouTube content partners.\n\nThe onBehalfOfContentOwner parameter indicates that the request's authorization credentials identify a YouTube CMS user who is acting on behalf of the content owner specified in the parameter value. This parameter is intended for YouTube content partners that own and manage many different YouTube channels. It allows content owners to authenticate once and get access to all their video and channel data, without having to provide authentication credentials for each individual channel. The actual CMS account that the user authenticates with must be linked to the specified YouTube content owner.", - "location": "query" - } - }, - "parameterOrder": [ - "id" - ], - "scopes": [ - "https://www.googleapis.com/auth/youtube.force-ssl", - "https://www.googleapis.com/auth/youtubepartner" - ] - }, - "download": { - "id": "youtube.captions.download", - "path": "captions/{id}", - "httpMethod": "GET", - "description": "Downloads a caption track. The caption track is returned in its original format unless the request specifies a value for the tfmt parameter and in its original language unless the request specifies a value for the tlang parameter.", - "parameters": { - "id": { - "type": "string", - "description": "The id parameter identifies the caption track that is being retrieved. The value is a caption track ID as identified by the id property in a caption resource.", - "required": true, - "location": "path" - }, - "onBehalfOf": { - "type": "string", - "description": "ID of the Google+ Page for the channel that the request is be on behalf of", - "location": "query" - }, - "onBehalfOfContentOwner": { - "type": "string", - "description": "Note: This parameter is intended exclusively for YouTube content partners.\n\nThe onBehalfOfContentOwner parameter indicates that the request's authorization credentials identify a YouTube CMS user who is acting on behalf of the content owner specified in the parameter value. This parameter is intended for YouTube content partners that own and manage many different YouTube channels. It allows content owners to authenticate once and get access to all their video and channel data, without having to provide authentication credentials for each individual channel. The actual CMS account that the user authenticates with must be linked to the specified YouTube content owner.", - "location": "query" - }, - "tfmt": { - "type": "string", - "description": "The tfmt parameter specifies that the caption track should be returned in a specific format. If the parameter is not included in the request, the track is returned in its original format.", - "enum": [ - "sbv", - "scc", - "srt", - "ttml", - "vtt" - ], - "enumDescriptions": [ - "SubViewer subtitle.", - "Scenarist Closed Caption format.", - "SubRip subtitle.", - "Timed Text Markup Language caption.", - "Web Video Text Tracks caption." - ], - "location": "query" - }, - "tlang": { - "type": "string", - "description": "The tlang parameter specifies that the API response should return a translation of the specified caption track. The parameter value is an ISO 639-1 two-letter language code that identifies the desired caption language. The translation is generated by using machine translation, such as Google Translate.", - "location": "query" - } - }, - "parameterOrder": [ - "id" - ], - "scopes": [ - "https://www.googleapis.com/auth/youtube.force-ssl", - "https://www.googleapis.com/auth/youtubepartner" - ], - "supportsMediaDownload": true - }, - "insert": { - "id": "youtube.captions.insert", - "path": "captions", - "httpMethod": "POST", - "description": "Uploads a caption track.", - "parameters": { - "onBehalfOf": { - "type": "string", - "description": "ID of the Google+ Page for the channel that the request is be on behalf of", - "location": "query" - }, - "onBehalfOfContentOwner": { - "type": "string", - "description": "Note: This parameter is intended exclusively for YouTube content partners.\n\nThe onBehalfOfContentOwner parameter indicates that the request's authorization credentials identify a YouTube CMS user who is acting on behalf of the content owner specified in the parameter value. This parameter is intended for YouTube content partners that own and manage many different YouTube channels. It allows content owners to authenticate once and get access to all their video and channel data, without having to provide authentication credentials for each individual channel. The actual CMS account that the user authenticates with must be linked to the specified YouTube content owner.", - "location": "query" - }, - "part": { - "type": "string", - "description": "The part parameter specifies the caption resource parts that the API response will include. Set the parameter value to snippet.", - "required": true, - "location": "query" - }, - "sync": { - "type": "boolean", - "description": "The sync parameter indicates whether YouTube should automatically synchronize the caption file with the audio track of the video. If you set the value to true, YouTube will disregard any time codes that are in the uploaded caption file and generate new time codes for the captions.\n\nYou should set the sync parameter to true if you are uploading a transcript, which has no time codes, or if you suspect the time codes in your file are incorrect and want YouTube to try to fix them.", - "location": "query" - } - }, - "parameterOrder": [ - "part" - ], - "request": { - "$ref": "Caption" - }, - "response": { - "$ref": "Caption" - }, - "scopes": [ - "https://www.googleapis.com/auth/youtube.force-ssl", - "https://www.googleapis.com/auth/youtubepartner" - ], - "supportsMediaUpload": true, - "mediaUpload": { - "accept": [ - "*/*", - "application/octet-stream", - "text/xml" - ], - "maxSize": "100MB", - "protocols": { - "simple": { - "multipart": true, - "path": "/upload/youtube/v3/captions" - }, - "resumable": { - "multipart": true, - "path": "/resumable/upload/youtube/v3/captions" - } - } - } - }, - "list": { - "id": "youtube.captions.list", - "path": "captions", - "httpMethod": "GET", - "description": "Returns a list of caption tracks that are associated with a specified video. Note that the API response does not contain the actual captions and that the captions.download method provides the ability to retrieve a caption track.", - "parameters": { - "id": { - "type": "string", - "description": "The id parameter specifies a comma-separated list of IDs that identify the caption resources that should be retrieved. Each ID must identify a caption track associated with the specified video.", - "location": "query" - }, - "onBehalfOf": { - "type": "string", - "description": "ID of the Google+ Page for the channel that the request is on behalf of.", - "location": "query" - }, - "onBehalfOfContentOwner": { - "type": "string", - "description": "Note: This parameter is intended exclusively for YouTube content partners.\n\nThe onBehalfOfContentOwner parameter indicates that the request's authorization credentials identify a YouTube CMS user who is acting on behalf of the content owner specified in the parameter value. This parameter is intended for YouTube content partners that own and manage many different YouTube channels. It allows content owners to authenticate once and get access to all their video and channel data, without having to provide authentication credentials for each individual channel. The actual CMS account that the user authenticates with must be linked to the specified YouTube content owner.", - "location": "query" - }, - "part": { - "type": "string", - "description": "The part parameter specifies a comma-separated list of one or more caption resource parts that the API response will include. The part names that you can include in the parameter value are id and snippet.", - "required": true, - "location": "query" - }, - "videoId": { - "type": "string", - "description": "The videoId parameter specifies the YouTube video ID of the video for which the API should return caption tracks.", - "required": true, - "location": "query" - } - }, - "parameterOrder": [ - "part", - "videoId" - ], - "response": { - "$ref": "CaptionListResponse" - }, - "scopes": [ - "https://www.googleapis.com/auth/youtube.force-ssl", - "https://www.googleapis.com/auth/youtubepartner" - ] - }, - "update": { - "id": "youtube.captions.update", - "path": "captions", - "httpMethod": "PUT", - "description": "Updates a caption track. When updating a caption track, you can change the track's draft status, upload a new caption file for the track, or both.", - "parameters": { - "onBehalfOf": { - "type": "string", - "description": "ID of the Google+ Page for the channel that the request is be on behalf of", - "location": "query" - }, - "onBehalfOfContentOwner": { - "type": "string", - "description": "Note: This parameter is intended exclusively for YouTube content partners.\n\nThe onBehalfOfContentOwner parameter indicates that the request's authorization credentials identify a YouTube CMS user who is acting on behalf of the content owner specified in the parameter value. This parameter is intended for YouTube content partners that own and manage many different YouTube channels. It allows content owners to authenticate once and get access to all their video and channel data, without having to provide authentication credentials for each individual channel. The actual CMS account that the user authenticates with must be linked to the specified YouTube content owner.", - "location": "query" - }, - "part": { - "type": "string", - "description": "The part parameter serves two purposes in this operation. It identifies the properties that the write operation will set as well as the properties that the API response will include. Set the property value to snippet if you are updating the track's draft status. Otherwise, set the property value to id.", - "required": true, - "location": "query" - }, - "sync": { - "type": "boolean", - "description": "Note: The API server only processes the parameter value if the request contains an updated caption file.\n\nThe sync parameter indicates whether YouTube should automatically synchronize the caption file with the audio track of the video. If you set the value to true, YouTube will automatically synchronize the caption track with the audio track.", - "location": "query" - } - }, - "parameterOrder": [ - "part" - ], - "request": { - "$ref": "Caption" - }, - "response": { - "$ref": "Caption" - }, - "scopes": [ - "https://www.googleapis.com/auth/youtube.force-ssl", - "https://www.googleapis.com/auth/youtubepartner" - ], - "supportsMediaUpload": true, - "mediaUpload": { - "accept": [ - "*/*", - "application/octet-stream", - "text/xml" - ], - "maxSize": "100MB", - "protocols": { - "simple": { - "multipart": true, - "path": "/upload/youtube/v3/captions" - }, - "resumable": { - "multipart": true, - "path": "/resumable/upload/youtube/v3/captions" - } - } - } - } - } - }, - "channelBanners": { - "methods": { - "insert": { - "id": "youtube.channelBanners.insert", - "path": "channelBanners/insert", - "httpMethod": "POST", - "description": "Uploads a channel banner image to YouTube. This method represents the first two steps in a three-step process to update the banner image for a channel:\n\n- Call the channelBanners.insert method to upload the binary image data to YouTube. The image must have a 16:9 aspect ratio and be at least 2120x1192 pixels.\n- Extract the url property's value from the response that the API returns for step 1.\n- Call the channels.update method to update the channel's branding settings. Set the brandingSettings.image.bannerExternalUrl property's value to the URL obtained in step 2.", - "parameters": { - "onBehalfOfContentOwner": { - "type": "string", - "description": "Note: This parameter is intended exclusively for YouTube content partners.\n\nThe onBehalfOfContentOwner parameter indicates that the request's authorization credentials identify a YouTube CMS user who is acting on behalf of the content owner specified in the parameter value. This parameter is intended for YouTube content partners that own and manage many different YouTube channels. It allows content owners to authenticate once and get access to all their video and channel data, without having to provide authentication credentials for each individual channel. The CMS account that the user authenticates with must be linked to the specified YouTube content owner.", - "location": "query" - } - }, - "request": { - "$ref": "ChannelBannerResource" - }, - "response": { - "$ref": "ChannelBannerResource" - }, - "scopes": [ - "https://www.googleapis.com/auth/youtube", - "https://www.googleapis.com/auth/youtube.force-ssl", - "https://www.googleapis.com/auth/youtube.upload" - ], - "supportsMediaUpload": true, - "mediaUpload": { - "accept": [ - "application/octet-stream", - "image/jpeg", - "image/png" - ], - "maxSize": "6MB", - "protocols": { - "simple": { - "multipart": true, - "path": "/upload/youtube/v3/channelBanners/insert" - }, - "resumable": { - "multipart": true, - "path": "/resumable/upload/youtube/v3/channelBanners/insert" - } - } - } - } - } - }, - "channelSections": { - "methods": { - "delete": { - "id": "youtube.channelSections.delete", - "path": "channelSections", - "httpMethod": "DELETE", - "description": "Deletes a channelSection.", - "parameters": { - "id": { - "type": "string", - "description": "The id parameter specifies the YouTube channelSection ID for the resource that is being deleted. In a channelSection resource, the id property specifies the YouTube channelSection ID.", - "required": true, - "location": "query" - }, - "onBehalfOfContentOwner": { - "type": "string", - "description": "Note: This parameter is intended exclusively for YouTube content partners.\n\nThe onBehalfOfContentOwner parameter indicates that the request's authorization credentials identify a YouTube CMS user who is acting on behalf of the content owner specified in the parameter value. This parameter is intended for YouTube content partners that own and manage many different YouTube channels. It allows content owners to authenticate once and get access to all their video and channel data, without having to provide authentication credentials for each individual channel. The CMS account that the user authenticates with must be linked to the specified YouTube content owner.", - "location": "query" - } - }, - "parameterOrder": [ - "id" - ], - "scopes": [ - "https://www.googleapis.com/auth/youtube", - "https://www.googleapis.com/auth/youtube.force-ssl", - "https://www.googleapis.com/auth/youtubepartner" - ] - }, - "insert": { - "id": "youtube.channelSections.insert", - "path": "channelSections", - "httpMethod": "POST", - "description": "Adds a channelSection for the authenticated user's channel.", - "parameters": { - "onBehalfOfContentOwner": { - "type": "string", - "description": "Note: This parameter is intended exclusively for YouTube content partners.\n\nThe onBehalfOfContentOwner parameter indicates that the request's authorization credentials identify a YouTube CMS user who is acting on behalf of the content owner specified in the parameter value. This parameter is intended for YouTube content partners that own and manage many different YouTube channels. It allows content owners to authenticate once and get access to all their video and channel data, without having to provide authentication credentials for each individual channel. The CMS account that the user authenticates with must be linked to the specified YouTube content owner.", - "location": "query" - }, - "onBehalfOfContentOwnerChannel": { - "type": "string", - "description": "This parameter can only be used in a properly authorized request. Note: This parameter is intended exclusively for YouTube content partners.\n\nThe onBehalfOfContentOwnerChannel parameter specifies the YouTube channel ID of the channel to which a video is being added. This parameter is required when a request specifies a value for the onBehalfOfContentOwner parameter, and it can only be used in conjunction with that parameter. In addition, the request must be authorized using a CMS account that is linked to the content owner that the onBehalfOfContentOwner parameter specifies. Finally, the channel that the onBehalfOfContentOwnerChannel parameter value specifies must be linked to the content owner that the onBehalfOfContentOwner parameter specifies.\n\nThis parameter is intended for YouTube content partners that own and manage many different YouTube channels. It allows content owners to authenticate once and perform actions on behalf of the channel specified in the parameter value, without having to provide authentication credentials for each separate channel.", - "location": "query" - }, - "part": { - "type": "string", - "description": "The part parameter serves two purposes in this operation. It identifies the properties that the write operation will set as well as the properties that the API response will include.\n\nThe part names that you can include in the parameter value are snippet and contentDetails.", - "required": true, - "location": "query" - } - }, - "parameterOrder": [ - "part" - ], - "request": { - "$ref": "ChannelSection" - }, - "response": { - "$ref": "ChannelSection" - }, - "scopes": [ - "https://www.googleapis.com/auth/youtube", - "https://www.googleapis.com/auth/youtube.force-ssl", - "https://www.googleapis.com/auth/youtubepartner" - ] - }, - "list": { - "id": "youtube.channelSections.list", - "path": "channelSections", - "httpMethod": "GET", - "description": "Returns channelSection resources that match the API request criteria.", - "parameters": { - "channelId": { - "type": "string", - "description": "The channelId parameter specifies a YouTube channel ID. The API will only return that channel's channelSections.", - "location": "query" - }, - "hl": { - "type": "string", - "description": "The hl parameter indicates that the snippet.localized property values in the returned channelSection resources should be in the specified language if localized values for that language are available. For example, if the API request specifies hl=de, the snippet.localized properties in the API response will contain German titles if German titles are available. Channel owners can provide localized channel section titles using either the channelSections.insert or channelSections.update method.", - "location": "query" - }, - "id": { - "type": "string", - "description": "The id parameter specifies a comma-separated list of the YouTube channelSection ID(s) for the resource(s) that are being retrieved. In a channelSection resource, the id property specifies the YouTube channelSection ID.", - "location": "query" - }, - "mine": { - "type": "boolean", - "description": "Set this parameter's value to true to retrieve a feed of the authenticated user's channelSections.", - "location": "query" - }, - "onBehalfOfContentOwner": { - "type": "string", - "description": "Note: This parameter is intended exclusively for YouTube content partners.\n\nThe onBehalfOfContentOwner parameter indicates that the request's authorization credentials identify a YouTube CMS user who is acting on behalf of the content owner specified in the parameter value. This parameter is intended for YouTube content partners that own and manage many different YouTube channels. It allows content owners to authenticate once and get access to all their video and channel data, without having to provide authentication credentials for each individual channel. The CMS account that the user authenticates with must be linked to the specified YouTube content owner.", - "location": "query" - }, - "part": { - "type": "string", - "description": "The part parameter specifies a comma-separated list of one or more channelSection resource properties that the API response will include. The part names that you can include in the parameter value are id, snippet, and contentDetails.\n\nIf the parameter identifies a property that contains child properties, the child properties will be included in the response. For example, in a channelSection resource, the snippet property contains other properties, such as a display title for the channelSection. If you set part=snippet, the API response will also contain all of those nested properties.", - "required": true, - "location": "query" - } - }, - "parameterOrder": [ - "part" - ], - "response": { - "$ref": "ChannelSectionListResponse" - }, - "scopes": [ - "https://www.googleapis.com/auth/youtube", - "https://www.googleapis.com/auth/youtube.force-ssl", - "https://www.googleapis.com/auth/youtube.readonly", - "https://www.googleapis.com/auth/youtubepartner" - ] - }, - "update": { - "id": "youtube.channelSections.update", - "path": "channelSections", - "httpMethod": "PUT", - "description": "Update a channelSection.", - "parameters": { - "onBehalfOfContentOwner": { - "type": "string", - "description": "Note: This parameter is intended exclusively for YouTube content partners.\n\nThe onBehalfOfContentOwner parameter indicates that the request's authorization credentials identify a YouTube CMS user who is acting on behalf of the content owner specified in the parameter value. This parameter is intended for YouTube content partners that own and manage many different YouTube channels. It allows content owners to authenticate once and get access to all their video and channel data, without having to provide authentication credentials for each individual channel. The CMS account that the user authenticates with must be linked to the specified YouTube content owner.", - "location": "query" - }, - "part": { - "type": "string", - "description": "The part parameter serves two purposes in this operation. It identifies the properties that the write operation will set as well as the properties that the API response will include.\n\nThe part names that you can include in the parameter value are snippet and contentDetails.", - "required": true, - "location": "query" - } - }, - "parameterOrder": [ - "part" - ], - "request": { - "$ref": "ChannelSection" - }, - "response": { - "$ref": "ChannelSection" - }, - "scopes": [ - "https://www.googleapis.com/auth/youtube", - "https://www.googleapis.com/auth/youtube.force-ssl", - "https://www.googleapis.com/auth/youtubepartner" - ] - } - } - }, - "channels": { - "methods": { - "list": { - "id": "youtube.channels.list", - "path": "channels", - "httpMethod": "GET", - "description": "Returns a collection of zero or more channel resources that match the request criteria.", - "parameters": { - "categoryId": { - "type": "string", - "description": "The categoryId parameter specifies a YouTube guide category, thereby requesting YouTube channels associated with that category.", - "location": "query" - }, - "forUsername": { - "type": "string", - "description": "The forUsername parameter specifies a YouTube username, thereby requesting the channel associated with that username.", - "location": "query" - }, - "hl": { - "type": "string", - "description": "The hl parameter should be used for filter out the properties that are not in the given language. Used for the brandingSettings part.", - "location": "query" - }, - "id": { - "type": "string", - "description": "The id parameter specifies a comma-separated list of the YouTube channel ID(s) for the resource(s) that are being retrieved. In a channel resource, the id property specifies the channel's YouTube channel ID.", - "location": "query" - }, - "managedByMe": { - "type": "boolean", - "description": "Note: This parameter is intended exclusively for YouTube content partners.\n\nSet this parameter's value to true to instruct the API to only return channels managed by the content owner that the onBehalfOfContentOwner parameter specifies. The user must be authenticated as a CMS account linked to the specified content owner and onBehalfOfContentOwner must be provided.", - "location": "query" - }, - "maxResults": { - "type": "integer", - "description": "The maxResults parameter specifies the maximum number of items that should be returned in the result set.", - "default": "5", - "format": "uint32", - "minimum": "0", - "maximum": "50", - "location": "query" - }, - "mine": { - "type": "boolean", - "description": "Set this parameter's value to true to instruct the API to only return channels owned by the authenticated user.", - "location": "query" - }, - "mySubscribers": { - "type": "boolean", - "description": "Use the subscriptions.list method and its mySubscribers parameter to retrieve a list of subscribers to the authenticated user's channel.", - "location": "query" - }, - "onBehalfOfContentOwner": { - "type": "string", - "description": "Note: This parameter is intended exclusively for YouTube content partners.\n\nThe onBehalfOfContentOwner parameter indicates that the request's authorization credentials identify a YouTube CMS user who is acting on behalf of the content owner specified in the parameter value. This parameter is intended for YouTube content partners that own and manage many different YouTube channels. It allows content owners to authenticate once and get access to all their video and channel data, without having to provide authentication credentials for each individual channel. The CMS account that the user authenticates with must be linked to the specified YouTube content owner.", - "location": "query" - }, - "pageToken": { - "type": "string", - "description": "The pageToken parameter identifies a specific page in the result set that should be returned. In an API response, the nextPageToken and prevPageToken properties identify other pages that could be retrieved.", - "location": "query" - }, - "part": { - "type": "string", - "description": "The part parameter specifies a comma-separated list of one or more channel resource properties that the API response will include.\n\nIf the parameter identifies a property that contains child properties, the child properties will be included in the response. For example, in a channel resource, the contentDetails property contains other properties, such as the uploads properties. As such, if you set part=contentDetails, the API response will also contain all of those nested properties.", - "required": true, - "location": "query" - } - }, - "parameterOrder": [ - "part" - ], - "response": { - "$ref": "ChannelListResponse" - }, - "scopes": [ - "https://www.googleapis.com/auth/youtube", - "https://www.googleapis.com/auth/youtube.force-ssl", - "https://www.googleapis.com/auth/youtube.readonly", - "https://www.googleapis.com/auth/youtubepartner", - "https://www.googleapis.com/auth/youtubepartner-channel-audit" - ] - }, - "update": { - "id": "youtube.channels.update", - "path": "channels", - "httpMethod": "PUT", - "description": "Updates a channel's metadata. Note that this method currently only supports updates to the channel resource's brandingSettings and invideoPromotion objects and their child properties.", - "parameters": { - "onBehalfOfContentOwner": { - "type": "string", - "description": "The onBehalfOfContentOwner parameter indicates that the authenticated user is acting on behalf of the content owner specified in the parameter value. This parameter is intended for YouTube content partners that own and manage many different YouTube channels. It allows content owners to authenticate once and get access to all their video and channel data, without having to provide authentication credentials for each individual channel. The actual CMS account that the user authenticates with needs to be linked to the specified YouTube content owner.", - "location": "query" - }, - "part": { - "type": "string", - "description": "The part parameter serves two purposes in this operation. It identifies the properties that the write operation will set as well as the properties that the API response will include.\n\nThe API currently only allows the parameter value to be set to either brandingSettings or invideoPromotion. (You cannot update both of those parts with a single request.)\n\nNote that this method overrides the existing values for all of the mutable properties that are contained in any parts that the parameter value specifies.", - "required": true, - "location": "query" - } - }, - "parameterOrder": [ - "part" - ], - "request": { - "$ref": "Channel" - }, - "response": { - "$ref": "Channel" - }, - "scopes": [ - "https://www.googleapis.com/auth/youtube", - "https://www.googleapis.com/auth/youtube.force-ssl", - "https://www.googleapis.com/auth/youtubepartner" - ] - } - } - }, - "commentThreads": { - "methods": { - "insert": { - "id": "youtube.commentThreads.insert", - "path": "commentThreads", - "httpMethod": "POST", - "description": "Creates a new top-level comment. To add a reply to an existing comment, use the comments.insert method instead.", - "parameters": { - "part": { - "type": "string", - "description": "The part parameter identifies the properties that the API response will include. Set the parameter value to snippet. The snippet part has a quota cost of 2 units.", - "required": true, - "location": "query" - } - }, - "parameterOrder": [ - "part" - ], - "request": { - "$ref": "CommentThread" - }, - "response": { - "$ref": "CommentThread" - }, - "scopes": [ - "https://www.googleapis.com/auth/youtube.force-ssl" - ] - }, - "list": { - "id": "youtube.commentThreads.list", - "path": "commentThreads", - "httpMethod": "GET", - "description": "Returns a list of comment threads that match the API request parameters.", - "parameters": { - "allThreadsRelatedToChannelId": { - "type": "string", - "description": "The allThreadsRelatedToChannelId parameter instructs the API to return all comment threads associated with the specified channel. The response can include comments about the channel or about the channel's videos.", - "location": "query" - }, - "channelId": { - "type": "string", - "description": "The channelId parameter instructs the API to return comment threads containing comments about the specified channel. (The response will not include comments left on videos that the channel uploaded.)", - "location": "query" - }, - "id": { - "type": "string", - "description": "The id parameter specifies a comma-separated list of comment thread IDs for the resources that should be retrieved.", - "location": "query" - }, - "maxResults": { - "type": "integer", - "description": "The maxResults parameter specifies the maximum number of items that should be returned in the result set.\n\nNote: This parameter is not supported for use in conjunction with the id parameter.", - "default": "20", - "format": "uint32", - "minimum": "1", - "maximum": "100", - "location": "query" - }, - "moderationStatus": { - "type": "string", - "description": "Set this parameter to limit the returned comment threads to a particular moderation state.\n\nNote: This parameter is not supported for use in conjunction with the id parameter.", - "default": "MODERATION_STATUS_PUBLISHED", - "enum": [ - "heldForReview", - "likelySpam", - "published" - ], - "enumDescriptions": [ - "Retrieve comment threads that are awaiting review by a moderator. A comment thread can be included in the response if the top-level comment or at least one of the replies to that comment are awaiting review.", - "Retrieve comment threads classified as likely to be spam. A comment thread can be included in the response if the top-level comment or at least one of the replies to that comment is considered likely to be spam.", - "Retrieve threads of published comments. This is the default value. A comment thread can be included in the response if its top-level comment has been published." - ], - "location": "query" - }, - "order": { - "type": "string", - "description": "The order parameter specifies the order in which the API response should list comment threads. Valid values are: \n- time - Comment threads are ordered by time. This is the default behavior.\n- relevance - Comment threads are ordered by relevance.Note: This parameter is not supported for use in conjunction with the id parameter.", - "default": "true", - "enum": [ - "relevance", - "time" - ], - "enumDescriptions": [ - "Order by relevance.", - "Order by time." - ], - "location": "query" - }, - "pageToken": { - "type": "string", - "description": "The pageToken parameter identifies a specific page in the result set that should be returned. In an API response, the nextPageToken property identifies the next page of the result that can be retrieved.\n\nNote: This parameter is not supported for use in conjunction with the id parameter.", - "location": "query" - }, - "part": { - "type": "string", - "description": "The part parameter specifies a comma-separated list of one or more commentThread resource properties that the API response will include.", - "required": true, - "location": "query" - }, - "searchTerms": { - "type": "string", - "description": "The searchTerms parameter instructs the API to limit the API response to only contain comments that contain the specified search terms.\n\nNote: This parameter is not supported for use in conjunction with the id parameter.", - "location": "query" - }, - "textFormat": { - "type": "string", - "description": "Set this parameter's value to html or plainText to instruct the API to return the comments left by users in html formatted or in plain text.", - "default": "FORMAT_HTML", - "enum": [ - "html", - "plainText" - ], - "enumDescriptions": [ - "Returns the comments in HTML format. This is the default value.", - "Returns the comments in plain text format." - ], - "location": "query" - }, - "videoId": { - "type": "string", - "description": "The videoId parameter instructs the API to return comment threads associated with the specified video ID.", - "location": "query" - } - }, - "parameterOrder": [ - "part" - ], - "response": { - "$ref": "CommentThreadListResponse" - }, - "scopes": [ - "https://www.googleapis.com/auth/youtube.force-ssl" - ] - }, - "update": { - "id": "youtube.commentThreads.update", - "path": "commentThreads", - "httpMethod": "PUT", - "description": "Modifies the top-level comment in a comment thread.", - "parameters": { - "part": { - "type": "string", - "description": "The part parameter specifies a comma-separated list of commentThread resource properties that the API response will include. You must at least include the snippet part in the parameter value since that part contains all of the properties that the API request can update.", - "required": true, - "location": "query" - } - }, - "parameterOrder": [ - "part" - ], - "request": { - "$ref": "CommentThread" - }, - "response": { - "$ref": "CommentThread" - }, - "scopes": [ - "https://www.googleapis.com/auth/youtube.force-ssl" - ] - } - } - }, - "comments": { - "methods": { - "delete": { - "id": "youtube.comments.delete", - "path": "comments", - "httpMethod": "DELETE", - "description": "Deletes a comment.", - "parameters": { - "id": { - "type": "string", - "description": "The id parameter specifies the comment ID for the resource that is being deleted.", - "required": true, - "location": "query" - } - }, - "parameterOrder": [ - "id" - ], - "scopes": [ - "https://www.googleapis.com/auth/youtube.force-ssl" - ] - }, - "insert": { - "id": "youtube.comments.insert", - "path": "comments", - "httpMethod": "POST", - "description": "Creates a reply to an existing comment. Note: To create a top-level comment, use the commentThreads.insert method.", - "parameters": { - "part": { - "type": "string", - "description": "The part parameter identifies the properties that the API response will include. Set the parameter value to snippet. The snippet part has a quota cost of 2 units.", - "required": true, - "location": "query" - } - }, - "parameterOrder": [ - "part" - ], - "request": { - "$ref": "Comment" - }, - "response": { - "$ref": "Comment" - }, - "scopes": [ - "https://www.googleapis.com/auth/youtube.force-ssl" - ] - }, - "list": { - "id": "youtube.comments.list", - "path": "comments", - "httpMethod": "GET", - "description": "Returns a list of comments that match the API request parameters.", - "parameters": { - "id": { - "type": "string", - "description": "The id parameter specifies a comma-separated list of comment IDs for the resources that are being retrieved. In a comment resource, the id property specifies the comment's ID.", - "location": "query" - }, - "maxResults": { - "type": "integer", - "description": "The maxResults parameter specifies the maximum number of items that should be returned in the result set.\n\nNote: This parameter is not supported for use in conjunction with the id parameter.", - "default": "20", - "format": "uint32", - "minimum": "1", - "maximum": "100", - "location": "query" - }, - "pageToken": { - "type": "string", - "description": "The pageToken parameter identifies a specific page in the result set that should be returned. In an API response, the nextPageToken property identifies the next page of the result that can be retrieved.\n\nNote: This parameter is not supported for use in conjunction with the id parameter.", - "location": "query" - }, - "parentId": { - "type": "string", - "description": "The parentId parameter specifies the ID of the comment for which replies should be retrieved.\n\nNote: YouTube currently supports replies only for top-level comments. However, replies to replies may be supported in the future.", - "location": "query" - }, - "part": { - "type": "string", - "description": "The part parameter specifies a comma-separated list of one or more comment resource properties that the API response will include.", - "required": true, - "location": "query" - }, - "textFormat": { - "type": "string", - "description": "This parameter indicates whether the API should return comments formatted as HTML or as plain text.", - "default": "FORMAT_HTML", - "enum": [ - "html", - "plainText" - ], - "enumDescriptions": [ - "Returns the comments in HTML format. This is the default value.", - "Returns the comments in plain text format." - ], - "location": "query" - } - }, - "parameterOrder": [ - "part" - ], - "response": { - "$ref": "CommentListResponse" - }, - "scopes": [ - "https://www.googleapis.com/auth/youtube.force-ssl" - ] - }, - "markAsSpam": { - "id": "youtube.comments.markAsSpam", - "path": "comments/markAsSpam", - "httpMethod": "POST", - "description": "Expresses the caller's opinion that one or more comments should be flagged as spam.", - "parameters": { - "id": { - "type": "string", - "description": "The id parameter specifies a comma-separated list of IDs of comments that the caller believes should be classified as spam.", - "required": true, - "location": "query" - } - }, - "parameterOrder": [ - "id" - ], - "scopes": [ - "https://www.googleapis.com/auth/youtube.force-ssl" - ] - }, - "setModerationStatus": { - "id": "youtube.comments.setModerationStatus", - "path": "comments/setModerationStatus", - "httpMethod": "POST", - "description": "Sets the moderation status of one or more comments. The API request must be authorized by the owner of the channel or video associated with the comments.", - "parameters": { - "banAuthor": { - "type": "boolean", - "description": "The banAuthor parameter lets you indicate that you want to automatically reject any additional comments written by the comment's author. Set the parameter value to true to ban the author.\n\nNote: This parameter is only valid if the moderationStatus parameter is also set to rejected.", - "default": "false", - "location": "query" - }, - "id": { - "type": "string", - "description": "The id parameter specifies a comma-separated list of IDs that identify the comments for which you are updating the moderation status.", - "required": true, - "location": "query" - }, - "moderationStatus": { - "type": "string", - "description": "Identifies the new moderation status of the specified comments.", - "required": true, - "enum": [ - "heldForReview", - "published", - "rejected" - ], - "enumDescriptions": [ - "Marks a comment as awaiting review by a moderator.", - "Clears a comment for public display.", - "Rejects a comment as being unfit for display. This action also effectively hides all replies to the rejected comment.\n\nNote: The API does not currently provide a way to list or otherwise discover rejected comments. However, you can change the moderation status of a rejected comment if you still know its ID. If you were to change the moderation status of a rejected comment, the comment replies would subsequently be discoverable again as well." - ], - "location": "query" - } - }, - "parameterOrder": [ - "id", - "moderationStatus" - ], - "scopes": [ - "https://www.googleapis.com/auth/youtube.force-ssl" - ] - }, - "update": { - "id": "youtube.comments.update", - "path": "comments", - "httpMethod": "PUT", - "description": "Modifies a comment.", - "parameters": { - "part": { - "type": "string", - "description": "The part parameter identifies the properties that the API response will include. You must at least include the snippet part in the parameter value since that part contains all of the properties that the API request can update.", - "required": true, - "location": "query" - } - }, - "parameterOrder": [ - "part" - ], - "request": { - "$ref": "Comment" - }, - "response": { - "$ref": "Comment" - }, - "scopes": [ - "https://www.googleapis.com/auth/youtube.force-ssl" - ] - } - } - }, - "fanFundingEvents": { - "methods": { - "list": { - "id": "youtube.fanFundingEvents.list", - "path": "fanFundingEvents", - "httpMethod": "GET", - "description": "Lists fan funding events for a channel.", - "parameters": { - "hl": { - "type": "string", - "description": "The hl parameter instructs the API to retrieve localized resource metadata for a specific application language that the YouTube website supports. The parameter value must be a language code included in the list returned by the i18nLanguages.list method.\n\nIf localized resource details are available in that language, the resource's snippet.localized object will contain the localized values. However, if localized details are not available, the snippet.localized object will contain resource details in the resource's default language.", - "location": "query" - }, - "maxResults": { - "type": "integer", - "description": "The maxResults parameter specifies the maximum number of items that should be returned in the result set.", - "default": "5", - "format": "uint32", - "minimum": "0", - "maximum": "50", - "location": "query" - }, - "pageToken": { - "type": "string", - "description": "The pageToken parameter identifies a specific page in the result set that should be returned. In an API response, the nextPageToken and prevPageToken properties identify other pages that could be retrieved.", - "location": "query" - }, - "part": { - "type": "string", - "description": "The part parameter specifies the fanFundingEvent resource parts that the API response will include. Supported values are id and snippet.", - "required": true, - "location": "query" - } - }, - "parameterOrder": [ - "part" - ], - "response": { - "$ref": "FanFundingEventListResponse" - }, - "scopes": [ - "https://www.googleapis.com/auth/youtube", - "https://www.googleapis.com/auth/youtube.force-ssl", - "https://www.googleapis.com/auth/youtube.readonly" - ] - } - } - }, - "guideCategories": { - "methods": { - "list": { - "id": "youtube.guideCategories.list", - "path": "guideCategories", - "httpMethod": "GET", - "description": "Returns a list of categories that can be associated with YouTube channels.", - "parameters": { - "hl": { - "type": "string", - "description": "The hl parameter specifies the language that will be used for text values in the API response.", - "default": "en-US", - "location": "query" - }, - "id": { - "type": "string", - "description": "The id parameter specifies a comma-separated list of the YouTube channel category ID(s) for the resource(s) that are being retrieved. In a guideCategory resource, the id property specifies the YouTube channel category ID.", - "location": "query" - }, - "part": { - "type": "string", - "description": "The part parameter specifies the guideCategory resource properties that the API response will include. Set the parameter value to snippet.", - "required": true, - "location": "query" - }, - "regionCode": { - "type": "string", - "description": "The regionCode parameter instructs the API to return the list of guide categories available in the specified country. The parameter value is an ISO 3166-1 alpha-2 country code.", - "location": "query" - } - }, - "parameterOrder": [ - "part" - ], - "response": { - "$ref": "GuideCategoryListResponse" - }, - "scopes": [ - "https://www.googleapis.com/auth/youtube", - "https://www.googleapis.com/auth/youtube.force-ssl", - "https://www.googleapis.com/auth/youtube.readonly", - "https://www.googleapis.com/auth/youtubepartner" - ] - } - } - }, - "i18nLanguages": { - "methods": { - "list": { - "id": "youtube.i18nLanguages.list", - "path": "i18nLanguages", - "httpMethod": "GET", - "description": "Returns a list of application languages that the YouTube website supports.", - "parameters": { - "hl": { - "type": "string", - "description": "The hl parameter specifies the language that should be used for text values in the API response.", - "default": "en_US", - "location": "query" - }, - "part": { - "type": "string", - "description": "The part parameter specifies the i18nLanguage resource properties that the API response will include. Set the parameter value to snippet.", - "required": true, - "location": "query" - } - }, - "parameterOrder": [ - "part" - ], - "response": { - "$ref": "I18nLanguageListResponse" - }, - "scopes": [ - "https://www.googleapis.com/auth/youtube", - "https://www.googleapis.com/auth/youtube.force-ssl", - "https://www.googleapis.com/auth/youtube.readonly", - "https://www.googleapis.com/auth/youtubepartner" - ] - } - } - }, - "i18nRegions": { - "methods": { - "list": { - "id": "youtube.i18nRegions.list", - "path": "i18nRegions", - "httpMethod": "GET", - "description": "Returns a list of content regions that the YouTube website supports.", - "parameters": { - "hl": { - "type": "string", - "description": "The hl parameter specifies the language that should be used for text values in the API response.", - "default": "en_US", - "location": "query" - }, - "part": { - "type": "string", - "description": "The part parameter specifies the i18nRegion resource properties that the API response will include. Set the parameter value to snippet.", - "required": true, - "location": "query" - } - }, - "parameterOrder": [ - "part" - ], - "response": { - "$ref": "I18nRegionListResponse" - }, - "scopes": [ - "https://www.googleapis.com/auth/youtube", - "https://www.googleapis.com/auth/youtube.force-ssl", - "https://www.googleapis.com/auth/youtube.readonly", - "https://www.googleapis.com/auth/youtubepartner" - ] - } - } - }, - "liveBroadcasts": { - "methods": { - "bind": { - "id": "youtube.liveBroadcasts.bind", - "path": "liveBroadcasts/bind", - "httpMethod": "POST", - "description": "Binds a YouTube broadcast to a stream or removes an existing binding between a broadcast and a stream. A broadcast can only be bound to one video stream, though a video stream may be bound to more than one broadcast.", - "parameters": { - "id": { - "type": "string", - "description": "The id parameter specifies the unique ID of the broadcast that is being bound to a video stream.", - "required": true, - "location": "query" - }, - "onBehalfOfContentOwner": { - "type": "string", - "description": "Note: This parameter is intended exclusively for YouTube content partners.\n\nThe onBehalfOfContentOwner parameter indicates that the request's authorization credentials identify a YouTube CMS user who is acting on behalf of the content owner specified in the parameter value. This parameter is intended for YouTube content partners that own and manage many different YouTube channels. It allows content owners to authenticate once and get access to all their video and channel data, without having to provide authentication credentials for each individual channel. The CMS account that the user authenticates with must be linked to the specified YouTube content owner.", - "location": "query" - }, - "onBehalfOfContentOwnerChannel": { - "type": "string", - "description": "This parameter can only be used in a properly authorized request. Note: This parameter is intended exclusively for YouTube content partners.\n\nThe onBehalfOfContentOwnerChannel parameter specifies the YouTube channel ID of the channel to which a video is being added. This parameter is required when a request specifies a value for the onBehalfOfContentOwner parameter, and it can only be used in conjunction with that parameter. In addition, the request must be authorized using a CMS account that is linked to the content owner that the onBehalfOfContentOwner parameter specifies. Finally, the channel that the onBehalfOfContentOwnerChannel parameter value specifies must be linked to the content owner that the onBehalfOfContentOwner parameter specifies.\n\nThis parameter is intended for YouTube content partners that own and manage many different YouTube channels. It allows content owners to authenticate once and perform actions on behalf of the channel specified in the parameter value, without having to provide authentication credentials for each separate channel.", - "location": "query" - }, - "part": { - "type": "string", - "description": "The part parameter specifies a comma-separated list of one or more liveBroadcast resource properties that the API response will include. The part names that you can include in the parameter value are id, snippet, contentDetails, and status.", - "required": true, - "location": "query" - }, - "streamId": { - "type": "string", - "description": "The streamId parameter specifies the unique ID of the video stream that is being bound to a broadcast. If this parameter is omitted, the API will remove any existing binding between the broadcast and a video stream.", - "location": "query" - } - }, - "parameterOrder": [ - "id", - "part" - ], - "response": { - "$ref": "LiveBroadcast" - }, - "scopes": [ - "https://www.googleapis.com/auth/youtube", - "https://www.googleapis.com/auth/youtube.force-ssl" - ] - }, - "control": { - "id": "youtube.liveBroadcasts.control", - "path": "liveBroadcasts/control", - "httpMethod": "POST", - "description": "Controls the settings for a slate that can be displayed in the broadcast stream.", - "parameters": { - "displaySlate": { - "type": "boolean", - "description": "The displaySlate parameter specifies whether the slate is being enabled or disabled.", - "location": "query" - }, - "id": { - "type": "string", - "description": "The id parameter specifies the YouTube live broadcast ID that uniquely identifies the broadcast in which the slate is being updated.", - "required": true, - "location": "query" - }, - "offsetTimeMs": { - "type": "string", - "description": "The offsetTimeMs parameter specifies a positive time offset when the specified slate change will occur. The value is measured in milliseconds from the beginning of the broadcast's monitor stream, which is the time that the testing phase for the broadcast began. Even though it is specified in milliseconds, the value is actually an approximation, and YouTube completes the requested action as closely as possible to that time.\n\nIf you do not specify a value for this parameter, then YouTube performs the action as soon as possible. See the Getting started guide for more details.\n\nImportant: You should only specify a value for this parameter if your broadcast stream is delayed.", - "format": "uint64", - "location": "query" - }, - "onBehalfOfContentOwner": { - "type": "string", - "description": "Note: This parameter is intended exclusively for YouTube content partners.\n\nThe onBehalfOfContentOwner parameter indicates that the request's authorization credentials identify a YouTube CMS user who is acting on behalf of the content owner specified in the parameter value. This parameter is intended for YouTube content partners that own and manage many different YouTube channels. It allows content owners to authenticate once and get access to all their video and channel data, without having to provide authentication credentials for each individual channel. The CMS account that the user authenticates with must be linked to the specified YouTube content owner.", - "location": "query" - }, - "onBehalfOfContentOwnerChannel": { - "type": "string", - "description": "This parameter can only be used in a properly authorized request. Note: This parameter is intended exclusively for YouTube content partners.\n\nThe onBehalfOfContentOwnerChannel parameter specifies the YouTube channel ID of the channel to which a video is being added. This parameter is required when a request specifies a value for the onBehalfOfContentOwner parameter, and it can only be used in conjunction with that parameter. In addition, the request must be authorized using a CMS account that is linked to the content owner that the onBehalfOfContentOwner parameter specifies. Finally, the channel that the onBehalfOfContentOwnerChannel parameter value specifies must be linked to the content owner that the onBehalfOfContentOwner parameter specifies.\n\nThis parameter is intended for YouTube content partners that own and manage many different YouTube channels. It allows content owners to authenticate once and perform actions on behalf of the channel specified in the parameter value, without having to provide authentication credentials for each separate channel.", - "location": "query" - }, - "part": { - "type": "string", - "description": "The part parameter specifies a comma-separated list of one or more liveBroadcast resource properties that the API response will include. The part names that you can include in the parameter value are id, snippet, contentDetails, and status.", - "required": true, - "location": "query" - }, - "walltime": { - "type": "string", - "description": "The walltime parameter specifies the wall clock time at which the specified slate change will occur. The value is specified in ISO 8601 (YYYY-MM-DDThh:mm:ss.sssZ) format.", - "format": "date-time", - "location": "query" - } - }, - "parameterOrder": [ - "id", - "part" - ], - "response": { - "$ref": "LiveBroadcast" - }, - "scopes": [ - "https://www.googleapis.com/auth/youtube", - "https://www.googleapis.com/auth/youtube.force-ssl" - ] - }, - "delete": { - "id": "youtube.liveBroadcasts.delete", - "path": "liveBroadcasts", - "httpMethod": "DELETE", - "description": "Deletes a broadcast.", - "parameters": { - "id": { - "type": "string", - "description": "The id parameter specifies the YouTube live broadcast ID for the resource that is being deleted.", - "required": true, - "location": "query" - }, - "onBehalfOfContentOwner": { - "type": "string", - "description": "Note: This parameter is intended exclusively for YouTube content partners.\n\nThe onBehalfOfContentOwner parameter indicates that the request's authorization credentials identify a YouTube CMS user who is acting on behalf of the content owner specified in the parameter value. This parameter is intended for YouTube content partners that own and manage many different YouTube channels. It allows content owners to authenticate once and get access to all their video and channel data, without having to provide authentication credentials for each individual channel. The CMS account that the user authenticates with must be linked to the specified YouTube content owner.", - "location": "query" - }, - "onBehalfOfContentOwnerChannel": { - "type": "string", - "description": "This parameter can only be used in a properly authorized request. Note: This parameter is intended exclusively for YouTube content partners.\n\nThe onBehalfOfContentOwnerChannel parameter specifies the YouTube channel ID of the channel to which a video is being added. This parameter is required when a request specifies a value for the onBehalfOfContentOwner parameter, and it can only be used in conjunction with that parameter. In addition, the request must be authorized using a CMS account that is linked to the content owner that the onBehalfOfContentOwner parameter specifies. Finally, the channel that the onBehalfOfContentOwnerChannel parameter value specifies must be linked to the content owner that the onBehalfOfContentOwner parameter specifies.\n\nThis parameter is intended for YouTube content partners that own and manage many different YouTube channels. It allows content owners to authenticate once and perform actions on behalf of the channel specified in the parameter value, without having to provide authentication credentials for each separate channel.", - "location": "query" - } - }, - "parameterOrder": [ - "id" - ], - "scopes": [ - "https://www.googleapis.com/auth/youtube", - "https://www.googleapis.com/auth/youtube.force-ssl" - ] - }, - "insert": { - "id": "youtube.liveBroadcasts.insert", - "path": "liveBroadcasts", - "httpMethod": "POST", - "description": "Creates a broadcast.", - "parameters": { - "onBehalfOfContentOwner": { - "type": "string", - "description": "Note: This parameter is intended exclusively for YouTube content partners.\n\nThe onBehalfOfContentOwner parameter indicates that the request's authorization credentials identify a YouTube CMS user who is acting on behalf of the content owner specified in the parameter value. This parameter is intended for YouTube content partners that own and manage many different YouTube channels. It allows content owners to authenticate once and get access to all their video and channel data, without having to provide authentication credentials for each individual channel. The CMS account that the user authenticates with must be linked to the specified YouTube content owner.", - "location": "query" - }, - "onBehalfOfContentOwnerChannel": { - "type": "string", - "description": "This parameter can only be used in a properly authorized request. Note: This parameter is intended exclusively for YouTube content partners.\n\nThe onBehalfOfContentOwnerChannel parameter specifies the YouTube channel ID of the channel to which a video is being added. This parameter is required when a request specifies a value for the onBehalfOfContentOwner parameter, and it can only be used in conjunction with that parameter. In addition, the request must be authorized using a CMS account that is linked to the content owner that the onBehalfOfContentOwner parameter specifies. Finally, the channel that the onBehalfOfContentOwnerChannel parameter value specifies must be linked to the content owner that the onBehalfOfContentOwner parameter specifies.\n\nThis parameter is intended for YouTube content partners that own and manage many different YouTube channels. It allows content owners to authenticate once and perform actions on behalf of the channel specified in the parameter value, without having to provide authentication credentials for each separate channel.", - "location": "query" - }, - "part": { - "type": "string", - "description": "The part parameter serves two purposes in this operation. It identifies the properties that the write operation will set as well as the properties that the API response will include.\n\nThe part properties that you can include in the parameter value are id, snippet, contentDetails, and status.", - "required": true, - "location": "query" - } - }, - "parameterOrder": [ - "part" - ], - "request": { - "$ref": "LiveBroadcast" - }, - "response": { - "$ref": "LiveBroadcast" - }, - "scopes": [ - "https://www.googleapis.com/auth/youtube", - "https://www.googleapis.com/auth/youtube.force-ssl" - ] - }, - "list": { - "id": "youtube.liveBroadcasts.list", - "path": "liveBroadcasts", - "httpMethod": "GET", - "description": "Returns a list of YouTube broadcasts that match the API request parameters.", - "parameters": { - "broadcastStatus": { - "type": "string", - "description": "The broadcastStatus parameter filters the API response to only include broadcasts with the specified status.", - "enum": [ - "active", - "all", - "completed", - "upcoming" - ], - "enumDescriptions": [ - "Return current live broadcasts.", - "Return all broadcasts.", - "Return broadcasts that have already ended.", - "Return broadcasts that have not yet started." - ], - "location": "query" - }, - "broadcastType": { - "type": "string", - "description": "The broadcastType parameter filters the API response to only include broadcasts with the specified type. This is only compatible with the mine filter for now.", - "default": "BROADCAST_TYPE_FILTER_EVENT", - "enum": [ - "all", - "event", - "persistent" - ], - "enumDescriptions": [ - "Return all broadcasts.", - "Return only scheduled event broadcasts.", - "Return only persistent broadcasts." - ], - "location": "query" - }, - "id": { - "type": "string", - "description": "The id parameter specifies a comma-separated list of YouTube broadcast IDs that identify the broadcasts being retrieved. In a liveBroadcast resource, the id property specifies the broadcast's ID.", - "location": "query" - }, - "maxResults": { - "type": "integer", - "description": "The maxResults parameter specifies the maximum number of items that should be returned in the result set.", - "default": "5", - "format": "uint32", - "minimum": "0", - "maximum": "50", - "location": "query" - }, - "mine": { - "type": "boolean", - "description": "The mine parameter can be used to instruct the API to only return broadcasts owned by the authenticated user. Set the parameter value to true to only retrieve your own broadcasts.", - "location": "query" - }, - "onBehalfOfContentOwner": { - "type": "string", - "description": "Note: This parameter is intended exclusively for YouTube content partners.\n\nThe onBehalfOfContentOwner parameter indicates that the request's authorization credentials identify a YouTube CMS user who is acting on behalf of the content owner specified in the parameter value. This parameter is intended for YouTube content partners that own and manage many different YouTube channels. It allows content owners to authenticate once and get access to all their video and channel data, without having to provide authentication credentials for each individual channel. The CMS account that the user authenticates with must be linked to the specified YouTube content owner.", - "location": "query" - }, - "onBehalfOfContentOwnerChannel": { - "type": "string", - "description": "This parameter can only be used in a properly authorized request. Note: This parameter is intended exclusively for YouTube content partners.\n\nThe onBehalfOfContentOwnerChannel parameter specifies the YouTube channel ID of the channel to which a video is being added. This parameter is required when a request specifies a value for the onBehalfOfContentOwner parameter, and it can only be used in conjunction with that parameter. In addition, the request must be authorized using a CMS account that is linked to the content owner that the onBehalfOfContentOwner parameter specifies. Finally, the channel that the onBehalfOfContentOwnerChannel parameter value specifies must be linked to the content owner that the onBehalfOfContentOwner parameter specifies.\n\nThis parameter is intended for YouTube content partners that own and manage many different YouTube channels. It allows content owners to authenticate once and perform actions on behalf of the channel specified in the parameter value, without having to provide authentication credentials for each separate channel.", - "location": "query" - }, - "pageToken": { - "type": "string", - "description": "The pageToken parameter identifies a specific page in the result set that should be returned. In an API response, the nextPageToken and prevPageToken properties identify other pages that could be retrieved.", - "location": "query" - }, - "part": { - "type": "string", - "description": "The part parameter specifies a comma-separated list of one or more liveBroadcast resource properties that the API response will include. The part names that you can include in the parameter value are id, snippet, contentDetails, and status.", - "required": true, - "location": "query" - } - }, - "parameterOrder": [ - "part" - ], - "response": { - "$ref": "LiveBroadcastListResponse" - }, - "scopes": [ - "https://www.googleapis.com/auth/youtube", - "https://www.googleapis.com/auth/youtube.force-ssl", - "https://www.googleapis.com/auth/youtube.readonly" - ] - }, - "transition": { - "id": "youtube.liveBroadcasts.transition", - "path": "liveBroadcasts/transition", - "httpMethod": "POST", - "description": "Changes the status of a YouTube live broadcast and initiates any processes associated with the new status. For example, when you transition a broadcast's status to testing, YouTube starts to transmit video to that broadcast's monitor stream. Before calling this method, you should confirm that the value of the status.streamStatus property for the stream bound to your broadcast is active.", - "parameters": { - "broadcastStatus": { - "type": "string", - "description": "The broadcastStatus parameter identifies the state to which the broadcast is changing. Note that to transition a broadcast to either the testing or live state, the status.streamStatus must be active for the stream that the broadcast is bound to.", - "required": true, - "enum": [ - "complete", - "live", - "testing" - ], - "enumDescriptions": [ - "The broadcast is over. YouTube stops transmitting video.", - "The broadcast is visible to its audience. YouTube transmits video to the broadcast's monitor stream and its broadcast stream.", - "Start testing the broadcast. YouTube transmits video to the broadcast's monitor stream. Note that you can only transition a broadcast to the testing state if its contentDetails.monitorStream.enableMonitorStream property is set to true." - ], - "location": "query" - }, - "id": { - "type": "string", - "description": "The id parameter specifies the unique ID of the broadcast that is transitioning to another status.", - "required": true, - "location": "query" - }, - "onBehalfOfContentOwner": { - "type": "string", - "description": "Note: This parameter is intended exclusively for YouTube content partners.\n\nThe onBehalfOfContentOwner parameter indicates that the request's authorization credentials identify a YouTube CMS user who is acting on behalf of the content owner specified in the parameter value. This parameter is intended for YouTube content partners that own and manage many different YouTube channels. It allows content owners to authenticate once and get access to all their video and channel data, without having to provide authentication credentials for each individual channel. The CMS account that the user authenticates with must be linked to the specified YouTube content owner.", - "location": "query" - }, - "onBehalfOfContentOwnerChannel": { - "type": "string", - "description": "This parameter can only be used in a properly authorized request. Note: This parameter is intended exclusively for YouTube content partners.\n\nThe onBehalfOfContentOwnerChannel parameter specifies the YouTube channel ID of the channel to which a video is being added. This parameter is required when a request specifies a value for the onBehalfOfContentOwner parameter, and it can only be used in conjunction with that parameter. In addition, the request must be authorized using a CMS account that is linked to the content owner that the onBehalfOfContentOwner parameter specifies. Finally, the channel that the onBehalfOfContentOwnerChannel parameter value specifies must be linked to the content owner that the onBehalfOfContentOwner parameter specifies.\n\nThis parameter is intended for YouTube content partners that own and manage many different YouTube channels. It allows content owners to authenticate once and perform actions on behalf of the channel specified in the parameter value, without having to provide authentication credentials for each separate channel.", - "location": "query" - }, - "part": { - "type": "string", - "description": "The part parameter specifies a comma-separated list of one or more liveBroadcast resource properties that the API response will include. The part names that you can include in the parameter value are id, snippet, contentDetails, and status.", - "required": true, - "location": "query" - } - }, - "parameterOrder": [ - "broadcastStatus", - "id", - "part" - ], - "response": { - "$ref": "LiveBroadcast" - }, - "scopes": [ - "https://www.googleapis.com/auth/youtube", - "https://www.googleapis.com/auth/youtube.force-ssl" - ] - }, - "update": { - "id": "youtube.liveBroadcasts.update", - "path": "liveBroadcasts", - "httpMethod": "PUT", - "description": "Updates a broadcast. For example, you could modify the broadcast settings defined in the liveBroadcast resource's contentDetails object.", - "parameters": { - "onBehalfOfContentOwner": { - "type": "string", - "description": "Note: This parameter is intended exclusively for YouTube content partners.\n\nThe onBehalfOfContentOwner parameter indicates that the request's authorization credentials identify a YouTube CMS user who is acting on behalf of the content owner specified in the parameter value. This parameter is intended for YouTube content partners that own and manage many different YouTube channels. It allows content owners to authenticate once and get access to all their video and channel data, without having to provide authentication credentials for each individual channel. The CMS account that the user authenticates with must be linked to the specified YouTube content owner.", - "location": "query" - }, - "onBehalfOfContentOwnerChannel": { - "type": "string", - "description": "This parameter can only be used in a properly authorized request. Note: This parameter is intended exclusively for YouTube content partners.\n\nThe onBehalfOfContentOwnerChannel parameter specifies the YouTube channel ID of the channel to which a video is being added. This parameter is required when a request specifies a value for the onBehalfOfContentOwner parameter, and it can only be used in conjunction with that parameter. In addition, the request must be authorized using a CMS account that is linked to the content owner that the onBehalfOfContentOwner parameter specifies. Finally, the channel that the onBehalfOfContentOwnerChannel parameter value specifies must be linked to the content owner that the onBehalfOfContentOwner parameter specifies.\n\nThis parameter is intended for YouTube content partners that own and manage many different YouTube channels. It allows content owners to authenticate once and perform actions on behalf of the channel specified in the parameter value, without having to provide authentication credentials for each separate channel.", - "location": "query" - }, - "part": { - "type": "string", - "description": "The part parameter serves two purposes in this operation. It identifies the properties that the write operation will set as well as the properties that the API response will include.\n\nThe part properties that you can include in the parameter value are id, snippet, contentDetails, and status.\n\nNote that this method will override the existing values for all of the mutable properties that are contained in any parts that the parameter value specifies. For example, a broadcast's privacy status is defined in the status part. As such, if your request is updating a private or unlisted broadcast, and the request's part parameter value includes the status part, the broadcast's privacy setting will be updated to whatever value the request body specifies. If the request body does not specify a value, the existing privacy setting will be removed and the broadcast will revert to the default privacy setting.", - "required": true, - "location": "query" - } - }, - "parameterOrder": [ - "part" - ], - "request": { - "$ref": "LiveBroadcast" - }, - "response": { - "$ref": "LiveBroadcast" - }, - "scopes": [ - "https://www.googleapis.com/auth/youtube", - "https://www.googleapis.com/auth/youtube.force-ssl" - ] - } - } - }, - "liveChatBans": { - "methods": { - "delete": { - "id": "youtube.liveChatBans.delete", - "path": "liveChat/bans", - "httpMethod": "DELETE", - "description": "Removes a chat ban.", - "parameters": { - "id": { - "type": "string", - "description": "The id parameter identifies the chat ban to remove. The value uniquely identifies both the ban and the chat.", - "required": true, - "location": "query" - } - }, - "parameterOrder": [ - "id" - ], - "scopes": [ - "https://www.googleapis.com/auth/youtube", - "https://www.googleapis.com/auth/youtube.force-ssl" - ] - }, - "insert": { - "id": "youtube.liveChatBans.insert", - "path": "liveChat/bans", - "httpMethod": "POST", - "description": "Adds a new ban to the chat.", - "parameters": { - "part": { - "type": "string", - "description": "The part parameter serves two purposes in this operation. It identifies the properties that the write operation will set as well as the properties that the API response returns. Set the parameter value to snippet.", - "required": true, - "location": "query" - } - }, - "parameterOrder": [ - "part" - ], - "request": { - "$ref": "LiveChatBan" - }, - "response": { - "$ref": "LiveChatBan" - }, - "scopes": [ - "https://www.googleapis.com/auth/youtube", - "https://www.googleapis.com/auth/youtube.force-ssl" - ] - } - } - }, - "liveChatMessages": { - "methods": { - "delete": { - "id": "youtube.liveChatMessages.delete", - "path": "liveChat/messages", - "httpMethod": "DELETE", - "description": "Deletes a chat message.", - "parameters": { - "id": { - "type": "string", - "description": "The id parameter specifies the YouTube chat message ID of the resource that is being deleted.", - "required": true, - "location": "query" - } - }, - "parameterOrder": [ - "id" - ], - "scopes": [ - "https://www.googleapis.com/auth/youtube", - "https://www.googleapis.com/auth/youtube.force-ssl" - ] - }, - "insert": { - "id": "youtube.liveChatMessages.insert", - "path": "liveChat/messages", - "httpMethod": "POST", - "description": "Adds a message to a live chat.", - "parameters": { - "part": { - "type": "string", - "description": "The part parameter serves two purposes. It identifies the properties that the write operation will set as well as the properties that the API response will include. Set the parameter value to snippet.", - "required": true, - "location": "query" - } - }, - "parameterOrder": [ - "part" - ], - "request": { - "$ref": "LiveChatMessage" - }, - "response": { - "$ref": "LiveChatMessage" - }, - "scopes": [ - "https://www.googleapis.com/auth/youtube", - "https://www.googleapis.com/auth/youtube.force-ssl" - ] - }, - "list": { - "id": "youtube.liveChatMessages.list", - "path": "liveChat/messages", - "httpMethod": "GET", - "description": "Lists live chat messages for a specific chat.", - "parameters": { - "hl": { - "type": "string", - "description": "The hl parameter instructs the API to retrieve localized resource metadata for a specific application language that the YouTube website supports. The parameter value must be a language code included in the list returned by the i18nLanguages.list method.\n\nIf localized resource details are available in that language, the resource's snippet.localized object will contain the localized values. However, if localized details are not available, the snippet.localized object will contain resource details in the resource's default language.", - "location": "query" - }, - "liveChatId": { - "type": "string", - "description": "The liveChatId parameter specifies the ID of the chat whose messages will be returned.", - "required": true, - "location": "query" - }, - "maxResults": { - "type": "integer", - "description": "The maxResults parameter specifies the maximum number of messages that should be returned in the result set.", - "default": "500", - "format": "uint32", - "minimum": "200", - "maximum": "2000", - "location": "query" - }, - "pageToken": { - "type": "string", - "description": "The pageToken parameter identifies a specific page in the result set that should be returned. In an API response, the nextPageToken property identify other pages that could be retrieved.", - "location": "query" - }, - "part": { - "type": "string", - "description": "The part parameter specifies the liveChatComment resource parts that the API response will include. Supported values are id and snippet.", - "required": true, - "location": "query" - }, - "profileImageSize": { - "type": "integer", - "description": "The profileImageSize parameter specifies the size of the user profile pictures that should be returned in the result set. Default: 88.", - "format": "uint32", - "minimum": "16", - "maximum": "720", - "location": "query" - } - }, - "parameterOrder": [ - "liveChatId", - "part" - ], - "response": { - "$ref": "LiveChatMessageListResponse" - }, - "scopes": [ - "https://www.googleapis.com/auth/youtube", - "https://www.googleapis.com/auth/youtube.force-ssl", - "https://www.googleapis.com/auth/youtube.readonly" - ] - } - } - }, - "liveChatModerators": { - "methods": { - "delete": { - "id": "youtube.liveChatModerators.delete", - "path": "liveChat/moderators", - "httpMethod": "DELETE", - "description": "Removes a chat moderator.", - "parameters": { - "id": { - "type": "string", - "description": "The id parameter identifies the chat moderator to remove. The value uniquely identifies both the moderator and the chat.", - "required": true, - "location": "query" - } - }, - "parameterOrder": [ - "id" - ], - "scopes": [ - "https://www.googleapis.com/auth/youtube", - "https://www.googleapis.com/auth/youtube.force-ssl" - ] - }, - "insert": { - "id": "youtube.liveChatModerators.insert", - "path": "liveChat/moderators", - "httpMethod": "POST", - "description": "Adds a new moderator for the chat.", - "parameters": { - "part": { - "type": "string", - "description": "The part parameter serves two purposes in this operation. It identifies the properties that the write operation will set as well as the properties that the API response returns. Set the parameter value to snippet.", - "required": true, - "location": "query" - } - }, - "parameterOrder": [ - "part" - ], - "request": { - "$ref": "LiveChatModerator" - }, - "response": { - "$ref": "LiveChatModerator" - }, - "scopes": [ - "https://www.googleapis.com/auth/youtube", - "https://www.googleapis.com/auth/youtube.force-ssl" - ] - }, - "list": { - "id": "youtube.liveChatModerators.list", - "path": "liveChat/moderators", - "httpMethod": "GET", - "description": "Lists moderators for a live chat.", - "parameters": { - "liveChatId": { - "type": "string", - "description": "The liveChatId parameter specifies the YouTube live chat for which the API should return moderators.", - "required": true, - "location": "query" - }, - "maxResults": { - "type": "integer", - "description": "The maxResults parameter specifies the maximum number of items that should be returned in the result set.", - "default": "5", - "format": "uint32", - "minimum": "0", - "maximum": "50", - "location": "query" - }, - "pageToken": { - "type": "string", - "description": "The pageToken parameter identifies a specific page in the result set that should be returned. In an API response, the nextPageToken and prevPageToken properties identify other pages that could be retrieved.", - "location": "query" - }, - "part": { - "type": "string", - "description": "The part parameter specifies the liveChatModerator resource parts that the API response will include. Supported values are id and snippet.", - "required": true, - "location": "query" - } - }, - "parameterOrder": [ - "liveChatId", - "part" - ], - "response": { - "$ref": "LiveChatModeratorListResponse" - }, - "scopes": [ - "https://www.googleapis.com/auth/youtube", - "https://www.googleapis.com/auth/youtube.force-ssl", - "https://www.googleapis.com/auth/youtube.readonly" - ] - } - } - }, - "liveStreams": { - "methods": { - "delete": { - "id": "youtube.liveStreams.delete", - "path": "liveStreams", - "httpMethod": "DELETE", - "description": "Deletes a video stream.", - "parameters": { - "id": { - "type": "string", - "description": "The id parameter specifies the YouTube live stream ID for the resource that is being deleted.", - "required": true, - "location": "query" - }, - "onBehalfOfContentOwner": { - "type": "string", - "description": "Note: This parameter is intended exclusively for YouTube content partners.\n\nThe onBehalfOfContentOwner parameter indicates that the request's authorization credentials identify a YouTube CMS user who is acting on behalf of the content owner specified in the parameter value. This parameter is intended for YouTube content partners that own and manage many different YouTube channels. It allows content owners to authenticate once and get access to all their video and channel data, without having to provide authentication credentials for each individual channel. The CMS account that the user authenticates with must be linked to the specified YouTube content owner.", - "location": "query" - }, - "onBehalfOfContentOwnerChannel": { - "type": "string", - "description": "This parameter can only be used in a properly authorized request. Note: This parameter is intended exclusively for YouTube content partners.\n\nThe onBehalfOfContentOwnerChannel parameter specifies the YouTube channel ID of the channel to which a video is being added. This parameter is required when a request specifies a value for the onBehalfOfContentOwner parameter, and it can only be used in conjunction with that parameter. In addition, the request must be authorized using a CMS account that is linked to the content owner that the onBehalfOfContentOwner parameter specifies. Finally, the channel that the onBehalfOfContentOwnerChannel parameter value specifies must be linked to the content owner that the onBehalfOfContentOwner parameter specifies.\n\nThis parameter is intended for YouTube content partners that own and manage many different YouTube channels. It allows content owners to authenticate once and perform actions on behalf of the channel specified in the parameter value, without having to provide authentication credentials for each separate channel.", - "location": "query" - } - }, - "parameterOrder": [ - "id" - ], - "scopes": [ - "https://www.googleapis.com/auth/youtube", - "https://www.googleapis.com/auth/youtube.force-ssl" - ] - }, - "insert": { - "id": "youtube.liveStreams.insert", - "path": "liveStreams", - "httpMethod": "POST", - "description": "Creates a video stream. The stream enables you to send your video to YouTube, which can then broadcast the video to your audience.", - "parameters": { - "onBehalfOfContentOwner": { - "type": "string", - "description": "Note: This parameter is intended exclusively for YouTube content partners.\n\nThe onBehalfOfContentOwner parameter indicates that the request's authorization credentials identify a YouTube CMS user who is acting on behalf of the content owner specified in the parameter value. This parameter is intended for YouTube content partners that own and manage many different YouTube channels. It allows content owners to authenticate once and get access to all their video and channel data, without having to provide authentication credentials for each individual channel. The CMS account that the user authenticates with must be linked to the specified YouTube content owner.", - "location": "query" - }, - "onBehalfOfContentOwnerChannel": { - "type": "string", - "description": "This parameter can only be used in a properly authorized request. Note: This parameter is intended exclusively for YouTube content partners.\n\nThe onBehalfOfContentOwnerChannel parameter specifies the YouTube channel ID of the channel to which a video is being added. This parameter is required when a request specifies a value for the onBehalfOfContentOwner parameter, and it can only be used in conjunction with that parameter. In addition, the request must be authorized using a CMS account that is linked to the content owner that the onBehalfOfContentOwner parameter specifies. Finally, the channel that the onBehalfOfContentOwnerChannel parameter value specifies must be linked to the content owner that the onBehalfOfContentOwner parameter specifies.\n\nThis parameter is intended for YouTube content partners that own and manage many different YouTube channels. It allows content owners to authenticate once and perform actions on behalf of the channel specified in the parameter value, without having to provide authentication credentials for each separate channel.", - "location": "query" - }, - "part": { - "type": "string", - "description": "The part parameter serves two purposes in this operation. It identifies the properties that the write operation will set as well as the properties that the API response will include.\n\nThe part properties that you can include in the parameter value are id, snippet, cdn, and status.", - "required": true, - "location": "query" - } - }, - "parameterOrder": [ - "part" - ], - "request": { - "$ref": "LiveStream" - }, - "response": { - "$ref": "LiveStream" - }, - "scopes": [ - "https://www.googleapis.com/auth/youtube", - "https://www.googleapis.com/auth/youtube.force-ssl" - ] - }, - "list": { - "id": "youtube.liveStreams.list", - "path": "liveStreams", - "httpMethod": "GET", - "description": "Returns a list of video streams that match the API request parameters.", - "parameters": { - "id": { - "type": "string", - "description": "The id parameter specifies a comma-separated list of YouTube stream IDs that identify the streams being retrieved. In a liveStream resource, the id property specifies the stream's ID.", - "location": "query" - }, - "maxResults": { - "type": "integer", - "description": "The maxResults parameter specifies the maximum number of items that should be returned in the result set.", - "default": "5", - "format": "uint32", - "minimum": "0", - "maximum": "50", - "location": "query" - }, - "mine": { - "type": "boolean", - "description": "The mine parameter can be used to instruct the API to only return streams owned by the authenticated user. Set the parameter value to true to only retrieve your own streams.", - "location": "query" - }, - "onBehalfOfContentOwner": { - "type": "string", - "description": "Note: This parameter is intended exclusively for YouTube content partners.\n\nThe onBehalfOfContentOwner parameter indicates that the request's authorization credentials identify a YouTube CMS user who is acting on behalf of the content owner specified in the parameter value. This parameter is intended for YouTube content partners that own and manage many different YouTube channels. It allows content owners to authenticate once and get access to all their video and channel data, without having to provide authentication credentials for each individual channel. The CMS account that the user authenticates with must be linked to the specified YouTube content owner.", - "location": "query" - }, - "onBehalfOfContentOwnerChannel": { - "type": "string", - "description": "This parameter can only be used in a properly authorized request. Note: This parameter is intended exclusively for YouTube content partners.\n\nThe onBehalfOfContentOwnerChannel parameter specifies the YouTube channel ID of the channel to which a video is being added. This parameter is required when a request specifies a value for the onBehalfOfContentOwner parameter, and it can only be used in conjunction with that parameter. In addition, the request must be authorized using a CMS account that is linked to the content owner that the onBehalfOfContentOwner parameter specifies. Finally, the channel that the onBehalfOfContentOwnerChannel parameter value specifies must be linked to the content owner that the onBehalfOfContentOwner parameter specifies.\n\nThis parameter is intended for YouTube content partners that own and manage many different YouTube channels. It allows content owners to authenticate once and perform actions on behalf of the channel specified in the parameter value, without having to provide authentication credentials for each separate channel.", - "location": "query" - }, - "pageToken": { - "type": "string", - "description": "The pageToken parameter identifies a specific page in the result set that should be returned. In an API response, the nextPageToken and prevPageToken properties identify other pages that could be retrieved.", - "location": "query" - }, - "part": { - "type": "string", - "description": "The part parameter specifies a comma-separated list of one or more liveStream resource properties that the API response will include. The part names that you can include in the parameter value are id, snippet, cdn, and status.", - "required": true, - "location": "query" - } - }, - "parameterOrder": [ - "part" - ], - "response": { - "$ref": "LiveStreamListResponse" - }, - "scopes": [ - "https://www.googleapis.com/auth/youtube", - "https://www.googleapis.com/auth/youtube.force-ssl", - "https://www.googleapis.com/auth/youtube.readonly" - ] - }, - "update": { - "id": "youtube.liveStreams.update", - "path": "liveStreams", - "httpMethod": "PUT", - "description": "Updates a video stream. If the properties that you want to change cannot be updated, then you need to create a new stream with the proper settings.", - "parameters": { - "onBehalfOfContentOwner": { - "type": "string", - "description": "Note: This parameter is intended exclusively for YouTube content partners.\n\nThe onBehalfOfContentOwner parameter indicates that the request's authorization credentials identify a YouTube CMS user who is acting on behalf of the content owner specified in the parameter value. This parameter is intended for YouTube content partners that own and manage many different YouTube channels. It allows content owners to authenticate once and get access to all their video and channel data, without having to provide authentication credentials for each individual channel. The CMS account that the user authenticates with must be linked to the specified YouTube content owner.", - "location": "query" - }, - "onBehalfOfContentOwnerChannel": { - "type": "string", - "description": "This parameter can only be used in a properly authorized request. Note: This parameter is intended exclusively for YouTube content partners.\n\nThe onBehalfOfContentOwnerChannel parameter specifies the YouTube channel ID of the channel to which a video is being added. This parameter is required when a request specifies a value for the onBehalfOfContentOwner parameter, and it can only be used in conjunction with that parameter. In addition, the request must be authorized using a CMS account that is linked to the content owner that the onBehalfOfContentOwner parameter specifies. Finally, the channel that the onBehalfOfContentOwnerChannel parameter value specifies must be linked to the content owner that the onBehalfOfContentOwner parameter specifies.\n\nThis parameter is intended for YouTube content partners that own and manage many different YouTube channels. It allows content owners to authenticate once and perform actions on behalf of the channel specified in the parameter value, without having to provide authentication credentials for each separate channel.", - "location": "query" - }, - "part": { - "type": "string", - "description": "The part parameter serves two purposes in this operation. It identifies the properties that the write operation will set as well as the properties that the API response will include.\n\nThe part properties that you can include in the parameter value are id, snippet, cdn, and status.\n\nNote that this method will override the existing values for all of the mutable properties that are contained in any parts that the parameter value specifies. If the request body does not specify a value for a mutable property, the existing value for that property will be removed.", - "required": true, - "location": "query" - } - }, - "parameterOrder": [ - "part" - ], - "request": { - "$ref": "LiveStream" - }, - "response": { - "$ref": "LiveStream" - }, - "scopes": [ - "https://www.googleapis.com/auth/youtube", - "https://www.googleapis.com/auth/youtube.force-ssl" - ] - } - } - }, - "playlistItems": { - "methods": { - "delete": { - "id": "youtube.playlistItems.delete", - "path": "playlistItems", - "httpMethod": "DELETE", - "description": "Deletes a playlist item.", - "parameters": { - "id": { - "type": "string", - "description": "The id parameter specifies the YouTube playlist item ID for the playlist item that is being deleted. In a playlistItem resource, the id property specifies the playlist item's ID.", - "required": true, - "location": "query" - }, - "onBehalfOfContentOwner": { - "type": "string", - "description": "Note: This parameter is intended exclusively for YouTube content partners.\n\nThe onBehalfOfContentOwner parameter indicates that the request's authorization credentials identify a YouTube CMS user who is acting on behalf of the content owner specified in the parameter value. This parameter is intended for YouTube content partners that own and manage many different YouTube channels. It allows content owners to authenticate once and get access to all their video and channel data, without having to provide authentication credentials for each individual channel. The CMS account that the user authenticates with must be linked to the specified YouTube content owner.", - "location": "query" - } - }, - "parameterOrder": [ - "id" - ], - "scopes": [ - "https://www.googleapis.com/auth/youtube", - "https://www.googleapis.com/auth/youtube.force-ssl", - "https://www.googleapis.com/auth/youtubepartner" - ] - }, - "insert": { - "id": "youtube.playlistItems.insert", - "path": "playlistItems", - "httpMethod": "POST", - "description": "Adds a resource to a playlist.", - "parameters": { - "onBehalfOfContentOwner": { - "type": "string", - "description": "Note: This parameter is intended exclusively for YouTube content partners.\n\nThe onBehalfOfContentOwner parameter indicates that the request's authorization credentials identify a YouTube CMS user who is acting on behalf of the content owner specified in the parameter value. This parameter is intended for YouTube content partners that own and manage many different YouTube channels. It allows content owners to authenticate once and get access to all their video and channel data, without having to provide authentication credentials for each individual channel. The CMS account that the user authenticates with must be linked to the specified YouTube content owner.", - "location": "query" - }, - "part": { - "type": "string", - "description": "The part parameter serves two purposes in this operation. It identifies the properties that the write operation will set as well as the properties that the API response will include.", - "required": true, - "location": "query" - } - }, - "parameterOrder": [ - "part" - ], - "request": { - "$ref": "PlaylistItem" - }, - "response": { - "$ref": "PlaylistItem" - }, - "scopes": [ - "https://www.googleapis.com/auth/youtube", - "https://www.googleapis.com/auth/youtube.force-ssl", - "https://www.googleapis.com/auth/youtubepartner" - ] - }, - "list": { - "id": "youtube.playlistItems.list", - "path": "playlistItems", - "httpMethod": "GET", - "description": "Returns a collection of playlist items that match the API request parameters. You can retrieve all of the playlist items in a specified playlist or retrieve one or more playlist items by their unique IDs.", - "parameters": { - "id": { - "type": "string", - "description": "The id parameter specifies a comma-separated list of one or more unique playlist item IDs.", - "location": "query" - }, - "maxResults": { - "type": "integer", - "description": "The maxResults parameter specifies the maximum number of items that should be returned in the result set.", - "default": "5", - "format": "uint32", - "minimum": "0", - "maximum": "50", - "location": "query" - }, - "onBehalfOfContentOwner": { - "type": "string", - "description": "Note: This parameter is intended exclusively for YouTube content partners.\n\nThe onBehalfOfContentOwner parameter indicates that the request's authorization credentials identify a YouTube CMS user who is acting on behalf of the content owner specified in the parameter value. This parameter is intended for YouTube content partners that own and manage many different YouTube channels. It allows content owners to authenticate once and get access to all their video and channel data, without having to provide authentication credentials for each individual channel. The CMS account that the user authenticates with must be linked to the specified YouTube content owner.", - "location": "query" - }, - "pageToken": { - "type": "string", - "description": "The pageToken parameter identifies a specific page in the result set that should be returned. In an API response, the nextPageToken and prevPageToken properties identify other pages that could be retrieved.", - "location": "query" - }, - "part": { - "type": "string", - "description": "The part parameter specifies a comma-separated list of one or more playlistItem resource properties that the API response will include.\n\nIf the parameter identifies a property that contains child properties, the child properties will be included in the response. For example, in a playlistItem resource, the snippet property contains numerous fields, including the title, description, position, and resourceId properties. As such, if you set part=snippet, the API response will contain all of those properties.", - "required": true, - "location": "query" - }, - "playlistId": { - "type": "string", - "description": "The playlistId parameter specifies the unique ID of the playlist for which you want to retrieve playlist items. Note that even though this is an optional parameter, every request to retrieve playlist items must specify a value for either the id parameter or the playlistId parameter.", - "location": "query" - }, - "videoId": { - "type": "string", - "description": "The videoId parameter specifies that the request should return only the playlist items that contain the specified video.", - "location": "query" - } - }, - "parameterOrder": [ - "part" - ], - "response": { - "$ref": "PlaylistItemListResponse" - }, - "scopes": [ - "https://www.googleapis.com/auth/youtube", - "https://www.googleapis.com/auth/youtube.force-ssl", - "https://www.googleapis.com/auth/youtube.readonly", - "https://www.googleapis.com/auth/youtubepartner" - ], - "supportsSubscription": true - }, - "update": { - "id": "youtube.playlistItems.update", - "path": "playlistItems", - "httpMethod": "PUT", - "description": "Modifies a playlist item. For example, you could update the item's position in the playlist.", - "parameters": { - "onBehalfOfContentOwner": { - "type": "string", - "description": "Note: This parameter is intended exclusively for YouTube content partners.\n\nThe onBehalfOfContentOwner parameter indicates that the request's authorization credentials identify a YouTube CMS user who is acting on behalf of the content owner specified in the parameter value. This parameter is intended for YouTube content partners that own and manage many different YouTube channels. It allows content owners to authenticate once and get access to all their video and channel data, without having to provide authentication credentials for each individual channel. The CMS account that the user authenticates with must be linked to the specified YouTube content owner.", - "location": "query" - }, - "part": { - "type": "string", - "description": "The part parameter serves two purposes in this operation. It identifies the properties that the write operation will set as well as the properties that the API response will include.\n\nNote that this method will override the existing values for all of the mutable properties that are contained in any parts that the parameter value specifies. For example, a playlist item can specify a start time and end time, which identify the times portion of the video that should play when users watch the video in the playlist. If your request is updating a playlist item that sets these values, and the request's part parameter value includes the contentDetails part, the playlist item's start and end times will be updated to whatever value the request body specifies. If the request body does not specify values, the existing start and end times will be removed and replaced with the default settings.", - "required": true, - "location": "query" - } - }, - "parameterOrder": [ - "part" - ], - "request": { - "$ref": "PlaylistItem" - }, - "response": { - "$ref": "PlaylistItem" - }, - "scopes": [ - "https://www.googleapis.com/auth/youtube", - "https://www.googleapis.com/auth/youtube.force-ssl", - "https://www.googleapis.com/auth/youtubepartner" - ] - } - } - }, - "playlists": { - "methods": { - "delete": { - "id": "youtube.playlists.delete", - "path": "playlists", - "httpMethod": "DELETE", - "description": "Deletes a playlist.", - "parameters": { - "id": { - "type": "string", - "description": "The id parameter specifies the YouTube playlist ID for the playlist that is being deleted. In a playlist resource, the id property specifies the playlist's ID.", - "required": true, - "location": "query" - }, - "onBehalfOfContentOwner": { - "type": "string", - "description": "Note: This parameter is intended exclusively for YouTube content partners.\n\nThe onBehalfOfContentOwner parameter indicates that the request's authorization credentials identify a YouTube CMS user who is acting on behalf of the content owner specified in the parameter value. This parameter is intended for YouTube content partners that own and manage many different YouTube channels. It allows content owners to authenticate once and get access to all their video and channel data, without having to provide authentication credentials for each individual channel. The CMS account that the user authenticates with must be linked to the specified YouTube content owner.", - "location": "query" - } - }, - "parameterOrder": [ - "id" - ], - "scopes": [ - "https://www.googleapis.com/auth/youtube", - "https://www.googleapis.com/auth/youtube.force-ssl", - "https://www.googleapis.com/auth/youtubepartner" - ] - }, - "insert": { - "id": "youtube.playlists.insert", - "path": "playlists", - "httpMethod": "POST", - "description": "Creates a playlist.", - "parameters": { - "onBehalfOfContentOwner": { - "type": "string", - "description": "Note: This parameter is intended exclusively for YouTube content partners.\n\nThe onBehalfOfContentOwner parameter indicates that the request's authorization credentials identify a YouTube CMS user who is acting on behalf of the content owner specified in the parameter value. This parameter is intended for YouTube content partners that own and manage many different YouTube channels. It allows content owners to authenticate once and get access to all their video and channel data, without having to provide authentication credentials for each individual channel. The CMS account that the user authenticates with must be linked to the specified YouTube content owner.", - "location": "query" - }, - "onBehalfOfContentOwnerChannel": { - "type": "string", - "description": "This parameter can only be used in a properly authorized request. Note: This parameter is intended exclusively for YouTube content partners.\n\nThe onBehalfOfContentOwnerChannel parameter specifies the YouTube channel ID of the channel to which a video is being added. This parameter is required when a request specifies a value for the onBehalfOfContentOwner parameter, and it can only be used in conjunction with that parameter. In addition, the request must be authorized using a CMS account that is linked to the content owner that the onBehalfOfContentOwner parameter specifies. Finally, the channel that the onBehalfOfContentOwnerChannel parameter value specifies must be linked to the content owner that the onBehalfOfContentOwner parameter specifies.\n\nThis parameter is intended for YouTube content partners that own and manage many different YouTube channels. It allows content owners to authenticate once and perform actions on behalf of the channel specified in the parameter value, without having to provide authentication credentials for each separate channel.", - "location": "query" - }, - "part": { - "type": "string", - "description": "The part parameter serves two purposes in this operation. It identifies the properties that the write operation will set as well as the properties that the API response will include.", - "required": true, - "location": "query" - } - }, - "parameterOrder": [ - "part" - ], - "request": { - "$ref": "Playlist" - }, - "response": { - "$ref": "Playlist" - }, - "scopes": [ - "https://www.googleapis.com/auth/youtube", - "https://www.googleapis.com/auth/youtube.force-ssl", - "https://www.googleapis.com/auth/youtubepartner" - ] - }, - "list": { - "id": "youtube.playlists.list", - "path": "playlists", - "httpMethod": "GET", - "description": "Returns a collection of playlists that match the API request parameters. For example, you can retrieve all playlists that the authenticated user owns, or you can retrieve one or more playlists by their unique IDs.", - "parameters": { - "channelId": { - "type": "string", - "description": "This value indicates that the API should only return the specified channel's playlists.", - "location": "query" - }, - "hl": { - "type": "string", - "description": "The hl parameter should be used for filter out the properties that are not in the given language. Used for the snippet part.", - "location": "query" - }, - "id": { - "type": "string", - "description": "The id parameter specifies a comma-separated list of the YouTube playlist ID(s) for the resource(s) that are being retrieved. In a playlist resource, the id property specifies the playlist's YouTube playlist ID.", - "location": "query" - }, - "maxResults": { - "type": "integer", - "description": "The maxResults parameter specifies the maximum number of items that should be returned in the result set.", - "default": "5", - "format": "uint32", - "minimum": "0", - "maximum": "50", - "location": "query" - }, - "mine": { - "type": "boolean", - "description": "Set this parameter's value to true to instruct the API to only return playlists owned by the authenticated user.", - "location": "query" - }, - "onBehalfOfContentOwner": { - "type": "string", - "description": "Note: This parameter is intended exclusively for YouTube content partners.\n\nThe onBehalfOfContentOwner parameter indicates that the request's authorization credentials identify a YouTube CMS user who is acting on behalf of the content owner specified in the parameter value. This parameter is intended for YouTube content partners that own and manage many different YouTube channels. It allows content owners to authenticate once and get access to all their video and channel data, without having to provide authentication credentials for each individual channel. The CMS account that the user authenticates with must be linked to the specified YouTube content owner.", - "location": "query" - }, - "onBehalfOfContentOwnerChannel": { - "type": "string", - "description": "This parameter can only be used in a properly authorized request. Note: This parameter is intended exclusively for YouTube content partners.\n\nThe onBehalfOfContentOwnerChannel parameter specifies the YouTube channel ID of the channel to which a video is being added. This parameter is required when a request specifies a value for the onBehalfOfContentOwner parameter, and it can only be used in conjunction with that parameter. In addition, the request must be authorized using a CMS account that is linked to the content owner that the onBehalfOfContentOwner parameter specifies. Finally, the channel that the onBehalfOfContentOwnerChannel parameter value specifies must be linked to the content owner that the onBehalfOfContentOwner parameter specifies.\n\nThis parameter is intended for YouTube content partners that own and manage many different YouTube channels. It allows content owners to authenticate once and perform actions on behalf of the channel specified in the parameter value, without having to provide authentication credentials for each separate channel.", - "location": "query" - }, - "pageToken": { - "type": "string", - "description": "The pageToken parameter identifies a specific page in the result set that should be returned. In an API response, the nextPageToken and prevPageToken properties identify other pages that could be retrieved.", - "location": "query" - }, - "part": { - "type": "string", - "description": "The part parameter specifies a comma-separated list of one or more playlist resource properties that the API response will include.\n\nIf the parameter identifies a property that contains child properties, the child properties will be included in the response. For example, in a playlist resource, the snippet property contains properties like author, title, description, tags, and timeCreated. As such, if you set part=snippet, the API response will contain all of those properties.", - "required": true, - "location": "query" - } - }, - "parameterOrder": [ - "part" - ], - "response": { - "$ref": "PlaylistListResponse" - }, - "scopes": [ - "https://www.googleapis.com/auth/youtube", - "https://www.googleapis.com/auth/youtube.force-ssl", - "https://www.googleapis.com/auth/youtube.readonly", - "https://www.googleapis.com/auth/youtubepartner" - ] - }, - "update": { - "id": "youtube.playlists.update", - "path": "playlists", - "httpMethod": "PUT", - "description": "Modifies a playlist. For example, you could change a playlist's title, description, or privacy status.", - "parameters": { - "onBehalfOfContentOwner": { - "type": "string", - "description": "Note: This parameter is intended exclusively for YouTube content partners.\n\nThe onBehalfOfContentOwner parameter indicates that the request's authorization credentials identify a YouTube CMS user who is acting on behalf of the content owner specified in the parameter value. This parameter is intended for YouTube content partners that own and manage many different YouTube channels. It allows content owners to authenticate once and get access to all their video and channel data, without having to provide authentication credentials for each individual channel. The CMS account that the user authenticates with must be linked to the specified YouTube content owner.", - "location": "query" - }, - "part": { - "type": "string", - "description": "The part parameter serves two purposes in this operation. It identifies the properties that the write operation will set as well as the properties that the API response will include.\n\nNote that this method will override the existing values for mutable properties that are contained in any parts that the request body specifies. For example, a playlist's description is contained in the snippet part, which must be included in the request body. If the request does not specify a value for the snippet.description property, the playlist's existing description will be deleted.", - "required": true, - "location": "query" - } - }, - "parameterOrder": [ - "part" - ], - "request": { - "$ref": "Playlist" - }, - "response": { - "$ref": "Playlist" - }, - "scopes": [ - "https://www.googleapis.com/auth/youtube", - "https://www.googleapis.com/auth/youtube.force-ssl", - "https://www.googleapis.com/auth/youtubepartner" - ] - } - } - }, - "search": { - "methods": { - "list": { - "id": "youtube.search.list", - "path": "search", - "httpMethod": "GET", - "description": "Returns a collection of search results that match the query parameters specified in the API request. By default, a search result set identifies matching video, channel, and playlist resources, but you can also configure queries to only retrieve a specific type of resource.", - "parameters": { - "channelId": { - "type": "string", - "description": "The channelId parameter indicates that the API response should only contain resources created by the channel", - "location": "query" - }, - "channelType": { - "type": "string", - "description": "The channelType parameter lets you restrict a search to a particular type of channel.", - "enum": [ - "any", - "show" - ], - "enumDescriptions": [ - "Return all channels.", - "Only retrieve shows." - ], - "location": "query" - }, - "eventType": { - "type": "string", - "description": "The eventType parameter restricts a search to broadcast events. If you specify a value for this parameter, you must also set the type parameter's value to video.", - "enum": [ - "completed", - "live", - "upcoming" - ], - "enumDescriptions": [ - "Only include completed broadcasts.", - "Only include active broadcasts.", - "Only include upcoming broadcasts." - ], - "location": "query" - }, - "forContentOwner": { - "type": "boolean", - "description": "Note: This parameter is intended exclusively for YouTube content partners.\n\nThe forContentOwner parameter restricts the search to only retrieve resources owned by the content owner specified by the onBehalfOfContentOwner parameter. The user must be authenticated using a CMS account linked to the specified content owner and onBehalfOfContentOwner must be provided.", - "location": "query" - }, - "forDeveloper": { - "type": "boolean", - "description": "The forDeveloper parameter restricts the search to only retrieve videos uploaded via the developer's application or website. The API server uses the request's authorization credentials to identify the developer. Therefore, a developer can restrict results to videos uploaded through the developer's own app or website but not to videos uploaded through other apps or sites.", - "location": "query" - }, - "forMine": { - "type": "boolean", - "description": "The forMine parameter restricts the search to only retrieve videos owned by the authenticated user. If you set this parameter to true, then the type parameter's value must also be set to video.", - "location": "query" - }, - "location": { - "type": "string", - "description": "The location parameter, in conjunction with the locationRadius parameter, defines a circular geographic area and also restricts a search to videos that specify, in their metadata, a geographic location that falls within that area. The parameter value is a string that specifies latitude/longitude coordinates e.g. (37.42307,-122.08427).\n\n\n- The location parameter value identifies the point at the center of the area.\n- The locationRadius parameter specifies the maximum distance that the location associated with a video can be from that point for the video to still be included in the search results.The API returns an error if your request specifies a value for the location parameter but does not also specify a value for the locationRadius parameter.", - "location": "query" - }, - "locationRadius": { - "type": "string", - "description": "The locationRadius parameter, in conjunction with the location parameter, defines a circular geographic area.\n\nThe parameter value must be a floating point number followed by a measurement unit. Valid measurement units are m, km, ft, and mi. For example, valid parameter values include 1500m, 5km, 10000ft, and 0.75mi. The API does not support locationRadius parameter values larger than 1000 kilometers.\n\nNote: See the definition of the location parameter for more information.", - "location": "query" - }, - "maxResults": { - "type": "integer", - "description": "The maxResults parameter specifies the maximum number of items that should be returned in the result set.", - "default": "5", - "format": "uint32", - "minimum": "0", - "maximum": "50", - "location": "query" - }, - "onBehalfOfContentOwner": { - "type": "string", - "description": "Note: This parameter is intended exclusively for YouTube content partners.\n\nThe onBehalfOfContentOwner parameter indicates that the request's authorization credentials identify a YouTube CMS user who is acting on behalf of the content owner specified in the parameter value. This parameter is intended for YouTube content partners that own and manage many different YouTube channels. It allows content owners to authenticate once and get access to all their video and channel data, without having to provide authentication credentials for each individual channel. The CMS account that the user authenticates with must be linked to the specified YouTube content owner.", - "location": "query" - }, - "order": { - "type": "string", - "description": "The order parameter specifies the method that will be used to order resources in the API response.", - "default": "SEARCH_SORT_RELEVANCE", - "enum": [ - "date", - "rating", - "relevance", - "title", - "videoCount", - "viewCount" - ], - "enumDescriptions": [ - "Resources are sorted in reverse chronological order based on the date they were created.", - "Resources are sorted from highest to lowest rating.", - "Resources are sorted based on their relevance to the search query. This is the default value for this parameter.", - "Resources are sorted alphabetically by title.", - "Channels are sorted in descending order of their number of uploaded videos.", - "Resources are sorted from highest to lowest number of views." - ], - "location": "query" - }, - "pageToken": { - "type": "string", - "description": "The pageToken parameter identifies a specific page in the result set that should be returned. In an API response, the nextPageToken and prevPageToken properties identify other pages that could be retrieved.", - "location": "query" - }, - "part": { - "type": "string", - "description": "The part parameter specifies a comma-separated list of one or more search resource properties that the API response will include. Set the parameter value to snippet.", - "required": true, - "location": "query" - }, - "publishedAfter": { - "type": "string", - "description": "The publishedAfter parameter indicates that the API response should only contain resources created after the specified time. The value is an RFC 3339 formatted date-time value (1970-01-01T00:00:00Z).", - "format": "date-time", - "location": "query" - }, - "publishedBefore": { - "type": "string", - "description": "The publishedBefore parameter indicates that the API response should only contain resources created before the specified time. The value is an RFC 3339 formatted date-time value (1970-01-01T00:00:00Z).", - "format": "date-time", - "location": "query" - }, - "q": { - "type": "string", - "description": "The q parameter specifies the query term to search for.\n\nYour request can also use the Boolean NOT (-) and OR (|) operators to exclude videos or to find videos that are associated with one of several search terms. For example, to search for videos matching either \"boating\" or \"sailing\", set the q parameter value to boating|sailing. Similarly, to search for videos matching either \"boating\" or \"sailing\" but not \"fishing\", set the q parameter value to boating|sailing -fishing. Note that the pipe character must be URL-escaped when it is sent in your API request. The URL-escaped value for the pipe character is %7C.", - "location": "query" - }, - "regionCode": { - "type": "string", - "description": "The regionCode parameter instructs the API to return search results for the specified country. The parameter value is an ISO 3166-1 alpha-2 country code.", - "location": "query" - }, - "relatedToVideoId": { - "type": "string", - "description": "The relatedToVideoId parameter retrieves a list of videos that are related to the video that the parameter value identifies. The parameter value must be set to a YouTube video ID and, if you are using this parameter, the type parameter must be set to video.", - "location": "query" - }, - "relevanceLanguage": { - "type": "string", - "description": "The relevanceLanguage parameter instructs the API to return search results that are most relevant to the specified language. The parameter value is typically an ISO 639-1 two-letter language code. However, you should use the values zh-Hans for simplified Chinese and zh-Hant for traditional Chinese. Please note that results in other languages will still be returned if they are highly relevant to the search query term.", - "location": "query" - }, - "safeSearch": { - "type": "string", - "description": "The safeSearch parameter indicates whether the search results should include restricted content as well as standard content.", - "enum": [ - "moderate", - "none", - "strict" - ], - "enumDescriptions": [ - "YouTube will filter some content from search results and, at the least, will filter content that is restricted in your locale. Based on their content, search results could be removed from search results or demoted in search results. This is the default parameter value.", - "YouTube will not filter the search result set.", - "YouTube will try to exclude all restricted content from the search result set. Based on their content, search results could be removed from search results or demoted in search results." - ], - "location": "query" - }, - "topicId": { - "type": "string", - "description": "The topicId parameter indicates that the API response should only contain resources associated with the specified topic. The value identifies a Freebase topic ID.", - "location": "query" - }, - "type": { - "type": "string", - "description": "The type parameter restricts a search query to only retrieve a particular type of resource. The value is a comma-separated list of resource types.", - "default": "video,channel,playlist", - "location": "query" - }, - "videoCaption": { - "type": "string", - "description": "The videoCaption parameter indicates whether the API should filter video search results based on whether they have captions. If you specify a value for this parameter, you must also set the type parameter's value to video.", - "enum": [ - "any", - "closedCaption", - "none" - ], - "enumDescriptions": [ - "Do not filter results based on caption availability.", - "Only include videos that have captions.", - "Only include videos that do not have captions." - ], - "location": "query" - }, - "videoCategoryId": { - "type": "string", - "description": "The videoCategoryId parameter filters video search results based on their category. If you specify a value for this parameter, you must also set the type parameter's value to video.", - "location": "query" - }, - "videoDefinition": { - "type": "string", - "description": "The videoDefinition parameter lets you restrict a search to only include either high definition (HD) or standard definition (SD) videos. HD videos are available for playback in at least 720p, though higher resolutions, like 1080p, might also be available. If you specify a value for this parameter, you must also set the type parameter's value to video.", - "enum": [ - "any", - "high", - "standard" - ], - "enumDescriptions": [ - "Return all videos, regardless of their resolution.", - "Only retrieve HD videos.", - "Only retrieve videos in standard definition." - ], - "location": "query" - }, - "videoDimension": { - "type": "string", - "description": "The videoDimension parameter lets you restrict a search to only retrieve 2D or 3D videos. If you specify a value for this parameter, you must also set the type parameter's value to video.", - "enum": [ - "2d", - "3d", - "any" - ], - "enumDescriptions": [ - "Restrict search results to exclude 3D videos.", - "Restrict search results to only include 3D videos.", - "Include both 3D and non-3D videos in returned results. This is the default value." - ], - "location": "query" - }, - "videoDuration": { - "type": "string", - "description": "The videoDuration parameter filters video search results based on their duration. If you specify a value for this parameter, you must also set the type parameter's value to video.", - "enum": [ - "any", - "long", - "medium", - "short" - ], - "enumDescriptions": [ - "Do not filter video search results based on their duration. This is the default value.", - "Only include videos longer than 20 minutes.", - "Only include videos that are between four and 20 minutes long (inclusive).", - "Only include videos that are less than four minutes long." - ], - "location": "query" - }, - "videoEmbeddable": { - "type": "string", - "description": "The videoEmbeddable parameter lets you to restrict a search to only videos that can be embedded into a webpage. If you specify a value for this parameter, you must also set the type parameter's value to video.", - "enum": [ - "any", - "true" - ], - "enumDescriptions": [ - "Return all videos, embeddable or not.", - "Only retrieve embeddable videos." - ], - "location": "query" - }, - "videoLicense": { - "type": "string", - "description": "The videoLicense parameter filters search results to only include videos with a particular license. YouTube lets video uploaders choose to attach either the Creative Commons license or the standard YouTube license to each of their videos. If you specify a value for this parameter, you must also set the type parameter's value to video.", - "enum": [ - "any", - "creativeCommon", - "youtube" - ], - "enumDescriptions": [ - "Return all videos, regardless of which license they have, that match the query parameters.", - "Only return videos that have a Creative Commons license. Users can reuse videos with this license in other videos that they create. Learn more.", - "Only return videos that have the standard YouTube license." - ], - "location": "query" - }, - "videoSyndicated": { - "type": "string", - "description": "The videoSyndicated parameter lets you to restrict a search to only videos that can be played outside youtube.com. If you specify a value for this parameter, you must also set the type parameter's value to video.", - "enum": [ - "any", - "true" - ], - "enumDescriptions": [ - "Return all videos, syndicated or not.", - "Only retrieve syndicated videos." - ], - "location": "query" - }, - "videoType": { - "type": "string", - "description": "The videoType parameter lets you restrict a search to a particular type of videos. If you specify a value for this parameter, you must also set the type parameter's value to video.", - "enum": [ - "any", - "episode", - "movie" - ], - "enumDescriptions": [ - "Return all videos.", - "Only retrieve episodes of shows.", - "Only retrieve movies." - ], - "location": "query" - } - }, - "parameterOrder": [ - "part" - ], - "response": { - "$ref": "SearchListResponse" - }, - "scopes": [ - "https://www.googleapis.com/auth/youtube", - "https://www.googleapis.com/auth/youtube.force-ssl", - "https://www.googleapis.com/auth/youtube.readonly", - "https://www.googleapis.com/auth/youtubepartner" - ] - } - } - }, - "sponsors": { - "methods": { - "list": { - "id": "youtube.sponsors.list", - "path": "sponsors", - "httpMethod": "GET", - "description": "Lists sponsors for a channel.", - "parameters": { - "filter": { - "type": "string", - "description": "The filter parameter specifies which channel sponsors to return.", - "default": "POLL_NEWEST", - "enum": [ - "all", - "newest" - ], - "enumDescriptions": [ - "Return all sponsors, from newest to oldest.", - "Return the most recent sponsors, from newest to oldest." - ], - "location": "query" - }, - "maxResults": { - "type": "integer", - "description": "The maxResults parameter specifies the maximum number of items that should be returned in the result set.", - "default": "5", - "format": "uint32", - "minimum": "0", - "maximum": "50", - "location": "query" - }, - "pageToken": { - "type": "string", - "description": "The pageToken parameter identifies a specific page in the result set that should be returned. In an API response, the nextPageToken and prevPageToken properties identify other pages that could be retrieved.", - "location": "query" - }, - "part": { - "type": "string", - "description": "The part parameter specifies the sponsor resource parts that the API response will include. Supported values are id and snippet.", - "required": true, - "location": "query" - } - }, - "parameterOrder": [ - "part" - ], - "response": { - "$ref": "SponsorListResponse" - }, - "scopes": [ - "https://www.googleapis.com/auth/youtube", - "https://www.googleapis.com/auth/youtube.force-ssl", - "https://www.googleapis.com/auth/youtube.readonly" - ] - } - } - }, - "subscriptions": { - "methods": { - "delete": { - "id": "youtube.subscriptions.delete", - "path": "subscriptions", - "httpMethod": "DELETE", - "description": "Deletes a subscription.", - "parameters": { - "id": { - "type": "string", - "description": "The id parameter specifies the YouTube subscription ID for the resource that is being deleted. In a subscription resource, the id property specifies the YouTube subscription ID.", - "required": true, - "location": "query" - } - }, - "parameterOrder": [ - "id" - ], - "scopes": [ - "https://www.googleapis.com/auth/youtube", - "https://www.googleapis.com/auth/youtube.force-ssl", - "https://www.googleapis.com/auth/youtubepartner" - ] - }, - "insert": { - "id": "youtube.subscriptions.insert", - "path": "subscriptions", - "httpMethod": "POST", - "description": "Adds a subscription for the authenticated user's channel.", - "parameters": { - "part": { - "type": "string", - "description": "The part parameter serves two purposes in this operation. It identifies the properties that the write operation will set as well as the properties that the API response will include.", - "required": true, - "location": "query" - } - }, - "parameterOrder": [ - "part" - ], - "request": { - "$ref": "Subscription" - }, - "response": { - "$ref": "Subscription" - }, - "scopes": [ - "https://www.googleapis.com/auth/youtube", - "https://www.googleapis.com/auth/youtube.force-ssl", - "https://www.googleapis.com/auth/youtubepartner" - ] - }, - "list": { - "id": "youtube.subscriptions.list", - "path": "subscriptions", - "httpMethod": "GET", - "description": "Returns subscription resources that match the API request criteria.", - "parameters": { - "channelId": { - "type": "string", - "description": "The channelId parameter specifies a YouTube channel ID. The API will only return that channel's subscriptions.", - "location": "query" - }, - "forChannelId": { - "type": "string", - "description": "The forChannelId parameter specifies a comma-separated list of channel IDs. The API response will then only contain subscriptions matching those channels.", - "location": "query" - }, - "id": { - "type": "string", - "description": "The id parameter specifies a comma-separated list of the YouTube subscription ID(s) for the resource(s) that are being retrieved. In a subscription resource, the id property specifies the YouTube subscription ID.", - "location": "query" - }, - "maxResults": { - "type": "integer", - "description": "The maxResults parameter specifies the maximum number of items that should be returned in the result set.", - "default": "5", - "format": "uint32", - "minimum": "0", - "maximum": "50", - "location": "query" - }, - "mine": { - "type": "boolean", - "description": "Set this parameter's value to true to retrieve a feed of the authenticated user's subscriptions.", - "location": "query" - }, - "myRecentSubscribers": { - "type": "boolean", - "description": "Set this parameter's value to true to retrieve a feed of the subscribers of the authenticated user in reverse chronological order (newest first).", - "location": "query" - }, - "mySubscribers": { - "type": "boolean", - "description": "Set this parameter's value to true to retrieve a feed of the subscribers of the authenticated user in no particular order.", - "location": "query" - }, - "onBehalfOfContentOwner": { - "type": "string", - "description": "Note: This parameter is intended exclusively for YouTube content partners.\n\nThe onBehalfOfContentOwner parameter indicates that the request's authorization credentials identify a YouTube CMS user who is acting on behalf of the content owner specified in the parameter value. This parameter is intended for YouTube content partners that own and manage many different YouTube channels. It allows content owners to authenticate once and get access to all their video and channel data, without having to provide authentication credentials for each individual channel. The CMS account that the user authenticates with must be linked to the specified YouTube content owner.", - "location": "query" - }, - "onBehalfOfContentOwnerChannel": { - "type": "string", - "description": "This parameter can only be used in a properly authorized request. Note: This parameter is intended exclusively for YouTube content partners.\n\nThe onBehalfOfContentOwnerChannel parameter specifies the YouTube channel ID of the channel to which a video is being added. This parameter is required when a request specifies a value for the onBehalfOfContentOwner parameter, and it can only be used in conjunction with that parameter. In addition, the request must be authorized using a CMS account that is linked to the content owner that the onBehalfOfContentOwner parameter specifies. Finally, the channel that the onBehalfOfContentOwnerChannel parameter value specifies must be linked to the content owner that the onBehalfOfContentOwner parameter specifies.\n\nThis parameter is intended for YouTube content partners that own and manage many different YouTube channels. It allows content owners to authenticate once and perform actions on behalf of the channel specified in the parameter value, without having to provide authentication credentials for each separate channel.", - "location": "query" - }, - "order": { - "type": "string", - "description": "The order parameter specifies the method that will be used to sort resources in the API response.", - "default": "SUBSCRIPTION_ORDER_RELEVANCE", - "enum": [ - "alphabetical", - "relevance", - "unread" - ], - "enumDescriptions": [ - "Sort alphabetically.", - "Sort by relevance.", - "Sort by order of activity." - ], - "location": "query" - }, - "pageToken": { - "type": "string", - "description": "The pageToken parameter identifies a specific page in the result set that should be returned. In an API response, the nextPageToken and prevPageToken properties identify other pages that could be retrieved.", - "location": "query" - }, - "part": { - "type": "string", - "description": "The part parameter specifies a comma-separated list of one or more subscription resource properties that the API response will include.\n\nIf the parameter identifies a property that contains child properties, the child properties will be included in the response. For example, in a subscription resource, the snippet property contains other properties, such as a display title for the subscription. If you set part=snippet, the API response will also contain all of those nested properties.", - "required": true, - "location": "query" - } - }, - "parameterOrder": [ - "part" - ], - "response": { - "$ref": "SubscriptionListResponse" - }, - "scopes": [ - "https://www.googleapis.com/auth/youtube", - "https://www.googleapis.com/auth/youtube.force-ssl", - "https://www.googleapis.com/auth/youtube.readonly", - "https://www.googleapis.com/auth/youtubepartner" - ] - } - } - }, - "superChatEvents": { - "methods": { - "list": { - "id": "youtube.superChatEvents.list", - "path": "superChatEvents", - "httpMethod": "GET", - "description": "Lists Super Chat events for a channel.", - "parameters": { - "hl": { - "type": "string", - "description": "The hl parameter instructs the API to retrieve localized resource metadata for a specific application language that the YouTube website supports. The parameter value must be a language code included in the list returned by the i18nLanguages.list method.\n\nIf localized resource details are available in that language, the resource's snippet.localized object will contain the localized values. However, if localized details are not available, the snippet.localized object will contain resource details in the resource's default language.", - "location": "query" - }, - "maxResults": { - "type": "integer", - "description": "The maxResults parameter specifies the maximum number of items that should be returned in the result set.", - "default": "5", - "format": "uint32", - "minimum": "0", - "maximum": "50", - "location": "query" - }, - "pageToken": { - "type": "string", - "description": "The pageToken parameter identifies a specific page in the result set that should be returned. In an API response, the nextPageToken and prevPageToken properties identify other pages that could be retrieved.", - "location": "query" - }, - "part": { - "type": "string", - "description": "The part parameter specifies the superChatEvent resource parts that the API response will include. Supported values are id and snippet.", - "required": true, - "location": "query" - } - }, - "parameterOrder": [ - "part" - ], - "response": { - "$ref": "SuperChatEventListResponse" - }, - "scopes": [ - "https://www.googleapis.com/auth/youtube", - "https://www.googleapis.com/auth/youtube.force-ssl", - "https://www.googleapis.com/auth/youtube.readonly" - ] - } - } - }, - "thumbnails": { - "methods": { - "set": { - "id": "youtube.thumbnails.set", - "path": "thumbnails/set", - "httpMethod": "POST", - "description": "Uploads a custom video thumbnail to YouTube and sets it for a video.", - "parameters": { - "onBehalfOfContentOwner": { - "type": "string", - "description": "Note: This parameter is intended exclusively for YouTube content partners.\n\nThe onBehalfOfContentOwner parameter indicates that the request's authorization credentials identify a YouTube CMS user who is acting on behalf of the content owner specified in the parameter value. This parameter is intended for YouTube content partners that own and manage many different YouTube channels. It allows content owners to authenticate once and get access to all their video and channel data, without having to provide authentication credentials for each individual channel. The actual CMS account that the user authenticates with must be linked to the specified YouTube content owner.", - "location": "query" - }, - "videoId": { - "type": "string", - "description": "The videoId parameter specifies a YouTube video ID for which the custom video thumbnail is being provided.", - "required": true, - "location": "query" - } - }, - "parameterOrder": [ - "videoId" - ], - "response": { - "$ref": "ThumbnailSetResponse" - }, - "scopes": [ - "https://www.googleapis.com/auth/youtube", - "https://www.googleapis.com/auth/youtube.force-ssl", - "https://www.googleapis.com/auth/youtube.upload", - "https://www.googleapis.com/auth/youtubepartner" - ], - "supportsMediaUpload": true, - "mediaUpload": { - "accept": [ - "application/octet-stream", - "image/jpeg", - "image/png" - ], - "maxSize": "2MB", - "protocols": { - "simple": { - "multipart": true, - "path": "/upload/youtube/v3/thumbnails/set" - }, - "resumable": { - "multipart": true, - "path": "/resumable/upload/youtube/v3/thumbnails/set" - } - } - } - } - } - }, - "videoAbuseReportReasons": { - "methods": { - "list": { - "id": "youtube.videoAbuseReportReasons.list", - "path": "videoAbuseReportReasons", - "httpMethod": "GET", - "description": "Returns a list of abuse reasons that can be used for reporting abusive videos.", - "parameters": { - "hl": { - "type": "string", - "description": "The hl parameter specifies the language that should be used for text values in the API response.", - "default": "en_US", - "location": "query" - }, - "part": { - "type": "string", - "description": "The part parameter specifies the videoCategory resource parts that the API response will include. Supported values are id and snippet.", - "required": true, - "location": "query" - } - }, - "parameterOrder": [ - "part" - ], - "response": { - "$ref": "VideoAbuseReportReasonListResponse" - }, - "scopes": [ - "https://www.googleapis.com/auth/youtube", - "https://www.googleapis.com/auth/youtube.force-ssl", - "https://www.googleapis.com/auth/youtube.readonly" - ] - } - } - }, - "videoCategories": { - "methods": { - "list": { - "id": "youtube.videoCategories.list", - "path": "videoCategories", - "httpMethod": "GET", - "description": "Returns a list of categories that can be associated with YouTube videos.", - "parameters": { - "hl": { - "type": "string", - "description": "The hl parameter specifies the language that should be used for text values in the API response.", - "default": "en_US", - "location": "query" - }, - "id": { - "type": "string", - "description": "The id parameter specifies a comma-separated list of video category IDs for the resources that you are retrieving.", - "location": "query" - }, - "part": { - "type": "string", - "description": "The part parameter specifies the videoCategory resource properties that the API response will include. Set the parameter value to snippet.", - "required": true, - "location": "query" - }, - "regionCode": { - "type": "string", - "description": "The regionCode parameter instructs the API to return the list of video categories available in the specified country. The parameter value is an ISO 3166-1 alpha-2 country code.", - "location": "query" - } - }, - "parameterOrder": [ - "part" - ], - "response": { - "$ref": "VideoCategoryListResponse" - }, - "scopes": [ - "https://www.googleapis.com/auth/youtube", - "https://www.googleapis.com/auth/youtube.force-ssl", - "https://www.googleapis.com/auth/youtube.readonly", - "https://www.googleapis.com/auth/youtubepartner" - ] - } - } - }, - "videos": { - "methods": { - "delete": { - "id": "youtube.videos.delete", - "path": "videos", - "httpMethod": "DELETE", - "description": "Deletes a YouTube video.", - "parameters": { - "id": { - "type": "string", - "description": "The id parameter specifies the YouTube video ID for the resource that is being deleted. In a video resource, the id property specifies the video's ID.", - "required": true, - "location": "query" - }, - "onBehalfOfContentOwner": { - "type": "string", - "description": "Note: This parameter is intended exclusively for YouTube content partners.\n\nThe onBehalfOfContentOwner parameter indicates that the request's authorization credentials identify a YouTube CMS user who is acting on behalf of the content owner specified in the parameter value. This parameter is intended for YouTube content partners that own and manage many different YouTube channels. It allows content owners to authenticate once and get access to all their video and channel data, without having to provide authentication credentials for each individual channel. The actual CMS account that the user authenticates with must be linked to the specified YouTube content owner.", - "location": "query" - } - }, - "parameterOrder": [ - "id" - ], - "scopes": [ - "https://www.googleapis.com/auth/youtube", - "https://www.googleapis.com/auth/youtube.force-ssl", - "https://www.googleapis.com/auth/youtubepartner" - ] - }, - "getRating": { - "id": "youtube.videos.getRating", - "path": "videos/getRating", - "httpMethod": "GET", - "description": "Retrieves the ratings that the authorized user gave to a list of specified videos.", - "parameters": { - "id": { - "type": "string", - "description": "The id parameter specifies a comma-separated list of the YouTube video ID(s) for the resource(s) for which you are retrieving rating data. In a video resource, the id property specifies the video's ID.", - "required": true, - "location": "query" - }, - "onBehalfOfContentOwner": { - "type": "string", - "description": "Note: This parameter is intended exclusively for YouTube content partners.\n\nThe onBehalfOfContentOwner parameter indicates that the request's authorization credentials identify a YouTube CMS user who is acting on behalf of the content owner specified in the parameter value. This parameter is intended for YouTube content partners that own and manage many different YouTube channels. It allows content owners to authenticate once and get access to all their video and channel data, without having to provide authentication credentials for each individual channel. The CMS account that the user authenticates with must be linked to the specified YouTube content owner.", - "location": "query" - } - }, - "parameterOrder": [ - "id" - ], - "response": { - "$ref": "VideoGetRatingResponse" - }, - "scopes": [ - "https://www.googleapis.com/auth/youtube", - "https://www.googleapis.com/auth/youtube.force-ssl", - "https://www.googleapis.com/auth/youtubepartner" - ] - }, - "insert": { - "id": "youtube.videos.insert", - "path": "videos", - "httpMethod": "POST", - "description": "Uploads a video to YouTube and optionally sets the video's metadata.", - "parameters": { - "autoLevels": { - "type": "boolean", - "description": "The autoLevels parameter indicates whether YouTube should automatically enhance the video's lighting and color.", - "location": "query" - }, - "notifySubscribers": { - "type": "boolean", - "description": "The notifySubscribers parameter indicates whether YouTube should send a notification about the new video to users who subscribe to the video's channel. A parameter value of True indicates that subscribers will be notified of newly uploaded videos. However, a channel owner who is uploading many videos might prefer to set the value to False to avoid sending a notification about each new video to the channel's subscribers.", - "default": "true", - "location": "query" - }, - "onBehalfOfContentOwner": { - "type": "string", - "description": "Note: This parameter is intended exclusively for YouTube content partners.\n\nThe onBehalfOfContentOwner parameter indicates that the request's authorization credentials identify a YouTube CMS user who is acting on behalf of the content owner specified in the parameter value. This parameter is intended for YouTube content partners that own and manage many different YouTube channels. It allows content owners to authenticate once and get access to all their video and channel data, without having to provide authentication credentials for each individual channel. The CMS account that the user authenticates with must be linked to the specified YouTube content owner.", - "location": "query" - }, - "onBehalfOfContentOwnerChannel": { - "type": "string", - "description": "This parameter can only be used in a properly authorized request. Note: This parameter is intended exclusively for YouTube content partners.\n\nThe onBehalfOfContentOwnerChannel parameter specifies the YouTube channel ID of the channel to which a video is being added. This parameter is required when a request specifies a value for the onBehalfOfContentOwner parameter, and it can only be used in conjunction with that parameter. In addition, the request must be authorized using a CMS account that is linked to the content owner that the onBehalfOfContentOwner parameter specifies. Finally, the channel that the onBehalfOfContentOwnerChannel parameter value specifies must be linked to the content owner that the onBehalfOfContentOwner parameter specifies.\n\nThis parameter is intended for YouTube content partners that own and manage many different YouTube channels. It allows content owners to authenticate once and perform actions on behalf of the channel specified in the parameter value, without having to provide authentication credentials for each separate channel.", - "location": "query" - }, - "part": { - "type": "string", - "description": "The part parameter serves two purposes in this operation. It identifies the properties that the write operation will set as well as the properties that the API response will include.\n\nNote that not all parts contain properties that can be set when inserting or updating a video. For example, the statistics object encapsulates statistics that YouTube calculates for a video and does not contain values that you can set or modify. If the parameter value specifies a part that does not contain mutable values, that part will still be included in the API response.", - "required": true, - "location": "query" - }, - "stabilize": { - "type": "boolean", - "description": "The stabilize parameter indicates whether YouTube should adjust the video to remove shaky camera motions.", - "location": "query" - } - }, - "parameterOrder": [ - "part" - ], - "request": { - "$ref": "Video" - }, - "response": { - "$ref": "Video" - }, - "scopes": [ - "https://www.googleapis.com/auth/youtube", - "https://www.googleapis.com/auth/youtube.force-ssl", - "https://www.googleapis.com/auth/youtube.upload", - "https://www.googleapis.com/auth/youtubepartner" - ], - "supportsMediaUpload": true, - "mediaUpload": { - "accept": [ - "application/octet-stream", - "video/*" - ], - "maxSize": "64GB", - "protocols": { - "simple": { - "multipart": true, - "path": "/upload/youtube/v3/videos" - }, - "resumable": { - "multipart": true, - "path": "/resumable/upload/youtube/v3/videos" - } - } - } - }, - "list": { - "id": "youtube.videos.list", - "path": "videos", - "httpMethod": "GET", - "description": "Returns a list of videos that match the API request parameters.", - "parameters": { - "chart": { - "type": "string", - "description": "The chart parameter identifies the chart that you want to retrieve.", - "enum": [ - "mostPopular" - ], - "enumDescriptions": [ - "Return the most popular videos for the specified content region and video category." - ], - "location": "query" - }, - "hl": { - "type": "string", - "description": "The hl parameter instructs the API to retrieve localized resource metadata for a specific application language that the YouTube website supports. The parameter value must be a language code included in the list returned by the i18nLanguages.list method.\n\nIf localized resource details are available in that language, the resource's snippet.localized object will contain the localized values. However, if localized details are not available, the snippet.localized object will contain resource details in the resource's default language.", - "location": "query" - }, - "id": { - "type": "string", - "description": "The id parameter specifies a comma-separated list of the YouTube video ID(s) for the resource(s) that are being retrieved. In a video resource, the id property specifies the video's ID.", - "location": "query" - }, - "locale": { - "type": "string", - "description": "DEPRECATED", - "location": "query" - }, - "maxHeight": { - "type": "integer", - "description": "The maxHeight parameter specifies a maximum height of the embedded player. If maxWidth is provided, maxHeight may not be reached in order to not violate the width request.", - "format": "uint32", - "minimum": "72", - "maximum": "8192", - "location": "query" - }, - "maxResults": { - "type": "integer", - "description": "The maxResults parameter specifies the maximum number of items that should be returned in the result set.\n\nNote: This parameter is supported for use in conjunction with the myRating and chart parameters, but it is not supported for use in conjunction with the id parameter.", - "default": "5", - "format": "uint32", - "minimum": "1", - "maximum": "50", - "location": "query" - }, - "maxWidth": { - "type": "integer", - "description": "The maxWidth parameter specifies a maximum width of the embedded player. If maxHeight is provided, maxWidth may not be reached in order to not violate the height request.", - "format": "uint32", - "minimum": "72", - "maximum": "8192", - "location": "query" - }, - "myRating": { - "type": "string", - "description": "Set this parameter's value to like or dislike to instruct the API to only return videos liked or disliked by the authenticated user.", - "enum": [ - "dislike", - "like" - ], - "enumDescriptions": [ - "Returns only videos disliked by the authenticated user.", - "Returns only video liked by the authenticated user." - ], - "location": "query" - }, - "onBehalfOfContentOwner": { - "type": "string", - "description": "Note: This parameter is intended exclusively for YouTube content partners.\n\nThe onBehalfOfContentOwner parameter indicates that the request's authorization credentials identify a YouTube CMS user who is acting on behalf of the content owner specified in the parameter value. This parameter is intended for YouTube content partners that own and manage many different YouTube channels. It allows content owners to authenticate once and get access to all their video and channel data, without having to provide authentication credentials for each individual channel. The CMS account that the user authenticates with must be linked to the specified YouTube content owner.", - "location": "query" - }, - "pageToken": { - "type": "string", - "description": "The pageToken parameter identifies a specific page in the result set that should be returned. In an API response, the nextPageToken and prevPageToken properties identify other pages that could be retrieved.\n\nNote: This parameter is supported for use in conjunction with the myRating and chart parameters, but it is not supported for use in conjunction with the id parameter.", - "location": "query" - }, - "part": { - "type": "string", - "description": "The part parameter specifies a comma-separated list of one or more video resource properties that the API response will include.\n\nIf the parameter identifies a property that contains child properties, the child properties will be included in the response. For example, in a video resource, the snippet property contains the channelId, title, description, tags, and categoryId properties. As such, if you set part=snippet, the API response will contain all of those properties.", - "required": true, - "location": "query" - }, - "regionCode": { - "type": "string", - "description": "The regionCode parameter instructs the API to select a video chart available in the specified region. This parameter can only be used in conjunction with the chart parameter. The parameter value is an ISO 3166-1 alpha-2 country code.", - "location": "query" - }, - "videoCategoryId": { - "type": "string", - "description": "The videoCategoryId parameter identifies the video category for which the chart should be retrieved. This parameter can only be used in conjunction with the chart parameter. By default, charts are not restricted to a particular category.", - "default": "0", - "location": "query" - } - }, - "parameterOrder": [ - "part" - ], - "response": { - "$ref": "VideoListResponse" - }, - "scopes": [ - "https://www.googleapis.com/auth/youtube", - "https://www.googleapis.com/auth/youtube.force-ssl", - "https://www.googleapis.com/auth/youtube.readonly", - "https://www.googleapis.com/auth/youtubepartner" - ] - }, - "rate": { - "id": "youtube.videos.rate", - "path": "videos/rate", - "httpMethod": "POST", - "description": "Add a like or dislike rating to a video or remove a rating from a video.", - "parameters": { - "id": { - "type": "string", - "description": "The id parameter specifies the YouTube video ID of the video that is being rated or having its rating removed.", - "required": true, - "location": "query" - }, - "rating": { - "type": "string", - "description": "Specifies the rating to record.", - "required": true, - "enum": [ - "dislike", - "like", - "none" - ], - "enumDescriptions": [ - "Records that the authenticated user disliked the video.", - "Records that the authenticated user liked the video.", - "Removes any rating that the authenticated user had previously set for the video." - ], - "location": "query" - } - }, - "parameterOrder": [ - "id", - "rating" - ], - "scopes": [ - "https://www.googleapis.com/auth/youtube", - "https://www.googleapis.com/auth/youtube.force-ssl", - "https://www.googleapis.com/auth/youtubepartner" - ] - }, - "reportAbuse": { - "id": "youtube.videos.reportAbuse", - "path": "videos/reportAbuse", - "httpMethod": "POST", - "description": "Report abuse for a video.", - "parameters": { - "onBehalfOfContentOwner": { - "type": "string", - "description": "Note: This parameter is intended exclusively for YouTube content partners.\n\nThe onBehalfOfContentOwner parameter indicates that the request's authorization credentials identify a YouTube CMS user who is acting on behalf of the content owner specified in the parameter value. This parameter is intended for YouTube content partners that own and manage many different YouTube channels. It allows content owners to authenticate once and get access to all their video and channel data, without having to provide authentication credentials for each individual channel. The CMS account that the user authenticates with must be linked to the specified YouTube content owner.", - "location": "query" - } - }, - "request": { - "$ref": "VideoAbuseReport" - }, - "scopes": [ - "https://www.googleapis.com/auth/youtube", - "https://www.googleapis.com/auth/youtube.force-ssl", - "https://www.googleapis.com/auth/youtubepartner" - ] - }, - "update": { - "id": "youtube.videos.update", - "path": "videos", - "httpMethod": "PUT", - "description": "Updates a video's metadata.", - "parameters": { - "onBehalfOfContentOwner": { - "type": "string", - "description": "Note: This parameter is intended exclusively for YouTube content partners.\n\nThe onBehalfOfContentOwner parameter indicates that the request's authorization credentials identify a YouTube CMS user who is acting on behalf of the content owner specified in the parameter value. This parameter is intended for YouTube content partners that own and manage many different YouTube channels. It allows content owners to authenticate once and get access to all their video and channel data, without having to provide authentication credentials for each individual channel. The actual CMS account that the user authenticates with must be linked to the specified YouTube content owner.", - "location": "query" - }, - "part": { - "type": "string", - "description": "The part parameter serves two purposes in this operation. It identifies the properties that the write operation will set as well as the properties that the API response will include.\n\nNote that this method will override the existing values for all of the mutable properties that are contained in any parts that the parameter value specifies. For example, a video's privacy setting is contained in the status part. As such, if your request is updating a private video, and the request's part parameter value includes the status part, the video's privacy setting will be updated to whatever value the request body specifies. If the request body does not specify a value, the existing privacy setting will be removed and the video will revert to the default privacy setting.\n\nIn addition, not all parts contain properties that can be set when inserting or updating a video. For example, the statistics object encapsulates statistics that YouTube calculates for a video and does not contain values that you can set or modify. If the parameter value specifies a part that does not contain mutable values, that part will still be included in the API response.", - "required": true, - "location": "query" - } - }, - "parameterOrder": [ - "part" - ], - "request": { - "$ref": "Video" - }, - "response": { - "$ref": "Video" - }, - "scopes": [ - "https://www.googleapis.com/auth/youtube", - "https://www.googleapis.com/auth/youtube.force-ssl", - "https://www.googleapis.com/auth/youtubepartner" - ] - } - } - }, - "watermarks": { - "methods": { - "set": { - "id": "youtube.watermarks.set", - "path": "watermarks/set", - "httpMethod": "POST", - "description": "Uploads a watermark image to YouTube and sets it for a channel.", - "parameters": { - "channelId": { - "type": "string", - "description": "The channelId parameter specifies the YouTube channel ID for which the watermark is being provided.", - "required": true, - "location": "query" - }, - "onBehalfOfContentOwner": { - "type": "string", - "description": "Note: This parameter is intended exclusively for YouTube content partners.\n\nThe onBehalfOfContentOwner parameter indicates that the request's authorization credentials identify a YouTube CMS user who is acting on behalf of the content owner specified in the parameter value. This parameter is intended for YouTube content partners that own and manage many different YouTube channels. It allows content owners to authenticate once and get access to all their video and channel data, without having to provide authentication credentials for each individual channel. The CMS account that the user authenticates with must be linked to the specified YouTube content owner.", - "location": "query" - } - }, - "parameterOrder": [ - "channelId" - ], - "request": { - "$ref": "InvideoBranding" - }, - "scopes": [ - "https://www.googleapis.com/auth/youtube", - "https://www.googleapis.com/auth/youtube.force-ssl", - "https://www.googleapis.com/auth/youtube.upload", - "https://www.googleapis.com/auth/youtubepartner" - ], - "supportsMediaUpload": true, - "mediaUpload": { - "accept": [ - "application/octet-stream", - "image/jpeg", - "image/png" - ], - "maxSize": "10MB", - "protocols": { - "simple": { - "multipart": true, - "path": "/upload/youtube/v3/watermarks/set" - }, - "resumable": { - "multipart": true, - "path": "/resumable/upload/youtube/v3/watermarks/set" - } - } - } - }, - "unset": { - "id": "youtube.watermarks.unset", - "path": "watermarks/unset", - "httpMethod": "POST", - "description": "Deletes a channel's watermark image.", - "parameters": { - "channelId": { - "type": "string", - "description": "The channelId parameter specifies the YouTube channel ID for which the watermark is being unset.", - "required": true, - "location": "query" - }, - "onBehalfOfContentOwner": { - "type": "string", - "description": "Note: This parameter is intended exclusively for YouTube content partners.\n\nThe onBehalfOfContentOwner parameter indicates that the request's authorization credentials identify a YouTube CMS user who is acting on behalf of the content owner specified in the parameter value. This parameter is intended for YouTube content partners that own and manage many different YouTube channels. It allows content owners to authenticate once and get access to all their video and channel data, without having to provide authentication credentials for each individual channel. The CMS account that the user authenticates with must be linked to the specified YouTube content owner.", - "location": "query" - } - }, - "parameterOrder": [ - "channelId" - ], - "scopes": [ - "https://www.googleapis.com/auth/youtube", - "https://www.googleapis.com/auth/youtube.force-ssl", - "https://www.googleapis.com/auth/youtubepartner" - ] - } - } - } - } -} diff --git a/test/data/youtube-playlistid.json b/test/data/youtube-playlistid.json deleted file mode 100644 index b69205f4342..00000000000 --- a/test/data/youtube-playlistid.json +++ /dev/null @@ -1 +0,0 @@ -{"regionCode": "US", "kind": "youtube#searchListResponse", "etag": "\"m2yskBQFythfE4irbTIeOgYYfBU/eoV8llUEbIu5LXnwqBaLOkOK0Hg\"", "pageInfo": {"resultsPerPage": 1, "totalResults": 1}, "items": [{"snippet": {"thumbnails": {"default": {"url": "https://i.ytimg.com/vi/lhYWB5FFkg4/default.jpg", "width": 120, "height": 90}, "high": {"url": "https://i.ytimg.com/vi/lhYWB5FFkg4/hqdefault.jpg", "width": 480, "height": 360}, "medium": {"url": "https://i.ytimg.com/vi/lhYWB5FFkg4/mqdefault.jpg", "width": 320, "height": 180}}, "title": "IETF98", "channelId": "UC8dtK9njBLdFnBahHFp0eZQ", "publishedAt": "2017-03-30T12:41:04.000Z", "liveBroadcastContent": "none", "channelTitle": "IETF - Internet Engineering Task Force", "description": "Videos from the IETF 98 Meeting held in Chicago, Illinois, United States 26-31 March 2017."}, "kind": "youtube#searchResult", "etag": "\"m2yskBQFythfE4irbTIeOgYYfBU/X3dbZGRvgpvedtOP0KLGhZLg5UI\"", "id": {"kind": "youtube#playlist", "playlistId": "PLC86T-test"}}]} diff --git a/test/data/youtube-playlistitems.json b/test/data/youtube-playlistitems.json deleted file mode 100644 index 4b42e3d21b9..00000000000 --- a/test/data/youtube-playlistitems.json +++ /dev/null @@ -1 +0,0 @@ -{"items": [{"snippet": {"playlistId": "PLC86T-6ZTP5jo6kIuqdyeYYhsKv9sUwG1", "thumbnails": {"default": {"url": "https://i.ytimg.com/vi/lhYWB5FFkg4/default.jpg", "width": 120, "height": 90}, "high": {"url": "https://i.ytimg.com/vi/lhYWB5FFkg4/hqdefault.jpg", "width": 480, "height": 360}, "medium": {"url": "https://i.ytimg.com/vi/lhYWB5FFkg4/mqdefault.jpg", "width": 320, "height": 180}, "maxres": {"url": "https://i.ytimg.com/vi/lhYWB5FFkg4/maxresdefault.jpg", "width": 1280, "height": 720}, "standard": {"url": "https://i.ytimg.com/vi/lhYWB5FFkg4/sddefault.jpg", "width": 640, "height": 480}}, "title": "IETF98 Wrap Up", "resourceId": {"kind": "youtube#video", "videoId": "lhYWB5FFkg4"}, "channelId": "UC8dtK9njBLdFnBahHFp0eZQ", "publishedAt": "2017-04-06T13:32:39.000Z", "channelTitle": "IETF - Internet Engineering Task Force", "position": 0, "description": "Jari Arkko and Alissa Cooper recap some highlights the IETF 98 meeting held 26-31 March 2017 in Chicago, Illinois, United States"}, "kind": "youtube#playlistItem", "etag": "\"m2yskBQFythfE4irbTIeOgYYfBU/eW_De3gQF2fRzN_rPBbX-kY7oBI\"", "id": "UExDODZULTZaVFA1am82a0l1cWR5ZVlZaHNLdjlzVXdHMS40OTQ5QjlEMDgzN0FBNUIw"}, {"snippet": {"playlistId": "PLC86T-6ZTP5jo6kIuqdyeYYhsKv9sUwG1", "thumbnails": {"default": {"url": "https://i.ytimg.com/vi/lPSTcBITbvs/default.jpg", "width": 120, "height": 90}, "high": {"url": "https://i.ytimg.com/vi/lPSTcBITbvs/hqdefault.jpg", "width": 480, "height": 360}, "medium": {"url": "https://i.ytimg.com/vi/lPSTcBITbvs/mqdefault.jpg", "width": 320, "height": 180}}, "title": "IETF 98 - QUIC Tutorial", "resourceId": {"kind": "youtube#video", "videoId": "lPSTcBITbvs"}, "channelId": "UC8dtK9njBLdFnBahHFp0eZQ", "publishedAt": "2017-03-30T12:41:35.000Z", "channelTitle": "IETF - Internet Engineering Task Force", "position": 1, "description": "A tutorial about the new QUIC protocol"}, "kind": "youtube#playlistItem", "etag": "\"m2yskBQFythfE4irbTIeOgYYfBU/GhKVt6zTuEpFavgtf9GWlWuzX9s\"", "id": "UExDODZULTZaVFA1am82a0l1cWR5ZVlZaHNLdjlzVXdHMS41NkI0NEY2RDEwNTU3Q0M2"}], "kind": "youtube#playlistItemListResponse", "etag": "\"m2yskBQFythfE4irbTIeOgYYfBU/jlFue-jZVpFMOuLUXQZH4Y0Lh3Y\"", "pageInfo": {"resultsPerPage": 2, "totalResults": 110}} diff --git a/test/lib/.gitignore b/test/lib/.gitignore deleted file mode 100644 index 330b0c2b644..00000000000 --- a/test/lib/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/django diff --git a/test/lib/README b/test/lib/README deleted file mode 100644 index 2dda507f05a..00000000000 --- a/test/lib/README +++ /dev/null @@ -1,9 +0,0 @@ -This directory will be used to set up packages used for testing if they need any -special handling which should not be applied to the system-wide setup. - -For instance, many of the tests to be run on the Django application should be run -with a standard Django environment; but there are some Django test features which -are broken in 0.9.6, and need patching in order to do the testing, like the ability -to create a test database to run unit tests, according to this issue and patch: -http://code.djangoproject.com/changeset/5106 - diff --git a/test/media/floor/.gitignore b/test/media/floor/.gitignore deleted file mode 100644 index 33662f5545b..00000000000 --- a/test/media/floor/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/* diff --git a/test/media/photo/.gitignore b/test/media/photo/.gitignore deleted file mode 100644 index 33662f5545b..00000000000 --- a/test/media/photo/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/* diff --git a/test/settings_local_test.py b/test/settings_local_test.py index 06d810e4af4..7097f76459e 100644 --- a/test/settings_local_test.py +++ b/test/settings_local_test.py @@ -5,6 +5,5 @@ SERVER_MODE = 'test' -IPR_DOCUMENT_PATH = '/home/ietf/adm/IPR/' SITE_ID = 1 diff --git a/vite.config.js b/vite.config.js index c9bc1fa3db2..048efa75ff0 100644 --- a/vite.config.js +++ b/vite.config.js @@ -1,24 +1,63 @@ import { defineConfig } from 'vite' +import { resolve } from 'path' import vue from '@vitejs/plugin-vue' +import servePreviewAssets from './dev/vite-plugins/serve-preview-assets' +import precompileLodashTemplates from './dev/vite-plugins/precompile-lodash-templates' // https://vitejs.dev/config/ -export default defineConfig({ - base: '/static/', - build: { - outDir: 'ietf/static/dist-neue', - manifest: true, - rollupOptions: { - input: { - agenda: 'client/agenda/main.js' +export default defineConfig(({ mode }) => { + const viteConfig = { + base: '/static/', + build: { + outDir: 'ietf/static/dist-neue', + manifest: true, + rollupOptions: { + input: { + main: 'client/main.js', + embedded: 'client/embedded.js' + } + }, + sourcemap: true + }, + cacheDir: '.vite', + plugins: [ + vue(), + precompileLodashTemplates({ + include: ['**/shared/urls.js'] + }) + ], + publicDir: 'ietf/static/public', + server: { + host: true, + port: 3000, + strictPort: true + }, + preview: { + host: true, + port: 3000, + strictPort: true + }, + css: { + preprocessorOptions: { + scss: { + quietDeps: true, + silenceDeprecations: [ + 'import', + 'if-function', + 'global-builtin', + 'color-functions', + 'legacy-js-api' + ] + } } } - }, - cacheDir: '.vite', - plugins: [ - vue() - ], - publicDir: 'ietf/static/public', - server: { - host: true } + if (mode === 'test') { + viteConfig.base = '/' + viteConfig.root = resolve(__dirname, 'client') + viteConfig.build.outDir = 'dist' + viteConfig.build.rollupOptions.input.main = resolve(__dirname, 'client/index.html') + viteConfig.plugins.push(servePreviewAssets()) + } + return viteConfig }) diff --git a/yarn.lock b/yarn.lock deleted file mode 100644 index 1a96ca9943e..00000000000 --- a/yarn.lock +++ /dev/null @@ -1,7889 +0,0 @@ -# This file is generated by running "yarn install" inside your project. -# Manual changes might be lost - proceed with caution! - -__metadata: - version: 6 - cacheKey: 8 - -"@babel/code-frame@npm:^7.0.0, @babel/code-frame@npm:^7.10.0, @babel/code-frame@npm:^7.16.0": - version: 7.16.7 - resolution: "@babel/code-frame@npm:7.16.7" - dependencies: - "@babel/highlight": ^7.16.7 - checksum: db2f7faa31bc2c9cf63197b481b30ea57147a5fc1a6fab60e5d6c02cdfbf6de8e17b5121f99917b3dabb5eeb572da078312e70697415940383efc140d4e0808b - languageName: node - linkType: hard - -"@babel/helper-validator-identifier@npm:^7.16.7": - version: 7.16.7 - resolution: "@babel/helper-validator-identifier@npm:7.16.7" - checksum: dbb3db9d184343152520a209b5684f5e0ed416109cde82b428ca9c759c29b10c7450657785a8b5c5256aa74acc6da491c1f0cf6b784939f7931ef82982051b69 - languageName: node - linkType: hard - -"@babel/highlight@npm:^7.16.7": - version: 7.17.12 - resolution: "@babel/highlight@npm:7.17.12" - dependencies: - "@babel/helper-validator-identifier": ^7.16.7 - chalk: ^2.0.0 - js-tokens: ^4.0.0 - checksum: 841a11aa353113bcce662b47085085a379251bf8b09054e37e1e082da1bf0d59355a556192a6b5e9ee98e8ee6f1f2831ac42510633c5e7043e3744dda2d6b9d6 - languageName: node - linkType: hard - -"@babel/parser@npm:^7.16.4, @babel/parser@npm:^7.6.0, @babel/parser@npm:^7.9.6": - version: 7.18.4 - resolution: "@babel/parser@npm:7.18.4" - bin: - parser: ./bin/babel-parser.js - checksum: e05b2dc720c4b200e088258f3c2a2de5041c140444edc38181d1217b10074e881a7133162c5b62356061f26279f08df5a06ec14c5842996ee8601ad03c57a44f - languageName: node - linkType: hard - -"@babel/types@npm:^7.6.1, @babel/types@npm:^7.8.3, @babel/types@npm:^7.9.6": - version: 7.18.4 - resolution: "@babel/types@npm:7.18.4" - dependencies: - "@babel/helper-validator-identifier": ^7.16.7 - to-fast-properties: ^2.0.0 - checksum: 85df59beb99c1b95e9e41590442f2ffa1e5b1b558d025489db40c9f7c906bd03a17da26c3ec486e5800e80af27c42ca7eee9506d9212ab17766d2d68d30fbf52 - languageName: node - linkType: hard - -"@bcoe/v8-coverage@npm:^0.2.3": - version: 0.2.3 - resolution: "@bcoe/v8-coverage@npm:0.2.3" - checksum: 850f9305536d0f2bd13e9e0881cb5f02e4f93fad1189f7b2d4bebf694e3206924eadee1068130d43c11b750efcc9405f88a8e42ef098b6d75239c0f047de1a27 - languageName: node - linkType: hard - -"@colors/colors@npm:1.5.0": - version: 1.5.0 - resolution: "@colors/colors@npm:1.5.0" - checksum: d64d5260bed1d5012ae3fc617d38d1afc0329fec05342f4e6b838f46998855ba56e0a73833f4a80fa8378c84810da254f76a8a19c39d038260dc06dc4e007425 - languageName: node - linkType: hard - -"@css-render/plugin-bem@npm:^0.15.10": - version: 0.15.10 - resolution: "@css-render/plugin-bem@npm:0.15.10" - peerDependencies: - css-render: ~0.15.10 - checksum: cbab72a7b5e6cec84041f8ea01b4e5c6d83e44f2a5c8e6cbba3b2a41a8b5ed5faf22390336d70648b5e471d7aab6b13123c0cdaea1bd21c6678d18abd399a203 - languageName: node - linkType: hard - -"@css-render/vue3-ssr@npm:^0.15.10": - version: 0.15.10 - resolution: "@css-render/vue3-ssr@npm:0.15.10" - peerDependencies: - vue: ^3.0.11 - checksum: 7977e0c440d34cd03743809313bea7362e913bf20acb988a1019bbbd8c2aa2c045794344b625fdd6d2bbb1bef9bcf9dccc866978d524b9a358389068c58c81a8 - languageName: node - linkType: hard - -"@cypress/request@npm:^2.88.10": - version: 2.88.10 - resolution: "@cypress/request@npm:2.88.10" - dependencies: - aws-sign2: ~0.7.0 - aws4: ^1.8.0 - caseless: ~0.12.0 - combined-stream: ~1.0.6 - extend: ~3.0.2 - forever-agent: ~0.6.1 - form-data: ~2.3.2 - http-signature: ~1.3.6 - is-typedarray: ~1.0.0 - isstream: ~0.1.2 - json-stringify-safe: ~5.0.1 - mime-types: ~2.1.19 - performance-now: ^2.1.0 - qs: ~6.5.2 - safe-buffer: ^5.1.2 - tough-cookie: ~2.5.0 - tunnel-agent: ^0.6.0 - uuid: ^8.3.2 - checksum: 69c3e3b332e9be4866a900f6bcca5d274d8cea6c99707fbcce061de8dbab11c9b1e39f4c017f6e83e6e682717781d4f6106fd6b7cf9546580fcfac353b6676cf - languageName: node - linkType: hard - -"@cypress/xvfb@npm:^1.2.4": - version: 1.2.4 - resolution: "@cypress/xvfb@npm:1.2.4" - dependencies: - debug: ^3.1.0 - lodash.once: ^4.1.1 - checksum: 7bdcdaeb1bb692ec9d9bf8ec52538aa0bead6764753f4a067a171a511807a43fab016f7285a56bef6a606c2467ff3f1365e1ad2d2d583b81beed849ee1573fd1 - languageName: node - linkType: hard - -"@emotion/hash@npm:~0.8.0": - version: 0.8.0 - resolution: "@emotion/hash@npm:0.8.0" - checksum: 4b35d88a97e67275c1d990c96d3b0450451d089d1508619488fc0acb882cb1ac91e93246d471346ebd1b5402215941ef4162efe5b51534859b39d8b3a0e3ffaa - languageName: node - linkType: hard - -"@eslint/eslintrc@npm:^1.3.0": - version: 1.3.0 - resolution: "@eslint/eslintrc@npm:1.3.0" - dependencies: - ajv: ^6.12.4 - debug: ^4.3.2 - espree: ^9.3.2 - globals: ^13.15.0 - ignore: ^5.2.0 - import-fresh: ^3.2.1 - js-yaml: ^4.1.0 - minimatch: ^3.1.2 - strip-json-comments: ^3.1.1 - checksum: a1e734ad31a8b5328dce9f479f185fd4fc83dd7f06c538e1fa457fd8226b89602a55cc6458cd52b29573b01cdfaf42331be8cfc1fec732570086b591f4ed6515 - languageName: node - linkType: hard - -"@fullcalendar/bootstrap5@npm:5.11.0": - version: 5.11.0 - resolution: "@fullcalendar/bootstrap5@npm:5.11.0" - dependencies: - "@fullcalendar/common": ~5.11.0 - tslib: ^2.1.0 - checksum: 164120b931ab2c07f312abcaa00ab832f4d828914ea0b74b0319e8477bc07d9ecd9f7d219b27453548484d02aad07ac0fc934e2ca98ce405b0028eb5589d0015 - languageName: node - linkType: hard - -"@fullcalendar/common@npm:~5.11.0": - version: 5.11.0 - resolution: "@fullcalendar/common@npm:5.11.0" - dependencies: - tslib: ^2.1.0 - checksum: 1bda749a433ec7d90f5f3438b205045652aec1ef7face62d490a3f76dfb5070c2e0831e14f3512bcce85ee1bdb758d8ef98d376f1368a49242621e46d293a5bd - languageName: node - linkType: hard - -"@fullcalendar/core@npm:5.11.0, @fullcalendar/core@npm:~5.11.0": - version: 5.11.0 - resolution: "@fullcalendar/core@npm:5.11.0" - dependencies: - "@fullcalendar/common": ~5.11.0 - preact: ^10.0.5 - tslib: ^2.1.0 - checksum: 20e60c65af127b3bde8340c7269f31cd776c16b0431821e91b685d4b193c6902fba8cad768b0567770046fe607898b45e8a089d05c51ad1233167ccb64aece4e - languageName: node - linkType: hard - -"@fullcalendar/daygrid@npm:5.11.0, @fullcalendar/daygrid@npm:~5.11.0": - version: 5.11.0 - resolution: "@fullcalendar/daygrid@npm:5.11.0" - dependencies: - "@fullcalendar/common": ~5.11.0 - tslib: ^2.1.0 - checksum: d30105222f76946a615a7560727c6fe3be7f51c37799f4f741e0ebccd9c4ee0256dbf9f2118e744df784be20cbff6629bb53b979b518f625f70bc234e32ab251 - languageName: node - linkType: hard - -"@fullcalendar/interaction@npm:5.11.0": - version: 5.11.0 - resolution: "@fullcalendar/interaction@npm:5.11.0" - dependencies: - "@fullcalendar/common": ~5.11.0 - tslib: ^2.1.0 - checksum: 625eb7ea331e56bb4539d4c2105c189342a9dca3d236f75a5a9ae2884595d480fb225444ff9feb1386cda07cbc92695c606921495922179b9f85b37877665db5 - languageName: node - linkType: hard - -"@fullcalendar/list@npm:5.11.0": - version: 5.11.0 - resolution: "@fullcalendar/list@npm:5.11.0" - dependencies: - "@fullcalendar/common": ~5.11.0 - tslib: ^2.1.0 - checksum: 08be90dbdfccfa9d3ffe60b9fc796a3ae98f47219629514ea484c50f34a4a0f18109df910c593d3e988b3e6b0ef2aaa87227e9b8cdbae826f9435421c8b1d2e9 - languageName: node - linkType: hard - -"@fullcalendar/luxon2@npm:5.11.0": - version: 5.11.0 - resolution: "@fullcalendar/luxon2@npm:5.11.0" - dependencies: - "@fullcalendar/common": ~5.11.0 - tslib: ^2.1.0 - peerDependencies: - luxon: ^2.0.0 - checksum: 7be523ce12b733ae83d818a89e75cdc9e3e47a41edcdc2c7731bc40f7c29344b0fc7ed4d5af092f6f92d9352511d72d7b52df1321f5ac472a7717468e1836502 - languageName: node - linkType: hard - -"@fullcalendar/timegrid@npm:5.11.0": - version: 5.11.0 - resolution: "@fullcalendar/timegrid@npm:5.11.0" - dependencies: - "@fullcalendar/common": ~5.11.0 - "@fullcalendar/daygrid": ~5.11.0 - tslib: ^2.1.0 - checksum: 4a7fb7fe3ece70ddd18bf684744ded9fd53d504880c576cf570cede79e1a58fe934258370be3ffb7b16d86a3802a4ad52b085d0c4a7394549b0ad07f9cb8ab0e - languageName: node - linkType: hard - -"@fullcalendar/vue3@npm:5.11.1": - version: 5.11.1 - resolution: "@fullcalendar/vue3@npm:5.11.1" - dependencies: - "@fullcalendar/core": ~5.11.0 - tslib: ^2.1.0 - peerDependencies: - vue: ^3.0.11 - checksum: 83ca9fecf5185c0c9cb9e7acbd5ec1f011dc61b13e242b63cd3cb3c3a1cde05f8ebf2b38bee3309c47440d9d7f063c929a960afcb0bb66f026e9af17642d96a4 - languageName: node - linkType: hard - -"@gar/promisify@npm:^1.1.3": - version: 1.1.3 - resolution: "@gar/promisify@npm:1.1.3" - checksum: 4059f790e2d07bf3c3ff3e0fec0daa8144fe35c1f6e0111c9921bd32106adaa97a4ab096ad7dab1e28ee6a9060083c4d1a4ada42a7f5f3f7a96b8812e2b757c1 - languageName: node - linkType: hard - -"@html-validate/stylish@npm:^3.0.0": - version: 3.0.0 - resolution: "@html-validate/stylish@npm:3.0.0" - dependencies: - kleur: ^4.0.0 - checksum: 818efd25ac4bd2fcc6728710edb064c0214d0c959a380b2026ae9d6a7d8e8bd153dad13a939aa042fa1fdf7e61cdde5eb13cc2031a7190a4e07e6c30ebb44a41 - languageName: node - linkType: hard - -"@humanwhocodes/config-array@npm:^0.9.2": - version: 0.9.5 - resolution: "@humanwhocodes/config-array@npm:0.9.5" - dependencies: - "@humanwhocodes/object-schema": ^1.2.1 - debug: ^4.1.1 - minimatch: ^3.0.4 - checksum: 8ba6281bc0590f6c6eadeefc14244b5a3e3f5903445aadd1a32099ed80e753037674026ce1b3c945ab93561bea5eb29e3c5bff67060e230c295595ba517a3492 - languageName: node - linkType: hard - -"@humanwhocodes/object-schema@npm:^1.2.1": - version: 1.2.1 - resolution: "@humanwhocodes/object-schema@npm:1.2.1" - checksum: a824a1ec31591231e4bad5787641f59e9633827d0a2eaae131a288d33c9ef0290bd16fda8da6f7c0fcb014147865d12118df10db57f27f41e20da92369fcb3f1 - languageName: node - linkType: hard - -"@istanbuljs/schema@npm:^0.1.2, @istanbuljs/schema@npm:^0.1.3": - version: 0.1.3 - resolution: "@istanbuljs/schema@npm:0.1.3" - checksum: 5282759d961d61350f33d9118d16bcaed914ebf8061a52f4fa474b2cb08720c9c81d165e13b82f2e5a8a212cc5af482f0c6fc1ac27b9e067e5394c9a6ed186c9 - languageName: node - linkType: hard - -"@jridgewell/resolve-uri@npm:^3.0.3": - version: 3.1.0 - resolution: "@jridgewell/resolve-uri@npm:3.1.0" - checksum: b5ceaaf9a110fcb2780d1d8f8d4a0bfd216702f31c988d8042e5f8fbe353c55d9b0f55a1733afdc64806f8e79c485d2464680ac48a0d9fcadb9548ee6b81d267 - languageName: node - linkType: hard - -"@jridgewell/sourcemap-codec@npm:^1.4.10": - version: 1.4.14 - resolution: "@jridgewell/sourcemap-codec@npm:1.4.14" - checksum: 61100637b6d173d3ba786a5dff019e1a74b1f394f323c1fee337ff390239f053b87266c7a948777f4b1ee68c01a8ad0ab61e5ff4abb5a012a0b091bec391ab97 - languageName: node - linkType: hard - -"@jridgewell/trace-mapping@npm:^0.3.12": - version: 0.3.14 - resolution: "@jridgewell/trace-mapping@npm:0.3.14" - dependencies: - "@jridgewell/resolve-uri": ^3.0.3 - "@jridgewell/sourcemap-codec": ^1.4.10 - checksum: b9537b9630ffb631aef9651a085fe361881cde1772cd482c257fe3c78c8fd5388d681f504a9c9fe1081b1c05e8f75edf55ee10fdb58d92bbaa8dbf6a7bd6b18c - languageName: node - linkType: hard - -"@juggle/resize-observer@npm:^3.3.1": - version: 3.3.1 - resolution: "@juggle/resize-observer@npm:3.3.1" - checksum: ddabc4044276a2cb57d469c4917206c7e39f2463aa8e3430e33e4eda554412afe29c22afa40e6708b49dad5d56768dc83acd68a704b1dcd49a0906bb96b991b2 - languageName: node - linkType: hard - -"@lezer/common@npm:^0.15.0, @lezer/common@npm:^0.15.7": - version: 0.15.12 - resolution: "@lezer/common@npm:0.15.12" - checksum: dae65816187bd690bf446bec116313d3b5328e70e3e1f7c806273d9356ca2017cf82aa650ea53b95260fb98898ea73d44f33319f9dbbd48d473e2f20771b2377 - languageName: node - linkType: hard - -"@lezer/lr@npm:^0.15.4": - version: 0.15.8 - resolution: "@lezer/lr@npm:0.15.8" - dependencies: - "@lezer/common": ^0.15.0 - checksum: e741225d6ac9cf08f8016bad49622fbd4a4e0d20c2e8c2b38a0abf0ddca69c58275b0ebdb9d5dde2905cf84f6977bc302f7ed5e5ba42c23afa27e9e65b900f36 - languageName: node - linkType: hard - -"@lmdb/lmdb-darwin-arm64@npm:2.5.2": - version: 2.5.2 - resolution: "@lmdb/lmdb-darwin-arm64@npm:2.5.2" - conditions: os=darwin & cpu=arm64 - languageName: node - linkType: hard - -"@lmdb/lmdb-darwin-x64@npm:2.5.2": - version: 2.5.2 - resolution: "@lmdb/lmdb-darwin-x64@npm:2.5.2" - conditions: os=darwin & cpu=x64 - languageName: node - linkType: hard - -"@lmdb/lmdb-linux-arm64@npm:2.5.2": - version: 2.5.2 - resolution: "@lmdb/lmdb-linux-arm64@npm:2.5.2" - conditions: os=linux & cpu=arm64 - languageName: node - linkType: hard - -"@lmdb/lmdb-linux-arm@npm:2.5.2": - version: 2.5.2 - resolution: "@lmdb/lmdb-linux-arm@npm:2.5.2" - conditions: os=linux & cpu=arm - languageName: node - linkType: hard - -"@lmdb/lmdb-linux-x64@npm:2.5.2": - version: 2.5.2 - resolution: "@lmdb/lmdb-linux-x64@npm:2.5.2" - conditions: os=linux & cpu=x64 - languageName: node - linkType: hard - -"@lmdb/lmdb-win32-x64@npm:2.5.2": - version: 2.5.2 - resolution: "@lmdb/lmdb-win32-x64@npm:2.5.2" - conditions: os=win32 & cpu=x64 - languageName: node - linkType: hard - -"@mischnic/json-sourcemap@npm:^0.1.0": - version: 0.1.0 - resolution: "@mischnic/json-sourcemap@npm:0.1.0" - dependencies: - "@lezer/common": ^0.15.7 - "@lezer/lr": ^0.15.4 - json5: ^2.2.1 - checksum: a30eda9eb02db5213b7aa2dc3c688257884a8969849ffa5a3a7c64c5f2a1cfed06691d94f02b37294a3a3b9efe7f88ee6b86c9ef20a799af54807ff2de2d253e - languageName: node - linkType: hard - -"@msgpackr-extract/msgpackr-extract-darwin-arm64@npm:2.0.2": - version: 2.0.2 - resolution: "@msgpackr-extract/msgpackr-extract-darwin-arm64@npm:2.0.2" - conditions: os=darwin & cpu=arm64 - languageName: node - linkType: hard - -"@msgpackr-extract/msgpackr-extract-darwin-x64@npm:2.0.2": - version: 2.0.2 - resolution: "@msgpackr-extract/msgpackr-extract-darwin-x64@npm:2.0.2" - conditions: os=darwin & cpu=x64 - languageName: node - linkType: hard - -"@msgpackr-extract/msgpackr-extract-linux-arm64@npm:2.0.2": - version: 2.0.2 - resolution: "@msgpackr-extract/msgpackr-extract-linux-arm64@npm:2.0.2" - conditions: os=linux & cpu=arm64 - languageName: node - linkType: hard - -"@msgpackr-extract/msgpackr-extract-linux-arm@npm:2.0.2": - version: 2.0.2 - resolution: "@msgpackr-extract/msgpackr-extract-linux-arm@npm:2.0.2" - conditions: os=linux & cpu=arm - languageName: node - linkType: hard - -"@msgpackr-extract/msgpackr-extract-linux-x64@npm:2.0.2": - version: 2.0.2 - resolution: "@msgpackr-extract/msgpackr-extract-linux-x64@npm:2.0.2" - conditions: os=linux & cpu=x64 - languageName: node - linkType: hard - -"@msgpackr-extract/msgpackr-extract-win32-x64@npm:2.0.2": - version: 2.0.2 - resolution: "@msgpackr-extract/msgpackr-extract-win32-x64@npm:2.0.2" - conditions: os=win32 & cpu=x64 - languageName: node - linkType: hard - -"@npmcli/fs@npm:^2.1.0": - version: 2.1.0 - resolution: "@npmcli/fs@npm:2.1.0" - dependencies: - "@gar/promisify": ^1.1.3 - semver: ^7.3.5 - checksum: 6ec6d678af6da49f9dac50cd882d7f661934dd278972ffbaacde40d9eaa2871292d634000a0cca9510f6fc29855fbd4af433e1adbff90a524ec3eaf140f1219b - languageName: node - linkType: hard - -"@npmcli/move-file@npm:^2.0.0": - version: 2.0.0 - resolution: "@npmcli/move-file@npm:2.0.0" - dependencies: - mkdirp: ^1.0.4 - rimraf: ^3.0.2 - checksum: 1388777b507b0c592d53f41b9d182e1a8de7763bc625fc07999b8edbc22325f074e5b3ec90af79c89d6987fdb2325bc66d59f483258543c14a43661621f841b0 - languageName: node - linkType: hard - -"@parcel/bundler-default@npm:2.6.2": - version: 2.6.2 - resolution: "@parcel/bundler-default@npm:2.6.2" - dependencies: - "@parcel/diagnostic": 2.6.2 - "@parcel/hash": 2.6.2 - "@parcel/plugin": 2.6.2 - "@parcel/utils": 2.6.2 - nullthrows: ^1.1.1 - checksum: f99c2b673beee732a88867354397ca9414f7528febfc03a6083c79e279f35dd385b8c606508a2a15954f3623ca72eb6f8873e6851039ee3218e6d241c1fb8860 - languageName: node - linkType: hard - -"@parcel/cache@npm:2.6.2": - version: 2.6.2 - resolution: "@parcel/cache@npm:2.6.2" - dependencies: - "@parcel/fs": 2.6.2 - "@parcel/logger": 2.6.2 - "@parcel/utils": 2.6.2 - lmdb: 2.5.2 - peerDependencies: - "@parcel/core": ^2.6.2 - checksum: e7b540fe104390399b5f51a3b48c048d38b02b304abbf9180d6398aba8adbd765d2e7acd4708c38a04b7a25b953f2c54e5126a451b1aa2b57c6f5b82f499a1a7 - languageName: node - linkType: hard - -"@parcel/codeframe@npm:2.6.2": - version: 2.6.2 - resolution: "@parcel/codeframe@npm:2.6.2" - dependencies: - chalk: ^4.1.0 - checksum: 3253f42b907edefecbc14d6a3f3924eeda1c828c32d9eb4b05d771c68ff124d6a7065aa950dd990beda73fa6b1c18f2b25329a013e8b52742a371cbcf620054f - languageName: node - linkType: hard - -"@parcel/compressor-raw@npm:2.6.2": - version: 2.6.2 - resolution: "@parcel/compressor-raw@npm:2.6.2" - dependencies: - "@parcel/plugin": 2.6.2 - checksum: fb147eb18952f68b6d2a63fe36a0810f503d326aa524bf46c1864091ef8abe05c3990d3228275e19597054296d5abea850d224d5355ced0def73cec381c02398 - languageName: node - linkType: hard - -"@parcel/config-default@npm:2.6.2": - version: 2.6.2 - resolution: "@parcel/config-default@npm:2.6.2" - dependencies: - "@parcel/bundler-default": 2.6.2 - "@parcel/compressor-raw": 2.6.2 - "@parcel/namer-default": 2.6.2 - "@parcel/optimizer-css": 2.6.2 - "@parcel/optimizer-htmlnano": 2.6.2 - "@parcel/optimizer-image": 2.6.2 - "@parcel/optimizer-svgo": 2.6.2 - "@parcel/optimizer-terser": 2.6.2 - "@parcel/packager-css": 2.6.2 - "@parcel/packager-html": 2.6.2 - "@parcel/packager-js": 2.6.2 - "@parcel/packager-raw": 2.6.2 - "@parcel/packager-svg": 2.6.2 - "@parcel/reporter-dev-server": 2.6.2 - "@parcel/resolver-default": 2.6.2 - "@parcel/runtime-browser-hmr": 2.6.2 - "@parcel/runtime-js": 2.6.2 - "@parcel/runtime-react-refresh": 2.6.2 - "@parcel/runtime-service-worker": 2.6.2 - "@parcel/transformer-babel": 2.6.2 - "@parcel/transformer-css": 2.6.2 - "@parcel/transformer-html": 2.6.2 - "@parcel/transformer-image": 2.6.2 - "@parcel/transformer-js": 2.6.2 - "@parcel/transformer-json": 2.6.2 - "@parcel/transformer-postcss": 2.6.2 - "@parcel/transformer-posthtml": 2.6.2 - "@parcel/transformer-raw": 2.6.2 - "@parcel/transformer-react-refresh-wrap": 2.6.2 - "@parcel/transformer-svg": 2.6.2 - peerDependencies: - "@parcel/core": ^2.6.2 - checksum: 08cf9d08bb0a19900cbe3512970b9be0aaf074af3d266a3bbb47808201e36bcaeb1b7c8764620810bb66a4c98924d4000bb365d3f384764aec18b326409fd86f - languageName: node - linkType: hard - -"@parcel/core@npm:2.6.2": - version: 2.6.2 - resolution: "@parcel/core@npm:2.6.2" - dependencies: - "@mischnic/json-sourcemap": ^0.1.0 - "@parcel/cache": 2.6.2 - "@parcel/diagnostic": 2.6.2 - "@parcel/events": 2.6.2 - "@parcel/fs": 2.6.2 - "@parcel/graph": 2.6.2 - "@parcel/hash": 2.6.2 - "@parcel/logger": 2.6.2 - "@parcel/package-manager": 2.6.2 - "@parcel/plugin": 2.6.2 - "@parcel/source-map": ^2.0.0 - "@parcel/types": 2.6.2 - "@parcel/utils": 2.6.2 - "@parcel/workers": 2.6.2 - abortcontroller-polyfill: ^1.1.9 - base-x: ^3.0.8 - browserslist: ^4.6.6 - clone: ^2.1.1 - dotenv: ^7.0.0 - dotenv-expand: ^5.1.0 - json5: ^2.2.0 - msgpackr: ^1.5.4 - nullthrows: ^1.1.1 - semver: ^5.7.1 - checksum: f550cbbd5ee9db5c9c9dda79ad6b4c307d8d16ca52d6abc42d1df846ad6f5a9dedf0aa1dcb6550a66611b8e89a52bc4036039ef4bc62e007c6faab63541d4c69 - languageName: node - linkType: hard - -"@parcel/css-darwin-arm64@npm:1.10.1": - version: 1.10.1 - resolution: "@parcel/css-darwin-arm64@npm:1.10.1" - conditions: os=darwin & cpu=arm64 - languageName: node - linkType: hard - -"@parcel/css-darwin-x64@npm:1.10.1": - version: 1.10.1 - resolution: "@parcel/css-darwin-x64@npm:1.10.1" - conditions: os=darwin & cpu=x64 - languageName: node - linkType: hard - -"@parcel/css-linux-arm-gnueabihf@npm:1.10.1": - version: 1.10.1 - resolution: "@parcel/css-linux-arm-gnueabihf@npm:1.10.1" - conditions: os=linux & cpu=arm & libc=gnueabihf - languageName: node - linkType: hard - -"@parcel/css-linux-arm64-gnu@npm:1.10.1": - version: 1.10.1 - resolution: "@parcel/css-linux-arm64-gnu@npm:1.10.1" - conditions: os=linux & cpu=arm64 & libc=glibc - languageName: node - linkType: hard - -"@parcel/css-linux-arm64-musl@npm:1.10.1": - version: 1.10.1 - resolution: "@parcel/css-linux-arm64-musl@npm:1.10.1" - conditions: os=linux & cpu=arm64 & libc=musl - languageName: node - linkType: hard - -"@parcel/css-linux-x64-gnu@npm:1.10.1": - version: 1.10.1 - resolution: "@parcel/css-linux-x64-gnu@npm:1.10.1" - conditions: os=linux & cpu=x64 & libc=glibc - languageName: node - linkType: hard - -"@parcel/css-linux-x64-musl@npm:1.10.1": - version: 1.10.1 - resolution: "@parcel/css-linux-x64-musl@npm:1.10.1" - conditions: os=linux & cpu=x64 & libc=musl - languageName: node - linkType: hard - -"@parcel/css-win32-x64-msvc@npm:1.10.1": - version: 1.10.1 - resolution: "@parcel/css-win32-x64-msvc@npm:1.10.1" - conditions: os=win32 & cpu=x64 - languageName: node - linkType: hard - -"@parcel/css@npm:^1.10.1": - version: 1.10.1 - resolution: "@parcel/css@npm:1.10.1" - dependencies: - "@parcel/css-darwin-arm64": 1.10.1 - "@parcel/css-darwin-x64": 1.10.1 - "@parcel/css-linux-arm-gnueabihf": 1.10.1 - "@parcel/css-linux-arm64-gnu": 1.10.1 - "@parcel/css-linux-arm64-musl": 1.10.1 - "@parcel/css-linux-x64-gnu": 1.10.1 - "@parcel/css-linux-x64-musl": 1.10.1 - "@parcel/css-win32-x64-msvc": 1.10.1 - detect-libc: ^1.0.3 - dependenciesMeta: - "@parcel/css-darwin-arm64": - optional: true - "@parcel/css-darwin-x64": - optional: true - "@parcel/css-linux-arm-gnueabihf": - optional: true - "@parcel/css-linux-arm64-gnu": - optional: true - "@parcel/css-linux-arm64-musl": - optional: true - "@parcel/css-linux-x64-gnu": - optional: true - "@parcel/css-linux-x64-musl": - optional: true - "@parcel/css-win32-x64-msvc": - optional: true - checksum: 699752d6ec21e1cb956db0c40b9ad40c5976219088047f97751386e21c5b6520abf8736b3b565abca49b4acf596e2b4fc839eda83f3f8aaf9ff54956e1014575 - languageName: node - linkType: hard - -"@parcel/diagnostic@npm:2.6.2": - version: 2.6.2 - resolution: "@parcel/diagnostic@npm:2.6.2" - dependencies: - "@mischnic/json-sourcemap": ^0.1.0 - nullthrows: ^1.1.1 - checksum: c20c7b12c4a9e840d612fcc0d891675a8fd0a79558698b1f96009cc3631a3222faf7484ebf36f728d255e91d9868ae67638766f7231e016ba078e7cf1899f6b3 - languageName: node - linkType: hard - -"@parcel/events@npm:2.6.2": - version: 2.6.2 - resolution: "@parcel/events@npm:2.6.2" - checksum: 272898db0c5de72bd59d7f43acce188a9c6574abc7235f6b47bf0376a73b49ea634f1fab5c3cdcf846a16e541f40ced16275325f80cc04332543d25d297973d1 - languageName: node - linkType: hard - -"@parcel/fs-search@npm:2.6.2": - version: 2.6.2 - resolution: "@parcel/fs-search@npm:2.6.2" - dependencies: - detect-libc: ^1.0.3 - checksum: 99850b1fd81009bbfb150421cfe9a7fc5936b617eb682a154227e563f53dc60baeb131c3825dda2d8bc240fcc3e96889f96b2a85ef7063c1d4925f4c0f9f7842 - languageName: node - linkType: hard - -"@parcel/fs@npm:2.6.2": - version: 2.6.2 - resolution: "@parcel/fs@npm:2.6.2" - dependencies: - "@parcel/fs-search": 2.6.2 - "@parcel/types": 2.6.2 - "@parcel/utils": 2.6.2 - "@parcel/watcher": ^2.0.0 - "@parcel/workers": 2.6.2 - peerDependencies: - "@parcel/core": ^2.6.2 - checksum: b5e324d93b5149fb75ba3b931cf45ed1e56266b1585d6ecd14d969cebb673ebd4c3a8d9762bf387185066b838a1a9e1d5a7411fc174a55e3801eae8b1201f68e - languageName: node - linkType: hard - -"@parcel/graph@npm:2.6.2": - version: 2.6.2 - resolution: "@parcel/graph@npm:2.6.2" - dependencies: - "@parcel/utils": 2.6.2 - nullthrows: ^1.1.1 - checksum: 74490009e804b14bcf795fe4a1518ae8dd21f04ac4a26fde43cfad69cf6874fe9a1ab7e7b4305d6ceb15b11600e8156504a8ee3279134b22133ffbb4cdab3398 - languageName: node - linkType: hard - -"@parcel/hash@npm:2.6.2": - version: 2.6.2 - resolution: "@parcel/hash@npm:2.6.2" - dependencies: - detect-libc: ^1.0.3 - xxhash-wasm: ^0.4.2 - checksum: 212f34e4397bdc48824892eb556755eeb2e3210dfd217cc14740ff94a3adaed89f4a18591916668aad7a0bf906a06b523ad6326fd970753a57b019453d26fb63 - languageName: node - linkType: hard - -"@parcel/logger@npm:2.6.2": - version: 2.6.2 - resolution: "@parcel/logger@npm:2.6.2" - dependencies: - "@parcel/diagnostic": 2.6.2 - "@parcel/events": 2.6.2 - checksum: d3536408dac9a28476821f6ba536f8f2b4efba635581d603fdadc78ec062084bdbeec17ab8d38c11c0b368092f63a1db1b757c986ede702654ab69d94b4b815c - languageName: node - linkType: hard - -"@parcel/markdown-ansi@npm:2.6.2": - version: 2.6.2 - resolution: "@parcel/markdown-ansi@npm:2.6.2" - dependencies: - chalk: ^4.1.0 - checksum: 742c64c5db484565de8ab549daf76f3b24156720e1914fc26c3b9d2e0b933213d0a37c421e54053387a5011e2060ef430b7b932265eb1922e4b23b151b06a449 - languageName: node - linkType: hard - -"@parcel/namer-default@npm:2.6.2": - version: 2.6.2 - resolution: "@parcel/namer-default@npm:2.6.2" - dependencies: - "@parcel/diagnostic": 2.6.2 - "@parcel/plugin": 2.6.2 - nullthrows: ^1.1.1 - checksum: 259053a59f24b46cf2618d548c4e10806f029e95cf61c4cafff90adb88cbbc2075d96412753df9278759448b09666e7abf3ec9ac8fbefb353a2463f3f6b2c4a0 - languageName: node - linkType: hard - -"@parcel/node-resolver-core@npm:2.6.2": - version: 2.6.2 - resolution: "@parcel/node-resolver-core@npm:2.6.2" - dependencies: - "@parcel/diagnostic": 2.6.2 - "@parcel/utils": 2.6.2 - nullthrows: ^1.1.1 - semver: ^5.7.1 - checksum: 7746b309fa87eeeba08e61e1a192b84feecd792a5f5b484edbda2da11a1e665ef27093e0b6d821f11dc74dd62a50601ae89de9b62efa7dd3d182a52faebaed8c - languageName: node - linkType: hard - -"@parcel/optimizer-css@npm:2.6.2": - version: 2.6.2 - resolution: "@parcel/optimizer-css@npm:2.6.2" - dependencies: - "@parcel/css": ^1.10.1 - "@parcel/diagnostic": 2.6.2 - "@parcel/plugin": 2.6.2 - "@parcel/source-map": ^2.0.0 - "@parcel/utils": 2.6.2 - browserslist: ^4.6.6 - nullthrows: ^1.1.1 - checksum: d1179276f49bdc756b8002050d9952d8724a157e5021886c9df4300ce8f6313d633b546cda3c7cd962e7017721fe5fe5d69d4a92d9094833c0a886e0bf4e6599 - languageName: node - linkType: hard - -"@parcel/optimizer-htmlnano@npm:2.6.2": - version: 2.6.2 - resolution: "@parcel/optimizer-htmlnano@npm:2.6.2" - dependencies: - "@parcel/plugin": 2.6.2 - htmlnano: ^2.0.0 - nullthrows: ^1.1.1 - posthtml: ^0.16.5 - svgo: ^2.4.0 - checksum: 3b86fb1b17d0af5dd2d25a3c9d5f1d587563305ca36afd12429c4de43d8ea29cdfdaed2d5434c2e83c85de7b5f856d4a90ba5b0119255fe3ba5150943c81bcf2 - languageName: node - linkType: hard - -"@parcel/optimizer-image@npm:2.6.2": - version: 2.6.2 - resolution: "@parcel/optimizer-image@npm:2.6.2" - dependencies: - "@parcel/diagnostic": 2.6.2 - "@parcel/plugin": 2.6.2 - "@parcel/utils": 2.6.2 - "@parcel/workers": 2.6.2 - detect-libc: ^1.0.3 - checksum: d36e3c4d801bbaafa4720aa148c0c329bc957c3f890aa568e90f9cfbcdb78fa1e8fd306dcef98dcecddbec32474dfa783fd4c400df6a55f0a8b07f4241816259 - languageName: node - linkType: hard - -"@parcel/optimizer-svgo@npm:2.6.2": - version: 2.6.2 - resolution: "@parcel/optimizer-svgo@npm:2.6.2" - dependencies: - "@parcel/diagnostic": 2.6.2 - "@parcel/plugin": 2.6.2 - "@parcel/utils": 2.6.2 - svgo: ^2.4.0 - checksum: 00b673780522f9594cea5ef0660cf06de5d8ab0542893e50ab52e5ff29a2b64c1fad0a1160abcc8e246239e66b4b67221bb1518755ac857148f2d2c80112a7a7 - languageName: node - linkType: hard - -"@parcel/optimizer-terser@npm:2.6.2": - version: 2.6.2 - resolution: "@parcel/optimizer-terser@npm:2.6.2" - dependencies: - "@parcel/diagnostic": 2.6.2 - "@parcel/plugin": 2.6.2 - "@parcel/source-map": ^2.0.0 - "@parcel/utils": 2.6.2 - nullthrows: ^1.1.1 - terser: ^5.2.0 - checksum: 1b9cdee1978ee56f03d86a3993cc07453bd1699a9624d79fbc14623c2e693256803863d3c0a77936e47b69777f6ba7e659edb3c15da206b15b97c3f6cd5c312e - languageName: node - linkType: hard - -"@parcel/package-manager@npm:2.6.2": - version: 2.6.2 - resolution: "@parcel/package-manager@npm:2.6.2" - dependencies: - "@parcel/diagnostic": 2.6.2 - "@parcel/fs": 2.6.2 - "@parcel/logger": 2.6.2 - "@parcel/types": 2.6.2 - "@parcel/utils": 2.6.2 - "@parcel/workers": 2.6.2 - semver: ^5.7.1 - peerDependencies: - "@parcel/core": ^2.6.2 - checksum: 0c7dfce953da0f26bcd2bc05104767d5d5e0391d66bb76a700022e562c91be683a43e6b4b81ce0c00bc02b3715f4045e0d144d73631dcf7eee2ebd1316dbb879 - languageName: node - linkType: hard - -"@parcel/packager-css@npm:2.6.2": - version: 2.6.2 - resolution: "@parcel/packager-css@npm:2.6.2" - dependencies: - "@parcel/plugin": 2.6.2 - "@parcel/source-map": ^2.0.0 - "@parcel/utils": 2.6.2 - nullthrows: ^1.1.1 - checksum: 70d0c5195f75a88a2ffd71e320a9feb814cef8df23810a6bd914146513705b2396330fe1b02a14dbfdb0a0f06c631df5b2558fbb5a15775ef81d5fa0c94b5399 - languageName: node - linkType: hard - -"@parcel/packager-html@npm:2.6.2": - version: 2.6.2 - resolution: "@parcel/packager-html@npm:2.6.2" - dependencies: - "@parcel/plugin": 2.6.2 - "@parcel/types": 2.6.2 - "@parcel/utils": 2.6.2 - nullthrows: ^1.1.1 - posthtml: ^0.16.5 - checksum: 5f0095111deca877361e604e0f48e9a514b7506f38915c85720d53c87eccf5a2cd106e181f4030c4f58e648a3583ae80da823cf825e74a912ee0d93026992841 - languageName: node - linkType: hard - -"@parcel/packager-js@npm:2.6.2": - version: 2.6.2 - resolution: "@parcel/packager-js@npm:2.6.2" - dependencies: - "@parcel/diagnostic": 2.6.2 - "@parcel/hash": 2.6.2 - "@parcel/plugin": 2.6.2 - "@parcel/source-map": ^2.0.0 - "@parcel/utils": 2.6.2 - globals: ^13.2.0 - nullthrows: ^1.1.1 - checksum: b441a709c668f4a0636fb872f672abd5fcd73a9830f89c6271c66c20b1d16c36d687ff3892605210e2305e76d44a01b108156f90f7e4f20e2ad8acbb9eac2d05 - languageName: node - linkType: hard - -"@parcel/packager-raw@npm:2.6.2": - version: 2.6.2 - resolution: "@parcel/packager-raw@npm:2.6.2" - dependencies: - "@parcel/plugin": 2.6.2 - checksum: c067a612c0b346a80448638cb6b5abc5461a3cc3bbb2a71da24497d09f8e2e9565b64c4de3cbe7d90905ded9363b5421b6708a5ab21eea00787a2266f9ede123 - languageName: node - linkType: hard - -"@parcel/packager-svg@npm:2.6.2": - version: 2.6.2 - resolution: "@parcel/packager-svg@npm:2.6.2" - dependencies: - "@parcel/plugin": 2.6.2 - "@parcel/types": 2.6.2 - "@parcel/utils": 2.6.2 - posthtml: ^0.16.4 - checksum: 50468d382f9423951b391025059d50264fb5f648c266c9d38e493c87d1f9d6d1f901dbc5487ba4d1a6d1fbe11ebaac3ab6b2df24439e7de4ebfea486d90f839d - languageName: node - linkType: hard - -"@parcel/plugin@npm:2.6.2": - version: 2.6.2 - resolution: "@parcel/plugin@npm:2.6.2" - dependencies: - "@parcel/types": 2.6.2 - checksum: 23da0fa37213a6aef0df3949eff7a53994ed68f413e396ee73d7246277b1e0b2f3ce5d34039cf25a5b79db05a1c769a74564d106e2005fe30b89a628a217294a - languageName: node - linkType: hard - -"@parcel/reporter-cli@npm:2.6.2": - version: 2.6.2 - resolution: "@parcel/reporter-cli@npm:2.6.2" - dependencies: - "@parcel/plugin": 2.6.2 - "@parcel/types": 2.6.2 - "@parcel/utils": 2.6.2 - chalk: ^4.1.0 - term-size: ^2.2.1 - checksum: 27486b9c5cb82ddfd3d52039c3909efc1f5dcd6d478231e329c08f8c87eeaa298bbb5f8f6312c92a9613b7e5f993324d1331af6f10229a12268845c0316f1234 - languageName: node - linkType: hard - -"@parcel/reporter-dev-server@npm:2.6.2": - version: 2.6.2 - resolution: "@parcel/reporter-dev-server@npm:2.6.2" - dependencies: - "@parcel/plugin": 2.6.2 - "@parcel/utils": 2.6.2 - checksum: 44007a3bce0ed6d0a64c2d82644e36ea193a6f5871ba614c083b43a7204031214be7b9de018e497b7fb4fcf01458fa07a665e8213ae6e5b276277f3f2d25bedd - languageName: node - linkType: hard - -"@parcel/resolver-default@npm:2.6.2": - version: 2.6.2 - resolution: "@parcel/resolver-default@npm:2.6.2" - dependencies: - "@parcel/node-resolver-core": 2.6.2 - "@parcel/plugin": 2.6.2 - checksum: e0dfff6e62892bfce11a76f66fa1a6013fdcf4f5f8d8afb80b43f0f2111ce0214bdc8348b32207658bd19b8bc046b53f77b1cb5a12892cc668df50373cacd78d - languageName: node - linkType: hard - -"@parcel/runtime-browser-hmr@npm:2.6.2": - version: 2.6.2 - resolution: "@parcel/runtime-browser-hmr@npm:2.6.2" - dependencies: - "@parcel/plugin": 2.6.2 - "@parcel/utils": 2.6.2 - checksum: 39a324c4ef4014a8a122fe989d3802dd09eac9a40ff8a762c4e02b1cd49ab0bff4cb1e803333a707ae2ae6a84907c4331f8a39aad753048347f618ffb70e29a9 - languageName: node - linkType: hard - -"@parcel/runtime-js@npm:2.6.2": - version: 2.6.2 - resolution: "@parcel/runtime-js@npm:2.6.2" - dependencies: - "@parcel/plugin": 2.6.2 - "@parcel/utils": 2.6.2 - nullthrows: ^1.1.1 - checksum: 861e89c53625b23b0e4c48a938db8f8bc168eb5d739416d3a2e81f91346dcdb163b03e73441fc609c8c8308f679497de7454ce86788251b995d57cf8c1908afe - languageName: node - linkType: hard - -"@parcel/runtime-react-refresh@npm:2.6.2": - version: 2.6.2 - resolution: "@parcel/runtime-react-refresh@npm:2.6.2" - dependencies: - "@parcel/plugin": 2.6.2 - "@parcel/utils": 2.6.2 - react-error-overlay: 6.0.9 - react-refresh: ^0.9.0 - checksum: 0c33a13dd47a822bc962cf394d57989d60fc2396463c523f8058dfada537a1d96f3d681932d793304d6d37eea7a9e4c39745c6ce42d3f3f8ddd9c6bced640b21 - languageName: node - linkType: hard - -"@parcel/runtime-service-worker@npm:2.6.2": - version: 2.6.2 - resolution: "@parcel/runtime-service-worker@npm:2.6.2" - dependencies: - "@parcel/plugin": 2.6.2 - "@parcel/utils": 2.6.2 - nullthrows: ^1.1.1 - checksum: 2a9790ad275212746873f0ee7a4296156096bf89ceb0c53b8be1f04bc110cbe451bcc3d4f8dca994f2641280e6ae37cba0f507b630ac1b85403f7f385a97f765 - languageName: node - linkType: hard - -"@parcel/source-map@npm:^2.0.0": - version: 2.0.5 - resolution: "@parcel/source-map@npm:2.0.5" - dependencies: - detect-libc: ^1.0.3 - checksum: b5e677edeb3f395e5a5ce340545b720ed220a3a953a8d338c11f90a33685d926c0553241ccc2e75a09d347a5f4de26d50b2068f018bd74d33131fb46a0ede114 - languageName: node - linkType: hard - -"@parcel/transformer-babel@npm:2.6.2": - version: 2.6.2 - resolution: "@parcel/transformer-babel@npm:2.6.2" - dependencies: - "@parcel/diagnostic": 2.6.2 - "@parcel/plugin": 2.6.2 - "@parcel/source-map": ^2.0.0 - "@parcel/utils": 2.6.2 - browserslist: ^4.6.6 - json5: ^2.2.0 - nullthrows: ^1.1.1 - semver: ^5.7.0 - checksum: c7f14b76bf70748995ea797f48bb61ceda8857426565e614560ed447597370869b647fa305a8d217a5e1b2ea7e88732264f8329fe3d6ee1efb954b18246f4881 - languageName: node - linkType: hard - -"@parcel/transformer-css@npm:2.6.2": - version: 2.6.2 - resolution: "@parcel/transformer-css@npm:2.6.2" - dependencies: - "@parcel/css": ^1.10.1 - "@parcel/diagnostic": 2.6.2 - "@parcel/plugin": 2.6.2 - "@parcel/source-map": ^2.0.0 - "@parcel/utils": 2.6.2 - browserslist: ^4.6.6 - nullthrows: ^1.1.1 - checksum: 2a8ac504571518fbd64d38cd1fe337cdeb43e5becd721b10c2cbba97271ad1c9929f7ecc7bca90b1e7657703be329c5cc8db635c381cfc6c172f942e9adbc3f3 - languageName: node - linkType: hard - -"@parcel/transformer-html@npm:2.6.2": - version: 2.6.2 - resolution: "@parcel/transformer-html@npm:2.6.2" - dependencies: - "@parcel/diagnostic": 2.6.2 - "@parcel/hash": 2.6.2 - "@parcel/plugin": 2.6.2 - nullthrows: ^1.1.1 - posthtml: ^0.16.5 - posthtml-parser: ^0.10.1 - posthtml-render: ^3.0.0 - semver: ^5.7.1 - checksum: 6d37d556aa7a744bc0c13e74d9a3769c6a85152fb2a609d334e016ce826b26bae04a63e9dad0ab36ca2c34573eafd534753c5c982d4c5855d84778dec98617d6 - languageName: node - linkType: hard - -"@parcel/transformer-image@npm:2.6.2": - version: 2.6.2 - resolution: "@parcel/transformer-image@npm:2.6.2" - dependencies: - "@parcel/plugin": 2.6.2 - "@parcel/workers": 2.6.2 - nullthrows: ^1.1.1 - peerDependencies: - "@parcel/core": ^2.6.2 - checksum: 2627a162b9bc730ad12086502edf043cac69b7e832b2c344478e2ed2b1c96db6686adbca32bd715c4421f8c360c301d029773e13209e6060639e40d020719d62 - languageName: node - linkType: hard - -"@parcel/transformer-js@npm:2.6.2": - version: 2.6.2 - resolution: "@parcel/transformer-js@npm:2.6.2" - dependencies: - "@parcel/diagnostic": 2.6.2 - "@parcel/plugin": 2.6.2 - "@parcel/source-map": ^2.0.0 - "@parcel/utils": 2.6.2 - "@parcel/workers": 2.6.2 - "@swc/helpers": ^0.4.2 - browserslist: ^4.6.6 - detect-libc: ^1.0.3 - nullthrows: ^1.1.1 - regenerator-runtime: ^0.13.7 - semver: ^5.7.1 - peerDependencies: - "@parcel/core": ^2.6.2 - checksum: 32a0480b2986b843d55e0c48a965ff842bf7e4d99325d77c1a7e451a1afc41f7f2602b5a61c79dda1d5382b75834b8e5a452cfb7242d029226f750236cbd3bcf - languageName: node - linkType: hard - -"@parcel/transformer-json@npm:2.6.2": - version: 2.6.2 - resolution: "@parcel/transformer-json@npm:2.6.2" - dependencies: - "@parcel/plugin": 2.6.2 - json5: ^2.2.0 - checksum: 0b4162ba936999e10ad66a569d16b42947c7e2f98f3ac83fcabe20aefac8990797f8032115441a1d49ad01ccb2555b31d70c3cf7f202ba2a1fcc1bc7e4703fe0 - languageName: node - linkType: hard - -"@parcel/transformer-postcss@npm:2.6.2": - version: 2.6.2 - resolution: "@parcel/transformer-postcss@npm:2.6.2" - dependencies: - "@parcel/diagnostic": 2.6.2 - "@parcel/hash": 2.6.2 - "@parcel/plugin": 2.6.2 - "@parcel/utils": 2.6.2 - clone: ^2.1.1 - nullthrows: ^1.1.1 - postcss-value-parser: ^4.2.0 - semver: ^5.7.1 - checksum: 473d1e96f9290a158ffe0f662f50769d386773e9dc7f6c5cfec9bb9db2f51020a191639d9f9ad30d73e859ba1e4a78cf2079256095b5481c41230b611f73d453 - languageName: node - linkType: hard - -"@parcel/transformer-posthtml@npm:2.6.2": - version: 2.6.2 - resolution: "@parcel/transformer-posthtml@npm:2.6.2" - dependencies: - "@parcel/plugin": 2.6.2 - "@parcel/utils": 2.6.2 - nullthrows: ^1.1.1 - posthtml: ^0.16.5 - posthtml-parser: ^0.10.1 - posthtml-render: ^3.0.0 - semver: ^5.7.1 - checksum: 3ddb727aa2f0ff8e867fee2c4a739d8cd4c213e7fbf61b672497a2b51559cb75ff4381881cb0262c511ff5c21a608dfa8805f96c9606a27cddbdff910dc9c2df - languageName: node - linkType: hard - -"@parcel/transformer-raw@npm:2.6.2": - version: 2.6.2 - resolution: "@parcel/transformer-raw@npm:2.6.2" - dependencies: - "@parcel/plugin": 2.6.2 - checksum: aa8543194f4958f21f74e8c06171116b63c17113d584b121128765277d604965f42a1acb8aca8a7babb2051697cc74edf4be9bd4c203601cff6c291da9cf5383 - languageName: node - linkType: hard - -"@parcel/transformer-react-refresh-wrap@npm:2.6.2": - version: 2.6.2 - resolution: "@parcel/transformer-react-refresh-wrap@npm:2.6.2" - dependencies: - "@parcel/plugin": 2.6.2 - "@parcel/utils": 2.6.2 - react-refresh: ^0.9.0 - checksum: 6655b93d5e362b4916eab061ec93badeefec0f07a28245d647d1eda2945f062874a6f2692446353e62c9a261a53840a31a6164775123192cd864d24af5f2e2ab - languageName: node - linkType: hard - -"@parcel/transformer-sass@npm:2.6.2": - version: 2.6.2 - resolution: "@parcel/transformer-sass@npm:2.6.2" - dependencies: - "@parcel/plugin": 2.6.2 - "@parcel/source-map": ^2.0.0 - sass: ^1.38.0 - checksum: b35e8d272f12ae9e3d21b1c8fecf901327117a114724221c5144cb055a9d9d7155b12cdfd4ffc1b5ba2838ab17ac3613055b2cff1e913b57a9dcac2d27ec04cc - languageName: node - linkType: hard - -"@parcel/transformer-svg@npm:2.6.2": - version: 2.6.2 - resolution: "@parcel/transformer-svg@npm:2.6.2" - dependencies: - "@parcel/diagnostic": 2.6.2 - "@parcel/hash": 2.6.2 - "@parcel/plugin": 2.6.2 - nullthrows: ^1.1.1 - posthtml: ^0.16.5 - posthtml-parser: ^0.10.1 - posthtml-render: ^3.0.0 - semver: ^5.7.1 - checksum: b768ecc0c69f3b5dd8716453ad2aaa7928ccc8eb95469cdb9d925e9c2e0cf4b3a61abfb8057471d9f106f992548001b628d5af82b75cb29dbb15c697ecbdec53 - languageName: node - linkType: hard - -"@parcel/types@npm:2.6.2": - version: 2.6.2 - resolution: "@parcel/types@npm:2.6.2" - dependencies: - "@parcel/cache": 2.6.2 - "@parcel/diagnostic": 2.6.2 - "@parcel/fs": 2.6.2 - "@parcel/package-manager": 2.6.2 - "@parcel/source-map": ^2.0.0 - "@parcel/workers": 2.6.2 - utility-types: ^3.10.0 - checksum: 16f3c3ac36eb6f4bfdf91e65b893b10be8911f708752976baf270d087f82957069fb84b410312fc231543ed74573e6dcf5bc01373fe1113f87f91833cb6d5a86 - languageName: node - linkType: hard - -"@parcel/utils@npm:2.6.2": - version: 2.6.2 - resolution: "@parcel/utils@npm:2.6.2" - dependencies: - "@parcel/codeframe": 2.6.2 - "@parcel/diagnostic": 2.6.2 - "@parcel/hash": 2.6.2 - "@parcel/logger": 2.6.2 - "@parcel/markdown-ansi": 2.6.2 - "@parcel/source-map": ^2.0.0 - chalk: ^4.1.0 - checksum: a74fdca9664412c6a18ef151cba80e784bb5e74784c5b1e1a8f00c0ab8c747203a819a3211e6822b9d86694825297b73c7fd4a8145212f78b2718d1e4b03c987 - languageName: node - linkType: hard - -"@parcel/watcher@npm:^2.0.0": - version: 2.0.5 - resolution: "@parcel/watcher@npm:2.0.5" - dependencies: - node-addon-api: ^3.2.1 - node-gyp: latest - node-gyp-build: ^4.3.0 - checksum: ddc5b073e82cfadbc3bca3c1c0d5e64f445550f77a073fa3f7b1ac4547ec545fd6474ba5cd7e37aa0121d1ea37e70535172be74f9b081a17e7458849cedffdb0 - languageName: node - linkType: hard - -"@parcel/workers@npm:2.6.2": - version: 2.6.2 - resolution: "@parcel/workers@npm:2.6.2" - dependencies: - "@parcel/diagnostic": 2.6.2 - "@parcel/logger": 2.6.2 - "@parcel/types": 2.6.2 - "@parcel/utils": 2.6.2 - chrome-trace-event: ^1.0.2 - nullthrows: ^1.1.1 - peerDependencies: - "@parcel/core": ^2.6.2 - checksum: 92b65cd3fde225dcd377f1f529caeb0d8ee56a9aeef3785716b1ad210132e5dc1b6bd9b7c4c6920094e0030c6aad9cc42d5dbf7b4fb0fb4668eedfd332e0b242 - languageName: node - linkType: hard - -"@popperjs/core@npm:*, @popperjs/core@npm:2.11.5": - version: 2.11.5 - resolution: "@popperjs/core@npm:2.11.5" - checksum: fd7f9dca3fb716d7426332b6ee283f88d2724c0ab342fb678865a640bad403dfb9eeebd8204a406986162f7e2b33394f104320008b74d0e9066d7322f70ea35d - languageName: node - linkType: hard - -"@sidvind/better-ajv-errors@npm:^2.0.0": - version: 2.0.0 - resolution: "@sidvind/better-ajv-errors@npm:2.0.0" - dependencies: - "@babel/code-frame": ^7.16.0 - chalk: ^4.1.0 - peerDependencies: - ajv: 4.11.8 - 8 - checksum: 12b0d87855737d1f36e869f9a55c706fa9eb232dfebaca5209c21d8d5caf7fa25671238064d68e619492c68591a73b6f49fcc1dff182fd77d2370e277033bd60 - languageName: node - linkType: hard - -"@swc/helpers@npm:^0.4.2": - version: 0.4.3 - resolution: "@swc/helpers@npm:0.4.3" - dependencies: - tslib: ^2.4.0 - checksum: 5c2f173e950dd3929d84ae48b3586a274d5a874e7cf2013b3d8081e4f8c723fa3a4d4e63b263e84bb7f06431f87b640e91a12655410463c81a3dc2bbc15eceda - languageName: node - linkType: hard - -"@tootallnate/once@npm:2": - version: 2.0.0 - resolution: "@tootallnate/once@npm:2.0.0" - checksum: ad87447820dd3f24825d2d947ebc03072b20a42bfc96cbafec16bff8bbda6c1a81fcb0be56d5b21968560c5359a0af4038a68ba150c3e1694fe4c109a063bed8 - languageName: node - linkType: hard - -"@trysound/sax@npm:0.2.0": - version: 0.2.0 - resolution: "@trysound/sax@npm:0.2.0" - checksum: 11226c39b52b391719a2a92e10183e4260d9651f86edced166da1d95f39a0a1eaa470e44d14ac685ccd6d3df7e2002433782872c0feeb260d61e80f21250e65c - languageName: node - linkType: hard - -"@types/chai-subset@npm:^1.3.3": - version: 1.3.3 - resolution: "@types/chai-subset@npm:1.3.3" - dependencies: - "@types/chai": "*" - checksum: 4481da7345022995f5a105e6683744f7203d2c3d19cfe88d8e17274d045722948abf55e0adfd97709e0f043dade37a4d4e98cd4c660e2e8a14f23e6ecf79418f - languageName: node - linkType: hard - -"@types/chai@npm:*, @types/chai@npm:^4.3.1": - version: 4.3.1 - resolution: "@types/chai@npm:4.3.1" - checksum: 2ee246b76c469cd620a7a1876a73bc597074361b67d547b4bd96a0c1adb43597ede2d8589ab626192e14349d83cbb646cc11e2c179eeeb43ff11596de94d82c4 - languageName: node - linkType: hard - -"@types/istanbul-lib-coverage@npm:^2.0.1": - version: 2.0.4 - resolution: "@types/istanbul-lib-coverage@npm:2.0.4" - checksum: a25d7589ee65c94d31464c16b72a9dc81dfa0bea9d3e105ae03882d616e2a0712a9c101a599ec482d297c3591e16336962878cb3eb1a0a62d5b76d277a890ce7 - languageName: node - linkType: hard - -"@types/jest@npm:^27.0.1": - version: 27.4.1 - resolution: "@types/jest@npm:27.4.1" - dependencies: - jest-matcher-utils: ^27.0.0 - pretty-format: ^27.0.0 - checksum: 5184f3eef4832d01ee8f59bed15eec45ccc8e29c724a5e6ce37bf74396b37bdf04f557000f45ba4fc38ae6075cf9cfcce3d7a75abc981023c61ceb27230a93e4 - languageName: node - linkType: hard - -"@types/json5@npm:^0.0.29": - version: 0.0.29 - resolution: "@types/json5@npm:0.0.29" - checksum: e60b153664572116dfea673c5bda7778dbff150498f44f998e34b5886d8afc47f16799280e4b6e241c0472aef1bc36add771c569c68fc5125fc2ae519a3eb9ac - languageName: node - linkType: hard - -"@types/lodash-es@npm:^4.17.6": - version: 4.17.6 - resolution: "@types/lodash-es@npm:4.17.6" - dependencies: - "@types/lodash": "*" - checksum: 9bd239dd525086e278821949ce12fbdd4f100a060fed9323fc7ad5661113e1641f28a7ebab617230ed3474680d8f4de705c1928b48252bb684be6ec9eed715db - languageName: node - linkType: hard - -"@types/lodash@npm:*, @types/lodash@npm:^4.14.181": - version: 4.14.182 - resolution: "@types/lodash@npm:4.14.182" - checksum: 7dd137aa9dbabd632408bd37009d984655164fa1ecc3f2b6eb94afe35bf0a5852cbab6183148d883e9c73a958b7fec9a9bcf7c8e45d41195add6a18c34958209 - languageName: node - linkType: hard - -"@types/node@npm:*, @types/node@npm:^14.14.31": - version: 14.18.18 - resolution: "@types/node@npm:14.18.18" - checksum: a165225cd2603f6e62af8407449e4a4407305e03b41c1adf6b186fdf546e1a03c8214217659b5b36c556947c0c06234993ac880d4db6378136a7a810d47e0742 - languageName: node - linkType: hard - -"@types/node@npm:~17.0.5": - version: 17.0.29 - resolution: "@types/node@npm:17.0.29" - checksum: bb9d7bce9d6d3882efd9d63b773b548dce98df4bd57eff8ceaa316aa2f3346e36d3618764cc93da84bbff92005174a35eec3465cde91ee973ef1c351ffa40074 - languageName: node - linkType: hard - -"@types/parse-json@npm:^4.0.0": - version: 4.0.0 - resolution: "@types/parse-json@npm:4.0.0" - checksum: fd6bce2b674b6efc3db4c7c3d336bd70c90838e8439de639b909ce22f3720d21344f52427f1d9e57b265fcb7f6c018699b99e5e0c208a1a4823014269a6bf35b - languageName: node - linkType: hard - -"@types/sinonjs__fake-timers@npm:8.1.1": - version: 8.1.1 - resolution: "@types/sinonjs__fake-timers@npm:8.1.1" - checksum: ca09d54d47091d87020824a73f026300fa06b17cd9f2f9b9387f28b549364b141ef194ee28db762f6588de71d8febcd17f753163cb7ea116b8387c18e80ebd5c - languageName: node - linkType: hard - -"@types/sizzle@npm:^2.3.2": - version: 2.3.3 - resolution: "@types/sizzle@npm:2.3.3" - checksum: 586a9fb1f6ff3e325e0f2cc1596a460615f0bc8a28f6e276ac9b509401039dd242fa8b34496d3a30c52f5b495873922d09a9e76c50c2ab2bcc70ba3fb9c4e160 - languageName: node - linkType: hard - -"@types/yauzl@npm:^2.9.1": - version: 2.10.0 - resolution: "@types/yauzl@npm:2.10.0" - dependencies: - "@types/node": "*" - checksum: 55d27ae5d346ea260e40121675c24e112ef0247649073848e5d4e03182713ae4ec8142b98f61a1c6cbe7d3b72fa99bbadb65d8b01873e5e605cdc30f1ff70ef2 - languageName: node - linkType: hard - -"@vitejs/plugin-vue@npm:2.3.3": - version: 2.3.3 - resolution: "@vitejs/plugin-vue@npm:2.3.3" - peerDependencies: - vite: ^2.5.10 - vue: ^3.2.25 - checksum: 9303dcb9c8580d0ee9b33542639ac1a36ad9cc0e773a1f9b9b05623d74574f6a901ce781918b53f5a58eb3c6218ba96c27ef6efbf3e7ef6be16864fc1cae1626 - languageName: node - linkType: hard - -"@vue/compiler-core@npm:3.2.37": - version: 3.2.37 - resolution: "@vue/compiler-core@npm:3.2.37" - dependencies: - "@babel/parser": ^7.16.4 - "@vue/shared": 3.2.37 - estree-walker: ^2.0.2 - source-map: ^0.6.1 - checksum: 5642e20813352f7ed57ef0eec0fb8a075d6485c91548555b435e8163e62a5e03402c26944bfa2486d6cc4c992f2649478f887478bcd23c8ad9036636f2dcff6a - languageName: node - linkType: hard - -"@vue/compiler-dom@npm:3.2.37": - version: 3.2.37 - resolution: "@vue/compiler-dom@npm:3.2.37" - dependencies: - "@vue/compiler-core": 3.2.37 - "@vue/shared": 3.2.37 - checksum: 6cfa9d2ee123339549ba005fa61b2cd5ccf079ba8d8d797f0075e7054c2766744029cb0997341bcb6a51e129ae43489263aa7d8500b262ef7b81c63c2b0c4576 - languageName: node - linkType: hard - -"@vue/compiler-sfc@npm:3.2.37": - version: 3.2.37 - resolution: "@vue/compiler-sfc@npm:3.2.37" - dependencies: - "@babel/parser": ^7.16.4 - "@vue/compiler-core": 3.2.37 - "@vue/compiler-dom": 3.2.37 - "@vue/compiler-ssr": 3.2.37 - "@vue/reactivity-transform": 3.2.37 - "@vue/shared": 3.2.37 - estree-walker: ^2.0.2 - magic-string: ^0.25.7 - postcss: ^8.1.10 - source-map: ^0.6.1 - checksum: 9f9067d79f40b0016e4063c180f5417e893f820b970ee291050cad8e19d9258f70a128e5de862e484bfb15572d335c8d5881c95e6b6a3032cb1a94829e8694cb - languageName: node - linkType: hard - -"@vue/compiler-ssr@npm:3.2.37": - version: 3.2.37 - resolution: "@vue/compiler-ssr@npm:3.2.37" - dependencies: - "@vue/compiler-dom": 3.2.37 - "@vue/shared": 3.2.37 - checksum: e137462340c220ef7891d0b40f11124e7d5311e760fdb0de1748c046481505aecd5be8ec8f7b25ac6fc26d2393cbcc267f258d2d26742a50cb9abaf828c28839 - languageName: node - linkType: hard - -"@vue/devtools-api@npm:^6.1.4": - version: 6.1.4 - resolution: "@vue/devtools-api@npm:6.1.4" - checksum: 027bb138b03ec7147dd15e5d0ef28d5b72c822530396cc8a86bc6fdb049dc6850314b9e897e497064e3ed47fad229a18141f56b8b8ca3d41092a576dc5b6538d - languageName: node - linkType: hard - -"@vue/reactivity-transform@npm:3.2.37": - version: 3.2.37 - resolution: "@vue/reactivity-transform@npm:3.2.37" - dependencies: - "@babel/parser": ^7.16.4 - "@vue/compiler-core": 3.2.37 - "@vue/shared": 3.2.37 - estree-walker: ^2.0.2 - magic-string: ^0.25.7 - checksum: d9e7c353e2bd3a62a9bbb7498ae231f5194428da003672daadb3e7af50c7839e10fb0ac68252852be353138428d1a36f3b8c7815f9c15499d46e7edaf3730c7e - languageName: node - linkType: hard - -"@vue/reactivity@npm:3.2.37": - version: 3.2.37 - resolution: "@vue/reactivity@npm:3.2.37" - dependencies: - "@vue/shared": 3.2.37 - checksum: 94e353f8b8a9301cae15c9366f2fec6a163efb7293e9fe5d1da3ed647f1859139b7b321451db56fb5e3141192c0f0755f74ca9c4bcd30ec44372e45def61d69f - languageName: node - linkType: hard - -"@vue/runtime-core@npm:3.2.37": - version: 3.2.37 - resolution: "@vue/runtime-core@npm:3.2.37" - dependencies: - "@vue/reactivity": 3.2.37 - "@vue/shared": 3.2.37 - checksum: 8dbf4e1f973335f5089d6b5965c2756a47589009956f883adb47036315a6d5701ef9d23d52456a6272673bc6f0bcee4f096826b5eae3fec65274e24e9f722a9b - languageName: node - linkType: hard - -"@vue/runtime-dom@npm:3.2.37": - version: 3.2.37 - resolution: "@vue/runtime-dom@npm:3.2.37" - dependencies: - "@vue/runtime-core": 3.2.37 - "@vue/shared": 3.2.37 - csstype: ^2.6.8 - checksum: 36dddfd56161c94a9a483903a570897e1ee46a95126d54f7948bc184d5d333c9f0c1a9c4cee90ddec63baf4ea2e35be9d0d678108427aba907b0adf0800c75a5 - languageName: node - linkType: hard - -"@vue/server-renderer@npm:3.2.37": - version: 3.2.37 - resolution: "@vue/server-renderer@npm:3.2.37" - dependencies: - "@vue/compiler-ssr": 3.2.37 - "@vue/shared": 3.2.37 - peerDependencies: - vue: 3.2.37 - checksum: 634d43cd21ed902ef3d1d710db2065c4d47402c979914325494f73e2cd37545d809e665c3aace1a02b32c3332a9ad7e772a00159f42e63abb8b73b0fef27a102 - languageName: node - linkType: hard - -"@vue/shared@npm:3.2.37": - version: 3.2.37 - resolution: "@vue/shared@npm:3.2.37" - checksum: 999ab8baeb13de190d07536e7dd0e74ab9354a864d8d903850a2127ae1a2aa2713a9edc0d957620ebf91165d6603d0cd2b0e8ee0db6cbaf8d57a6a0f912af810 - languageName: node - linkType: hard - -"@vue/test-utils@npm:2.0.2": - version: 2.0.2 - resolution: "@vue/test-utils@npm:2.0.2" - peerDependencies: - vue: ^3.0.1 - checksum: 384bdd4231d3f3eaa02e2ffaef2e2c90934cd9f44ab53fdfe1e9603fbe9a0e702c4a15e8bdc0fc907af210f23abe35fc43a4814598ed0a297af4fa144161f87f - languageName: node - linkType: hard - -"abbrev@npm:1": - version: 1.1.1 - resolution: "abbrev@npm:1.1.1" - checksum: a4a97ec07d7ea112c517036882b2ac22f3109b7b19077dc656316d07d308438aac28e4d9746dc4d84bf6b1e75b4a7b0a5f3cb30592419f128ca9a8cee3bcfa17 - languageName: node - linkType: hard - -"abortcontroller-polyfill@npm:^1.1.9": - version: 1.7.3 - resolution: "abortcontroller-polyfill@npm:1.7.3" - checksum: 55739d7f0c9bd6afa2aabb3148778967c4dd4dcff91f6b9259df38da34f9882d3f7730b0954e9767a19cc16a8dd9a58915da4e8a50220300d45af3817d7557b1 - languageName: node - linkType: hard - -"acorn-jsx@npm:^5.3.2": - version: 5.3.2 - resolution: "acorn-jsx@npm:5.3.2" - peerDependencies: - acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 - checksum: c3d3b2a89c9a056b205b69530a37b972b404ee46ec8e5b341666f9513d3163e2a4f214a71f4dfc7370f5a9c07472d2fd1c11c91c3f03d093e37637d95da98950 - languageName: node - linkType: hard - -"acorn-walk@npm:^8.0.0": - version: 8.2.0 - resolution: "acorn-walk@npm:8.2.0" - checksum: 1715e76c01dd7b2d4ca472f9c58968516a4899378a63ad5b6c2d668bba8da21a71976c14ec5f5b75f887b6317c4ae0b897ab141c831d741dc76024d8745f1ad1 - languageName: node - linkType: hard - -"acorn@npm:^7.1.1": - version: 7.4.1 - resolution: "acorn@npm:7.4.1" - bin: - acorn: bin/acorn - checksum: 1860f23c2107c910c6177b7b7be71be350db9e1080d814493fae143ae37605189504152d1ba8743ba3178d0b37269ce1ffc42b101547fdc1827078f82671e407 - languageName: node - linkType: hard - -"acorn@npm:^8.5.0, acorn@npm:^8.7.1": - version: 8.7.1 - resolution: "acorn@npm:8.7.1" - bin: - acorn: bin/acorn - checksum: aca0aabf98826717920ac2583fdcad0a6fbe4e583fdb6e843af2594e907455aeafe30b1e14f1757cd83ce1776773cf8296ffc3a4acf13f0bd3dfebcf1db6ae80 - languageName: node - linkType: hard - -"agent-base@npm:6, agent-base@npm:^6.0.2": - version: 6.0.2 - resolution: "agent-base@npm:6.0.2" - dependencies: - debug: 4 - checksum: f52b6872cc96fd5f622071b71ef200e01c7c4c454ee68bc9accca90c98cfb39f2810e3e9aa330435835eedc8c23f4f8a15267f67c6e245d2b33757575bdac49d - languageName: node - linkType: hard - -"agentkeepalive@npm:^4.2.1": - version: 4.2.1 - resolution: "agentkeepalive@npm:4.2.1" - dependencies: - debug: ^4.1.0 - depd: ^1.1.2 - humanize-ms: ^1.2.1 - checksum: 39cb49ed8cf217fd6da058a92828a0a84e0b74c35550f82ee0a10e1ee403c4b78ade7948be2279b188b7a7303f5d396ea2738b134731e464bf28de00a4f72a18 - languageName: node - linkType: hard - -"aggregate-error@npm:^3.0.0": - version: 3.1.0 - resolution: "aggregate-error@npm:3.1.0" - dependencies: - clean-stack: ^2.0.0 - indent-string: ^4.0.0 - checksum: 1101a33f21baa27a2fa8e04b698271e64616b886795fd43c31068c07533c7b3facfcaf4e9e0cab3624bd88f729a592f1c901a1a229c9e490eafce411a8644b79 - languageName: node - linkType: hard - -"ajv@npm:^6.10.0, ajv@npm:^6.12.4": - version: 6.12.6 - resolution: "ajv@npm:6.12.6" - dependencies: - fast-deep-equal: ^3.1.1 - fast-json-stable-stringify: ^2.0.0 - json-schema-traverse: ^0.4.1 - uri-js: ^4.2.2 - checksum: 874972efe5c4202ab0a68379481fbd3d1b5d0a7bd6d3cc21d40d3536ebff3352a2a1fabb632d4fd2cc7fe4cbdcd5ed6782084c9bbf7f32a1536d18f9da5007d4 - languageName: node - linkType: hard - -"ajv@npm:^8.0.0": - version: 8.11.0 - resolution: "ajv@npm:8.11.0" - dependencies: - fast-deep-equal: ^3.1.1 - json-schema-traverse: ^1.0.0 - require-from-string: ^2.0.2 - uri-js: ^4.2.2 - checksum: 5e0ff226806763be73e93dd7805b634f6f5921e3e90ca04acdf8db81eed9d8d3f0d4c5f1213047f45ebbf8047ffe0c840fa1ef2ec42c3a644899f69aa72b5bef - languageName: node - linkType: hard - -"ansi-colors@npm:^4.1.1": - version: 4.1.3 - resolution: "ansi-colors@npm:4.1.3" - checksum: a9c2ec842038a1fabc7db9ece7d3177e2fe1c5dc6f0c51ecfbf5f39911427b89c00b5dc6b8bd95f82a26e9b16aaae2e83d45f060e98070ce4d1333038edceb0e - languageName: node - linkType: hard - -"ansi-escapes@npm:^4.3.0": - version: 4.3.2 - resolution: "ansi-escapes@npm:4.3.2" - dependencies: - type-fest: ^0.21.3 - checksum: 93111c42189c0a6bed9cdb4d7f2829548e943827ee8479c74d6e0b22ee127b2a21d3f8b5ca57723b8ef78ce011fbfc2784350eb2bde3ccfccf2f575fa8489815 - languageName: node - linkType: hard - -"ansi-regex@npm:^5.0.1": - version: 5.0.1 - resolution: "ansi-regex@npm:5.0.1" - checksum: 2aa4bb54caf2d622f1afdad09441695af2a83aa3fe8b8afa581d205e57ed4261c183c4d3877cee25794443fde5876417d859c108078ab788d6af7e4fe52eb66b - languageName: node - linkType: hard - -"ansi-styles@npm:^3.2.1": - version: 3.2.1 - resolution: "ansi-styles@npm:3.2.1" - dependencies: - color-convert: ^1.9.0 - checksum: d85ade01c10e5dd77b6c89f34ed7531da5830d2cb5882c645f330079975b716438cd7ebb81d0d6e6b4f9c577f19ae41ab55f07f19786b02f9dfd9e0377395665 - languageName: node - linkType: hard - -"ansi-styles@npm:^4.0.0, ansi-styles@npm:^4.1.0": - version: 4.3.0 - resolution: "ansi-styles@npm:4.3.0" - dependencies: - color-convert: ^2.0.1 - checksum: 513b44c3b2105dd14cc42a19271e80f386466c4be574bccf60b627432f9198571ebf4ab1e4c3ba17347658f4ee1711c163d574248c0c1cdc2d5917a0ad582ec4 - languageName: node - linkType: hard - -"ansi-styles@npm:^5.0.0": - version: 5.2.0 - resolution: "ansi-styles@npm:5.2.0" - checksum: d7f4e97ce0623aea6bc0d90dcd28881ee04cba06c570b97fd3391bd7a268eedfd9d5e2dd4fdcbdd82b8105df5faf6f24aaedc08eaf3da898e702db5948f63469 - languageName: node - linkType: hard - -"anymatch@npm:~3.1.2": - version: 3.1.2 - resolution: "anymatch@npm:3.1.2" - dependencies: - normalize-path: ^3.0.0 - picomatch: ^2.0.4 - checksum: 985163db2292fac9e5a1e072bf99f1b5baccf196e4de25a0b0b81865ebddeb3b3eb4480734ef0a2ac8c002845396b91aa89121f5b84f93981a4658164a9ec6e9 - languageName: node - linkType: hard - -"aproba@npm:^1.0.3 || ^2.0.0": - version: 2.0.0 - resolution: "aproba@npm:2.0.0" - checksum: 5615cadcfb45289eea63f8afd064ab656006361020e1735112e346593856f87435e02d8dcc7ff0d11928bc7d425f27bc7c2a84f6c0b35ab0ff659c814c138a24 - languageName: node - linkType: hard - -"arch@npm:^2.2.0": - version: 2.2.0 - resolution: "arch@npm:2.2.0" - checksum: e21b7635029fe8e9cdd5a026f9a6c659103e63fff423834323cdf836a1bb240a72d0c39ca8c470f84643385cf581bd8eda2cad8bf493e27e54bd9783abe9101f - languageName: node - linkType: hard - -"are-we-there-yet@npm:^3.0.0": - version: 3.0.0 - resolution: "are-we-there-yet@npm:3.0.0" - dependencies: - delegates: ^1.0.0 - readable-stream: ^3.6.0 - checksum: 348edfdd931b0b50868b55402c01c3f64df1d4c229ab6f063539a5025fd6c5f5bb8a0cab409bbed8d75d34762d22aa91b7c20b4204eb8177063158d9ba792981 - languageName: node - linkType: hard - -"argparse@npm:^2.0.1": - version: 2.0.1 - resolution: "argparse@npm:2.0.1" - checksum: 83644b56493e89a254bae05702abf3a1101b4fa4d0ca31df1c9985275a5a5bd47b3c27b7fa0b71098d41114d8ca000e6ed90cad764b306f8a503665e4d517ced - languageName: node - linkType: hard - -"array-includes@npm:^3.1.4": - version: 3.1.4 - resolution: "array-includes@npm:3.1.4" - dependencies: - call-bind: ^1.0.2 - define-properties: ^1.1.3 - es-abstract: ^1.19.1 - get-intrinsic: ^1.1.1 - is-string: ^1.0.7 - checksum: 69967c38c52698f84b50a7aed5554aadc89c6ac6399b6d92ad061a5952f8423b4bba054c51d40963f791dfa294d7247cdd7988b6b1f2c5861477031c6386e1c0 - languageName: node - linkType: hard - -"array.prototype.flat@npm:^1.2.5": - version: 1.3.0 - resolution: "array.prototype.flat@npm:1.3.0" - dependencies: - call-bind: ^1.0.2 - define-properties: ^1.1.3 - es-abstract: ^1.19.2 - es-shim-unscopables: ^1.0.0 - checksum: 2a652b3e8dc0bebb6117e42a5ab5738af0203a14c27341d7bb2431467bdb4b348e2c5dc555dfcda8af0a5e4075c400b85311ded73861c87290a71a17c3e0a257 - languageName: node - linkType: hard - -"asap@npm:~2.0.3": - version: 2.0.6 - resolution: "asap@npm:2.0.6" - checksum: b296c92c4b969e973260e47523207cd5769abd27c245a68c26dc7a0fe8053c55bb04360237cb51cab1df52be939da77150ace99ad331fb7fb13b3423ed73ff3d - languageName: node - linkType: hard - -"asn1@npm:~0.2.3": - version: 0.2.6 - resolution: "asn1@npm:0.2.6" - dependencies: - safer-buffer: ~2.1.0 - checksum: 39f2ae343b03c15ad4f238ba561e626602a3de8d94ae536c46a4a93e69578826305366dc09fbb9b56aec39b4982a463682f259c38e59f6fa380cd72cd61e493d - languageName: node - linkType: hard - -"assert-never@npm:^1.2.1": - version: 1.2.1 - resolution: "assert-never@npm:1.2.1" - checksum: ea4f1756d90f55254c4dc7a20d6c5d5bc169160562aefe3d8756b598c10e695daf568f21b6d6b12245d7f3782d3ff83ef6a01ab75d487adfc6909470a813bf8c - languageName: node - linkType: hard - -"assert-plus@npm:1.0.0, assert-plus@npm:^1.0.0": - version: 1.0.0 - resolution: "assert-plus@npm:1.0.0" - checksum: 19b4340cb8f0e6a981c07225eacac0e9d52c2644c080198765d63398f0075f83bbc0c8e95474d54224e297555ad0d631c1dcd058adb1ddc2437b41a6b424ac64 - languageName: node - linkType: hard - -"assertion-error@npm:^1.1.0": - version: 1.1.0 - resolution: "assertion-error@npm:1.1.0" - checksum: fd9429d3a3d4fd61782eb3962ae76b6d08aa7383123fca0596020013b3ebd6647891a85b05ce821c47d1471ed1271f00b0545cf6a4326cf2fc91efcc3b0fbecf - languageName: node - linkType: hard - -"astral-regex@npm:^2.0.0": - version: 2.0.0 - resolution: "astral-regex@npm:2.0.0" - checksum: 876231688c66400473ba505731df37ea436e574dd524520294cc3bbc54ea40334865e01fa0d074d74d036ee874ee7e62f486ea38bc421ee8e6a871c06f011766 - languageName: node - linkType: hard - -"async-validator@npm:^4.0.7": - version: 4.1.1 - resolution: "async-validator@npm:4.1.1" - checksum: 88590ab8ad1db6e3f6e01136d5313d4e91e269e74b7d4017aa16c64dac5be2697dbd1ff3de18f0e000d12073626475de9f77ba41808af38b0ea23eb0e6e8a361 - languageName: node - linkType: hard - -"async@npm:^3.2.0": - version: 3.2.3 - resolution: "async@npm:3.2.3" - checksum: c4bee57ab2249af3dc83ca3ef9acfa8e822c0d5e5aa41bae3eaf7f673648343cd64ecd7d26091ffd357f3f044428b17b5f00098494b6cf8b6b3e9681f0636ca1 - languageName: node - linkType: hard - -"asynckit@npm:^0.4.0": - version: 0.4.0 - resolution: "asynckit@npm:0.4.0" - checksum: 7b78c451df768adba04e2d02e63e2d0bf3b07adcd6e42b4cf665cb7ce899bedd344c69a1dcbce355b5f972d597b25aaa1c1742b52cffd9caccb22f348114f6be - languageName: node - linkType: hard - -"at-least-node@npm:^1.0.0": - version: 1.0.0 - resolution: "at-least-node@npm:1.0.0" - checksum: 463e2f8e43384f1afb54bc68485c436d7622acec08b6fad269b421cb1d29cebb5af751426793d0961ed243146fe4dc983402f6d5a51b720b277818dbf6f2e49e - languageName: node - linkType: hard - -"aws-sign2@npm:~0.7.0": - version: 0.7.0 - resolution: "aws-sign2@npm:0.7.0" - checksum: b148b0bb0778098ad8cf7e5fc619768bcb51236707ca1d3e5b49e41b171166d8be9fdc2ea2ae43d7decf02989d0aaa3a9c4caa6f320af95d684de9b548a71525 - languageName: node - linkType: hard - -"aws4@npm:^1.8.0": - version: 1.11.0 - resolution: "aws4@npm:1.11.0" - checksum: 5a00d045fd0385926d20ebebcfba5ec79d4482fe706f63c27b324d489a04c68edb0db99ed991e19eda09cb8c97dc2452059a34d97545cebf591d7a2b5a10999f - languageName: node - linkType: hard - -"babel-walk@npm:3.0.0-canary-5": - version: 3.0.0-canary-5 - resolution: "babel-walk@npm:3.0.0-canary-5" - dependencies: - "@babel/types": ^7.9.6 - checksum: 6fe7ee3889343a6602f665c28ea135956a0767d7f7ca5fc1d72c5243e2f6e9d8a64f51254bf2fd0cce47b79fceeccf7a357f37cfa755a509dfb930a21151837c - languageName: node - linkType: hard - -"balanced-match@npm:^1.0.0": - version: 1.0.2 - resolution: "balanced-match@npm:1.0.2" - checksum: 9706c088a283058a8a99e0bf91b0a2f75497f185980d9ffa8b304de1d9e58ebda7c72c07ebf01dadedaac5b2907b2c6f566f660d62bd336c3468e960403b9d65 - languageName: node - linkType: hard - -"base-x@npm:^3.0.8": - version: 3.0.9 - resolution: "base-x@npm:3.0.9" - dependencies: - safe-buffer: ^5.0.1 - checksum: 957101d6fd09e1903e846fd8f69fd7e5e3e50254383e61ab667c725866bec54e5ece5ba49ce385128ae48f9ec93a26567d1d5ebb91f4d56ef4a9cc0d5a5481e8 - languageName: node - linkType: hard - -"base64-js@npm:^1.3.1": - version: 1.5.1 - resolution: "base64-js@npm:1.5.1" - checksum: 669632eb3745404c2f822a18fc3a0122d2f9a7a13f7fb8b5823ee19d1d2ff9ee5b52c53367176ea4ad093c332fd5ab4bd0ebae5a8e27917a4105a4cfc86b1005 - languageName: node - linkType: hard - -"bcrypt-pbkdf@npm:^1.0.0": - version: 1.0.2 - resolution: "bcrypt-pbkdf@npm:1.0.2" - dependencies: - tweetnacl: ^0.14.3 - checksum: 4edfc9fe7d07019609ccf797a2af28351736e9d012c8402a07120c4453a3b789a15f2ee1530dc49eee8f7eb9379331a8dd4b3766042b9e502f74a68e7f662291 - languageName: node - linkType: hard - -"binary-extensions@npm:^2.0.0": - version: 2.2.0 - resolution: "binary-extensions@npm:2.2.0" - checksum: ccd267956c58d2315f5d3ea6757cf09863c5fc703e50fbeb13a7dc849b812ef76e3cf9ca8f35a0c48498776a7478d7b4a0418e1e2b8cb9cb9731f2922aaad7f8 - languageName: node - linkType: hard - -"blob-util@npm:^2.0.2": - version: 2.0.2 - resolution: "blob-util@npm:2.0.2" - checksum: d543e6b92e4ca715ca33c78e89a07a2290d43e5b2bc897d7ec588c5c7bbf59df93e45225ac0c9258aa6ce4320358990f99c9288f1c48280f8ec5d7a2e088d19b - languageName: node - linkType: hard - -"bluebird@npm:^3.7.2": - version: 3.7.2 - resolution: "bluebird@npm:3.7.2" - checksum: 869417503c722e7dc54ca46715f70e15f4d9c602a423a02c825570862d12935be59ed9c7ba34a9b31f186c017c23cac6b54e35446f8353059c101da73eac22ef - languageName: node - linkType: hard - -"boolbase@npm:^1.0.0": - version: 1.0.0 - resolution: "boolbase@npm:1.0.0" - checksum: 3e25c80ef626c3a3487c73dbfc70ac322ec830666c9ad915d11b701142fab25ec1e63eff2c450c74347acfd2de854ccde865cd79ef4db1683f7c7b046ea43bb0 - languageName: node - linkType: hard - -"bootstrap-icons@npm:1.9.1": - version: 1.9.1 - resolution: "bootstrap-icons@npm:1.9.1" - checksum: b388264719b5d2526809df509b83aa7e696d467f3b976d79faefb6fc7f07cee5427a894331af90b00b1ceb8d28a99fc398f1ca0553afaa53eb77a7749bb73ea5 - languageName: node - linkType: hard - -"bootstrap@npm:5.2.0": - version: 5.2.0 - resolution: "bootstrap@npm:5.2.0" - peerDependencies: - "@popperjs/core": ^2.11.5 - checksum: 9dbfb5d26bbdac3e27a6b46cb7456cd4dd75ae3b48644737809885b8ea9c265d3359c4cdbf25a55bb7e5046f51e441557033ba21eeaf24ef8316bfbb3d420084 - languageName: node - linkType: hard - -"bootstrap@npm:^5.1.3": - version: 5.1.3 - resolution: "bootstrap@npm:5.1.3" - peerDependencies: - "@popperjs/core": ^2.10.2 - checksum: 301b5ed872efba061104cf22ac93568e3837867fb5527ab9326a51510fb752bd4883e1d488225c8be72f86d9d3a55ef5b166aa7fa62c2fdd077c3f05b65752f8 - languageName: node - linkType: hard - -"brace-expansion@npm:^1.1.7": - version: 1.1.11 - resolution: "brace-expansion@npm:1.1.11" - dependencies: - balanced-match: ^1.0.0 - concat-map: 0.0.1 - checksum: faf34a7bb0c3fcf4b59c7808bc5d2a96a40988addf2e7e09dfbb67a2251800e0d14cd2bfc1aa79174f2f5095c54ff27f46fb1289fe2d77dac755b5eb3434cc07 - languageName: node - linkType: hard - -"brace-expansion@npm:^2.0.1": - version: 2.0.1 - resolution: "brace-expansion@npm:2.0.1" - dependencies: - balanced-match: ^1.0.0 - checksum: a61e7cd2e8a8505e9f0036b3b6108ba5e926b4b55089eeb5550cd04a471fe216c96d4fe7e4c7f995c728c554ae20ddfc4244cad10aef255e72b62930afd233d1 - languageName: node - linkType: hard - -"braces@npm:~3.0.2": - version: 3.0.2 - resolution: "braces@npm:3.0.2" - dependencies: - fill-range: ^7.0.1 - checksum: e2a8e769a863f3d4ee887b5fe21f63193a891c68b612ddb4b68d82d1b5f3ff9073af066c343e9867a393fe4c2555dcb33e89b937195feb9c1613d259edfcd459 - languageName: node - linkType: hard - -"browser-fs-access@npm:0.31.0": - version: 0.31.0 - resolution: "browser-fs-access@npm:0.31.0" - checksum: d1b6682415c2ee4c05dc44cd95daaa1a4f3f59d1ec723bde0d384bf44b71c804a665ca24a3805d0a76d7f2626541d4a777df4f45ae4a7439a8b76e20897d301d - languageName: node - linkType: hard - -browserlist@latest: - version: 1.0.1 - resolution: "browserlist@npm:1.0.1" - dependencies: - chalk: ^2.4.1 - bin: - browserlist: ./cli.js - checksum: db4dc273b59637f4e716676978d2c8a2431fb021860ec8ea9552eebe24bff67e955630d42c3995a9b03c1606819b18fb032ab943103b54b830933ec4d695e516 - languageName: node - linkType: hard - -"browserslist@npm:^4.6.6": - version: 4.20.3 - resolution: "browserslist@npm:4.20.3" - dependencies: - caniuse-lite: ^1.0.30001332 - electron-to-chromium: ^1.4.118 - escalade: ^3.1.1 - node-releases: ^2.0.3 - picocolors: ^1.0.0 - bin: - browserslist: cli.js - checksum: 1e4b719ac2ca0fe235218a606e8b8ef16b8809e0973b924158c39fbc435a0b0fe43437ea52dd6ef5ad2efcb83fcb07431244e472270177814217f7c563651f7d - languageName: node - linkType: hard - -"buffer-crc32@npm:~0.2.3": - version: 0.2.13 - resolution: "buffer-crc32@npm:0.2.13" - checksum: 06252347ae6daca3453b94e4b2f1d3754a3b146a111d81c68924c22d91889a40623264e95e67955b1cb4a68cbedf317abeabb5140a9766ed248973096db5ce1c - languageName: node - linkType: hard - -"buffer-from@npm:^1.0.0": - version: 1.1.2 - resolution: "buffer-from@npm:1.1.2" - checksum: 0448524a562b37d4d7ed9efd91685a5b77a50672c556ea254ac9a6d30e3403a517d8981f10e565db24e8339413b43c97ca2951f10e399c6125a0d8911f5679bb - languageName: node - linkType: hard - -"buffer@npm:^5.6.0": - version: 5.7.1 - resolution: "buffer@npm:5.7.1" - dependencies: - base64-js: ^1.3.1 - ieee754: ^1.1.13 - checksum: e2cf8429e1c4c7b8cbd30834ac09bd61da46ce35f5c22a78e6c2f04497d6d25541b16881e30a019c6fd3154150650ccee27a308eff3e26229d788bbdeb08ab84 - languageName: node - linkType: hard - -"builtins@npm:^4.0.0": - version: 4.1.0 - resolution: "builtins@npm:4.1.0" - dependencies: - semver: ^7.0.0 - checksum: 3524f5a5898c3f77a73fee2e0046e676abbb0acc18db1e495676ee07fbef1537134b0e9c4da525f4cb12ba3cd1b430a26c373d32b59b80a5c048f8ace31b595f - languageName: node - linkType: hard - -"c8@npm:7.12.0": - version: 7.12.0 - resolution: "c8@npm:7.12.0" - dependencies: - "@bcoe/v8-coverage": ^0.2.3 - "@istanbuljs/schema": ^0.1.3 - find-up: ^5.0.0 - foreground-child: ^2.0.0 - istanbul-lib-coverage: ^3.2.0 - istanbul-lib-report: ^3.0.0 - istanbul-reports: ^3.1.4 - rimraf: ^3.0.2 - test-exclude: ^6.0.0 - v8-to-istanbul: ^9.0.0 - yargs: ^16.2.0 - yargs-parser: ^20.2.9 - bin: - c8: bin/c8.js - checksum: 3b7fa9ad7cff2cb0bb579467e6b544498fbd46e9353a809ad3b8cf749df4beadd074cde277356b0552f3c8055b1b3ec3ebaf2209e9ad4bdefed92dbf64d283ab - languageName: node - linkType: hard - -"cacache@npm:^16.1.0": - version: 16.1.0 - resolution: "cacache@npm:16.1.0" - dependencies: - "@npmcli/fs": ^2.1.0 - "@npmcli/move-file": ^2.0.0 - chownr: ^2.0.0 - fs-minipass: ^2.1.0 - glob: ^8.0.1 - infer-owner: ^1.0.4 - lru-cache: ^7.7.1 - minipass: ^3.1.6 - minipass-collect: ^1.0.2 - minipass-flush: ^1.0.5 - minipass-pipeline: ^1.2.4 - mkdirp: ^1.0.4 - p-map: ^4.0.0 - promise-inflight: ^1.0.1 - rimraf: ^3.0.2 - ssri: ^9.0.0 - tar: ^6.1.11 - unique-filename: ^1.1.1 - checksum: ddfcf92f079f24ccecef4e2ca1e4428443787b61429b921803b020fd0f33d9ac829ac47837b74b40868d8ae4f1b2ed82e164cdaa5508fbd790eee005a9d88469 - languageName: node - linkType: hard - -"cachedir@npm:^2.3.0": - version: 2.3.0 - resolution: "cachedir@npm:2.3.0" - checksum: ec90cb0f2e6336e266aa748dbadf3da9e0b20e843e43f1591acab7a3f1451337dc2f26cb9dd833ae8cfefeffeeb43ef5b5ff62782a685f4e3c2305dd98482fcb - languageName: node - linkType: hard - -"call-bind@npm:^1.0.0, call-bind@npm:^1.0.2": - version: 1.0.2 - resolution: "call-bind@npm:1.0.2" - dependencies: - function-bind: ^1.1.1 - get-intrinsic: ^1.0.2 - checksum: f8e31de9d19988a4b80f3e704788c4a2d6b6f3d17cfec4f57dc29ced450c53a49270dc66bf0fbd693329ee948dd33e6c90a329519aef17474a4d961e8d6426b0 - languageName: node - linkType: hard - -"callsites@npm:^3.0.0": - version: 3.1.0 - resolution: "callsites@npm:3.1.0" - checksum: 072d17b6abb459c2ba96598918b55868af677154bec7e73d222ef95a8fdb9bbf7dae96a8421085cdad8cd190d86653b5b6dc55a4484f2e5b2e27d5e0c3fc15b3 - languageName: node - linkType: hard - -"caniuse-lite@npm:1.0.30001368": - version: 1.0.30001368 - resolution: "caniuse-lite@npm:1.0.30001368" - checksum: e2a763e7bca8f7a2494f752d0e1a5c0cd1c70ebd18df2eda2bdcf2f908901bbff14f78961ad1cada3eb7af32120ce95aa93f06c5a093d721e787816dc7f5bfaa - languageName: node - linkType: hard - -"caniuse-lite@npm:^1.0.30001332": - version: 1.0.30001340 - resolution: "caniuse-lite@npm:1.0.30001340" - checksum: 5b419c93cb5a67568ffe8c84520d149146e5b84056ce41ee509c89d2bd036e4ce6d87485e25dfee2bb8a818d46e0734e93cacbef6b9b911c20166b943b36b78c - languageName: node - linkType: hard - -"caseless@npm:~0.12.0": - version: 0.12.0 - resolution: "caseless@npm:0.12.0" - checksum: b43bd4c440aa1e8ee6baefee8063b4850fd0d7b378f6aabc796c9ec8cb26d27fb30b46885350777d9bd079c5256c0e1329ad0dc7c2817e0bb466810ebb353751 - languageName: node - linkType: hard - -"chai@npm:^4.3.6": - version: 4.3.6 - resolution: "chai@npm:4.3.6" - dependencies: - assertion-error: ^1.1.0 - check-error: ^1.0.2 - deep-eql: ^3.0.1 - get-func-name: ^2.0.0 - loupe: ^2.3.1 - pathval: ^1.1.1 - type-detect: ^4.0.5 - checksum: acff93fd537f96d4a4d62dd83810285dffcfccb5089e1bf2a1205b28ec82d93dff551368722893cf85004282df10ee68802737c33c90c5493957ed449ed7ce71 - languageName: node - linkType: hard - -"chalk@npm:^2.0.0, chalk@npm:^2.4.1": - version: 2.4.2 - resolution: "chalk@npm:2.4.2" - dependencies: - ansi-styles: ^3.2.1 - escape-string-regexp: ^1.0.5 - supports-color: ^5.3.0 - checksum: ec3661d38fe77f681200f878edbd9448821924e0f93a9cefc0e26a33b145f1027a2084bf19967160d11e1f03bfe4eaffcabf5493b89098b2782c3fe0b03d80c2 - languageName: node - linkType: hard - -"chalk@npm:^4.0.0, chalk@npm:^4.1.0": - version: 4.1.2 - resolution: "chalk@npm:4.1.2" - dependencies: - ansi-styles: ^4.1.0 - supports-color: ^7.1.0 - checksum: fe75c9d5c76a7a98d45495b91b2172fa3b7a09e0cc9370e5c8feb1c567b85c4288e2b3fded7cfdd7359ac28d6b3844feb8b82b8686842e93d23c827c417e83fc - languageName: node - linkType: hard - -"character-parser@npm:^2.2.0": - version: 2.2.0 - resolution: "character-parser@npm:2.2.0" - dependencies: - is-regex: ^1.0.3 - checksum: 71826fae509d4dc3ef07c2e824da9c8853f910ba0d8fe699edaab263051fd3b8db77bb96e46ed896bb36ed1d86108e6d6ceedff436bec7786ba7f0b585a0bc93 - languageName: node - linkType: hard - -"check-error@npm:^1.0.2": - version: 1.0.2 - resolution: "check-error@npm:1.0.2" - checksum: d9d106504404b8addd1ee3f63f8c0eaa7cd962a1a28eb9c519b1c4a1dc7098be38007fc0060f045ee00f075fbb7a2a4f42abcf61d68323677e11ab98dc16042e - languageName: node - linkType: hard - -"check-more-types@npm:^2.24.0": - version: 2.24.0 - resolution: "check-more-types@npm:2.24.0" - checksum: b09080ec3404d20a4b0ead828994b2e5913236ef44ed3033a27062af0004cf7d2091fbde4b396bf13b7ce02fb018bc9960b48305e6ab2304cd82d73ed7a51ef4 - languageName: node - linkType: hard - -"chokidar@npm:>=3.0.0 <4.0.0": - version: 3.5.3 - resolution: "chokidar@npm:3.5.3" - dependencies: - anymatch: ~3.1.2 - braces: ~3.0.2 - fsevents: ~2.3.2 - glob-parent: ~5.1.2 - is-binary-path: ~2.1.0 - is-glob: ~4.0.1 - normalize-path: ~3.0.0 - readdirp: ~3.6.0 - dependenciesMeta: - fsevents: - optional: true - checksum: b49fcde40176ba007ff361b198a2d35df60d9bb2a5aab228279eb810feae9294a6b4649ab15981304447afe1e6ffbf4788ad5db77235dc770ab777c6e771980c - languageName: node - linkType: hard - -"chownr@npm:^2.0.0": - version: 2.0.0 - resolution: "chownr@npm:2.0.0" - checksum: c57cf9dd0791e2f18a5ee9c1a299ae6e801ff58fee96dc8bfd0dcb4738a6ce58dd252a3605b1c93c6418fe4f9d5093b28ffbf4d66648cb2a9c67eaef9679be2f - languageName: node - linkType: hard - -"chrome-trace-event@npm:^1.0.2": - version: 1.0.3 - resolution: "chrome-trace-event@npm:1.0.3" - checksum: cb8b1fc7e881aaef973bd0c4a43cd353c2ad8323fb471a041e64f7c2dd849cde4aad15f8b753331a32dda45c973f032c8a03b8177fc85d60eaa75e91e08bfb97 - languageName: node - linkType: hard - -"ci-info@npm:^3.2.0": - version: 3.3.1 - resolution: "ci-info@npm:3.3.1" - checksum: 244546317cca96955860d2cb8d0bf47dd66d9078bbe83a215fa87464ab24b352c6fc6f56027d1c82f002e3f833be253f1320d35ed7199bd81134f7788c657f3a - languageName: node - linkType: hard - -"clean-stack@npm:^2.0.0": - version: 2.2.0 - resolution: "clean-stack@npm:2.2.0" - checksum: 2ac8cd2b2f5ec986a3c743935ec85b07bc174d5421a5efc8017e1f146a1cf5f781ae962618f416352103b32c9cd7e203276e8c28241bbe946160cab16149fb68 - languageName: node - linkType: hard - -"cli-cursor@npm:^3.1.0": - version: 3.1.0 - resolution: "cli-cursor@npm:3.1.0" - dependencies: - restore-cursor: ^3.1.0 - checksum: 2692784c6cd2fd85cfdbd11f53aea73a463a6d64a77c3e098b2b4697a20443f430c220629e1ca3b195ea5ac4a97a74c2ee411f3807abf6df2b66211fec0c0a29 - languageName: node - linkType: hard - -"cli-table3@npm:~0.6.1": - version: 0.6.2 - resolution: "cli-table3@npm:0.6.2" - dependencies: - "@colors/colors": 1.5.0 - string-width: ^4.2.0 - dependenciesMeta: - "@colors/colors": - optional: true - checksum: 2f82391698b8a2a2a5e45d2adcfea5d93e557207f90455a8d4c1aac688e9b18a204d9eb4ba1d322fa123b17d64ea3dc5e11de8b005529f3c3e7dbeb27cb4d9be - languageName: node - linkType: hard - -"cli-truncate@npm:^2.1.0": - version: 2.1.0 - resolution: "cli-truncate@npm:2.1.0" - dependencies: - slice-ansi: ^3.0.0 - string-width: ^4.2.0 - checksum: bf1e4e6195392dc718bf9cd71f317b6300dc4a9191d052f31046b8773230ece4fa09458813bf0e3455a5e68c0690d2ea2c197d14a8b85a7b5e01c97f4b5feb5d - languageName: node - linkType: hard - -"cliui@npm:^7.0.2": - version: 7.0.4 - resolution: "cliui@npm:7.0.4" - dependencies: - string-width: ^4.2.0 - strip-ansi: ^6.0.0 - wrap-ansi: ^7.0.0 - checksum: ce2e8f578a4813806788ac399b9e866297740eecd4ad1823c27fd344d78b22c5f8597d548adbcc46f0573e43e21e751f39446c5a5e804a12aace402b7a315d7f - languageName: node - linkType: hard - -"clone@npm:^2.1.1": - version: 2.1.2 - resolution: "clone@npm:2.1.2" - checksum: aaf106e9bc025b21333e2f4c12da539b568db4925c0501a1bf4070836c9e848c892fa22c35548ce0d1132b08bbbfa17a00144fe58fccdab6fa900fec4250f67d - languageName: node - linkType: hard - -"color-convert@npm:^1.9.0": - version: 1.9.3 - resolution: "color-convert@npm:1.9.3" - dependencies: - color-name: 1.1.3 - checksum: fd7a64a17cde98fb923b1dd05c5f2e6f7aefda1b60d67e8d449f9328b4e53b228a428fd38bfeaeb2db2ff6b6503a776a996150b80cdf224062af08a5c8a3a203 - languageName: node - linkType: hard - -"color-convert@npm:^2.0.1": - version: 2.0.1 - resolution: "color-convert@npm:2.0.1" - dependencies: - color-name: ~1.1.4 - checksum: 79e6bdb9fd479a205c71d89574fccfb22bd9053bd98c6c4d870d65c132e5e904e6034978e55b43d69fcaa7433af2016ee203ce76eeba9cfa554b373e7f7db336 - languageName: node - linkType: hard - -"color-name@npm:1.1.3": - version: 1.1.3 - resolution: "color-name@npm:1.1.3" - checksum: 09c5d3e33d2105850153b14466501f2bfb30324a2f76568a408763a3b7433b0e50e5b4ab1947868e65cb101bb7cb75029553f2c333b6d4b8138a73fcc133d69d - languageName: node - linkType: hard - -"color-name@npm:~1.1.4": - version: 1.1.4 - resolution: "color-name@npm:1.1.4" - checksum: b0445859521eb4021cd0fb0cc1a75cecf67fceecae89b63f62b201cca8d345baf8b952c966862a9d9a2632987d4f6581f0ec8d957dfacece86f0a7919316f610 - languageName: node - linkType: hard - -"color-support@npm:^1.1.3": - version: 1.1.3 - resolution: "color-support@npm:1.1.3" - bin: - color-support: bin.js - checksum: 9b7356817670b9a13a26ca5af1c21615463b500783b739b7634a0c2047c16cef4b2865d7576875c31c3cddf9dd621fa19285e628f20198b233a5cfdda6d0793b - languageName: node - linkType: hard - -"colorette@npm:^2.0.16": - version: 2.0.16 - resolution: "colorette@npm:2.0.16" - checksum: cd55596a3a2d1071c1a28eee7fd8a5387593ff1bd10a3e8d0a6221499311fe34a9f2b9272d77c391e0e003dcdc8934fb2f8d106e7ef1f7516f8060c901d41a27 - languageName: node - linkType: hard - -"combined-stream@npm:^1.0.6, combined-stream@npm:~1.0.6": - version: 1.0.8 - resolution: "combined-stream@npm:1.0.8" - dependencies: - delayed-stream: ~1.0.0 - checksum: 49fa4aeb4916567e33ea81d088f6584749fc90c7abec76fd516bf1c5aa5c79f3584b5ba3de6b86d26ddd64bae5329c4c7479343250cfe71c75bb366eae53bb7c - languageName: node - linkType: hard - -"commander@npm:7, commander@npm:^7.0.0, commander@npm:^7.2.0": - version: 7.2.0 - resolution: "commander@npm:7.2.0" - checksum: 53501cbeee61d5157546c0bef0fedb6cdfc763a882136284bed9a07225f09a14b82d2a84e7637edfd1a679fb35ed9502fd58ef1d091e6287f60d790147f68ddc - languageName: node - linkType: hard - -"commander@npm:^2.20.0": - version: 2.20.3 - resolution: "commander@npm:2.20.3" - checksum: ab8c07884e42c3a8dbc5dd9592c606176c7eb5c1ca5ff274bcf907039b2c41de3626f684ea75ccf4d361ba004bbaff1f577d5384c155f3871e456bdf27becf9e - languageName: node - linkType: hard - -"commander@npm:^5.1.0": - version: 5.1.0 - resolution: "commander@npm:5.1.0" - checksum: 0b7fec1712fbcc6230fcb161d8d73b4730fa91a21dc089515489402ad78810547683f058e2a9835929c212fead1d6a6ade70db28bbb03edbc2829a9ab7d69447 - languageName: node - linkType: hard - -"common-tags@npm:^1.8.0": - version: 1.8.2 - resolution: "common-tags@npm:1.8.2" - checksum: 767a6255a84bbc47df49a60ab583053bb29a7d9687066a18500a516188a062c4e4cd52de341f22de0b07062e699b1b8fe3cfa1cb55b241cb9301aeb4f45b4dff - languageName: node - linkType: hard - -"concat-map@npm:0.0.1": - version: 0.0.1 - resolution: "concat-map@npm:0.0.1" - checksum: 902a9f5d8967a3e2faf138d5cb784b9979bad2e6db5357c5b21c568df4ebe62bcb15108af1b2253744844eb964fc023fbd9afbbbb6ddd0bcc204c6fb5b7bf3af - languageName: node - linkType: hard - -"console-control-strings@npm:^1.1.0": - version: 1.1.0 - resolution: "console-control-strings@npm:1.1.0" - checksum: 8755d76787f94e6cf79ce4666f0c5519906d7f5b02d4b884cf41e11dcd759ed69c57da0670afd9236d229a46e0f9cf519db0cd829c6dca820bb5a5c3def584ed - languageName: node - linkType: hard - -"constantinople@npm:^4.0.1": - version: 4.0.1 - resolution: "constantinople@npm:4.0.1" - dependencies: - "@babel/parser": ^7.6.0 - "@babel/types": ^7.6.1 - checksum: 8f70f16ddf97cdc263ca16b398bc52470c25e2ec5ed27bc015f251b849597223ce3a123e6924f43efddeb75422c1f55b7e56e0e2e594e4dd2964bfc9392b9b82 - languageName: node - linkType: hard - -"convert-source-map@npm:^1.6.0": - version: 1.8.0 - resolution: "convert-source-map@npm:1.8.0" - dependencies: - safe-buffer: ~5.1.1 - checksum: 985d974a2d33e1a2543ada51c93e1ba2f73eaed608dc39f229afc78f71dcc4c8b7d7c684aa647e3c6a3a204027444d69e53e169ce94e8d1fa8d7dee80c9c8fed - languageName: node - linkType: hard - -"core-util-is@npm:1.0.2": - version: 1.0.2 - resolution: "core-util-is@npm:1.0.2" - checksum: 7a4c925b497a2c91421e25bf76d6d8190f0b2359a9200dbeed136e63b2931d6294d3b1893eda378883ed363cd950f44a12a401384c609839ea616befb7927dab - languageName: node - linkType: hard - -"cosmiconfig@npm:^7.0.1": - version: 7.0.1 - resolution: "cosmiconfig@npm:7.0.1" - dependencies: - "@types/parse-json": ^4.0.0 - import-fresh: ^3.2.1 - parse-json: ^5.0.0 - path-type: ^4.0.0 - yaml: ^1.10.0 - checksum: 4be63e7117955fd88333d7460e4c466a90f556df6ef34efd59034d2463484e339666c41f02b523d574a797ec61f4a91918c5b89a316db2ea2f834e0d2d09465b - languageName: node - linkType: hard - -"cross-spawn@npm:^7.0.0, cross-spawn@npm:^7.0.2": - version: 7.0.3 - resolution: "cross-spawn@npm:7.0.3" - dependencies: - path-key: ^3.1.0 - shebang-command: ^2.0.0 - which: ^2.0.1 - checksum: 671cc7c7288c3a8406f3c69a3ae2fc85555c04169e9d611def9a675635472614f1c0ed0ef80955d5b6d4e724f6ced67f0ad1bb006c2ea643488fcfef994d7f52 - languageName: node - linkType: hard - -"css-render@npm:^0.15.10": - version: 0.15.10 - resolution: "css-render@npm:0.15.10" - dependencies: - "@emotion/hash": ~0.8.0 - "@types/node": ~17.0.5 - csstype: ~3.0.5 - checksum: 051ebb6a56bc8ef1149ef15eecef54b9a08e6ba1aec8866e459c6823988c5307b7e52de4c80fa17ac80d04a81573dbe7811092b2ba85cc586c78fb1f0f7ab918 - languageName: node - linkType: hard - -"css-select@npm:^4.1.3": - version: 4.3.0 - resolution: "css-select@npm:4.3.0" - dependencies: - boolbase: ^1.0.0 - css-what: ^6.0.1 - domhandler: ^4.3.1 - domutils: ^2.8.0 - nth-check: ^2.0.1 - checksum: d6202736839194dd7f910320032e7cfc40372f025e4bf21ca5bf6eb0a33264f322f50ba9c0adc35dadd342d3d6fae5ca244779a4873afbfa76561e343f2058e0 - languageName: node - linkType: hard - -"css-tree@npm:^1.1.2, css-tree@npm:^1.1.3": - version: 1.1.3 - resolution: "css-tree@npm:1.1.3" - dependencies: - mdn-data: 2.0.14 - source-map: ^0.6.1 - checksum: 79f9b81803991b6977b7fcb1588799270438274d89066ce08f117f5cdb5e20019b446d766c61506dd772c839df84caa16042d6076f20c97187f5abe3b50e7d1f - languageName: node - linkType: hard - -"css-what@npm:^6.0.1": - version: 6.1.0 - resolution: "css-what@npm:6.1.0" - checksum: b975e547e1e90b79625918f84e67db5d33d896e6de846c9b584094e529f0c63e2ab85ee33b9daffd05bff3a146a1916bec664e18bb76dd5f66cbff9fc13b2bbe - languageName: node - linkType: hard - -"cssesc@npm:^3.0.0": - version: 3.0.0 - resolution: "cssesc@npm:3.0.0" - bin: - cssesc: bin/cssesc - checksum: f8c4ababffbc5e2ddf2fa9957dda1ee4af6048e22aeda1869d0d00843223c1b13ad3f5d88b51caa46c994225eacb636b764eb807a8883e2fb6f99b4f4e8c48b2 - languageName: node - linkType: hard - -"csso@npm:^4.2.0": - version: 4.2.0 - resolution: "csso@npm:4.2.0" - dependencies: - css-tree: ^1.1.2 - checksum: 380ba9663da3bcea58dee358a0d8c4468bb6539be3c439dc266ac41c047217f52fd698fb7e4b6b6ccdfb8cf53ef4ceed8cc8ceccb8dfca2aa628319826b5b998 - languageName: node - linkType: hard - -"csstype@npm:^2.6.8": - version: 2.6.20 - resolution: "csstype@npm:2.6.20" - checksum: cb5d5ded49c3390909e93b20b285d4a63d0ba5b10294bdfbc4cf911f80e91d6cf367ea671f99f09570762535c14ea7074a2c7fa73f02008203f01328dea8968b - languageName: node - linkType: hard - -"csstype@npm:~3.0.5": - version: 3.0.11 - resolution: "csstype@npm:3.0.11" - checksum: 95e56abfe9ca219ae065acb4e43f61771a03170eed919127f558dfa168240867aba7629c8d98a201a0dd06d9a5ce82686f0570031c928516c61816adbc7c877f - languageName: node - linkType: hard - -"cypress-real-events@npm:1.7.1": - version: 1.7.1 - resolution: "cypress-real-events@npm:1.7.1" - peerDependencies: - cypress: ^4.x || ^5.x || ^6.x || ^7.x || ^8.x || ^9.x || ^10.x - checksum: b31c2facfa03e01e298926cd0925260b12474770fc1a3ce8998da21818db7e6d9fc2f9eb60d1771aa4ce3c29aca63d04da21e1a63e3bb117b1506a72ab0c3eb1 - languageName: node - linkType: hard - -"cypress@npm:10.3.1": - version: 10.3.1 - resolution: "cypress@npm:10.3.1" - dependencies: - "@cypress/request": ^2.88.10 - "@cypress/xvfb": ^1.2.4 - "@types/node": ^14.14.31 - "@types/sinonjs__fake-timers": 8.1.1 - "@types/sizzle": ^2.3.2 - arch: ^2.2.0 - blob-util: ^2.0.2 - bluebird: ^3.7.2 - buffer: ^5.6.0 - cachedir: ^2.3.0 - chalk: ^4.1.0 - check-more-types: ^2.24.0 - cli-cursor: ^3.1.0 - cli-table3: ~0.6.1 - commander: ^5.1.0 - common-tags: ^1.8.0 - dayjs: ^1.10.4 - debug: ^4.3.2 - enquirer: ^2.3.6 - eventemitter2: ^6.4.3 - execa: 4.1.0 - executable: ^4.1.1 - extract-zip: 2.0.1 - figures: ^3.2.0 - fs-extra: ^9.1.0 - getos: ^3.2.1 - is-ci: ^3.0.0 - is-installed-globally: ~0.4.0 - lazy-ass: ^1.6.0 - listr2: ^3.8.3 - lodash: ^4.17.21 - log-symbols: ^4.0.0 - minimist: ^1.2.6 - ospath: ^1.2.2 - pretty-bytes: ^5.6.0 - proxy-from-env: 1.0.0 - request-progress: ^3.0.0 - semver: ^7.3.2 - supports-color: ^8.1.1 - tmp: ~0.2.1 - untildify: ^4.0.0 - yauzl: ^2.10.0 - bin: - cypress: bin/cypress - checksum: 7c76157195ec9409b9665aa9f7698ffd221c74c17f5026769fa20f90a60869cc8274282fa5b9b65e495429839f7a0ba05d69cf12a8af7a318ebcd704f96156c2 - languageName: node - linkType: hard - -"d3-array@npm:2 - 3, d3-array@npm:2.10.0 - 3, d3-array@npm:2.5.0 - 3, d3-array@npm:3": - version: 3.1.6 - resolution: "d3-array@npm:3.1.6" - dependencies: - internmap: 1 - 2 - checksum: 32f515bd2559624681048ca86b0bd395047887b3473ddf136ddb4276620c39a0f3996865320ac49c74969a06a8e30e6f9d2d2097e908ba49c11b0f7fe0cbebda - languageName: node - linkType: hard - -"d3-array@npm:^3.2.0": - version: 3.2.0 - resolution: "d3-array@npm:3.2.0" - dependencies: - internmap: 1 - 2 - checksum: e236f6670b60b64abb6c435da25b5cbbdc2c7c0decdbf9355bc4cf6803d6da4fa820b7b78b9cbd127edb493555934a9788d45084c2f39d7c2e1a2b7aa48264a4 - languageName: node - linkType: hard - -"d3-axis@npm:3": - version: 3.0.0 - resolution: "d3-axis@npm:3.0.0" - checksum: 227ddaa6d4bad083539c1ec245e2228b4620cca941997a8a650cb0af239375dc20271993127eedac66f0543f331027aca09385e1e16eed023f93eac937cddf0b - languageName: node - linkType: hard - -"d3-brush@npm:3": - version: 3.0.0 - resolution: "d3-brush@npm:3.0.0" - dependencies: - d3-dispatch: 1 - 3 - d3-drag: 2 - 3 - d3-interpolate: 1 - 3 - d3-selection: 3 - d3-transition: 3 - checksum: 1d042167769a02ac76271c71e90376d7184206e489552b7022a8ec2860209fe269db55e0a3430f3dcbe13b6fec2ff65b1adeaccba3218991b38e022390df72e3 - languageName: node - linkType: hard - -"d3-chord@npm:3": - version: 3.0.1 - resolution: "d3-chord@npm:3.0.1" - dependencies: - d3-path: 1 - 3 - checksum: ddf35d41675e0f8738600a8a2f05bf0858def413438c12cba357c5802ecc1014c80a658acbbee63cbad2a8c747912efb2358455d93e59906fe37469f1dc6b78b - languageName: node - linkType: hard - -"d3-color@npm:1 - 3, d3-color@npm:3": - version: 3.1.0 - resolution: "d3-color@npm:3.1.0" - checksum: 4931fbfda5d7c4b5cfa283a13c91a954f86e3b69d75ce588d06cde6c3628cebfc3af2069ccf225e982e8987c612aa7948b3932163ce15eb3c11cd7c003f3ee3b - languageName: node - linkType: hard - -"d3-contour@npm:4": - version: 4.0.0 - resolution: "d3-contour@npm:4.0.0" - dependencies: - d3-array: ^3.2.0 - checksum: 1f9b9e56d0966d98a4c740b6af32b4fa2d14424159644adc24f4eb0ab023afbd414938f63f95032a66407fb701f4966efe40875e2cc0460fb653a943d3fc86b0 - languageName: node - linkType: hard - -"d3-delaunay@npm:6": - version: 6.0.2 - resolution: "d3-delaunay@npm:6.0.2" - dependencies: - delaunator: 5 - checksum: 80b18686dd7a5919a570000061f1515d106b7c7e3cba9da55706c312fc8f6de58a72674f2ea4eadc6694611f2df59f82c8b9d304845dd8b7903ee1f303aa5865 - languageName: node - linkType: hard - -"d3-dispatch@npm:1 - 3, d3-dispatch@npm:3": - version: 3.0.1 - resolution: "d3-dispatch@npm:3.0.1" - checksum: fdfd4a230f46463e28e5b22a45dd76d03be9345b605e1b5dc7d18bd7ebf504e6c00ae123fd6d03e23d9e2711e01f0e14ea89cd0632545b9f0c00b924ba4be223 - languageName: node - linkType: hard - -"d3-drag@npm:2 - 3, d3-drag@npm:3": - version: 3.0.0 - resolution: "d3-drag@npm:3.0.0" - dependencies: - d3-dispatch: 1 - 3 - d3-selection: 3 - checksum: d297231e60ecd633b0d076a63b4052b436ddeb48b5a3a11ff68c7e41a6774565473a6b064c5e9256e88eca6439a917ab9cea76032c52d944ddbf4fd289e31111 - languageName: node - linkType: hard - -"d3-dsv@npm:1 - 3, d3-dsv@npm:3": - version: 3.0.1 - resolution: "d3-dsv@npm:3.0.1" - dependencies: - commander: 7 - iconv-lite: 0.6 - rw: 1 - bin: - csv2json: bin/dsv2json.js - csv2tsv: bin/dsv2dsv.js - dsv2dsv: bin/dsv2dsv.js - dsv2json: bin/dsv2json.js - json2csv: bin/json2dsv.js - json2dsv: bin/json2dsv.js - json2tsv: bin/json2dsv.js - tsv2csv: bin/dsv2dsv.js - tsv2json: bin/dsv2json.js - checksum: 5fc0723647269d5dccd181d74f2265920ab368a2868b0b4f55ffa2fecdfb7814390ea28622cd61ee5d9594ab262879509059544e9f815c54fe76fbfb4ffa4c8a - languageName: node - linkType: hard - -"d3-ease@npm:1 - 3, d3-ease@npm:3": - version: 3.0.1 - resolution: "d3-ease@npm:3.0.1" - checksum: 06e2ee5326d1e3545eab4e2c0f84046a123dcd3b612e68858219aa034da1160333d9ce3da20a1d3486d98cb5c2a06f7d233eee1bc19ce42d1533458bd85dedcd - languageName: node - linkType: hard - -"d3-fetch@npm:3": - version: 3.0.1 - resolution: "d3-fetch@npm:3.0.1" - dependencies: - d3-dsv: 1 - 3 - checksum: 382dcea06549ef82c8d0b719e5dc1d96286352579e3b51b20f71437f5800323315b09cf7dcfd4e1f60a41e1204deb01758470cea257d2285a7abd9dcec806984 - languageName: node - linkType: hard - -"d3-force@npm:3": - version: 3.0.0 - resolution: "d3-force@npm:3.0.0" - dependencies: - d3-dispatch: 1 - 3 - d3-quadtree: 1 - 3 - d3-timer: 1 - 3 - checksum: 6c7e96438cab62fa32aeadb0ade3297b62b51f81b1b38b0a60a5ec9fd627d74090c1189654d92df2250775f31b06812342f089f1d5947de9960a635ee3581def - languageName: node - linkType: hard - -"d3-format@npm:1 - 3, d3-format@npm:3": - version: 3.1.0 - resolution: "d3-format@npm:3.1.0" - checksum: f345ec3b8ad3cab19bff5dead395bd9f5590628eb97a389b1dd89f0b204c7c4fc1d9520f13231c2c7cf14b7c9a8cf10f8ef15bde2befbab41454a569bd706ca2 - languageName: node - linkType: hard - -"d3-geo@npm:3": - version: 3.0.1 - resolution: "d3-geo@npm:3.0.1" - dependencies: - d3-array: 2.5.0 - 3 - checksum: e0f7e6a2f0d4c26efe08a7aa2c40b9a1a5a037220c6aaa51fb527035597e6e8841222b433e5681f9b5588b5b6f9a1c2d7f032a76ccbac3a17b0c1cbfffd05c1b - languageName: node - linkType: hard - -"d3-hierarchy@npm:3": - version: 3.1.2 - resolution: "d3-hierarchy@npm:3.1.2" - checksum: 0fd946a8c5fd4686d43d3e11bbfc2037a145fda29d2261ccd0e36f70b66af6d7638e2c0c7112124d63fc3d3127197a00a6aecf676bd5bd392a94d7235a214263 - languageName: node - linkType: hard - -"d3-interpolate@npm:1 - 3, d3-interpolate@npm:1.2.0 - 3, d3-interpolate@npm:3": - version: 3.0.1 - resolution: "d3-interpolate@npm:3.0.1" - dependencies: - d3-color: 1 - 3 - checksum: a42ba314e295e95e5365eff0f604834e67e4a3b3c7102458781c477bd67e9b24b6bb9d8e41ff5521050a3f2c7c0c4bbbb6e187fd586daa3980943095b267e78b - languageName: node - linkType: hard - -"d3-path@npm:1 - 3, d3-path@npm:3": - version: 3.0.1 - resolution: "d3-path@npm:3.0.1" - checksum: 6347c7055e0af330acadbe7f02144963eecabff560a791ecfeaffb45662e4d38eedabc6109dc481478f136b41d03707d3a43321ca9a115962888c99732ceb41a - languageName: node - linkType: hard - -"d3-polygon@npm:3": - version: 3.0.1 - resolution: "d3-polygon@npm:3.0.1" - checksum: 0b85c532517895544683849768a2c377cee3801ef8ccf3fa9693c8871dd21a0c1a2a0fc75ff54192f0ba2c562b0da2bc27f5bf959dfafc7fa23573b574865d2c - languageName: node - linkType: hard - -"d3-quadtree@npm:1 - 3, d3-quadtree@npm:3": - version: 3.0.1 - resolution: "d3-quadtree@npm:3.0.1" - checksum: 5469d462763811475f34a7294d984f3eb100515b0585ca5b249656f6b1a6e99b20056a2d2e463cc9944b888896d2b1d07859c50f9c0cf23438df9cd2e3146066 - languageName: node - linkType: hard - -"d3-random@npm:3": - version: 3.0.1 - resolution: "d3-random@npm:3.0.1" - checksum: a70ad8d1cabe399ebeb2e482703121ac8946a3b336830b518da6848b9fdd48a111990fc041dc716f16885a72176ffa2898f2a250ca3d363ecdba5ef92b18e131 - languageName: node - linkType: hard - -"d3-scale-chromatic@npm:3": - version: 3.0.0 - resolution: "d3-scale-chromatic@npm:3.0.0" - dependencies: - d3-color: 1 - 3 - d3-interpolate: 1 - 3 - checksum: a8ce4cb0267a17b28ebbb929f5e3071d985908a9c13b6fcaa2a198e1e018f275804d691c5794b970df0049725b7944f32297b31603d235af6414004f0c7f82c0 - languageName: node - linkType: hard - -"d3-scale@npm:4": - version: 4.0.2 - resolution: "d3-scale@npm:4.0.2" - dependencies: - d3-array: 2.10.0 - 3 - d3-format: 1 - 3 - d3-interpolate: 1.2.0 - 3 - d3-time: 2.1.1 - 3 - d3-time-format: 2 - 4 - checksum: a9c770d283162c3bd11477c3d9d485d07f8db2071665f1a4ad23eec3e515e2cefbd369059ec677c9ac849877d1a765494e90e92051d4f21111aa56791c98729e - languageName: node - linkType: hard - -"d3-selection@npm:2 - 3, d3-selection@npm:3": - version: 3.0.0 - resolution: "d3-selection@npm:3.0.0" - checksum: f4e60e133309115b99f5b36a79ae0a19d71ee6e2d5e3c7216ef3e75ebd2cb1e778c2ed2fa4c01bef35e0dcbd96c5428f5bd6ca2184fe2957ed582fde6841cbc5 - languageName: node - linkType: hard - -"d3-shape@npm:3": - version: 3.1.0 - resolution: "d3-shape@npm:3.1.0" - dependencies: - d3-path: 1 - 3 - checksum: 3dffe31b56feaf0817954748c9823c0e1fb6ab888b83775e9d568176ffa369546064ae49403963aac70108272988f632452634851f1c8a92805134d0c40e6dba - languageName: node - linkType: hard - -"d3-time-format@npm:2 - 4, d3-time-format@npm:4": - version: 4.1.0 - resolution: "d3-time-format@npm:4.1.0" - dependencies: - d3-time: 1 - 3 - checksum: 7342bce28355378152bbd4db4e275405439cabba082d9cd01946d40581140481c8328456d91740b0fe513c51ec4a467f4471ffa390c7e0e30ea30e9ec98fcdf4 - languageName: node - linkType: hard - -"d3-time@npm:1 - 3, d3-time@npm:2.1.1 - 3, d3-time@npm:3": - version: 3.0.0 - resolution: "d3-time@npm:3.0.0" - dependencies: - d3-array: 2 - 3 - checksum: 01646568ef01682550b7ee9f32394e4eb116a29515564861958871ed8de8fff02a25cd50dd8c4413921e6d9ecb8c8ce39be3266f655c8c18599fe58bcb253d60 - languageName: node - linkType: hard - -"d3-timer@npm:1 - 3, d3-timer@npm:3": - version: 3.0.1 - resolution: "d3-timer@npm:3.0.1" - checksum: 1cfddf86d7bca22f73f2c427f52dfa35c49f50d64e187eb788dcad6e927625c636aa18ae4edd44d084eb9d1f81d8ca4ec305dae7f733c15846a824575b789d73 - languageName: node - linkType: hard - -"d3-transition@npm:2 - 3, d3-transition@npm:3": - version: 3.0.1 - resolution: "d3-transition@npm:3.0.1" - dependencies: - d3-color: 1 - 3 - d3-dispatch: 1 - 3 - d3-ease: 1 - 3 - d3-interpolate: 1 - 3 - d3-timer: 1 - 3 - peerDependencies: - d3-selection: 2 - 3 - checksum: cb1e6e018c3abf0502fe9ff7b631ad058efb197b5e14b973a410d3935aead6e3c07c67d726cfab258e4936ef2667c2c3d1cd2037feb0765f0b4e1d3b8788c0ea - languageName: node - linkType: hard - -"d3-zoom@npm:3": - version: 3.0.0 - resolution: "d3-zoom@npm:3.0.0" - dependencies: - d3-dispatch: 1 - 3 - d3-drag: 2 - 3 - d3-interpolate: 1 - 3 - d3-selection: 2 - 3 - d3-transition: 2 - 3 - checksum: 8056e3527281cfd1ccbcbc458408f86973b0583e9dac00e51204026d1d36803ca437f970b5736f02fafed9f2b78f145f72a5dbc66397e02d4d95d4c594b8ff54 - languageName: node - linkType: hard - -"d3@npm:7.6.1": - version: 7.6.1 - resolution: "d3@npm:7.6.1" - dependencies: - d3-array: 3 - d3-axis: 3 - d3-brush: 3 - d3-chord: 3 - d3-color: 3 - d3-contour: 4 - d3-delaunay: 6 - d3-dispatch: 3 - d3-drag: 3 - d3-dsv: 3 - d3-ease: 3 - d3-fetch: 3 - d3-force: 3 - d3-format: 3 - d3-geo: 3 - d3-hierarchy: 3 - d3-interpolate: 3 - d3-path: 3 - d3-polygon: 3 - d3-quadtree: 3 - d3-random: 3 - d3-scale: 4 - d3-scale-chromatic: 3 - d3-selection: 3 - d3-shape: 3 - d3-time: 3 - d3-time-format: 4 - d3-timer: 3 - d3-transition: 3 - d3-zoom: 3 - checksum: af883cfeaf0a861afb2424edcb5419a5c56c84ddbc1ac9c7771c569f1926ace8db3cf0f4996038eb1db9700f7335e30c23b885199e0320a002893492ae83b415 - languageName: node - linkType: hard - -"dashdash@npm:^1.12.0": - version: 1.14.1 - resolution: "dashdash@npm:1.14.1" - dependencies: - assert-plus: ^1.0.0 - checksum: 3634c249570f7f34e3d34f866c93f866c5b417f0dd616275decae08147dcdf8fccfaa5947380ccfb0473998ea3a8057c0b4cd90c875740ee685d0624b2983598 - languageName: node - linkType: hard - -"date-fns-tz@npm:^1.3.3": - version: 1.3.3 - resolution: "date-fns-tz@npm:1.3.3" - peerDependencies: - date-fns: ">=2.0.0" - checksum: 52111dffb44f9f419df00b325ed510b8d4723190cb47e2efaaf9704c2dc510f39d5f9c32263bff9599c5218f31a9c7775731bd8a9365d3ce6042059897110101 - languageName: node - linkType: hard - -"date-fns@npm:^2.28.0": - version: 2.28.0 - resolution: "date-fns@npm:2.28.0" - checksum: a0516b2e4f99b8bffc6cc5193349f185f195398385bdcaf07f17c2c4a24473c99d933eb0018be4142a86a6d46cb0b06be6440ad874f15e795acbedd6fd727a1f - languageName: node - linkType: hard - -"dayjs@npm:^1.10.4": - version: 1.11.2 - resolution: "dayjs@npm:1.11.2" - checksum: 78f8bd04a9e5f5554aa06eacda65a7d59e162d39f621a46fd34fb3b51367c3662426d86b4e2f4ac535f81e0c4d5af3e8a83b37e672412eb556267d726c61f8f3 - languageName: node - linkType: hard - -"debug@npm:4, debug@npm:^4.1.0, debug@npm:^4.1.1, debug@npm:^4.3.2, debug@npm:^4.3.3, debug@npm:^4.3.4": - version: 4.3.4 - resolution: "debug@npm:4.3.4" - dependencies: - ms: 2.1.2 - peerDependenciesMeta: - supports-color: - optional: true - checksum: 3dbad3f94ea64f34431a9cbf0bafb61853eda57bff2880036153438f50fb5a84f27683ba0d8e5426bf41a8c6ff03879488120cf5b3a761e77953169c0600a708 - languageName: node - linkType: hard - -"debug@npm:^2.6.9": - version: 2.6.9 - resolution: "debug@npm:2.6.9" - dependencies: - ms: 2.0.0 - checksum: d2f51589ca66df60bf36e1fa6e4386b318c3f1e06772280eea5b1ae9fd3d05e9c2b7fd8a7d862457d00853c75b00451aa2d7459b924629ee385287a650f58fe6 - languageName: node - linkType: hard - -"debug@npm:^3.1.0, debug@npm:^3.2.7": - version: 3.2.7 - resolution: "debug@npm:3.2.7" - dependencies: - ms: ^2.1.1 - checksum: b3d8c5940799914d30314b7c3304a43305fd0715581a919dacb8b3176d024a782062368405b47491516d2091d6462d4d11f2f4974a405048094f8bfebfa3071c - languageName: node - linkType: hard - -"deep-eql@npm:^3.0.1": - version: 3.0.1 - resolution: "deep-eql@npm:3.0.1" - dependencies: - type-detect: ^4.0.0 - checksum: 4f4c9fb79eb994fb6e81d4aa8b063adc40c00f831588aa65e20857d5d52f15fb23034a6576ecf886f7ff6222d5ae42e71e9b7d57113e0715b1df7ea1e812b125 - languageName: node - linkType: hard - -"deep-is@npm:^0.1.3": - version: 0.1.4 - resolution: "deep-is@npm:0.1.4" - checksum: edb65dd0d7d1b9c40b2f50219aef30e116cedd6fc79290e740972c132c09106d2e80aa0bc8826673dd5a00222d4179c84b36a790eef63a4c4bca75a37ef90804 - languageName: node - linkType: hard - -"deepmerge@npm:^4.2.0": - version: 4.2.2 - resolution: "deepmerge@npm:4.2.2" - checksum: a8c43a1ed8d6d1ed2b5bf569fa4c8eb9f0924034baf75d5d406e47e157a451075c4db353efea7b6bcc56ec48116a8ce72fccf867b6e078e7c561904b5897530b - languageName: node - linkType: hard - -"define-properties@npm:^1.1.3": - version: 1.1.4 - resolution: "define-properties@npm:1.1.4" - dependencies: - has-property-descriptors: ^1.0.0 - object-keys: ^1.1.1 - checksum: ce0aef3f9eb193562b5cfb79b2d2c86b6a109dfc9fdcb5f45d680631a1a908c06824ddcdb72b7573b54e26ace07f0a23420aaba0d5c627b34d2c1de8ef527e2b - languageName: node - linkType: hard - -"delaunator@npm:5": - version: 5.0.0 - resolution: "delaunator@npm:5.0.0" - dependencies: - robust-predicates: ^3.0.0 - checksum: d6764188442b7f7c6bcacebd96edc00e35f542a96f1af3ef600e586bfb9849a3682c489c0ab423440c90bc4c7cac77f28761babff76fa29e193e1cf50a95b860 - languageName: node - linkType: hard - -"delayed-stream@npm:~1.0.0": - version: 1.0.0 - resolution: "delayed-stream@npm:1.0.0" - checksum: 46fe6e83e2cb1d85ba50bd52803c68be9bd953282fa7096f51fc29edd5d67ff84ff753c51966061e5ba7cb5e47ef6d36a91924eddb7f3f3483b1c560f77a0020 - languageName: node - linkType: hard - -"delegates@npm:^1.0.0": - version: 1.0.0 - resolution: "delegates@npm:1.0.0" - checksum: a51744d9b53c164ba9c0492471a1a2ffa0b6727451bdc89e31627fdf4adda9d51277cfcbfb20f0a6f08ccb3c436f341df3e92631a3440226d93a8971724771fd - languageName: node - linkType: hard - -"depd@npm:^1.1.2": - version: 1.1.2 - resolution: "depd@npm:1.1.2" - checksum: 6b406620d269619852885ce15965272b829df6f409724415e0002c8632ab6a8c0a08ec1f0bd2add05dc7bd7507606f7e2cc034fa24224ab829580040b835ecd9 - languageName: node - linkType: hard - -"detect-libc@npm:^1.0.3": - version: 1.0.3 - resolution: "detect-libc@npm:1.0.3" - bin: - detect-libc: ./bin/detect-libc.js - checksum: daaaed925ffa7889bd91d56e9624e6c8033911bb60f3a50a74a87500680652969dbaab9526d1e200a4c94acf80fc862a22131841145a0a8482d60a99c24f4a3e - languageName: node - linkType: hard - -"diff-sequences@npm:^27.5.1": - version: 27.5.1 - resolution: "diff-sequences@npm:27.5.1" - checksum: a00db5554c9da7da225db2d2638d85f8e41124eccbd56cbaefb3b276dcbb1c1c2ad851c32defe2055a54a4806f030656cbf6638105fd6ce97bb87b90b32a33ca - languageName: node - linkType: hard - -"doctrine@npm:^2.1.0": - version: 2.1.0 - resolution: "doctrine@npm:2.1.0" - dependencies: - esutils: ^2.0.2 - checksum: a45e277f7feaed309fe658ace1ff286c6e2002ac515af0aaf37145b8baa96e49899638c7cd47dccf84c3d32abfc113246625b3ac8f552d1046072adee13b0dc8 - languageName: node - linkType: hard - -"doctrine@npm:^3.0.0": - version: 3.0.0 - resolution: "doctrine@npm:3.0.0" - dependencies: - esutils: ^2.0.2 - checksum: fd7673ca77fe26cd5cba38d816bc72d641f500f1f9b25b83e8ce28827fe2da7ad583a8da26ab6af85f834138cf8dae9f69b0cd6ab925f52ddab1754db44d99ce - languageName: node - linkType: hard - -"doctypes@npm:^1.1.0": - version: 1.1.0 - resolution: "doctypes@npm:1.1.0" - checksum: 6e6c2d1a80f2072dc4831994c914c44455e341c5ab18c16797368a0afd59d7c22f3335805ba2c1dd2931e9539d1ba8b613b7650dc63f6ab56b77b8d888055de8 - languageName: node - linkType: hard - -"dom-serializer@npm:^1.0.1": - version: 1.4.1 - resolution: "dom-serializer@npm:1.4.1" - dependencies: - domelementtype: ^2.0.1 - domhandler: ^4.2.0 - entities: ^2.0.0 - checksum: fbb0b01f87a8a2d18e6e5a388ad0f7ec4a5c05c06d219377da1abc7bb0f674d804f4a8a94e3f71ff15f6cb7dcfc75704a54b261db672b9b3ab03da6b758b0b22 - languageName: node - linkType: hard - -"domelementtype@npm:^2.0.1, domelementtype@npm:^2.2.0": - version: 2.3.0 - resolution: "domelementtype@npm:2.3.0" - checksum: ee837a318ff702622f383409d1f5b25dd1024b692ef64d3096ff702e26339f8e345820f29a68bcdcea8cfee3531776b3382651232fbeae95612d6f0a75efb4f6 - languageName: node - linkType: hard - -"domhandler@npm:^4.2.0, domhandler@npm:^4.2.2, domhandler@npm:^4.3.1": - version: 4.3.1 - resolution: "domhandler@npm:4.3.1" - dependencies: - domelementtype: ^2.2.0 - checksum: 4c665ceed016e1911bf7d1dadc09dc888090b64dee7851cccd2fcf5442747ec39c647bb1cb8c8919f8bbdd0f0c625a6bafeeed4b2d656bbecdbae893f43ffaaa - languageName: node - linkType: hard - -"domutils@npm:^2.8.0": - version: 2.8.0 - resolution: "domutils@npm:2.8.0" - dependencies: - dom-serializer: ^1.0.1 - domelementtype: ^2.2.0 - domhandler: ^4.2.0 - checksum: abf7434315283e9aadc2a24bac0e00eab07ae4313b40cc239f89d84d7315ebdfd2fb1b5bf750a96bc1b4403d7237c7b2ebf60459be394d625ead4ca89b934391 - languageName: node - linkType: hard - -"dotenv-expand@npm:^5.1.0": - version: 5.1.0 - resolution: "dotenv-expand@npm:5.1.0" - checksum: 8017675b7f254384915d55f9eb6388e577cf0a1231a28d54b0ca03b782be9501b0ac90ac57338636d395fa59051e6209e9b44b8ddf169ce6076dffb5dea227d3 - languageName: node - linkType: hard - -"dotenv@npm:^7.0.0": - version: 7.0.0 - resolution: "dotenv@npm:7.0.0" - checksum: 18a7b3ef0e90fd6fcce7c7cbdd48d923b0cb180807540b80c797bda4a098097e17820d6315ae28eec22f73954cd0ab9d81904d46370183817c09f694d40566ff - languageName: node - linkType: hard - -"ecc-jsbn@npm:~0.1.1": - version: 0.1.2 - resolution: "ecc-jsbn@npm:0.1.2" - dependencies: - jsbn: ~0.1.0 - safer-buffer: ^2.1.0 - checksum: 22fef4b6203e5f31d425f5b711eb389e4c6c2723402e389af394f8411b76a488fa414d309d866e2b577ce3e8462d344205545c88a8143cc21752a5172818888a - languageName: node - linkType: hard - -"electron-to-chromium@npm:^1.4.118": - version: 1.4.137 - resolution: "electron-to-chromium@npm:1.4.137" - checksum: 639d7b94906efafcf363519c3698eecc44be46755a6a5cdc9088954329978866cc93fbd57e08b97290599b68d5226243d21de9fa50be416b8a5d3fa8fd42c3a0 - languageName: node - linkType: hard - -"emoji-regex@npm:^8.0.0": - version: 8.0.0 - resolution: "emoji-regex@npm:8.0.0" - checksum: d4c5c39d5a9868b5fa152f00cada8a936868fd3367f33f71be515ecee4c803132d11b31a6222b2571b1e5f7e13890156a94880345594d0ce7e3c9895f560f192 - languageName: node - linkType: hard - -"encoding@npm:^0.1.13": - version: 0.1.13 - resolution: "encoding@npm:0.1.13" - dependencies: - iconv-lite: ^0.6.2 - checksum: bb98632f8ffa823996e508ce6a58ffcf5856330fde839ae42c9e1f436cc3b5cc651d4aeae72222916545428e54fd0f6aa8862fd8d25bdbcc4589f1e3f3715e7f - languageName: node - linkType: hard - -"end-of-stream@npm:^1.1.0": - version: 1.4.4 - resolution: "end-of-stream@npm:1.4.4" - dependencies: - once: ^1.4.0 - checksum: 530a5a5a1e517e962854a31693dbb5c0b2fc40b46dad2a56a2deec656ca040631124f4795823acc68238147805f8b021abbe221f4afed5ef3c8e8efc2024908b - languageName: node - linkType: hard - -"enquirer@npm:^2.3.6": - version: 2.3.6 - resolution: "enquirer@npm:2.3.6" - dependencies: - ansi-colors: ^4.1.1 - checksum: 1c0911e14a6f8d26721c91e01db06092a5f7675159f0261d69c403396a385afd13dd76825e7678f66daffa930cfaa8d45f506fb35f818a2788463d022af1b884 - languageName: node - linkType: hard - -"entities@npm:^2.0.0": - version: 2.2.0 - resolution: "entities@npm:2.2.0" - checksum: 19010dacaf0912c895ea262b4f6128574f9ccf8d4b3b65c7e8334ad0079b3706376360e28d8843ff50a78aabcb8f08f0a32dbfacdc77e47ed77ca08b713669b3 - languageName: node - linkType: hard - -"entities@npm:^3.0.1": - version: 3.0.1 - resolution: "entities@npm:3.0.1" - checksum: aaf7f12033f0939be91f5161593f853f2da55866db55ccbf72f45430b8977e2b79dbd58c53d0fdd2d00bd7d313b75b0968d09f038df88e308aa97e39f9456572 - languageName: node - linkType: hard - -"env-paths@npm:^2.2.0": - version: 2.2.1 - resolution: "env-paths@npm:2.2.1" - checksum: 65b5df55a8bab92229ab2b40dad3b387fad24613263d103a97f91c9fe43ceb21965cd3392b1ccb5d77088021e525c4e0481adb309625d0cb94ade1d1fb8dc17e - languageName: node - linkType: hard - -"err-code@npm:^2.0.2": - version: 2.0.3 - resolution: "err-code@npm:2.0.3" - checksum: 8b7b1be20d2de12d2255c0bc2ca638b7af5171142693299416e6a9339bd7d88fc8d7707d913d78e0993176005405a236b066b45666b27b797252c771156ace54 - languageName: node - linkType: hard - -"error-ex@npm:^1.3.1": - version: 1.3.2 - resolution: "error-ex@npm:1.3.2" - dependencies: - is-arrayish: ^0.2.1 - checksum: c1c2b8b65f9c91b0f9d75f0debaa7ec5b35c266c2cac5de412c1a6de86d4cbae04ae44e510378cb14d032d0645a36925d0186f8bb7367bcc629db256b743a001 - languageName: node - linkType: hard - -"es-abstract@npm:^1.19.1, es-abstract@npm:^1.19.2": - version: 1.19.5 - resolution: "es-abstract@npm:1.19.5" - dependencies: - call-bind: ^1.0.2 - es-to-primitive: ^1.2.1 - function-bind: ^1.1.1 - get-intrinsic: ^1.1.1 - get-symbol-description: ^1.0.0 - has: ^1.0.3 - has-symbols: ^1.0.3 - internal-slot: ^1.0.3 - is-callable: ^1.2.4 - is-negative-zero: ^2.0.2 - is-regex: ^1.1.4 - is-shared-array-buffer: ^1.0.2 - is-string: ^1.0.7 - is-weakref: ^1.0.2 - object-inspect: ^1.12.0 - object-keys: ^1.1.1 - object.assign: ^4.1.2 - string.prototype.trimend: ^1.0.4 - string.prototype.trimstart: ^1.0.4 - unbox-primitive: ^1.0.1 - checksum: 55199b0f179a12b3b0ec9c9f2e3a27a7561686e4f88d46f9ef32c836448a336e367c14d8f792612fc83a64113896e478259e4dffbbcffb3efdd06650f6360324 - languageName: node - linkType: hard - -"es-shim-unscopables@npm:^1.0.0": - version: 1.0.0 - resolution: "es-shim-unscopables@npm:1.0.0" - dependencies: - has: ^1.0.3 - checksum: 83e95cadbb6ee44d3644dfad60dcad7929edbc42c85e66c3e99aefd68a3a5c5665f2686885cddb47dfeabfd77bd5ea5a7060f2092a955a729bbd8834f0d86fa1 - languageName: node - linkType: hard - -"es-to-primitive@npm:^1.2.1": - version: 1.2.1 - resolution: "es-to-primitive@npm:1.2.1" - dependencies: - is-callable: ^1.1.4 - is-date-object: ^1.0.1 - is-symbol: ^1.0.2 - checksum: 4ead6671a2c1402619bdd77f3503991232ca15e17e46222b0a41a5d81aebc8740a77822f5b3c965008e631153e9ef0580540007744521e72de8e33599fca2eed - languageName: node - linkType: hard - -"esbuild-android-64@npm:0.14.38": - version: 0.14.38 - resolution: "esbuild-android-64@npm:0.14.38" - conditions: os=android & cpu=x64 - languageName: node - linkType: hard - -"esbuild-android-64@npm:0.14.49": - version: 0.14.49 - resolution: "esbuild-android-64@npm:0.14.49" - conditions: os=android & cpu=x64 - languageName: node - linkType: hard - -"esbuild-android-arm64@npm:0.14.38": - version: 0.14.38 - resolution: "esbuild-android-arm64@npm:0.14.38" - conditions: os=android & cpu=arm64 - languageName: node - linkType: hard - -"esbuild-android-arm64@npm:0.14.49": - version: 0.14.49 - resolution: "esbuild-android-arm64@npm:0.14.49" - conditions: os=android & cpu=arm64 - languageName: node - linkType: hard - -"esbuild-darwin-64@npm:0.14.38": - version: 0.14.38 - resolution: "esbuild-darwin-64@npm:0.14.38" - conditions: os=darwin & cpu=x64 - languageName: node - linkType: hard - -"esbuild-darwin-64@npm:0.14.49": - version: 0.14.49 - resolution: "esbuild-darwin-64@npm:0.14.49" - conditions: os=darwin & cpu=x64 - languageName: node - linkType: hard - -"esbuild-darwin-arm64@npm:0.14.38": - version: 0.14.38 - resolution: "esbuild-darwin-arm64@npm:0.14.38" - conditions: os=darwin & cpu=arm64 - languageName: node - linkType: hard - -"esbuild-darwin-arm64@npm:0.14.49": - version: 0.14.49 - resolution: "esbuild-darwin-arm64@npm:0.14.49" - conditions: os=darwin & cpu=arm64 - languageName: node - linkType: hard - -"esbuild-freebsd-64@npm:0.14.38": - version: 0.14.38 - resolution: "esbuild-freebsd-64@npm:0.14.38" - conditions: os=freebsd & cpu=x64 - languageName: node - linkType: hard - -"esbuild-freebsd-64@npm:0.14.49": - version: 0.14.49 - resolution: "esbuild-freebsd-64@npm:0.14.49" - conditions: os=freebsd & cpu=x64 - languageName: node - linkType: hard - -"esbuild-freebsd-arm64@npm:0.14.38": - version: 0.14.38 - resolution: "esbuild-freebsd-arm64@npm:0.14.38" - conditions: os=freebsd & cpu=arm64 - languageName: node - linkType: hard - -"esbuild-freebsd-arm64@npm:0.14.49": - version: 0.14.49 - resolution: "esbuild-freebsd-arm64@npm:0.14.49" - conditions: os=freebsd & cpu=arm64 - languageName: node - linkType: hard - -"esbuild-linux-32@npm:0.14.38": - version: 0.14.38 - resolution: "esbuild-linux-32@npm:0.14.38" - conditions: os=linux & cpu=ia32 - languageName: node - linkType: hard - -"esbuild-linux-32@npm:0.14.49": - version: 0.14.49 - resolution: "esbuild-linux-32@npm:0.14.49" - conditions: os=linux & cpu=ia32 - languageName: node - linkType: hard - -"esbuild-linux-64@npm:0.14.38": - version: 0.14.38 - resolution: "esbuild-linux-64@npm:0.14.38" - conditions: os=linux & cpu=x64 - languageName: node - linkType: hard - -"esbuild-linux-64@npm:0.14.49": - version: 0.14.49 - resolution: "esbuild-linux-64@npm:0.14.49" - conditions: os=linux & cpu=x64 - languageName: node - linkType: hard - -"esbuild-linux-arm64@npm:0.14.38": - version: 0.14.38 - resolution: "esbuild-linux-arm64@npm:0.14.38" - conditions: os=linux & cpu=arm64 - languageName: node - linkType: hard - -"esbuild-linux-arm64@npm:0.14.49": - version: 0.14.49 - resolution: "esbuild-linux-arm64@npm:0.14.49" - conditions: os=linux & cpu=arm64 - languageName: node - linkType: hard - -"esbuild-linux-arm@npm:0.14.38": - version: 0.14.38 - resolution: "esbuild-linux-arm@npm:0.14.38" - conditions: os=linux & cpu=arm - languageName: node - linkType: hard - -"esbuild-linux-arm@npm:0.14.49": - version: 0.14.49 - resolution: "esbuild-linux-arm@npm:0.14.49" - conditions: os=linux & cpu=arm - languageName: node - linkType: hard - -"esbuild-linux-mips64le@npm:0.14.38": - version: 0.14.38 - resolution: "esbuild-linux-mips64le@npm:0.14.38" - conditions: os=linux & cpu=mips64el - languageName: node - linkType: hard - -"esbuild-linux-mips64le@npm:0.14.49": - version: 0.14.49 - resolution: "esbuild-linux-mips64le@npm:0.14.49" - conditions: os=linux & cpu=mips64el - languageName: node - linkType: hard - -"esbuild-linux-ppc64le@npm:0.14.38": - version: 0.14.38 - resolution: "esbuild-linux-ppc64le@npm:0.14.38" - conditions: os=linux & cpu=ppc64 - languageName: node - linkType: hard - -"esbuild-linux-ppc64le@npm:0.14.49": - version: 0.14.49 - resolution: "esbuild-linux-ppc64le@npm:0.14.49" - conditions: os=linux & cpu=ppc64 - languageName: node - linkType: hard - -"esbuild-linux-riscv64@npm:0.14.38": - version: 0.14.38 - resolution: "esbuild-linux-riscv64@npm:0.14.38" - conditions: os=linux & cpu=riscv64 - languageName: node - linkType: hard - -"esbuild-linux-riscv64@npm:0.14.49": - version: 0.14.49 - resolution: "esbuild-linux-riscv64@npm:0.14.49" - conditions: os=linux & cpu=riscv64 - languageName: node - linkType: hard - -"esbuild-linux-s390x@npm:0.14.38": - version: 0.14.38 - resolution: "esbuild-linux-s390x@npm:0.14.38" - conditions: os=linux & cpu=s390x - languageName: node - linkType: hard - -"esbuild-linux-s390x@npm:0.14.49": - version: 0.14.49 - resolution: "esbuild-linux-s390x@npm:0.14.49" - conditions: os=linux & cpu=s390x - languageName: node - linkType: hard - -"esbuild-netbsd-64@npm:0.14.38": - version: 0.14.38 - resolution: "esbuild-netbsd-64@npm:0.14.38" - conditions: os=netbsd & cpu=x64 - languageName: node - linkType: hard - -"esbuild-netbsd-64@npm:0.14.49": - version: 0.14.49 - resolution: "esbuild-netbsd-64@npm:0.14.49" - conditions: os=netbsd & cpu=x64 - languageName: node - linkType: hard - -"esbuild-openbsd-64@npm:0.14.38": - version: 0.14.38 - resolution: "esbuild-openbsd-64@npm:0.14.38" - conditions: os=openbsd & cpu=x64 - languageName: node - linkType: hard - -"esbuild-openbsd-64@npm:0.14.49": - version: 0.14.49 - resolution: "esbuild-openbsd-64@npm:0.14.49" - conditions: os=openbsd & cpu=x64 - languageName: node - linkType: hard - -"esbuild-sunos-64@npm:0.14.38": - version: 0.14.38 - resolution: "esbuild-sunos-64@npm:0.14.38" - conditions: os=sunos & cpu=x64 - languageName: node - linkType: hard - -"esbuild-sunos-64@npm:0.14.49": - version: 0.14.49 - resolution: "esbuild-sunos-64@npm:0.14.49" - conditions: os=sunos & cpu=x64 - languageName: node - linkType: hard - -"esbuild-windows-32@npm:0.14.38": - version: 0.14.38 - resolution: "esbuild-windows-32@npm:0.14.38" - conditions: os=win32 & cpu=ia32 - languageName: node - linkType: hard - -"esbuild-windows-32@npm:0.14.49": - version: 0.14.49 - resolution: "esbuild-windows-32@npm:0.14.49" - conditions: os=win32 & cpu=ia32 - languageName: node - linkType: hard - -"esbuild-windows-64@npm:0.14.38": - version: 0.14.38 - resolution: "esbuild-windows-64@npm:0.14.38" - conditions: os=win32 & cpu=x64 - languageName: node - linkType: hard - -"esbuild-windows-64@npm:0.14.49": - version: 0.14.49 - resolution: "esbuild-windows-64@npm:0.14.49" - conditions: os=win32 & cpu=x64 - languageName: node - linkType: hard - -"esbuild-windows-arm64@npm:0.14.38": - version: 0.14.38 - resolution: "esbuild-windows-arm64@npm:0.14.38" - conditions: os=win32 & cpu=arm64 - languageName: node - linkType: hard - -"esbuild-windows-arm64@npm:0.14.49": - version: 0.14.49 - resolution: "esbuild-windows-arm64@npm:0.14.49" - conditions: os=win32 & cpu=arm64 - languageName: node - linkType: hard - -"esbuild@npm:^0.14.27": - version: 0.14.38 - resolution: "esbuild@npm:0.14.38" - dependencies: - esbuild-android-64: 0.14.38 - esbuild-android-arm64: 0.14.38 - esbuild-darwin-64: 0.14.38 - esbuild-darwin-arm64: 0.14.38 - esbuild-freebsd-64: 0.14.38 - esbuild-freebsd-arm64: 0.14.38 - esbuild-linux-32: 0.14.38 - esbuild-linux-64: 0.14.38 - esbuild-linux-arm: 0.14.38 - esbuild-linux-arm64: 0.14.38 - esbuild-linux-mips64le: 0.14.38 - esbuild-linux-ppc64le: 0.14.38 - esbuild-linux-riscv64: 0.14.38 - esbuild-linux-s390x: 0.14.38 - esbuild-netbsd-64: 0.14.38 - esbuild-openbsd-64: 0.14.38 - esbuild-sunos-64: 0.14.38 - esbuild-windows-32: 0.14.38 - esbuild-windows-64: 0.14.38 - esbuild-windows-arm64: 0.14.38 - dependenciesMeta: - esbuild-android-64: - optional: true - esbuild-android-arm64: - optional: true - esbuild-darwin-64: - optional: true - esbuild-darwin-arm64: - optional: true - esbuild-freebsd-64: - optional: true - esbuild-freebsd-arm64: - optional: true - esbuild-linux-32: - optional: true - esbuild-linux-64: - optional: true - esbuild-linux-arm: - optional: true - esbuild-linux-arm64: - optional: true - esbuild-linux-mips64le: - optional: true - esbuild-linux-ppc64le: - optional: true - esbuild-linux-riscv64: - optional: true - esbuild-linux-s390x: - optional: true - esbuild-netbsd-64: - optional: true - esbuild-openbsd-64: - optional: true - esbuild-sunos-64: - optional: true - esbuild-windows-32: - optional: true - esbuild-windows-64: - optional: true - esbuild-windows-arm64: - optional: true - bin: - esbuild: bin/esbuild - checksum: d7523a36bd28016c010829c527386dbc0c6b9f514920abf5ac8003f346665161aa61026fd6822c5091fc1c1af52fe26c9281a81740fc06f2994cdbb7c2880297 - languageName: node - linkType: hard - -"esbuild@npm:^0.14.47": - version: 0.14.49 - resolution: "esbuild@npm:0.14.49" - dependencies: - esbuild-android-64: 0.14.49 - esbuild-android-arm64: 0.14.49 - esbuild-darwin-64: 0.14.49 - esbuild-darwin-arm64: 0.14.49 - esbuild-freebsd-64: 0.14.49 - esbuild-freebsd-arm64: 0.14.49 - esbuild-linux-32: 0.14.49 - esbuild-linux-64: 0.14.49 - esbuild-linux-arm: 0.14.49 - esbuild-linux-arm64: 0.14.49 - esbuild-linux-mips64le: 0.14.49 - esbuild-linux-ppc64le: 0.14.49 - esbuild-linux-riscv64: 0.14.49 - esbuild-linux-s390x: 0.14.49 - esbuild-netbsd-64: 0.14.49 - esbuild-openbsd-64: 0.14.49 - esbuild-sunos-64: 0.14.49 - esbuild-windows-32: 0.14.49 - esbuild-windows-64: 0.14.49 - esbuild-windows-arm64: 0.14.49 - dependenciesMeta: - esbuild-android-64: - optional: true - esbuild-android-arm64: - optional: true - esbuild-darwin-64: - optional: true - esbuild-darwin-arm64: - optional: true - esbuild-freebsd-64: - optional: true - esbuild-freebsd-arm64: - optional: true - esbuild-linux-32: - optional: true - esbuild-linux-64: - optional: true - esbuild-linux-arm: - optional: true - esbuild-linux-arm64: - optional: true - esbuild-linux-mips64le: - optional: true - esbuild-linux-ppc64le: - optional: true - esbuild-linux-riscv64: - optional: true - esbuild-linux-s390x: - optional: true - esbuild-netbsd-64: - optional: true - esbuild-openbsd-64: - optional: true - esbuild-sunos-64: - optional: true - esbuild-windows-32: - optional: true - esbuild-windows-64: - optional: true - esbuild-windows-arm64: - optional: true - bin: - esbuild: bin/esbuild - checksum: b718f4c9eaf2f83bb26f2cdb18d82d70365179ae8d1d88636afc3073a0c328364340695798b9a6322ae15e31b90e1f71266151f61637412649fb31bb3ecb2e0a - languageName: node - linkType: hard - -"escalade@npm:^3.1.1": - version: 3.1.1 - resolution: "escalade@npm:3.1.1" - checksum: a3e2a99f07acb74b3ad4989c48ca0c3140f69f923e56d0cba0526240ee470b91010f9d39001f2a4a313841d237ede70a729e92125191ba5d21e74b106800b133 - languageName: node - linkType: hard - -"escape-string-regexp@npm:^1.0.5": - version: 1.0.5 - resolution: "escape-string-regexp@npm:1.0.5" - checksum: 6092fda75c63b110c706b6a9bfde8a612ad595b628f0bd2147eea1d3406723020810e591effc7db1da91d80a71a737a313567c5abb3813e8d9c71f4aa595b410 - languageName: node - linkType: hard - -"escape-string-regexp@npm:^4.0.0": - version: 4.0.0 - resolution: "escape-string-regexp@npm:4.0.0" - checksum: 98b48897d93060f2322108bf29db0feba7dd774be96cd069458d1453347b25ce8682ecc39859d4bca2203cc0ab19c237bcc71755eff49a0f8d90beadeeba5cc5 - languageName: node - linkType: hard - -"eslint-config-standard@npm:17.0.0": - version: 17.0.0 - resolution: "eslint-config-standard@npm:17.0.0" - peerDependencies: - eslint: ^8.0.1 - eslint-plugin-import: ^2.25.2 - eslint-plugin-n: ^15.0.0 - eslint-plugin-promise: ^6.0.0 - checksum: dc0ed51e186fd963ff2c0819d33ef580afce11b11036cbcf5e74427e26e514c2b1be96b8ffe74fd2fd00263554a0d49cc873fcf76f17c3dfdba614b45d7fd7da - languageName: node - linkType: hard - -"eslint-import-resolver-node@npm:^0.3.6": - version: 0.3.6 - resolution: "eslint-import-resolver-node@npm:0.3.6" - dependencies: - debug: ^3.2.7 - resolve: ^1.20.0 - checksum: 6266733af1e112970e855a5bcc2d2058fb5ae16ad2a6d400705a86b29552b36131ffc5581b744c23d550de844206fb55e9193691619ee4dbf225c4bde526b1c8 - languageName: node - linkType: hard - -"eslint-module-utils@npm:^2.7.3": - version: 2.7.3 - resolution: "eslint-module-utils@npm:2.7.3" - dependencies: - debug: ^3.2.7 - find-up: ^2.1.0 - checksum: 77048263f309167a1e6a1e1b896bfb5ddd1d3859b2e2abbd9c32c432aee13d610d46e6820b1ca81b37fba437cf423a404bc6649be64ace9148a3062d1886a678 - languageName: node - linkType: hard - -"eslint-plugin-cypress@npm:2.12.1": - version: 2.12.1 - resolution: "eslint-plugin-cypress@npm:2.12.1" - dependencies: - globals: ^11.12.0 - peerDependencies: - eslint: ">= 3.2.1" - checksum: 1f1c36e149304e9a6f58e2292a761abad58274da33b3a48b24ad55ad20cbce3ac7467321f2b6fcb052f9563c89f67004de4766eba2e2bdbcb010a6a0666989cf - languageName: node - linkType: hard - -"eslint-plugin-es@npm:^3.0.0": - version: 3.0.1 - resolution: "eslint-plugin-es@npm:3.0.1" - dependencies: - eslint-utils: ^2.0.0 - regexpp: ^3.0.0 - peerDependencies: - eslint: ">=4.19.1" - checksum: e57592c52301ee8ddc296ae44216df007f3a870bcb3be8d1fbdb909a1d3a3efe3fa3785de02066f9eba1d6466b722d3eb3cc3f8b75b3cf6a1cbded31ac6298e4 - languageName: node - linkType: hard - -"eslint-plugin-es@npm:^4.1.0": - version: 4.1.0 - resolution: "eslint-plugin-es@npm:4.1.0" - dependencies: - eslint-utils: ^2.0.0 - regexpp: ^3.0.0 - peerDependencies: - eslint: ">=4.19.1" - checksum: 26b87a216d3625612b1d3ca8653ac8a1d261046d2a973bb0eb2759070267d2bfb0509051facdeb5ae03dc8dfb51a434be23aff7309a752ca901d637da535677f - languageName: node - linkType: hard - -"eslint-plugin-import@npm:2.26.0": - version: 2.26.0 - resolution: "eslint-plugin-import@npm:2.26.0" - dependencies: - array-includes: ^3.1.4 - array.prototype.flat: ^1.2.5 - debug: ^2.6.9 - doctrine: ^2.1.0 - eslint-import-resolver-node: ^0.3.6 - eslint-module-utils: ^2.7.3 - has: ^1.0.3 - is-core-module: ^2.8.1 - is-glob: ^4.0.3 - minimatch: ^3.1.2 - object.values: ^1.1.5 - resolve: ^1.22.0 - tsconfig-paths: ^3.14.1 - peerDependencies: - eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 - checksum: 0bf77ad80339554481eafa2b1967449e1f816b94c7a6f9614ce33fb4083c4e6c050f10d241dd50b4975d47922880a34de1e42ea9d8e6fd663ebb768baa67e655 - languageName: node - linkType: hard - -"eslint-plugin-n@npm:*": - version: 15.2.0 - resolution: "eslint-plugin-n@npm:15.2.0" - dependencies: - builtins: ^4.0.0 - eslint-plugin-es: ^4.1.0 - eslint-utils: ^3.0.0 - ignore: ^5.1.1 - is-core-module: ^2.3.0 - minimatch: ^3.0.4 - resolve: ^1.10.1 - semver: ^6.3.0 - peerDependencies: - eslint: ">=7.0.0" - checksum: 4303dea35a40877958e5de9d54c098d842191428e1cef0df320cc3533ecd0b539a67323f6788bffdf76445c2f5a5dfe28837a5d1efb70ebb29c0caa6259bb805 - languageName: node - linkType: hard - -"eslint-plugin-node@npm:11.1.0": - version: 11.1.0 - resolution: "eslint-plugin-node@npm:11.1.0" - dependencies: - eslint-plugin-es: ^3.0.0 - eslint-utils: ^2.0.0 - ignore: ^5.1.1 - minimatch: ^3.0.4 - resolve: ^1.10.1 - semver: ^6.1.0 - peerDependencies: - eslint: ">=5.16.0" - checksum: 5804c4f8a6e721f183ef31d46fbe3b4e1265832f352810060e0502aeac7de034df83352fc88643b19641bb2163f2587f1bd4119aff0fd21e8d98c57c450e013b - languageName: node - linkType: hard - -"eslint-plugin-promise@npm:6.0.0": - version: 6.0.0 - resolution: "eslint-plugin-promise@npm:6.0.0" - peerDependencies: - eslint: ^7.0.0 || ^8.0.0 - checksum: 7e761507c51267b77e4ad710e7c8938aa4f8f69b975886034e57497a1816e9527eda364e25aac03d1b4e0df2e738ba98e49ad075d028824fcfea533a1419751c - languageName: node - linkType: hard - -"eslint-plugin-vue@npm:9.2.0": - version: 9.2.0 - resolution: "eslint-plugin-vue@npm:9.2.0" - dependencies: - eslint-utils: ^3.0.0 - natural-compare: ^1.4.0 - nth-check: ^2.0.1 - postcss-selector-parser: ^6.0.9 - semver: ^7.3.5 - vue-eslint-parser: ^9.0.1 - xml-name-validator: ^4.0.0 - peerDependencies: - eslint: ^6.2.0 || ^7.0.0 || ^8.0.0 - checksum: 008819b12ad50ed62bfdc7f93e9e610575fa16dcccfb62ad9bb4ad27e69b1245419bf76752285742434fa6b9cf076f6fc173324084639e10209b2af2992630df - languageName: node - linkType: hard - -"eslint-scope@npm:^7.1.1": - version: 7.1.1 - resolution: "eslint-scope@npm:7.1.1" - dependencies: - esrecurse: ^4.3.0 - estraverse: ^5.2.0 - checksum: 9f6e974ab2db641ca8ab13508c405b7b859e72afe9f254e8131ff154d2f40c99ad4545ce326fd9fde3212ff29707102562a4834f1c48617b35d98c71a97fbf3e - languageName: node - linkType: hard - -"eslint-utils@npm:^2.0.0": - version: 2.1.0 - resolution: "eslint-utils@npm:2.1.0" - dependencies: - eslint-visitor-keys: ^1.1.0 - checksum: 27500938f348da42100d9e6ad03ae29b3de19ba757ae1a7f4a087bdcf83ac60949bbb54286492ca61fac1f5f3ac8692dd21537ce6214240bf95ad0122f24d71d - languageName: node - linkType: hard - -"eslint-utils@npm:^3.0.0": - version: 3.0.0 - resolution: "eslint-utils@npm:3.0.0" - dependencies: - eslint-visitor-keys: ^2.0.0 - peerDependencies: - eslint: ">=5" - checksum: 0668fe02f5adab2e5a367eee5089f4c39033af20499df88fe4e6aba2015c20720404d8c3d6349b6f716b08fdf91b9da4e5d5481f265049278099c4c836ccb619 - languageName: node - linkType: hard - -"eslint-visitor-keys@npm:^1.1.0": - version: 1.3.0 - resolution: "eslint-visitor-keys@npm:1.3.0" - checksum: 37a19b712f42f4c9027e8ba98c2b06031c17e0c0a4c696cd429bd9ee04eb43889c446f2cd545e1ff51bef9593fcec94ecd2c2ef89129fcbbf3adadbef520376a - languageName: node - linkType: hard - -"eslint-visitor-keys@npm:^2.0.0": - version: 2.1.0 - resolution: "eslint-visitor-keys@npm:2.1.0" - checksum: e3081d7dd2611a35f0388bbdc2f5da60b3a3c5b8b6e928daffff7391146b434d691577aa95064c8b7faad0b8a680266bcda0a42439c18c717b80e6718d7e267d - languageName: node - linkType: hard - -"eslint-visitor-keys@npm:^3.3.0": - version: 3.3.0 - resolution: "eslint-visitor-keys@npm:3.3.0" - checksum: d59e68a7c5a6d0146526b0eec16ce87fbf97fe46b8281e0d41384224375c4e52f5ffb9e16d48f4ea50785cde93f766b0c898e31ab89978d88b0e1720fbfb7808 - languageName: node - linkType: hard - -"eslint@npm:8.20.0": - version: 8.20.0 - resolution: "eslint@npm:8.20.0" - dependencies: - "@eslint/eslintrc": ^1.3.0 - "@humanwhocodes/config-array": ^0.9.2 - ajv: ^6.10.0 - chalk: ^4.0.0 - cross-spawn: ^7.0.2 - debug: ^4.3.2 - doctrine: ^3.0.0 - escape-string-regexp: ^4.0.0 - eslint-scope: ^7.1.1 - eslint-utils: ^3.0.0 - eslint-visitor-keys: ^3.3.0 - espree: ^9.3.2 - esquery: ^1.4.0 - esutils: ^2.0.2 - fast-deep-equal: ^3.1.3 - file-entry-cache: ^6.0.1 - functional-red-black-tree: ^1.0.1 - glob-parent: ^6.0.1 - globals: ^13.15.0 - ignore: ^5.2.0 - import-fresh: ^3.0.0 - imurmurhash: ^0.1.4 - is-glob: ^4.0.0 - js-yaml: ^4.1.0 - json-stable-stringify-without-jsonify: ^1.0.1 - levn: ^0.4.1 - lodash.merge: ^4.6.2 - minimatch: ^3.1.2 - natural-compare: ^1.4.0 - optionator: ^0.9.1 - regexpp: ^3.2.0 - strip-ansi: ^6.0.1 - strip-json-comments: ^3.1.0 - text-table: ^0.2.0 - v8-compile-cache: ^2.0.3 - bin: - eslint: bin/eslint.js - checksum: a31adf390d71d916925586bc8467b48f620e93dd0416bc1e897d99265af88b48d4eba3985b5ff4653ae5cc46311a360d373574002277e159bb38a4363abf9228 - languageName: node - linkType: hard - -"espree@npm:^9.0.0, espree@npm:^9.3.1, espree@npm:^9.3.2": - version: 9.3.2 - resolution: "espree@npm:9.3.2" - dependencies: - acorn: ^8.7.1 - acorn-jsx: ^5.3.2 - eslint-visitor-keys: ^3.3.0 - checksum: 9a790d6779847051e87f70d720a0f6981899a722419e80c92ab6dee01e1ab83b8ce52d11b4dc96c2c490182efb5a4c138b8b0d569205bfe1cd4629e658e58c30 - languageName: node - linkType: hard - -"esquery@npm:^1.4.0": - version: 1.4.0 - resolution: "esquery@npm:1.4.0" - dependencies: - estraverse: ^5.1.0 - checksum: a0807e17abd7fbe5fbd4fab673038d6d8a50675cdae6b04fbaa520c34581be0c5fa24582990e8acd8854f671dd291c78bb2efb9e0ed5b62f33bac4f9cf820210 - languageName: node - linkType: hard - -"esrecurse@npm:^4.3.0": - version: 4.3.0 - resolution: "esrecurse@npm:4.3.0" - dependencies: - estraverse: ^5.2.0 - checksum: ebc17b1a33c51cef46fdc28b958994b1dc43cd2e86237515cbc3b4e5d2be6a811b2315d0a1a4d9d340b6d2308b15322f5c8291059521cc5f4802f65e7ec32837 - languageName: node - linkType: hard - -"estraverse@npm:^5.1.0, estraverse@npm:^5.2.0": - version: 5.3.0 - resolution: "estraverse@npm:5.3.0" - checksum: 072780882dc8416ad144f8fe199628d2b3e7bbc9989d9ed43795d2c90309a2047e6bc5979d7e2322a341163d22cfad9e21f4110597fe487519697389497e4e2b - languageName: node - linkType: hard - -"estree-walker@npm:^2.0.2": - version: 2.0.2 - resolution: "estree-walker@npm:2.0.2" - checksum: 6151e6f9828abe2259e57f5fd3761335bb0d2ebd76dc1a01048ccee22fabcfef3c0859300f6d83ff0d1927849368775ec5a6d265dde2f6de5a1be1721cd94efc - languageName: node - linkType: hard - -"esutils@npm:^2.0.2": - version: 2.0.3 - resolution: "esutils@npm:2.0.3" - checksum: 22b5b08f74737379a840b8ed2036a5fb35826c709ab000683b092d9054e5c2a82c27818f12604bfc2a9a76b90b6834ef081edbc1c7ae30d1627012e067c6ec87 - languageName: node - linkType: hard - -"eventemitter2@npm:^6.4.3": - version: 6.4.5 - resolution: "eventemitter2@npm:6.4.5" - checksum: 84504f9cf0cc30205cdd46783fe9df3733435e5097f13070b678023110b5ef07847651808ae280cd94c42cd5976880211c7a40321a8ff8fa56f7c5f9c5c11960 - languageName: node - linkType: hard - -"evtd@npm:^0.2.2, evtd@npm:^0.2.3": - version: 0.2.3 - resolution: "evtd@npm:0.2.3" - checksum: 5ddded626355bf97c62e9b0a99aa2187b74e90b50032c06e2e75723250a152ad5b57bbca844fc07d3bd0b9f22f8dfe96ae4c68614efe5f879a4191c3c8070b5a - languageName: node - linkType: hard - -"execa@npm:4.1.0": - version: 4.1.0 - resolution: "execa@npm:4.1.0" - dependencies: - cross-spawn: ^7.0.0 - get-stream: ^5.0.0 - human-signals: ^1.1.1 - is-stream: ^2.0.0 - merge-stream: ^2.0.0 - npm-run-path: ^4.0.0 - onetime: ^5.1.0 - signal-exit: ^3.0.2 - strip-final-newline: ^2.0.0 - checksum: e30d298934d9c52f90f3847704fd8224e849a081ab2b517bbc02f5f7732c24e56a21f14cb96a08256deffeb2d12b2b7cb7e2b014a12fb36f8d3357e06417ed55 - languageName: node - linkType: hard - -"executable@npm:^4.1.1": - version: 4.1.1 - resolution: "executable@npm:4.1.1" - dependencies: - pify: ^2.2.0 - checksum: f01927ce59bccec804e171bf859a26e362c1f50aa9ebc69f7cafdcce3859d29d4b6267fd47237c18b0a1830614bd3f0ee14b7380d9bad18a4e7af9b5f0b6984f - languageName: node - linkType: hard - -"extend@npm:~3.0.2": - version: 3.0.2 - resolution: "extend@npm:3.0.2" - checksum: a50a8309ca65ea5d426382ff09f33586527882cf532931cb08ca786ea3146c0553310bda688710ff61d7668eba9f96b923fe1420cdf56a2c3eaf30fcab87b515 - languageName: node - linkType: hard - -"extract-zip@npm:2.0.1": - version: 2.0.1 - resolution: "extract-zip@npm:2.0.1" - dependencies: - "@types/yauzl": ^2.9.1 - debug: ^4.1.1 - get-stream: ^5.1.0 - yauzl: ^2.10.0 - dependenciesMeta: - "@types/yauzl": - optional: true - bin: - extract-zip: cli.js - checksum: 8cbda9debdd6d6980819cc69734d874ddd71051c9fe5bde1ef307ebcedfe949ba57b004894b585f758b7c9eeeea0e3d87f2dda89b7d25320459c2c9643ebb635 - languageName: node - linkType: hard - -"extsprintf@npm:1.3.0, extsprintf@npm:^1.2.0": - version: 1.3.0 - resolution: "extsprintf@npm:1.3.0" - checksum: cee7a4a1e34cffeeec18559109de92c27517e5641991ec6bab849aa64e3081022903dd53084f2080d0d2530803aa5ee84f1e9de642c365452f9e67be8f958ce2 - languageName: node - linkType: hard - -"fast-deep-equal@npm:^3.1.1, fast-deep-equal@npm:^3.1.3": - version: 3.1.3 - resolution: "fast-deep-equal@npm:3.1.3" - checksum: e21a9d8d84f53493b6aa15efc9cfd53dd5b714a1f23f67fb5dc8f574af80df889b3bce25dc081887c6d25457cce704e636395333abad896ccdec03abaf1f3f9d - languageName: node - linkType: hard - -"fast-json-stable-stringify@npm:^2.0.0": - version: 2.1.0 - resolution: "fast-json-stable-stringify@npm:2.1.0" - checksum: b191531e36c607977e5b1c47811158733c34ccb3bfde92c44798929e9b4154884378536d26ad90dfecd32e1ffc09c545d23535ad91b3161a27ddbb8ebe0cbecb - languageName: node - linkType: hard - -"fast-levenshtein@npm:^2.0.6": - version: 2.0.6 - resolution: "fast-levenshtein@npm:2.0.6" - checksum: 92cfec0a8dfafd9c7a15fba8f2cc29cd0b62b85f056d99ce448bbcd9f708e18ab2764bda4dd5158364f4145a7c72788538994f0d1787b956ef0d1062b0f7c24c - languageName: node - linkType: hard - -"fd-slicer@npm:~1.1.0": - version: 1.1.0 - resolution: "fd-slicer@npm:1.1.0" - dependencies: - pend: ~1.2.0 - checksum: c8585fd5713f4476eb8261150900d2cb7f6ff2d87f8feb306ccc8a1122efd152f1783bdb2b8dc891395744583436bfd8081d8e63ece0ec8687eeefea394d4ff2 - languageName: node - linkType: hard - -"figures@npm:^3.2.0": - version: 3.2.0 - resolution: "figures@npm:3.2.0" - dependencies: - escape-string-regexp: ^1.0.5 - checksum: 85a6ad29e9aca80b49b817e7c89ecc4716ff14e3779d9835af554db91bac41c0f289c418923519392a1e582b4d10482ad282021330cd045bb7b80c84152f2a2b - languageName: node - linkType: hard - -"file-entry-cache@npm:^6.0.1": - version: 6.0.1 - resolution: "file-entry-cache@npm:6.0.1" - dependencies: - flat-cache: ^3.0.4 - checksum: f49701feaa6314c8127c3c2f6173cfefff17612f5ed2daaafc6da13b5c91fd43e3b2a58fd0d63f9f94478a501b167615931e7200e31485e320f74a33885a9c74 - languageName: node - linkType: hard - -"file-saver@npm:2.0.5": - version: 2.0.5 - resolution: "file-saver@npm:2.0.5" - checksum: c62d96e5cebc58b4bdf3ae8a60d5cf9607ad82f75f798c33a4ee63435ac2203002584d5256a2a780eda7feb5e19dc3b6351c2212e58b3f529e63d265a7cc79f7 - languageName: node - linkType: hard - -"fill-range@npm:^7.0.1": - version: 7.0.1 - resolution: "fill-range@npm:7.0.1" - dependencies: - to-regex-range: ^5.0.1 - checksum: cc283f4e65b504259e64fd969bcf4def4eb08d85565e906b7d36516e87819db52029a76b6363d0f02d0d532f0033c9603b9e2d943d56ee3b0d4f7ad3328ff917 - languageName: node - linkType: hard - -"find-up@npm:^2.1.0": - version: 2.1.0 - resolution: "find-up@npm:2.1.0" - dependencies: - locate-path: ^2.0.0 - checksum: 43284fe4da09f89011f08e3c32cd38401e786b19226ea440b75386c1b12a4cb738c94969808d53a84f564ede22f732c8409e3cfc3f7fb5b5c32378ad0bbf28bd - languageName: node - linkType: hard - -"find-up@npm:^5.0.0": - version: 5.0.0 - resolution: "find-up@npm:5.0.0" - dependencies: - locate-path: ^6.0.0 - path-exists: ^4.0.0 - checksum: 07955e357348f34660bde7920783204ff5a26ac2cafcaa28bace494027158a97b9f56faaf2d89a6106211a8174db650dd9f503f9c0d526b1202d5554a00b9095 - languageName: node - linkType: hard - -"flat-cache@npm:^3.0.4": - version: 3.0.4 - resolution: "flat-cache@npm:3.0.4" - dependencies: - flatted: ^3.1.0 - rimraf: ^3.0.2 - checksum: 4fdd10ecbcbf7d520f9040dd1340eb5dfe951e6f0ecf2252edeec03ee68d989ec8b9a20f4434270e71bcfd57800dc09b3344fca3966b2eb8f613072c7d9a2365 - languageName: node - linkType: hard - -"flatted@npm:^3.1.0": - version: 3.2.5 - resolution: "flatted@npm:3.2.5" - checksum: 3c436e9695ccca29620b4be5671dd72e5dd0a7500e0856611b7ca9bd8169f177f408c3b9abfa78dfe1493ee2d873e2c119080a8a9bee4e1a186a9e60ca6c89f1 - languageName: node - linkType: hard - -"foreground-child@npm:^2.0.0": - version: 2.0.0 - resolution: "foreground-child@npm:2.0.0" - dependencies: - cross-spawn: ^7.0.0 - signal-exit: ^3.0.2 - checksum: f77ec9aff621abd6b754cb59e690743e7639328301fbea6ff09df27d2befaf7dd5b77cec51c32323d73a81a7d91caaf9413990d305cbe3d873eec4fe58960956 - languageName: node - linkType: hard - -"forever-agent@npm:~0.6.1": - version: 0.6.1 - resolution: "forever-agent@npm:0.6.1" - checksum: 766ae6e220f5fe23676bb4c6a99387cec5b7b62ceb99e10923376e27bfea72f3c3aeec2ba5f45f3f7ba65d6616965aa7c20b15002b6860833bb6e394dea546a8 - languageName: node - linkType: hard - -"form-data@npm:~2.3.2": - version: 2.3.3 - resolution: "form-data@npm:2.3.3" - dependencies: - asynckit: ^0.4.0 - combined-stream: ^1.0.6 - mime-types: ^2.1.12 - checksum: 10c1780fa13dbe1ff3100114c2ce1f9307f8be10b14bf16e103815356ff567b6be39d70fc4a40f8990b9660012dc24b0f5e1dde1b6426166eb23a445ba068ca3 - languageName: node - linkType: hard - -"fs-extra@npm:^9.1.0": - version: 9.1.0 - resolution: "fs-extra@npm:9.1.0" - dependencies: - at-least-node: ^1.0.0 - graceful-fs: ^4.2.0 - jsonfile: ^6.0.1 - universalify: ^2.0.0 - checksum: ba71ba32e0faa74ab931b7a0031d1523c66a73e225de7426e275e238e312d07313d2da2d33e34a52aa406c8763ade5712eb3ec9ba4d9edce652bcacdc29e6b20 - languageName: node - linkType: hard - -"fs-minipass@npm:^2.0.0, fs-minipass@npm:^2.1.0": - version: 2.1.0 - resolution: "fs-minipass@npm:2.1.0" - dependencies: - minipass: ^3.0.0 - checksum: 1b8d128dae2ac6cc94230cc5ead341ba3e0efaef82dab46a33d171c044caaa6ca001364178d42069b2809c35a1c3c35079a32107c770e9ffab3901b59af8c8b1 - languageName: node - linkType: hard - -"fs.realpath@npm:^1.0.0": - version: 1.0.0 - resolution: "fs.realpath@npm:1.0.0" - checksum: 99ddea01a7e75aa276c250a04eedeffe5662bce66c65c07164ad6264f9de18fb21be9433ead460e54cff20e31721c811f4fb5d70591799df5f85dce6d6746fd0 - languageName: node - linkType: hard - -"fsevents@npm:~2.3.2": - version: 2.3.2 - resolution: "fsevents@npm:2.3.2" - dependencies: - node-gyp: latest - checksum: 97ade64e75091afee5265e6956cb72ba34db7819b4c3e94c431d4be2b19b8bb7a2d4116da417950c3425f17c8fe693d25e20212cac583ac1521ad066b77ae31f - conditions: os=darwin - languageName: node - linkType: hard - -"fsevents@patch:fsevents@~2.3.2#~builtin": - version: 2.3.2 - resolution: "fsevents@patch:fsevents@npm%3A2.3.2#~builtin::version=2.3.2&hash=18f3a7" - dependencies: - node-gyp: latest - conditions: os=darwin - languageName: node - linkType: hard - -"function-bind@npm:^1.1.1": - version: 1.1.1 - resolution: "function-bind@npm:1.1.1" - checksum: b32fbaebb3f8ec4969f033073b43f5c8befbb58f1a79e12f1d7490358150359ebd92f49e72ff0144f65f2c48ea2a605bff2d07965f548f6474fd8efd95bf361a - languageName: node - linkType: hard - -"functional-red-black-tree@npm:^1.0.1": - version: 1.0.1 - resolution: "functional-red-black-tree@npm:1.0.1" - checksum: ca6c170f37640e2d94297da8bb4bf27a1d12bea3e00e6a3e007fd7aa32e37e000f5772acf941b4e4f3cf1c95c3752033d0c509af157ad8f526e7f00723b9eb9f - languageName: node - linkType: hard - -"gauge@npm:^4.0.3": - version: 4.0.4 - resolution: "gauge@npm:4.0.4" - dependencies: - aproba: ^1.0.3 || ^2.0.0 - color-support: ^1.1.3 - console-control-strings: ^1.1.0 - has-unicode: ^2.0.1 - signal-exit: ^3.0.7 - string-width: ^4.2.3 - strip-ansi: ^6.0.1 - wide-align: ^1.1.5 - checksum: 788b6bfe52f1dd8e263cda800c26ac0ca2ff6de0b6eee2fe0d9e3abf15e149b651bd27bf5226be10e6e3edb5c4e5d5985a5a1a98137e7a892f75eff76467ad2d - languageName: node - linkType: hard - -"get-caller-file@npm:^2.0.5": - version: 2.0.5 - resolution: "get-caller-file@npm:2.0.5" - checksum: b9769a836d2a98c3ee734a88ba712e62703f1df31b94b784762c433c27a386dd6029ff55c2a920c392e33657d80191edbf18c61487e198844844516f843496b9 - languageName: node - linkType: hard - -"get-func-name@npm:^2.0.0": - version: 2.0.0 - resolution: "get-func-name@npm:2.0.0" - checksum: 8d82e69f3e7fab9e27c547945dfe5cc0c57fc0adf08ce135dddb01081d75684a03e7a0487466f478872b341d52ac763ae49e660d01ab83741f74932085f693c3 - languageName: node - linkType: hard - -"get-intrinsic@npm:^1.0.2, get-intrinsic@npm:^1.1.0, get-intrinsic@npm:^1.1.1": - version: 1.1.1 - resolution: "get-intrinsic@npm:1.1.1" - dependencies: - function-bind: ^1.1.1 - has: ^1.0.3 - has-symbols: ^1.0.1 - checksum: a9fe2ca8fa3f07f9b0d30fb202bcd01f3d9b9b6b732452e79c48e79f7d6d8d003af3f9e38514250e3553fdc83c61650851cb6870832ac89deaaceb08e3721a17 - languageName: node - linkType: hard - -"get-port@npm:^4.2.0": - version: 4.2.0 - resolution: "get-port@npm:4.2.0" - checksum: 6c9a452b2d6e81fe36781a69ed201883d37c02f141ba5770eaef3eca768ca38777c2eba4bec303f6b8c3f45f29036f95d5606b255f613320a6b4b680e1975c07 - languageName: node - linkType: hard - -"get-stream@npm:^5.0.0, get-stream@npm:^5.1.0": - version: 5.2.0 - resolution: "get-stream@npm:5.2.0" - dependencies: - pump: ^3.0.0 - checksum: 8bc1a23174a06b2b4ce600df38d6c98d2ef6d84e020c1ddad632ad75bac4e092eeb40e4c09e0761c35fc2dbc5e7fff5dab5e763a383582c4a167dd69a905bd12 - languageName: node - linkType: hard - -"get-symbol-description@npm:^1.0.0": - version: 1.0.0 - resolution: "get-symbol-description@npm:1.0.0" - dependencies: - call-bind: ^1.0.2 - get-intrinsic: ^1.1.1 - checksum: 9ceff8fe968f9270a37a1f73bf3f1f7bda69ca80f4f80850670e0e7b9444ff99323f7ac52f96567f8b5f5fbe7ac717a0d81d3407c7313e82810c6199446a5247 - languageName: node - linkType: hard - -"getos@npm:^3.2.1": - version: 3.2.1 - resolution: "getos@npm:3.2.1" - dependencies: - async: ^3.2.0 - checksum: 42fd78a66d47cebd3e09de5566cc0044e034b08f4a000a310dbd89a77b02c65d8f4002554bfa495ea5bdc4fa9d515f5ac785a7cc474ba45383cc697f865eeaf1 - languageName: node - linkType: hard - -"getpass@npm:^0.1.1": - version: 0.1.7 - resolution: "getpass@npm:0.1.7" - dependencies: - assert-plus: ^1.0.0 - checksum: ab18d55661db264e3eac6012c2d3daeafaab7a501c035ae0ccb193c3c23e9849c6e29b6ac762b9c2adae460266f925d55a3a2a3a3c8b94be2f222df94d70c046 - languageName: node - linkType: hard - -"glob-parent@npm:^6.0.1": - version: 6.0.2 - resolution: "glob-parent@npm:6.0.2" - dependencies: - is-glob: ^4.0.3 - checksum: c13ee97978bef4f55106b71e66428eb1512e71a7466ba49025fc2aec59a5bfb0954d5abd58fc5ee6c9b076eef4e1f6d3375c2e964b88466ca390da4419a786a8 - languageName: node - linkType: hard - -"glob-parent@npm:~5.1.2": - version: 5.1.2 - resolution: "glob-parent@npm:5.1.2" - dependencies: - is-glob: ^4.0.1 - checksum: f4f2bfe2425296e8a47e36864e4f42be38a996db40420fe434565e4480e3322f18eb37589617a98640c5dc8fdec1a387007ee18dbb1f3f5553409c34d17f425e - languageName: node - linkType: hard - -"glob@npm:^7.1.3, glob@npm:^7.1.4": - version: 7.2.3 - resolution: "glob@npm:7.2.3" - dependencies: - fs.realpath: ^1.0.0 - inflight: ^1.0.4 - inherits: 2 - minimatch: ^3.1.1 - once: ^1.3.0 - path-is-absolute: ^1.0.0 - checksum: 29452e97b38fa704dabb1d1045350fb2467cf0277e155aa9ff7077e90ad81d1ea9d53d3ee63bd37c05b09a065e90f16aec4a65f5b8de401d1dac40bc5605d133 - languageName: node - linkType: hard - -"glob@npm:^8.0.0, glob@npm:^8.0.1": - version: 8.0.3 - resolution: "glob@npm:8.0.3" - dependencies: - fs.realpath: ^1.0.0 - inflight: ^1.0.4 - inherits: 2 - minimatch: ^5.0.1 - once: ^1.3.0 - checksum: 50bcdea19d8e79d8de5f460b1939ffc2b3299eac28deb502093fdca22a78efebc03e66bf54f0abc3d3d07d8134d19a32850288b7440d77e072aa55f9d33b18c5 - languageName: node - linkType: hard - -"global-dirs@npm:^3.0.0": - version: 3.0.0 - resolution: "global-dirs@npm:3.0.0" - dependencies: - ini: 2.0.0 - checksum: 953c17cf14bf6ee0e2100ae82a0d779934eed8a3ec5c94a7a4f37c5b3b592c31ea015fb9a15cf32484de13c79f4a814f3015152f3e1d65976cfbe47c1bfe4a88 - languageName: node - linkType: hard - -"globals@npm:^11.12.0": - version: 11.12.0 - resolution: "globals@npm:11.12.0" - checksum: 67051a45eca3db904aee189dfc7cd53c20c7d881679c93f6146ddd4c9f4ab2268e68a919df740d39c71f4445d2b38ee360fc234428baea1dbdfe68bbcb46979e - languageName: node - linkType: hard - -"globals@npm:^13.15.0, globals@npm:^13.2.0": - version: 13.15.0 - resolution: "globals@npm:13.15.0" - dependencies: - type-fest: ^0.20.2 - checksum: 383ade0873b2ab29ce6d143466c203ed960491575bc97406395e5c8434026fb02472ab2dfff5bc16689b8460269b18fda1047975295cd0183904385c51258bae - languageName: node - linkType: hard - -"graceful-fs@npm:^4.1.6, graceful-fs@npm:^4.2.0, graceful-fs@npm:^4.2.6": - version: 4.2.10 - resolution: "graceful-fs@npm:4.2.10" - checksum: 3f109d70ae123951905d85032ebeae3c2a5a7a997430df00ea30df0e3a6c60cf6689b109654d6fdacd28810a053348c4d14642da1d075049e6be1ba5216218da - languageName: node - linkType: hard - -"has-bigints@npm:^1.0.1, has-bigints@npm:^1.0.2": - version: 1.0.2 - resolution: "has-bigints@npm:1.0.2" - checksum: 390e31e7be7e5c6fe68b81babb73dfc35d413604d7ee5f56da101417027a4b4ce6a27e46eff97ad040c835b5d228676eae99a9b5c3bc0e23c8e81a49241ff45b - languageName: node - linkType: hard - -"has-flag@npm:^3.0.0": - version: 3.0.0 - resolution: "has-flag@npm:3.0.0" - checksum: 4a15638b454bf086c8148979aae044dd6e39d63904cd452d970374fa6a87623423da485dfb814e7be882e05c096a7ccf1ebd48e7e7501d0208d8384ff4dea73b - languageName: node - linkType: hard - -"has-flag@npm:^4.0.0": - version: 4.0.0 - resolution: "has-flag@npm:4.0.0" - checksum: 261a1357037ead75e338156b1f9452c016a37dcd3283a972a30d9e4a87441ba372c8b81f818cd0fbcd9c0354b4ae7e18b9e1afa1971164aef6d18c2b6095a8ad - languageName: node - linkType: hard - -"has-property-descriptors@npm:^1.0.0": - version: 1.0.0 - resolution: "has-property-descriptors@npm:1.0.0" - dependencies: - get-intrinsic: ^1.1.1 - checksum: a6d3f0a266d0294d972e354782e872e2fe1b6495b321e6ef678c9b7a06a40408a6891817350c62e752adced73a94ac903c54734fee05bf65b1905ee1368194bb - languageName: node - linkType: hard - -"has-symbols@npm:^1.0.1, has-symbols@npm:^1.0.2, has-symbols@npm:^1.0.3": - version: 1.0.3 - resolution: "has-symbols@npm:1.0.3" - checksum: a054c40c631c0d5741a8285010a0777ea0c068f99ed43e5d6eb12972da223f8af553a455132fdb0801bdcfa0e0f443c0c03a68d8555aa529b3144b446c3f2410 - languageName: node - linkType: hard - -"has-tostringtag@npm:^1.0.0": - version: 1.0.0 - resolution: "has-tostringtag@npm:1.0.0" - dependencies: - has-symbols: ^1.0.2 - checksum: cc12eb28cb6ae22369ebaad3a8ab0799ed61270991be88f208d508076a1e99abe4198c965935ce85ea90b60c94ddda73693b0920b58e7ead048b4a391b502c1c - languageName: node - linkType: hard - -"has-unicode@npm:^2.0.1": - version: 2.0.1 - resolution: "has-unicode@npm:2.0.1" - checksum: 1eab07a7436512db0be40a710b29b5dc21fa04880b7f63c9980b706683127e3c1b57cb80ea96d47991bdae2dfe479604f6a1ba410106ee1046a41d1bd0814400 - languageName: node - linkType: hard - -"has@npm:^1.0.3": - version: 1.0.3 - resolution: "has@npm:1.0.3" - dependencies: - function-bind: ^1.1.1 - checksum: b9ad53d53be4af90ce5d1c38331e712522417d017d5ef1ebd0507e07c2fbad8686fffb8e12ddecd4c39ca9b9b47431afbb975b8abf7f3c3b82c98e9aad052792 - languageName: node - linkType: hard - -"highcharts@npm:10.2.0": - version: 10.2.0 - resolution: "highcharts@npm:10.2.0" - checksum: b9e16b9fc40b7e7af37936741398b3fd591256a1968462cb2b7d77163ebfd6b1ceb6deb1a55ee27f336277c78e8820f317d14e8f76f288784eabaf8121e14d2a - languageName: node - linkType: hard - -"highlight.js@npm:^11.5.0": - version: 11.5.1 - resolution: "highlight.js@npm:11.5.1" - checksum: bff556101d7691c6275ad19318e368fc971cd0621ef3d86222f5373df7d8191a2fc1ffd47f118138cbcf85e5fe91cfeefaecd6184f49a3ec18090955efc9edef - languageName: node - linkType: hard - -"html-escaper@npm:^2.0.0": - version: 2.0.2 - resolution: "html-escaper@npm:2.0.2" - checksum: d2df2da3ad40ca9ee3a39c5cc6475ef67c8f83c234475f24d8e9ce0dc80a2c82df8e1d6fa78ddd1e9022a586ea1bd247a615e80a5cd9273d90111ddda7d9e974 - languageName: node - linkType: hard - -"html-validate@npm:7.1.2": - version: 7.1.2 - resolution: "html-validate@npm:7.1.2" - dependencies: - "@babel/code-frame": ^7.10.0 - "@html-validate/stylish": ^3.0.0 - "@sidvind/better-ajv-errors": ^2.0.0 - acorn-walk: ^8.0.0 - ajv: ^8.0.0 - deepmerge: ^4.2.0 - espree: ^9.0.0 - glob: ^8.0.0 - ignore: ^5.0.0 - kleur: ^4.1.0 - minimist: ^1.2.0 - prompts: ^2.0.0 - semver: ^7.0.0 - peerDependencies: - jest: ^25.1 || ^26 || ^27.1 || ^28 - jest-diff: ^25.1 || ^26 || ^27.1 || ^28 - jest-snapshot: ^25.1 || ^26 || ^27.1 || ^28 - peerDependenciesMeta: - jest: - optional: true - jest-diff: - optional: true - jest-snapshot: - optional: true - bin: - html-validate: bin/html-validate.js - checksum: 616c8596477e78cb4b2f175960c4fff4c3a1f5160e6cc3d8d835d4fb16aaba74910c4b8545c8765431aab0eed3f9749ff7f1fe22c487470c829ed815184a3332 - languageName: node - linkType: hard - -"htmlnano@npm:^2.0.0": - version: 2.0.2 - resolution: "htmlnano@npm:2.0.2" - dependencies: - cosmiconfig: ^7.0.1 - posthtml: ^0.16.5 - timsort: ^0.3.0 - peerDependencies: - cssnano: ^5.0.11 - postcss: ^8.3.11 - purgecss: ^4.0.3 - relateurl: ^0.2.7 - srcset: ^5.0.0 - svgo: ^2.8.0 - terser: ^5.10.0 - uncss: ^0.17.3 - peerDependenciesMeta: - cssnano: - optional: true - postcss: - optional: true - purgecss: - optional: true - relateurl: - optional: true - srcset: - optional: true - svgo: - optional: true - terser: - optional: true - uncss: - optional: true - checksum: 41f9e0c0e54367730109e9ea31a1e625ebfa4134f6689d36aba76551cb62a9a5c200bee556b4ad12c230d3586243ac6ebaaaab93bb3091d7f96686a98c5caa1a - languageName: node - linkType: hard - -"htmlparser2@npm:^7.1.1": - version: 7.2.0 - resolution: "htmlparser2@npm:7.2.0" - dependencies: - domelementtype: ^2.0.1 - domhandler: ^4.2.2 - domutils: ^2.8.0 - entities: ^3.0.1 - checksum: 96563d9965729cfcb3f5f19c26d013c6831b4cb38d79d8c185e9cd669ea6a9ffe8fb9ccc74d29a068c9078aa0e2767053ed6b19aa32723c41550340d0094bea0 - languageName: node - linkType: hard - -"http-cache-semantics@npm:^4.1.0": - version: 4.1.0 - resolution: "http-cache-semantics@npm:4.1.0" - checksum: 974de94a81c5474be07f269f9fd8383e92ebb5a448208223bfb39e172a9dbc26feff250192ecc23b9593b3f92098e010406b0f24bd4d588d631f80214648ed42 - languageName: node - linkType: hard - -"http-proxy-agent@npm:^5.0.0": - version: 5.0.0 - resolution: "http-proxy-agent@npm:5.0.0" - dependencies: - "@tootallnate/once": 2 - agent-base: 6 - debug: 4 - checksum: e2ee1ff1656a131953839b2a19cd1f3a52d97c25ba87bd2559af6ae87114abf60971e498021f9b73f9fd78aea8876d1fb0d4656aac8a03c6caa9fc175f22b786 - languageName: node - linkType: hard - -"http-signature@npm:~1.3.6": - version: 1.3.6 - resolution: "http-signature@npm:1.3.6" - dependencies: - assert-plus: ^1.0.0 - jsprim: ^2.0.2 - sshpk: ^1.14.1 - checksum: 10be2af4764e71fee0281392937050201ee576ac755c543f570d6d87134ce5e858663fe999a7adb3e4e368e1e356d0d7fec6b9542295b875726ff615188e7a0c - languageName: node - linkType: hard - -"https-proxy-agent@npm:^5.0.0": - version: 5.0.1 - resolution: "https-proxy-agent@npm:5.0.1" - dependencies: - agent-base: 6 - debug: 4 - checksum: 571fccdf38184f05943e12d37d6ce38197becdd69e58d03f43637f7fa1269cf303a7d228aa27e5b27bbd3af8f09fd938e1c91dcfefff2df7ba77c20ed8dfc765 - languageName: node - linkType: hard - -"human-signals@npm:^1.1.1": - version: 1.1.1 - resolution: "human-signals@npm:1.1.1" - checksum: d587647c9e8ec24e02821b6be7de5a0fc37f591f6c4e319b3054b43fd4c35a70a94c46fc74d8c1a43c47fde157d23acd7421f375e1c1365b09a16835b8300205 - languageName: node - linkType: hard - -"humanize-ms@npm:^1.2.1": - version: 1.2.1 - resolution: "humanize-ms@npm:1.2.1" - dependencies: - ms: ^2.0.0 - checksum: 9c7a74a2827f9294c009266c82031030eae811ca87b0da3dceb8d6071b9bde22c9f3daef0469c3c533cc67a97d8a167cd9fc0389350e5f415f61a79b171ded16 - languageName: node - linkType: hard - -"iconv-lite@npm:0.6, iconv-lite@npm:^0.6.2": - version: 0.6.3 - resolution: "iconv-lite@npm:0.6.3" - dependencies: - safer-buffer: ">= 2.1.2 < 3.0.0" - checksum: 3f60d47a5c8fc3313317edfd29a00a692cc87a19cac0159e2ce711d0ebc9019064108323b5e493625e25594f11c6236647d8e256fbe7a58f4a3b33b89e6d30bf - languageName: node - linkType: hard - -"ieee754@npm:^1.1.13": - version: 1.2.1 - resolution: "ieee754@npm:1.2.1" - checksum: 5144c0c9815e54ada181d80a0b810221a253562422e7c6c3a60b1901154184f49326ec239d618c416c1c5945a2e197107aee8d986a3dd836b53dffefd99b5e7e - languageName: node - linkType: hard - -"ignore@npm:^5.0.0, ignore@npm:^5.1.1, ignore@npm:^5.2.0": - version: 5.2.0 - resolution: "ignore@npm:5.2.0" - checksum: 6b1f926792d614f64c6c83da3a1f9c83f6196c2839aa41e1e32dd7b8d174cef2e329d75caabb62cb61ce9dc432f75e67d07d122a037312db7caa73166a1bdb77 - languageName: node - linkType: hard - -"immutable@npm:^4.0.0": - version: 4.0.0 - resolution: "immutable@npm:4.0.0" - checksum: 4b5e9181e4d5fa06728a481835ec09c86367e5d03268666c95b522b7644ab891098022e4479a43c4c81a68f2ed82f10751ce5d33e208d7b873b6e7f9dfaf4d87 - languageName: node - linkType: hard - -"import-fresh@npm:^3.0.0, import-fresh@npm:^3.2.1": - version: 3.3.0 - resolution: "import-fresh@npm:3.3.0" - dependencies: - parent-module: ^1.0.0 - resolve-from: ^4.0.0 - checksum: 2cacfad06e652b1edc50be650f7ec3be08c5e5a6f6d12d035c440a42a8cc028e60a5b99ca08a77ab4d6b1346da7d971915828f33cdab730d3d42f08242d09baa - languageName: node - linkType: hard - -"imurmurhash@npm:^0.1.4": - version: 0.1.4 - resolution: "imurmurhash@npm:0.1.4" - checksum: 7cae75c8cd9a50f57dadd77482359f659eaebac0319dd9368bcd1714f55e65badd6929ca58569da2b6494ef13fdd5598cd700b1eba23f8b79c5f19d195a3ecf7 - languageName: node - linkType: hard - -"indent-string@npm:^4.0.0": - version: 4.0.0 - resolution: "indent-string@npm:4.0.0" - checksum: 824cfb9929d031dabf059bebfe08cf3137365e112019086ed3dcff6a0a7b698cb80cf67ccccde0e25b9e2d7527aa6cc1fed1ac490c752162496caba3e6699612 - languageName: node - linkType: hard - -"infer-owner@npm:^1.0.4": - version: 1.0.4 - resolution: "infer-owner@npm:1.0.4" - checksum: 181e732764e4a0611576466b4b87dac338972b839920b2a8cde43642e4ed6bd54dc1fb0b40874728f2a2df9a1b097b8ff83b56d5f8f8e3927f837fdcb47d8a89 - languageName: node - linkType: hard - -"inflight@npm:^1.0.4": - version: 1.0.6 - resolution: "inflight@npm:1.0.6" - dependencies: - once: ^1.3.0 - wrappy: 1 - checksum: f4f76aa072ce19fae87ce1ef7d221e709afb59d445e05d47fba710e85470923a75de35bfae47da6de1b18afc3ce83d70facf44cfb0aff89f0a3f45c0a0244dfd - languageName: node - linkType: hard - -"inherits@npm:2, inherits@npm:^2.0.3": - version: 2.0.4 - resolution: "inherits@npm:2.0.4" - checksum: 4a48a733847879d6cf6691860a6b1e3f0f4754176e4d71494c41f3475553768b10f84b5ce1d40fbd0e34e6bfbb864ee35858ad4dd2cf31e02fc4a154b724d7f1 - languageName: node - linkType: hard - -"ini@npm:2.0.0": - version: 2.0.0 - resolution: "ini@npm:2.0.0" - checksum: e7aadc5fb2e4aefc666d74ee2160c073995a4061556b1b5b4241ecb19ad609243b9cceafe91bae49c219519394bbd31512516cb22a3b1ca6e66d869e0447e84e - languageName: node - linkType: hard - -"internal-slot@npm:^1.0.3": - version: 1.0.3 - resolution: "internal-slot@npm:1.0.3" - dependencies: - get-intrinsic: ^1.1.0 - has: ^1.0.3 - side-channel: ^1.0.4 - checksum: 1944f92e981e47aebc98a88ff0db579fd90543d937806104d0b96557b10c1f170c51fb777b97740a8b6ddeec585fca8c39ae99fd08a8e058dfc8ab70937238bf - languageName: node - linkType: hard - -"internmap@npm:1 - 2": - version: 2.0.3 - resolution: "internmap@npm:2.0.3" - checksum: 7ca41ec6aba8f0072fc32fa8a023450a9f44503e2d8e403583c55714b25efd6390c38a87161ec456bf42d7bc83aab62eb28f5aef34876b1ac4e60693d5e1d241 - languageName: node - linkType: hard - -"ip@npm:^1.1.5": - version: 1.1.8 - resolution: "ip@npm:1.1.8" - checksum: a2ade53eb339fb0cbe9e69a44caab10d6e3784662285eb5d2677117ee4facc33a64679051c35e0dfdb1a3983a51ce2f5d2cb36446d52e10d01881789b76e28fb - languageName: node - linkType: hard - -"is-arrayish@npm:^0.2.1": - version: 0.2.1 - resolution: "is-arrayish@npm:0.2.1" - checksum: eef4417e3c10e60e2c810b6084942b3ead455af16c4509959a27e490e7aee87cfb3f38e01bbde92220b528a0ee1a18d52b787e1458ee86174d8c7f0e58cd488f - languageName: node - linkType: hard - -"is-bigint@npm:^1.0.1": - version: 1.0.4 - resolution: "is-bigint@npm:1.0.4" - dependencies: - has-bigints: ^1.0.1 - checksum: c56edfe09b1154f8668e53ebe8252b6f185ee852a50f9b41e8d921cb2bed425652049fbe438723f6cb48a63ca1aa051e948e7e401e093477c99c84eba244f666 - languageName: node - linkType: hard - -"is-binary-path@npm:~2.1.0": - version: 2.1.0 - resolution: "is-binary-path@npm:2.1.0" - dependencies: - binary-extensions: ^2.0.0 - checksum: 84192eb88cff70d320426f35ecd63c3d6d495da9d805b19bc65b518984b7c0760280e57dbf119b7e9be6b161784a5a673ab2c6abe83abb5198a432232ad5b35c - languageName: node - linkType: hard - -"is-boolean-object@npm:^1.1.0": - version: 1.1.2 - resolution: "is-boolean-object@npm:1.1.2" - dependencies: - call-bind: ^1.0.2 - has-tostringtag: ^1.0.0 - checksum: c03b23dbaacadc18940defb12c1c0e3aaece7553ef58b162a0f6bba0c2a7e1551b59f365b91e00d2dbac0522392d576ef322628cb1d036a0fe51eb466db67222 - languageName: node - linkType: hard - -"is-callable@npm:^1.1.4, is-callable@npm:^1.2.4": - version: 1.2.4 - resolution: "is-callable@npm:1.2.4" - checksum: 1a28d57dc435797dae04b173b65d6d1e77d4f16276e9eff973f994eadcfdc30a017e6a597f092752a083c1103cceb56c91e3dadc6692fedb9898dfaba701575f - languageName: node - linkType: hard - -"is-ci@npm:^3.0.0": - version: 3.0.1 - resolution: "is-ci@npm:3.0.1" - dependencies: - ci-info: ^3.2.0 - bin: - is-ci: bin.js - checksum: 192c66dc7826d58f803ecae624860dccf1899fc1f3ac5505284c0a5cf5f889046ffeb958fa651e5725d5705c5bcb14f055b79150ea5fcad7456a9569de60260e - languageName: node - linkType: hard - -"is-core-module@npm:^2.3.0, is-core-module@npm:^2.8.1, is-core-module@npm:^2.9.0": - version: 2.9.0 - resolution: "is-core-module@npm:2.9.0" - dependencies: - has: ^1.0.3 - checksum: b27034318b4b462f1c8f1dfb1b32baecd651d891a4e2d1922135daeff4141dfced2b82b07aef83ef54275c4a3526aa38da859223664d0868ca24182badb784ce - languageName: node - linkType: hard - -"is-date-object@npm:^1.0.1": - version: 1.0.5 - resolution: "is-date-object@npm:1.0.5" - dependencies: - has-tostringtag: ^1.0.0 - checksum: baa9077cdf15eb7b58c79398604ca57379b2fc4cf9aa7a9b9e295278648f628c9b201400c01c5e0f7afae56507d741185730307cbe7cad3b9f90a77e5ee342fc - languageName: node - linkType: hard - -"is-expression@npm:^4.0.0": - version: 4.0.0 - resolution: "is-expression@npm:4.0.0" - dependencies: - acorn: ^7.1.1 - object-assign: ^4.1.1 - checksum: 0f01d0ff53fbbec36abae8fbb7ef056c6d024f7128646856a3e6c500b205788d3e0f337025e72df979d7d7cf4674a00370633d7f8974c668b2d3fdb7e8a83bdb - languageName: node - linkType: hard - -"is-extglob@npm:^2.1.1": - version: 2.1.1 - resolution: "is-extglob@npm:2.1.1" - checksum: df033653d06d0eb567461e58a7a8c9f940bd8c22274b94bf7671ab36df5719791aae15eef6d83bbb5e23283967f2f984b8914559d4449efda578c775c4be6f85 - languageName: node - linkType: hard - -"is-fullwidth-code-point@npm:^3.0.0": - version: 3.0.0 - resolution: "is-fullwidth-code-point@npm:3.0.0" - checksum: 44a30c29457c7fb8f00297bce733f0a64cd22eca270f83e58c105e0d015e45c019491a4ab2faef91ab51d4738c670daff901c799f6a700e27f7314029e99e348 - languageName: node - linkType: hard - -"is-glob@npm:^4.0.0, is-glob@npm:^4.0.1, is-glob@npm:^4.0.3, is-glob@npm:~4.0.1": - version: 4.0.3 - resolution: "is-glob@npm:4.0.3" - dependencies: - is-extglob: ^2.1.1 - checksum: d381c1319fcb69d341cc6e6c7cd588e17cd94722d9a32dbd60660b993c4fb7d0f19438674e68dfec686d09b7c73139c9166b47597f846af387450224a8101ab4 - languageName: node - linkType: hard - -"is-installed-globally@npm:~0.4.0": - version: 0.4.0 - resolution: "is-installed-globally@npm:0.4.0" - dependencies: - global-dirs: ^3.0.0 - is-path-inside: ^3.0.2 - checksum: 3359840d5982d22e9b350034237b2cda2a12bac1b48a721912e1ab8e0631dd07d45a2797a120b7b87552759a65ba03e819f1bd63f2d7ab8657ec0b44ee0bf399 - languageName: node - linkType: hard - -"is-json@npm:^2.0.1": - version: 2.0.1 - resolution: "is-json@npm:2.0.1" - checksum: 29efc4f82e912bf54cd7b28632dd8e52a311085ca879fe51c869a81ba1313bb689eb440ace53dd480edbc009f92a425c24059e0766f4117fe9888fe59e86186f - languageName: node - linkType: hard - -"is-lambda@npm:^1.0.1": - version: 1.0.1 - resolution: "is-lambda@npm:1.0.1" - checksum: 93a32f01940220532e5948538699ad610d5924ac86093fcee83022252b363eb0cc99ba53ab084a04e4fb62bf7b5731f55496257a4c38adf87af9c4d352c71c35 - languageName: node - linkType: hard - -"is-negative-zero@npm:^2.0.2": - version: 2.0.2 - resolution: "is-negative-zero@npm:2.0.2" - checksum: f3232194c47a549da60c3d509c9a09be442507616b69454716692e37ae9f37c4dea264fb208ad0c9f3efd15a796a46b79df07c7e53c6227c32170608b809149a - languageName: node - linkType: hard - -"is-number-object@npm:^1.0.4": - version: 1.0.7 - resolution: "is-number-object@npm:1.0.7" - dependencies: - has-tostringtag: ^1.0.0 - checksum: d1e8d01bb0a7134c74649c4e62da0c6118a0bfc6771ea3c560914d52a627873e6920dd0fd0ebc0e12ad2ff4687eac4c308f7e80320b973b2c8a2c8f97a7524f7 - languageName: node - linkType: hard - -"is-number@npm:^7.0.0": - version: 7.0.0 - resolution: "is-number@npm:7.0.0" - checksum: 456ac6f8e0f3111ed34668a624e45315201dff921e5ac181f8ec24923b99e9f32ca1a194912dc79d539c97d33dba17dc635202ff0b2cf98326f608323276d27a - languageName: node - linkType: hard - -"is-path-inside@npm:^3.0.2": - version: 3.0.3 - resolution: "is-path-inside@npm:3.0.3" - checksum: abd50f06186a052b349c15e55b182326f1936c89a78bf6c8f2b707412517c097ce04bc49a0ca221787bc44e1049f51f09a2ffb63d22899051988d3a618ba13e9 - languageName: node - linkType: hard - -"is-promise@npm:^2.0.0": - version: 2.2.2 - resolution: "is-promise@npm:2.2.2" - checksum: 18bf7d1c59953e0ad82a1ed963fb3dc0d135c8f299a14f89a17af312fc918373136e56028e8831700e1933519630cc2fd4179a777030330fde20d34e96f40c78 - languageName: node - linkType: hard - -"is-regex@npm:^1.0.3, is-regex@npm:^1.1.4": - version: 1.1.4 - resolution: "is-regex@npm:1.1.4" - dependencies: - call-bind: ^1.0.2 - has-tostringtag: ^1.0.0 - checksum: 362399b33535bc8f386d96c45c9feb04cf7f8b41c182f54174c1a45c9abbbe5e31290bbad09a458583ff6bf3b2048672cdb1881b13289569a7c548370856a652 - languageName: node - linkType: hard - -"is-shared-array-buffer@npm:^1.0.2": - version: 1.0.2 - resolution: "is-shared-array-buffer@npm:1.0.2" - dependencies: - call-bind: ^1.0.2 - checksum: 9508929cf14fdc1afc9d61d723c6e8d34f5e117f0bffda4d97e7a5d88c3a8681f633a74f8e3ad1fe92d5113f9b921dc5ca44356492079612f9a247efbce7032a - languageName: node - linkType: hard - -"is-stream@npm:^2.0.0": - version: 2.0.1 - resolution: "is-stream@npm:2.0.1" - checksum: b8e05ccdf96ac330ea83c12450304d4a591f9958c11fd17bed240af8d5ffe08aedafa4c0f4cfccd4d28dc9d4d129daca1023633d5c11601a6cbc77521f6fae66 - languageName: node - linkType: hard - -"is-string@npm:^1.0.5, is-string@npm:^1.0.7": - version: 1.0.7 - resolution: "is-string@npm:1.0.7" - dependencies: - has-tostringtag: ^1.0.0 - checksum: 323b3d04622f78d45077cf89aab783b2f49d24dc641aa89b5ad1a72114cfeff2585efc8c12ef42466dff32bde93d839ad321b26884cf75e5a7892a938b089989 - languageName: node - linkType: hard - -"is-symbol@npm:^1.0.2, is-symbol@npm:^1.0.3": - version: 1.0.4 - resolution: "is-symbol@npm:1.0.4" - dependencies: - has-symbols: ^1.0.2 - checksum: 92805812ef590738d9de49d677cd17dfd486794773fb6fa0032d16452af46e9b91bb43ffe82c983570f015b37136f4b53b28b8523bfb10b0ece7a66c31a54510 - languageName: node - linkType: hard - -"is-typedarray@npm:~1.0.0": - version: 1.0.0 - resolution: "is-typedarray@npm:1.0.0" - checksum: 3508c6cd0a9ee2e0df2fa2e9baabcdc89e911c7bd5cf64604586697212feec525aa21050e48affb5ffc3df20f0f5d2e2cf79b08caa64e1ccc9578e251763aef7 - languageName: node - linkType: hard - -"is-unicode-supported@npm:^0.1.0": - version: 0.1.0 - resolution: "is-unicode-supported@npm:0.1.0" - checksum: a2aab86ee7712f5c2f999180daaba5f361bdad1efadc9610ff5b8ab5495b86e4f627839d085c6530363c6d6d4ecbde340fb8e54bdb83da4ba8e0865ed5513c52 - languageName: node - linkType: hard - -"is-weakref@npm:^1.0.2": - version: 1.0.2 - resolution: "is-weakref@npm:1.0.2" - dependencies: - call-bind: ^1.0.2 - checksum: 95bd9a57cdcb58c63b1c401c60a474b0f45b94719c30f548c891860f051bc2231575c290a6b420c6bc6e7ed99459d424c652bd5bf9a1d5259505dc35b4bf83de - languageName: node - linkType: hard - -"isexe@npm:^2.0.0": - version: 2.0.0 - resolution: "isexe@npm:2.0.0" - checksum: 26bf6c5480dda5161c820c5b5c751ae1e766c587b1f951ea3fcfc973bafb7831ae5b54a31a69bd670220e42e99ec154475025a468eae58ea262f813fdc8d1c62 - languageName: node - linkType: hard - -"isstream@npm:~0.1.2": - version: 0.1.2 - resolution: "isstream@npm:0.1.2" - checksum: 1eb2fe63a729f7bdd8a559ab552c69055f4f48eb5c2f03724430587c6f450783c8f1cd936c1c952d0a927925180fcc892ebd5b174236cf1065d4bd5bdb37e963 - languageName: node - linkType: hard - -"istanbul-lib-coverage@npm:^3.0.0, istanbul-lib-coverage@npm:^3.2.0": - version: 3.2.0 - resolution: "istanbul-lib-coverage@npm:3.2.0" - checksum: a2a545033b9d56da04a8571ed05c8120bf10e9bce01cf8633a3a2b0d1d83dff4ac4fe78d6d5673c27fc29b7f21a41d75f83a36be09f82a61c367b56aa73c1ff9 - languageName: node - linkType: hard - -"istanbul-lib-report@npm:^3.0.0": - version: 3.0.0 - resolution: "istanbul-lib-report@npm:3.0.0" - dependencies: - istanbul-lib-coverage: ^3.0.0 - make-dir: ^3.0.0 - supports-color: ^7.1.0 - checksum: 3f29eb3f53c59b987386e07fe772d24c7f58c6897f34c9d7a296f4000de7ae3de9eb95c3de3df91dc65b134c84dee35c54eee572a56243e8907c48064e34ff1b - languageName: node - linkType: hard - -"istanbul-reports@npm:^3.1.4": - version: 3.1.4 - resolution: "istanbul-reports@npm:3.1.4" - dependencies: - html-escaper: ^2.0.0 - istanbul-lib-report: ^3.0.0 - checksum: 2132983355710c522f6b26808015cab9a0ee8b9f5ae0db0d3edeff40b886dd83cb670fb123cb7b32dbe59473d7c00cdde2ba6136bc0acdb20a865fccea64dfe1 - languageName: node - linkType: hard - -"jest-diff@npm:^27.5.1": - version: 27.5.1 - resolution: "jest-diff@npm:27.5.1" - dependencies: - chalk: ^4.0.0 - diff-sequences: ^27.5.1 - jest-get-type: ^27.5.1 - pretty-format: ^27.5.1 - checksum: 8be27c1e1ee57b2bb2bef9c0b233c19621b4c43d53a3c26e2c00a4e805eb4ea11fe1694a06a9fb0e80ffdcfdc0d2b1cb0b85920b3f5c892327ecd1e7bd96b865 - languageName: node - linkType: hard - -"jest-get-type@npm:^27.5.1": - version: 27.5.1 - resolution: "jest-get-type@npm:27.5.1" - checksum: 63064ab70195c21007d897c1157bf88ff94a790824a10f8c890392e7d17eda9c3900513cb291ca1c8d5722cad79169764e9a1279f7c8a9c4cd6e9109ff04bbc0 - languageName: node - linkType: hard - -"jest-matcher-utils@npm:^27.0.0": - version: 27.5.1 - resolution: "jest-matcher-utils@npm:27.5.1" - dependencies: - chalk: ^4.0.0 - jest-diff: ^27.5.1 - jest-get-type: ^27.5.1 - pretty-format: ^27.5.1 - checksum: bb2135fc48889ff3fe73888f6cc7168ddab9de28b51b3148f820c89fdfd2effdcad005f18be67d0b9be80eda208ad47290f62f03d0a33f848db2dd0273c8217a - languageName: node - linkType: hard - -"jquery-migrate@npm:3.4.0": - version: 3.4.0 - resolution: "jquery-migrate@npm:3.4.0" - peerDependencies: - jquery: ">=3 <4" - checksum: 7431685c560d5ff6bc083f613dc4ea72905832b84cb9df4b28c4de71f41dc69c86ac135601a5fe41329773dde0739b4002456ba2249f646d2969afb98092fe4a - languageName: node - linkType: hard - -"jquery-ui-dist@npm:1.13.1": - version: 1.13.1 - resolution: "jquery-ui-dist@npm:1.13.1" - dependencies: - jquery: ">=1.8.0 <4.0.0" - checksum: 9a19f520b80ab6e62bcd3ecf1dc946386b67fd349b5f4fb1186ab5a8608b047958f4f0e78aeed3dd2c128a5375c2e359cbc2f98bb5d2a091cee85e4bb60a0b3b - languageName: node - linkType: hard - -"jquery@npm:3.6.0, jquery@npm:>=1.8.0 <4.0.0": - version: 3.6.0 - resolution: "jquery@npm:3.6.0" - checksum: 8fd5fef4aa48fd374ec716dd1c1df1af407814a228e15c1260ca140de3a697c2a77c30c54ff1d238b6a3ab4ddc445ddeef9adce6c6d28e4869d85eb9d3951c0e - languageName: node - linkType: hard - -"js-cookie@npm:3.0.1": - version: 3.0.1 - resolution: "js-cookie@npm:3.0.1" - checksum: bb48de67e2a6bd1ae3dfd6b2d5a167c33dd0c5a37e909206161eb0358c98f17cb55acd55827a58e9eea3630d89444e7479f7938ef4420dda443218b8c434a4c3 - languageName: node - linkType: hard - -"js-stringify@npm:^1.0.2": - version: 1.0.2 - resolution: "js-stringify@npm:1.0.2" - checksum: f9701d9e535d3ac0f62bbf2624b76c5d0af5b889187232817ae284a41ba21fd7a8b464c2dce3815d8cf52c8bea3480be6b368cfc2c67da799cad458058e8bbf5 - languageName: node - linkType: hard - -"js-tokens@npm:^4.0.0": - version: 4.0.0 - resolution: "js-tokens@npm:4.0.0" - checksum: 8a95213a5a77deb6cbe94d86340e8d9ace2b93bc367790b260101d2f36a2eaf4e4e22d9fa9cf459b38af3a32fb4190e638024cf82ec95ef708680e405ea7cc78 - languageName: node - linkType: hard - -"js-yaml@npm:^4.1.0": - version: 4.1.0 - resolution: "js-yaml@npm:4.1.0" - dependencies: - argparse: ^2.0.1 - bin: - js-yaml: bin/js-yaml.js - checksum: c7830dfd456c3ef2c6e355cc5a92e6700ceafa1d14bba54497b34a99f0376cecbb3e9ac14d3e5849b426d5a5140709a66237a8c991c675431271c4ce5504151a - languageName: node - linkType: hard - -"jsbn@npm:~0.1.0": - version: 0.1.1 - resolution: "jsbn@npm:0.1.1" - checksum: e5ff29c1b8d965017ef3f9c219dacd6e40ad355c664e277d31246c90545a02e6047018c16c60a00f36d561b3647215c41894f5d869ada6908a2e0ce4200c88f2 - languageName: node - linkType: hard - -"json-parse-even-better-errors@npm:^2.3.0": - version: 2.3.1 - resolution: "json-parse-even-better-errors@npm:2.3.1" - checksum: 798ed4cf3354a2d9ccd78e86d2169515a0097a5c133337807cdf7f1fc32e1391d207ccfc276518cc1d7d8d4db93288b8a50ba4293d212ad1336e52a8ec0a941f - languageName: node - linkType: hard - -"json-schema-traverse@npm:^0.4.1": - version: 0.4.1 - resolution: "json-schema-traverse@npm:0.4.1" - checksum: 7486074d3ba247769fda17d5181b345c9fb7d12e0da98b22d1d71a5db9698d8b4bd900a3ec1a4ffdd60846fc2556274a5c894d0c48795f14cb03aeae7b55260b - languageName: node - linkType: hard - -"json-schema-traverse@npm:^1.0.0": - version: 1.0.0 - resolution: "json-schema-traverse@npm:1.0.0" - checksum: 02f2f466cdb0362558b2f1fd5e15cce82ef55d60cd7f8fa828cf35ba74330f8d767fcae5c5c2adb7851fa811766c694b9405810879bc4e1ddd78a7c0e03658ad - languageName: node - linkType: hard - -"json-schema@npm:0.4.0": - version: 0.4.0 - resolution: "json-schema@npm:0.4.0" - checksum: 66389434c3469e698da0df2e7ac5a3281bcff75e797a5c127db7c5b56270e01ae13d9afa3c03344f76e32e81678337a8c912bdbb75101c62e487dc3778461d72 - languageName: node - linkType: hard - -"json-stable-stringify-without-jsonify@npm:^1.0.1": - version: 1.0.1 - resolution: "json-stable-stringify-without-jsonify@npm:1.0.1" - checksum: cff44156ddce9c67c44386ad5cddf91925fe06b1d217f2da9c4910d01f358c6e3989c4d5a02683c7a5667f9727ff05831f7aa8ae66c8ff691c556f0884d49215 - languageName: node - linkType: hard - -"json-stringify-safe@npm:~5.0.1": - version: 5.0.1 - resolution: "json-stringify-safe@npm:5.0.1" - checksum: 48ec0adad5280b8a96bb93f4563aa1667fd7a36334f79149abd42446d0989f2ddc58274b479f4819f1f00617957e6344c886c55d05a4e15ebb4ab931e4a6a8ee - languageName: node - linkType: hard - -"json5@npm:^1.0.1": - version: 1.0.1 - resolution: "json5@npm:1.0.1" - dependencies: - minimist: ^1.2.0 - bin: - json5: lib/cli.js - checksum: e76ea23dbb8fc1348c143da628134a98adf4c5a4e8ea2adaa74a80c455fc2cdf0e2e13e6398ef819bfe92306b610ebb2002668ed9fc1af386d593691ef346fc3 - languageName: node - linkType: hard - -"json5@npm:^2.2.0, json5@npm:^2.2.1": - version: 2.2.1 - resolution: "json5@npm:2.2.1" - bin: - json5: lib/cli.js - checksum: 74b8a23b102a6f2bf2d224797ae553a75488b5adbaee9c9b6e5ab8b510a2fc6e38f876d4c77dea672d4014a44b2399e15f2051ac2b37b87f74c0c7602003543b - languageName: node - linkType: hard - -"jsonfile@npm:^6.0.1": - version: 6.1.0 - resolution: "jsonfile@npm:6.1.0" - dependencies: - graceful-fs: ^4.1.6 - universalify: ^2.0.0 - dependenciesMeta: - graceful-fs: - optional: true - checksum: 7af3b8e1ac8fe7f1eccc6263c6ca14e1966fcbc74b618d3c78a0a2075579487547b94f72b7a1114e844a1e15bb00d440e5d1720bfc4612d790a6f285d5ea8354 - languageName: node - linkType: hard - -"jsprim@npm:^2.0.2": - version: 2.0.2 - resolution: "jsprim@npm:2.0.2" - dependencies: - assert-plus: 1.0.0 - extsprintf: 1.3.0 - json-schema: 0.4.0 - verror: 1.10.0 - checksum: d175f6b1991e160cb0aa39bc857da780e035611986b5492f32395411879fdaf4e513d98677f08f7352dac93a16b66b8361c674b86a3fa406e2e7af6b26321838 - languageName: node - linkType: hard - -"jstransformer@npm:1.0.0": - version: 1.0.0 - resolution: "jstransformer@npm:1.0.0" - dependencies: - is-promise: ^2.0.0 - promise: ^7.0.1 - checksum: 1e019fde17a38766a5b96bccf0738156badc60cfa61e2ba8a8bbd3b855e7d5d7e17492b8a66e4aaabc39483e335d23217343ae32d0f7e5a81af42a95c3e075f9 - languageName: node - linkType: hard - -"kleur@npm:^3.0.3": - version: 3.0.3 - resolution: "kleur@npm:3.0.3" - checksum: df82cd1e172f957bae9c536286265a5cdbd5eeca487cb0a3b2a7b41ef959fc61f8e7c0e9aeea9c114ccf2c166b6a8dd45a46fd619c1c569d210ecd2765ad5169 - languageName: node - linkType: hard - -"kleur@npm:^4.0.0, kleur@npm:^4.1.0": - version: 4.1.4 - resolution: "kleur@npm:4.1.4" - checksum: 7f6db36e378045dec14acd3cbf0b1e59130c09e984ee8b8ce56dd2d2257cfff90389c1e8f8b19bd09dd5d241080566a814b4ccd99fdcef91f59ef93ec33c8a44 - languageName: node - linkType: hard - -"lazy-ass@npm:^1.6.0": - version: 1.6.0 - resolution: "lazy-ass@npm:1.6.0" - checksum: 5a3ebb17915b03452320804466345382a6c25ac782ec4874fecdb2385793896cd459be2f187dc7def8899180c32ee0ab9a1aa7fe52193ac3ff3fe29bb0591729 - languageName: node - linkType: hard - -"levn@npm:^0.4.1": - version: 0.4.1 - resolution: "levn@npm:0.4.1" - dependencies: - prelude-ls: ^1.2.1 - type-check: ~0.4.0 - checksum: 12c5021c859bd0f5248561bf139121f0358285ec545ebf48bb3d346820d5c61a4309535c7f387ed7d84361cf821e124ce346c6b7cef8ee09a67c1473b46d0fc4 - languageName: node - linkType: hard - -"lines-and-columns@npm:^1.1.6": - version: 1.2.4 - resolution: "lines-and-columns@npm:1.2.4" - checksum: 0c37f9f7fa212b38912b7145e1cd16a5f3cd34d782441c3e6ca653485d326f58b3caccda66efce1c5812bde4961bbde3374fae4b0d11bf1226152337f3894aa5 - languageName: node - linkType: hard - -"list.js@npm:2.3.1": - version: 2.3.1 - resolution: "list.js@npm:2.3.1" - dependencies: - string-natural-compare: ^2.0.2 - checksum: 3bb4e9035b422ebcb6b3ca643b11c69acc0254bd1561722c7525e8fe6a8f5732bbd553961112fbdabc2b58cda3db77be6182154e43a89523da4ff472c0aca5fc - languageName: node - linkType: hard - -"listr2@npm:^3.8.3": - version: 3.14.0 - resolution: "listr2@npm:3.14.0" - dependencies: - cli-truncate: ^2.1.0 - colorette: ^2.0.16 - log-update: ^4.0.0 - p-map: ^4.0.0 - rfdc: ^1.3.0 - rxjs: ^7.5.1 - through: ^2.3.8 - wrap-ansi: ^7.0.0 - peerDependencies: - enquirer: ">= 2.3.0 < 3" - peerDependenciesMeta: - enquirer: - optional: true - checksum: fdb8b2d6bdf5df9371ebd5082bee46c6d0ca3d1e5f2b11fbb5a127839855d5f3da9d4968fce94f0a5ec67cac2459766abbb1faeef621065ebb1829b11ef9476d - languageName: node - linkType: hard - -"lmdb@npm:2.5.2": - version: 2.5.2 - resolution: "lmdb@npm:2.5.2" - dependencies: - "@lmdb/lmdb-darwin-arm64": 2.5.2 - "@lmdb/lmdb-darwin-x64": 2.5.2 - "@lmdb/lmdb-linux-arm": 2.5.2 - "@lmdb/lmdb-linux-arm64": 2.5.2 - "@lmdb/lmdb-linux-x64": 2.5.2 - "@lmdb/lmdb-win32-x64": 2.5.2 - msgpackr: ^1.5.4 - node-addon-api: ^4.3.0 - node-gyp: latest - node-gyp-build-optional-packages: 5.0.3 - ordered-binary: ^1.2.4 - weak-lru-cache: ^1.2.2 - dependenciesMeta: - "@lmdb/lmdb-darwin-arm64": - optional: true - "@lmdb/lmdb-darwin-x64": - optional: true - "@lmdb/lmdb-linux-arm": - optional: true - "@lmdb/lmdb-linux-arm64": - optional: true - "@lmdb/lmdb-linux-x64": - optional: true - "@lmdb/lmdb-win32-x64": - optional: true - checksum: 3362dc2b03c6fbdfc02291001007e4096767476e65fbf8d5e332ef473946a0d108319748ef5974ebb84cf6ffa4015c039920f130bcc09c03a751b03a9fd93dff - languageName: node - linkType: hard - -"local-pkg@npm:^0.4.2": - version: 0.4.2 - resolution: "local-pkg@npm:0.4.2" - checksum: 22be451353c25c4411b552bf01880ebc9e995b93574b2facc7757968d888356df59199cacada14162ab53bbc9da055bb692c907b4171f008dbce45a2afc777c1 - languageName: node - linkType: hard - -"locate-path@npm:^2.0.0": - version: 2.0.0 - resolution: "locate-path@npm:2.0.0" - dependencies: - p-locate: ^2.0.0 - path-exists: ^3.0.0 - checksum: 02d581edbbbb0fa292e28d96b7de36b5b62c2fa8b5a7e82638ebb33afa74284acf022d3b1e9ae10e3ffb7658fbc49163fcd5e76e7d1baaa7801c3e05a81da755 - languageName: node - linkType: hard - -"locate-path@npm:^6.0.0": - version: 6.0.0 - resolution: "locate-path@npm:6.0.0" - dependencies: - p-locate: ^5.0.0 - checksum: 72eb661788a0368c099a184c59d2fee760b3831c9c1c33955e8a19ae4a21b4116e53fa736dc086cdeb9fce9f7cc508f2f92d2d3aae516f133e16a2bb59a39f5a - languageName: node - linkType: hard - -"lodash-es@npm:^4.17.21": - version: 4.17.21 - resolution: "lodash-es@npm:4.17.21" - checksum: 05cbffad6e2adbb331a4e16fbd826e7faee403a1a04873b82b42c0f22090f280839f85b95393f487c1303c8a3d2a010048bf06151a6cbe03eee4d388fb0a12d2 - languageName: node - linkType: hard - -"lodash.merge@npm:^4.6.2": - version: 4.6.2 - resolution: "lodash.merge@npm:4.6.2" - checksum: ad580b4bdbb7ca1f7abf7e1bce63a9a0b98e370cf40194b03380a46b4ed799c9573029599caebc1b14e3f24b111aef72b96674a56cfa105e0f5ac70546cdc005 - languageName: node - linkType: hard - -"lodash.once@npm:^4.1.1": - version: 4.1.1 - resolution: "lodash.once@npm:4.1.1" - checksum: d768fa9f9b4e1dc6453be99b753906f58990e0c45e7b2ca5a3b40a33111e5d17f6edf2f768786e2716af90a8e78f8f91431ab8435f761fef00f9b0c256f6d245 - languageName: node - linkType: hard - -"lodash.sortby@npm:^4.7.0": - version: 4.7.0 - resolution: "lodash.sortby@npm:4.7.0" - checksum: db170c9396d29d11fe9a9f25668c4993e0c1331bcb941ddbd48fb76f492e732add7f2a47cfdf8e9d740fa59ac41bbfaf931d268bc72aab3ab49e9f89354d718c - languageName: node - linkType: hard - -"lodash@npm:4.17.21, lodash@npm:^4.17.21": - version: 4.17.21 - resolution: "lodash@npm:4.17.21" - checksum: eb835a2e51d381e561e508ce932ea50a8e5a68f4ebdd771ea240d3048244a8d13658acbd502cd4829768c56f2e16bdd4340b9ea141297d472517b83868e677f7 - languageName: node - linkType: hard - -"log-symbols@npm:^4.0.0": - version: 4.1.0 - resolution: "log-symbols@npm:4.1.0" - dependencies: - chalk: ^4.1.0 - is-unicode-supported: ^0.1.0 - checksum: fce1497b3135a0198803f9f07464165e9eb83ed02ceb2273930a6f8a508951178d8cf4f0378e9d28300a2ed2bc49050995d2bd5f53ab716bb15ac84d58c6ef74 - languageName: node - linkType: hard - -"log-update@npm:^4.0.0": - version: 4.0.0 - resolution: "log-update@npm:4.0.0" - dependencies: - ansi-escapes: ^4.3.0 - cli-cursor: ^3.1.0 - slice-ansi: ^4.0.0 - wrap-ansi: ^6.2.0 - checksum: ae2f85bbabc1906034154fb7d4c4477c79b3e703d22d78adee8b3862fa913942772e7fa11713e3d96fb46de4e3cabefbf5d0a544344f03b58d3c4bff52aa9eb2 - languageName: node - linkType: hard - -"loupe@npm:^2.3.1": - version: 2.3.4 - resolution: "loupe@npm:2.3.4" - dependencies: - get-func-name: ^2.0.0 - checksum: 5af91db61aa18530f1749a64735ee194ac263e65e9f4d1562bf3036c591f1baa948289c193e0e34c7b5e2c1b75d3c1dc4fce87f5edb3cee10b0c0df46bc9ffb3 - languageName: node - linkType: hard - -"lru-cache@npm:^6.0.0": - version: 6.0.0 - resolution: "lru-cache@npm:6.0.0" - dependencies: - yallist: ^4.0.0 - checksum: f97f499f898f23e4585742138a22f22526254fdba6d75d41a1c2526b3b6cc5747ef59c5612ba7375f42aca4f8461950e925ba08c991ead0651b4918b7c978297 - languageName: node - linkType: hard - -"lru-cache@npm:^7.7.1": - version: 7.10.1 - resolution: "lru-cache@npm:7.10.1" - checksum: e8b190d71ed0fcd7b29c71a3e9b01f851c92d1ef8865ff06b5581ca991db1e5e006920ed4da8b56da1910664ed51abfd76c46fb55e82ac252ff6c970ff910d72 - languageName: node - linkType: hard - -"luxon@npm:3.0.1": - version: 3.0.1 - resolution: "luxon@npm:3.0.1" - checksum: aa966eb919bf95b1bd819cda784d1f6f66e3fb65bd9ec7bf68b6a978eeb4e3e14f7e2275021b473f93b15b6b7ba2e5a30471e53add3929a7e695fcfd6dd40ec8 - languageName: node - linkType: hard - -"magic-string@npm:^0.25.7": - version: 0.25.9 - resolution: "magic-string@npm:0.25.9" - dependencies: - sourcemap-codec: ^1.4.8 - checksum: 9a0e55a15c7303fc360f9572a71cffba1f61451bc92c5602b1206c9d17f492403bf96f946dfce7483e66822d6b74607262e24392e87b0ac27b786e69a40e9b1a - languageName: node - linkType: hard - -"make-dir@npm:^3.0.0": - version: 3.1.0 - resolution: "make-dir@npm:3.1.0" - dependencies: - semver: ^6.0.0 - checksum: 484200020ab5a1fdf12f393fe5f385fc8e4378824c940fba1729dcd198ae4ff24867bc7a5646331e50cead8abff5d9270c456314386e629acec6dff4b8016b78 - languageName: node - linkType: hard - -"make-fetch-happen@npm:^10.0.3": - version: 10.1.5 - resolution: "make-fetch-happen@npm:10.1.5" - dependencies: - agentkeepalive: ^4.2.1 - cacache: ^16.1.0 - http-cache-semantics: ^4.1.0 - http-proxy-agent: ^5.0.0 - https-proxy-agent: ^5.0.0 - is-lambda: ^1.0.1 - lru-cache: ^7.7.1 - minipass: ^3.1.6 - minipass-collect: ^1.0.2 - minipass-fetch: ^2.0.3 - minipass-flush: ^1.0.5 - minipass-pipeline: ^1.2.4 - negotiator: ^0.6.3 - promise-retry: ^2.0.1 - socks-proxy-agent: ^6.1.1 - ssri: ^9.0.0 - checksum: b0b42a1ccdcbc3180749727a52cf6887d9df6218d8ca35101bb9f7ab35729dd166d99203b70149a19a818d1ba72de40b982002ddb0b308c548457f5725d6e7f6 - languageName: node - linkType: hard - -"mdn-data@npm:2.0.14": - version: 2.0.14 - resolution: "mdn-data@npm:2.0.14" - checksum: 9d0128ed425a89f4cba8f787dca27ad9408b5cb1b220af2d938e2a0629d17d879a34d2cb19318bdb26c3f14c77dd5dfbae67211f5caaf07b61b1f2c5c8c7dc16 - languageName: node - linkType: hard - -"merge-stream@npm:^2.0.0": - version: 2.0.0 - resolution: "merge-stream@npm:2.0.0" - checksum: 6fa4dcc8d86629705cea944a4b88ef4cb0e07656ebf223fa287443256414283dd25d91c1cd84c77987f2aec5927af1a9db6085757cb43d90eb170ebf4b47f4f4 - languageName: node - linkType: hard - -"mime-db@npm:1.52.0": - version: 1.52.0 - resolution: "mime-db@npm:1.52.0" - checksum: 0d99a03585f8b39d68182803b12ac601d9c01abfa28ec56204fa330bc9f3d1c5e14beb049bafadb3dbdf646dfb94b87e24d4ec7b31b7279ef906a8ea9b6a513f - languageName: node - linkType: hard - -"mime-types@npm:^2.1.12, mime-types@npm:~2.1.19": - version: 2.1.35 - resolution: "mime-types@npm:2.1.35" - dependencies: - mime-db: 1.52.0 - checksum: 89a5b7f1def9f3af5dad6496c5ed50191ae4331cc5389d7c521c8ad28d5fdad2d06fd81baf38fed813dc4e46bb55c8145bb0ff406330818c9cf712fb2e9b3836 - languageName: node - linkType: hard - -"mimic-fn@npm:^2.1.0": - version: 2.1.0 - resolution: "mimic-fn@npm:2.1.0" - checksum: d2421a3444848ce7f84bd49115ddacff29c15745db73f54041edc906c14b131a38d05298dae3081667627a59b2eb1ca4b436ff2e1b80f69679522410418b478a - languageName: node - linkType: hard - -"minimatch@npm:^3.0.4, minimatch@npm:^3.1.1, minimatch@npm:^3.1.2": - version: 3.1.2 - resolution: "minimatch@npm:3.1.2" - dependencies: - brace-expansion: ^1.1.7 - checksum: c154e566406683e7bcb746e000b84d74465b3a832c45d59912b9b55cd50dee66e5c4b1e5566dba26154040e51672f9aa450a9aef0c97cfc7336b78b7afb9540a - languageName: node - linkType: hard - -"minimatch@npm:^5.0.1": - version: 5.1.0 - resolution: "minimatch@npm:5.1.0" - dependencies: - brace-expansion: ^2.0.1 - checksum: 15ce53d31a06361e8b7a629501b5c75491bc2b59712d53e802b1987121d91b433d73fcc5be92974fde66b2b51d8fb28d75a9ae900d249feb792bb1ba2a4f0a90 - languageName: node - linkType: hard - -"minimist@npm:^1.2.0, minimist@npm:^1.2.6": - version: 1.2.6 - resolution: "minimist@npm:1.2.6" - checksum: d15428cd1e11eb14e1233bcfb88ae07ed7a147de251441d61158619dfb32c4d7e9061d09cab4825fdee18ecd6fce323228c8c47b5ba7cd20af378ca4048fb3fb - languageName: node - linkType: hard - -"minipass-collect@npm:^1.0.2": - version: 1.0.2 - resolution: "minipass-collect@npm:1.0.2" - dependencies: - minipass: ^3.0.0 - checksum: 14df761028f3e47293aee72888f2657695ec66bd7d09cae7ad558da30415fdc4752bbfee66287dcc6fd5e6a2fa3466d6c484dc1cbd986525d9393b9523d97f10 - languageName: node - linkType: hard - -"minipass-fetch@npm:^2.0.3": - version: 2.1.0 - resolution: "minipass-fetch@npm:2.1.0" - dependencies: - encoding: ^0.1.13 - minipass: ^3.1.6 - minipass-sized: ^1.0.3 - minizlib: ^2.1.2 - dependenciesMeta: - encoding: - optional: true - checksum: 1334732859a3f7959ed22589bafd9c40384b885aebb5932328071c33f86b3eb181d54c86919675d1825ab5f1c8e4f328878c863873258d113c29d79a4b0c9c9f - languageName: node - linkType: hard - -"minipass-flush@npm:^1.0.5": - version: 1.0.5 - resolution: "minipass-flush@npm:1.0.5" - dependencies: - minipass: ^3.0.0 - checksum: 56269a0b22bad756a08a94b1ffc36b7c9c5de0735a4dd1ab2b06c066d795cfd1f0ac44a0fcae13eece5589b908ecddc867f04c745c7009be0b566421ea0944cf - languageName: node - linkType: hard - -"minipass-pipeline@npm:^1.2.4": - version: 1.2.4 - resolution: "minipass-pipeline@npm:1.2.4" - dependencies: - minipass: ^3.0.0 - checksum: b14240dac0d29823c3d5911c286069e36d0b81173d7bdf07a7e4a91ecdef92cdff4baaf31ea3746f1c61e0957f652e641223970870e2353593f382112257971b - languageName: node - linkType: hard - -"minipass-sized@npm:^1.0.3": - version: 1.0.3 - resolution: "minipass-sized@npm:1.0.3" - dependencies: - minipass: ^3.0.0 - checksum: 79076749fcacf21b5d16dd596d32c3b6bf4d6e62abb43868fac21674078505c8b15eaca4e47ed844985a4514854f917d78f588fcd029693709417d8f98b2bd60 - languageName: node - linkType: hard - -"minipass@npm:^3.0.0, minipass@npm:^3.1.1, minipass@npm:^3.1.6": - version: 3.1.6 - resolution: "minipass@npm:3.1.6" - dependencies: - yallist: ^4.0.0 - checksum: 57a04041413a3531a65062452cb5175f93383ef245d6f4a2961d34386eb9aa8ac11ac7f16f791f5e8bbaf1dfb1ef01596870c88e8822215db57aa591a5bb0a77 - languageName: node - linkType: hard - -"minizlib@npm:^2.1.1, minizlib@npm:^2.1.2": - version: 2.1.2 - resolution: "minizlib@npm:2.1.2" - dependencies: - minipass: ^3.0.0 - yallist: ^4.0.0 - checksum: f1fdeac0b07cf8f30fcf12f4b586795b97be856edea22b5e9072707be51fc95d41487faec3f265b42973a304fe3a64acd91a44a3826a963e37b37bafde0212c3 - languageName: node - linkType: hard - -"mkdirp@npm:^1.0.3, mkdirp@npm:^1.0.4": - version: 1.0.4 - resolution: "mkdirp@npm:1.0.4" - bin: - mkdirp: bin/cmd.js - checksum: a96865108c6c3b1b8e1d5e9f11843de1e077e57737602de1b82030815f311be11f96f09cce59bd5b903d0b29834733e5313f9301e3ed6d6f6fba2eae0df4298f - languageName: node - linkType: hard - -"moment-timezone@npm:0.5.34": - version: 0.5.34 - resolution: "moment-timezone@npm:0.5.34" - dependencies: - moment: ">= 2.9.0" - checksum: 12a1d3d52e4ba509cf1fa36bbda59d898a08fa80ab35f6c358747e93aec1f07e617cec647eaf2e8acf5f9132e581d4704d34a9edffa9a80c5cd04bf23b277595 - languageName: node - linkType: hard - -"moment@npm:2.29.4": - version: 2.29.4 - resolution: "moment@npm:2.29.4" - checksum: 0ec3f9c2bcba38dc2451b1daed5daded747f17610b92427bebe1d08d48d8b7bdd8d9197500b072d14e326dd0ccf3e326b9e3d07c5895d3d49e39b6803b76e80e - languageName: node - linkType: hard - -"moment@npm:>= 2.9.0": - version: 2.29.3 - resolution: "moment@npm:2.29.3" - checksum: 2e780e36d9a1823c08a1b6313cbb08bd01ecbb2a9062095820a34f42c878991ccba53abaa6abb103fd5c01e763724f295162a8c50b7e95b4f1c992ef0772d3f0 - languageName: node - linkType: hard - -"ms@npm:2.0.0": - version: 2.0.0 - resolution: "ms@npm:2.0.0" - checksum: 0e6a22b8b746d2e0b65a430519934fefd41b6db0682e3477c10f60c76e947c4c0ad06f63ffdf1d78d335f83edee8c0aa928aa66a36c7cd95b69b26f468d527f4 - languageName: node - linkType: hard - -"ms@npm:2.1.2, ms@npm:^2.1.1": - version: 2.1.2 - resolution: "ms@npm:2.1.2" - checksum: 673cdb2c3133eb050c745908d8ce632ed2c02d85640e2edb3ace856a2266a813b30c613569bf3354fdf4ea7d1a1494add3bfa95e2713baa27d0c2c71fc44f58f - languageName: node - linkType: hard - -"ms@npm:^2.0.0": - version: 2.1.3 - resolution: "ms@npm:2.1.3" - checksum: aa92de608021b242401676e35cfa5aa42dd70cbdc082b916da7fb925c542173e36bce97ea3e804923fe92c0ad991434e4a38327e15a1b5b5f945d66df615ae6d - languageName: node - linkType: hard - -"msgpackr-extract@npm:^2.0.2": - version: 2.0.2 - resolution: "msgpackr-extract@npm:2.0.2" - dependencies: - "@msgpackr-extract/msgpackr-extract-darwin-arm64": 2.0.2 - "@msgpackr-extract/msgpackr-extract-darwin-x64": 2.0.2 - "@msgpackr-extract/msgpackr-extract-linux-arm": 2.0.2 - "@msgpackr-extract/msgpackr-extract-linux-arm64": 2.0.2 - "@msgpackr-extract/msgpackr-extract-linux-x64": 2.0.2 - "@msgpackr-extract/msgpackr-extract-win32-x64": 2.0.2 - node-gyp: latest - node-gyp-build-optional-packages: 5.0.2 - dependenciesMeta: - "@msgpackr-extract/msgpackr-extract-darwin-arm64": - optional: true - "@msgpackr-extract/msgpackr-extract-darwin-x64": - optional: true - "@msgpackr-extract/msgpackr-extract-linux-arm": - optional: true - "@msgpackr-extract/msgpackr-extract-linux-arm64": - optional: true - "@msgpackr-extract/msgpackr-extract-linux-x64": - optional: true - "@msgpackr-extract/msgpackr-extract-win32-x64": - optional: true - checksum: 6b24c0e89eae881012484787082a50290f78d2dc69df28c28838c65f9cda3f585272c73b9ebbf386f9958c16a9956f0cabddf2ccfc1229ee612a6b88e9519c68 - languageName: node - linkType: hard - -"msgpackr@npm:^1.5.4": - version: 1.6.0 - resolution: "msgpackr@npm:1.6.0" - dependencies: - msgpackr-extract: ^2.0.2 - dependenciesMeta: - msgpackr-extract: - optional: true - checksum: 7f94acbe93d4ba10fd05a8a88523a2c90c5385ab1ebb7feff25903c6d465255e52f6c0b64b70a93f08e2ba190a490b62d1396b0f392c8ecc3707871acc0115f7 - languageName: node - linkType: hard - -"murmurhash-js@npm:1.0.0": - version: 1.0.0 - resolution: "murmurhash-js@npm:1.0.0" - checksum: 083cea92a11bc9eb25be1446fc92eded3f49731bc1ad34fa8023afd68c234d1dd59458d70eb20e667b1383bedeeb8dfb1a16c89913b6ffe3584fd22fb598739d - languageName: node - linkType: hard - -"naive-ui@npm:2.31.0": - version: 2.31.0 - resolution: "naive-ui@npm:2.31.0" - dependencies: - "@css-render/plugin-bem": ^0.15.10 - "@css-render/vue3-ssr": ^0.15.10 - "@types/lodash": ^4.14.181 - "@types/lodash-es": ^4.17.6 - async-validator: ^4.0.7 - css-render: ^0.15.10 - date-fns: ^2.28.0 - date-fns-tz: ^1.3.3 - evtd: ^0.2.3 - highlight.js: ^11.5.0 - lodash: ^4.17.21 - lodash-es: ^4.17.21 - seemly: ^0.3.4 - treemate: ^0.3.11 - vdirs: ^0.1.8 - vooks: ^0.2.12 - vueuc: ^0.4.47 - peerDependencies: - vue: ^3.0.0 - checksum: 7194b4a8143fa3702b78ba4b197f068e1164553811fb24619c7fad21ba2f53f2490df111e2bc2ace21ce8f26778c8d4af7d4ee5a921be5d6820ad2e95c4d486b - languageName: node - linkType: hard - -"nanoid@npm:^3.3.1": - version: 3.3.3 - resolution: "nanoid@npm:3.3.3" - bin: - nanoid: bin/nanoid.cjs - checksum: ada019402a07464a694553c61d2dca8a4353645a7d92f2830f0d487fedff403678a0bee5323a46522752b2eab95a0bc3da98b6cccaa7c0c55cd9975130e6d6f0 - languageName: node - linkType: hard - -"nanoid@npm:^3.3.4": - version: 3.3.4 - resolution: "nanoid@npm:3.3.4" - bin: - nanoid: bin/nanoid.cjs - checksum: 2fddd6dee994b7676f008d3ffa4ab16035a754f4bb586c61df5a22cf8c8c94017aadd360368f47d653829e0569a92b129979152ff97af23a558331e47e37cd9c - languageName: node - linkType: hard - -"natural-compare@npm:^1.4.0": - version: 1.4.0 - resolution: "natural-compare@npm:1.4.0" - checksum: 23ad088b08f898fc9b53011d7bb78ec48e79de7627e01ab5518e806033861bef68d5b0cd0e2205c2f36690ac9571ff6bcb05eb777ced2eeda8d4ac5b44592c3d - languageName: node - linkType: hard - -"negotiator@npm:^0.6.3": - version: 0.6.3 - resolution: "negotiator@npm:0.6.3" - checksum: b8ffeb1e262eff7968fc90a2b6767b04cfd9842582a9d0ece0af7049537266e7b2506dfb1d107a32f06dd849ab2aea834d5830f7f4d0e5cb7d36e1ae55d021d9 - languageName: node - linkType: hard - -"node-addon-api@npm:^3.2.1": - version: 3.2.1 - resolution: "node-addon-api@npm:3.2.1" - dependencies: - node-gyp: latest - checksum: 2369986bb0881ccd9ef6bacdf39550e07e089a9c8ede1cbc5fc7712d8e2faa4d50da0e487e333d4125f8c7a616c730131d1091676c9d499af1d74560756b4a18 - languageName: node - linkType: hard - -"node-addon-api@npm:^4.3.0": - version: 4.3.0 - resolution: "node-addon-api@npm:4.3.0" - dependencies: - node-gyp: latest - checksum: 3de396e23cc209f539c704583e8e99c148850226f6e389a641b92e8967953713228109f919765abc1f4355e801e8f41842f96210b8d61c7dcc10a477002dcf00 - languageName: node - linkType: hard - -"node-gyp-build-optional-packages@npm:5.0.2": - version: 5.0.2 - resolution: "node-gyp-build-optional-packages@npm:5.0.2" - bin: - node-gyp-build-optional: optional.js - node-gyp-build-optional-packages: bin.js - node-gyp-build-test: build-test.js - checksum: 6fca33cd1e297a446dead8a9bc7a48988be30098c219e75e8466d0218dea6b03bf5da092fe20301cb8b72218356c656422f1a64520c37ebc30eb596b012d1ad9 - languageName: node - linkType: hard - -"node-gyp-build-optional-packages@npm:5.0.3": - version: 5.0.3 - resolution: "node-gyp-build-optional-packages@npm:5.0.3" - bin: - node-gyp-build-optional-packages: bin.js - node-gyp-build-optional-packages-optional: optional.js - node-gyp-build-optional-packages-test: build-test.js - checksum: be3f0235925c8361e5bc1a03848f5e24815b0df8aa90bd13f1eac91cd86264bbb8b7689ca6cd083b02c8099c7b54f9fb83066c7bb77c2389dc4eceab921f084f - languageName: node - linkType: hard - -"node-gyp-build@npm:^4.3.0": - version: 4.4.0 - resolution: "node-gyp-build@npm:4.4.0" - bin: - node-gyp-build: bin.js - node-gyp-build-optional: optional.js - node-gyp-build-test: build-test.js - checksum: 972a059f960253d254e0b23ce10f54c8982236fc0edcab85166d0b7f87443b2ce98391c877cfb2f6eeafcf03c538c5f4dd3e0bfff03828eb48634f58f4c64343 - languageName: node - linkType: hard - -"node-gyp@npm:latest": - version: 9.0.0 - resolution: "node-gyp@npm:9.0.0" - dependencies: - env-paths: ^2.2.0 - glob: ^7.1.4 - graceful-fs: ^4.2.6 - make-fetch-happen: ^10.0.3 - nopt: ^5.0.0 - npmlog: ^6.0.0 - rimraf: ^3.0.2 - semver: ^7.3.5 - tar: ^6.1.2 - which: ^2.0.2 - bin: - node-gyp: bin/node-gyp.js - checksum: 4d8ef8860f7e4f4d86c91db3f519d26ed5cc23b48fe54543e2afd86162b4acbd14f21de42a5db344525efb69a991e021b96a68c70c6e2d5f4a5cb770793da6d3 - languageName: node - linkType: hard - -"node-releases@npm:^2.0.3": - version: 2.0.4 - resolution: "node-releases@npm:2.0.4" - checksum: b32d6c2032c7b169ae3938b416fc50f123f5bd577d54a79b2ae201febf27b22846b01c803dd35ac8689afe840f8ba4e5f7154723db629b80f359836b6707b92f - languageName: node - linkType: hard - -"nopt@npm:^5.0.0": - version: 5.0.0 - resolution: "nopt@npm:5.0.0" - dependencies: - abbrev: 1 - bin: - nopt: bin/nopt.js - checksum: d35fdec187269503843924e0114c0c6533fb54bbf1620d0f28b4b60ba01712d6687f62565c55cc20a504eff0fbe5c63e22340c3fad549ad40469ffb611b04f2f - languageName: node - linkType: hard - -"normalize-path@npm:^3.0.0, normalize-path@npm:~3.0.0": - version: 3.0.0 - resolution: "normalize-path@npm:3.0.0" - checksum: 88eeb4da891e10b1318c4b2476b6e2ecbeb5ff97d946815ffea7794c31a89017c70d7f34b3c2ebf23ef4e9fc9fb99f7dffe36da22011b5b5c6ffa34f4873ec20 - languageName: node - linkType: hard - -"npm-run-path@npm:^4.0.0": - version: 4.0.1 - resolution: "npm-run-path@npm:4.0.1" - dependencies: - path-key: ^3.0.0 - checksum: 5374c0cea4b0bbfdfae62da7bbdf1e1558d338335f4cacf2515c282ff358ff27b2ecb91ffa5330a8b14390ac66a1e146e10700440c1ab868208430f56b5f4d23 - languageName: node - linkType: hard - -"npmlog@npm:^6.0.0": - version: 6.0.2 - resolution: "npmlog@npm:6.0.2" - dependencies: - are-we-there-yet: ^3.0.0 - console-control-strings: ^1.1.0 - gauge: ^4.0.3 - set-blocking: ^2.0.0 - checksum: ae238cd264a1c3f22091cdd9e2b106f684297d3c184f1146984ecbe18aaa86343953f26b9520dedd1b1372bc0316905b736c1932d778dbeb1fcf5a1001390e2a - languageName: node - linkType: hard - -"nth-check@npm:^2.0.1": - version: 2.1.1 - resolution: "nth-check@npm:2.1.1" - dependencies: - boolbase: ^1.0.0 - checksum: 5afc3dafcd1573b08877ca8e6148c52abd565f1d06b1eb08caf982e3fa289a82f2cae697ffb55b5021e146d60443f1590a5d6b944844e944714a5b549675bcd3 - languageName: node - linkType: hard - -"nullthrows@npm:^1.1.1": - version: 1.1.1 - resolution: "nullthrows@npm:1.1.1" - checksum: 10806b92121253eb1b08ecf707d92480f5331ba8ae5b23fa3eb0548ad24196eb797ed47606153006568a5733ea9e528a3579f21421f7828e09e7756f4bdd386f - languageName: node - linkType: hard - -"object-assign@npm:^4.1.1": - version: 4.1.1 - resolution: "object-assign@npm:4.1.1" - checksum: fcc6e4ea8c7fe48abfbb552578b1c53e0d194086e2e6bbbf59e0a536381a292f39943c6e9628af05b5528aa5e3318bb30d6b2e53cadaf5b8fe9e12c4b69af23f - languageName: node - linkType: hard - -"object-inspect@npm:^1.12.0, object-inspect@npm:^1.9.0": - version: 1.12.0 - resolution: "object-inspect@npm:1.12.0" - checksum: 2b36d4001a9c921c6b342e2965734519c9c58c355822243c3207fbf0aac271f8d44d30d2d570d450b2cc6f0f00b72bcdba515c37827d2560e5f22b1899a31cf4 - languageName: node - linkType: hard - -"object-keys@npm:^1.1.1": - version: 1.1.1 - resolution: "object-keys@npm:1.1.1" - checksum: b363c5e7644b1e1b04aa507e88dcb8e3a2f52b6ffd0ea801e4c7a62d5aa559affe21c55a07fd4b1fd55fc03a33c610d73426664b20032405d7b92a1414c34d6a - languageName: node - linkType: hard - -"object.assign@npm:^4.1.2": - version: 4.1.2 - resolution: "object.assign@npm:4.1.2" - dependencies: - call-bind: ^1.0.0 - define-properties: ^1.1.3 - has-symbols: ^1.0.1 - object-keys: ^1.1.1 - checksum: d621d832ed7b16ac74027adb87196804a500d80d9aca536fccb7ba48d33a7e9306a75f94c1d29cbfa324bc091bfc530bc24789568efdaee6a47fcfa298993814 - languageName: node - linkType: hard - -"object.values@npm:^1.1.5": - version: 1.1.5 - resolution: "object.values@npm:1.1.5" - dependencies: - call-bind: ^1.0.2 - define-properties: ^1.1.3 - es-abstract: ^1.19.1 - checksum: 0f17e99741ebfbd0fa55ce942f6184743d3070c61bd39221afc929c8422c4907618c8da694c6915bc04a83ab3224260c779ba37fc07bb668bdc5f33b66a902a4 - languageName: node - linkType: hard - -"once@npm:^1.3.0, once@npm:^1.3.1, once@npm:^1.4.0": - version: 1.4.0 - resolution: "once@npm:1.4.0" - dependencies: - wrappy: 1 - checksum: cd0a88501333edd640d95f0d2700fbde6bff20b3d4d9bdc521bdd31af0656b5706570d6c6afe532045a20bb8dc0849f8332d6f2a416e0ba6d3d3b98806c7db68 - languageName: node - linkType: hard - -"onetime@npm:^5.1.0": - version: 5.1.2 - resolution: "onetime@npm:5.1.2" - dependencies: - mimic-fn: ^2.1.0 - checksum: 2478859ef817fc5d4e9c2f9e5728512ddd1dbc9fb7829ad263765bb6d3b91ce699d6e2332eef6b7dff183c2f490bd3349f1666427eaba4469fba0ac38dfd0d34 - languageName: node - linkType: hard - -"optionator@npm:^0.9.1": - version: 0.9.1 - resolution: "optionator@npm:0.9.1" - dependencies: - deep-is: ^0.1.3 - fast-levenshtein: ^2.0.6 - levn: ^0.4.1 - prelude-ls: ^1.2.1 - type-check: ^0.4.0 - word-wrap: ^1.2.3 - checksum: dbc6fa065604b24ea57d734261914e697bd73b69eff7f18e967e8912aa2a40a19a9f599a507fa805be6c13c24c4eae8c71306c239d517d42d4c041c942f508a0 - languageName: node - linkType: hard - -"ordered-binary@npm:^1.2.4": - version: 1.2.5 - resolution: "ordered-binary@npm:1.2.5" - checksum: fd0f1322a67064fa7e35bada142b05c50442976907e834a0c4d19b64aa621cd6941fc3d0f87eede91359ace9a932119f3c2248eb43fd52e6103ba1210aa3c506 - languageName: node - linkType: hard - -"ospath@npm:^1.2.2": - version: 1.2.2 - resolution: "ospath@npm:1.2.2" - checksum: 505f48a4f4f1c557d6c656ec985707726e3714721680139be037613e903aa8c8fa4ddd8d1342006f9b2dc0065e6e20f8b7bea2ee05354f31257044790367b347 - languageName: node - linkType: hard - -"p-limit@npm:^1.1.0": - version: 1.3.0 - resolution: "p-limit@npm:1.3.0" - dependencies: - p-try: ^1.0.0 - checksum: 281c1c0b8c82e1ac9f81acd72a2e35d402bf572e09721ce5520164e9de07d8274451378a3470707179ad13240535558f4b277f02405ad752e08c7d5b0d54fbfd - languageName: node - linkType: hard - -"p-limit@npm:^3.0.2": - version: 3.1.0 - resolution: "p-limit@npm:3.1.0" - dependencies: - yocto-queue: ^0.1.0 - checksum: 7c3690c4dbf62ef625671e20b7bdf1cbc9534e83352a2780f165b0d3ceba21907e77ad63401708145ca4e25bfc51636588d89a8c0aeb715e6c37d1c066430360 - languageName: node - linkType: hard - -"p-locate@npm:^2.0.0": - version: 2.0.0 - resolution: "p-locate@npm:2.0.0" - dependencies: - p-limit: ^1.1.0 - checksum: e2dceb9b49b96d5513d90f715780f6f4972f46987dc32a0e18bc6c3fc74a1a5d73ec5f81b1398af5e58b99ea1ad03fd41e9181c01fa81b4af2833958696e3081 - languageName: node - linkType: hard - -"p-locate@npm:^5.0.0": - version: 5.0.0 - resolution: "p-locate@npm:5.0.0" - dependencies: - p-limit: ^3.0.2 - checksum: 1623088f36cf1cbca58e9b61c4e62bf0c60a07af5ae1ca99a720837356b5b6c5ba3eb1b2127e47a06865fee59dd0453cad7cc844cda9d5a62ac1a5a51b7c86d3 - languageName: node - linkType: hard - -"p-map@npm:^4.0.0": - version: 4.0.0 - resolution: "p-map@npm:4.0.0" - dependencies: - aggregate-error: ^3.0.0 - checksum: cb0ab21ec0f32ddffd31dfc250e3afa61e103ef43d957cc45497afe37513634589316de4eb88abdfd969fe6410c22c0b93ab24328833b8eb1ccc087fc0442a1c - languageName: node - linkType: hard - -"p-try@npm:^1.0.0": - version: 1.0.0 - resolution: "p-try@npm:1.0.0" - checksum: 3b5303f77eb7722144154288bfd96f799f8ff3e2b2b39330efe38db5dd359e4fb27012464cd85cb0a76e9b7edd1b443568cb3192c22e7cffc34989df0bafd605 - languageName: node - linkType: hard - -"parcel@npm:2.6.2": - version: 2.6.2 - resolution: "parcel@npm:2.6.2" - dependencies: - "@parcel/config-default": 2.6.2 - "@parcel/core": 2.6.2 - "@parcel/diagnostic": 2.6.2 - "@parcel/events": 2.6.2 - "@parcel/fs": 2.6.2 - "@parcel/logger": 2.6.2 - "@parcel/package-manager": 2.6.2 - "@parcel/reporter-cli": 2.6.2 - "@parcel/reporter-dev-server": 2.6.2 - "@parcel/utils": 2.6.2 - chalk: ^4.1.0 - commander: ^7.0.0 - get-port: ^4.2.0 - v8-compile-cache: ^2.0.0 - bin: - parcel: lib/bin.js - checksum: 4c0de2d27ac9df2568c053f36523d0a549ff0317de37d28e47815d432332e3b56382d4855a3cdb5a7a21bd1297ea3511b93568bbcc59187d21c2e7ba78e6ec23 - languageName: node - linkType: hard - -"parent-module@npm:^1.0.0": - version: 1.0.1 - resolution: "parent-module@npm:1.0.1" - dependencies: - callsites: ^3.0.0 - checksum: 6ba8b255145cae9470cf5551eb74be2d22281587af787a2626683a6c20fbb464978784661478dd2a3f1dad74d1e802d403e1b03c1a31fab310259eec8ac560ff - languageName: node - linkType: hard - -"parse-json@npm:^5.0.0": - version: 5.2.0 - resolution: "parse-json@npm:5.2.0" - dependencies: - "@babel/code-frame": ^7.0.0 - error-ex: ^1.3.1 - json-parse-even-better-errors: ^2.3.0 - lines-and-columns: ^1.1.6 - checksum: 62085b17d64da57f40f6afc2ac1f4d95def18c4323577e1eced571db75d9ab59b297d1d10582920f84b15985cbfc6b6d450ccbf317644cfa176f3ed982ad87e2 - languageName: node - linkType: hard - -"path-exists@npm:^3.0.0": - version: 3.0.0 - resolution: "path-exists@npm:3.0.0" - checksum: 96e92643aa34b4b28d0de1cd2eba52a1c5313a90c6542d03f62750d82480e20bfa62bc865d5cfc6165f5fcd5aeb0851043c40a39be5989646f223300021bae0a - languageName: node - linkType: hard - -"path-exists@npm:^4.0.0": - version: 4.0.0 - resolution: "path-exists@npm:4.0.0" - checksum: 505807199dfb7c50737b057dd8d351b82c033029ab94cb10a657609e00c1bc53b951cfdbccab8de04c5584d5eff31128ce6afd3db79281874a5ef2adbba55ed1 - languageName: node - linkType: hard - -"path-is-absolute@npm:^1.0.0": - version: 1.0.1 - resolution: "path-is-absolute@npm:1.0.1" - checksum: 060840f92cf8effa293bcc1bea81281bd7d363731d214cbe5c227df207c34cd727430f70c6037b5159c8a870b9157cba65e775446b0ab06fd5ecc7e54615a3b8 - languageName: node - linkType: hard - -"path-key@npm:^3.0.0, path-key@npm:^3.1.0": - version: 3.1.1 - resolution: "path-key@npm:3.1.1" - checksum: 55cd7a9dd4b343412a8386a743f9c746ef196e57c823d90ca3ab917f90ab9f13dd0ded27252ba49dbdfcab2b091d998bc446f6220cd3cea65db407502a740020 - languageName: node - linkType: hard - -"path-parse@npm:^1.0.7": - version: 1.0.7 - resolution: "path-parse@npm:1.0.7" - checksum: 49abf3d81115642938a8700ec580da6e830dde670be21893c62f4e10bd7dd4c3742ddc603fe24f898cba7eb0c6bc1777f8d9ac14185d34540c6d4d80cd9cae8a - languageName: node - linkType: hard - -"path-type@npm:^4.0.0": - version: 4.0.0 - resolution: "path-type@npm:4.0.0" - checksum: 5b1e2daa247062061325b8fdbfd1fb56dde0a448fb1455453276ea18c60685bdad23a445dc148cf87bc216be1573357509b7d4060494a6fd768c7efad833ee45 - languageName: node - linkType: hard - -"pathval@npm:^1.1.1": - version: 1.1.1 - resolution: "pathval@npm:1.1.1" - checksum: 090e3147716647fb7fb5b4b8c8e5b55e5d0a6086d085b6cd23f3d3c01fcf0ff56fd3cc22f2f4a033bd2e46ed55d61ed8379e123b42afe7d531a2a5fc8bb556d6 - languageName: node - linkType: hard - -"pend@npm:~1.2.0": - version: 1.2.0 - resolution: "pend@npm:1.2.0" - checksum: 6c72f5243303d9c60bd98e6446ba7d30ae29e3d56fdb6fae8767e8ba6386f33ee284c97efe3230a0d0217e2b1723b8ab490b1bbf34fcbb2180dbc8a9de47850d - languageName: node - linkType: hard - -"performance-now@npm:^2.1.0": - version: 2.1.0 - resolution: "performance-now@npm:2.1.0" - checksum: 534e641aa8f7cba160f0afec0599b6cecefbb516a2e837b512be0adbe6c1da5550e89c78059c7fabc5c9ffdf6627edabe23eb7c518c4500067a898fa65c2b550 - languageName: node - linkType: hard - -"picocolors@npm:^1.0.0": - version: 1.0.0 - resolution: "picocolors@npm:1.0.0" - checksum: a2e8092dd86c8396bdba9f2b5481032848525b3dc295ce9b57896f931e63fc16f79805144321f72976383fc249584672a75cc18d6777c6b757603f372f745981 - languageName: node - linkType: hard - -"picomatch@npm:^2.0.4, picomatch@npm:^2.2.1": - version: 2.3.1 - resolution: "picomatch@npm:2.3.1" - checksum: 050c865ce81119c4822c45d3c84f1ced46f93a0126febae20737bd05ca20589c564d6e9226977df859ed5e03dc73f02584a2b0faad36e896936238238b0446cf - languageName: node - linkType: hard - -"pify@npm:^2.2.0": - version: 2.3.0 - resolution: "pify@npm:2.3.0" - checksum: 9503aaeaf4577acc58642ad1d25c45c6d90288596238fb68f82811c08104c800e5a7870398e9f015d82b44ecbcbef3dc3d4251a1cbb582f6e5959fe09884b2ba - languageName: node - linkType: hard - -"pinia-plugin-persist@npm:1.0.0": - version: 1.0.0 - resolution: "pinia-plugin-persist@npm:1.0.0" - dependencies: - vue-demi: ^0.12.1 - peerDependencies: - "@vue/composition-api": ^1.0.0 - pinia: ^2.0.0 - vue: ^2.0.0 || >=3.0.0 - peerDependenciesMeta: - "@vue/composition-api": - optional: true - checksum: 49335d720751d00e990bdb4e0a8a90a67c617b4402a55c7427bfdb2f2b60bdb5a75745d94cc7aa227eb41248fb8ca5c607816d2d482878e3a0113b8cd32fdc2e - languageName: node - linkType: hard - -"pinia@npm:2.0.16": - version: 2.0.16 - resolution: "pinia@npm:2.0.16" - dependencies: - "@vue/devtools-api": ^6.1.4 - vue-demi: "*" - peerDependencies: - "@vue/composition-api": ^1.4.0 - typescript: ">=4.4.4" - vue: ^2.6.14 || ^3.2.0 - peerDependenciesMeta: - "@vue/composition-api": - optional: true - typescript: - optional: true - checksum: 226aaf57a8809848ec7f679999578308ad70b8939de6163af3ff62e91c2606a274fd8ab626af8071654d76316ff260fe3fc42a9725218bdbcd4b46b1a26e90d5 - languageName: node - linkType: hard - -"postcss-selector-parser@npm:^6.0.9": - version: 6.0.10 - resolution: "postcss-selector-parser@npm:6.0.10" - dependencies: - cssesc: ^3.0.0 - util-deprecate: ^1.0.2 - checksum: 46afaa60e3d1998bd7adf6caa374baf857cc58d3ff944e29459c9a9e4680a7fe41597bd5b755fc81d7c388357e9bf67c0251d047c640a09f148e13606b8a8608 - languageName: node - linkType: hard - -"postcss-value-parser@npm:^4.2.0": - version: 4.2.0 - resolution: "postcss-value-parser@npm:4.2.0" - checksum: 819ffab0c9d51cf0acbabf8996dffbfafbafa57afc0e4c98db88b67f2094cb44488758f06e5da95d7036f19556a4a732525e84289a425f4f6fd8e412a9d7442f - languageName: node - linkType: hard - -"postcss@npm:^8.1.10": - version: 8.4.12 - resolution: "postcss@npm:8.4.12" - dependencies: - nanoid: ^3.3.1 - picocolors: ^1.0.0 - source-map-js: ^1.0.2 - checksum: 248e3d0f9bbb8efaafcfda7f91627a29bdc9a19f456896886330beb28c5abea0e14c7901b35191928602e2eccbed496b1e94097d27a0b2a980854cd00c7a835f - languageName: node - linkType: hard - -"postcss@npm:^8.4.13, postcss@npm:^8.4.14": - version: 8.4.14 - resolution: "postcss@npm:8.4.14" - dependencies: - nanoid: ^3.3.4 - picocolors: ^1.0.0 - source-map-js: ^1.0.2 - checksum: fe58766ff32e4becf65a7d57678995cfd239df6deed2fe0557f038b47c94e4132e7e5f68b5aa820c13adfec32e523b693efaeb65798efb995ce49ccd83953816 - languageName: node - linkType: hard - -"posthtml-parser@npm:^0.10.1": - version: 0.10.2 - resolution: "posthtml-parser@npm:0.10.2" - dependencies: - htmlparser2: ^7.1.1 - checksum: 63ec8e8631031f7879cada68ad165436ad6142eedd6ed9cb19b28c87848985819d50104d73a182a5205e7083e93131b68196c13c32cea12c0e225c7400591432 - languageName: node - linkType: hard - -"posthtml-parser@npm:^0.11.0": - version: 0.11.0 - resolution: "posthtml-parser@npm:0.11.0" - dependencies: - htmlparser2: ^7.1.1 - checksum: 37dca546a04dc2ddc936a629596edccc9e439a7f6ad503dae5165ea197ddc53f102e69259719a49ecd491e01b093b95c96287c38101f985b78a846c05a206b3c - languageName: node - linkType: hard - -"posthtml-render@npm:^3.0.0": - version: 3.0.0 - resolution: "posthtml-render@npm:3.0.0" - dependencies: - is-json: ^2.0.1 - checksum: 5ed2d6e8813af63c4e5a2d9d026f611fd178c9052a16b302a6e0e81d1badb64dab36e3fc1531b5bdd376465f39d19a6488299b3c6dfe13beae3dd525ff856573 - languageName: node - linkType: hard - -"posthtml@npm:^0.16.4, posthtml@npm:^0.16.5": - version: 0.16.6 - resolution: "posthtml@npm:0.16.6" - dependencies: - posthtml-parser: ^0.11.0 - posthtml-render: ^3.0.0 - checksum: 8b9b9d27bd2417d6b5b7d408000b23316c3c4d2a2d0ea62080a8fbec5654cc7376ea9d6317b290c030d616142144a8ca0a96ffe1e919493e3eac17442d362596 - languageName: node - linkType: hard - -"preact@npm:^10.0.5": - version: 10.7.2 - resolution: "preact@npm:10.7.2" - checksum: 2f0655e0430f1c6927b40cb4abffb2c0ee4fe63e3201d44e37d0992c0ab534346f206cf23c0405572b70908e3eba2f7f60ab8e4531f409ebcbc35af06920cd60 - languageName: node - linkType: hard - -"prelude-ls@npm:^1.2.1": - version: 1.2.1 - resolution: "prelude-ls@npm:1.2.1" - checksum: cd192ec0d0a8e4c6da3bb80e4f62afe336df3f76271ac6deb0e6a36187133b6073a19e9727a1ff108cd8b9982e4768850d413baa71214dd80c7979617dca827a - languageName: node - linkType: hard - -"pretty-bytes@npm:^5.6.0": - version: 5.6.0 - resolution: "pretty-bytes@npm:5.6.0" - checksum: 9c082500d1e93434b5b291bd651662936b8bd6204ec9fa17d563116a192d6d86b98f6d328526b4e8d783c07d5499e2614a807520249692da9ec81564b2f439cd - languageName: node - linkType: hard - -"pretty-format@npm:^27.0.0, pretty-format@npm:^27.5.1": - version: 27.5.1 - resolution: "pretty-format@npm:27.5.1" - dependencies: - ansi-regex: ^5.0.1 - ansi-styles: ^5.0.0 - react-is: ^17.0.1 - checksum: cf610cffcb793885d16f184a62162f2dd0df31642d9a18edf4ca298e909a8fe80bdbf556d5c9573992c102ce8bf948691da91bf9739bee0ffb6e79c8a8a6e088 - languageName: node - linkType: hard - -"promise-inflight@npm:^1.0.1": - version: 1.0.1 - resolution: "promise-inflight@npm:1.0.1" - checksum: 22749483091d2c594261517f4f80e05226d4d5ecc1fc917e1886929da56e22b5718b7f2a75f3807e7a7d471bc3be2907fe92e6e8f373ddf5c64bae35b5af3981 - languageName: node - linkType: hard - -"promise-retry@npm:^2.0.1": - version: 2.0.1 - resolution: "promise-retry@npm:2.0.1" - dependencies: - err-code: ^2.0.2 - retry: ^0.12.0 - checksum: f96a3f6d90b92b568a26f71e966cbbc0f63ab85ea6ff6c81284dc869b41510e6cdef99b6b65f9030f0db422bf7c96652a3fff9f2e8fb4a0f069d8f4430359429 - languageName: node - linkType: hard - -"promise@npm:^7.0.1": - version: 7.3.1 - resolution: "promise@npm:7.3.1" - dependencies: - asap: ~2.0.3 - checksum: 475bb069130179fbd27ed2ab45f26d8862376a137a57314cf53310bdd85cc986a826fd585829be97ebc0aaf10e9d8e68be1bfe5a4a0364144b1f9eedfa940cf1 - languageName: node - linkType: hard - -"prompts@npm:^2.0.0": - version: 2.4.2 - resolution: "prompts@npm:2.4.2" - dependencies: - kleur: ^3.0.3 - sisteransi: ^1.0.5 - checksum: d8fd1fe63820be2412c13bfc5d0a01909acc1f0367e32396962e737cb2fc52d004f3302475d5ce7d18a1e8a79985f93ff04ee03007d091029c3f9104bffc007d - languageName: node - linkType: hard - -"proxy-from-env@npm:1.0.0": - version: 1.0.0 - resolution: "proxy-from-env@npm:1.0.0" - checksum: 292e28d1de0c315958d71d8315eb546dd3cd8c8cbc2dab7c54eeb9f5c17f421771964ad0b5e1f77011bab2305bdae42e1757ce33bdb1ccc3e87732322a8efcf1 - languageName: node - linkType: hard - -"psl@npm:^1.1.28": - version: 1.8.0 - resolution: "psl@npm:1.8.0" - checksum: 6150048ed2da3f919478bee8a82f3828303bc0fc730fb015a48f83c9977682c7b28c60ab01425a72d82a2891a1681627aa530a991d50c086b48a3be27744bde7 - languageName: node - linkType: hard - -"pug-attrs@npm:^3.0.0": - version: 3.0.0 - resolution: "pug-attrs@npm:3.0.0" - dependencies: - constantinople: ^4.0.1 - js-stringify: ^1.0.2 - pug-runtime: ^3.0.0 - checksum: 2ca2d34de3065239f01f0fc3c0e104c17f7a7105684d088bb71df623005a45f40a2301e65f49ec4581bb31794c74e691862643d4e34062d1509e92fa56a15aa5 - languageName: node - linkType: hard - -"pug-code-gen@npm:^3.0.2": - version: 3.0.2 - resolution: "pug-code-gen@npm:3.0.2" - dependencies: - constantinople: ^4.0.1 - doctypes: ^1.1.0 - js-stringify: ^1.0.2 - pug-attrs: ^3.0.0 - pug-error: ^2.0.0 - pug-runtime: ^3.0.0 - void-elements: ^3.1.0 - with: ^7.0.0 - checksum: 1644d3a4d673392794248749eb146299704639a8197746454b7d03b240b83ee102f25b76d203381501e283be3927ab01eb3f4563ff51c45a478de1f3435a400d - languageName: node - linkType: hard - -"pug-error@npm:^2.0.0": - version: 2.0.0 - resolution: "pug-error@npm:2.0.0" - checksum: c5372d018c897c1d6a141dd803c50957feecfda1f3d84a6adc6149801315d6c7f8c28b05f3e186d98d774fc9718699d1e1caa675630dd3c4453f8c5ec4e4a986 - languageName: node - linkType: hard - -"pug-filters@npm:^4.0.0": - version: 4.0.0 - resolution: "pug-filters@npm:4.0.0" - dependencies: - constantinople: ^4.0.1 - jstransformer: 1.0.0 - pug-error: ^2.0.0 - pug-walk: ^2.0.0 - resolve: ^1.15.1 - checksum: 44eb3273195e3f42f034ad81109452236377780557eaf5a28db6e478f297675e19b8598cca9de65a0ba9c1d57e2ca2a93e332f0ab4be79dc5dd042375228cdff - languageName: node - linkType: hard - -"pug-lexer@npm:^5.0.1": - version: 5.0.1 - resolution: "pug-lexer@npm:5.0.1" - dependencies: - character-parser: ^2.2.0 - is-expression: ^4.0.0 - pug-error: ^2.0.0 - checksum: afdd2f43f2c3ba96001a7b734c0c3bc745eb5d7dd68c787c2690c606d34573ca46ba807e4b4c7e70db9b4556fb938625dbb9c25b79cdb8857868e6deb2574d3e - languageName: node - linkType: hard - -"pug-linker@npm:^4.0.0": - version: 4.0.0 - resolution: "pug-linker@npm:4.0.0" - dependencies: - pug-error: ^2.0.0 - pug-walk: ^2.0.0 - checksum: 7433aa65181cd5b7bc631ab5f14baae7496fd8da98608cbd55bbea9bc72fe69a863e72026781a9fe76ab429d7037465b942145455420ee1178e2875ec87a1e12 - languageName: node - linkType: hard - -"pug-load@npm:^3.0.0": - version: 3.0.0 - resolution: "pug-load@npm:3.0.0" - dependencies: - object-assign: ^4.1.1 - pug-walk: ^2.0.0 - checksum: 1800ec51994c92338401bcf79bbfa0d5ef9aa312bc415c2618263d6c04d1d7c5be5ac4a333c47a0eaa823f6231b4ade1a1c40f5784b99eb576d25853597bff2f - languageName: node - linkType: hard - -"pug-parser@npm:^6.0.0": - version: 6.0.0 - resolution: "pug-parser@npm:6.0.0" - dependencies: - pug-error: ^2.0.0 - token-stream: 1.0.0 - checksum: a6954d1383601233ec9d58e8fb22339f4809cf938272db16c551d8574566f388af3bf5560ec95ad5e23902bc358e6fa857409e840de4ed1ff5120a1dd6892cca - languageName: node - linkType: hard - -"pug-runtime@npm:^3.0.0, pug-runtime@npm:^3.0.1": - version: 3.0.1 - resolution: "pug-runtime@npm:3.0.1" - checksum: 48a71b587caa08a5bccf9c1164206a34067edc1d13c2164bebad2dc562b529317578f889a0c41f0e16ddab3853c599696ff29a085f2d4554b783228f0002c41b - languageName: node - linkType: hard - -"pug-strip-comments@npm:^2.0.0": - version: 2.0.0 - resolution: "pug-strip-comments@npm:2.0.0" - dependencies: - pug-error: ^2.0.0 - checksum: 2cfcbf506c14bb3e64204a1d93f12ca61658d2540475b0f0911c35531ad28421e8d1e73a646d841d58cfa2c20f8593c52e492dfe5b6bec968e20b614e4dea1e4 - languageName: node - linkType: hard - -"pug-walk@npm:^2.0.0": - version: 2.0.0 - resolution: "pug-walk@npm:2.0.0" - checksum: bee64e133b711e1ed58022c0869b59e62f9f3ebb7084293857f074120b3cb588e7b8f74c4566426bf2b26dc1ec176ca6b64a2d1e53782f3fbbe039c5d4816638 - languageName: node - linkType: hard - -"pug@npm:3.0.2": - version: 3.0.2 - resolution: "pug@npm:3.0.2" - dependencies: - pug-code-gen: ^3.0.2 - pug-filters: ^4.0.0 - pug-lexer: ^5.0.1 - pug-linker: ^4.0.0 - pug-load: ^3.0.0 - pug-parser: ^6.0.0 - pug-runtime: ^3.0.1 - pug-strip-comments: ^2.0.0 - checksum: 3e1a3d48897c0c7dedd4f959ce8afaf6417a63756b149e1b5382bef16de5792ec7c7ae6a7d41641059cb149520f20b0d1ecf57014c0661526e96f0bad88541e5 - languageName: node - linkType: hard - -"pump@npm:^3.0.0": - version: 3.0.0 - resolution: "pump@npm:3.0.0" - dependencies: - end-of-stream: ^1.1.0 - once: ^1.3.1 - checksum: e42e9229fba14732593a718b04cb5e1cfef8254544870997e0ecd9732b189a48e1256e4e5478148ecb47c8511dca2b09eae56b4d0aad8009e6fac8072923cfc9 - languageName: node - linkType: hard - -"punycode@npm:^2.1.0, punycode@npm:^2.1.1": - version: 2.1.1 - resolution: "punycode@npm:2.1.1" - checksum: 823bf443c6dd14f669984dea25757b37993f67e8d94698996064035edd43bed8a5a17a9f12e439c2b35df1078c6bec05a6c86e336209eb1061e8025c481168e8 - languageName: node - linkType: hard - -"qs@npm:~6.5.2": - version: 6.5.3 - resolution: "qs@npm:6.5.3" - checksum: 6f20bf08cabd90c458e50855559539a28d00b2f2e7dddcb66082b16a43188418cb3cb77cbd09268bcef6022935650f0534357b8af9eeb29bf0f27ccb17655692 - languageName: node - linkType: hard - -"react-error-overlay@npm:6.0.9": - version: 6.0.9 - resolution: "react-error-overlay@npm:6.0.9" - checksum: 695853bc885e798008a00c10d8d94e5ac91626e8130802fea37345f9c037f41b80104345db2ee87f225feb4a4ef71b0df572b17c378a6d397b6815f6d4a84293 - languageName: node - linkType: hard - -"react-is@npm:^17.0.1": - version: 17.0.2 - resolution: "react-is@npm:17.0.2" - checksum: 9d6d111d8990dc98bc5402c1266a808b0459b5d54830bbea24c12d908b536df7883f268a7868cfaedde3dd9d4e0d574db456f84d2e6df9c4526f99bb4b5344d8 - languageName: node - linkType: hard - -"react-refresh@npm:^0.9.0": - version: 0.9.0 - resolution: "react-refresh@npm:0.9.0" - checksum: 6440146176f19402ffb7d66f317e40b1c42c88579b4d439b49021e38be6307c642da3e8732a72e6997b6bb1127db0da92f4aa433da4313ce8ebad0c1efa2ed4a - languageName: node - linkType: hard - -"readable-stream@npm:^3.6.0": - version: 3.6.0 - resolution: "readable-stream@npm:3.6.0" - dependencies: - inherits: ^2.0.3 - string_decoder: ^1.1.1 - util-deprecate: ^1.0.1 - checksum: d4ea81502d3799439bb955a3a5d1d808592cf3133350ed352aeaa499647858b27b1c4013984900238b0873ec8d0d8defce72469fb7a83e61d53f5ad61cb80dc8 - languageName: node - linkType: hard - -"readdirp@npm:~3.6.0": - version: 3.6.0 - resolution: "readdirp@npm:3.6.0" - dependencies: - picomatch: ^2.2.1 - checksum: 1ced032e6e45670b6d7352d71d21ce7edf7b9b928494dcaba6f11fba63180d9da6cd7061ebc34175ffda6ff529f481818c962952004d273178acd70f7059b320 - languageName: node - linkType: hard - -"regenerator-runtime@npm:^0.13.7": - version: 0.13.9 - resolution: "regenerator-runtime@npm:0.13.9" - checksum: 65ed455fe5afd799e2897baf691ca21c2772e1a969d19bb0c4695757c2d96249eb74ee3553ea34a91062b2a676beedf630b4c1551cc6299afb937be1426ec55e - languageName: node - linkType: hard - -"regexpp@npm:^3.0.0, regexpp@npm:^3.2.0": - version: 3.2.0 - resolution: "regexpp@npm:3.2.0" - checksum: a78dc5c7158ad9ddcfe01aa9144f46e192ddbfa7b263895a70a5c6c73edd9ce85faf7c0430e59ac38839e1734e275b9c3de5c57ee3ab6edc0e0b1bdebefccef8 - languageName: node - linkType: hard - -"request-progress@npm:^3.0.0": - version: 3.0.0 - resolution: "request-progress@npm:3.0.0" - dependencies: - throttleit: ^1.0.0 - checksum: 6ea1761dcc8a8b7b5894afd478c0286aa31bd69438d7050294bd4fd0d0b3e09b5cde417d38deef9c49809039c337d8744e4bb49d8632b0c3e4ffa5e8a687e0fd - languageName: node - linkType: hard - -"require-directory@npm:^2.1.1": - version: 2.1.1 - resolution: "require-directory@npm:2.1.1" - checksum: fb47e70bf0001fdeabdc0429d431863e9475e7e43ea5f94ad86503d918423c1543361cc5166d713eaa7029dd7a3d34775af04764bebff99ef413111a5af18c80 - languageName: node - linkType: hard - -"require-from-string@npm:^2.0.2": - version: 2.0.2 - resolution: "require-from-string@npm:2.0.2" - checksum: a03ef6895445f33a4015300c426699bc66b2b044ba7b670aa238610381b56d3f07c686251740d575e22f4c87531ba662d06937508f0f3c0f1ddc04db3130560b - languageName: node - linkType: hard - -"resolve-from@npm:^4.0.0": - version: 4.0.0 - resolution: "resolve-from@npm:4.0.0" - checksum: f4ba0b8494846a5066328ad33ef8ac173801a51739eb4d63408c847da9a2e1c1de1e6cbbf72699211f3d13f8fc1325648b169bd15eb7da35688e30a5fb0e4a7f - languageName: node - linkType: hard - -"resolve@npm:^1.10.1, resolve@npm:^1.15.1, resolve@npm:^1.20.0, resolve@npm:^1.22.0": - version: 1.22.0 - resolution: "resolve@npm:1.22.0" - dependencies: - is-core-module: ^2.8.1 - path-parse: ^1.0.7 - supports-preserve-symlinks-flag: ^1.0.0 - bin: - resolve: bin/resolve - checksum: a2d14cc437b3a23996f8c7367eee5c7cf8149c586b07ca2ae00e96581ce59455555a1190be9aa92154785cf9f2042646c200d0e00e0bbd2b8a995a93a0ed3e4e - languageName: node - linkType: hard - -"resolve@npm:^1.22.1": - version: 1.22.1 - resolution: "resolve@npm:1.22.1" - dependencies: - is-core-module: ^2.9.0 - path-parse: ^1.0.7 - supports-preserve-symlinks-flag: ^1.0.0 - bin: - resolve: bin/resolve - checksum: 07af5fc1e81aa1d866cbc9e9460fbb67318a10fa3c4deadc35c3ad8a898ee9a71a86a65e4755ac3195e0ea0cfbe201eb323ebe655ce90526fd61917313a34e4e - languageName: node - linkType: hard - -"resolve@patch:resolve@^1.10.1#~builtin, resolve@patch:resolve@^1.15.1#~builtin, resolve@patch:resolve@^1.20.0#~builtin, resolve@patch:resolve@^1.22.0#~builtin": - version: 1.22.0 - resolution: "resolve@patch:resolve@npm%3A1.22.0#~builtin::version=1.22.0&hash=07638b" - dependencies: - is-core-module: ^2.8.1 - path-parse: ^1.0.7 - supports-preserve-symlinks-flag: ^1.0.0 - bin: - resolve: bin/resolve - checksum: c79ecaea36c872ee4a79e3db0d3d4160b593f2ca16e031d8283735acd01715a203607e9ded3f91f68899c2937fa0d49390cddbe0fb2852629212f3cda283f4a7 - languageName: node - linkType: hard - -"resolve@patch:resolve@^1.22.1#~builtin": - version: 1.22.1 - resolution: "resolve@patch:resolve@npm%3A1.22.1#~builtin::version=1.22.1&hash=07638b" - dependencies: - is-core-module: ^2.9.0 - path-parse: ^1.0.7 - supports-preserve-symlinks-flag: ^1.0.0 - bin: - resolve: bin/resolve - checksum: 5656f4d0bedcf8eb52685c1abdf8fbe73a1603bb1160a24d716e27a57f6cecbe2432ff9c89c2bd57542c3a7b9d14b1882b73bfe2e9d7849c9a4c0b8b39f02b8b - languageName: node - linkType: hard - -"restore-cursor@npm:^3.1.0": - version: 3.1.0 - resolution: "restore-cursor@npm:3.1.0" - dependencies: - onetime: ^5.1.0 - signal-exit: ^3.0.2 - checksum: f877dd8741796b909f2a82454ec111afb84eb45890eb49ac947d87991379406b3b83ff9673a46012fca0d7844bb989f45cc5b788254cf1a39b6b5a9659de0630 - languageName: node - linkType: hard - -"retry@npm:^0.12.0": - version: 0.12.0 - resolution: "retry@npm:0.12.0" - checksum: 623bd7d2e5119467ba66202d733ec3c2e2e26568074923bc0585b6b99db14f357e79bdedb63cab56cec47491c4a0da7e6021a7465ca6dc4f481d3898fdd3158c - languageName: node - linkType: hard - -"rfdc@npm:^1.3.0": - version: 1.3.0 - resolution: "rfdc@npm:1.3.0" - checksum: fb2ba8512e43519983b4c61bd3fa77c0f410eff6bae68b08614437bc3f35f91362215f7b4a73cbda6f67330b5746ce07db5dd9850ad3edc91271ad6deea0df32 - languageName: node - linkType: hard - -"rimraf@npm:^3.0.0, rimraf@npm:^3.0.2": - version: 3.0.2 - resolution: "rimraf@npm:3.0.2" - dependencies: - glob: ^7.1.3 - bin: - rimraf: bin.js - checksum: 87f4164e396f0171b0a3386cc1877a817f572148ee13a7e113b238e48e8a9f2f31d009a92ec38a591ff1567d9662c6b67fd8818a2dbbaed74bc26a87a2a4a9a0 - languageName: node - linkType: hard - -"robust-predicates@npm:^3.0.0": - version: 3.0.1 - resolution: "robust-predicates@npm:3.0.1" - checksum: 45e9de2df4380da84a2a561d4fd54ea92194e878b93ed19d5e4bc90f4e834a13755e846c8516bab8360190309696f0564a0150386c52ef01f70f2b388449dac5 - languageName: node - linkType: hard - -"rollup@npm:^2.59.0": - version: 2.75.3 - resolution: "rollup@npm:2.75.3" - dependencies: - fsevents: ~2.3.2 - dependenciesMeta: - fsevents: - optional: true - bin: - rollup: dist/bin/rollup - checksum: ac33a2336df049f21dea64e4c9faee2551bddf2920944ea6214b2ed214f3861c9a4e1a8b7a32d2af6632f649a25a2bf4da8fad9f84f5093f2bf4d7e77933756b - languageName: node - linkType: hard - -"rollup@npm:^2.75.6": - version: 2.76.0 - resolution: "rollup@npm:2.76.0" - dependencies: - fsevents: ~2.3.2 - dependenciesMeta: - fsevents: - optional: true - bin: - rollup: dist/bin/rollup - checksum: 58293e1c63c11d4afcfcf619601d5c5136dd3d0c9d3bd6a0b6141fede32027edc1eb53873bbb9a9c1e95e86c67f6ad66185720031b6eadf325972174d1d8fbcb - languageName: node - linkType: hard - -"root-workspace-0b6124@workspace:.": - version: 0.0.0-use.local - resolution: "root-workspace-0b6124@workspace:." - dependencies: - "@fullcalendar/bootstrap5": 5.11.0 - "@fullcalendar/core": 5.11.0 - "@fullcalendar/daygrid": 5.11.0 - "@fullcalendar/interaction": 5.11.0 - "@fullcalendar/list": 5.11.0 - "@fullcalendar/luxon2": 5.11.0 - "@fullcalendar/timegrid": 5.11.0 - "@fullcalendar/vue3": 5.11.1 - "@parcel/transformer-sass": 2.6.2 - "@popperjs/core": 2.11.5 - "@vitejs/plugin-vue": 2.3.3 - "@vue/test-utils": 2.0.2 - bootstrap: 5.2.0 - bootstrap-icons: 1.9.1 - browser-fs-access: 0.31.0 - browserlist: latest - c8: 7.12.0 - caniuse-lite: 1.0.30001368 - cypress: 10.3.1 - cypress-real-events: 1.7.1 - d3: 7.6.1 - eslint: 8.20.0 - eslint-config-standard: 17.0.0 - eslint-plugin-cypress: 2.12.1 - eslint-plugin-import: 2.26.0 - eslint-plugin-node: 11.1.0 - eslint-plugin-promise: 6.0.0 - eslint-plugin-vue: 9.2.0 - file-saver: 2.0.5 - highcharts: 10.2.0 - html-validate: 7.1.2 - jquery: 3.6.0 - jquery-migrate: 3.4.0 - jquery-ui-dist: 1.13.1 - js-cookie: 3.0.1 - list.js: 2.3.1 - lodash: 4.17.21 - luxon: 3.0.1 - moment: 2.29.4 - moment-timezone: 0.5.34 - murmurhash-js: 1.0.0 - naive-ui: 2.31.0 - parcel: 2.6.2 - pinia: 2.0.16 - pinia-plugin-persist: 1.0.0 - pug: 3.0.2 - sass: 1.53.0 - select2: 4.1.0-rc.0 - select2-bootstrap-5-theme: 1.3.0 - slugify: 1.6.5 - sortablejs: 1.15.0 - vite: 2.9.14 - vitest: 0.18.1 - vue: 3.2.37 - vue-router: 4.1.2 - zxcvbn: 4.4.2 - languageName: unknown - linkType: soft - -"rw@npm:1": - version: 1.3.3 - resolution: "rw@npm:1.3.3" - checksum: c20d82421f5a71c86a13f76121b751553a99cd4a70ea27db86f9b23f33db941f3f06019c30f60d50c356d0bd674c8e74764ac146ea55e217c091bde6fba82aa3 - languageName: node - linkType: hard - -"rxjs@npm:^7.5.1": - version: 7.5.5 - resolution: "rxjs@npm:7.5.5" - dependencies: - tslib: ^2.1.0 - checksum: e034f60805210cce756dd2f49664a8108780b117cf5d0e2281506e9e6387f7b4f1532d974a8c8b09314fa7a16dd2f6cff3462072a5789672b5dcb45c4173f3c6 - languageName: node - linkType: hard - -"safe-buffer@npm:^5.0.1, safe-buffer@npm:^5.1.2, safe-buffer@npm:~5.2.0": - version: 5.2.1 - resolution: "safe-buffer@npm:5.2.1" - checksum: b99c4b41fdd67a6aaf280fcd05e9ffb0813654894223afb78a31f14a19ad220bba8aba1cb14eddce1fcfb037155fe6de4e861784eb434f7d11ed58d1e70dd491 - languageName: node - linkType: hard - -"safe-buffer@npm:~5.1.1": - version: 5.1.2 - resolution: "safe-buffer@npm:5.1.2" - checksum: f2f1f7943ca44a594893a852894055cf619c1fbcb611237fc39e461ae751187e7baf4dc391a72125e0ac4fb2d8c5c0b3c71529622e6a58f46b960211e704903c - languageName: node - linkType: hard - -"safer-buffer@npm:>= 2.1.2 < 3.0.0, safer-buffer@npm:^2.0.2, safer-buffer@npm:^2.1.0, safer-buffer@npm:~2.1.0": - version: 2.1.2 - resolution: "safer-buffer@npm:2.1.2" - checksum: cab8f25ae6f1434abee8d80023d7e72b598cf1327164ddab31003c51215526801e40b66c5e65d658a0af1e9d6478cadcb4c745f4bd6751f97d8644786c0978b0 - languageName: node - linkType: hard - -"sass@npm:1.53.0": - version: 1.53.0 - resolution: "sass@npm:1.53.0" - dependencies: - chokidar: ">=3.0.0 <4.0.0" - immutable: ^4.0.0 - source-map-js: ">=0.6.2 <2.0.0" - bin: - sass: sass.js - checksum: 4bcb0617d6a4d1f2c089a1cb5c32f65a9ee874b23559f2742fab07cf8478fb74ad20c0730cf9f93915d7dbfc258901f89970674228c3ac91c3883a0a62a0ddab - languageName: node - linkType: hard - -"sass@npm:^1.38.0": - version: 1.52.1 - resolution: "sass@npm:1.52.1" - dependencies: - chokidar: ">=3.0.0 <4.0.0" - immutable: ^4.0.0 - source-map-js: ">=0.6.2 <2.0.0" - bin: - sass: sass.js - checksum: a0508c88b149641202e8fb589f731e0cb09a15650128dfee6d0d1ee4a868cb57f1e71575535ccd72f54c5313b684a8beb208d293402ca8d32084ee1709d9f26d - languageName: node - linkType: hard - -"seemly@npm:^0.3.1": - version: 0.3.3 - resolution: "seemly@npm:0.3.3" - dependencies: - "@types/jest": ^27.0.1 - checksum: b6445553f8e7b19310a5ea0240c80981aa669a6826e1ddbd62449cb1119236913607f6874759247bb6de8e22f3db966b5a498b5e8ac7682e42035951125fbea4 - languageName: node - linkType: hard - -"seemly@npm:^0.3.4": - version: 0.3.4 - resolution: "seemly@npm:0.3.4" - dependencies: - "@types/jest": ^27.0.1 - checksum: 7b422b0d5184d217139a9cd68a1a7a96bd500c52f2d45665587002daba481b101a3d9773a06c009ec8bece355a06409eddc5a44fa664f076cec641897f622e25 - languageName: node - linkType: hard - -"select2-bootstrap-5-theme@npm:1.3.0": - version: 1.3.0 - resolution: "select2-bootstrap-5-theme@npm:1.3.0" - dependencies: - bootstrap: ^5.1.3 - checksum: 248a8698352109c33c462d4f08d1f6afd31d633a36c854a89b37719b6927d07b14f0909214db780ad779ae461bb6e48587fdb74f71f0ee6731981fb9aa668364 - languageName: node - linkType: hard - -"select2@npm:4.1.0-rc.0": - version: 4.1.0-rc.0 - resolution: "select2@npm:4.1.0-rc.0" - checksum: c27cefc3967d2082b2887869e8379f6e8e0ec2e02a268b7abbaec87fbda20abe4d62ac008b87a14f17bfa46dd27aa0b33ee793ed30142e3bc30ba408e208ad20 - languageName: node - linkType: hard - -"semver@npm:^5.7.0, semver@npm:^5.7.1": - version: 5.7.1 - resolution: "semver@npm:5.7.1" - bin: - semver: ./bin/semver - checksum: 57fd0acfd0bac382ee87cd52cd0aaa5af086a7dc8d60379dfe65fea491fb2489b6016400813930ecd61fd0952dae75c115287a1b16c234b1550887117744dfaf - languageName: node - linkType: hard - -"semver@npm:^6.0.0, semver@npm:^6.1.0, semver@npm:^6.3.0": - version: 6.3.0 - resolution: "semver@npm:6.3.0" - bin: - semver: ./bin/semver.js - checksum: 1b26ecf6db9e8292dd90df4e781d91875c0dcc1b1909e70f5d12959a23c7eebb8f01ea581c00783bbee72ceeaad9505797c381756326073850dc36ed284b21b9 - languageName: node - linkType: hard - -"semver@npm:^7.0.0, semver@npm:^7.3.2, semver@npm:^7.3.5, semver@npm:^7.3.6": - version: 7.3.7 - resolution: "semver@npm:7.3.7" - dependencies: - lru-cache: ^6.0.0 - bin: - semver: bin/semver.js - checksum: 2fa3e877568cd6ce769c75c211beaed1f9fce80b28338cadd9d0b6c40f2e2862bafd62c19a6cff42f3d54292b7c623277bcab8816a2b5521cf15210d43e75232 - languageName: node - linkType: hard - -"set-blocking@npm:^2.0.0": - version: 2.0.0 - resolution: "set-blocking@npm:2.0.0" - checksum: 6e65a05f7cf7ebdf8b7c75b101e18c0b7e3dff4940d480efed8aad3a36a4005140b660fa1d804cb8bce911cac290441dc728084a30504d3516ac2ff7ad607b02 - languageName: node - linkType: hard - -"shebang-command@npm:^2.0.0": - version: 2.0.0 - resolution: "shebang-command@npm:2.0.0" - dependencies: - shebang-regex: ^3.0.0 - checksum: 6b52fe87271c12968f6a054e60f6bde5f0f3d2db483a1e5c3e12d657c488a15474121a1d55cd958f6df026a54374ec38a4a963988c213b7570e1d51575cea7fa - languageName: node - linkType: hard - -"shebang-regex@npm:^3.0.0": - version: 3.0.0 - resolution: "shebang-regex@npm:3.0.0" - checksum: 1a2bcae50de99034fcd92ad4212d8e01eedf52c7ec7830eedcf886622804fe36884278f2be8be0ea5fde3fd1c23911643a4e0f726c8685b61871c8908af01222 - languageName: node - linkType: hard - -"side-channel@npm:^1.0.4": - version: 1.0.4 - resolution: "side-channel@npm:1.0.4" - dependencies: - call-bind: ^1.0.0 - get-intrinsic: ^1.0.2 - object-inspect: ^1.9.0 - checksum: 351e41b947079c10bd0858364f32bb3a7379514c399edb64ab3dce683933483fc63fb5e4efe0a15a2e8a7e3c436b6a91736ddb8d8c6591b0460a24bb4a1ee245 - languageName: node - linkType: hard - -"signal-exit@npm:^3.0.2, signal-exit@npm:^3.0.7": - version: 3.0.7 - resolution: "signal-exit@npm:3.0.7" - checksum: a2f098f247adc367dffc27845853e9959b9e88b01cb301658cfe4194352d8d2bb32e18467c786a7fe15f1d44b233ea35633d076d5e737870b7139949d1ab6318 - languageName: node - linkType: hard - -"sisteransi@npm:^1.0.5": - version: 1.0.5 - resolution: "sisteransi@npm:1.0.5" - checksum: aba6438f46d2bfcef94cf112c835ab395172c75f67453fe05c340c770d3c402363018ae1ab4172a1026a90c47eaccf3af7b6ff6fa749a680c2929bd7fa2b37a4 - languageName: node - linkType: hard - -"slice-ansi@npm:^3.0.0": - version: 3.0.0 - resolution: "slice-ansi@npm:3.0.0" - dependencies: - ansi-styles: ^4.0.0 - astral-regex: ^2.0.0 - is-fullwidth-code-point: ^3.0.0 - checksum: 5ec6d022d12e016347e9e3e98a7eb2a592213a43a65f1b61b74d2c78288da0aded781f665807a9f3876b9daa9ad94f64f77d7633a0458876c3a4fdc4eb223f24 - languageName: node - linkType: hard - -"slice-ansi@npm:^4.0.0": - version: 4.0.0 - resolution: "slice-ansi@npm:4.0.0" - dependencies: - ansi-styles: ^4.0.0 - astral-regex: ^2.0.0 - is-fullwidth-code-point: ^3.0.0 - checksum: 4a82d7f085b0e1b070e004941ada3c40d3818563ac44766cca4ceadd2080427d337554f9f99a13aaeb3b4a94d9964d9466c807b3d7b7541d1ec37ee32d308756 - languageName: node - linkType: hard - -"slugify@npm:1.6.5": - version: 1.6.5 - resolution: "slugify@npm:1.6.5" - checksum: a955a1b600201030f4c1daa9bb74a17d4402a0693fc40978bbd17e44e64fd72dad3bac4037422aa8aed55b5170edd57f3f4cd8f59ba331f5cf0f10f1a7795609 - languageName: node - linkType: hard - -"smart-buffer@npm:^4.2.0": - version: 4.2.0 - resolution: "smart-buffer@npm:4.2.0" - checksum: b5167a7142c1da704c0e3af85c402002b597081dd9575031a90b4f229ca5678e9a36e8a374f1814c8156a725d17008ae3bde63b92f9cfd132526379e580bec8b - languageName: node - linkType: hard - -"socks-proxy-agent@npm:^6.1.1": - version: 6.2.0 - resolution: "socks-proxy-agent@npm:6.2.0" - dependencies: - agent-base: ^6.0.2 - debug: ^4.3.3 - socks: ^2.6.2 - checksum: 6723fd64fb50334e2b340fd0a80fd8488ffc5bc43d85b7cf1d25612044f814dd7d6ea417fd47602159941236f7f4bd15669fa5d7e1f852598a31288e1a43967b - languageName: node - linkType: hard - -"socks@npm:^2.6.2": - version: 2.6.2 - resolution: "socks@npm:2.6.2" - dependencies: - ip: ^1.1.5 - smart-buffer: ^4.2.0 - checksum: dd9194293059d737759d5c69273850ad4149f448426249325c4bea0e340d1cf3d266c3b022694b0dcf5d31f759de23657244c481fc1e8322add80b7985c36b5e - languageName: node - linkType: hard - -"sortablejs@npm:1.15.0": - version: 1.15.0 - resolution: "sortablejs@npm:1.15.0" - checksum: bb82223a663484640d317cad510ac987f26b7a443631040407224de1be069afcc6c39048b6d8527f10f269e33595e8128d7de2fac23517c8260470f77f932d55 - languageName: node - linkType: hard - -"source-map-js@npm:>=0.6.2 <2.0.0, source-map-js@npm:^1.0.2": - version: 1.0.2 - resolution: "source-map-js@npm:1.0.2" - checksum: c049a7fc4deb9a7e9b481ae3d424cc793cb4845daa690bc5a05d428bf41bf231ced49b4cf0c9e77f9d42fdb3d20d6187619fc586605f5eabe995a316da8d377c - languageName: node - linkType: hard - -"source-map-support@npm:~0.5.20": - version: 0.5.21 - resolution: "source-map-support@npm:0.5.21" - dependencies: - buffer-from: ^1.0.0 - source-map: ^0.6.0 - checksum: 43e98d700d79af1d36f859bdb7318e601dfc918c7ba2e98456118ebc4c4872b327773e5a1df09b0524e9e5063bb18f0934538eace60cca2710d1fa687645d137 - languageName: node - linkType: hard - -"source-map@npm:^0.6.0, source-map@npm:^0.6.1": - version: 0.6.1 - resolution: "source-map@npm:0.6.1" - checksum: 59ce8640cf3f3124f64ac289012c2b8bd377c238e316fb323ea22fbfe83da07d81e000071d7242cad7a23cd91c7de98e4df8830ec3f133cb6133a5f6e9f67bc2 - languageName: node - linkType: hard - -"source-map@npm:~0.8.0-beta.0": - version: 0.8.0-beta.0 - resolution: "source-map@npm:0.8.0-beta.0" - dependencies: - whatwg-url: ^7.0.0 - checksum: e94169be6461ab0ac0913313ad1719a14c60d402bd22b0ad96f4a6cffd79130d91ab5df0a5336a326b04d2df131c1409f563c9dc0d21a6ca6239a44b6c8dbd92 - languageName: node - linkType: hard - -"sourcemap-codec@npm:^1.4.8": - version: 1.4.8 - resolution: "sourcemap-codec@npm:1.4.8" - checksum: b57981c05611afef31605732b598ccf65124a9fcb03b833532659ac4d29ac0f7bfacbc0d6c5a28a03e84c7510e7e556d758d0bb57786e214660016fb94279316 - languageName: node - linkType: hard - -"sshpk@npm:^1.14.1": - version: 1.17.0 - resolution: "sshpk@npm:1.17.0" - dependencies: - asn1: ~0.2.3 - assert-plus: ^1.0.0 - bcrypt-pbkdf: ^1.0.0 - dashdash: ^1.12.0 - ecc-jsbn: ~0.1.1 - getpass: ^0.1.1 - jsbn: ~0.1.0 - safer-buffer: ^2.0.2 - tweetnacl: ~0.14.0 - bin: - sshpk-conv: bin/sshpk-conv - sshpk-sign: bin/sshpk-sign - sshpk-verify: bin/sshpk-verify - checksum: ba109f65c8e6c35133b8e6ed5576abeff8aa8d614824b7275ec3ca308f081fef483607c28d97780c1e235818b0f93ed8c8b56d0a5968d5a23fd6af57718c7597 - languageName: node - linkType: hard - -"ssri@npm:^9.0.0": - version: 9.0.1 - resolution: "ssri@npm:9.0.1" - dependencies: - minipass: ^3.1.1 - checksum: fb58f5e46b6923ae67b87ad5ef1c5ab6d427a17db0bead84570c2df3cd50b4ceb880ebdba2d60726588272890bae842a744e1ecce5bd2a2a582fccd5068309eb - languageName: node - linkType: hard - -"stable@npm:^0.1.8": - version: 0.1.8 - resolution: "stable@npm:0.1.8" - checksum: 2ff482bb100285d16dd75cd8f7c60ab652570e8952c0bfa91828a2b5f646a0ff533f14596ea4eabd48bb7f4aeea408dce8f8515812b975d958a4cc4fa6b9dfeb - languageName: node - linkType: hard - -"string-natural-compare@npm:^2.0.2": - version: 2.0.3 - resolution: "string-natural-compare@npm:2.0.3" - checksum: e0f22bb0de432f60e2e33f2b10d2fa9dce557cf982337a1475a136cf250535135912ad066c25341fb56d7047ba175bfa76a2351ddabd79089dc9528ca247ff19 - languageName: node - linkType: hard - -"string-width@npm:^1.0.2 || 2 || 3 || 4, string-width@npm:^4.1.0, string-width@npm:^4.2.0, string-width@npm:^4.2.3": - version: 4.2.3 - resolution: "string-width@npm:4.2.3" - dependencies: - emoji-regex: ^8.0.0 - is-fullwidth-code-point: ^3.0.0 - strip-ansi: ^6.0.1 - checksum: e52c10dc3fbfcd6c3a15f159f54a90024241d0f149cf8aed2982a2d801d2e64df0bf1dc351cf8e95c3319323f9f220c16e740b06faecd53e2462df1d2b5443fb - languageName: node - linkType: hard - -"string.prototype.trimend@npm:^1.0.4": - version: 1.0.4 - resolution: "string.prototype.trimend@npm:1.0.4" - dependencies: - call-bind: ^1.0.2 - define-properties: ^1.1.3 - checksum: 17e5aa45c3983f582693161f972c1c1fa4bbbdf22e70e582b00c91b6575f01680dc34e83005b98e31abe4d5d29e0b21fcc24690239c106c7b2315aade6a898ac - languageName: node - linkType: hard - -"string.prototype.trimstart@npm:^1.0.4": - version: 1.0.4 - resolution: "string.prototype.trimstart@npm:1.0.4" - dependencies: - call-bind: ^1.0.2 - define-properties: ^1.1.3 - checksum: 3fb06818d3cccac5fa3f5f9873d984794ca0e9f6616fae6fcc745885d9efed4e17fe15f832515d9af5e16c279857fdbffdfc489ca4ed577811b017721b30302f - languageName: node - linkType: hard - -"string_decoder@npm:^1.1.1": - version: 1.3.0 - resolution: "string_decoder@npm:1.3.0" - dependencies: - safe-buffer: ~5.2.0 - checksum: 8417646695a66e73aefc4420eb3b84cc9ffd89572861fe004e6aeb13c7bc00e2f616247505d2dbbef24247c372f70268f594af7126f43548565c68c117bdeb56 - languageName: node - linkType: hard - -"strip-ansi@npm:^6.0.0, strip-ansi@npm:^6.0.1": - version: 6.0.1 - resolution: "strip-ansi@npm:6.0.1" - dependencies: - ansi-regex: ^5.0.1 - checksum: f3cd25890aef3ba6e1a74e20896c21a46f482e93df4a06567cebf2b57edabb15133f1f94e57434e0a958d61186087b1008e89c94875d019910a213181a14fc8c - languageName: node - linkType: hard - -"strip-bom@npm:^3.0.0": - version: 3.0.0 - resolution: "strip-bom@npm:3.0.0" - checksum: 8d50ff27b7ebe5ecc78f1fe1e00fcdff7af014e73cf724b46fb81ef889eeb1015fc5184b64e81a2efe002180f3ba431bdd77e300da5c6685d702780fbf0c8d5b - languageName: node - linkType: hard - -"strip-final-newline@npm:^2.0.0": - version: 2.0.0 - resolution: "strip-final-newline@npm:2.0.0" - checksum: 69412b5e25731e1938184b5d489c32e340605bb611d6140344abc3421b7f3c6f9984b21dff296dfcf056681b82caa3bb4cc996a965ce37bcfad663e92eae9c64 - languageName: node - linkType: hard - -"strip-json-comments@npm:^3.1.0, strip-json-comments@npm:^3.1.1": - version: 3.1.1 - resolution: "strip-json-comments@npm:3.1.1" - checksum: 492f73e27268f9b1c122733f28ecb0e7e8d8a531a6662efbd08e22cccb3f9475e90a1b82cab06a392f6afae6d2de636f977e231296400d0ec5304ba70f166443 - languageName: node - linkType: hard - -"supports-color@npm:^5.3.0": - version: 5.5.0 - resolution: "supports-color@npm:5.5.0" - dependencies: - has-flag: ^3.0.0 - checksum: 95f6f4ba5afdf92f495b5a912d4abee8dcba766ae719b975c56c084f5004845f6f5a5f7769f52d53f40e21952a6d87411bafe34af4a01e65f9926002e38e1dac - languageName: node - linkType: hard - -"supports-color@npm:^7.1.0": - version: 7.2.0 - resolution: "supports-color@npm:7.2.0" - dependencies: - has-flag: ^4.0.0 - checksum: 3dda818de06ebbe5b9653e07842d9479f3555ebc77e9a0280caf5a14fb877ffee9ed57007c3b78f5a6324b8dbeec648d9e97a24e2ed9fdb81ddc69ea07100f4a - languageName: node - linkType: hard - -"supports-color@npm:^8.1.1": - version: 8.1.1 - resolution: "supports-color@npm:8.1.1" - dependencies: - has-flag: ^4.0.0 - checksum: c052193a7e43c6cdc741eb7f378df605636e01ad434badf7324f17fb60c69a880d8d8fcdcb562cf94c2350e57b937d7425ab5b8326c67c2adc48f7c87c1db406 - languageName: node - linkType: hard - -"supports-preserve-symlinks-flag@npm:^1.0.0": - version: 1.0.0 - resolution: "supports-preserve-symlinks-flag@npm:1.0.0" - checksum: 53b1e247e68e05db7b3808b99b892bd36fb096e6fba213a06da7fab22045e97597db425c724f2bbd6c99a3c295e1e73f3e4de78592289f38431049e1277ca0ae - languageName: node - linkType: hard - -"svgo@npm:^2.4.0": - version: 2.8.0 - resolution: "svgo@npm:2.8.0" - dependencies: - "@trysound/sax": 0.2.0 - commander: ^7.2.0 - css-select: ^4.1.3 - css-tree: ^1.1.3 - csso: ^4.2.0 - picocolors: ^1.0.0 - stable: ^0.1.8 - bin: - svgo: bin/svgo - checksum: b92f71a8541468ffd0b81b8cdb36b1e242eea320bf3c1a9b2c8809945853e9d8c80c19744267eb91cabf06ae9d5fff3592d677df85a31be4ed59ff78534fa420 - languageName: node - linkType: hard - -"tar@npm:^6.1.11, tar@npm:^6.1.2": - version: 6.1.11 - resolution: "tar@npm:6.1.11" - dependencies: - chownr: ^2.0.0 - fs-minipass: ^2.0.0 - minipass: ^3.0.0 - minizlib: ^2.1.1 - mkdirp: ^1.0.3 - yallist: ^4.0.0 - checksum: a04c07bb9e2d8f46776517d4618f2406fb977a74d914ad98b264fc3db0fe8224da5bec11e5f8902c5b9bcb8ace22d95fbe3c7b36b8593b7dfc8391a25898f32f - languageName: node - linkType: hard - -"term-size@npm:^2.2.1": - version: 2.2.1 - resolution: "term-size@npm:2.2.1" - checksum: 1ed981335483babc1e8206f843e06bd2bf89b85f0bf5a9a9d928033a0fcacdba183c03ba7d91814643015543ba002f1339f7112402a21da8f24b6c56b062a5a9 - languageName: node - linkType: hard - -"terser@npm:^5.2.0": - version: 5.13.1 - resolution: "terser@npm:5.13.1" - dependencies: - acorn: ^8.5.0 - commander: ^2.20.0 - source-map: ~0.8.0-beta.0 - source-map-support: ~0.5.20 - bin: - terser: bin/terser - checksum: 0b1f5043cf5c3973005fe2ae4ff3be82511c336a6430599dacd4e2acf77c974d4474b0f1eec4823977c1f33823147e736ff712ca8e098bee3db25946480fa29d - languageName: node - linkType: hard - -"test-exclude@npm:^6.0.0": - version: 6.0.0 - resolution: "test-exclude@npm:6.0.0" - dependencies: - "@istanbuljs/schema": ^0.1.2 - glob: ^7.1.4 - minimatch: ^3.0.4 - checksum: 3b34a3d77165a2cb82b34014b3aba93b1c4637a5011807557dc2f3da826c59975a5ccad765721c4648b39817e3472789f9b0fa98fc854c5c1c7a1e632aacdc28 - languageName: node - linkType: hard - -"text-table@npm:^0.2.0": - version: 0.2.0 - resolution: "text-table@npm:0.2.0" - checksum: b6937a38c80c7f84d9c11dd75e49d5c44f71d95e810a3250bd1f1797fc7117c57698204adf676b71497acc205d769d65c16ae8fa10afad832ae1322630aef10a - languageName: node - linkType: hard - -"throttleit@npm:^1.0.0": - version: 1.0.0 - resolution: "throttleit@npm:1.0.0" - checksum: 1b2db4d2454202d589e8236c07a69d2fab838876d370030ebea237c34c0a7d1d9cf11c29f994531ebb00efd31e9728291042b7754f2798a8352ec4463455b659 - languageName: node - linkType: hard - -"through@npm:^2.3.8": - version: 2.3.8 - resolution: "through@npm:2.3.8" - checksum: a38c3e059853c494af95d50c072b83f8b676a9ba2818dcc5b108ef252230735c54e0185437618596c790bbba8fcdaef5b290405981ffa09dce67b1f1bf190cbd - languageName: node - linkType: hard - -"timsort@npm:^0.3.0": - version: 0.3.0 - resolution: "timsort@npm:0.3.0" - checksum: 1a66cb897dacabd7dd7c91b7e2301498ca9e224de2edb9e42d19f5b17c4b6dc62a8d4cbc64f28be82aaf1541cb5a78ab49aa818f42a2989ebe049a64af731e2a - languageName: node - linkType: hard - -"tinypool@npm:^0.2.4": - version: 0.2.4 - resolution: "tinypool@npm:0.2.4" - checksum: f050bd36c89529a2a0d3f9c1fdbba3f317114e3ee6eb5d5ba72c51e887d45ef3ef8d8533fb2ca2eba7189d19d2231712b81b3a75e099248532f5563369929c33 - languageName: node - linkType: hard - -"tinyspy@npm:^1.0.0": - version: 1.0.0 - resolution: "tinyspy@npm:1.0.0" - checksum: f9a7cea406db9b0f99a4ef162eb0a45d88fc36facbc309702c8d568283baa363ab3c4138d8402fbfdef7a8d3157ff7cfae3e99ec6c75d8f684bd7b23485b5ec5 - languageName: node - linkType: hard - -"tmp@npm:~0.2.1": - version: 0.2.1 - resolution: "tmp@npm:0.2.1" - dependencies: - rimraf: ^3.0.0 - checksum: 8b1214654182575124498c87ca986ac53dc76ff36e8f0e0b67139a8d221eaecfdec108c0e6ec54d76f49f1f72ab9325500b246f562b926f85bcdfca8bf35df9e - languageName: node - linkType: hard - -"to-fast-properties@npm:^2.0.0": - version: 2.0.0 - resolution: "to-fast-properties@npm:2.0.0" - checksum: be2de62fe58ead94e3e592680052683b1ec986c72d589e7b21e5697f8744cdbf48c266fa72f6c15932894c10187b5f54573a3bcf7da0bfd964d5caf23d436168 - languageName: node - linkType: hard - -"to-regex-range@npm:^5.0.1": - version: 5.0.1 - resolution: "to-regex-range@npm:5.0.1" - dependencies: - is-number: ^7.0.0 - checksum: f76fa01b3d5be85db6a2a143e24df9f60dd047d151062d0ba3df62953f2f697b16fe5dad9b0ac6191c7efc7b1d9dcaa4b768174b7b29da89d4428e64bc0a20ed - languageName: node - linkType: hard - -"token-stream@npm:1.0.0": - version: 1.0.0 - resolution: "token-stream@npm:1.0.0" - checksum: e8adb56f31b813b6157130e7fc2fe14eb60e7cbf7b746e70e8293c7e55664d8e7ad5d93d7ae3aa4cad7fcb2b0aaf59dad6f2fd4ee0269204e55af5b05bc369e2 - languageName: node - linkType: hard - -"tough-cookie@npm:~2.5.0": - version: 2.5.0 - resolution: "tough-cookie@npm:2.5.0" - dependencies: - psl: ^1.1.28 - punycode: ^2.1.1 - checksum: 16a8cd090224dd176eee23837cbe7573ca0fa297d7e468ab5e1c02d49a4e9a97bb05fef11320605eac516f91d54c57838a25864e8680e27b069a5231d8264977 - languageName: node - linkType: hard - -"tr46@npm:^1.0.1": - version: 1.0.1 - resolution: "tr46@npm:1.0.1" - dependencies: - punycode: ^2.1.0 - checksum: 96d4ed46bc161db75dbf9247a236ea0bfcaf5758baae6749e92afab0bc5a09cb59af21788ede7e55080f2bf02dce3e4a8f2a484cc45164e29f4b5e68f7cbcc1a - languageName: node - linkType: hard - -"treemate@npm:^0.3.11": - version: 0.3.11 - resolution: "treemate@npm:0.3.11" - checksum: 0c6ccbc6c5ce7faf27f5f48669c4734aa93ba4064a77f1324af02779aab6333986f6b32748aafe8de1ba99da8f8d9a027fe9c7c1d5389b4768edb5fc6a77fca2 - languageName: node - linkType: hard - -"tsconfig-paths@npm:^3.14.1": - version: 3.14.1 - resolution: "tsconfig-paths@npm:3.14.1" - dependencies: - "@types/json5": ^0.0.29 - json5: ^1.0.1 - minimist: ^1.2.6 - strip-bom: ^3.0.0 - checksum: 8afa01c673ebb4782ba53d3a12df97fa837ce524f8ad38ee4e2b2fd57f5ac79abc21c574e9e9eb014d93efe7fe8214001b96233b5c6ea75bd1ea82afe17a4c6d - languageName: node - linkType: hard - -"tslib@npm:^2.1.0, tslib@npm:^2.4.0": - version: 2.4.0 - resolution: "tslib@npm:2.4.0" - checksum: 8c4aa6a3c5a754bf76aefc38026134180c053b7bd2f81338cb5e5ebf96fefa0f417bff221592bf801077f5bf990562f6264fecbc42cd3309b33872cb6fc3b113 - languageName: node - linkType: hard - -"tunnel-agent@npm:^0.6.0": - version: 0.6.0 - resolution: "tunnel-agent@npm:0.6.0" - dependencies: - safe-buffer: ^5.0.1 - checksum: 05f6510358f8afc62a057b8b692f05d70c1782b70db86d6a1e0d5e28a32389e52fa6e7707b6c5ecccacc031462e4bc35af85ecfe4bbc341767917b7cf6965711 - languageName: node - linkType: hard - -"tweetnacl@npm:^0.14.3, tweetnacl@npm:~0.14.0": - version: 0.14.5 - resolution: "tweetnacl@npm:0.14.5" - checksum: 6061daba1724f59473d99a7bb82e13f211cdf6e31315510ae9656fefd4779851cb927adad90f3b488c8ed77c106adc0421ea8055f6f976ff21b27c5c4e918487 - languageName: node - linkType: hard - -"type-check@npm:^0.4.0, type-check@npm:~0.4.0": - version: 0.4.0 - resolution: "type-check@npm:0.4.0" - dependencies: - prelude-ls: ^1.2.1 - checksum: ec688ebfc9c45d0c30412e41ca9c0cdbd704580eb3a9ccf07b9b576094d7b86a012baebc95681999dd38f4f444afd28504cb3a89f2ef16b31d4ab61a0739025a - languageName: node - linkType: hard - -"type-detect@npm:^4.0.0, type-detect@npm:^4.0.5": - version: 4.0.8 - resolution: "type-detect@npm:4.0.8" - checksum: 62b5628bff67c0eb0b66afa371bd73e230399a8d2ad30d852716efcc4656a7516904570cd8631a49a3ce57c10225adf5d0cbdcb47f6b0255fe6557c453925a15 - languageName: node - linkType: hard - -"type-fest@npm:^0.20.2": - version: 0.20.2 - resolution: "type-fest@npm:0.20.2" - checksum: 4fb3272df21ad1c552486f8a2f8e115c09a521ad7a8db3d56d53718d0c907b62c6e9141ba5f584af3f6830d0872c521357e512381f24f7c44acae583ad517d73 - languageName: node - linkType: hard - -"type-fest@npm:^0.21.3": - version: 0.21.3 - resolution: "type-fest@npm:0.21.3" - checksum: e6b32a3b3877f04339bae01c193b273c62ba7bfc9e325b8703c4ee1b32dc8fe4ef5dfa54bf78265e069f7667d058e360ae0f37be5af9f153b22382cd55a9afe0 - languageName: node - linkType: hard - -"unbox-primitive@npm:^1.0.1": - version: 1.0.2 - resolution: "unbox-primitive@npm:1.0.2" - dependencies: - call-bind: ^1.0.2 - has-bigints: ^1.0.2 - has-symbols: ^1.0.3 - which-boxed-primitive: ^1.0.2 - checksum: b7a1cf5862b5e4b5deb091672ffa579aa274f648410009c81cca63fed3b62b610c4f3b773f912ce545bb4e31edc3138975b5bc777fc6e4817dca51affb6380e9 - languageName: node - linkType: hard - -"unique-filename@npm:^1.1.1": - version: 1.1.1 - resolution: "unique-filename@npm:1.1.1" - dependencies: - unique-slug: ^2.0.0 - checksum: cf4998c9228cc7647ba7814e255dec51be43673903897b1786eff2ac2d670f54d4d733357eb08dea969aa5e6875d0e1bd391d668fbdb5a179744e7c7551a6f80 - languageName: node - linkType: hard - -"unique-slug@npm:^2.0.0": - version: 2.0.2 - resolution: "unique-slug@npm:2.0.2" - dependencies: - imurmurhash: ^0.1.4 - checksum: 5b6876a645da08d505dedb970d1571f6cebdf87044cb6b740c8dbb24f0d6e1dc8bdbf46825fd09f994d7cf50760e6f6e063cfa197d51c5902c00a861702eb75a - languageName: node - linkType: hard - -"universalify@npm:^2.0.0": - version: 2.0.0 - resolution: "universalify@npm:2.0.0" - checksum: 2406a4edf4a8830aa6813278bab1f953a8e40f2f63a37873ffa9a3bc8f9745d06cc8e88f3572cb899b7e509013f7f6fcc3e37e8a6d914167a5381d8440518c44 - languageName: node - linkType: hard - -"untildify@npm:^4.0.0": - version: 4.0.0 - resolution: "untildify@npm:4.0.0" - checksum: 39ced9c418a74f73f0a56e1ba4634b4d959422dff61f4c72a8e39f60b99380c1b45ed776fbaa0a4101b157e4310d873ad7d114e8534ca02609b4916bb4187fb9 - languageName: node - linkType: hard - -"uri-js@npm:^4.2.2": - version: 4.4.1 - resolution: "uri-js@npm:4.4.1" - dependencies: - punycode: ^2.1.0 - checksum: 7167432de6817fe8e9e0c9684f1d2de2bb688c94388f7569f7dbdb1587c9f4ca2a77962f134ec90be0cc4d004c939ff0d05acc9f34a0db39a3c797dada262633 - languageName: node - linkType: hard - -"util-deprecate@npm:^1.0.1, util-deprecate@npm:^1.0.2": - version: 1.0.2 - resolution: "util-deprecate@npm:1.0.2" - checksum: 474acf1146cb2701fe3b074892217553dfcf9a031280919ba1b8d651a068c9b15d863b7303cb15bd00a862b498e6cf4ad7b4a08fb134edd5a6f7641681cb54a2 - languageName: node - linkType: hard - -"utility-types@npm:^3.10.0": - version: 3.10.0 - resolution: "utility-types@npm:3.10.0" - checksum: 8f274415c6196ab62883b8bd98c9d2f8829b58016e4269aaa1ebd84184ac5dda7dc2ca45800c0d5e0e0650966ba063bf9a412aaeaea6850ca4440a391283d5c8 - languageName: node - linkType: hard - -"uuid@npm:^8.3.2": - version: 8.3.2 - resolution: "uuid@npm:8.3.2" - bin: - uuid: dist/bin/uuid - checksum: 5575a8a75c13120e2f10e6ddc801b2c7ed7d8f3c8ac22c7ed0c7b2ba6383ec0abda88c905085d630e251719e0777045ae3236f04c812184b7c765f63a70e58df - languageName: node - linkType: hard - -"v8-compile-cache@npm:^2.0.0, v8-compile-cache@npm:^2.0.3": - version: 2.3.0 - resolution: "v8-compile-cache@npm:2.3.0" - checksum: adb0a271eaa2297f2f4c536acbfee872d0dd26ec2d76f66921aa7fc437319132773483344207bdbeee169225f4739016d8d2dbf0553913a52bb34da6d0334f8e - languageName: node - linkType: hard - -"v8-to-istanbul@npm:^9.0.0": - version: 9.0.1 - resolution: "v8-to-istanbul@npm:9.0.1" - dependencies: - "@jridgewell/trace-mapping": ^0.3.12 - "@types/istanbul-lib-coverage": ^2.0.1 - convert-source-map: ^1.6.0 - checksum: a49c34bf0a3af0c11041a3952a2600913904a983bd1bc87148b5c033bc5c1d02d5a13620fcdbfa2c60bc582a2e2970185780f0c844b4c3a220abf405f8af6311 - languageName: node - linkType: hard - -"vdirs@npm:^0.1.4, vdirs@npm:^0.1.8": - version: 0.1.8 - resolution: "vdirs@npm:0.1.8" - dependencies: - evtd: ^0.2.2 - peerDependencies: - vue: ^3.0.11 - checksum: a7be8ccad3e72f2891150d53085b8f924cc9d9a9e474cd58827e81417e8feef7f5a8ecbb00efa7631592bf5b3be0a0fa40da41789fcf18dab2cec2bddd01ea47 - languageName: node - linkType: hard - -"verror@npm:1.10.0": - version: 1.10.0 - resolution: "verror@npm:1.10.0" - dependencies: - assert-plus: ^1.0.0 - core-util-is: 1.0.2 - extsprintf: ^1.2.0 - checksum: c431df0bedf2088b227a4e051e0ff4ca54df2c114096b0c01e1cbaadb021c30a04d7dd5b41ab277bcd51246ca135bf931d4c4c796ecae7a4fef6d744ecef36ea - languageName: node - linkType: hard - -"vite@npm:2.9.14": - version: 2.9.14 - resolution: "vite@npm:2.9.14" - dependencies: - esbuild: ^0.14.27 - fsevents: ~2.3.2 - postcss: ^8.4.13 - resolve: ^1.22.0 - rollup: ^2.59.0 - peerDependencies: - less: "*" - sass: "*" - stylus: "*" - dependenciesMeta: - fsevents: - optional: true - peerDependenciesMeta: - less: - optional: true - sass: - optional: true - stylus: - optional: true - bin: - vite: bin/vite.js - checksum: f78b54f58482ea97d385e36873ae1aa4744c5e467c1d6d4e0835bd55494d2d8f6ce763f17c241c66104be687d5ee535b8e1e96c14210c9ba0c343fe78c58f694 - languageName: node - linkType: hard - -"vite@npm:^2.9.12 || ^3.0.0-0": - version: 3.0.0-beta.10 - resolution: "vite@npm:3.0.0-beta.10" - dependencies: - esbuild: ^0.14.47 - fsevents: ~2.3.2 - postcss: ^8.4.14 - resolve: ^1.22.1 - rollup: ^2.75.6 - peerDependencies: - less: "*" - sass: "*" - stylus: "*" - terser: ^5.4.0 - dependenciesMeta: - fsevents: - optional: true - peerDependenciesMeta: - less: - optional: true - sass: - optional: true - stylus: - optional: true - terser: - optional: true - bin: - vite: bin/vite.js - checksum: 2b27107dac3e240c7fd5bc5be40e62befce6de6d31220f8cc0d25e1c583e9e00c259c5eaa423c58e0ee87ab7bc46b5e07dd774d081f6439a3e747ee908e375b0 - languageName: node - linkType: hard - -"vitest@npm:0.18.1": - version: 0.18.1 - resolution: "vitest@npm:0.18.1" - dependencies: - "@types/chai": ^4.3.1 - "@types/chai-subset": ^1.3.3 - "@types/node": "*" - chai: ^4.3.6 - debug: ^4.3.4 - local-pkg: ^0.4.2 - tinypool: ^0.2.4 - tinyspy: ^1.0.0 - vite: ^2.9.12 || ^3.0.0-0 - peerDependencies: - "@edge-runtime/vm": "*" - "@vitest/ui": "*" - c8: "*" - happy-dom: "*" - jsdom: "*" - peerDependenciesMeta: - "@edge-runtime/vm": - optional: true - "@vitest/ui": - optional: true - c8: - optional: true - happy-dom: - optional: true - jsdom: - optional: true - bin: - vitest: vitest.mjs - checksum: 0d3a77625eb542bae27715cb24c91b7f4379d1084ce154ff54c991ab669fe0977a927121d232e6659e97b71b852060ca85c0b1825612f2e092b436e24cca276c - languageName: node - linkType: hard - -"void-elements@npm:^3.1.0": - version: 3.1.0 - resolution: "void-elements@npm:3.1.0" - checksum: 0390f818107fa8fce55bb0a5c3f661056001c1d5a2a48c28d582d4d847347c2ab5b7f8272314cac58acf62345126b6b09bea623a185935f6b1c3bbce0dfd7f7f - languageName: node - linkType: hard - -"vooks@npm:^0.2.12, vooks@npm:^0.2.4": - version: 0.2.12 - resolution: "vooks@npm:0.2.12" - dependencies: - evtd: ^0.2.2 - peerDependencies: - vue: ^3.0.0 - checksum: e6841ec5b6cb3938ce3ba0822a209fc4fd9cbb18af7e5034a979f3a80a6f6cfcdadc402bf8992ddffe09a5796c746731b7f6c3366c4a2e8309278f657ae8ea18 - languageName: node - linkType: hard - -"vue-demi@npm:*": - version: 0.13.1 - resolution: "vue-demi@npm:0.13.1" - peerDependencies: - "@vue/composition-api": ^1.0.0-rc.1 - vue: ^3.0.0-0 || ^2.6.0 - peerDependenciesMeta: - "@vue/composition-api": - optional: true - bin: - vue-demi-fix: bin/vue-demi-fix.js - vue-demi-switch: bin/vue-demi-switch.js - checksum: d26b0602587f4dbd81f975f8f2de39910239805f0f2d72cafed0c7349c512f5363daf57e2761ba6a7ac66331a4cfa3dc857d6f7f62c57adbae85752d270118c8 - languageName: node - linkType: hard - -"vue-demi@npm:^0.12.1": - version: 0.12.5 - resolution: "vue-demi@npm:0.12.5" - peerDependencies: - "@vue/composition-api": ^1.0.0-rc.1 - vue: ^3.0.0-0 || ^2.6.0 - peerDependenciesMeta: - "@vue/composition-api": - optional: true - bin: - vue-demi-fix: bin/vue-demi-fix.js - vue-demi-switch: bin/vue-demi-switch.js - checksum: 40a0470caea8312e0d4df2541f141c36c768dfc7f2f7d41f0f28ba29df11d3119e2f09b94c815f13b7c7f3f45dbc247b0e9e0c02a1800e2823e241c1d771e39b - languageName: node - linkType: hard - -"vue-eslint-parser@npm:^9.0.1": - version: 9.0.3 - resolution: "vue-eslint-parser@npm:9.0.3" - dependencies: - debug: ^4.3.4 - eslint-scope: ^7.1.1 - eslint-visitor-keys: ^3.3.0 - espree: ^9.3.1 - esquery: ^1.4.0 - lodash: ^4.17.21 - semver: ^7.3.6 - peerDependencies: - eslint: ">=6.0.0" - checksum: 61248eb504b8d0cbc95ed3f7ec6b11b72782cd76e4049798626f9c09031d620691a967231985c79d8ece8b04864797e465b7f47bcf91828e18344ae3691d9066 - languageName: node - linkType: hard - -"vue-router@npm:4.1.2": - version: 4.1.2 - resolution: "vue-router@npm:4.1.2" - dependencies: - "@vue/devtools-api": ^6.1.4 - peerDependencies: - vue: ^3.2.0 - checksum: f4b900f0db25a098647ada5eee05de6bc48e8f9c87deb403a87e7996965f39560654580f2d074c1ae0da427cc8d47eac9395cb17f6dc58a29d7d555f7510600e - languageName: node - linkType: hard - -"vue@npm:3.2.37": - version: 3.2.37 - resolution: "vue@npm:3.2.37" - dependencies: - "@vue/compiler-dom": 3.2.37 - "@vue/compiler-sfc": 3.2.37 - "@vue/runtime-dom": 3.2.37 - "@vue/server-renderer": 3.2.37 - "@vue/shared": 3.2.37 - checksum: cd20069c311e1de54b7d9b5d9c6021f1a6a70b0cf05cf7fc36b59c02623cbdc7c0075fb2c9e17859c77c86b15c596a447ee16c70064e9f2feba2df27139260b9 - languageName: node - linkType: hard - -"vueuc@npm:^0.4.47": - version: 0.4.47 - resolution: "vueuc@npm:0.4.47" - dependencies: - "@css-render/vue3-ssr": ^0.15.10 - "@juggle/resize-observer": ^3.3.1 - css-render: ^0.15.10 - evtd: ^0.2.2 - seemly: ^0.3.1 - vdirs: ^0.1.4 - vooks: ^0.2.4 - peerDependencies: - vue: ^3.0.11 - checksum: b82b77a882d29f8f6e432cabaf1ce3cefda1a87f5b956655e4f38a96351fa4ec17472608eb8ba30b5aa5edf894cfbad15447ddf4b46d46d9caf2c02b679a5cab - languageName: node - linkType: hard - -"weak-lru-cache@npm:^1.2.2": - version: 1.2.2 - resolution: "weak-lru-cache@npm:1.2.2" - checksum: 0fbe16839d193ed82ddb4fe331ca8cfaee2ecbd42596aa02366c708956cf41f7258f2d5411c3bc9aa099c26058dc47afbd2593d449718a18e4ef4d870c5ace18 - languageName: node - linkType: hard - -"webidl-conversions@npm:^4.0.2": - version: 4.0.2 - resolution: "webidl-conversions@npm:4.0.2" - checksum: c93d8dfe908a0140a4ae9c0ebc87a33805b416a33ee638a605b551523eec94a9632165e54632f6d57a39c5f948c4bab10e0e066525e9a4b87a79f0d04fbca374 - languageName: node - linkType: hard - -"whatwg-url@npm:^7.0.0": - version: 7.1.0 - resolution: "whatwg-url@npm:7.1.0" - dependencies: - lodash.sortby: ^4.7.0 - tr46: ^1.0.1 - webidl-conversions: ^4.0.2 - checksum: fecb07c87290b47d2ec2fb6d6ca26daad3c9e211e0e531dd7566e7ff95b5b3525a57d4f32640ad4adf057717e0c215731db842ad761e61d947e81010e05cf5fd - languageName: node - linkType: hard - -"which-boxed-primitive@npm:^1.0.2": - version: 1.0.2 - resolution: "which-boxed-primitive@npm:1.0.2" - dependencies: - is-bigint: ^1.0.1 - is-boolean-object: ^1.1.0 - is-number-object: ^1.0.4 - is-string: ^1.0.5 - is-symbol: ^1.0.3 - checksum: 53ce774c7379071729533922adcca47220228405e1895f26673bbd71bdf7fb09bee38c1d6399395927c6289476b5ae0629863427fd151491b71c4b6cb04f3a5e - languageName: node - linkType: hard - -"which@npm:^2.0.1, which@npm:^2.0.2": - version: 2.0.2 - resolution: "which@npm:2.0.2" - dependencies: - isexe: ^2.0.0 - bin: - node-which: ./bin/node-which - checksum: 1a5c563d3c1b52d5f893c8b61afe11abc3bab4afac492e8da5bde69d550de701cf9806235f20a47b5c8fa8a1d6a9135841de2596535e998027a54589000e66d1 - languageName: node - linkType: hard - -"wide-align@npm:^1.1.5": - version: 1.1.5 - resolution: "wide-align@npm:1.1.5" - dependencies: - string-width: ^1.0.2 || 2 || 3 || 4 - checksum: d5fc37cd561f9daee3c80e03b92ed3e84d80dde3365a8767263d03dacfc8fa06b065ffe1df00d8c2a09f731482fcacae745abfbb478d4af36d0a891fad4834d3 - languageName: node - linkType: hard - -"with@npm:^7.0.0": - version: 7.0.2 - resolution: "with@npm:7.0.2" - dependencies: - "@babel/parser": ^7.9.6 - "@babel/types": ^7.9.6 - assert-never: ^1.2.1 - babel-walk: 3.0.0-canary-5 - checksum: a00fe87b736e434bd8b9d3e62ddcd664bde7d3990a011a0f1bdeb499db0d6c28e6d2ef921dcc47650b8d436eee55459bcae8fab4ce1ed89f4926ddda407ab755 - languageName: node - linkType: hard - -"word-wrap@npm:^1.2.3": - version: 1.2.3 - resolution: "word-wrap@npm:1.2.3" - checksum: 30b48f91fcf12106ed3186ae4fa86a6a1842416df425be7b60485de14bec665a54a68e4b5156647dec3a70f25e84d270ca8bc8cd23182ed095f5c7206a938c1f - languageName: node - linkType: hard - -"wrap-ansi@npm:^6.2.0": - version: 6.2.0 - resolution: "wrap-ansi@npm:6.2.0" - dependencies: - ansi-styles: ^4.0.0 - string-width: ^4.1.0 - strip-ansi: ^6.0.0 - checksum: 6cd96a410161ff617b63581a08376f0cb9162375adeb7956e10c8cd397821f7eb2a6de24eb22a0b28401300bf228c86e50617cd568209b5f6775b93c97d2fe3a - languageName: node - linkType: hard - -"wrap-ansi@npm:^7.0.0": - version: 7.0.0 - resolution: "wrap-ansi@npm:7.0.0" - dependencies: - ansi-styles: ^4.0.0 - string-width: ^4.1.0 - strip-ansi: ^6.0.0 - checksum: a790b846fd4505de962ba728a21aaeda189b8ee1c7568ca5e817d85930e06ef8d1689d49dbf0e881e8ef84436af3a88bc49115c2e2788d841ff1b8b5b51a608b - languageName: node - linkType: hard - -"wrappy@npm:1": - version: 1.0.2 - resolution: "wrappy@npm:1.0.2" - checksum: 159da4805f7e84a3d003d8841557196034155008f817172d4e986bd591f74aa82aa7db55929a54222309e01079a65a92a9e6414da5a6aa4b01ee44a511ac3ee5 - languageName: node - linkType: hard - -"xml-name-validator@npm:^4.0.0": - version: 4.0.0 - resolution: "xml-name-validator@npm:4.0.0" - checksum: af100b79c29804f05fa35aa3683e29a321db9b9685d5e5febda3fa1e40f13f85abc40f45a6b2bf7bee33f68a1dc5e8eaef4cec100a304a9db565e6061d4cb5ad - languageName: node - linkType: hard - -"xxhash-wasm@npm:^0.4.2": - version: 0.4.2 - resolution: "xxhash-wasm@npm:0.4.2" - checksum: 747b32fcfed1dc9a1e7592b134e4e65794bc10fd5d32515792e486bf4d0b65f9dec790cfc49ce2f9c01dd02e3593c3a6cd51df1ef37adf003c5bbd386c43c64d - languageName: node - linkType: hard - -"y18n@npm:^5.0.5": - version: 5.0.8 - resolution: "y18n@npm:5.0.8" - checksum: 54f0fb95621ee60898a38c572c515659e51cc9d9f787fb109cef6fde4befbe1c4602dc999d30110feee37456ad0f1660fa2edcfde6a9a740f86a290999550d30 - languageName: node - linkType: hard - -"yallist@npm:^4.0.0": - version: 4.0.0 - resolution: "yallist@npm:4.0.0" - checksum: 343617202af32df2a15a3be36a5a8c0c8545208f3d3dfbc6bb7c3e3b7e8c6f8e7485432e4f3b88da3031a6e20afa7c711eded32ddfb122896ac5d914e75848d5 - languageName: node - linkType: hard - -"yaml@npm:^1.10.0": - version: 1.10.2 - resolution: "yaml@npm:1.10.2" - checksum: ce4ada136e8a78a0b08dc10b4b900936912d15de59905b2bf415b4d33c63df1d555d23acb2a41b23cf9fb5da41c256441afca3d6509de7247daa062fd2c5ea5f - languageName: node - linkType: hard - -"yargs-parser@npm:^20.2.2, yargs-parser@npm:^20.2.9": - version: 20.2.9 - resolution: "yargs-parser@npm:20.2.9" - checksum: 8bb69015f2b0ff9e17b2c8e6bfe224ab463dd00ca211eece72a4cd8a906224d2703fb8a326d36fdd0e68701e201b2a60ed7cf81ce0fd9b3799f9fe7745977ae3 - languageName: node - linkType: hard - -"yargs@npm:^16.2.0": - version: 16.2.0 - resolution: "yargs@npm:16.2.0" - dependencies: - cliui: ^7.0.2 - escalade: ^3.1.1 - get-caller-file: ^2.0.5 - require-directory: ^2.1.1 - string-width: ^4.2.0 - y18n: ^5.0.5 - yargs-parser: ^20.2.2 - checksum: b14afbb51e3251a204d81937c86a7e9d4bdbf9a2bcee38226c900d00f522969ab675703bee2a6f99f8e20103f608382936034e64d921b74df82b63c07c5e8f59 - languageName: node - linkType: hard - -"yauzl@npm:^2.10.0": - version: 2.10.0 - resolution: "yauzl@npm:2.10.0" - dependencies: - buffer-crc32: ~0.2.3 - fd-slicer: ~1.1.0 - checksum: 7f21fe0bbad6e2cb130044a5d1d0d5a0e5bf3d8d4f8c4e6ee12163ce798fee3de7388d22a7a0907f563ac5f9d40f8699a223d3d5c1718da90b0156da6904022b - languageName: node - linkType: hard - -"yocto-queue@npm:^0.1.0": - version: 0.1.0 - resolution: "yocto-queue@npm:0.1.0" - checksum: f77b3d8d00310def622123df93d4ee654fc6a0096182af8bd60679ddcdfb3474c56c6c7190817c84a2785648cdee9d721c0154eb45698c62176c322fb46fc700 - languageName: node - linkType: hard - -"zxcvbn@npm:4.4.2": - version: 4.4.2 - resolution: "zxcvbn@npm:4.4.2" - checksum: 76ab32c066082ac73491b7cd7f93ad0595c59b6d45ae80a0745e9e1661237388beb2f0c2ba0ae3dc330ca3ecdb87edcb7a21e0c09137ab81d5b32e584cda1e5d - languageName: node - linkType: hard